123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542 |
- // This file is generated by Values_cpp.template.
- // Copyright 2016 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- //#include "Values.h"
- #include "{{config.crdtp.dir}}/cbor.h"
- {% for namespace in config.protocol.namespace %}
- namespace {{namespace}} {
- {% endfor %}
- namespace {
- using {{config.crdtp.namespace}}::Status;
- using {{config.crdtp.namespace}}::ParserHandler;
- using {{config.crdtp.namespace}}::span;
- namespace cbor {
- using {{config.crdtp.namespace}}::cbor::ParseCBOR;
- using {{config.crdtp.namespace}}::cbor::EncodeBinary;
- using {{config.crdtp.namespace}}::cbor::EncodeDouble;
- using {{config.crdtp.namespace}}::cbor::EncodeFalse;
- using {{config.crdtp.namespace}}::cbor::EncodeFromLatin1;
- using {{config.crdtp.namespace}}::cbor::EncodeFromUTF16;
- using {{config.crdtp.namespace}}::cbor::EncodeIndefiniteLengthArrayStart;
- using {{config.crdtp.namespace}}::cbor::EncodeIndefiniteLengthMapStart;
- using {{config.crdtp.namespace}}::cbor::EncodeInt32;
- using {{config.crdtp.namespace}}::cbor::EncodeNull;
- using {{config.crdtp.namespace}}::cbor::EncodeStop;
- using {{config.crdtp.namespace}}::cbor::EncodeString8;
- using {{config.crdtp.namespace}}::cbor::EncodeTrue;
- using {{config.crdtp.namespace}}::cbor::EnvelopeEncoder;
- } // namespace cbor
- // Uses the parsing events received from driver of |ParserHandler|
- // (e.g. cbor::ParseCBOR) into a protocol::Value instance.
- class ValueParserHandler : public ParserHandler {
- public:
- // Provides the parsed protocol::Value.
- std::unique_ptr<Value> ReleaseRoot() { return std::move(root_); }
- // The first parsing error encountered; |status().ok()| is the default.
- Status status() const { return status_; }
- private:
- //
- // Implementation of ParserHandler.
- //
- void HandleMapBegin() override {
- if (!status_.ok()) return;
- std::unique_ptr<DictionaryValue> dict = DictionaryValue::create();
- DictionaryValue* dict_ptr = dict.get();
- AddValueToParent(std::move(dict));
- stack_.emplace_back(dict_ptr);
- }
- void HandleMapEnd() override {
- if (!status_.ok()) return;
- DCHECK(!stack_.empty());
- DCHECK(stack_.back().is_dict);
- stack_.pop_back();
- }
- void HandleArrayBegin() override {
- if (!status_.ok()) return;
- std::unique_ptr<ListValue> list = ListValue::create();
- ListValue* list_ptr = list.get();
- AddValueToParent(std::move(list));
- stack_.emplace_back(list_ptr);
- }
- void HandleArrayEnd() override {
- if (!status_.ok()) return;
- DCHECK(!stack_.empty());
- DCHECK(!stack_.back().is_dict);
- stack_.pop_back();
- }
- void HandleString8(span<uint8_t> chars) override {
- AddStringToParent(StringUtil::fromUTF8(chars.data(), chars.size()));
- }
- void HandleString16(span<uint16_t> chars) override {
- AddStringToParent(
- StringUtil::fromUTF16LE(chars.data(), chars.size()));
- }
- void HandleBinary(span<uint8_t> bytes) override {
- AddValueToParent(
- BinaryValue::create(Binary::fromSpan(bytes.data(), bytes.size())));
- }
- void HandleDouble(double value) override {
- AddValueToParent(FundamentalValue::create(value));
- }
- void HandleInt32(int32_t value) override {
- AddValueToParent(FundamentalValue::create(value));
- }
- void HandleBool(bool value) override {
- AddValueToParent(FundamentalValue::create(value));
- }
- void HandleNull() override {
- AddValueToParent(Value::null());
- }
- void HandleError(Status error) override {
- status_ = error;
- }
- //
- // Adding strings and values to the parent value.
- // Strings are handled separately because they can be keys for
- // dictionary values.
- //
- void AddStringToParent(String str) {
- if (!status_.ok()) return;
- if (!root_) {
- DCHECK(!key_is_pending_);
- root_ = StringValue::create(str);
- } else if (stack_.back().is_dict) {
- // If we already have a pending key, then this is the value of the
- // key/value pair. Otherwise, it's the new pending key.
- if (key_is_pending_) {
- stack_.back().dict->setString(pending_key_, str);
- key_is_pending_ = false;
- } else {
- pending_key_ = std::move(str);
- key_is_pending_ = true;
- }
- } else { // Top of the stack is a list.
- DCHECK(!key_is_pending_);
- stack_.back().list->pushValue(StringValue::create(str));
- }
- }
- void AddValueToParent(std::unique_ptr<Value> value) {
- if (!status_.ok()) return;
- if (!root_) {
- DCHECK(!key_is_pending_);
- root_ = std::move(value);
- } else if (stack_.back().is_dict) {
- DCHECK(key_is_pending_);
- stack_.back().dict->setValue(pending_key_, std::move(value));
- key_is_pending_ = false;
- } else { // Top of the stack is a list.
- DCHECK(!key_is_pending_);
- stack_.back().list->pushValue(std::move(value));
- }
- }
- // |status_.ok()| is the default; if we receive an error event
- // we keep the first one and stop modifying any other state.
- Status status_;
- // The root of the parsed protocol::Value tree.
- std::unique_ptr<Value> root_;
- // If root_ is a list or a dictionary, this stack keeps track of
- // the container we're currently parsing as well as its ancestors.
- struct ContainerState {
- ContainerState(DictionaryValue* dict) : is_dict(true), dict(dict) {}
- ContainerState(ListValue* list) : is_dict(false), list(list) {}
- bool is_dict;
- union {
- DictionaryValue* dict;
- ListValue* list;
- };
- };
- std::vector<ContainerState> stack_;
- // For maps, keys and values are alternating events, so we keep the
- // key around and process it when the value arrives.
- bool key_is_pending_ = false;
- String pending_key_;
- };
- } // anonymous namespace
- // static
- std::unique_ptr<Value> Value::parseBinary(const uint8_t* data, size_t size) {
- ValueParserHandler handler;
- cbor::ParseCBOR(span<uint8_t>(data, size), &handler);
- // TODO(johannes): We have decent error info in handler.status(); provide
- // a richer interface that makes this available to client code.
- if (handler.status().ok())
- return handler.ReleaseRoot();
- return nullptr;
- }
- bool Value::asBoolean(bool*) const
- {
- return false;
- }
- bool Value::asDouble(double*) const
- {
- return false;
- }
- bool Value::asInteger(int*) const
- {
- return false;
- }
- bool Value::asString(String*) const
- {
- return false;
- }
- bool Value::asBinary(Binary*) const
- {
- return false;
- }
- void Value::AppendSerialized(std::vector<uint8_t>* bytes) const {
- DCHECK(m_type == TypeNull);
- bytes->push_back(cbor::EncodeNull());
- }
- std::unique_ptr<Value> Value::clone() const
- {
- return Value::null();
- }
- bool FundamentalValue::asBoolean(bool* output) const
- {
- if (type() != TypeBoolean)
- return false;
- *output = m_boolValue;
- return true;
- }
- bool FundamentalValue::asDouble(double* output) const
- {
- if (type() == TypeDouble) {
- *output = m_doubleValue;
- return true;
- }
- if (type() == TypeInteger) {
- *output = m_integerValue;
- return true;
- }
- return false;
- }
- bool FundamentalValue::asInteger(int* output) const
- {
- if (type() != TypeInteger)
- return false;
- *output = m_integerValue;
- return true;
- }
- void FundamentalValue::AppendSerialized(std::vector<uint8_t>* bytes) const {
- switch (type()) {
- case TypeDouble:
- cbor::EncodeDouble(m_doubleValue, bytes);
- return;
- case TypeInteger:
- cbor::EncodeInt32(m_integerValue, bytes);
- return;
- case TypeBoolean:
- bytes->push_back(m_boolValue ? cbor::EncodeTrue() : cbor::EncodeFalse());
- return;
- default:
- DCHECK(false);
- }
- }
- std::unique_ptr<Value> FundamentalValue::clone() const
- {
- switch (type()) {
- case TypeDouble: return FundamentalValue::create(m_doubleValue);
- case TypeInteger: return FundamentalValue::create(m_integerValue);
- case TypeBoolean: return FundamentalValue::create(m_boolValue);
- default:
- DCHECK(false);
- }
- return nullptr;
- }
- bool StringValue::asString(String* output) const
- {
- *output = m_stringValue;
- return true;
- }
- namespace {
- // This routine distinguishes between the current encoding for a given
- // string |s|, and calls encoding routines that will
- // - Ensure that all ASCII strings end up being encoded as UTF8 in
- // the wire format - e.g., EncodeFromUTF16 will detect ASCII and
- // do the (trivial) transcode to STRING8 on the wire, but if it's
- // not ASCII it'll do STRING16.
- // - Select a format that's cheap to convert to. E.g., we don't
- // have LATIN1 on the wire, so we call EncodeFromLatin1 which
- // transcodes to UTF8 if needed.
- void EncodeString(const String& s, std::vector<uint8_t>* out) {
- if (StringUtil::CharacterCount(s) == 0) {
- cbor::EncodeString8(span<uint8_t>(nullptr, 0), out); // Empty string.
- } else if (StringUtil::CharactersLatin1(s)) {
- cbor::EncodeFromLatin1(span<uint8_t>(StringUtil::CharactersLatin1(s),
- StringUtil::CharacterCount(s)),
- out);
- } else if (StringUtil::CharactersUTF16(s)) {
- cbor::EncodeFromUTF16(span<uint16_t>(StringUtil::CharactersUTF16(s),
- StringUtil::CharacterCount(s)),
- out);
- } else if (StringUtil::CharactersUTF8(s)) {
- cbor::EncodeString8(span<uint8_t>(StringUtil::CharactersUTF8(s),
- StringUtil::CharacterCount(s)),
- out);
- }
- }
- } // namespace
- void StringValue::AppendSerialized(std::vector<uint8_t>* bytes) const {
- EncodeString(m_stringValue, bytes);
- }
- std::unique_ptr<Value> StringValue::clone() const
- {
- return StringValue::create(m_stringValue);
- }
- bool BinaryValue::asBinary(Binary* output) const
- {
- *output = m_binaryValue;
- return true;
- }
- void BinaryValue::AppendSerialized(std::vector<uint8_t>* bytes) const {
- cbor::EncodeBinary(span<uint8_t>(m_binaryValue.data(),
- m_binaryValue.size()), bytes);
- }
- std::unique_ptr<Value> BinaryValue::clone() const
- {
- return BinaryValue::create(m_binaryValue);
- }
- DictionaryValue::~DictionaryValue()
- {
- }
- void DictionaryValue::setBoolean(const String& name, bool value)
- {
- setValue(name, FundamentalValue::create(value));
- }
- void DictionaryValue::setInteger(const String& name, int value)
- {
- setValue(name, FundamentalValue::create(value));
- }
- void DictionaryValue::setDouble(const String& name, double value)
- {
- setValue(name, FundamentalValue::create(value));
- }
- void DictionaryValue::setString(const String& name, const String& value)
- {
- setValue(name, StringValue::create(value));
- }
- void DictionaryValue::setValue(const String& name, std::unique_ptr<Value> value)
- {
- set(name, value);
- }
- void DictionaryValue::setObject(const String& name, std::unique_ptr<DictionaryValue> value)
- {
- set(name, value);
- }
- void DictionaryValue::setArray(const String& name, std::unique_ptr<ListValue> value)
- {
- set(name, value);
- }
- bool DictionaryValue::getBoolean(const String& name, bool* output) const
- {
- protocol::Value* value = get(name);
- if (!value)
- return false;
- return value->asBoolean(output);
- }
- bool DictionaryValue::getInteger(const String& name, int* output) const
- {
- Value* value = get(name);
- if (!value)
- return false;
- return value->asInteger(output);
- }
- bool DictionaryValue::getDouble(const String& name, double* output) const
- {
- Value* value = get(name);
- if (!value)
- return false;
- return value->asDouble(output);
- }
- bool DictionaryValue::getString(const String& name, String* output) const
- {
- protocol::Value* value = get(name);
- if (!value)
- return false;
- return value->asString(output);
- }
- DictionaryValue* DictionaryValue::getObject(const String& name) const
- {
- return DictionaryValue::cast(get(name));
- }
- protocol::ListValue* DictionaryValue::getArray(const String& name) const
- {
- return ListValue::cast(get(name));
- }
- protocol::Value* DictionaryValue::get(const String& name) const
- {
- Dictionary::const_iterator it = m_data.find(name);
- if (it == m_data.end())
- return nullptr;
- return it->second.get();
- }
- DictionaryValue::Entry DictionaryValue::at(size_t index) const
- {
- const String key = m_order[index];
- return std::make_pair(key, m_data.find(key)->second.get());
- }
- bool DictionaryValue::booleanProperty(const String& name, bool defaultValue) const
- {
- bool result = defaultValue;
- getBoolean(name, &result);
- return result;
- }
- int DictionaryValue::integerProperty(const String& name, int defaultValue) const
- {
- int result = defaultValue;
- getInteger(name, &result);
- return result;
- }
- double DictionaryValue::doubleProperty(const String& name, double defaultValue) const
- {
- double result = defaultValue;
- getDouble(name, &result);
- return result;
- }
- void DictionaryValue::remove(const String& name)
- {
- m_data.erase(name);
- m_order.erase(std::remove(m_order.begin(), m_order.end(), name), m_order.end());
- }
- void DictionaryValue::AppendSerialized(std::vector<uint8_t>* bytes) const {
- cbor::EnvelopeEncoder encoder;
- encoder.EncodeStart(bytes);
- bytes->push_back(cbor::EncodeIndefiniteLengthMapStart());
- for (size_t i = 0; i < m_order.size(); ++i) {
- const String& key = m_order[i];
- Dictionary::const_iterator value = m_data.find(key);
- DCHECK(value != m_data.cend() && value->second);
- EncodeString(key, bytes);
- value->second->AppendSerialized(bytes);
- }
- bytes->push_back(cbor::EncodeStop());
- encoder.EncodeStop(bytes);
- }
- std::unique_ptr<Value> DictionaryValue::clone() const
- {
- std::unique_ptr<DictionaryValue> result = DictionaryValue::create();
- for (size_t i = 0; i < m_order.size(); ++i) {
- String key = m_order[i];
- Dictionary::const_iterator value = m_data.find(key);
- DCHECK(value != m_data.cend() && value->second);
- result->setValue(key, value->second->clone());
- }
- return result;
- }
- DictionaryValue::DictionaryValue()
- : Value(TypeObject)
- {
- }
- ListValue::~ListValue()
- {
- }
- void ListValue::AppendSerialized(std::vector<uint8_t>* bytes) const {
- cbor::EnvelopeEncoder encoder;
- encoder.EncodeStart(bytes);
- bytes->push_back(cbor::EncodeIndefiniteLengthArrayStart());
- for (size_t i = 0; i < m_data.size(); ++i) {
- m_data[i]->AppendSerialized(bytes);
- }
- bytes->push_back(cbor::EncodeStop());
- encoder.EncodeStop(bytes);
- }
- std::unique_ptr<Value> ListValue::clone() const
- {
- std::unique_ptr<ListValue> result = ListValue::create();
- for (const std::unique_ptr<protocol::Value>& value : m_data)
- result->pushValue(value->clone());
- return result;
- }
- ListValue::ListValue()
- : Value(TypeArray)
- {
- }
- void ListValue::pushValue(std::unique_ptr<protocol::Value> value)
- {
- DCHECK(value);
- m_data.push_back(std::move(value));
- }
- protocol::Value* ListValue::at(size_t index)
- {
- DCHECK_LT(index, m_data.size());
- return m_data[index].get();
- }
- {% for namespace in config.protocol.namespace %}
- } // namespace {{namespace}}
- {% endfor %}
|