BitStream.cpp

00001 /* 
00002  *      Copyright (C) 2003-2005 Gabest
00003  *      http://www.gabest.org
00004  *
00005  *  This Program is free software; you can redistribute it and/or modify
00006  *  it under the terms of the GNU General Public License as published by
00007  *  the Free Software Foundation; either version 2, or (at your option)
00008  *  any later version.
00009  *   
00010  *  This Program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00013  *  GNU General Public License for more details.
00014  *   
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with GNU Make; see the file COPYING.  If not, write to
00017  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
00018  *  http://www.gnu.org/copyleft/gpl.html
00019  *
00020  */
00021 
00022 #include "StdAfx.h"
00023 #include "BitStream.h"
00024 
00025 //
00026 // CBitStream
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); // not that it worked...
00042 
00043         m_pStream->Commit(S_OK); // also seems to have no effect, but maybe in the future...
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 // IBitStream
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 }

Generated on Tue Dec 13 14:47:08 2005 for guliverkli by  doxygen 1.4.5