gfx/skia/trunk/src/ports/SkXMLPullParser_expat.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.

michael@0 1
michael@0 2 /*
michael@0 3 * Copyright 2006 The Android Open Source Project
michael@0 4 *
michael@0 5 * Use of this source code is governed by a BSD-style license that can be
michael@0 6 * found in the LICENSE file.
michael@0 7 */
michael@0 8
michael@0 9
michael@0 10 #include "SkXMLParser.h"
michael@0 11 #include "SkChunkAlloc.h"
michael@0 12 #include "SkString.h"
michael@0 13 #include "SkStream.h"
michael@0 14
michael@0 15 #include "expat.h"
michael@0 16
michael@0 17 static inline char* dupstr(SkChunkAlloc& chunk, const char src[], size_t len)
michael@0 18 {
michael@0 19 SkASSERT(src);
michael@0 20 char* dst = (char*)chunk.alloc(len + 1, SkChunkAlloc::kThrow_AllocFailType);
michael@0 21
michael@0 22 memcpy(dst, src, len);
michael@0 23 dst[len] = 0;
michael@0 24 return dst;
michael@0 25 }
michael@0 26
michael@0 27 static inline int count_pairs(const char** p)
michael@0 28 {
michael@0 29 const char** start = p;
michael@0 30 while (*p)
michael@0 31 {
michael@0 32 SkASSERT(p[1] != NULL);
michael@0 33 p += 2;
michael@0 34 }
michael@0 35 return (p - start) >> 1;
michael@0 36 }
michael@0 37
michael@0 38 struct Data {
michael@0 39 Data() : fAlloc(2048), fState(NORMAL) {}
michael@0 40
michael@0 41 XML_Parser fParser;
michael@0 42 SkXMLPullParser::Curr* fCurr;
michael@0 43 SkChunkAlloc fAlloc;
michael@0 44
michael@0 45 enum State {
michael@0 46 NORMAL,
michael@0 47 MISSED_START_TAG,
michael@0 48 RETURN_END_TAG
michael@0 49 };
michael@0 50 State fState;
michael@0 51 const char* fEndTag; // if state is RETURN_END_TAG
michael@0 52 };
michael@0 53
michael@0 54 static void XMLCALL start_proc(void *data, const char *el, const char **attr)
michael@0 55 {
michael@0 56 Data* p = (Data*)data;
michael@0 57 SkXMLPullParser::Curr* c = p->fCurr;
michael@0 58 SkChunkAlloc& alloc = p->fAlloc;
michael@0 59
michael@0 60 c->fName = dupstr(alloc, el, strlen(el));
michael@0 61
michael@0 62 int n = count_pairs(attr);
michael@0 63 SkXMLPullParser::AttrInfo* info = (SkXMLPullParser::AttrInfo*)alloc.alloc(n * sizeof(SkXMLPullParser::AttrInfo),
michael@0 64 SkChunkAlloc::kThrow_AllocFailType);
michael@0 65 c->fAttrInfoCount = n;
michael@0 66 c->fAttrInfos = info;
michael@0 67
michael@0 68 for (int i = 0; i < n; i++)
michael@0 69 {
michael@0 70 info[i].fName = dupstr(alloc, attr[0], strlen(attr[0]));
michael@0 71 info[i].fValue = dupstr(alloc, attr[1], strlen(attr[1]));
michael@0 72 attr += 2;
michael@0 73 }
michael@0 74
michael@0 75 c->fEventType = SkXMLPullParser::START_TAG;
michael@0 76 XML_StopParser(p->fParser, true);
michael@0 77 }
michael@0 78
michael@0 79 static void XMLCALL end_proc(void *data, const char *el)
michael@0 80 {
michael@0 81 Data* p = (Data*)data;
michael@0 82 SkXMLPullParser::Curr* c = p->fCurr;
michael@0 83
michael@0 84 if (c->fEventType == SkXMLPullParser::START_TAG)
michael@0 85 {
michael@0 86 /* if we get here, we were called with a start_tag immediately
michael@0 87 followed by this end_tag. The caller will only see the end_tag,
michael@0 88 so we set a flag to notify them of the missed start_tag
michael@0 89 */
michael@0 90 p->fState = Data::MISSED_START_TAG;
michael@0 91
michael@0 92 SkASSERT(c->fName != NULL);
michael@0 93 SkASSERT(strcmp(c->fName, el) == 0);
michael@0 94 }
michael@0 95 else
michael@0 96 c->fName = dupstr(p->fAlloc, el, strlen(el));
michael@0 97
michael@0 98 c->fEventType = SkXMLPullParser::END_TAG;
michael@0 99 XML_StopParser(p->fParser, true);
michael@0 100 }
michael@0 101
michael@0 102 #include <ctype.h>
michael@0 103
michael@0 104 static bool isws(const char s[])
michael@0 105 {
michael@0 106 for (; *s; s++)
michael@0 107 if (!isspace(*s))
michael@0 108 return false;
michael@0 109 return true;
michael@0 110 }
michael@0 111
michael@0 112 static void XMLCALL text_proc(void* data, const char* text, int len)
michael@0 113 {
michael@0 114 Data* p = (Data*)data;
michael@0 115 SkXMLPullParser::Curr* c = p->fCurr;
michael@0 116
michael@0 117 c->fName = dupstr(p->fAlloc, text, len);
michael@0 118 c->fIsWhitespace = isws(c->fName);
michael@0 119
michael@0 120 c->fEventType = SkXMLPullParser::TEXT;
michael@0 121 XML_StopParser(p->fParser, true);
michael@0 122 }
michael@0 123
michael@0 124 //////////////////////////////////////////////////////////////////////////
michael@0 125
michael@0 126 struct SkXMLPullParser::Impl {
michael@0 127 Data fData;
michael@0 128 void* fBuffer;
michael@0 129 size_t fBufferLen;
michael@0 130 };
michael@0 131
michael@0 132 static void reportError(XML_Parser parser)
michael@0 133 {
michael@0 134 XML_Error code = XML_GetErrorCode(parser);
michael@0 135 int lineNumber = XML_GetCurrentLineNumber(parser);
michael@0 136 const char* msg = XML_ErrorString(code);
michael@0 137
michael@0 138 printf("-------- XML error [%d] on line %d, %s\n", code, lineNumber, msg);
michael@0 139 }
michael@0 140
michael@0 141 bool SkXMLPullParser::onInit()
michael@0 142 {
michael@0 143 fImpl = new Impl;
michael@0 144
michael@0 145 XML_Parser p = XML_ParserCreate(NULL);
michael@0 146 SkASSERT(p);
michael@0 147
michael@0 148 fImpl->fData.fParser = p;
michael@0 149 fImpl->fData.fCurr = &fCurr;
michael@0 150
michael@0 151 XML_SetElementHandler(p, start_proc, end_proc);
michael@0 152 XML_SetCharacterDataHandler(p, text_proc);
michael@0 153 XML_SetUserData(p, &fImpl->fData);
michael@0 154
michael@0 155 size_t len = fStream->getLength();
michael@0 156 fImpl->fBufferLen = len;
michael@0 157 fImpl->fBuffer = sk_malloc_throw(len);
michael@0 158 fStream->rewind();
michael@0 159 size_t len2 = fStream->read(fImpl->fBuffer, len);
michael@0 160 return len2 == len;
michael@0 161 }
michael@0 162
michael@0 163 void SkXMLPullParser::onExit()
michael@0 164 {
michael@0 165 sk_free(fImpl->fBuffer);
michael@0 166 XML_ParserFree(fImpl->fData.fParser);
michael@0 167 delete fImpl;
michael@0 168 fImpl = NULL;
michael@0 169 }
michael@0 170
michael@0 171 SkXMLPullParser::EventType SkXMLPullParser::onNextToken()
michael@0 172 {
michael@0 173 if (Data::RETURN_END_TAG == fImpl->fData.fState)
michael@0 174 {
michael@0 175 fImpl->fData.fState = Data::NORMAL;
michael@0 176 fCurr.fName = fImpl->fData.fEndTag; // restore name from (below) save
michael@0 177 return SkXMLPullParser::END_TAG;
michael@0 178 }
michael@0 179
michael@0 180 fImpl->fData.fAlloc.reset();
michael@0 181
michael@0 182 XML_Parser p = fImpl->fData.fParser;
michael@0 183 XML_Status status;
michael@0 184
michael@0 185 status = XML_ResumeParser(p);
michael@0 186
michael@0 187 CHECK_STATUS:
michael@0 188 switch (status) {
michael@0 189 case XML_STATUS_OK:
michael@0 190 return SkXMLPullParser::END_DOCUMENT;
michael@0 191
michael@0 192 case XML_STATUS_ERROR:
michael@0 193 if (XML_GetErrorCode(p) != XML_ERROR_NOT_SUSPENDED)
michael@0 194 {
michael@0 195 reportError(p);
michael@0 196 return SkXMLPullParser::ERROR;
michael@0 197 }
michael@0 198 status = XML_Parse(p, (const char*)fImpl->fBuffer, fImpl->fBufferLen, true);
michael@0 199 goto CHECK_STATUS;
michael@0 200
michael@0 201 case XML_STATUS_SUSPENDED:
michael@0 202 if (Data::MISSED_START_TAG == fImpl->fData.fState)
michael@0 203 {
michael@0 204 // return a start_tag, and clear the flag so we return end_tag next
michael@0 205 SkASSERT(SkXMLPullParser::END_TAG == fCurr.fEventType);
michael@0 206 fImpl->fData.fState = Data::RETURN_END_TAG;
michael@0 207 fImpl->fData.fEndTag = fCurr.fName; // save this pointer
michael@0 208 return SkXMLPullParser::START_TAG;
michael@0 209 }
michael@0 210 break;
michael@0 211 }
michael@0 212 return fCurr.fEventType;
michael@0 213 }

mercurial