// 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/fpdfapi/fpdf_parser/include/cpdf_simple_parser.h"
|
|
#include "core/fpdfapi/fpdf_parser/fpdf_parser_utility.h"
|
|
CPDF_SimpleParser::CPDF_SimpleParser(const uint8_t* pData, uint32_t dwSize)
|
: m_pData(pData), m_dwSize(dwSize), m_dwCurPos(0) {}
|
|
CPDF_SimpleParser::CPDF_SimpleParser(const CFX_ByteStringC& str)
|
: m_pData(str.raw_str()), m_dwSize(str.GetLength()), m_dwCurPos(0) {}
|
|
void CPDF_SimpleParser::ParseWord(const uint8_t*& pStart, uint32_t& 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;
|
}
|
}
|
|
uint32_t 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;
|
uint32_t 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++;
|
uint32_t* pBuf = FX_Alloc(uint32_t, 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;
|
}
|