Home | History | Annotate | Download | only in xml
      1 // Copyright 2017 PDFium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
      6 
      7 #include "core/fxcrt/xml/cfx_saxreaderhandler.h"
      8 
      9 #include <string>
     10 
     11 #include "core/fxcrt/cfx_checksumcontext.h"
     12 
     13 CFX_SAXReaderHandler::CFX_SAXReaderHandler(CFX_ChecksumContext* pContext)
     14     : m_pContext(pContext) {
     15   ASSERT(m_pContext);
     16 }
     17 
     18 CFX_SAXReaderHandler::~CFX_SAXReaderHandler() {}
     19 
     20 CFX_SAXContext* CFX_SAXReaderHandler::OnTagEnter(
     21     const ByteStringView& bsTagName,
     22     CFX_SAXItem::Type eType,
     23     uint32_t dwStartPos) {
     24   UpdateChecksum(true);
     25   if (eType != CFX_SAXItem::Type::Tag &&
     26       eType != CFX_SAXItem::Type::Instruction) {
     27     return nullptr;
     28   }
     29 
     30   m_SAXContext.m_eNode = eType;
     31   m_SAXContext.m_TextBuf << "<";
     32   if (eType == CFX_SAXItem::Type::Instruction)
     33     m_SAXContext.m_TextBuf << "?";
     34 
     35   m_SAXContext.m_TextBuf << bsTagName;
     36   m_SAXContext.m_bsTagName = bsTagName;
     37   return &m_SAXContext;
     38 }
     39 
     40 void CFX_SAXReaderHandler::OnTagAttribute(CFX_SAXContext* pTag,
     41                                           const ByteStringView& bsAttri,
     42                                           const ByteStringView& bsValue) {
     43   if (!pTag)
     44     return;
     45   pTag->m_TextBuf << " " << bsAttri << "=\"" << bsValue << "\"";
     46 }
     47 
     48 void CFX_SAXReaderHandler::OnTagBreak(CFX_SAXContext* pTag) {
     49   if (!pTag)
     50     return;
     51 
     52   pTag->m_TextBuf << ">";
     53   UpdateChecksum(false);
     54 }
     55 
     56 void CFX_SAXReaderHandler::OnTagData(CFX_SAXContext* pTag,
     57                                      CFX_SAXItem::Type eType,
     58                                      const ByteStringView& bsData,
     59                                      uint32_t dwStartPos) {
     60   if (!pTag)
     61     return;
     62 
     63   if (eType == CFX_SAXItem::Type::CharData)
     64     pTag->m_TextBuf << "<![CDATA[";
     65 
     66   pTag->m_TextBuf << bsData;
     67   if (eType == CFX_SAXItem::Type::CharData)
     68     pTag->m_TextBuf << "]]>";
     69 }
     70 
     71 void CFX_SAXReaderHandler::OnTagClose(CFX_SAXContext* pTag, uint32_t dwEndPos) {
     72   if (!pTag)
     73     return;
     74 
     75   if (pTag->m_eNode == CFX_SAXItem::Type::Instruction)
     76     pTag->m_TextBuf << "?>";
     77   else if (pTag->m_eNode == CFX_SAXItem::Type::Tag)
     78     pTag->m_TextBuf << "></" << pTag->m_bsTagName.AsStringView() << ">";
     79 
     80   UpdateChecksum(false);
     81 }
     82 
     83 void CFX_SAXReaderHandler::OnTagEnd(CFX_SAXContext* pTag,
     84                                     const ByteStringView& bsTagName,
     85                                     uint32_t dwEndPos) {
     86   if (!pTag)
     87     return;
     88 
     89   pTag->m_TextBuf << "</" << bsTagName << ">";
     90   UpdateChecksum(false);
     91 }
     92 
     93 void CFX_SAXReaderHandler::OnTargetData(CFX_SAXContext* pTag,
     94                                         CFX_SAXItem::Type eType,
     95                                         const ByteStringView& bsData,
     96                                         uint32_t dwStartPos) {
     97   if (!pTag && eType != CFX_SAXItem::Type::Comment)
     98     return;
     99 
    100   if (eType == CFX_SAXItem::Type::Comment) {
    101     m_SAXContext.m_TextBuf << "<!--" << bsData << "-->";
    102     UpdateChecksum(false);
    103   } else {
    104     pTag->m_TextBuf << " " << bsData;
    105   }
    106 }
    107 
    108 void CFX_SAXReaderHandler::UpdateChecksum(bool bCheckSpace) {
    109   int32_t iLength = m_SAXContext.m_TextBuf.tellp();
    110   if (iLength < 1)
    111     return;
    112 
    113   std::string sBuffer = m_SAXContext.m_TextBuf.str();
    114   const uint8_t* pBuffer = reinterpret_cast<const uint8_t*>(sBuffer.c_str());
    115   bool bUpdata = true;
    116   if (bCheckSpace) {
    117     bUpdata = false;
    118     for (int32_t i = 0; i < iLength; i++) {
    119       bUpdata = (pBuffer[i] > 0x20);
    120       if (bUpdata)
    121         break;
    122     }
    123   }
    124   if (bUpdata)
    125     m_pContext->Update(ByteStringView(pBuffer, iLength));
    126 
    127   m_SAXContext.m_TextBuf.str("");
    128 }
    129