tools/profiler/JSStreamWriter.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include "JSStreamWriter.h"
     8 #include "mozilla/ArrayUtils.h" // for ArrayLength
     9 #include "nsDataHashtable.h"
    10 #include "nsString.h"
    11 #include "nsTArray.h"
    12 #include "nsUTF8Utils.h"
    14 #if _MSC_VER
    15  #define snprintf _snprintf
    16 #endif
    18 #define ARRAY (void*)1
    19 #define OBJECT (void*)2
    21 // Escape a UTF8 string to a stream. When an illegal encoding
    22 // is found it will insert "INVALID" and the function will return.
    23 static void EscapeToStream(std::ostream& stream, const char* str) {
    24   stream << "\"";
    26   size_t len = strlen(str);
    27   const char* end = &str[len];
    28   while (str < end) {
    29     bool err;
    30     const char* utf8CharStart = str;
    31     uint32_t ucs4Char = UTF8CharEnumerator::NextChar(&str, end, &err);
    33     if (err) {
    34       // Encoding error
    35       stream << "INVALID\"";
    36       return;
    37     }
    39     // See http://www.ietf.org/rfc/rfc4627.txt?number=4627
    40     // characters that must be escaped: quotation mark,
    41     // reverse solidus, and the control characters
    42     // (U+0000 through U+001F).
    43     if (ucs4Char == '\"') {
    44       stream << "\\\"";
    45     } else if (ucs4Char == '\\') {
    46       stream << "\\\\";
    47     } else if (ucs4Char > 0xFF) {
    48       char16_t chr[2];
    49       ConvertUTF8toUTF16 encoder(chr);
    50       encoder.write(utf8CharStart, uint32_t(str-utf8CharStart));
    51       char escChar[13];
    52       snprintf(escChar, mozilla::ArrayLength(escChar), "\\u%04X\\u%04X", chr[0], chr[1]);
    53       stream << escChar;
    54     } else if (ucs4Char < 0x1F || ucs4Char > 0xFF) {
    55       char escChar[7];
    56       snprintf(escChar, mozilla::ArrayLength(escChar), "\\u%04X", ucs4Char);
    57       stream << escChar;
    58     } else {
    59       stream << char(ucs4Char);
    60     }
    61   }
    62   stream << "\"";
    63 }
    65 JSStreamWriter::JSStreamWriter(std::ostream& aStream)
    66   : mStream(aStream)
    67   , mNeedsComma(false)
    68   , mNeedsName(false)
    69 { }
    71 JSStreamWriter::~JSStreamWriter()
    72 {
    73   MOZ_ASSERT(mStack.GetSize() == 0);
    74 }
    76 void
    77 JSStreamWriter::BeginObject()
    78 {
    79   MOZ_ASSERT(!mNeedsName);
    80   if (mNeedsComma && mStack.Peek() == ARRAY) {
    81     mStream << ",";
    82   }
    83   mStream << "{";
    84   mNeedsComma = false;
    85   mNeedsName = true;
    86   mStack.Push(OBJECT);
    87 }
    89 void
    90 JSStreamWriter::EndObject()
    91 {
    92   MOZ_ASSERT(mStack.Peek() == OBJECT);
    93   mStream << "}";
    94   mNeedsComma = true;
    95   mNeedsName = false;
    96   mStack.Pop();
    97   if (mStack.GetSize() > 0 && mStack.Peek() == OBJECT) {
    98     mNeedsName = true;
    99   }
   100 }
   102 void
   103 JSStreamWriter::BeginArray()
   104 {
   105   MOZ_ASSERT(!mNeedsName);
   106   if (mNeedsComma && mStack.Peek() == ARRAY) {
   107     mStream << ",";
   108   }
   109   mStream << "[";
   110   mNeedsComma = false;
   111   mStack.Push(ARRAY);
   112 }
   114 void
   115 JSStreamWriter::EndArray()
   116 {
   117   MOZ_ASSERT(!mNeedsName);
   118   MOZ_ASSERT(mStack.Peek() == ARRAY);
   119   mStream << "]";
   120   mNeedsComma = true;
   121   mStack.Pop();
   122   if (mStack.GetSize() > 0 && mStack.Peek() == OBJECT) {
   123     mNeedsName = true;
   124   }
   125 }
   127 void
   128 JSStreamWriter::Name(const char *aName)
   129 {
   130   MOZ_ASSERT(mNeedsName);
   131   if (mNeedsComma && mStack.Peek() == OBJECT) {
   132     mStream << ",";
   133   }
   134   EscapeToStream(mStream, aName);
   135   mStream << ":";
   136   mNeedsName = false;
   137 }
   139 void
   140 JSStreamWriter::Value(int aValue)
   141 {
   142   MOZ_ASSERT(!mNeedsName);
   143   if (mNeedsComma && mStack.Peek() == ARRAY) {
   144     mStream << ",";
   145   }
   146   mStream << aValue;
   147   mNeedsComma = true;
   148   if (mStack.Peek() == OBJECT) {
   149     mNeedsName = true;
   150   }
   151 }
   153 void
   154 JSStreamWriter::Value(double aValue)
   155 {
   156   MOZ_ASSERT(!mNeedsName);
   157   if (mNeedsComma && mStack.Peek() == ARRAY) {
   158     mStream << ",";
   159   }
   160   mStream.precision(18);
   161   mStream << aValue;
   162   mNeedsComma = true;
   163   if (mStack.Peek() == OBJECT) {
   164     mNeedsName = true;
   165   }
   166 }
   168 void
   169 JSStreamWriter::Value(const char *aValue)
   170 {
   171   MOZ_ASSERT(!mNeedsName);
   172   if (mNeedsComma && mStack.Peek() == ARRAY) {
   173     mStream << ",";
   174   }
   175   EscapeToStream(mStream, aValue);
   176   mNeedsComma = true;
   177   if (mStack.Peek() == OBJECT) {
   178     mNeedsName = true;
   179   }
   180 }

mercurial