• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// This file is generated by Values_cpp.template.
2
3// Copyright 2016 The Chromium Authors. All rights reserved.
4// Use of this source code is governed by a BSD-style license that can be
5// found in the LICENSE file.
6
7//#include "Values.h"
8
9{% for namespace in config.protocol.namespace %}
10namespace {{namespace}} {
11{% endfor %}
12
13namespace {
14
15const char* const nullValueString = "null";
16const char* const trueValueString = "true";
17const char* const falseValueString = "false";
18
19inline bool escapeChar(uint16_t c, StringBuilder* dst)
20{
21    switch (c) {
22    case '\b': StringUtil::builderAppend(*dst, "\\b"); break;
23    case '\f': StringUtil::builderAppend(*dst, "\\f"); break;
24    case '\n': StringUtil::builderAppend(*dst, "\\n"); break;
25    case '\r': StringUtil::builderAppend(*dst, "\\r"); break;
26    case '\t': StringUtil::builderAppend(*dst, "\\t"); break;
27    case '\\': StringUtil::builderAppend(*dst, "\\\\"); break;
28    case '"': StringUtil::builderAppend(*dst, "\\\""); break;
29    default:
30        return false;
31    }
32    return true;
33}
34
35const char hexDigits[17] = "0123456789ABCDEF";
36
37void appendUnsignedAsHex(uint16_t number, StringBuilder* dst)
38{
39    StringUtil::builderAppend(*dst, "\\u");
40    for (size_t i = 0; i < 4; ++i) {
41        uint16_t c = hexDigits[(number & 0xF000) >> 12];
42        StringUtil::builderAppend(*dst, c);
43        number <<= 4;
44    }
45}
46
47template <typename Char>
48void escapeStringForJSONInternal(const Char* str, unsigned len,
49                                 StringBuilder* dst)
50{
51    for (unsigned i = 0; i < len; ++i) {
52        Char c = str[i];
53        if (escapeChar(c, dst))
54            continue;
55        if (c < 32 || c > 126) {
56            appendUnsignedAsHex(c, dst);
57        } else {
58            StringUtil::builderAppend(*dst, c);
59        }
60    }
61}
62
63// When parsing CBOR, we limit recursion depth for objects and arrays
64// to this constant.
65static constexpr int kStackLimitValues = 1000;
66
67// Below are three parsing routines for CBOR, which cover enough
68// to roundtrip JSON messages.
69std::unique_ptr<DictionaryValue> parseMap(int32_t stack_depth, cbor::CBORTokenizer* tokenizer);
70std::unique_ptr<ListValue> parseArray(int32_t stack_depth, cbor::CBORTokenizer* tokenizer);
71std::unique_ptr<Value> parseValue(int32_t stack_depth, cbor::CBORTokenizer* tokenizer);
72
73// |bytes| must start with the indefinite length array byte, so basically,
74// ParseArray may only be called after an indefinite length array has been
75// detected.
76std::unique_ptr<ListValue> parseArray(int32_t stack_depth, cbor::CBORTokenizer* tokenizer) {
77  DCHECK(tokenizer->TokenTag() == cbor::CBORTokenTag::ARRAY_START);
78  tokenizer->Next();
79  auto list = ListValue::create();
80  while (tokenizer->TokenTag() != cbor::CBORTokenTag::STOP) {
81    // Error::CBOR_UNEXPECTED_EOF_IN_ARRAY
82    if (tokenizer->TokenTag() == cbor::CBORTokenTag::DONE) return nullptr;
83    if (tokenizer->TokenTag() == cbor::CBORTokenTag::ERROR_VALUE) return nullptr;
84    // Parse value.
85    auto value = parseValue(stack_depth, tokenizer);
86    if (!value) return nullptr;
87    list->pushValue(std::move(value));
88  }
89  tokenizer->Next();
90  return list;
91}
92
93std::unique_ptr<Value> parseValue(
94    int32_t stack_depth, cbor::CBORTokenizer* tokenizer) {
95  // Error::CBOR_STACK_LIMIT_EXCEEDED
96  if (stack_depth > kStackLimitValues) return nullptr;
97  // Skip past the envelope to get to what's inside.
98  if (tokenizer->TokenTag() == cbor::CBORTokenTag::ENVELOPE)
99    tokenizer->EnterEnvelope();
100  switch (tokenizer->TokenTag()) {
101    case cbor::CBORTokenTag::ERROR_VALUE:
102      return nullptr;
103    case cbor::CBORTokenTag::DONE:
104      // Error::CBOR_UNEXPECTED_EOF_EXPECTED_VALUE
105      return nullptr;
106    case cbor::CBORTokenTag::TRUE_VALUE: {
107      std::unique_ptr<Value> value = FundamentalValue::create(true);
108      tokenizer->Next();
109      return value;
110    }
111    case cbor::CBORTokenTag::FALSE_VALUE: {
112      std::unique_ptr<Value> value = FundamentalValue::create(false);
113      tokenizer->Next();
114      return value;
115    }
116    case cbor::CBORTokenTag::NULL_VALUE: {
117      std::unique_ptr<Value> value = FundamentalValue::null();
118      tokenizer->Next();
119      return value;
120    }
121    case cbor::CBORTokenTag::INT32: {
122      std::unique_ptr<Value> value = FundamentalValue::create(tokenizer->GetInt32());
123      tokenizer->Next();
124      return value;
125    }
126    case cbor::CBORTokenTag::DOUBLE: {
127      std::unique_ptr<Value> value = FundamentalValue::create(tokenizer->GetDouble());
128      tokenizer->Next();
129      return value;
130    }
131    case cbor::CBORTokenTag::STRING8: {
132      span<uint8_t> str = tokenizer->GetString8();
133      std::unique_ptr<Value> value =
134          StringValue::create(StringUtil::fromUTF8(str.data(), str.size()));
135      tokenizer->Next();
136      return value;
137    }
138    case cbor::CBORTokenTag::STRING16: {
139      span<uint8_t> wire = tokenizer->GetString16WireRep();
140      DCHECK_EQ(wire.size() & 1, 0u);
141      std::unique_ptr<Value> value = StringValue::create(StringUtil::fromUTF16(
142          reinterpret_cast<const uint16_t*>(wire.data()), wire.size() / 2));
143      tokenizer->Next();
144      return value;
145    }
146    case cbor::CBORTokenTag::BINARY: {
147      span<uint8_t> payload = tokenizer->GetBinary();
148      tokenizer->Next();
149      return BinaryValue::create(Binary::fromSpan(payload.data(), payload.size()));
150    }
151    case cbor::CBORTokenTag::MAP_START:
152      return parseMap(stack_depth + 1, tokenizer);
153    case cbor::CBORTokenTag::ARRAY_START:
154      return parseArray(stack_depth + 1, tokenizer);
155    default:
156      // Error::CBOR_UNSUPPORTED_VALUE
157      return nullptr;
158  }
159}
160
161// |bytes| must start with the indefinite length array byte, so basically,
162// ParseArray may only be called after an indefinite length array has been
163// detected.
164std::unique_ptr<DictionaryValue> parseMap(
165    int32_t stack_depth, cbor::CBORTokenizer* tokenizer) {
166  auto dict = DictionaryValue::create();
167  tokenizer->Next();
168  while (tokenizer->TokenTag() != cbor::CBORTokenTag::STOP) {
169    if (tokenizer->TokenTag() == cbor::CBORTokenTag::DONE) {
170      // Error::CBOR_UNEXPECTED_EOF_IN_MAP
171      return nullptr;
172    }
173    if (tokenizer->TokenTag() == cbor::CBORTokenTag::ERROR_VALUE) return nullptr;
174    // Parse key.
175    String key;
176    if (tokenizer->TokenTag() == cbor::CBORTokenTag::STRING8) {
177      span<uint8_t> key_span = tokenizer->GetString8();
178      key = StringUtil::fromUTF8(key_span.data(), key_span.size());
179      tokenizer->Next();
180    } else if (tokenizer->TokenTag() == cbor::CBORTokenTag::STRING16) {
181      return nullptr;  // STRING16 not supported yet.
182    } else {
183      // Error::CBOR_INVALID_MAP_KEY
184      return nullptr;
185    }
186    // Parse value.
187    auto value = parseValue(stack_depth, tokenizer);
188    if (!value) return nullptr;
189    dict->setValue(key, std::move(value));
190  }
191  tokenizer->Next();
192  return dict;
193}
194
195} // anonymous namespace
196
197// static
198std::unique_ptr<Value> Value::parseBinary(const uint8_t* data, size_t size) {
199  span<uint8_t> bytes(data, size);
200
201  // Error::CBOR_NO_INPUT
202  if (bytes.empty()) return nullptr;
203
204  // Error::CBOR_INVALID_START_BYTE
205  if (bytes[0] != cbor::InitialByteForEnvelope()) return nullptr;
206
207  cbor::CBORTokenizer tokenizer(bytes);
208  if (tokenizer.TokenTag() == cbor::CBORTokenTag::ERROR_VALUE) return nullptr;
209
210  // We checked for the envelope start byte above, so the tokenizer
211  // must agree here, since it's not an error.
212  DCHECK(tokenizer.TokenTag() == cbor::CBORTokenTag::ENVELOPE);
213  tokenizer.EnterEnvelope();
214  // Error::MAP_START_EXPECTED
215  if (tokenizer.TokenTag() != cbor::CBORTokenTag::MAP_START) return nullptr;
216  std::unique_ptr<Value> result = parseMap(/*stack_depth=*/1, &tokenizer);
217  if (!result) return nullptr;
218  if (tokenizer.TokenTag() == cbor::CBORTokenTag::DONE) return result;
219  if (tokenizer.TokenTag() == cbor::CBORTokenTag::ERROR_VALUE) return nullptr;
220  // Error::CBOR_TRAILING_JUNK
221  return nullptr;
222}
223
224bool Value::asBoolean(bool*) const
225{
226    return false;
227}
228
229bool Value::asDouble(double*) const
230{
231    return false;
232}
233
234bool Value::asInteger(int*) const
235{
236    return false;
237}
238
239bool Value::asString(String*) const
240{
241    return false;
242}
243
244bool Value::asBinary(Binary*) const
245{
246    return false;
247}
248
249void Value::writeJSON(StringBuilder* output) const
250{
251    DCHECK(m_type == TypeNull);
252    StringUtil::builderAppend(*output, nullValueString, 4);
253}
254
255void Value::writeBinary(std::vector<uint8_t>* bytes) const {
256    DCHECK(m_type == TypeNull);
257    bytes->push_back(cbor::EncodeNull());
258}
259
260std::unique_ptr<Value> Value::clone() const
261{
262    return Value::null();
263}
264
265String Value::toJSONString() const
266{
267    StringBuilder result;
268    StringUtil::builderReserve(result, 512);
269    writeJSON(&result);
270    return StringUtil::builderToString(result);
271}
272
273String Value::serializeToJSON() {
274    return toJSONString();
275}
276
277std::vector<uint8_t> Value::serializeToBinary() {
278    std::vector<uint8_t> bytes;
279    writeBinary(&bytes);
280    return bytes;
281}
282
283bool FundamentalValue::asBoolean(bool* output) const
284{
285    if (type() != TypeBoolean)
286        return false;
287    *output = m_boolValue;
288    return true;
289}
290
291bool FundamentalValue::asDouble(double* output) const
292{
293    if (type() == TypeDouble) {
294        *output = m_doubleValue;
295        return true;
296    }
297    if (type() == TypeInteger) {
298        *output = m_integerValue;
299        return true;
300    }
301    return false;
302}
303
304bool FundamentalValue::asInteger(int* output) const
305{
306    if (type() != TypeInteger)
307        return false;
308    *output = m_integerValue;
309    return true;
310}
311
312void FundamentalValue::writeJSON(StringBuilder* output) const
313{
314    DCHECK(type() == TypeBoolean || type() == TypeInteger || type() == TypeDouble);
315    if (type() == TypeBoolean) {
316        if (m_boolValue)
317            StringUtil::builderAppend(*output, trueValueString, 4);
318        else
319            StringUtil::builderAppend(*output, falseValueString, 5);
320    } else if (type() == TypeDouble) {
321        if (!std::isfinite(m_doubleValue)) {
322            StringUtil::builderAppend(*output, nullValueString, 4);
323            return;
324        }
325        StringUtil::builderAppend(*output, StringUtil::fromDouble(m_doubleValue));
326    } else if (type() == TypeInteger) {
327        StringUtil::builderAppend(*output, StringUtil::fromInteger(m_integerValue));
328    }
329}
330
331void FundamentalValue::writeBinary(std::vector<uint8_t>* bytes) const {
332    switch (type()) {
333    case TypeDouble:
334        cbor::EncodeDouble(m_doubleValue, bytes);
335        return;
336    case TypeInteger:
337        cbor::EncodeInt32(m_integerValue, bytes);
338        return;
339    case TypeBoolean:
340        bytes->push_back(m_boolValue ? cbor::EncodeTrue() : cbor::EncodeFalse());
341        return;
342    default:
343        DCHECK(false);
344    }
345}
346
347std::unique_ptr<Value> FundamentalValue::clone() const
348{
349    switch (type()) {
350    case TypeDouble: return FundamentalValue::create(m_doubleValue);
351    case TypeInteger: return FundamentalValue::create(m_integerValue);
352    case TypeBoolean: return FundamentalValue::create(m_boolValue);
353    default:
354        DCHECK(false);
355    }
356    return nullptr;
357}
358
359bool StringValue::asString(String* output) const
360{
361    *output = m_stringValue;
362    return true;
363}
364
365void StringValue::writeJSON(StringBuilder* output) const
366{
367    DCHECK(type() == TypeString);
368    StringUtil::builderAppendQuotedString(*output, m_stringValue);
369}
370
371namespace {
372// This routine distinguishes between the current encoding for a given
373// string |s|, and calls encoding routines that will
374// - Ensure that all ASCII strings end up being encoded as UTF8 in
375//   the wire format - e.g., EncodeFromUTF16 will detect ASCII and
376//   do the (trivial) transcode to STRING8 on the wire, but if it's
377//   not ASCII it'll do STRING16.
378// - Select a format that's cheap to convert to. E.g., we don't
379//   have LATIN1 on the wire, so we call EncodeFromLatin1 which
380//   transcodes to UTF8 if needed.
381void EncodeString(const String& s, std::vector<uint8_t>* out) {
382  if (StringUtil::CharacterCount(s) == 0) {
383    cbor::EncodeString8(span<uint8_t>(nullptr, 0), out);  // Empty string.
384  } else if (StringUtil::CharactersLatin1(s)) {
385    cbor::EncodeFromLatin1(span<uint8_t>(StringUtil::CharactersLatin1(s),
386		                         StringUtil::CharacterCount(s)),
387                           out);
388  } else if (StringUtil::CharactersUTF16(s)) {
389    cbor::EncodeFromUTF16(span<uint16_t>(StringUtil::CharactersUTF16(s),
390                                         StringUtil::CharacterCount(s)),
391                          out);
392  } else if (StringUtil::CharactersUTF8(s)) {
393    cbor::EncodeString8(span<uint8_t>(StringUtil::CharactersUTF8(s),
394                                      StringUtil::CharacterCount(s)),
395                        out);
396  }
397}
398}  // namespace
399
400void StringValue::writeBinary(std::vector<uint8_t>* bytes) const {
401  EncodeString(m_stringValue, bytes);
402}
403
404std::unique_ptr<Value> StringValue::clone() const
405{
406    return StringValue::create(m_stringValue);
407}
408
409bool BinaryValue::asBinary(Binary* output) const
410{
411    *output = m_binaryValue;
412    return true;
413}
414
415void BinaryValue::writeJSON(StringBuilder* output) const
416{
417    DCHECK(type() == TypeBinary);
418    StringUtil::builderAppendQuotedString(*output, m_binaryValue.toBase64());
419}
420
421void BinaryValue::writeBinary(std::vector<uint8_t>* bytes) const {
422    cbor::EncodeBinary(span<uint8_t>(m_binaryValue.data(),
423                                     m_binaryValue.size()), bytes);
424}
425
426std::unique_ptr<Value> BinaryValue::clone() const
427{
428    return BinaryValue::create(m_binaryValue);
429}
430
431void SerializedValue::writeJSON(StringBuilder* output) const
432{
433    DCHECK(type() == TypeSerialized);
434    StringUtil::builderAppend(*output, m_serializedJSON);
435}
436
437void SerializedValue::writeBinary(std::vector<uint8_t>* output) const
438{
439    DCHECK(type() == TypeSerialized);
440    output->insert(output->end(), m_serializedBinary.begin(), m_serializedBinary.end());
441}
442
443std::unique_ptr<Value> SerializedValue::clone() const
444{
445    return std::unique_ptr<SerializedValue>(new SerializedValue(m_serializedJSON, m_serializedBinary));
446}
447
448DictionaryValue::~DictionaryValue()
449{
450}
451
452void DictionaryValue::setBoolean(const String& name, bool value)
453{
454    setValue(name, FundamentalValue::create(value));
455}
456
457void DictionaryValue::setInteger(const String& name, int value)
458{
459    setValue(name, FundamentalValue::create(value));
460}
461
462void DictionaryValue::setDouble(const String& name, double value)
463{
464    setValue(name, FundamentalValue::create(value));
465}
466
467void DictionaryValue::setString(const String& name, const String& value)
468{
469    setValue(name, StringValue::create(value));
470}
471
472void DictionaryValue::setValue(const String& name, std::unique_ptr<Value> value)
473{
474    set(name, value);
475}
476
477void DictionaryValue::setObject(const String& name, std::unique_ptr<DictionaryValue> value)
478{
479    set(name, value);
480}
481
482void DictionaryValue::setArray(const String& name, std::unique_ptr<ListValue> value)
483{
484    set(name, value);
485}
486
487bool DictionaryValue::getBoolean(const String& name, bool* output) const
488{
489    protocol::Value* value = get(name);
490    if (!value)
491        return false;
492    return value->asBoolean(output);
493}
494
495bool DictionaryValue::getInteger(const String& name, int* output) const
496{
497    Value* value = get(name);
498    if (!value)
499        return false;
500    return value->asInteger(output);
501}
502
503bool DictionaryValue::getDouble(const String& name, double* output) const
504{
505    Value* value = get(name);
506    if (!value)
507        return false;
508    return value->asDouble(output);
509}
510
511bool DictionaryValue::getString(const String& name, String* output) const
512{
513    protocol::Value* value = get(name);
514    if (!value)
515        return false;
516    return value->asString(output);
517}
518
519DictionaryValue* DictionaryValue::getObject(const String& name) const
520{
521    return DictionaryValue::cast(get(name));
522}
523
524protocol::ListValue* DictionaryValue::getArray(const String& name) const
525{
526    return ListValue::cast(get(name));
527}
528
529protocol::Value* DictionaryValue::get(const String& name) const
530{
531    Dictionary::const_iterator it = m_data.find(name);
532    if (it == m_data.end())
533        return nullptr;
534    return it->second.get();
535}
536
537DictionaryValue::Entry DictionaryValue::at(size_t index) const
538{
539    const String key = m_order[index];
540    return std::make_pair(key, m_data.find(key)->second.get());
541}
542
543bool DictionaryValue::booleanProperty(const String& name, bool defaultValue) const
544{
545    bool result = defaultValue;
546    getBoolean(name, &result);
547    return result;
548}
549
550int DictionaryValue::integerProperty(const String& name, int defaultValue) const
551{
552    int result = defaultValue;
553    getInteger(name, &result);
554    return result;
555}
556
557double DictionaryValue::doubleProperty(const String& name, double defaultValue) const
558{
559    double result = defaultValue;
560    getDouble(name, &result);
561    return result;
562}
563
564void DictionaryValue::remove(const String& name)
565{
566    m_data.erase(name);
567    m_order.erase(std::remove(m_order.begin(), m_order.end(), name), m_order.end());
568}
569
570void DictionaryValue::writeJSON(StringBuilder* output) const
571{
572    StringUtil::builderAppend(*output, '{');
573    for (size_t i = 0; i < m_order.size(); ++i) {
574        Dictionary::const_iterator it = m_data.find(m_order[i]);
575        CHECK(it != m_data.end());
576        if (i)
577            StringUtil::builderAppend(*output, ',');
578        StringUtil::builderAppendQuotedString(*output, it->first);
579        StringUtil::builderAppend(*output, ':');
580        it->second->writeJSON(output);
581    }
582    StringUtil::builderAppend(*output, '}');
583}
584
585void DictionaryValue::writeBinary(std::vector<uint8_t>* bytes) const {
586    cbor::EnvelopeEncoder encoder;
587    encoder.EncodeStart(bytes);
588    bytes->push_back(cbor::EncodeIndefiniteLengthMapStart());
589    for (size_t i = 0; i < m_order.size(); ++i) {
590        const String& key = m_order[i];
591        Dictionary::const_iterator value = m_data.find(key);
592        DCHECK(value != m_data.cend() && value->second);
593        EncodeString(key, bytes);
594        value->second->writeBinary(bytes);
595    }
596    bytes->push_back(cbor::EncodeStop());
597    encoder.EncodeStop(bytes);
598}
599
600std::unique_ptr<Value> DictionaryValue::clone() const
601{
602    std::unique_ptr<DictionaryValue> result = DictionaryValue::create();
603    for (size_t i = 0; i < m_order.size(); ++i) {
604        String key = m_order[i];
605        Dictionary::const_iterator value = m_data.find(key);
606        DCHECK(value != m_data.cend() && value->second);
607        result->setValue(key, value->second->clone());
608    }
609    return std::move(result);
610}
611
612DictionaryValue::DictionaryValue()
613    : Value(TypeObject)
614{
615}
616
617ListValue::~ListValue()
618{
619}
620
621void ListValue::writeJSON(StringBuilder* output) const
622{
623    StringUtil::builderAppend(*output, '[');
624    bool first = true;
625    for (const std::unique_ptr<protocol::Value>& value : m_data) {
626        if (!first)
627            StringUtil::builderAppend(*output, ',');
628        value->writeJSON(output);
629        first = false;
630    }
631    StringUtil::builderAppend(*output, ']');
632}
633
634void ListValue::writeBinary(std::vector<uint8_t>* bytes) const {
635    cbor::EnvelopeEncoder encoder;
636    encoder.EncodeStart(bytes);
637    bytes->push_back(cbor::EncodeIndefiniteLengthArrayStart());
638    for (size_t i = 0; i < m_data.size(); ++i) {
639        m_data[i]->writeBinary(bytes);
640    }
641    bytes->push_back(cbor::EncodeStop());
642    encoder.EncodeStop(bytes);
643}
644
645std::unique_ptr<Value> ListValue::clone() const
646{
647    std::unique_ptr<ListValue> result = ListValue::create();
648    for (const std::unique_ptr<protocol::Value>& value : m_data)
649        result->pushValue(value->clone());
650    return std::move(result);
651}
652
653ListValue::ListValue()
654    : Value(TypeArray)
655{
656}
657
658void ListValue::pushValue(std::unique_ptr<protocol::Value> value)
659{
660    DCHECK(value);
661    m_data.push_back(std::move(value));
662}
663
664protocol::Value* ListValue::at(size_t index)
665{
666    DCHECK_LT(index, m_data.size());
667    return m_data[index].get();
668}
669
670void escapeLatinStringForJSON(const uint8_t* str, unsigned len, StringBuilder* dst)
671{
672    escapeStringForJSONInternal<uint8_t>(str, len, dst);
673}
674
675void escapeWideStringForJSON(const uint16_t* str, unsigned len, StringBuilder* dst)
676{
677    escapeStringForJSONInternal<uint16_t>(str, len, dst);
678}
679
680{% for namespace in config.protocol.namespace %}
681} // namespace {{namespace}}
682{% endfor %}
683