3gppttstructs.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:44k
- /* ***** BEGIN LICENSE BLOCK *****
- * Version: RCSL 1.0/RPSL 1.0
- *
- * Portions Copyright (c) 1995-2003 RealNetworks, Inc. All Rights Reserved.
- *
- * The contents of this file, and the files included with this file, are
- * subject to the current version of the RealNetworks Public Source License
- * Version 1.0 (the "RPSL") available at
- * http://www.helixcommunity.org/content/rpsl unless you have licensed
- * the file under the RealNetworks Community Source License Version 1.0
- * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
- * in which case the RCSL will apply. You may also obtain the license terms
- * directly from RealNetworks. You may not use this file except in
- * compliance with the RPSL or, if you have a valid RCSL with RealNetworks
- * applicable to this file, the RCSL. Please see the applicable RPSL or
- * RCSL for the rights, obligations and limitations governing use of the
- * contents of the file.
- *
- * This file is part of the Helix DNA Technology. RealNetworks is the
- * developer of the Original Code and owns the copyrights in the portions
- * it created.
- *
- * This file, and the files included with this file, is distributed and made
- * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- *
- * Technology Compatibility Kit Test Suite(s) Location:
- * http://www.helixcommunity.org/content/tck
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
- /****************************************************************************
- * Includes
- */
- #include <string.h> // /for memset, strncmp, stricmp
- #include "hlxclib/memory.h" // /for memset, memcpy
- #include "chxpckts.h" // /For IHXPacket
- #include "hxwintyp.h" // /For HXxRect
- #if defined(_SYMBIAN) // / -----vvvvvvvvvvvvvvvvvvvvvvvvvv-----
- #include <utf.h> // /For CnvUtfConverter::ConvertToUnicodeFromUtf8();
- #endif // /_SYMBIAN _____^^^^^^^^^^^^^^^^^^^^^^^^^^_____
- #include "3gppttstructs.h"
- #include "3gppttutils.h"
- #include "hxheap.h"
- #ifdef _DEBUG
- #undef HX_THIS_FILE
- static const char HX_THIS_FILE[] = __FILE__;
- #endif
- // for DPRINTF
- //#define INCLUDE_DPRINTF
- #if(INCLUDE_DPRINTF)
- # include "debug.h"
- # define D_TIMEDTEXT D_INFO
- #else
- # define DPRINTF(a,b)
- #endif
- HX_RESULT C3GPPTextboxBox::Build(const UINT8*& pData)
- {
- DPRINTF(D_TIMEDTEXT, ("C3GPPTextboxBox::Build()n"));
- m_top = ReadUI16(pData);
- m_left = ReadUI16(pData);
- m_bottom = ReadUI16(pData);
- m_right = ReadUI16(pData);
- return HXR_OK;
- }
- HX_RESULT C3GPPStyleRecord::Build(const UINT8*& pData)
- {
- DPRINTF(D_TIMEDTEXT, ("C3GPPStyleRecord::Build()n"));
- m_uiStartCharOffset = ReadUI16(pData);
- m_uiEndCharOffset = ReadUI16(pData);
- m_uiFontID = ReadUI16(pData);
- m_uFaceStyleFlags = *pData++;
- m_uFontSize = *pData++;
- m_textColor = ReadARGB(pData);
- return HXR_OK;
- }
- HX_RESULT C3GPPFontRecord::Build(const UINT8*& pData)
- {
- DPRINTF(D_TIMEDTEXT, ("C3GPPFontRecord::Build()n"));
- m_uiFontID = ReadUI16(pData);
- UINT8 cchFontName = *pData++;
- HX_RESULT hr = m_strFont.Set((const char*)pData, cchFontName);
- if(SUCCEEDED(hr))
- {
- pData += cchFontName;
- }
- return hr;
- }
- HX_RESULT C3GPPTextHyperTextBox::Build(const UINT8*& pData)
- {
- DPRINTF(D_TIMEDTEXT, ("C3GPPTextHyperTextBox::Build()n"));
- m_uiStartCharOffset = ReadUI16(pData);
- m_uiEndCharOffset = ReadUI16(pData);
- UINT8 cchURL = *pData++;
-
- HX_RESULT hr = m_strURL.Set((const char*)pData, cchURL);
- if(SUCCEEDED(hr))
- {
- pData += cchURL;
- cchURL = *pData++;
- hr = m_strAltURL.Set((const char*)pData, cchURL);
- if(SUCCEEDED(hr))
- {
- pData += cchURL;
- }
- }
- return hr;
- }
- HX_RESULT C3GPPTextSampleEntry::Build(const UINT8*& pData)
- {
- DPRINTF(D_TIMEDTEXT, ("C3GPPTextSampleEntry::Build()n"));
- HX_RESULT hr = C3GPPArrayEntry::Build(pData);
- if(SUCCEEDED(hr))
- {
- m_ulDisplayFlags = ReadUL32(pData);
- m_horizontalJustification = *pData++;
- m_verticalJustification = *pData++;
- m_bgColor = ReadARGB(pData);
- hr = m_defaultTextBox.Build(pData);
- if(SUCCEEDED(hr))
- {
- hr = m_defaultStyle.Build(pData);
- if(SUCCEEDED(hr))
- {
- hr = m_fontTable.Build(pData);
- }
- }
- }
- return hr;
- }
- C3GPPTextSampleEntry::C3GPPTextSampleEntry()
- : m_ulDisplayFlags(0)
- , m_horizontalJustification(0)
- , m_verticalJustification(0)
- , m_bgColor(0)
- {
- }
- TextSampleScrollDirection
- C3GPPTextSampleEntry::getScrollDirection() const
- {
- TextSampleScrollDirection retval = scrollDirNone;
- if (hasScrollIn() || hasScrollOut())
- {
- switch (m_ulDisplayFlags & HX_3GPPTT_DISPLAYFLAGS_SCROLL_DIR_MASK)
- {
- case HX_3GPPTT_DISPLAYFLAGS_SCROLL_DIR_UP:
- retval = scrollDirUp;
- break;
- case HX_3GPPTT_DISPLAYFLAGS_SCROLL_DIR_RTOL:
- retval = scrollDirRightToLeft;
- break;
- case HX_3GPPTT_DISPLAYFLAGS_SCROLL_DIR_DOWN:
- retval = scrollDirDown;
- break;
- case HX_3GPPTT_DISPLAYFLAGS_SCROLL_DIR_LTOR:
- retval = scrollDirLeftToRight;
- break;
- default:
- // /Should be one of the above:
- HX_ASSERT(m_ulDisplayFlags & HX_3GPPTT_DISPLAYFLAGS_SCROLL_DIR_MASK);
- retval = scrollDirNone;
- break;
- }
- }
- return retval;
- }
- C3GPPTextSampleModifierBox::ModifierType C3GPPTextSampleModifierBox::ReadType(const UINT8*& pData)
- {
- const char* pchType = (const char*)pData;
- pData += 4;
- ModifierType type = UNKNOWN;
- if (!strncmp(pchType, "styl", 4) )
- {
- type = STYL;
- }
- else if (!strncmp(pchType, "hlit", 4) )
- {
- type = HLIT;
- }
- else if (!strncmp(pchType, "hclr", 4) )
- {
- type = HCLR;
- }
- else if (!strncmp(pchType, "krok", 4) )
- {
- type = KROK;
- }
- else if (!strncmp(pchType, "dlay", 4) )
- {
- type = DLAY;
- }
- else if (!strncmp(pchType, "href", 4) )
- {
- type = HREF;
- }
- else if (!strncmp(pchType, "tbox", 4) )
- {
- type = TBOX;
- }
- else if (!strncmp(pchType, "blnk", 4) )
- {
- type = BLNK;
- }
- return type;
- }
- HX_RESULT C3GPPTextSample::Init(IHXBuffer* pIHXBuff)
- {
- HX_ASSERT(pIHXBuff);
- m_pIHXBuff->AddRef();
- const UINT8* pPackedBuff = m_pIHXBuff->GetBuffer();
- HX_ASSERT(pPackedBuff);
- UINT32 cbSampleTotal = m_pIHXBuff->GetSize();
- m_uiTextLengthInBytes = ReadUI16(pPackedBuff);
- UINT32 cbSampleTextBox = 2 + m_uiTextLengthInBytes; //size field + text
- HX_ASSERT(cbSampleTotal >= cbSampleTextBox);
- if (m_uiTextLengthInBytes && (cbSampleTotal > 2) )
- {
- // /NOTE: The spec says:
- // "Authors should limit the string in each text sample to not more
- // than 2048 bytes, for maximum terminal interoperability."
- // and it also says:
- // "Any unrecognised box found in the text sample should be skipped
- // and ignored, and processing continue as if it were not there."
- m_pText = (const char*) pPackedBuff;
-
- m_uiTextModifiersTotalSize = UINT16(cbSampleTotal - cbSampleTextBox);
- DPRINTF(D_TIMEDTEXT, ("C3GPPTextSample::Init(): %.*s;n", 200, m_pText));
- if (m_uiTextModifiersTotalSize)
- {
- // text modifiers follow
- m_pTextModifierData = pPackedBuff + m_uiTextLengthInBytes;
-
- }
- }
- return HXR_OK;
- }
- C3GPPTextSample::C3GPPTextSample(IHXBuffer* pIHXBuff)
- : m_pText(NULL)
- , m_uiTextLengthInBytes(0)
- , m_pTextModifierData(NULL)
- , m_uiTextModifiersTotalSize(0)
- , m_pIHXBuff(pIHXBuff)
- {
- Init(pIHXBuff);
- }
- HX_RESULT C3GPPTextStyleBox::Build(const UINT8*& pData)
- {
- DPRINTF(D_TIMEDTEXT, ("C3GPPTextStyleBox::Build()n"));
- HX_RESULT hr = HXR_OK;
- UINT16 entryCount = ReadUI16(pData);
- HX_ASSERT(m_entries.GetCount() == 0);
- DPRINTF(D_TIMEDTEXT, ("C3GPPTextStyleBox::Build(): %u entriesn", entryCount));
- hr = m_entries.Reset(entryCount);
- if(SUCCEEDED(hr))
- {
- for(UINT16 idx = 0; idx < entryCount; ++idx)
- {
- C3GPPStyleRecord* pEntry = new C3GPPStyleRecord();
- if(!pEntry)
- {
- return HXR_OUTOFMEMORY;
- }
- hr = pEntry->Build(pData);
- if(FAILED(hr))
- {
- HX_DELETE(pEntry);
- break;
- }
- m_entries[idx] = pEntry;
- }
- }
- return hr;
- }
- C3GPPFontTableBox::~C3GPPFontTableBox()
- {
- CleanUp();
- }
- void C3GPPFontTableBox::CleanUp()
- {
- for ( UINT32 idx = 0; idx != m_entries.GetCount(); ++idx )
- {
- C3GPPFontRecord*& pEntry = (C3GPPFontRecord*&)(m_entries[idx]);
- delete pEntry;
- }
- m_entries.Reset(0);
- }
- HX_RESULT C3GPPFontTableBox::Build(const UINT8*& pData)
- {
- DPRINTF(D_TIMEDTEXT, ("C3GPPFontTableBox::Build()n"));
- HX_RESULT hr = HXR_OK;
- m_ulFontTableSizeInBytes = ReadUL32(pData);
- // skip ftab
- HX_ASSERT(!strncmp((const char*)pData, "ftab", 4));
- pData += 4;
- UINT16 entryCount = ReadUI16(pData);
- HX_ASSERT(m_entries.GetCount() == 0);
- DPRINTF(D_TIMEDTEXT, ("C3GPPFontTableBox::Build(): %u entriesn", entryCount));
- hr = m_entries.Reset(entryCount);
- if(SUCCEEDED(hr))
- {
- for(UINT16 idx = 0; idx < entryCount; ++idx)
- {
- C3GPPFontRecord* pEntry = new C3GPPFontRecord();
- if(!pEntry)
- {
- return HXR_OUTOFMEMORY;
- }
- hr = pEntry->Build(pData);
- if(FAILED(hr))
- {
- HX_ASSERT(false);
- HX_DELETE(pEntry);
- break;
- }
- HX_ASSERT(0 == m_entries[idx]);
- m_entries[idx] = pEntry;
- }
- }
- return hr;
- }
- C3GPPTextStyleBox::~C3GPPTextStyleBox()
- {
- CleanUp();
- }
- void C3GPPTextStyleBox::CleanUp()
- {
- for ( INT32 idx = 0; idx != m_entries.GetCount(); ++idx )
- {
- C3GPPStyleRecord*& pEntry = (C3GPPStyleRecord*&)(m_entries[idx]);
- delete pEntry;
- }
- m_entries.Reset(0);
- }
- HX_RESULT C3GPPTextKaraokeBox::Build(const UINT8*& pData)
- {
- DPRINTF(D_TIMEDTEXT, ("C3GPPTextKaraokeBox::Build()n"));
- HX_RESULT hr = HXR_OK;
- m_ul1stHighlightStartTime = ReadUL32(pData);
- UINT16 entryCount = ReadUI16(pData);
- HX_ASSERT(m_entries.GetCount() == 0);
- DPRINTF(D_TIMEDTEXT, ("C3GPPTextKaraokeBox::Build(): %u entriesn", entryCount));
- hr = m_entries.Reset(entryCount);
- if(SUCCEEDED(hr))
- {
- for(UINT16 idx = 0; idx < entryCount; ++idx)
- {
- C3GPPTextKaraokeControlEntry* pEntry = new C3GPPTextKaraokeControlEntry();
- if(!pEntry)
- {
- return HXR_OUTOFMEMORY;
- }
- hr = pEntry->Build(pData);
- if(FAILED(hr))
- {
- HX_ASSERT(false);
- HX_DELETE(pEntry);
- break;
- }
- m_entries[idx] = pEntry;
- }
- }
- return hr;
- }
- C3GPPTextKaraokeBox::~C3GPPTextKaraokeBox()
- {
- CleanUp();
- }
- void C3GPPTextKaraokeBox::CleanUp()
- {
- for ( INT32 idx = 0; idx != m_entries.GetCount(); ++idx )
- {
- C3GPPTextKaraokeControlEntry*& pEntry = (C3GPPTextKaraokeControlEntry*&)(m_entries[idx]);
- delete pEntry;
- }
- m_entries.Reset(0);
- }
- HX_RESULT C3GPPTextKaraokeBox::C3GPPTextKaraokeControlEntry::Build(const UINT8*& pData)
- {
- m_ulHighlightEndTime = ReadUL32(pData);
- m_uiStartCharOffset = ReadUI16(pData);
- m_uiEndCharOffset = ReadUI16(pData);
- return HXR_OK;
- }
- HX_RESULT C3GPPTextContainer::BuildKROK(const UINT8*& pData,
- UINT16& uiLowestPotentialNextTCStartOffsetFound,
- BOOL& bNeedToBreakTCsUpAtNewlines,
- UINT16& curEndCharOffset)
- {
- DPRINTF(D_TIMEDTEXT, ("C3GPPTextContainer::BuildKROK()n"));
- HX_ASSERT(!m_pTextKaraokeBox);
-
- m_pTextKaraokeBox = new C3GPPTextKaraokeBox();
- if(!m_pTextKaraokeBox)
- {
- return HXR_OUTOFMEMORY;
- }
- HX_RESULT hr = m_pTextKaraokeBox->Build(pData);
- if(SUCCEEDED(hr))
- {
- BOOL bAssignBoxToCurrent = FALSE;
- m_uiTextKaraokeBoxIndex = HX_3GPPTT_INVALID_INDEX;
- // /Go through the array of C3GPPTextKaraokeControlEntry(s)
- // & look at their m_uiStartCharOffset & m_uiEndCharOffset.
- // If all are fully before or fully after, ignore the
- // whole enchilada:
- UINT16 uiEntryCount = m_pTextKaraokeBox->GetEntryCount();
- DPRINTF(D_TIMEDTEXT, ("C3GPPTextContainer::BuildKROK(): %u entriesn", uiEntryCount));
- for (UINT16 uiCurEntry = 0; uiCurEntry < uiEntryCount; uiCurEntry++)
- {
- const C3GPPTextKaraokeBox::C3GPPTextKaraokeControlEntry*
- pCurKaraokeCtrlEntry =
- m_pTextKaraokeBox->GetKaraokeControlEntry(uiCurEntry);
- HX_ASSERT(pCurKaraokeCtrlEntry);
- if (pCurKaraokeCtrlEntry)
- {
- UINT16 uiCurStartCharOffset =
- pCurKaraokeCtrlEntry->GetStartOffset();
- curEndCharOffset =
- pCurKaraokeCtrlEntry->GetEndOffset();
- DPRINTF(D_TIMEDTEXT, ("C3GPPTextContainer::BuildKROK(): range %u, %un", uiCurStartCharOffset, curEndCharOffset));
- if (HXR_OK != UpdateLowestPotentialNextTCStartOffset(
- uiCurStartCharOffset, curEndCharOffset,
- /*REF IN/OUT */ uiLowestPotentialNextTCStartOffsetFound,
- /*REF OUT*/ bAssignBoxToCurrent) )
- {
- DPRINTF(D_TIMEDTEXT, ("C3GPPTextContainer::BuildKROK(): discarding entry %u n", uiCurEntry));
- continue; // /Ignore this entry; bad data.
- }
- if (bAssignBoxToCurrent)
- {
- m_uiTextKaraokeBoxIndex = uiCurEntry;
- break;
- }
- }
- }
- if (HX_3GPPTT_INVALID_INDEX == m_uiTextKaraokeBoxIndex)
- {
- // /All Karaoke control entries are before or after,
- // so ignore this entire karaoke modifier:
- HX_DELETE(m_pTextKaraokeBox);
- }
- bNeedToBreakTCsUpAtNewlines = TRUE;
- }
- else
- {
- HX_ASSERT(false);
- HX_DELETE(m_pTextKaraokeBox);
- }
- return hr;
- }
- HX_RESULT C3GPPTextContainer::BuildDLAY(const UINT8*& pData)
- {
- DPRINTF(D_TIMEDTEXT, ("C3GPPTextContainer::BuildDLAY()n"));
- HX_ASSERT(!m_pTextScrollDelayBox);
- m_pTextScrollDelayBox = new C3GPPTextScrollDelayBox();
- if(!m_pTextScrollDelayBox)
- {
- return HXR_OUTOFMEMORY;
- }
- HX_RESULT hr = m_pTextScrollDelayBox->Build(pData);
- if(FAILED(hr))
- {
- HX_ASSERT(false);
- HX_DELETE(m_pTextScrollDelayBox);
- }
- return hr;
-
- }
- HX_RESULT C3GPPTextContainer::BuildHCLR(const UINT8*& pData)
- {
- DPRINTF(D_TIMEDTEXT, ("C3GPPTextContainer::BuildHCLR()n"));
- HX_ASSERT(!m_pTextHilightColorBox);
- m_pTextHilightColorBox = new C3GPPTextHilightColorBox();
- if(!m_pTextHilightColorBox)
- {
- return HXR_OUTOFMEMORY;
- }
- HX_RESULT hr = m_pTextHilightColorBox->Build(pData);
- if(FAILED(hr))
- {
- HX_ASSERT(false);
- HX_DELETE(m_pTextHilightColorBox);
- }
- return hr;
- }
- HX_RESULT C3GPPTextContainer::BuildTBOX(const UINT8*& pData)
- {
- DPRINTF(D_TIMEDTEXT, ("C3GPPTextContainer::BuildTBOX(): text boxn"));
- HX_ASSERT(!m_pTextboxBox);
- m_pTextboxBox = new C3GPPTextboxBox();
- if(!m_pTextboxBox)
- {
- return HXR_OUTOFMEMORY;
- }
- HX_RESULT hr = m_pTextboxBox->Build(pData);
- if(FAILED(hr))
- {
- HX_ASSERT(false);
- HX_DELETE(m_pTextboxBox);
- }
- return hr;
- }
-
- HX_RESULT C3GPPTextContainer::BuildHLIT(const UINT8*& pData,
- UINT16& uiLowestPotentialNextTCStartOffsetFound,
- BOOL& bNeedToBreakTCsUpAtNewlines,
- UINT16& curEndCharOffset)
- {
- DPRINTF(D_TIMEDTEXT, ("C3GPPTextContainer::BuildHLIT()n"));
- HX_ASSERT(!m_pTextHighlightBox);
-
- m_pTextHighlightBox = new C3GPPTextHighlightBox();
- if(!m_pTextHighlightBox)
- {
- return HXR_OUTOFMEMORY;
- }
- HX_RESULT hr = m_pTextHighlightBox->Build(pData);
- if(SUCCEEDED(hr))
- {
- BOOL bAssignBoxToCurrent = FALSE;
- UINT16 uiCurStartCharOffset = m_pTextHighlightBox->GetStartOffset();
- curEndCharOffset = m_pTextHighlightBox->GetEndOffset();
- DPRINTF(D_TIMEDTEXT, ("C3GPPTextContainer::BuildHLIT(): range %u, %un", uiCurStartCharOffset, curEndCharOffset));
- // /If data is bad or if this is out of range, then
- // this hlit box is not this's modifier:
- if (HXR_OK != UpdateLowestPotentialNextTCStartOffset(
- uiCurStartCharOffset, curEndCharOffset,
- /*REF IN/OUT */ uiLowestPotentialNextTCStartOffsetFound,
- /*REF OUT*/ bAssignBoxToCurrent)
- // /FALSE means this is out of box's range:
- || !bAssignBoxToCurrent)
- {
- DPRINTF(D_TIMEDTEXT, ("C3GPPTextContainer::BuildHLIT(): discardingn"));
- HX_DELETE(m_pTextHighlightBox);
- }
-
- bNeedToBreakTCsUpAtNewlines = TRUE;
- }
- else
- {
- HX_ASSERT(false);
- HX_DELETE(m_pTextBlinkBox);
- }
- return hr;
- }
- HX_RESULT C3GPPTextContainer::BuildHREF(const UINT8*& pData,
- UINT16& uiLowestPotentialNextTCStartOffsetFound,
- BOOL& bNeedToBreakTCsUpAtNewlines,
- UINT16& curEndCharOffset)
- {
- DPRINTF(D_TIMEDTEXT, ("C3GPPTextContainer::BuildHREF()n"));
- HX_ASSERT(!m_pTextHyperTextBox);
- m_pTextHyperTextBox = new C3GPPTextHyperTextBox();
- if(!m_pTextHyperTextBox)
- {
- return HXR_OUTOFMEMORY;
- }
- HX_RESULT hr = m_pTextHyperTextBox->Build(pData);
- if(SUCCEEDED(hr))
- {
- BOOL bAssignBoxToCurrent = FALSE;
- UINT16 uiCurStartCharOffset = m_pTextHyperTextBox->GetStartOffset();
- curEndCharOffset = m_pTextHyperTextBox->GetEndOffset();
-
- DPRINTF(D_TIMEDTEXT, ("C3GPPTextContainer::BuildHREF(): range %u, %un", uiCurStartCharOffset, curEndCharOffset));
- // /If data is bad or if this is out of range, then
- // this hlit box is not this's modifier:
- if (HXR_OK != UpdateLowestPotentialNextTCStartOffset(
- uiCurStartCharOffset, curEndCharOffset,
- /*REF IN/OUT */ uiLowestPotentialNextTCStartOffsetFound,
- /*REF OUT */ bAssignBoxToCurrent)
- // /FALSE means this is out of box's range:
- || !bAssignBoxToCurrent)
- {
- DPRINTF(D_TIMEDTEXT, ("C3GPPTextContainer::BuildHREF(): discardingn"));
- HX_DELETE(m_pTextHyperTextBox);
- }
-
- bNeedToBreakTCsUpAtNewlines = TRUE;
- }
- else
- {
- HX_ASSERT(false);
- HX_DELETE(m_pTextHyperTextBox);
- }
- return hr;
- }
- HX_RESULT C3GPPTextContainer::BuildBLNK(const UINT8*& pData,
- UINT16& uiLowestPotentialNextTCStartOffsetFound,
- BOOL& bNeedToBreakTCsUpAtNewlines,
- UINT16& curEndCharOffset)
- {
- DPRINTF(D_TIMEDTEXT, ("C3GPPTextContainer::BuildBLNK()n"));
- HX_ASSERT(!m_pTextBlinkBox);
- m_pTextBlinkBox = new C3GPPTextBlinkBox();
- if(!m_pTextBlinkBox)
- {
- return HXR_OUTOFMEMORY;
- }
- HX_RESULT hr = m_pTextBlinkBox->Build(pData);
- if(SUCCEEDED(hr))
- {
- BOOL bAssignBoxToCurrent = FALSE;
- UINT16 uiCurStartCharOffset = m_pTextBlinkBox->GetStartOffset();
- curEndCharOffset = m_pTextBlinkBox->GetEndOffset();
- DPRINTF(D_TIMEDTEXT, ("C3GPPTextContainer::BuildBLNK(): range %u, %un", uiCurStartCharOffset, curEndCharOffset));
- // /If data is bad or if this is out of range, then
- // this hlit box is not this's modifier:
- if (HXR_OK != UpdateLowestPotentialNextTCStartOffset(
- uiCurStartCharOffset, curEndCharOffset,
- /*REF IN/OUT */ uiLowestPotentialNextTCStartOffsetFound,
- /*REF OUT */ bAssignBoxToCurrent)
- // /FALSE means this is out of box's range:
- || !bAssignBoxToCurrent)
- {
- DPRINTF(D_TIMEDTEXT, ("C3GPPTextContainer::BuildBLNK(): discardingn"));
- HX_DELETE(m_pTextBlinkBox);
- }
-
- bNeedToBreakTCsUpAtNewlines = TRUE;
- }
- else
- {
- HX_ASSERT(false);
- HX_DELETE(m_pTextBlinkBox);
- }
- return hr;
- }
- HX_RESULT C3GPPTextContainer::BuildSTYL(const UINT8*& pData,
- UINT16& uiLowestPotentialNextTCStartOffsetFound,
- BOOL& bNeedToBreakTCsUpAtNewlines,
- UINT16& curEndCharOffset)
- {
- DPRINTF(D_TIMEDTEXT, ("C3GPPTextContainer::BuildSTYL()n"));
- HX_ASSERT(!m_pTextStyleBox);
- m_pTextStyleBox = new C3GPPTextStyleBox();
- if(!m_pTextStyleBox)
- {
- return HXR_OUTOFMEMORY;
- }
- HX_RESULT hr = m_pTextStyleBox->Build(pData);
- if(SUCCEEDED(hr))
- {
- BOOL bAssignBoxToCurrent = FALSE;
- m_uiTextStyleBoxIndex = HX_3GPPTT_INVALID_INDEX;
- // /Go through the array of C3GPPStyleRecords and look
- // at their m_uiStartCharOffset and m_uiEndCharOffset.
- // If all are fully before or fully after, ignore the
- // whole shebang:
- UINT16 uiEntryCount = m_pTextStyleBox->GetEntryCount();
- DPRINTF(D_TIMEDTEXT, ("C3GPPTextContainer::BuildSTYL(): %u entriesn", uiEntryCount));
- for (UINT16 uiCurEntry = 0; uiCurEntry < uiEntryCount; uiCurEntry++)
- {
- const C3GPPStyleRecord* pCurStyleRecord =
- m_pTextStyleBox->GetStyleRecord(uiCurEntry);
- HX_ASSERT(pCurStyleRecord);
- if (pCurStyleRecord)
- {
- UINT16 uiCurStartCharOffset = pCurStyleRecord->GetStartOffset();
- curEndCharOffset = pCurStyleRecord->GetEndOffset();
- DPRINTF(D_TIMEDTEXT, ("C3GPPTextContainer::BuildSTYL(): [entry %u] range %u, %un", uiCurEntry, uiCurStartCharOffset, curEndCharOffset));
- if (HXR_OK != UpdateLowestPotentialNextTCStartOffset(
- uiCurStartCharOffset, curEndCharOffset,
- /*REF IN/OUT */ uiLowestPotentialNextTCStartOffsetFound,
- /*REF OUT*/ bAssignBoxToCurrent) )
- {
- // ignore, bad data
- DPRINTF(D_TIMEDTEXT, ("C3GPPTextContainer::BuildSTYL(): discardingn"));
- continue;
- }
- if (bAssignBoxToCurrent)
- {
- m_uiTextStyleBoxIndex = uiCurEntry;
- break;
- }
- }
- }
-
-
- if (HX_3GPPTT_INVALID_INDEX == m_uiTextStyleBoxIndex)
- {
- // /All style records are before or after, so
- // ignore entire style modifier:
- HX_DELETE(m_pTextStyleBox);
- }
- bNeedToBreakTCsUpAtNewlines = TRUE;
- }
- else
- {
- HX_ASSERT(false);
- HX_DELETE(m_pTextStyleBox);
- }
- return hr;
- }
- HX_RESULT C3GPPTextContainer::BuildSampleModifiers(BOOL& bNeedToBreakTCsUpAtNewlines)
- {
- DPRINTF(D_TIMEDTEXT, ("C3GPPTextContainer::BuildSampleModifiers()n"));
- bNeedToBreakTCsUpAtNewlines = FALSE;
- HX_ASSERT(m_pTextSample);
- if (!m_pTextSample->GetModifierData())
- {
- // no modifiers; no work to do
- DPRINTF(D_TIMEDTEXT, ("C3GPPTextContainer::BuildSampleModifiers(): no sample modifiersn"));
- return HXR_OK;
- }
-
- HX_RESULT hr = HXR_OK;
- // /Walk the sampleModifier array and find the next start-
- // index boundary that is greater than m_uiStartCharOffset;
- // What we find, if any, is 1 + our end index:
- UINT16 uiLowestPotentialNextTCStartOffsetFound =
- HX_3GPPTT_MAX_CHAR_OFFSET;
- UINT16 curEndCharOffset = HX_3GPPTT_INVALID_INDEX;
-
- const UINT8* pData = m_pTextSample->GetModifierData();
- HX_ASSERT(m_pTextSample->GetModifierDataSize() > 0);
- const UINT8* pDataEnd = pData + m_pTextSample->GetModifierDataSize();
- while (pData < pDataEnd)
- {
- // get sample modifier type and size
- C3GPPTextSampleModifierBox box;
-
- hr = box.Build(pData);
- HX_ASSERT(HXR_OK == hr);
- if(pData + box.GetDataSize() > pDataEnd)
- {
- HX_ASSERT(false);
- hr = HXR_FAIL;
- break;
- }
- // create sample modifier object for this modifier type
- switch(box.GetType())
- {
- case C3GPPTextSampleModifierBox::STYL:
- hr = BuildSTYL(pData,
- uiLowestPotentialNextTCStartOffsetFound,
- bNeedToBreakTCsUpAtNewlines, curEndCharOffset);
- break;
- case C3GPPTextSampleModifierBox::HLIT:
- hr = BuildHLIT(pData,
- uiLowestPotentialNextTCStartOffsetFound,
- bNeedToBreakTCsUpAtNewlines, curEndCharOffset);
- break;
- case C3GPPTextSampleModifierBox::HCLR:
- hr = BuildHCLR(pData);
- break;
- case C3GPPTextSampleModifierBox::KROK:
- hr = BuildKROK(pData,
- uiLowestPotentialNextTCStartOffsetFound,
- bNeedToBreakTCsUpAtNewlines, curEndCharOffset);
- break;
- case C3GPPTextSampleModifierBox::DLAY:
- hr = BuildDLAY(pData);
- break;
- case C3GPPTextSampleModifierBox::HREF:
- hr = BuildHREF(pData,
- uiLowestPotentialNextTCStartOffsetFound,
- bNeedToBreakTCsUpAtNewlines, curEndCharOffset);
- break;
- case C3GPPTextSampleModifierBox::TBOX:
- hr = BuildTBOX(pData);
- break;
- case C3GPPTextSampleModifierBox::BLNK:
- hr = BuildBLNK(pData,
- uiLowestPotentialNextTCStartOffsetFound,
- bNeedToBreakTCsUpAtNewlines, curEndCharOffset);
- break;
- default:
- HX_ASSERT(false); //XXXLCM skip unknown types?
- hr = HXR_FAIL;
- break;
- }
- if(FAILED(hr))
- {
- HX_ASSERT(false);
- break;
- }
-
- // we should consume the box data size exactly
- HX_ASSERT( UINT32(pData - box.GetData()) == box.GetDataSize());
- // /If we found one, then use it if it's lowest so far:
- if (curEndCharOffset <
- uiLowestPotentialNextTCStartOffsetFound &&
- // /Ignore if end is prior to our start:
- // /(Changed '>=' to '>' to prevent infinite loop)
- curEndCharOffset > m_uiUnpackedStartCharOffset)
- {
- uiLowestPotentialNextTCStartOffsetFound =
- curEndCharOffset;
- }
- }
- if(SUCCEEDED(hr))
- {
- // we should always end up exactly at end of data
- HX_ASSERT(pData == pDataEnd);
- // /OK, our end char offset is one less than the lowest start
- // of the next T.C. found, above, (& not less than our start):
- HX_ASSERT(uiLowestPotentialNextTCStartOffsetFound > 0);
- if (HX_3GPPTT_MAX_CHAR_OFFSET !=
- uiLowestPotentialNextTCStartOffsetFound)
- {
- // /Don't add 1 here; it's end-point exclusive:
- m_uiUnpackedEndCharOffset = uiLowestPotentialNextTCStartOffsetFound;
- }
- else
- {
- m_uiUnpackedEndCharOffset = HX_3GPPTT_MAX_CHAR_OFFSET;
- }
- }
- return hr;
-
- }
- HX_RESULT C3GPPTextContainer::Init
- (
- IHXPacket* pPacket,
- UINT32 ulPacketContentsBeginTime,
- UINT32 ulMaxEndTime,
- UINT16 uiStartCharOffset,
- /*OUT*/ UINT16& uiREFIndexOfLastChar)
- {
- HX_RESULT hxr = HXR_OK;
- HX_ASSERT(pPacket);
- m_pPacket = pPacket;
- m_pPacket->AddRef();
- m_ulEndTime = ulMaxEndTime; // /Initialize for now to this
- m_ulBeginTime = ulPacketContentsBeginTime;
- m_uiUnpackedStartCharOffset = uiStartCharOffset;
- uiREFIndexOfLastChar = HX_3GPPTT_INVALID_INDEX;
- BOOL bNeedToBreakTCsUpAtNewlines = FALSE;
-
- // /Go through the textModifiers of the packet and figure out what our
- // end index is in the text buffer based on where the end of same-
- // attributed continguous text ends. Return the end index in
- // uiREFIndexOfLastChar so, if there's any text remaining, another
- // C3GPPTextContainer can be created knowing where to start:
- //-----------------------------------------------------------------------------
- IHXBuffer* pBuff = m_pPacket->GetBuffer();
- if (pBuff)
- {
- BOOL bTextIsUTF16ReverseEncoded = FALSE;
- BOOL bTextIsUTF16Encoded = FALSE;
- m_pTextSample = new C3GPPTextSample(pBuff);
- HX_ASSERT(m_pTextSample);
- if (!m_pTextSample)
- {
- hxr = HXR_OUTOFMEMORY;
- goto cleanup;
- }
- bTextIsUTF16Encoded = IsUTF16Encoded(
- (UCHAR*)(m_pTextSample->GetText()),
- m_pTextSample->GetTextLenInBytes(),
- bTextIsUTF16ReverseEncoded);
- hxr = BuildSampleModifiers(bNeedToBreakTCsUpAtNewlines);
- if(FAILED(hxr))
- {
- goto cleanup;
- }
- // /XXXEH- TODO: this is not UTF-8 friendly code (when 2-byte
- //