00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "StdAfx.h"
00023 #include "BitStream.h"
00024
00025
00026
00027
00028
00029 CBitStream::CBitStream(IStream* pStream, bool fThrowError)
00030 : CUnknown(_T("CBitStream"), NULL)
00031 , m_pStream(pStream)
00032 , m_fThrowError(fThrowError)
00033 , m_bitlen(0)
00034 {
00035 ASSERT(m_pStream);
00036
00037 LARGE_INTEGER li = {0};
00038 m_pStream->Seek(li, STREAM_SEEK_SET, NULL);
00039
00040 ULARGE_INTEGER uli = {0};
00041 m_pStream->SetSize(uli);
00042
00043 m_pStream->Commit(S_OK);
00044 }
00045
00046 CBitStream::~CBitStream()
00047 {
00048 BitFlush();
00049 }
00050
00051 STDMETHODIMP CBitStream::NonDelegatingQueryInterface(REFIID riid, void** ppv)
00052 {
00053 CheckPointer(ppv, E_POINTER);
00054
00055 *ppv = NULL;
00056
00057 return
00058 QI(IBitStream)
00059 __super::NonDelegatingQueryInterface(riid, ppv);
00060 }
00061
00062
00063
00064 STDMETHODIMP_(UINT64) CBitStream::GetPos()
00065 {
00066 ULARGE_INTEGER pos = {0, 0};
00067 m_pStream->Seek(*(LARGE_INTEGER*)&pos, STREAM_SEEK_CUR, &pos);
00068 return pos.QuadPart;
00069 }
00070
00071 STDMETHODIMP_(UINT64) CBitStream::Seek(UINT64 pos)
00072 {
00073 BitFlush();
00074
00075 LARGE_INTEGER li;
00076 li.QuadPart = pos;
00077 ULARGE_INTEGER linew;
00078 linew.QuadPart = -1;
00079 m_pStream->Seek(li, STREAM_SEEK_SET, &linew);
00080 ASSERT(li.QuadPart == linew.QuadPart);
00081 return linew.QuadPart;
00082 }
00083
00084 STDMETHODIMP CBitStream::ByteWrite(const void* pData, int len)
00085 {
00086 HRESULT hr = S_OK;
00087
00088 BitFlush();
00089
00090 if(len > 0)
00091 {
00092 ULONG cbWritten = 0;
00093 hr = m_pStream->Write(pData, len, &cbWritten);
00094
00095 ASSERT(SUCCEEDED(hr));
00096 if(m_fThrowError && FAILED(hr)) throw hr;
00097 }
00098
00099 return hr;
00100 }
00101
00102 STDMETHODIMP CBitStream::BitWrite(UINT64 data, int len)
00103 {
00104 HRESULT hr = S_OK;
00105
00106 ASSERT(len >= 0 && len <= 64);
00107
00108 if(len > 56) {BitWrite(data >> 56, len - 56); len = 56;}
00109
00110 m_bitbuff <<= len;
00111 m_bitbuff |= data & ((1ui64 << len) - 1);
00112 m_bitlen += len;
00113
00114 while(m_bitlen >= 8)
00115 {
00116 BYTE b = (BYTE)(m_bitbuff >> (m_bitlen - 8));
00117 hr = m_pStream->Write(&b, 1, NULL);
00118 m_bitlen -= 8;
00119
00120 ASSERT(SUCCEEDED(hr));
00121 if(m_fThrowError && FAILED(hr)) throw E_FAIL;
00122 }
00123
00124 return hr;
00125 }
00126
00127 STDMETHODIMP CBitStream::BitFlush()
00128 {
00129 HRESULT hr = S_OK;
00130
00131 if(m_bitlen > 0)
00132 {
00133 ASSERT(m_bitlen < 8);
00134 BYTE b = (BYTE)(m_bitbuff << (8 - m_bitlen));
00135 hr = m_pStream->Write(&b, 1, NULL);
00136 m_bitlen = 0;
00137
00138 ASSERT(SUCCEEDED(hr));
00139 if(m_fThrowError && FAILED(hr)) throw E_FAIL;
00140 }
00141
00142 return hr;
00143 }