gfx/skia/trunk/src/xml/SkXMLWriter.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     2 /*
     3  * Copyright 2006 The Android Open Source Project
     4  *
     5  * Use of this source code is governed by a BSD-style license that can be
     6  * found in the LICENSE file.
     7  */
    10 #include "SkXMLWriter.h"
    11 #include "SkStream.h"
    13 SkXMLWriter::SkXMLWriter(bool doEscapeMarkup) : fDoEscapeMarkup(doEscapeMarkup)
    14 {
    15 }
    17 SkXMLWriter::~SkXMLWriter()
    18 {
    19     SkASSERT(fElems.count() == 0);
    20 }
    22 void SkXMLWriter::flush()
    23 {
    24     while (fElems.count())
    25         this->endElement();
    26 }
    28 void SkXMLWriter::addAttribute(const char name[], const char value[])
    29 {
    30     this->addAttributeLen(name, value, strlen(value));
    31 }
    33 void SkXMLWriter::addS32Attribute(const char name[], int32_t value)
    34 {
    35     SkString    tmp;
    36     tmp.appendS32(value);
    37     this->addAttribute(name, tmp.c_str());
    38 }
    40 void SkXMLWriter::addHexAttribute(const char name[], uint32_t value, int minDigits)
    41 {
    42     SkString    tmp("0x");
    43     tmp.appendHex(value, minDigits);
    44     this->addAttribute(name, tmp.c_str());
    45 }
    47 void SkXMLWriter::addScalarAttribute(const char name[], SkScalar value)
    48 {
    49     SkString    tmp;
    50     tmp.appendScalar(value);
    51     this->addAttribute(name, tmp.c_str());
    52 }
    54 void SkXMLWriter::doEnd(Elem* elem)
    55 {
    56     delete elem;
    57 }
    59 bool SkXMLWriter::doStart(const char name[], size_t length)
    60 {
    61     int level = fElems.count();
    62     bool firstChild = level > 0 && !fElems[level-1]->fHasChildren;
    63     if (firstChild)
    64         fElems[level-1]->fHasChildren = true;
    65     Elem** elem = fElems.push();
    66     *elem = new Elem;
    67     (*elem)->fName.set(name, length);
    68     (*elem)->fHasChildren = 0;
    69     return firstChild;
    70 }
    72 SkXMLWriter::Elem* SkXMLWriter::getEnd()
    73 {
    74     Elem* elem;
    75     fElems.pop(&elem);
    76     return elem;
    77 }
    79 const char* SkXMLWriter::getHeader()
    80 {
    81     static const char gHeader[] = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>";
    82     return gHeader;
    83 }
    85 void SkXMLWriter::startElement(const char name[])
    86 {
    87     this->startElementLen(name, strlen(name));
    88 }
    90 static const char* escape_char(char c, char storage[2])
    91 {
    92     static const char* gEscapeChars[] = {
    93         "<&lt;",
    94         ">&gt;",
    95         //"\"&quot;",
    96         //"'&apos;",
    97         "&&amp;"
    98     };
   100     const char** array = gEscapeChars;
   101     for (unsigned i = 0; i < SK_ARRAY_COUNT(gEscapeChars); i++)
   102     {
   103         if (array[i][0] == c)
   104             return &array[i][1];
   105     }
   106     storage[0] = c;
   107     storage[1] = 0;
   108     return storage;
   109 }
   111 static size_t escape_markup(char dst[], const char src[], size_t length)
   112 {
   113     size_t      extra = 0;
   114     const char* stop = src + length;
   116     while (src < stop)
   117     {
   118         char        orig[2];
   119         const char* seq = escape_char(*src, orig);
   120         size_t      seqSize = strlen(seq);
   122         if (dst)
   123         {
   124             memcpy(dst, seq, seqSize);
   125             dst += seqSize;
   126         }
   128         // now record the extra size needed
   129         extra += seqSize - 1;   // minus one to subtract the original char
   131         // bump to the next src char
   132         src += 1;
   133     }
   134     return extra;
   135 }
   137 void SkXMLWriter::addAttributeLen(const char name[], const char value[], size_t length)
   138 {
   139     SkString valueStr;
   141     if (fDoEscapeMarkup)
   142     {
   143         size_t   extra = escape_markup(NULL, value, length);
   144         if (extra)
   145         {
   146             valueStr.resize(length + extra);
   147             (void)escape_markup(valueStr.writable_str(), value, length);
   148             value = valueStr.c_str();
   149             length += extra;
   150         }
   151     }
   152     this->onAddAttributeLen(name, value, length);
   153 }
   155 void SkXMLWriter::startElementLen(const char elem[], size_t length)
   156 {
   157     this->onStartElementLen(elem, length);
   158 }
   160 ////////////////////////////////////////////////////////////////////////////////////////
   162 static void write_dom(const SkDOM& dom, const SkDOM::Node* node, SkXMLWriter* w, bool skipRoot)
   163 {
   164     if (!skipRoot)
   165     {
   166         w->startElement(dom.getName(node));
   168         SkDOM::AttrIter iter(dom, node);
   169         const char* name;
   170         const char* value;
   171         while ((name = iter.next(&value)) != NULL)
   172             w->addAttribute(name, value);
   173     }
   175     node = dom.getFirstChild(node, NULL);
   176     while (node)
   177     {
   178         write_dom(dom, node, w, false);
   179         node = dom.getNextSibling(node, NULL);
   180     }
   182     if (!skipRoot)
   183         w->endElement();
   184 }
   186 void SkXMLWriter::writeDOM(const SkDOM& dom, const SkDOM::Node* node, bool skipRoot)
   187 {
   188     if (node)
   189         write_dom(dom, node, this, skipRoot);
   190 }
   192 void SkXMLWriter::writeHeader()
   193 {
   194 }
   196 // SkXMLStreamWriter
   198 static void tab(SkWStream& stream, int level)
   199 {
   200     for (int i = 0; i < level; i++)
   201         stream.writeText("\t");
   202 }
   204 SkXMLStreamWriter::SkXMLStreamWriter(SkWStream* stream) : fStream(*stream)
   205 {
   206 }
   208 SkXMLStreamWriter::~SkXMLStreamWriter()
   209 {
   210     this->flush();
   211 }
   213 void SkXMLStreamWriter::onAddAttributeLen(const char name[], const char value[], size_t length)
   214 {
   215     SkASSERT(!fElems.top()->fHasChildren);
   216     fStream.writeText(" ");
   217     fStream.writeText(name);
   218     fStream.writeText("=\"");
   219     fStream.write(value, length);
   220     fStream.writeText("\"");
   221 }
   223 void SkXMLStreamWriter::onEndElement()
   224 {
   225     Elem* elem = getEnd();
   226     if (elem->fHasChildren)
   227     {
   228         tab(fStream, fElems.count());
   229         fStream.writeText("</");
   230         fStream.writeText(elem->fName.c_str());
   231         fStream.writeText(">");
   232     }
   233     else
   234         fStream.writeText("/>");
   235     fStream.newline();
   236     doEnd(elem);
   237 }
   239 void SkXMLStreamWriter::onStartElementLen(const char name[], size_t length)
   240 {
   241     int level = fElems.count();
   242     if (this->doStart(name, length))
   243     {
   244         // the first child, need to close with >
   245         fStream.writeText(">");
   246         fStream.newline();
   247     }
   249     tab(fStream, level);
   250     fStream.writeText("<");
   251     fStream.write(name, length);
   252 }
   254 void SkXMLStreamWriter::writeHeader()
   255 {
   256     const char* header = getHeader();
   257     fStream.write(header, strlen(header));
   258     fStream.newline();
   259 }
   261 ////////////////////////////////////////////////////////////////////////////////////////////////
   263 #include "SkXMLParser.h"
   265 SkXMLParserWriter::SkXMLParserWriter(SkXMLParser* parser)
   266     : SkXMLWriter(false), fParser(*parser)
   267 {
   268 }
   270 SkXMLParserWriter::~SkXMLParserWriter()
   271 {
   272     this->flush();
   273 }
   275 void SkXMLParserWriter::onAddAttributeLen(const char name[], const char value[], size_t length)
   276 {
   277     SkASSERT(fElems.count() == 0 || !fElems.top()->fHasChildren);
   278     SkString str(value, length);
   279     fParser.addAttribute(name, str.c_str());
   280 }
   282 void SkXMLParserWriter::onEndElement()
   283 {
   284     Elem* elem = this->getEnd();
   285     fParser.endElement(elem->fName.c_str());
   286     this->doEnd(elem);
   287 }
   289 void SkXMLParserWriter::onStartElementLen(const char name[], size_t length)
   290 {
   291     (void)this->doStart(name, length);
   292     SkString str(name, length);
   293     fParser.startElement(str.c_str());
   294 }
   297 ////////////////////////////////////////////////////////////////////////////////////////
   298 ////////////////////////////////////////////////////////////////////////////////////////
   300 #ifdef SK_DEBUG
   302 void SkXMLStreamWriter::UnitTest()
   303 {
   304 #ifdef SK_SUPPORT_UNITTEST
   305     SkDebugWStream  s;
   306     SkXMLStreamWriter       w(&s);
   308     w.startElement("elem0");
   309     w.addAttribute("hello", "world");
   310     w.addS32Attribute("dec", 42);
   311     w.addHexAttribute("hex", 0x42, 3);
   312     w.addScalarAttribute("scalar", -4.2f);
   313     w.startElement("elem1");
   314         w.endElement();
   315         w.startElement("elem1");
   316         w.addAttribute("name", "value");
   317         w.endElement();
   318         w.startElement("elem1");
   319             w.startElement("elem2");
   320                 w.startElement("elem3");
   321                 w.addAttribute("name", "value");
   322                 w.endElement();
   323             w.endElement();
   324             w.startElement("elem2");
   325             w.endElement();
   326         w.endElement();
   327     w.endElement();
   328 #endif
   329 }
   331 #endif

mercurial