00001 #include "StdAfx.h"
00002 #include ".\oggfile.h"
00003
00004 COggFile::COggFile(IAsyncReader* pAsyncReader, HRESULT& hr)
00005 : CBaseSplitterFile(pAsyncReader, hr)
00006 {
00007 if(FAILED(hr)) return;
00008 hr = Init();
00009 }
00010
00011 HRESULT COggFile::Init()
00012 {
00013 Seek(0);
00014 if(!Sync()) return E_FAIL;
00015
00016 return S_OK;
00017 }
00018
00019 bool COggFile::Sync(HANDLE hBreak)
00020 {
00021 __int64 start = GetPos();
00022
00023 DWORD dw;
00024 for(__int64 i = 0, j = hBreak ? GetLength() - start : 65536;
00025 i < j && S_OK == Read((BYTE*)&dw, sizeof(dw))
00026 && ((i&0xffff) || !hBreak || WaitForSingleObject(hBreak, 0) != WAIT_OBJECT_0);
00027 i++, Seek(start + i))
00028 {
00029 if(dw == 'SggO')
00030 {
00031 Seek(start + i);
00032 return(true);
00033 }
00034 }
00035
00036 Seek(start);
00037
00038 return(false);
00039 }
00040
00041 bool COggFile::Read(OggPageHeader& hdr, HANDLE hBreak)
00042 {
00043 return Sync(hBreak) && S_OK == Read((BYTE*)&hdr, sizeof(hdr)) && hdr.capture_pattern == 'SggO';
00044 }
00045
00046 bool COggFile::Read(OggPage& page, bool fFull, HANDLE hBreak)
00047 {
00048 memset(&page.m_hdr, 0, sizeof(page.m_hdr));
00049 page.m_lens.RemoveAll();
00050 page.SetSize(0);
00051
00052 if(!Read(page.m_hdr, hBreak))
00053 return(false);
00054
00055 int pagelen = 0, packetlen = 0;
00056 for(BYTE i = 0; i < page.m_hdr.number_page_segments; i++)
00057 {
00058 BYTE b;
00059 if(S_OK != Read(&b, 1)) return(false);
00060 packetlen += b;
00061 if(1) {page.m_lens.AddTail(packetlen); pagelen += packetlen; packetlen = 0;}
00062 }
00063
00064 if(fFull)
00065 {
00066 page.SetSize(pagelen);
00067 if(S_OK != Read(page.GetData(), page.GetSize()))
00068 return(false);
00069 }
00070 else
00071 {
00072 Seek(GetPos()+pagelen);
00073 page.m_lens.RemoveAll();
00074 }
00075
00076 return(true);
00077 }