📄 smlparse.cpp
字号:
char* pTok = strtok(pCoordCopy, ",");
for(i=0;i<4,pTok;++i)
{
char* pEndPtr = 0;
double dVal = strtod(pTok, &pEndPtr);
coordArray[i] = dVal;
percentArray[i] = (*pEndPtr == '%') ? TRUE: FALSE;
pTok = strtok(NULL, ",");
}
delete[] pCoordCopy;
pAnchor->m_ulOriginalLeftX = pAnchor->m_ulLeftX =
(UINT32)coordArray[0];
pAnchor->m_bLeftXIsPercent = percentArray[0];
pAnchor->m_ulOriginalTopY = pAnchor->m_ulTopY =
(UINT32)coordArray[1];
pAnchor->m_bTopYIsPercent = percentArray[1];
pAnchor->m_ulOriginalRightX = pAnchor->m_ulRightX =
(UINT32)coordArray[2];
pAnchor->m_bRightXIsPercent = percentArray[2];
pAnchor->m_ulOriginalBottomY = pAnchor->m_ulBottomY =
(UINT32)coordArray[3];
pAnchor->m_bBottomYIsPercent = percentArray[3];
pAnchor->m_bCoordsSet = TRUE;
return rc;
}
HX_RESULT
CSmil1Parser::parseDuration(const char* pDuration, CSmil1Element* pElement,
SMILSyncAttributeTag nTag)
{
HX_RESULT rc = HXR_OK;
if(!pDuration)
{
return HXR_FAIL;
}
const char* pCh = pDuration;
// check for event-source
// syntax is: id(a)(4s)
if(strncmp(pCh, "id(", 3) == 0)
{
BOOL bParseError = FALSE;
BOOL bHasEvent = TRUE;
UINT32 clockValue = 0;
char* pIdTag = new char[strlen(pDuration)+1];
char* pEvent = new char[strlen(pDuration)+1];
pIdTag[0] = 0;
pEvent[0] = 0;
pCh += 3; // skip over 'id('
int i = 0;
while(*pCh && (*pCh != ')'))
{
pIdTag[i++] = *pCh++;
}
if(*pCh == ')')
{
pIdTag[i] = 0;
// lookup ID to see if it references an existing entity,
// otherwise it is an error
void* pDummy = NULL;
if(!m_pIDMap->Lookup(pIdTag, pDummy))
{
rc = HXR_FAIL;
CSmil1SMILSyntaxErrorHandler errHandler(m_pContext);
errHandler.ReportError(SMILErrorBadDuration, pDuration,
pElement->m_pNode->m_ulTagStartLine);
bParseError = TRUE;
}
else
{
switch(nTag)
{
case SMILSyncAttrBegin:
{
pElement->m_BeginEventSourceID = pIdTag;
}
break;
case SMILSyncAttrEnd:
{
pElement->m_EndEventSourceID = pIdTag;
}
break;
case SMILSyncAttrEndsync:
{
pElement->m_EndsyncEventSourceID = pIdTag;
}
break;
default:
break;
}
}
delete[] pIdTag;
if(strlen(pCh) > 2)
{
if(nTag != SMILSyncAttrEndsync)
{
pCh++; // skip over ')'
pCh++; // skip over '('
i = 0;
while(*pCh && (*pCh != ')'))
{
pEvent[i++] = *pCh++;
}
if(*pCh == ')')
{
pEvent[i] = 0;
}
else
{
bParseError = TRUE;
}
}
else
{
bParseError = TRUE;
}
}
else
{
if(nTag == SMILSyncAttrEndsync)
{
pElement->m_nEndsyncEventSourceTag = SMILEventSourceID;
bHasEvent = FALSE;
}
else
{
bParseError = TRUE;
}
}
}
else
{
bParseError = TRUE;
}
if(bParseError)
{
rc = HXR_FAIL;
CSmil1SMILSyntaxErrorHandler errHandler(m_pContext);
errHandler.ReportError(SMILErrorBadDuration, pDuration,
pElement->m_pNode->m_ulTagStartLine);
}
else if(bHasEvent)
{
SMILEventSourceTag eSourceTag = SMILEventSourceNone;
UINT32 ulEventClockValue = 0;
if(strcmp(pEvent, "begin") == 0)
{
eSourceTag = SMILEventSourceBegin;
}
else if(strcmp(pEvent, "end") == 0)
{
eSourceTag = SMILEventSourceEnd;
}
else
{
if(HXR_OK == parseClockValue(pEvent, ulEventClockValue))
{
eSourceTag = SMILEventSourceClock;
}
else
{
rc = HXR_FAIL;
CSmil1SMILSyntaxErrorHandler errHandler(m_pContext);
errHandler.ReportError(SMILErrorBadDuration, pDuration,
pElement->m_pNode->m_ulTagStartLine);
}
}
switch(nTag)
{
case SMILSyncAttrBegin:
{
pElement->m_nBeginEventSourceTag = eSourceTag;
pElement->m_ulBeginEventClockValue = ulEventClockValue;
}
break;
case SMILSyncAttrEnd:
{
pElement->m_nEndEventSourceTag = eSourceTag;
pElement->m_ulEndEventClockValue = ulEventClockValue;
}
break;
case SMILSyncAttrEndsync:
{
pElement->m_nEndsyncEventSourceTag = eSourceTag;
}
break;
default:
break;
}
}
delete[] pEvent;
}
else if(strcmp(pCh, "first") == 0)
{
if(nTag == SMILSyncAttrEndsync)
{
pElement->m_nEndsyncEventSourceTag = SMILEventSourceFirst;
}
}
else if(strcmp(pCh, "last") == 0)
{
if(nTag == SMILSyncAttrEndsync)
{
pElement->m_nEndsyncEventSourceTag = SMILEventSourceLast;
}
}
else if(strcmp(pCh, "indefinite") == 0)
{
if (pElement->m_pNode->m_tag == SMILSeq ||
pElement->m_pNode->m_tag == SMILPar)
{
rc = HXR_FAIL;
CSmil1SMILSyntaxErrorHandler errHandler(m_pContext);
errHandler.ReportError(SMILErrorIndefiniteNotSupported, NULL,
pElement->m_pNode->m_ulTagStartLine);
}
else
{
pElement->m_bIndefiniteDuration = TRUE;
}
}
else
{
UINT32 ulClockValue = 0;
if(HXR_OK == parseClockValue(pCh, ulClockValue))
{
switch(nTag)
{
case SMILSyncAttrBegin:
{
pElement->m_ulBeginOffset = ulClockValue;
}
break;
case SMILSyncAttrEnd:
{
pElement->m_ulEndOffset = ulClockValue;
}
break;
case SMILSyncAttrDur:
{
pElement->m_ulDuration = ulClockValue;
}
break;
case SMILSyncAttrEndsync:
{
pElement->m_ulEndSync = ulClockValue;
}
break;
case SMILSyncAttrClipBegin:
{
pElement->m_ulClipBegin = ulClockValue;
}
break;
case SMILSyncAttrClipEnd:
{
pElement->m_ulClipEnd = ulClockValue;
}
break;
default:
break;
}
}
else
{
rc = HXR_FAIL;
CSmil1SMILSyntaxErrorHandler errHandler(m_pContext);
errHandler.ReportError(SMILErrorBadDuration, pCh,
pElement->m_pNode->m_ulTagStartLine);
}
}
return rc;
}
HX_RESULT
CSmil1Parser::adjustDuration(CSmil1Element* pElement)
{
HX_RESULT rc = HXR_OK;
// check for duration errors
if(pElement->m_ulEndOffset != (UINT32)-1)
{
if(pElement->m_ulBeginOffset != (UINT32)-1)
{
if(pElement->m_ulEndOffset <
pElement->m_ulBeginOffset)
{
pElement->m_ulDuration = 0;
goto exit;
}
if(pElement->m_ulDuration != (UINT32)-1)
{
if(pElement->m_ulDuration !=
pElement->m_ulEndOffset -
pElement->m_ulBeginOffset)
{
// If the element has both an explicit dur and an explicit
// end, the desired end is the minimum of: the sum of the
// desired begin and the explicit dur; and the explicit end.
// override "dur"
if ( pElement->m_ulBeginOffset + pElement->m_ulDuration >
pElement->m_ulEndOffset )
{
// we want to override the duration, because it is
// greater than the end offset.
pElement->m_ulDuration =
pElement->m_ulEndOffset -
pElement->m_ulBeginOffset;
}
else
{
// else we want to use the current duration,
// and override the end offset.
pElement->m_ulEndOffset = pElement->m_ulBeginOffset
+ pElement->m_ulDuration;
}
goto exit;
}
}
}
else
{
if(pElement->m_ulDuration != (UINT32)-1)
{
if(pElement->m_ulEndOffset >
pElement->m_ulDuration)
{
pElement->m_ulDuration = pElement->m_ulEndOffset;
goto exit;
}
}
}
}
// adjust for begin/end/dur attributes
if(pElement->m_ulDuration == (UINT32)-1) // duration not set
{
if(pElement->m_ulEndOffset != (UINT32)-1)
{
// has an end but no duration
if(pElement->m_ulBeginOffset != (UINT32)-1)
{
pElement->m_ulDuration = pElement->m_ulEndOffset -
pElement->m_ulBeginOffset;
}
else
{
pElement->m_ulDuration = pElement->m_ulEndOffset;
}
}
}
else // explicit duration set
{
if(pElement->m_ulEndOffset != (UINT32)-1)
{
// has a duration and an end
UINT32 ulDur = 0;
if(pElement->m_ulBeginOffset != (UINT32)-1)
{
ulDur = pElement->m_ulEndOffset -
pElement->m_ulBeginOffset;
}
else
{
ulDur = pElement->m_ulEndOffset;
}
pElement->m_ulDuration = ulDur;
}
}
exit:
return rc;
}
UINT8
CSmil1Parser::getColorElement(const char* pColorFrag, int len)
{
UINT8 ucValue = 0;
char* pTmpBuf = new char[len+1];
strncpy(pTmpBuf, pColorFrag, len); /* Flawfinder: ignore */
pTmpBuf[len] = 0;
ucValue = (UINT8)strtol(pTmpBuf, 0, 16);
delete[] pTmpBuf;
return ucValue;
}
HXxColor
CSmil1Parser::parseColor(const char* pColorString)
{
HXxColor theColor = 0;
UINT8 ucRed = 0;
UINT8 ucGreen = 0;
UINT8 ucBlue = 0;
if(pColorString[0] == '#')
{
if(strlen(pColorString) == 4)
{
/* #rgb, duplicate the numbers */
char tmpBuf[6]; /* Flawfinder: ignore */
tmpBuf[0] = tmpBuf[1] = pColorString[1];
tmpBuf[2] = tmpBuf[3] = pColorString[2];
tmpBuf[4] = tmpBuf[5] = pColorString[3];
ucRed = getColorElement(&tmpBuf[0], 2);
ucGreen = getColorElement(&tmpBuf[2], 2);
ucBlue = getColorElement(&tmpBuf[4], 2);
}
else if(strlen(pColorString) == 7)
{
/* #rrggbb */
ucRed = getColorElement(&pColorString[1], 2);
ucGreen = getColorElement(&pColorString[3], 2);
ucBlue = getColorElement(&pColorString[5], 2);
}
}
else
{
// string, try to get it from the color table
int i = 0;
const char* pColorName = Smil1ColorTable[i].m_pColorName;
while(pColorName)
{
if(strcmp(pColorName, pColorString) == 0)
{
ucRed = Smil1ColorTable[i].m_ucRed;
ucBlue = Smil1ColorTable[i].m_ucBlue;
ucGreen = Smil1ColorTable[i].m_ucGreen;
break;
}
pColorName = Smil1ColorTable[++i].m_pColorName;
}
}
#ifdef _WINDOWS
theColor = (HXxColor)(RGB(ucRed, ucGreen, ucBlue));
#else
theColor = (HXxColor)
(ucRed << 16 |
ucGreen << 8 |
ucBlue);
#endif
return theColor;
}
void
CSmil1Parser::badAttributeError(SMIL1NodeTag tag, const char* pAttrName,
UINT32 ulLineNumber, BOOL bJustStore)
{
const char* pTagName = "unknown";
// get tag name from table
int i = 0;
SMIL1NodeTag thisTag = smil1TagTable[i].m_tag;
while(thisTag != SMILUnknown)
{
if(thisTag == tag)
{
pTagName = smil1TagTable[i].m_name;
break;
}
++i;
thisTag = smil1TagTable[i].m_tag;
}
char tmpBuf[256]; /* Flawfinder: ignore */
SafeSprintf(tmpBuf, 256, "<%s>: %s",
pTagName, pAttrName);
if (m_bStoreErrors)
{
storeError(SMILErrorUnrecognizedAttribute, tmpBuf, 0,
ulLineNumber, 0, FALSE);
}
if (!bJustStore)
{
CSmil1SMILSyntaxErrorHandler errHandler(m_pContext);
errHandler.ReportError(SMILErrorUnrecognizedAttribute, tmpBuf, ulLineNumber);
}
}
CSmil1Meta*
CSmil1Parser::makeMeta(SMIL1Node* pNode)
{
CSmil1Meta* pMeta = new CSmil1Meta(pNode);
if(pNode->m_pValues)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -