std::unique_ptr<CPDF_Object> CPDF_DataAvail::ParseIndirectObjectAt( FX_FILESIZE pos, uint32_t objnum, CPDF_IndirectObjectHolder* pObjList) { FX_FILESIZE SavedPos = m_syntaxParser.SavePos(); m_syntaxParser.RestorePos(pos); bool bIsNumber; CFX_ByteString word = m_syntaxParser.GetNextWord(&bIsNumber); if (!bIsNumber) return nullptr; uint32_t parser_objnum = FXSYS_atoui(word.c_str()); if (objnum && parser_objnum != objnum) return nullptr; word = m_syntaxParser.GetNextWord(&bIsNumber); if (!bIsNumber) return nullptr; uint32_t gennum = FXSYS_atoui(word.c_str()); if (m_syntaxParser.GetKeyword() != "obj") { m_syntaxParser.RestorePos(SavedPos); return nullptr; } std::unique_ptr<CPDF_Object> pObj = m_syntaxParser.GetObject(pObjList, parser_objnum, gennum, true); m_syntaxParser.RestorePos(SavedPos); return pObj; }
bool CPDF_DataAvail::IsLinearizedFile(uint8_t* pData, uint32_t dwLen) { if (m_pLinearized) return true; ScopedFileStream file(FX_CreateMemoryStream(pData, (size_t)dwLen, false)); int32_t offset = GetHeaderOffset(file.get()); if (offset == -1) { m_docStatus = PDF_DATAAVAIL_ERROR; return false; } m_dwHeaderOffset = offset; m_syntaxParser.InitParser(file.get(), offset); m_syntaxParser.RestorePos(m_syntaxParser.m_HeaderOffset + 9); bool bNumber; CFX_ByteString wordObjNum = m_syntaxParser.GetNextWord(&bNumber); if (!bNumber) return false; uint32_t objnum = FXSYS_atoui(wordObjNum.c_str()); m_pLinearized = CPDF_LinearizedHeader::CreateForObject( ParseIndirectObjectAt(m_syntaxParser.m_HeaderOffset + 9, objnum)); if (!m_pLinearized || m_pLinearized->GetFileSize() != m_pFileRead->GetSize()) { m_pLinearized.reset(); return false; } return true; }
int32_t CPDF_DataAvail::CheckCrossRefStream(DownloadHints* pHints, FX_FILESIZE& xref_offset) { xref_offset = 0; uint32_t req_size = (uint32_t)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512); if (m_pFileAvail->IsDataAvail(m_Pos, req_size)) { int32_t iSize = (int32_t)(m_Pos + req_size - m_dwCurrentXRefSteam); CFX_BinaryBuf buf(iSize); uint8_t* pBuf = buf.GetBuffer(); m_pFileRead->ReadBlock(pBuf, m_dwCurrentXRefSteam, iSize); ScopedFileStream file(FX_CreateMemoryStream(pBuf, (size_t)iSize, false)); m_parser.m_pSyntax->InitParser(file.get(), 0); bool bNumber; CFX_ByteString objnum = m_parser.m_pSyntax->GetNextWord(&bNumber); if (!bNumber) return -1; uint32_t objNum = FXSYS_atoui(objnum.c_str()); std::unique_ptr<CPDF_Object> pObj = m_parser.ParseIndirectObjectAt(nullptr, 0, objNum); if (!pObj) { m_Pos += m_parser.m_pSyntax->SavePos(); return 0; } CPDF_Dictionary* pDict = pObj->GetDict(); CPDF_Name* pName = ToName(pDict ? pDict->GetObjectFor("Type") : nullptr); if (pName && pName->GetString() == "XRef") { m_Pos += m_parser.m_pSyntax->SavePos(); xref_offset = pObj->GetDict()->GetIntegerFor("Prev"); return 1; } return -1; } pHints->AddSegment(m_Pos, req_size); return 0; }
void CFDF_Document::ParseStream(IFX_FileRead* pFile, FX_BOOL bOwnFile) { m_pFile = pFile; m_bOwnFile = bOwnFile; CPDF_SyntaxParser parser; parser.InitParser(m_pFile, 0); while (1) { bool bNumber; CFX_ByteString word = parser.GetNextWord(&bNumber); if (bNumber) { uint32_t objnum = FXSYS_atoui(word.c_str()); word = parser.GetNextWord(&bNumber); if (!bNumber) break; word = parser.GetNextWord(nullptr); if (word != "obj") break; CPDF_Object* pObj = parser.GetObject(this, objnum, 0, true); if (!pObj) break; ReplaceIndirectObjectIfHigherGeneration(objnum, pObj); word = parser.GetNextWord(nullptr); if (word != "endobj") break; } else { if (word != "trailer") break; if (CPDF_Dictionary* pMainDict = ToDictionary(parser.GetObject(this, 0, 0, true))) { m_pRootDict = pMainDict->GetDictFor("Root"); pMainDict->Release(); } break; } } }