gfx/skia/trunk/src/utils/SkJSON.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.

     1 /*
     2  * Copyright 2011 Google Inc.
     3  *
     4  * Use of this source code is governed by a BSD-style license that can be
     5  * found in the LICENSE file.
     6  */
     8 #include "SkJSON.h"
     9 #include "SkString.h"
    11 #ifdef SK_DEBUG
    12 //    #define TRACE_SKJSON_LEAKS
    13 #endif
    15 #ifdef TRACE_SKJSON_LEAKS
    16     static int gStringCount;
    17     static int gSlotCount;
    18     static int gObjectCount;
    19     static int gArrayCount;
    20     #define LEAK_CODE(code) code
    21 #else
    22     #define LEAK_CODE(code)
    23 #endif
    25 ///////////////////////////////////////////////////////////////////////////////
    27 static char* alloc_string(size_t len) {
    28     LEAK_CODE(SkDebugf(" string[%d]\n", gStringCount++);)
    29     char* str = (char*)sk_malloc_throw(len + 1);
    30     str[len] = 0;
    31     return str;
    32 }
    34 static char* dup_string(const char src[]) {
    35     if (NULL == src) {
    36         return NULL;
    37     }
    38     size_t len = strlen(src);
    39     char* dst = alloc_string(len);
    40     memcpy(dst, src, len);
    41     return dst;
    42 }
    44 static void free_string(char* str) {
    45     if (str) {
    46         sk_free(str);
    47         LEAK_CODE(SkASSERT(gStringCount > 0); SkDebugf("~string[%d]\n", --gStringCount);)
    48     }
    49 }
    51 ///////////////////////////////////////////////////////////////////////////////
    53 struct SkJSON::Object::Slot {
    54     Slot(const char name[], Type type) {
    55         LEAK_CODE(SkDebugf(" slot[%d]\n", gSlotCount++);)
    56         SkASSERT(name);
    58         fNext = NULL;
    60         size_t len = strlen(name);
    61         // extra 1 for str[0] which stores the type
    62         char* str = alloc_string(1 + len);
    63         str[0] = (char)type;
    64         // str[1] skips the type, len+1 includes the terminating 0 byte.
    65         memcpy(&str[1], name, len + 1);
    66         fName = str;
    68         // fValue is uninitialized
    69     }
    70     ~Slot();
    72     Type type() const { return (Type)fName[0]; }
    73     const char* name() const { return &fName[1]; }
    75     Slot*   fNext;
    76     char*   fName;    // fName[0] is the type, &fName[1] is the "name"
    77     union {
    78         Object* fObject;
    79         Array*  fArray;
    80         char*   fString;
    81         int32_t fInt;
    82         float   fFloat;
    83         bool    fBool;
    84     } fValue;
    85 };
    87 SkJSON::Object::Slot::~Slot() {
    88     free_string(fName);
    89     switch (this->type()) {
    90         case kObject:
    91             delete fValue.fObject;
    92             break;
    93         case kArray:
    94             delete fValue.fArray;
    95             break;
    96         case kString:
    97             free_string(fValue.fString);
    98             break;
    99         default:
   100             break;
   101     }
   102     LEAK_CODE(SkASSERT(gSlotCount > 0); SkDebugf("~slot[%d]\n", --gSlotCount);)
   103 }
   105 ///////////////////////////////////////////////////////////////////////////////
   107 SkJSON::Object::Iter::Iter(const Object& obj) : fSlot(obj.fHead) {}
   109 bool SkJSON::Object::Iter::done() const {
   110     return NULL == fSlot;
   111 }
   113 void SkJSON::Object::Iter::next() {
   114     SkASSERT(fSlot);
   115     fSlot = fSlot->fNext;
   116 }
   118 SkJSON::Type SkJSON::Object::Iter::type() const {
   119     SkASSERT(fSlot);
   120     return fSlot->type();
   121 }
   123 const char* SkJSON::Object::Iter::name() const {
   124     SkASSERT(fSlot);
   125     return fSlot->name();
   126 }
   128 SkJSON::Object* SkJSON::Object::Iter::objectValue() const {
   129     SkASSERT(fSlot);
   130     SkASSERT(kObject == fSlot->type());
   131     return fSlot->fValue.fObject;
   132 }
   134 SkJSON::Array* SkJSON::Object::Iter::arrayValue() const {
   135     SkASSERT(fSlot);
   136     SkASSERT(kArray == fSlot->type());
   137     return fSlot->fValue.fArray;
   138 }
   140 const char* SkJSON::Object::Iter::stringValue() const {
   141     SkASSERT(fSlot);
   142     SkASSERT(kString == fSlot->type());
   143     return fSlot->fValue.fString;
   144 }
   146 int32_t SkJSON::Object::Iter::intValue() const {
   147     SkASSERT(fSlot);
   148     SkASSERT(kInt == fSlot->type());
   149     return fSlot->fValue.fInt;
   150 }
   152 float SkJSON::Object::Iter::floatValue() const {
   153     SkASSERT(fSlot);
   154     SkASSERT(kFloat == fSlot->type());
   155     return fSlot->fValue.fFloat;
   156 }
   158 bool SkJSON::Object::Iter::boolValue() const {
   159     SkASSERT(fSlot);
   160     SkASSERT(kBool == fSlot->type());
   161     return fSlot->fValue.fBool;
   162 }
   164 ///////////////////////////////////////////////////////////////////////////////
   166 SkJSON::Object::Object() : fHead(NULL), fTail(NULL) {
   167     LEAK_CODE(SkDebugf(" object[%d]\n", gObjectCount++);)
   168 }
   170 SkJSON::Object::Object(const Object& other) : fHead(NULL), fTail(NULL) {
   171     LEAK_CODE(SkDebugf(" object[%d]\n", gObjectCount++);)
   173     Iter iter(other);
   174     while (!iter.done()) {
   175         switch (iter.type()) {
   176             case kObject:
   177                 this->addObject(iter.name(), new Object(*iter.objectValue()));
   178                 break;
   179             case kArray:
   180                 this->addArray(iter.name(), new Array(*iter.arrayValue()));
   181                 break;
   182             case kString:
   183                 this->addString(iter.name(), dup_string(iter.stringValue()));
   184                 break;
   185             case kInt:
   186                 this->addInt(iter.name(), iter.intValue());
   187                 break;
   188             case kFloat:
   189                 this->addFloat(iter.name(), iter.floatValue());
   190                 break;
   191             case kBool:
   192                 this->addBool(iter.name(), iter.boolValue());
   193                 break;
   194         }
   195         iter.next();
   196     }
   197 }
   199 SkJSON::Object::~Object() {
   200     Slot* slot = fHead;
   201     while (slot) {
   202         Slot* next = slot->fNext;
   203         delete slot;
   204         slot = next;
   205     }
   206     LEAK_CODE(SkASSERT(gObjectCount > 0); SkDebugf("~object[%d]\n", --gObjectCount);)
   207 }
   209 int SkJSON::Object::count() const {
   210     int n = 0;
   211     for (const Slot* slot = fHead; slot; slot = slot->fNext) {
   212         n += 1;
   213     }
   214     return n;
   215 }
   217 SkJSON::Object::Slot* SkJSON::Object::addSlot(Slot* slot) {
   218     SkASSERT(NULL == slot->fNext);
   219     if (NULL == fHead) {
   220         SkASSERT(NULL == fTail);
   221         fHead = fTail = slot;
   222     } else {
   223         SkASSERT(fTail);
   224         SkASSERT(NULL == fTail->fNext);
   225         fTail->fNext = slot;
   226         fTail = slot;
   227     }
   228     return slot;
   229 }
   231 void SkJSON::Object::addObject(const char name[], SkJSON::Object* value) {
   232     this->addSlot(new Slot(name, kObject))->fValue.fObject = value;
   233 }
   235 void SkJSON::Object::addArray(const char name[], SkJSON::Array* value) {
   236     this->addSlot(new Slot(name, kArray))->fValue.fArray = value;
   237 }
   239 void SkJSON::Object::addString(const char name[], const char value[]) {
   240     this->addSlot(new Slot(name, kString))->fValue.fString = dup_string(value);
   241 }
   243 void SkJSON::Object::addInt(const char name[], int32_t value) {
   244     this->addSlot(new Slot(name, kInt))->fValue.fInt = value;
   245 }
   247 void SkJSON::Object::addFloat(const char name[], float value) {
   248     this->addSlot(new Slot(name, kFloat))->fValue.fFloat = value;
   249 }
   251 void SkJSON::Object::addBool(const char name[], bool value) {
   252     this->addSlot(new Slot(name, kBool))->fValue.fBool = value;
   253 }
   255 ///////////////////////////////////////////////////////////////////////////////
   257 const SkJSON::Object::Slot* SkJSON::Object::findSlot(const char name[],
   258                                                      Type t) const {
   259     for (const Slot* slot = fHead; slot; slot = slot->fNext) {
   260         if (t == slot->type() && !strcmp(slot->name(), name)) {
   261             return slot;
   262         }
   263     }
   264     return NULL;
   265 }
   267 bool SkJSON::Object::find(const char name[], Type t) const {
   268     return this->findSlot(name, t) != NULL;
   269 }
   271 bool SkJSON::Object::findObject(const char name[], SkJSON::Object** value) const {
   272     const Slot* slot = this->findSlot(name, kObject);
   273     if (slot) {
   274         if (value) {
   275             *value = slot->fValue.fObject;
   276         }
   277         return true;
   278     }
   279     return false;
   280 }
   282 bool SkJSON::Object::findArray(const char name[], SkJSON::Array** value) const {
   283     const Slot* slot = this->findSlot(name, kArray);
   284     if (slot) {
   285         if (value) {
   286             *value = slot->fValue.fArray;
   287         }
   288         return true;
   289     }
   290     return false;
   291 }
   293 bool SkJSON::Object::findString(const char name[], SkString* value) const {
   294     const Slot* slot = this->findSlot(name, kString);
   295     if (slot) {
   296         if (value) {
   297             value->set(slot->fValue.fString);
   298         }
   299         return true;
   300     }
   301     return false;
   302 }
   304 bool SkJSON::Object::findInt(const char name[], int32_t* value) const {
   305     const Slot* slot = this->findSlot(name, kInt);
   306     if (slot) {
   307         if (value) {
   308             *value = slot->fValue.fInt;
   309         }
   310         return true;
   311     }
   312     return false;
   313 }
   315 bool SkJSON::Object::findFloat(const char name[], float* value) const {
   316     const Slot* slot = this->findSlot(name, kFloat);
   317     if (slot) {
   318         if (value) {
   319             *value = slot->fValue.fFloat;
   320         }
   321         return true;
   322     }
   323     return false;
   324 }
   326 bool SkJSON::Object::findBool(const char name[], bool* value) const {
   327     const Slot* slot = this->findSlot(name, kBool);
   328     if (slot) {
   329         if (value) {
   330             *value = slot->fValue.fBool;
   331         }
   332         return true;
   333     }
   334     return false;
   335 }
   337 bool SkJSON::Object::remove(const char name[], Type t) {
   338     SkDEBUGCODE(int count = this->count();)
   339     Slot* prev = NULL;
   340     Slot* slot = fHead;
   341     while (slot) {
   342         Slot* next = slot->fNext;
   343         if (t == slot->type() && !strcmp(slot->name(), name)) {
   344             if (prev) {
   345                 SkASSERT(fHead != slot);
   346                 prev->fNext = next;
   347             } else {
   348                 SkASSERT(fHead == slot);
   349                 fHead = next;
   350             }
   351             if (fTail == slot) {
   352                 fTail = prev;
   353             }
   354             delete slot;
   355             SkASSERT(count - 1 == this->count());
   356             return true;
   357         }
   358         prev = slot;
   359         slot = next;
   360     }
   361     SkASSERT(count == this->count());
   362     return false;
   363 }
   365 ///////////////////////////////////////////////////////////////////////////////
   367 static void tabForLevel(int level) {
   368     for (int i = 0; i < level; ++i) {
   369         SkDebugf("    ");
   370     }
   371 }
   373 void SkJSON::Object::toDebugf() const {
   374     SkDebugf("{\n");
   375     this->dumpLevel(0);
   376     SkDebugf("}\n");
   377 }
   379 void SkJSON::Object::dumpLevel(int level) const {
   380     for (Slot* slot = fHead; slot; slot = slot->fNext) {
   381         Type t = slot->type();
   382         tabForLevel(level + 1);
   383         SkDebugf("\"%s\" : ", slot->name());
   384         switch (slot->type()) {
   385             case kObject:
   386                 if (slot->fValue.fObject) {
   387                     SkDebugf("{\n");
   388                     slot->fValue.fObject->dumpLevel(level + 1);
   389                     tabForLevel(level + 1);
   390                     SkDebugf("}");
   391                 } else {
   392                     SkDebugf("null");
   393                 }
   394                 break;
   395             case kArray:
   396                 if (slot->fValue.fArray) {
   397                     SkDebugf("[");
   398                     slot->fValue.fArray->dumpLevel(level + 1);
   399                     SkDebugf("]");
   400                 } else {
   401                     SkDebugf("null");
   402                 }
   403                 break;
   404             case kString:
   405                 SkDebugf("\"%s\"", slot->fValue.fString);
   406                 break;
   407             case kInt:
   408                 SkDebugf("%d", slot->fValue.fInt);
   409                 break;
   410             case kFloat:
   411                 SkDebugf("%g", slot->fValue.fFloat);
   412                 break;
   413             case kBool:
   414                 SkDebugf("%s", slot->fValue.fBool ? "true" : "false");
   415                 break;
   416             default:
   417                 SkDEBUGFAIL("how did I get here");
   418                 break;
   419         }
   420         if (slot->fNext) {
   421             SkDebugf(",");
   422         }
   423         SkDebugf("\n");
   424     }
   425 }
   427 void SkJSON::Array::dumpLevel(int level) const {
   428     if (0 == fCount) {
   429         return;
   430     }
   431     int last = fCount - 1;
   433     switch (this->type()) {
   434         case kObject: {
   435             SkDebugf("\n");
   436             for (int i = 0; i <= last; ++i) {
   437                 Object* obj = fArray.fObjects[i];
   438                 tabForLevel(level + 1);
   439                 if (obj) {
   440                     SkDebugf("{\n");
   441                     obj->dumpLevel(level + 1);
   442                     tabForLevel(level + 1);
   443                     SkDebugf(i < last ? "}," : "}");
   444                 } else {
   445                     SkDebugf(i < last ? "null," : "null");
   446                 }
   447                 SkDebugf("\n");
   448             }
   449         } break;
   450         case kArray: {
   451             SkDebugf("\n");
   452             for (int i = 0; i <= last; ++i) {
   453                 Array* array = fArray.fArrays[i];
   454                 tabForLevel(level + 1);
   455                 if (array) {
   456                     SkDebugf("[");
   457                     array->dumpLevel(level + 1);
   458                     tabForLevel(level + 1);
   459                     SkDebugf(i < last ? "]," : "]");
   460                 } else {
   461                     SkDebugf(i < last ? "null," : "null");
   462                 }
   463                 SkDebugf("\n");
   464             }
   465         } break;
   466         case kString: {
   467             for (int i = 0; i < last; ++i) {
   468                 const char* str = fArray.fStrings[i];
   469                 SkDebugf(str ? " \"%s\"," : " null,", str);
   470             }
   471             const char* str = fArray.fStrings[last];
   472             SkDebugf(str ? " \"%s\" " : " null ", str);
   473         } break;
   474         case kInt: {
   475             for (int i = 0; i < last; ++i) {
   476                 SkDebugf(" %d,", fArray.fInts[i]);
   477             }
   478             SkDebugf(" %d ", fArray.fInts[last]);
   479         } break;
   480         case kFloat: {
   481             for (int i = 0; i < last; ++i) {
   482                 SkDebugf(" %g,", fArray.fFloats[i]);
   483             }
   484             SkDebugf(" %g ", fArray.fFloats[last]);
   485         } break;
   486         case kBool: {
   487             for (int i = 0; i < last; ++i) {
   488                 SkDebugf(" %s,", fArray.fBools[i] ? "true" : "false");
   489             }
   490             SkDebugf(" %s ", fArray.fInts[last] ? "true" : "false");
   491         } break;
   492         default:
   493             SkDEBUGFAIL("unsupported array type");
   494             break;
   495     }
   496 }
   498 ///////////////////////////////////////////////////////////////////////////////
   500 static const uint8_t gBytesPerType[] = {
   501     sizeof(SkJSON::Object*),
   502     sizeof(SkJSON::Array*),
   503     sizeof(char*),
   504     sizeof(int32_t),
   505     sizeof(float),
   506     sizeof(bool)
   507 };
   509 typedef void* (*DupProc)(const void*);
   511 static void* dup_object(const void* src) {
   512     return SkNEW_ARGS(SkJSON::Object, (*(SkJSON::Object*)src));
   513 }
   515 static void* dup_array(const void* src) {
   516     return SkNEW_ARGS(SkJSON::Array, (*(SkJSON::Array*)src));
   517 }
   519 static const DupProc gDupProcs[] = {
   520     dup_object,             // Object
   521     dup_array,              // Array
   522     (DupProc)dup_string,    // String
   523     NULL,                   // int
   524     NULL,                   // float
   525     NULL,                   // bool
   526 };
   528 void SkJSON::Array::init(Type type, int count, const void* src) {
   529     LEAK_CODE(SkDebugf(" array[%d]\n", gArrayCount++);)
   531     SkASSERT((unsigned)type < SK_ARRAY_COUNT(gBytesPerType));
   533     if (count < 0) {
   534         count = 0;
   535     }
   536     size_t size = count * gBytesPerType[type];
   538     fCount = count;
   539     fType = type;
   540     fArray.fVoids = sk_malloc_throw(size);
   541     if (src) {
   542         DupProc proc = gDupProcs[fType];
   543         if (!proc) {
   544             memcpy(fArray.fVoids, src, size);
   545         } else {
   546             void** srcPtr = (void**)src;
   547             void** dstPtr = (void**)fArray.fVoids;
   548             for (int i = 0; i < fCount; ++i) {
   549                 dstPtr[i] = proc(srcPtr[i]);
   550             }
   551         }
   552     } else {
   553         sk_bzero(fArray.fVoids, size);
   554     }
   555 }
   557 SkJSON::Array::Array(Type type, int count) {
   558     this->init(type, count, NULL);
   559 }
   561 SkJSON::Array::Array(const int32_t values[], int count) {
   562     this->init(kInt, count, values);
   563 }
   565 SkJSON::Array::Array(const float values[], int count) {
   566     this->init(kFloat, count, values);
   567 }
   569 SkJSON::Array::Array(const bool values[], int count) {
   570     this->init(kBool, count, values);
   571 }
   573 SkJSON::Array::Array(const Array& other) {
   574     this->init(other.type(), other.count(), other.fArray.fVoids);
   575 }
   577 typedef void (*FreeProc)(void*);
   579 static void free_object(void* obj) {
   580     delete (SkJSON::Object*)obj;
   581 }
   583 static void free_array(void* array) {
   584     delete (SkJSON::Array*)array;
   585 }
   587 static const FreeProc gFreeProcs[] = {
   588     free_object,            // Object
   589     free_array,             // Array
   590     (FreeProc)free_string,  // String
   591     NULL,                   // int
   592     NULL,                   // float
   593     NULL,                   // bool
   594 };
   596 SkJSON::Array::~Array() {
   597     FreeProc proc = gFreeProcs[fType];
   598     if (proc) {
   599         void** ptr = (void**)fArray.fVoids;
   600         for (int i = 0; i < fCount; ++i) {
   601             proc(ptr[i]);
   602         }
   603     }
   604     sk_free(fArray.fVoids);
   606     LEAK_CODE(SkASSERT(gArrayCount > 0); SkDebugf("~array[%d]\n", --gArrayCount);)
   607 }
   609 void SkJSON::Array::setObject(int index, Object* object) {
   610     SkASSERT((unsigned)index < (unsigned)fCount);
   611     Object*& prev = fArray.fObjects[index];
   612     if (prev != object) {
   613         delete prev;
   614         prev = object;
   615     }
   616 }
   618 void SkJSON::Array::setArray(int index, Array* array) {
   619     SkASSERT((unsigned)index < (unsigned)fCount);
   620     Array*& prev = fArray.fArrays[index];
   621     if (prev != array) {
   622         delete prev;
   623         prev = array;
   624     }
   625 }
   627 void SkJSON::Array::setString(int index, const char str[]) {
   628     SkASSERT((unsigned)index < (unsigned)fCount);
   629     char*& prev = fArray.fStrings[index];
   630     if (prev != str) {
   631         free_string(prev);
   632         prev = dup_string(str);
   633     }
   634 }

mercurial