Index: core/src/fpdfapi/fpdf_parser/cpdf_simple_parser.cpp |
diff --git a/core/src/fpdfapi/fpdf_parser/cpdf_simple_parser.cpp b/core/src/fpdfapi/fpdf_parser/cpdf_simple_parser.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..ad656795f2fff0558ec1a709304f52476d4885fd |
--- /dev/null |
+++ b/core/src/fpdfapi/fpdf_parser/cpdf_simple_parser.cpp |
@@ -0,0 +1,170 @@ |
+// Copyright 2016 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 "core/include/fpdfapi/cpdf_simple_parser.h" |
+ |
+#include "core/src/fpdfapi/fpdf_parser/fpdf_parser_utility.h" |
+ |
+CPDF_SimpleParser::CPDF_SimpleParser(const uint8_t* pData, FX_DWORD dwSize) |
+ : m_pData(pData), m_dwSize(dwSize), m_dwCurPos(0) {} |
+ |
+CPDF_SimpleParser::CPDF_SimpleParser(const CFX_ByteStringC& str) |
+ : m_pData(str.GetPtr()), m_dwSize(str.GetLength()), m_dwCurPos(0) {} |
+ |
+void CPDF_SimpleParser::ParseWord(const uint8_t*& pStart, FX_DWORD& dwSize) { |
+ pStart = nullptr; |
+ dwSize = 0; |
+ uint8_t ch; |
+ while (1) { |
+ if (m_dwSize <= m_dwCurPos) |
+ return; |
+ ch = m_pData[m_dwCurPos++]; |
+ while (PDFCharIsWhitespace(ch)) { |
+ if (m_dwSize <= m_dwCurPos) |
+ return; |
+ ch = m_pData[m_dwCurPos++]; |
+ } |
+ |
+ if (ch != '%') |
+ break; |
+ |
+ while (1) { |
+ if (m_dwSize <= m_dwCurPos) |
+ return; |
+ ch = m_pData[m_dwCurPos++]; |
+ if (PDFCharIsLineEnding(ch)) |
+ break; |
+ } |
+ } |
+ |
+ FX_DWORD start_pos = m_dwCurPos - 1; |
+ pStart = m_pData + start_pos; |
+ if (PDFCharIsDelimiter(ch)) { |
+ if (ch == '/') { |
+ while (1) { |
+ if (m_dwSize <= m_dwCurPos) |
+ return; |
+ ch = m_pData[m_dwCurPos++]; |
+ if (!PDFCharIsOther(ch) && !PDFCharIsNumeric(ch)) { |
+ m_dwCurPos--; |
+ dwSize = m_dwCurPos - start_pos; |
+ return; |
+ } |
+ } |
+ } else { |
+ dwSize = 1; |
+ if (ch == '<') { |
+ if (m_dwSize <= m_dwCurPos) |
+ return; |
+ ch = m_pData[m_dwCurPos++]; |
+ if (ch == '<') |
+ dwSize = 2; |
+ else |
+ m_dwCurPos--; |
+ } else if (ch == '>') { |
+ if (m_dwSize <= m_dwCurPos) |
+ return; |
+ ch = m_pData[m_dwCurPos++]; |
+ if (ch == '>') |
+ dwSize = 2; |
+ else |
+ m_dwCurPos--; |
+ } |
+ } |
+ return; |
+ } |
+ |
+ dwSize = 1; |
+ while (1) { |
+ if (m_dwSize <= m_dwCurPos) |
+ return; |
+ ch = m_pData[m_dwCurPos++]; |
+ |
+ if (PDFCharIsDelimiter(ch) || PDFCharIsWhitespace(ch)) { |
+ m_dwCurPos--; |
+ break; |
+ } |
+ dwSize++; |
+ } |
+} |
+ |
+CFX_ByteStringC CPDF_SimpleParser::GetWord() { |
+ const uint8_t* pStart; |
+ FX_DWORD dwSize; |
+ ParseWord(pStart, dwSize); |
+ if (dwSize == 1 && pStart[0] == '<') { |
+ while (m_dwCurPos < m_dwSize && m_pData[m_dwCurPos] != '>') { |
+ m_dwCurPos++; |
+ } |
+ if (m_dwCurPos < m_dwSize) { |
+ m_dwCurPos++; |
+ } |
+ return CFX_ByteStringC(pStart, |
+ (FX_STRSIZE)(m_dwCurPos - (pStart - m_pData))); |
+ } |
+ if (dwSize == 1 && pStart[0] == '(') { |
+ int level = 1; |
+ while (m_dwCurPos < m_dwSize) { |
+ if (m_pData[m_dwCurPos] == ')') { |
+ level--; |
+ if (level == 0) { |
+ break; |
+ } |
+ } |
+ if (m_pData[m_dwCurPos] == '\\') { |
+ if (m_dwSize <= m_dwCurPos) { |
+ break; |
+ } |
+ m_dwCurPos++; |
+ } else if (m_pData[m_dwCurPos] == '(') { |
+ level++; |
+ } |
+ if (m_dwSize <= m_dwCurPos) { |
+ break; |
+ } |
+ m_dwCurPos++; |
+ } |
+ if (m_dwCurPos < m_dwSize) { |
+ m_dwCurPos++; |
+ } |
+ return CFX_ByteStringC(pStart, |
+ (FX_STRSIZE)(m_dwCurPos - (pStart - m_pData))); |
+ } |
+ return CFX_ByteStringC(pStart, dwSize); |
+} |
+ |
+bool CPDF_SimpleParser::FindTagParamFromStart(const CFX_ByteStringC& token, |
+ int nParams) { |
+ nParams++; |
+ FX_DWORD* pBuf = FX_Alloc(FX_DWORD, nParams); |
+ int buf_index = 0; |
+ int buf_count = 0; |
+ m_dwCurPos = 0; |
+ while (1) { |
+ pBuf[buf_index++] = m_dwCurPos; |
+ if (buf_index == nParams) { |
+ buf_index = 0; |
+ } |
+ buf_count++; |
+ if (buf_count > nParams) { |
+ buf_count = nParams; |
+ } |
+ CFX_ByteStringC word = GetWord(); |
+ if (word.IsEmpty()) { |
+ FX_Free(pBuf); |
+ return false; |
+ } |
+ if (word == token) { |
+ if (buf_count < nParams) { |
+ continue; |
+ } |
+ m_dwCurPos = pBuf[buf_index]; |
+ FX_Free(pBuf); |
+ return true; |
+ } |
+ } |
+ return false; |
+} |