📄 smlparse.cpp
字号:
const char* pName = 0;
IHXBuffer* pBuf = 0;
HX_RESULT rc = pNode->m_pValues->GetFirstPropertyCString(pName, pBuf);
while(HXR_OK == rc)
{
if(strcmp(pName, "name") == 0)
{
pMeta->m_name = (const char*)pBuf->GetBuffer();
}
else if(strcmp(pName, "content") == 0)
{
pMeta->m_content = (const char*)pBuf->GetBuffer();
}
HX_RELEASE(pBuf);
rc = pNode->m_pValues->GetNextPropertyCString(pName, pBuf);
}
HX_RELEASE(pBuf);
// check for 'base'
if(pMeta->m_name == "base")
{
HX_DELETE(m_pBasePath);
m_pBasePath = new_string((const char*)pMeta->m_content);
HX_RELEASE(pBuf);
}
}
return pMeta;
}
CSmil1RendererPreFetch*
CSmil1Parser::makeRendererPreFetch(SMIL1Node* pNode)
{
CSmil1RendererPreFetch* pRenderer =
new CSmil1RendererPreFetch(pNode);
if(pNode->m_pValues)
{
const char* pName = 0;
IHXBuffer* pBuf = 0;
HX_RESULT rc = pNode->m_pValues->GetFirstPropertyCString(pName, pBuf);
while(HXR_OK == rc)
{
if(strcmp(pName, "type") == 0)
{
pRenderer->m_mimeType = (const char*)pBuf->GetBuffer();
}
rc = pNode->m_pValues->GetNextPropertyCString(pName, pBuf);
}
}
return pRenderer;
}
CSmil1RootLayout*
CSmil1Parser::makeRootLayout(SMIL1Node* pNode)
{
BOOL bHasHeight = FALSE;
BOOL bHasWidth = FALSE;
//[SMIL 1.0 compliance] Fixes PR 22674. SMIL 1.0 documentation states:
// "If a document contains more than one "root-layout" element,
// this is an error, and the document should not be displayed."
if (m_bSMILRootLayoutAlreadyFound && m_bSMIL10FullCompliance)
{
CSmil1SMILSyntaxErrorHandler errHandler(m_pContext);
errHandler.ReportError(SMILErrorUnexpectedTag,
(const char*)pNode->m_name, pNode->m_ulTagStartLine);
return NULL;
}
else if (m_bStoreErrors && m_bSMILRootLayoutAlreadyFound)
{
storeError(SMILErrorUnexpectedTag, pNode->m_name, 0,
pNode->m_ulTagStartLine, 0, FALSE);
}
m_bSMILRootLayoutAlreadyFound = TRUE;
CSmil1RootLayout* pLayout = new CSmil1RootLayout(pNode);
if(pNode->m_pValues)
{
const char* pName = 0;
IHXBuffer* pBuf = 0;
HX_RESULT rc = pNode->m_pValues->GetFirstPropertyCString(pName, pBuf);
while(HXR_OK == rc)
{
//[SMIL 1.0 compliance] Fixes PR 24628. SMIL 1.0
// documentation states in section 3.3.1 that only "length"
// values are allowed in a root-layout height or width;
// percentages are not allowed:
// [SMIL 1.0 compliance] Also fixes PR 25694: don't allow
// ANYTHING other than numeric values with 'px' allowed as
// the only valid units string:
if (m_bSMIL10FullCompliance)
{
if(!strcmp(pName, "height") || !strcmp(pName, "width"))
{
const char* pTmp = (const char*)pBuf->GetBuffer();
UINT32 ulBuflen = pBuf->GetSize();
UINT32 ulCounter = 0L;
BOOL bNumCharFound = FALSE;
BOOL bPxFoundAlready = FALSE;
while (pTmp && *pTmp)
{
//The SMIL 1.0 spec says to use a "length" value as
// defined in the CSS2 spec, except that the "px"
// units are optional. The CSS2 spec can be found
// here:
// http://www.w3.org/TR/REC-CSS2/syndata.html
// with the specific definition found here in that
// page:
// .../syndata.html#value-def-length
// Look for: "[+|-](#*)[.][(#*)][px]"
if (bPxFoundAlready ||
( ('0' > *pTmp || '9' < *pTmp) &&
'.' != *pTmp &&
(bNumCharFound || ('-' != *pTmp &&
'+' != *pTmp)) ) )
{
//If at least one number was found already
// and "px" follows, then this char (*pTmp)
// is not illegal here:
if (!bPxFoundAlready &&
bNumCharFound &&
'p' == *pTmp &&
ulCounter < ulBuflen-1 &&
'x' == *(pTmp+1) )
{
//the first "px" following a number is ok;
bPxFoundAlready = TRUE;
++pTmp; //jump past the 'x'.
}
else
{
CSmil1SMILSyntaxErrorHandler errHandler(
m_pContext);
errHandler.ReportError(SMILErrorBadAttribute,
(const char*)pBuf->GetBuffer(),
pNode->m_ulTagStartLine);
return NULL;
}
}
else if ('.' == *pTmp || '-' == *pTmp ||
'+' == *pTmp)
{
//Valid chars at start, so keep going.
}
else
{
bNumCharFound = TRUE;
}
++pTmp;
++ulCounter;
}
}
}
if(strcmp(pName, "height") == 0)
{
pLayout->m_ulHeight = atol((const char*)pBuf->GetBuffer());
bHasHeight = TRUE;
}
else if(strcmp(pName, "width") == 0)
{
pLayout->m_ulWidth = atol((const char*)pBuf->GetBuffer());
bHasWidth = TRUE;
}
else if(strcmp(pName, "background-color") == 0)
{
UINT32 ulColor = 0;
HX_RESULT rv = HXParseColorUINT32((const char*) pBuf->GetBuffer(),
ulColor);
if (SUCCEEDED(rv))
{
pLayout->m_ulBgColor = ulColor;
}
}
else if(strcmp(pName, "overflow") == 0)
{
pLayout->m_overflow = (const char*)pBuf->GetBuffer();
}
else if(strcmp(pName, "title") == 0)
{
pLayout->m_title = (const char*)pBuf->GetBuffer();
}
else if((strcmp(pName, "id") == 0) ||
(strcmp(pName, "skip-content") == 0))
{
// dont' do anything with these attributes
}
HX_RELEASE(pBuf);
rc = pNode->m_pValues->GetNextPropertyCString(pName, pBuf);
}
}
//[SMIL 1.0 Compliance]: PR 24630:
// height and width are not required in root layout, per the 1.0 spec:
pLayout->m_bHeightUnspecified = !bHasHeight;
pLayout->m_bWidthUnspecified = !bHasWidth;
return pLayout;
}
CSmil1Region*
CSmil1Parser::makeRegion(SMIL1Node* pNode)
{
CSmil1Region* pRegion = new CSmil1Region(pNode);
if(pNode->m_pValues)
{
const char* pName = 0;
IHXBuffer* pBuf = 0;
HX_RESULT rc = pNode->m_pValues->GetFirstPropertyCString(pName, pBuf);
while(HXR_OK == rc)
{
//[SMIL 1.0 compliance] Fixes PR 25697. SMIL 1.0
// documentation states in section 3.3.1 that only percentage and
// "length" values are allowed in a root-layout height or width;
if (m_bSMIL10FullCompliance)
{
if(!strcmp(pName, "height") || !strcmp(pName, "width") ||
!strcmp(pName, "top") || !strcmp(pName, "left"))
{
const char* pTmp = (const char*)pBuf->GetBuffer();
UINT32 ulBuflen = pBuf->GetSize();
UINT32 ulCounter = 0L;
BOOL bNumCharFound = FALSE;
BOOL bPxOrPercentFoundAlready = FALSE;
while (pTmp && *pTmp)
{
//The SMIL 1.0 spec says to use a percentage value
// or a "length" value as defined in the CSS2 spec,
// except that the "px" units are the only ones
// allowed and are optional.
// The CSS2 spec can be found here:
// http://www.w3.org/TR/REC-CSS2/syndata.html
// with the specific definition found here in that
// page:
// .../syndata.html#value-def-length
// Look for: "[+|-](#*)[.][(#*)][px|%]"
if (bPxOrPercentFoundAlready ||
( ('0' > *pTmp || '9' < *pTmp) &&
'.' != *pTmp &&
(bNumCharFound || ('-' != *pTmp &&
'+' != *pTmp)) ) )
{
//If at least one number was found already
// and "px" or "%" follows, then this char
// (*pTmp) is not illegal here:
if (!bPxOrPercentFoundAlready &&
bNumCharFound &&
( '%' == *pTmp ||
('p' == *pTmp &&
ulCounter < ulBuflen-1 &&
'x' == *(pTmp+1))) )
{
//The first "px" or "%" following a number
// is ok;
bPxOrPercentFoundAlready = TRUE;
if ('p' == *pTmp)
{
++pTmp; //jump past the 'x'.
}
}
else
{
CSmil1SMILSyntaxErrorHandler errHandler(
m_pContext);
errHandler.ReportError(SMILErrorBadAttribute,
(const char*)pBuf->GetBuffer(),
pNode->m_ulTagStartLine);
return NULL;
}
}
else if ('.' == *pTmp || '-' == *pTmp ||
'+' == *pTmp)
{
//Valid chars at start, so keep going.
}
else
{
bNumCharFound = TRUE;
}
++pTmp;
++ulCounter;
}
}
}
if(strcmp(pName, "left") == 0)
{
pRegion->m_left = (const char*)pBuf->GetBuffer();
}
else if(strcmp(pName, "top") == 0)
{
pRegion->m_top = (const char*)pBuf->GetBuffer();
}
else if(strcmp(pName, "height") == 0)
{
pRegion->m_height = (const char*)pBuf->GetBuffer();
}
else if(strcmp(pName, "width") == 0)
{
pRegion->m_width = (const char*)pBuf->GetBuffer();
}
else if(strcmp(pName, "fit") == 0)
{
pRegion->m_fit = (const char*)pBuf->GetBuffer();
}
else if(strcmp(pName, "z-index") == 0)
{
pRegion->m_zIndex = atol((const char*)pBuf->GetBuffer());
}
else if(strcmp(pName, "background-color") == 0)
{
const char* pActualColor = (const char*)pBuf->GetBuffer();
if(strcmp(pActualColor, "transparent") == 0)
{
pRegion->m_bBgColorSet = FALSE;
}
else
{
UINT32 ulColor = 0;
HX_RESULT rv = HXParseColorUINT32((const char*) pBuf->GetBuffer(),
ulColor);
if (SUCCEEDED(rv))
{
pRegion->m_ulBgColor = ulColor;
pRegion->m_bBgColorSet = TRUE;
}
}
}
pBuf->Release();
rc = pNode->m_pValues->GetNextPropertyCString(pName, pBuf);
}
}
return pRegion;
}
CSmil1AAnchorElement*
CSmil1Parser::makeAAnchorElement(SMIL1Node* pNode)
{
CSmil1AAnchorElement* pAnchor =
new CSmil1AAnchorElement(pNode);
if(pNode->m_pValues)
{
const char* pName = 0;
IHXBuffer* pBuf = 0;
HX_RESULT rc = pNode->m_pValues->GetFirstPropertyCString(pName, pBuf);
while(HXR_OK == rc)
{
if(strcmp(pName, "href") == 0)
{
pAnchor->m_href = (const char*)pBuf->GetBuffer();
}
else if(strcmp(pName, "show") == 0)
{
pAnchor->m_show = (const char*)pBuf->GetBuffer();
}
pBuf->Release();
rc = pNode->m_pValues->GetNextPropertyCString(pName, pBuf);
}
}
return pAnchor;
}
CSmil1AnchorElement*
CSmil1Parser::makeAnchorElement(SMIL1Node* pNode)
{
CSmil1AnchorElement* pAnchor = new CSmil1AnchorElement(pNode);
if(pNode->m_pValues)
{
const char* pName = 0;
IHXBuffer* pBuf = 0;
HX_RESULT rc = pNode->m_pValues->GetFirstPropertyCString(pName, pBuf);
while(HXR_OK == rc)
{
if(strcmp(pName, "href") == 0)
{
pAnchor->m_href = (const char*)pBuf->GetBuffer();
}
else if(strcmp(pName, "show") == 0)
{
pAnchor->m_show = (const char*)pBuf->GetBuffer();
}
else if(strcmp(pName, "coords") == 0)
{
rc = parseAnchorCoords((const char*)pBuf->GetBuffer(),
pAnchor);
}
else if(strcmp(pName, "fragment-id") == 0)
{
pAnchor->m_fragmentID = (const char*)pBuf->GetBuffer();
}
else if(strcmp(pName, "z-index") == 0)
{
pAnchor->m_zIndex = atol((const char*)pBuf->GetBuffer());
}
else if(strcmp(pName, "begin") == 0)
{
rc = parseDuration((const char*)pBuf->GetBuffer(), pAnchor,
SMILSyncAttrBegin);
if(HXR_OK == rc)
{
pAnchor->m_bTimeValueSet = TRUE;
}
}
else if(strcmp(pName, "end") == 0)
{
rc = parseDuration((const char*)pBuf->GetBuffer(), pAnchor,
SMILSyncAttrEnd);
if(HXR_OK == rc)
{
pAnchor->m_bTimeValueSet = TRUE;
}
}
pBuf->Release();
rc = pNode->m_pValues->GetNextPropertyCString(pName, pBuf);
}
}
return pAnchor;
}
CSmil1Source*
CSmil1Parser::makeSource(SMIL1Node* pNode)
{
HX_RESULT rc = HXR_OK;
CSmil1Source* pSource = new CSmil1Source(pNode);
// assign to a group
if(pNode->m_nGroup == (UINT16)-1)
{
SMIL1Node* pParent = pNode->m_pParent;
while(pParent)
{
if(pParent->m_nGroup != (UINT16)-1)
{
pNode->m_nGroup = pParent->m_nGroup;
break;
}
pParent = pParent->m_pParent;
}
}
if(pNode->m_pValues)
{
const char* pName = 0;
IHXBuffer* pBuf = 0;
rc = pNode->m_pValues->GetFirstPropertyCString(pName, pBuf);
while(HXR_OK == rc)
{
if(strcmp(pName, "src") == 0)
{
CHXString src = (const char*)pBuf->GetBuffer();
// trim leading/trailing spaces
src.TrimRight();
src.TrimLeft();
if(m_pBasePath &&
isRelativeURL(src))
{
pSource->m_src = CHXString(m_pBasePath) + src;
}
else
{
pSource->m_src = src;
}
}
else if(strcmp(pName, "region") == 0)
{
//char szPersistentComponentID[MAX_DISPLAY_NAME] = {0};
//itoa(m_ulPersistentComponentID, szPersistentComponentID, 10);
// append persistent ID to the end of region id
// to make it unique in nested meta
pSource->m_region = (const char*)pBuf->GetBuffer();
//pSource->m_region += "_";
//pSource->m_region += szPersistentComponentID;
}
else if(strcmp(pName, "begin") == 0)
{
rc = parseDuration((const char*)pBuf->GetBuffer(), pSource,
SMILSyncAttrBegin);
}
else if(strcmp(pName, "end") == 0)
{
rc = parseDuration((const char*)pBuf->GetBuffer(), pSource,
SMILSyncAttrEnd);
}
else if(strcmp(pName, "clip-begin") == 0)
{
rc = parseDuration((const char*)pBuf->GetBuffer(), pSource,
SMILSyncAttrClipBegin);
}
else if(strcmp(pName, "clip-end") == 0)
{
rc = parseDuration((const char*)pBuf->GetBuffer(), pSource,
SMILSyncAttrClipEnd);
}
else if(strcmp(pName, "dur") == 0)
{
rc = parseDuration((const char*)pBuf->GetBuffer(), pSource,
SMILSyncAttrDur);
}
else if(strcmp(pName, "fill") == 0)
{
pSource->m_fill = (const char*)pBuf->GetBuffer();
}
else if(strcmp(pName, "title") == 0)
{
pSource->m_title = (const char*)pBuf->GetBuffer();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -