Index: xfa/src/fdp/src/css/fde_csssyntax.cpp |
diff --git a/xfa/src/fdp/src/css/fde_csssyntax.cpp b/xfa/src/fdp/src/css/fde_csssyntax.cpp |
index 2cd3d12b64e4f985ab5825fbdf481a597f1acd8c..2308281be5516c8bd5f47083052c087124ff879b 100644 |
--- a/xfa/src/fdp/src/css/fde_csssyntax.cpp |
+++ b/xfa/src/fdp/src/css/fde_csssyntax.cpp |
@@ -1,484 +1,484 @@ |
-// Copyright 2014 PDFium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
- |
-#include "xfa/src/foxitlib.h" |
-#include "fde_csssyntax.h" |
-#include "fde_cssdatatable.h" |
-#ifdef _cplusplus |
-extern "C" { |
-#endif |
-inline FX_BOOL FDE_IsSelectorStart(FX_WCHAR wch) { |
- return wch == '.' || wch == '#' || wch == '*' || (wch >= 'a' && wch <= 'z') || |
- (wch >= 'A' && wch <= 'Z'); |
-} |
-#ifdef _cplusplus |
-}; |
-#endif |
-IFDE_CSSSyntaxParser* IFDE_CSSSyntaxParser::Create() { |
- return new CFDE_CSSSyntaxParser; |
-} |
-CFDE_CSSSyntaxParser::CFDE_CSSSyntaxParser() |
- : m_pStream(NULL), |
- m_iStreamPos(0), |
- m_iPlaneSize(0), |
- m_iTextDatLen(0), |
- m_dwCheck((FX_DWORD)-1), |
- m_eMode(FDE_CSSSYNTAXMODE_RuleSet), |
- m_eStatus(FDE_CSSSYNTAXSTATUS_None) {} |
-CFDE_CSSSyntaxParser::~CFDE_CSSSyntaxParser() { |
- m_TextData.Reset(); |
- m_TextPlane.Reset(); |
-} |
-FX_BOOL CFDE_CSSSyntaxParser::Init(IFX_Stream* pStream, |
- int32_t iCSSPlaneSize, |
- int32_t iTextDataSize, |
- FX_BOOL bOnlyDeclaration) { |
- FXSYS_assert(pStream != NULL && iCSSPlaneSize > 0 && iTextDataSize > 0); |
- Reset(bOnlyDeclaration); |
- if (!m_TextData.EstimateSize(iTextDataSize)) { |
- return FALSE; |
- } |
- uint8_t bom[4]; |
- m_pStream = pStream; |
- m_iStreamPos = m_pStream->GetBOM(bom); |
- m_iPlaneSize = iCSSPlaneSize; |
- return TRUE; |
-} |
-FX_BOOL CFDE_CSSSyntaxParser::Init(const FX_WCHAR* pBuffer, |
- int32_t iBufferSize, |
- int32_t iTextDatSize, |
- FX_BOOL bOnlyDeclaration) { |
- FXSYS_assert(pBuffer != NULL && iBufferSize > 0 && iTextDatSize > 0); |
- Reset(bOnlyDeclaration); |
- if (!m_TextData.EstimateSize(iTextDatSize)) { |
- return FALSE; |
- } |
- return m_TextPlane.AttachBuffer(pBuffer, iBufferSize); |
-} |
-void CFDE_CSSSyntaxParser::Reset(FX_BOOL bOnlyDeclaration) { |
- m_TextPlane.Reset(); |
- m_TextData.Reset(); |
- m_pStream = NULL; |
- m_iStreamPos = 0; |
- m_iTextDatLen = 0; |
- m_dwCheck = (FX_DWORD)-1; |
- m_eStatus = FDE_CSSSYNTAXSTATUS_None; |
- m_eMode = bOnlyDeclaration ? FDE_CSSSYNTAXMODE_PropertyName |
- : FDE_CSSSYNTAXMODE_RuleSet; |
-} |
-FDE_CSSSYNTAXSTATUS CFDE_CSSSyntaxParser::DoSyntaxParse() { |
- while (m_eStatus >= FDE_CSSSYNTAXSTATUS_None) { |
- if (m_TextPlane.IsEOF()) { |
- if (m_pStream == NULL) { |
- if (m_eMode == FDE_CSSSYNTAXMODE_PropertyValue && |
- m_TextData.GetLength() > 0) { |
- SaveTextData(); |
- return m_eStatus = FDE_CSSSYNTAXSTATUS_PropertyValue; |
- } |
- return m_eStatus = FDE_CSSSYNTAXSTATUS_EOS; |
- } |
- FX_BOOL bEOS; |
- int32_t iLen = m_TextPlane.LoadFromStream(m_pStream, m_iStreamPos, |
- m_iPlaneSize, bEOS); |
- m_iStreamPos = m_pStream->GetPosition(); |
- if (iLen < 1) { |
- if (m_eMode == FDE_CSSSYNTAXMODE_PropertyValue && |
- m_TextData.GetLength() > 0) { |
- SaveTextData(); |
- return m_eStatus = FDE_CSSSYNTAXSTATUS_PropertyValue; |
- } |
- return m_eStatus = FDE_CSSSYNTAXSTATUS_EOS; |
- } |
- } |
- FX_WCHAR wch; |
- while (!m_TextPlane.IsEOF()) { |
- wch = m_TextPlane.GetChar(); |
- switch (m_eMode) { |
- case FDE_CSSSYNTAXMODE_RuleSet: |
- switch (wch) { |
- case '@': |
- m_TextPlane.MoveNext(); |
- SwitchMode(FDE_CSSSYNTAXMODE_AtRule); |
- break; |
- case '}': |
- m_TextPlane.MoveNext(); |
- if (RestoreMode()) { |
- return FDE_CSSSYNTAXSTATUS_DeclClose; |
- } else { |
- return m_eStatus = FDE_CSSSYNTAXSTATUS_Error; |
- } |
- break; |
- case '/': |
- if (m_TextPlane.GetNextChar() == '*') { |
- m_ModeStack.Push(m_eMode); |
- SwitchMode(FDE_CSSSYNTAXMODE_Comment); |
- break; |
- } |
- default: |
- if (wch <= ' ') { |
- m_TextPlane.MoveNext(); |
- } else if (FDE_IsSelectorStart(wch)) { |
- SwitchMode(FDE_CSSSYNTAXMODE_Selector); |
- return FDE_CSSSYNTAXSTATUS_StyleRule; |
- } else { |
- return m_eStatus = FDE_CSSSYNTAXSTATUS_Error; |
- } |
- break; |
- } |
- break; |
- case FDE_CSSSYNTAXMODE_Selector: |
- switch (wch) { |
- case ',': |
- m_TextPlane.MoveNext(); |
- SwitchMode(FDE_CSSSYNTAXMODE_Selector); |
- if (m_iTextDatLen > 0) { |
- return FDE_CSSSYNTAXSTATUS_Selector; |
- } |
- break; |
- case '{': |
- if (m_TextData.GetLength() > 0) { |
- SaveTextData(); |
- return FDE_CSSSYNTAXSTATUS_Selector; |
- } else { |
- m_TextPlane.MoveNext(); |
- m_ModeStack.Push(FDE_CSSSYNTAXMODE_RuleSet); |
- SwitchMode(FDE_CSSSYNTAXMODE_PropertyName); |
- return FDE_CSSSYNTAXSTATUS_DeclOpen; |
- } |
- break; |
- case '/': |
- if (m_TextPlane.GetNextChar() == '*') { |
- if (SwitchToComment() > 0) { |
- return FDE_CSSSYNTAXSTATUS_Selector; |
- } |
- break; |
- } |
- default: |
- AppendChar(wch); |
- break; |
- } |
- break; |
- case FDE_CSSSYNTAXMODE_PropertyName: |
- switch (wch) { |
- case ':': |
- m_TextPlane.MoveNext(); |
- SwitchMode(FDE_CSSSYNTAXMODE_PropertyValue); |
- return FDE_CSSSYNTAXSTATUS_PropertyName; |
- case '}': |
- m_TextPlane.MoveNext(); |
- if (RestoreMode()) { |
- return FDE_CSSSYNTAXSTATUS_DeclClose; |
- } else { |
- return m_eStatus = FDE_CSSSYNTAXSTATUS_Error; |
- } |
- break; |
- case '/': |
- if (m_TextPlane.GetNextChar() == '*') { |
- if (SwitchToComment() > 0) { |
- return FDE_CSSSYNTAXSTATUS_PropertyName; |
- } |
- break; |
- } |
- default: |
- AppendChar(wch); |
- break; |
- } |
- break; |
- case FDE_CSSSYNTAXMODE_PropertyValue: |
- switch (wch) { |
- case ';': |
- m_TextPlane.MoveNext(); |
- case '}': |
- SwitchMode(FDE_CSSSYNTAXMODE_PropertyName); |
- return FDE_CSSSYNTAXSTATUS_PropertyValue; |
- case '/': |
- if (m_TextPlane.GetNextChar() == '*') { |
- if (SwitchToComment() > 0) { |
- return FDE_CSSSYNTAXSTATUS_PropertyValue; |
- } |
- break; |
- } |
- default: |
- AppendChar(wch); |
- break; |
- } |
- break; |
- case FDE_CSSSYNTAXMODE_Comment: |
- if (wch == '/' && m_TextData.GetLength() > 0 && |
- m_TextData.GetAt(m_TextData.GetLength() - 1) == '*') { |
- RestoreMode(); |
- } else { |
- m_TextData.AppendChar(wch); |
- } |
- m_TextPlane.MoveNext(); |
- break; |
- case FDE_CSSSYNTAXMODE_MediaType: |
- switch (wch) { |
- case ',': |
- m_TextPlane.MoveNext(); |
- SwitchMode(FDE_CSSSYNTAXMODE_MediaType); |
- if (m_iTextDatLen > 0) { |
- return FDE_CSSSYNTAXSTATUS_MediaType; |
- } |
- break; |
- case '{': { |
- FDE_CSSSYNTAXMODE* pMode = m_ModeStack.GetTopElement(); |
- if (pMode == NULL || *pMode != FDE_CSSSYNTAXMODE_MediaRule) { |
- return m_eStatus = FDE_CSSSYNTAXSTATUS_Error; |
- } |
- if (m_TextData.GetLength() > 0) { |
- SaveTextData(); |
- return FDE_CSSSYNTAXSTATUS_MediaType; |
- } else { |
- m_TextPlane.MoveNext(); |
- *pMode = FDE_CSSSYNTAXMODE_RuleSet; |
- SwitchMode(FDE_CSSSYNTAXMODE_RuleSet); |
- return FDE_CSSSYNTAXSTATUS_DeclOpen; |
- } |
- } break; |
- case ';': { |
- FDE_CSSSYNTAXMODE* pMode = m_ModeStack.GetTopElement(); |
- if (pMode == NULL || *pMode != FDE_CSSSYNTAXMODE_Import) { |
- return m_eStatus = FDE_CSSSYNTAXSTATUS_Error; |
- } |
- if (m_TextData.GetLength() > 0) { |
- SaveTextData(); |
- if (IsImportEnabled()) { |
- return FDE_CSSSYNTAXSTATUS_MediaType; |
- } |
- } else { |
- FX_BOOL bEnabled = IsImportEnabled(); |
- m_TextPlane.MoveNext(); |
- m_ModeStack.Pop(); |
- SwitchMode(FDE_CSSSYNTAXMODE_RuleSet); |
- if (bEnabled) { |
- DisableImport(); |
- return FDE_CSSSYNTAXSTATUS_ImportClose; |
- } |
- } |
- } break; |
- case '/': |
- if (m_TextPlane.GetNextChar() == '*') { |
- if (SwitchToComment() > 0) { |
- return FDE_CSSSYNTAXSTATUS_MediaType; |
- } |
- break; |
- } |
- default: |
- AppendChar(wch); |
- break; |
- } |
- break; |
- case FDE_CSSSYNTAXMODE_URI: { |
- FDE_CSSSYNTAXMODE* pMode = m_ModeStack.GetTopElement(); |
- if (pMode == NULL || *pMode != FDE_CSSSYNTAXMODE_Import) { |
- return m_eStatus = FDE_CSSSYNTAXSTATUS_Error; |
- } |
- if (wch <= ' ' || wch == ';') { |
- int32_t iURIStart, iURILength = m_TextData.GetLength(); |
- if (iURILength > 0 && |
- FDE_ParseCSSURI(m_TextData.GetBuffer(), iURILength, iURIStart, |
- iURILength)) { |
- m_TextData.Subtract(iURIStart, iURILength); |
- SwitchMode(FDE_CSSSYNTAXMODE_MediaType); |
- if (IsImportEnabled()) { |
- return FDE_CSSSYNTAXSTATUS_URI; |
- } else { |
- break; |
- } |
- } |
- } |
- AppendChar(wch); |
- } break; |
- case FDE_CSSSYNTAXMODE_AtRule: |
- if (wch > ' ') { |
- AppendChar(wch); |
- } else { |
- int32_t iLen = m_TextData.GetLength(); |
- const FX_WCHAR* psz = m_TextData.GetBuffer(); |
- if (FXSYS_wcsncmp(L"charset", psz, iLen) == 0) { |
- SwitchMode(FDE_CSSSYNTAXMODE_Charset); |
- } else if (FXSYS_wcsncmp(L"import", psz, iLen) == 0) { |
- m_ModeStack.Push(FDE_CSSSYNTAXMODE_Import); |
- SwitchMode(FDE_CSSSYNTAXMODE_URI); |
- if (IsImportEnabled()) { |
- return FDE_CSSSYNTAXSTATUS_ImportRule; |
- } else { |
- break; |
- } |
- } else if (FXSYS_wcsncmp(L"media", psz, iLen) == 0) { |
- m_ModeStack.Push(FDE_CSSSYNTAXMODE_MediaRule); |
- SwitchMode(FDE_CSSSYNTAXMODE_MediaType); |
- return FDE_CSSSYNTAXSTATUS_MediaRule; |
- } else if (FXSYS_wcsncmp(L"font-face", psz, iLen) == 0) { |
- SwitchMode(FDE_CSSSYNTAXMODE_Selector); |
- return FDE_CSSSYNTAXSTATUS_FontFaceRule; |
- } else if (FXSYS_wcsncmp(L"page", psz, iLen) == 0) { |
- SwitchMode(FDE_CSSSYNTAXMODE_Selector); |
- return FDE_CSSSYNTAXSTATUS_PageRule; |
- } else { |
- SwitchMode(FDE_CSSSYNTAXMODE_UnknownRule); |
- } |
- } |
- break; |
- case FDE_CSSSYNTAXMODE_Charset: |
- if (wch == ';') { |
- m_TextPlane.MoveNext(); |
- SwitchMode(FDE_CSSSYNTAXMODE_RuleSet); |
- if (IsCharsetEnabled()) { |
- DisableCharset(); |
- if (m_iTextDatLen > 0) { |
- if (m_pStream != NULL) { |
- FX_WORD wCodePage = FX_GetCodePageFormStringW( |
- m_TextData.GetBuffer(), m_iTextDatLen); |
- if (wCodePage < 0xFFFF && |
- m_pStream->GetCodePage() != wCodePage) { |
- m_pStream->SetCodePage(wCodePage); |
- } |
- } |
- return FDE_CSSSYNTAXSTATUS_Charset; |
- } |
- } |
- } else { |
- AppendChar(wch); |
- } |
- break; |
- case FDE_CSSSYNTAXMODE_UnknownRule: |
- if (wch == ';') { |
- SwitchMode(FDE_CSSSYNTAXMODE_RuleSet); |
- } |
- m_TextPlane.MoveNext(); |
- break; |
- default: |
- FXSYS_assert(FALSE); |
- break; |
- } |
- } |
- } |
- return m_eStatus; |
-} |
-FX_BOOL CFDE_CSSSyntaxParser::IsImportEnabled() const { |
- if ((m_dwCheck & FDE_CSSSYNTAXCHECK_AllowImport) == 0) { |
- return FALSE; |
- } |
- if (m_ModeStack.GetSize() > 1) { |
- return FALSE; |
- } |
- return TRUE; |
-} |
-inline FX_BOOL CFDE_CSSSyntaxParser::AppendChar(FX_WCHAR wch) { |
- m_TextPlane.MoveNext(); |
- if (m_TextData.GetLength() > 0 || wch > ' ') { |
- m_TextData.AppendChar(wch); |
- return TRUE; |
- } |
- return FALSE; |
-} |
-inline int32_t CFDE_CSSSyntaxParser::SaveTextData() { |
- m_iTextDatLen = m_TextData.TrimEnd(); |
- m_TextData.Clear(); |
- return m_iTextDatLen; |
-} |
-inline void CFDE_CSSSyntaxParser::SwitchMode(FDE_CSSSYNTAXMODE eMode) { |
- m_eMode = eMode; |
- SaveTextData(); |
-} |
-inline int32_t CFDE_CSSSyntaxParser::SwitchToComment() { |
- int32_t iLength = m_TextData.GetLength(); |
- m_ModeStack.Push(m_eMode); |
- SwitchMode(FDE_CSSSYNTAXMODE_Comment); |
- return iLength; |
-} |
-inline FX_BOOL CFDE_CSSSyntaxParser::RestoreMode() { |
- FDE_CSSSYNTAXMODE* pMode = m_ModeStack.GetTopElement(); |
- if (pMode == NULL) { |
- return FALSE; |
- } |
- SwitchMode(*pMode); |
- m_ModeStack.Pop(); |
- return TRUE; |
-} |
-const FX_WCHAR* CFDE_CSSSyntaxParser::GetCurrentString(int32_t& iLength) const { |
- iLength = m_iTextDatLen; |
- return m_TextData.GetBuffer(); |
-} |
-CFDE_CSSTextBuf::CFDE_CSSTextBuf() |
- : m_bExtBuf(FALSE), |
- m_pBuffer(NULL), |
- m_iBufLen(0), |
- m_iDatLen(0), |
- m_iDatPos(0) {} |
-CFDE_CSSTextBuf::~CFDE_CSSTextBuf() { |
- Reset(); |
-} |
-void CFDE_CSSTextBuf::Reset() { |
- if (!m_bExtBuf) { |
- FX_Free(m_pBuffer); |
- m_pBuffer = NULL; |
- } |
- m_iDatPos = m_iDatLen = m_iBufLen; |
-} |
-FX_BOOL CFDE_CSSTextBuf::AttachBuffer(const FX_WCHAR* pBuffer, |
- int32_t iBufLen) { |
- Reset(); |
- m_pBuffer = (FX_WCHAR*)pBuffer; |
- m_iDatLen = m_iBufLen = iBufLen; |
- return m_bExtBuf = TRUE; |
-} |
-FX_BOOL CFDE_CSSTextBuf::EstimateSize(int32_t iAllocSize) { |
- FXSYS_assert(iAllocSize > 0); |
- Clear(); |
- m_bExtBuf = FALSE; |
- return ExpandBuf(iAllocSize); |
-} |
-int32_t CFDE_CSSTextBuf::LoadFromStream(IFX_Stream* pTxtStream, |
- int32_t iStreamOffset, |
- int32_t iMaxChars, |
- FX_BOOL& bEOS) { |
- FXSYS_assert(iStreamOffset >= 0 && iMaxChars > 0); |
- Clear(); |
- m_bExtBuf = FALSE; |
- if (!ExpandBuf(iMaxChars)) { |
- return 0; |
- } |
- pTxtStream->Lock(); |
- if (pTxtStream->GetPosition() != iStreamOffset) { |
- pTxtStream->Seek(FX_STREAMSEEK_Begin, iStreamOffset); |
- } |
- m_iDatLen = pTxtStream->ReadString(m_pBuffer, iMaxChars, bEOS); |
- pTxtStream->Unlock(); |
- return m_iDatLen; |
-} |
-FX_BOOL CFDE_CSSTextBuf::ExpandBuf(int32_t iDesiredSize) { |
- if (m_bExtBuf) { |
- return FALSE; |
- } |
- if (!m_pBuffer) { |
- m_pBuffer = FX_Alloc(FX_WCHAR, iDesiredSize); |
- } else if (m_iBufLen != iDesiredSize) { |
- m_pBuffer = FX_Realloc(FX_WCHAR, m_pBuffer, iDesiredSize); |
- } else { |
- return TRUE; |
- } |
- if (!m_pBuffer) { |
- m_iBufLen = 0; |
- return FALSE; |
- } |
- m_iBufLen = iDesiredSize; |
- return TRUE; |
-} |
-void CFDE_CSSTextBuf::Subtract(int32_t iStart, int32_t iLength) { |
- FXSYS_assert(iStart >= 0 && iLength > 0); |
- if (iLength > m_iDatLen - iStart) { |
- iLength = m_iDatLen - iStart; |
- } |
- if (iLength < 0) { |
- iLength = 0; |
- } else { |
- FXSYS_memmove(m_pBuffer, m_pBuffer + iStart, iLength * sizeof(FX_WCHAR)); |
- } |
- m_iDatLen = iLength; |
-} |
+// Copyright 2014 PDFium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
+ |
+#include "xfa/src/foxitlib.h" |
+#include "fde_csssyntax.h" |
+#include "fde_cssdatatable.h" |
+#ifdef _cplusplus |
+extern "C" { |
+#endif |
+inline FX_BOOL FDE_IsSelectorStart(FX_WCHAR wch) { |
+ return wch == '.' || wch == '#' || wch == '*' || (wch >= 'a' && wch <= 'z') || |
+ (wch >= 'A' && wch <= 'Z'); |
+} |
+#ifdef _cplusplus |
+}; |
+#endif |
+IFDE_CSSSyntaxParser* IFDE_CSSSyntaxParser::Create() { |
+ return new CFDE_CSSSyntaxParser; |
+} |
+CFDE_CSSSyntaxParser::CFDE_CSSSyntaxParser() |
+ : m_pStream(NULL), |
+ m_iStreamPos(0), |
+ m_iPlaneSize(0), |
+ m_iTextDatLen(0), |
+ m_dwCheck((FX_DWORD)-1), |
+ m_eMode(FDE_CSSSYNTAXMODE_RuleSet), |
+ m_eStatus(FDE_CSSSYNTAXSTATUS_None) {} |
+CFDE_CSSSyntaxParser::~CFDE_CSSSyntaxParser() { |
+ m_TextData.Reset(); |
+ m_TextPlane.Reset(); |
+} |
+FX_BOOL CFDE_CSSSyntaxParser::Init(IFX_Stream* pStream, |
+ int32_t iCSSPlaneSize, |
+ int32_t iTextDataSize, |
+ FX_BOOL bOnlyDeclaration) { |
+ FXSYS_assert(pStream != NULL && iCSSPlaneSize > 0 && iTextDataSize > 0); |
+ Reset(bOnlyDeclaration); |
+ if (!m_TextData.EstimateSize(iTextDataSize)) { |
+ return FALSE; |
+ } |
+ uint8_t bom[4]; |
+ m_pStream = pStream; |
+ m_iStreamPos = m_pStream->GetBOM(bom); |
+ m_iPlaneSize = iCSSPlaneSize; |
+ return TRUE; |
+} |
+FX_BOOL CFDE_CSSSyntaxParser::Init(const FX_WCHAR* pBuffer, |
+ int32_t iBufferSize, |
+ int32_t iTextDatSize, |
+ FX_BOOL bOnlyDeclaration) { |
+ FXSYS_assert(pBuffer != NULL && iBufferSize > 0 && iTextDatSize > 0); |
+ Reset(bOnlyDeclaration); |
+ if (!m_TextData.EstimateSize(iTextDatSize)) { |
+ return FALSE; |
+ } |
+ return m_TextPlane.AttachBuffer(pBuffer, iBufferSize); |
+} |
+void CFDE_CSSSyntaxParser::Reset(FX_BOOL bOnlyDeclaration) { |
+ m_TextPlane.Reset(); |
+ m_TextData.Reset(); |
+ m_pStream = NULL; |
+ m_iStreamPos = 0; |
+ m_iTextDatLen = 0; |
+ m_dwCheck = (FX_DWORD)-1; |
+ m_eStatus = FDE_CSSSYNTAXSTATUS_None; |
+ m_eMode = bOnlyDeclaration ? FDE_CSSSYNTAXMODE_PropertyName |
+ : FDE_CSSSYNTAXMODE_RuleSet; |
+} |
+FDE_CSSSYNTAXSTATUS CFDE_CSSSyntaxParser::DoSyntaxParse() { |
+ while (m_eStatus >= FDE_CSSSYNTAXSTATUS_None) { |
+ if (m_TextPlane.IsEOF()) { |
+ if (m_pStream == NULL) { |
+ if (m_eMode == FDE_CSSSYNTAXMODE_PropertyValue && |
+ m_TextData.GetLength() > 0) { |
+ SaveTextData(); |
+ return m_eStatus = FDE_CSSSYNTAXSTATUS_PropertyValue; |
+ } |
+ return m_eStatus = FDE_CSSSYNTAXSTATUS_EOS; |
+ } |
+ FX_BOOL bEOS; |
+ int32_t iLen = m_TextPlane.LoadFromStream(m_pStream, m_iStreamPos, |
+ m_iPlaneSize, bEOS); |
+ m_iStreamPos = m_pStream->GetPosition(); |
+ if (iLen < 1) { |
+ if (m_eMode == FDE_CSSSYNTAXMODE_PropertyValue && |
+ m_TextData.GetLength() > 0) { |
+ SaveTextData(); |
+ return m_eStatus = FDE_CSSSYNTAXSTATUS_PropertyValue; |
+ } |
+ return m_eStatus = FDE_CSSSYNTAXSTATUS_EOS; |
+ } |
+ } |
+ FX_WCHAR wch; |
+ while (!m_TextPlane.IsEOF()) { |
+ wch = m_TextPlane.GetChar(); |
+ switch (m_eMode) { |
+ case FDE_CSSSYNTAXMODE_RuleSet: |
+ switch (wch) { |
+ case '@': |
+ m_TextPlane.MoveNext(); |
+ SwitchMode(FDE_CSSSYNTAXMODE_AtRule); |
+ break; |
+ case '}': |
+ m_TextPlane.MoveNext(); |
+ if (RestoreMode()) { |
+ return FDE_CSSSYNTAXSTATUS_DeclClose; |
+ } else { |
+ return m_eStatus = FDE_CSSSYNTAXSTATUS_Error; |
+ } |
+ break; |
+ case '/': |
+ if (m_TextPlane.GetNextChar() == '*') { |
+ m_ModeStack.Push(m_eMode); |
+ SwitchMode(FDE_CSSSYNTAXMODE_Comment); |
+ break; |
+ } |
+ default: |
+ if (wch <= ' ') { |
+ m_TextPlane.MoveNext(); |
+ } else if (FDE_IsSelectorStart(wch)) { |
+ SwitchMode(FDE_CSSSYNTAXMODE_Selector); |
+ return FDE_CSSSYNTAXSTATUS_StyleRule; |
+ } else { |
+ return m_eStatus = FDE_CSSSYNTAXSTATUS_Error; |
+ } |
+ break; |
+ } |
+ break; |
+ case FDE_CSSSYNTAXMODE_Selector: |
+ switch (wch) { |
+ case ',': |
+ m_TextPlane.MoveNext(); |
+ SwitchMode(FDE_CSSSYNTAXMODE_Selector); |
+ if (m_iTextDatLen > 0) { |
+ return FDE_CSSSYNTAXSTATUS_Selector; |
+ } |
+ break; |
+ case '{': |
+ if (m_TextData.GetLength() > 0) { |
+ SaveTextData(); |
+ return FDE_CSSSYNTAXSTATUS_Selector; |
+ } else { |
+ m_TextPlane.MoveNext(); |
+ m_ModeStack.Push(FDE_CSSSYNTAXMODE_RuleSet); |
+ SwitchMode(FDE_CSSSYNTAXMODE_PropertyName); |
+ return FDE_CSSSYNTAXSTATUS_DeclOpen; |
+ } |
+ break; |
+ case '/': |
+ if (m_TextPlane.GetNextChar() == '*') { |
+ if (SwitchToComment() > 0) { |
+ return FDE_CSSSYNTAXSTATUS_Selector; |
+ } |
+ break; |
+ } |
+ default: |
+ AppendChar(wch); |
+ break; |
+ } |
+ break; |
+ case FDE_CSSSYNTAXMODE_PropertyName: |
+ switch (wch) { |
+ case ':': |
+ m_TextPlane.MoveNext(); |
+ SwitchMode(FDE_CSSSYNTAXMODE_PropertyValue); |
+ return FDE_CSSSYNTAXSTATUS_PropertyName; |
+ case '}': |
+ m_TextPlane.MoveNext(); |
+ if (RestoreMode()) { |
+ return FDE_CSSSYNTAXSTATUS_DeclClose; |
+ } else { |
+ return m_eStatus = FDE_CSSSYNTAXSTATUS_Error; |
+ } |
+ break; |
+ case '/': |
+ if (m_TextPlane.GetNextChar() == '*') { |
+ if (SwitchToComment() > 0) { |
+ return FDE_CSSSYNTAXSTATUS_PropertyName; |
+ } |
+ break; |
+ } |
+ default: |
+ AppendChar(wch); |
+ break; |
+ } |
+ break; |
+ case FDE_CSSSYNTAXMODE_PropertyValue: |
+ switch (wch) { |
+ case ';': |
+ m_TextPlane.MoveNext(); |
+ case '}': |
+ SwitchMode(FDE_CSSSYNTAXMODE_PropertyName); |
+ return FDE_CSSSYNTAXSTATUS_PropertyValue; |
+ case '/': |
+ if (m_TextPlane.GetNextChar() == '*') { |
+ if (SwitchToComment() > 0) { |
+ return FDE_CSSSYNTAXSTATUS_PropertyValue; |
+ } |
+ break; |
+ } |
+ default: |
+ AppendChar(wch); |
+ break; |
+ } |
+ break; |
+ case FDE_CSSSYNTAXMODE_Comment: |
+ if (wch == '/' && m_TextData.GetLength() > 0 && |
+ m_TextData.GetAt(m_TextData.GetLength() - 1) == '*') { |
+ RestoreMode(); |
+ } else { |
+ m_TextData.AppendChar(wch); |
+ } |
+ m_TextPlane.MoveNext(); |
+ break; |
+ case FDE_CSSSYNTAXMODE_MediaType: |
+ switch (wch) { |
+ case ',': |
+ m_TextPlane.MoveNext(); |
+ SwitchMode(FDE_CSSSYNTAXMODE_MediaType); |
+ if (m_iTextDatLen > 0) { |
+ return FDE_CSSSYNTAXSTATUS_MediaType; |
+ } |
+ break; |
+ case '{': { |
+ FDE_CSSSYNTAXMODE* pMode = m_ModeStack.GetTopElement(); |
+ if (pMode == NULL || *pMode != FDE_CSSSYNTAXMODE_MediaRule) { |
+ return m_eStatus = FDE_CSSSYNTAXSTATUS_Error; |
+ } |
+ if (m_TextData.GetLength() > 0) { |
+ SaveTextData(); |
+ return FDE_CSSSYNTAXSTATUS_MediaType; |
+ } else { |
+ m_TextPlane.MoveNext(); |
+ *pMode = FDE_CSSSYNTAXMODE_RuleSet; |
+ SwitchMode(FDE_CSSSYNTAXMODE_RuleSet); |
+ return FDE_CSSSYNTAXSTATUS_DeclOpen; |
+ } |
+ } break; |
+ case ';': { |
+ FDE_CSSSYNTAXMODE* pMode = m_ModeStack.GetTopElement(); |
+ if (pMode == NULL || *pMode != FDE_CSSSYNTAXMODE_Import) { |
+ return m_eStatus = FDE_CSSSYNTAXSTATUS_Error; |
+ } |
+ if (m_TextData.GetLength() > 0) { |
+ SaveTextData(); |
+ if (IsImportEnabled()) { |
+ return FDE_CSSSYNTAXSTATUS_MediaType; |
+ } |
+ } else { |
+ FX_BOOL bEnabled = IsImportEnabled(); |
+ m_TextPlane.MoveNext(); |
+ m_ModeStack.Pop(); |
+ SwitchMode(FDE_CSSSYNTAXMODE_RuleSet); |
+ if (bEnabled) { |
+ DisableImport(); |
+ return FDE_CSSSYNTAXSTATUS_ImportClose; |
+ } |
+ } |
+ } break; |
+ case '/': |
+ if (m_TextPlane.GetNextChar() == '*') { |
+ if (SwitchToComment() > 0) { |
+ return FDE_CSSSYNTAXSTATUS_MediaType; |
+ } |
+ break; |
+ } |
+ default: |
+ AppendChar(wch); |
+ break; |
+ } |
+ break; |
+ case FDE_CSSSYNTAXMODE_URI: { |
+ FDE_CSSSYNTAXMODE* pMode = m_ModeStack.GetTopElement(); |
+ if (pMode == NULL || *pMode != FDE_CSSSYNTAXMODE_Import) { |
+ return m_eStatus = FDE_CSSSYNTAXSTATUS_Error; |
+ } |
+ if (wch <= ' ' || wch == ';') { |
+ int32_t iURIStart, iURILength = m_TextData.GetLength(); |
+ if (iURILength > 0 && |
+ FDE_ParseCSSURI(m_TextData.GetBuffer(), iURILength, iURIStart, |
+ iURILength)) { |
+ m_TextData.Subtract(iURIStart, iURILength); |
+ SwitchMode(FDE_CSSSYNTAXMODE_MediaType); |
+ if (IsImportEnabled()) { |
+ return FDE_CSSSYNTAXSTATUS_URI; |
+ } else { |
+ break; |
+ } |
+ } |
+ } |
+ AppendChar(wch); |
+ } break; |
+ case FDE_CSSSYNTAXMODE_AtRule: |
+ if (wch > ' ') { |
+ AppendChar(wch); |
+ } else { |
+ int32_t iLen = m_TextData.GetLength(); |
+ const FX_WCHAR* psz = m_TextData.GetBuffer(); |
+ if (FXSYS_wcsncmp(L"charset", psz, iLen) == 0) { |
+ SwitchMode(FDE_CSSSYNTAXMODE_Charset); |
+ } else if (FXSYS_wcsncmp(L"import", psz, iLen) == 0) { |
+ m_ModeStack.Push(FDE_CSSSYNTAXMODE_Import); |
+ SwitchMode(FDE_CSSSYNTAXMODE_URI); |
+ if (IsImportEnabled()) { |
+ return FDE_CSSSYNTAXSTATUS_ImportRule; |
+ } else { |
+ break; |
+ } |
+ } else if (FXSYS_wcsncmp(L"media", psz, iLen) == 0) { |
+ m_ModeStack.Push(FDE_CSSSYNTAXMODE_MediaRule); |
+ SwitchMode(FDE_CSSSYNTAXMODE_MediaType); |
+ return FDE_CSSSYNTAXSTATUS_MediaRule; |
+ } else if (FXSYS_wcsncmp(L"font-face", psz, iLen) == 0) { |
+ SwitchMode(FDE_CSSSYNTAXMODE_Selector); |
+ return FDE_CSSSYNTAXSTATUS_FontFaceRule; |
+ } else if (FXSYS_wcsncmp(L"page", psz, iLen) == 0) { |
+ SwitchMode(FDE_CSSSYNTAXMODE_Selector); |
+ return FDE_CSSSYNTAXSTATUS_PageRule; |
+ } else { |
+ SwitchMode(FDE_CSSSYNTAXMODE_UnknownRule); |
+ } |
+ } |
+ break; |
+ case FDE_CSSSYNTAXMODE_Charset: |
+ if (wch == ';') { |
+ m_TextPlane.MoveNext(); |
+ SwitchMode(FDE_CSSSYNTAXMODE_RuleSet); |
+ if (IsCharsetEnabled()) { |
+ DisableCharset(); |
+ if (m_iTextDatLen > 0) { |
+ if (m_pStream != NULL) { |
+ FX_WORD wCodePage = FX_GetCodePageFormStringW( |
+ m_TextData.GetBuffer(), m_iTextDatLen); |
+ if (wCodePage < 0xFFFF && |
+ m_pStream->GetCodePage() != wCodePage) { |
+ m_pStream->SetCodePage(wCodePage); |
+ } |
+ } |
+ return FDE_CSSSYNTAXSTATUS_Charset; |
+ } |
+ } |
+ } else { |
+ AppendChar(wch); |
+ } |
+ break; |
+ case FDE_CSSSYNTAXMODE_UnknownRule: |
+ if (wch == ';') { |
+ SwitchMode(FDE_CSSSYNTAXMODE_RuleSet); |
+ } |
+ m_TextPlane.MoveNext(); |
+ break; |
+ default: |
+ FXSYS_assert(FALSE); |
+ break; |
+ } |
+ } |
+ } |
+ return m_eStatus; |
+} |
+FX_BOOL CFDE_CSSSyntaxParser::IsImportEnabled() const { |
+ if ((m_dwCheck & FDE_CSSSYNTAXCHECK_AllowImport) == 0) { |
+ return FALSE; |
+ } |
+ if (m_ModeStack.GetSize() > 1) { |
+ return FALSE; |
+ } |
+ return TRUE; |
+} |
+inline FX_BOOL CFDE_CSSSyntaxParser::AppendChar(FX_WCHAR wch) { |
+ m_TextPlane.MoveNext(); |
+ if (m_TextData.GetLength() > 0 || wch > ' ') { |
+ m_TextData.AppendChar(wch); |
+ return TRUE; |
+ } |
+ return FALSE; |
+} |
+inline int32_t CFDE_CSSSyntaxParser::SaveTextData() { |
+ m_iTextDatLen = m_TextData.TrimEnd(); |
+ m_TextData.Clear(); |
+ return m_iTextDatLen; |
+} |
+inline void CFDE_CSSSyntaxParser::SwitchMode(FDE_CSSSYNTAXMODE eMode) { |
+ m_eMode = eMode; |
+ SaveTextData(); |
+} |
+inline int32_t CFDE_CSSSyntaxParser::SwitchToComment() { |
+ int32_t iLength = m_TextData.GetLength(); |
+ m_ModeStack.Push(m_eMode); |
+ SwitchMode(FDE_CSSSYNTAXMODE_Comment); |
+ return iLength; |
+} |
+inline FX_BOOL CFDE_CSSSyntaxParser::RestoreMode() { |
+ FDE_CSSSYNTAXMODE* pMode = m_ModeStack.GetTopElement(); |
+ if (pMode == NULL) { |
+ return FALSE; |
+ } |
+ SwitchMode(*pMode); |
+ m_ModeStack.Pop(); |
+ return TRUE; |
+} |
+const FX_WCHAR* CFDE_CSSSyntaxParser::GetCurrentString(int32_t& iLength) const { |
+ iLength = m_iTextDatLen; |
+ return m_TextData.GetBuffer(); |
+} |
+CFDE_CSSTextBuf::CFDE_CSSTextBuf() |
+ : m_bExtBuf(FALSE), |
+ m_pBuffer(NULL), |
+ m_iBufLen(0), |
+ m_iDatLen(0), |
+ m_iDatPos(0) {} |
+CFDE_CSSTextBuf::~CFDE_CSSTextBuf() { |
+ Reset(); |
+} |
+void CFDE_CSSTextBuf::Reset() { |
+ if (!m_bExtBuf) { |
+ FX_Free(m_pBuffer); |
+ m_pBuffer = NULL; |
+ } |
+ m_iDatPos = m_iDatLen = m_iBufLen; |
+} |
+FX_BOOL CFDE_CSSTextBuf::AttachBuffer(const FX_WCHAR* pBuffer, |
+ int32_t iBufLen) { |
+ Reset(); |
+ m_pBuffer = (FX_WCHAR*)pBuffer; |
+ m_iDatLen = m_iBufLen = iBufLen; |
+ return m_bExtBuf = TRUE; |
+} |
+FX_BOOL CFDE_CSSTextBuf::EstimateSize(int32_t iAllocSize) { |
+ FXSYS_assert(iAllocSize > 0); |
+ Clear(); |
+ m_bExtBuf = FALSE; |
+ return ExpandBuf(iAllocSize); |
+} |
+int32_t CFDE_CSSTextBuf::LoadFromStream(IFX_Stream* pTxtStream, |
+ int32_t iStreamOffset, |
+ int32_t iMaxChars, |
+ FX_BOOL& bEOS) { |
+ FXSYS_assert(iStreamOffset >= 0 && iMaxChars > 0); |
+ Clear(); |
+ m_bExtBuf = FALSE; |
+ if (!ExpandBuf(iMaxChars)) { |
+ return 0; |
+ } |
+ pTxtStream->Lock(); |
+ if (pTxtStream->GetPosition() != iStreamOffset) { |
+ pTxtStream->Seek(FX_STREAMSEEK_Begin, iStreamOffset); |
+ } |
+ m_iDatLen = pTxtStream->ReadString(m_pBuffer, iMaxChars, bEOS); |
+ pTxtStream->Unlock(); |
+ return m_iDatLen; |
+} |
+FX_BOOL CFDE_CSSTextBuf::ExpandBuf(int32_t iDesiredSize) { |
+ if (m_bExtBuf) { |
+ return FALSE; |
+ } |
+ if (!m_pBuffer) { |
+ m_pBuffer = FX_Alloc(FX_WCHAR, iDesiredSize); |
+ } else if (m_iBufLen != iDesiredSize) { |
+ m_pBuffer = FX_Realloc(FX_WCHAR, m_pBuffer, iDesiredSize); |
+ } else { |
+ return TRUE; |
+ } |
+ if (!m_pBuffer) { |
+ m_iBufLen = 0; |
+ return FALSE; |
+ } |
+ m_iBufLen = iDesiredSize; |
+ return TRUE; |
+} |
+void CFDE_CSSTextBuf::Subtract(int32_t iStart, int32_t iLength) { |
+ FXSYS_assert(iStart >= 0 && iLength > 0); |
+ if (iLength > m_iDatLen - iStart) { |
+ iLength = m_iDatLen - iStart; |
+ } |
+ if (iLength < 0) { |
+ iLength = 0; |
+ } else { |
+ FXSYS_memmove(m_pBuffer, m_pBuffer + iStart, iLength * sizeof(FX_WCHAR)); |
+ } |
+ m_iDatLen = iLength; |
+} |