%PDF- <> %âãÏÓ endobj 2 0 obj <> endobj 3 0 obj <>/ExtGState<>/ProcSet[/PDF/Text/ImageB/ImageC/ImageI] >>/Annots[ 28 0 R 29 0 R] /MediaBox[ 0 0 595.5 842.25] /Contents 4 0 R/Group<>/Tabs/S>> endobj ºaâÚÎΞ-ÌE1ÍØÄ÷{òò2ÿ ÛÖ^ÔÀá TÎ{¦?§®¥kuµùÕ5sLOšuY>endobj 2 0 obj<>endobj 2 0 obj<>endobj 2 0 obj<>endobj 2 0 obj<> endobj 2 0 obj<>endobj 2 0 obj<>es 3 0 R>> endobj 2 0 obj<> ox[ 0.000000 0.000000 609.600000 935.600000]/Fi endobj 3 0 obj<> endobj 7 1 obj<>/ProcSet[/PDF/Text/ImageB/ImageC/ImageI]>>/Subtype/Form>> stream
// This file is generated by ErrorSupport_h.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. #ifndef node_inspector_protocol_ErrorSupport_h #define node_inspector_protocol_ErrorSupport_h #include "src/node/inspector/protocol/Forward.h" namespace node { namespace inspector { namespace protocol { class ErrorSupport { public: ErrorSupport(); ~ErrorSupport(); void push(); void setName(const char*); void setName(const String&); void pop(); void addError(const char*); void addError(const String&); bool hasErrors(); String errors(); private: std::vector<String> m_path; std::vector<String> m_errors; }; } // namespace node } // namespace inspector } // namespace protocol #endif // !defined(node_inspector_protocol_ErrorSupport_h) // This file is generated by Values_h.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. #ifndef node_inspector_protocol_Values_h #define node_inspector_protocol_Values_h //#include "Allocator.h" //#include "Forward.h" namespace node { namespace inspector { namespace protocol { class ListValue; class DictionaryValue; class Value; class Value : public Serializable { PROTOCOL_DISALLOW_COPY(Value); public: virtual ~Value() override { } static std::unique_ptr<Value> null() { return std::unique_ptr<Value>(new Value()); } static std::unique_ptr<Value> parseBinary(const uint8_t* data, size_t size); enum ValueType { TypeNull = 0, TypeBoolean, TypeInteger, TypeDouble, TypeString, TypeBinary, TypeObject, TypeArray, TypeSerialized, TypeImported }; ValueType type() const { return m_type; } bool isNull() const { return m_type == TypeNull; } virtual bool asBoolean(bool* output) const; virtual bool asDouble(double* output) const; virtual bool asInteger(int* output) const; virtual bool asString(String* output) const; virtual bool asBinary(Binary* output) const; virtual void writeJSON(StringBuilder* output) const; virtual void writeBinary(std::vector<uint8_t>* bytes) const; virtual std::unique_ptr<Value> clone() const; String toJSONString() const; String serializeToJSON() override; std::vector<uint8_t> serializeToBinary() override; protected: Value() : m_type(TypeNull) { } explicit Value(ValueType type) : m_type(type) { } private: friend class DictionaryValue; friend class ListValue; ValueType m_type; }; class FundamentalValue : public Value { public: static std::unique_ptr<FundamentalValue> create(bool value) { return std::unique_ptr<FundamentalValue>(new FundamentalValue(value)); } static std::unique_ptr<FundamentalValue> create(int value) { return std::unique_ptr<FundamentalValue>(new FundamentalValue(value)); } static std::unique_ptr<FundamentalValue> create(double value) { return std::unique_ptr<FundamentalValue>(new FundamentalValue(value)); } bool asBoolean(bool* output) const override; bool asDouble(double* output) const override; bool asInteger(int* output) const override; void writeJSON(StringBuilder* output) const override; void writeBinary(std::vector<uint8_t>* bytes) const override; std::unique_ptr<Value> clone() const override; private: explicit FundamentalValue(bool value) : Value(TypeBoolean), m_boolValue(value) { } explicit FundamentalValue(int value) : Value(TypeInteger), m_integerValue(value) { } explicit FundamentalValue(double value) : Value(TypeDouble), m_doubleValue(value) { } union { bool m_boolValue; double m_doubleValue; int m_integerValue; }; }; class StringValue : public Value { public: static std::unique_ptr<StringValue> create(const String& value) { return std::unique_ptr<StringValue>(new StringValue(value)); } static std::unique_ptr<StringValue> create(const char* value) { return std::unique_ptr<StringValue>(new StringValue(value)); } bool asString(String* output) const override; void writeJSON(StringBuilder* output) const override; void writeBinary(std::vector<uint8_t>* bytes) const override; std::unique_ptr<Value> clone() const override; private: explicit StringValue(const String& value) : Value(TypeString), m_stringValue(value) { } explicit StringValue(const char* value) : Value(TypeString), m_stringValue(value) { } String m_stringValue; }; class BinaryValue : public Value { public: static std::unique_ptr<BinaryValue> create(const Binary& value) { return std::unique_ptr<BinaryValue>(new BinaryValue(value)); } bool asBinary(Binary* output) const override; void writeJSON(StringBuilder* output) const override; void writeBinary(std::vector<uint8_t>* bytes) const override; std::unique_ptr<Value> clone() const override; private: explicit BinaryValue(const Binary& value) : Value(TypeBinary), m_binaryValue(value) { } Binary m_binaryValue; }; class SerializedValue : public Value { public: static std::unique_ptr<SerializedValue> fromJSON(const String& value) { return std::unique_ptr<SerializedValue>(new SerializedValue(value)); } static std::unique_ptr<SerializedValue> fromBinary(std::vector<uint8_t> value) { return std::unique_ptr<SerializedValue>(new SerializedValue(std::move(value))); } void writeJSON(StringBuilder* output) const override; void writeBinary(std::vector<uint8_t>* bytes) const override; std::unique_ptr<Value> clone() const override; private: explicit SerializedValue(const String& json) : Value(TypeSerialized), m_serializedJSON(json) { } explicit SerializedValue(std::vector<uint8_t> binary) : Value(TypeSerialized), m_serializedBinary(std::move(binary)) { } SerializedValue(const String& json, const std::vector<uint8_t>& binary) : Value(TypeSerialized), m_serializedJSON(json), m_serializedBinary(binary) { } String m_serializedJSON; std::vector<uint8_t> m_serializedBinary; }; class DictionaryValue : public Value { public: using Entry = std::pair<String, Value*>; static std::unique_ptr<DictionaryValue> create() { return std::unique_ptr<DictionaryValue>(new DictionaryValue()); } static DictionaryValue* cast(Value* value) { if (!value || value->type() != TypeObject) return nullptr; return static_cast<DictionaryValue*>(value); } static std::unique_ptr<DictionaryValue> cast(std::unique_ptr<Value> value) { return std::unique_ptr<DictionaryValue>(DictionaryValue::cast(value.release())); } void writeJSON(StringBuilder* output) const override; void writeBinary(std::vector<uint8_t>* bytes) const override; std::unique_ptr<Value> clone() const override; size_t size() const { return m_data.size(); } void setBoolean(const String& name, bool); void setInteger(const String& name, int); void setDouble(const String& name, double); void setString(const String& name, const String&); void setValue(const String& name, std::unique_ptr<Value>); void setObject(const String& name, std::unique_ptr<DictionaryValue>); void setArray(const String& name, std::unique_ptr<ListValue>); bool getBoolean(const String& name, bool* output) const; bool getInteger(const String& name, int* output) const; bool getDouble(const String& name, double* output) const; bool getString(const String& name, String* output) const; DictionaryValue* getObject(const String& name) const; ListValue* getArray(const String& name) const; Value* get(const String& name) const; Entry at(size_t index) const; bool booleanProperty(const String& name, bool defaultValue) const; int integerProperty(const String& name, int defaultValue) const; double doubleProperty(const String& name, double defaultValue) const; void remove(const String& name); ~DictionaryValue() override; private: DictionaryValue(); template<typename T> void set(const String& key, std::unique_ptr<T>& value) { DCHECK(value); bool isNew = m_data.find(key) == m_data.end(); m_data[key] = std::move(value); if (isNew) m_order.push_back(key); } using Dictionary = std::unordered_map<String, std::unique_ptr<Value>>; Dictionary m_data; std::vector<String> m_order; }; class ListValue : public Value { public: static std::unique_ptr<ListValue> create() { return std::unique_ptr<ListValue>(new ListValue()); } static ListValue* cast(Value* value) { if (!value || value->type() != TypeArray) return nullptr; return static_cast<ListValue*>(value); } static std::unique_ptr<ListValue> cast(std::unique_ptr<Value> value) { return std::unique_ptr<ListValue>(ListValue::cast(value.release())); } ~ListValue() override; void writeJSON(StringBuilder* output) const override; void writeBinary(std::vector<uint8_t>* bytes) const override; std::unique_ptr<Value> clone() const override; void pushValue(std::unique_ptr<Value>); Value* at(size_t index); size_t size() const { return m_data.size(); } private: ListValue(); std::vector<std::unique_ptr<Value>> m_data; }; void escapeLatinStringForJSON(const uint8_t* str, unsigned len, StringBuilder* dst); void escapeWideStringForJSON(const uint16_t* str, unsigned len, StringBuilder* dst); } // namespace node } // namespace inspector } // namespace protocol #endif // node_inspector_protocol_Values_h // This file is generated by Object_h.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. #ifndef node_inspector_protocol_Object_h #define node_inspector_protocol_Object_h //#include "ErrorSupport.h" //#include "Forward.h" //#include "Values.h" namespace node { namespace inspector { namespace protocol { class Object { public: static std::unique_ptr<Object> fromValue(protocol::Value*, ErrorSupport*); explicit Object(std::unique_ptr<protocol::DictionaryValue>); ~Object(); std::unique_ptr<protocol::DictionaryValue> toValue() const; std::unique_ptr<Object> clone() const; private: std::unique_ptr<protocol::DictionaryValue> m_object; }; } // namespace node } // namespace inspector } // namespace protocol #endif // !defined(node_inspector_protocol_Object_h) // This file is generated by ValueConversions_h.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. #ifndef node_inspector_protocol_ValueConversions_h #define node_inspector_protocol_ValueConversions_h //#include "ErrorSupport.h" //#include "Forward.h" //#include "Values.h" namespace node { namespace inspector { namespace protocol { template<typename T> struct ValueConversions { static std::unique_ptr<T> fromValue(protocol::Value* value, ErrorSupport* errors) { return T::fromValue(value, errors); } static std::unique_ptr<protocol::Value> toValue(T* value) { return value->toValue(); } static std::unique_ptr<protocol::Value> toValue(const std::unique_ptr<T>& value) { return value->toValue(); } }; template<> struct ValueConversions<bool> { static bool fromValue(protocol::Value* value, ErrorSupport* errors) { bool result = false; bool success = value ? value->asBoolean(&result) : false; if (!success) errors->addError("boolean value expected"); return result; } static std::unique_ptr<protocol::Value> toValue(bool value) { return FundamentalValue::create(value); } }; template<> struct ValueConversions<int> { static int fromValue(protocol::Value* value, ErrorSupport* errors) { int result = 0; bool success = value ? value->asInteger(&result) : false; if (!success) errors->addError("integer value expected"); return result; } static std::unique_ptr<protocol::Value> toValue(int value) { return FundamentalValue::create(value); } }; template<> struct ValueConversions<double> { static double fromValue(protocol::Value* value, ErrorSupport* errors) { double result = 0; bool success = value ? value->asDouble(&result) : false; if (!success) errors->addError("double value expected"); return result; } static std::unique_ptr<protocol::Value> toValue(double value) { return FundamentalValue::create(value); } }; template<> struct ValueConversions<String> { static String fromValue(protocol::Value* value, ErrorSupport* errors) { String result; bool success = value ? value->asString(&result) : false; if (!success) errors->addError("string value expected"); return result; } static std::unique_ptr<protocol::Value> toValue(const String& value) { return StringValue::create(value); } }; template<> struct ValueConversions<Binary> { static Binary fromValue(protocol::Value* value, ErrorSupport* errors) { if (!value || (value->type() != Value::TypeBinary && value->type() != Value::TypeString)) { errors->addError("Either string base64 or binary value expected"); return Binary(); } Binary binary; if (value->asBinary(&binary)) return binary; String result; value->asString(&result); bool success; Binary out = Binary::fromBase64(result, &success); if (!success) errors->addError("base64 decoding error"); return out; } static std::unique_ptr<protocol::Value> toValue(const Binary& value) { return BinaryValue::create(value); } }; template<> struct ValueConversions<Value> { static std::unique_ptr<Value> fromValue(protocol::Value* value, ErrorSupport* errors) { bool success = !!value; if (!success) { errors->addError("value expected"); return nullptr; } return value->clone(); } static std::unique_ptr<protocol::Value> toValue(Value* value) { return value->clone(); } static std::unique_ptr<protocol::Value> toValue(const std::unique_ptr<Value>& value) { return value->clone(); } }; template<> struct ValueConversions<DictionaryValue> { static std::unique_ptr<DictionaryValue> fromValue(protocol::Value* value, ErrorSupport* errors) { bool success = value && value->type() == protocol::Value::TypeObject; if (!success) errors->addError("object expected"); return DictionaryValue::cast(value->clone()); } static std::unique_ptr<protocol::Value> toValue(DictionaryValue* value) { return value->clone(); } static std::unique_ptr<protocol::Value> toValue(const std::unique_ptr<DictionaryValue>& value) { return value->clone(); } }; template<> struct ValueConversions<ListValue> { static std::unique_ptr<ListValue> fromValue(protocol::Value* value, ErrorSupport* errors) { bool success = value && value->type() == protocol::Value::TypeArray; if (!success) errors->addError("list expected"); return ListValue::cast(value->clone()); } static std::unique_ptr<protocol::Value> toValue(ListValue* value) { return value->clone(); } static std::unique_ptr<protocol::Value> toValue(const std::unique_ptr<ListValue>& value) { return value->clone(); } }; } // namespace node } // namespace inspector } // namespace protocol #endif // !defined(node_inspector_protocol_ValueConversions_h) // This file is generated by Maybe_h.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. #ifndef node_inspector_protocol_Maybe_h #define node_inspector_protocol_Maybe_h // This macro allows to test for the version of the GNU C++ compiler. // Note that this also applies to compilers that masquerade as GCC, // for example clang and the Intel C++ compiler for Linux. // Use like: // #if IP_GNUC_PREREQ(4, 3, 1) // ... // #endif #if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) #define IP_GNUC_PREREQ(major, minor, patchlevel) \ ((__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= \ ((major)*10000 + (minor)*100 + (patchlevel))) #elif defined(__GNUC__) && defined(__GNUC_MINOR__) #define IP_GNUC_PREREQ(major, minor, patchlevel) \ ((__GNUC__ * 10000 + __GNUC_MINOR__ * 100) >= \ ((major)*10000 + (minor)*100 + (patchlevel))) #else #define IP_GNUC_PREREQ(major, minor, patchlevel) 0 #endif #if defined(__mips64) #define IP_TARGET_ARCH_MIPS64 1 #elif defined(__MIPSEB__) || defined(__MIPSEL__) #define IP_TARGET_ARCH_MIPS 1 #endif // Allowing the use of noexcept by removing the keyword on older compilers that // do not support adding noexcept to default members. #if ((IP_GNUC_PREREQ(4, 9, 0) && !defined(IP_TARGET_ARCH_MIPS) && \ !defined(IP_TARGET_ARCH_MIPS64)) || \ (defined(__clang__) && __cplusplus > 201300L)) #define IP_NOEXCEPT noexcept #else #define IP_NOEXCEPT #endif //#include "Forward.h" namespace node { namespace inspector { namespace protocol { template<typename T> class Maybe { public: Maybe() : m_value() { } Maybe(std::unique_ptr<T> value) : m_value(std::move(value)) { } Maybe(Maybe&& other) IP_NOEXCEPT : m_value(std::move(other.m_value)) {} void operator=(std::unique_ptr<T> value) { m_value = std::move(value); } T* fromJust() const { DCHECK(m_value); return m_value.get(); } T* fromMaybe(T* defaultValue) const { return m_value ? m_value.get() : defaultValue; } bool isJust() const { return !!m_value; } std::unique_ptr<T> takeJust() { DCHECK(m_value); return std::move(m_value); } private: std::unique_ptr<T> m_value; }; template<typename T> class MaybeBase { public: MaybeBase() : m_isJust(false) { } MaybeBase(T value) : m_isJust(true), m_value(value) { } MaybeBase(MaybeBase&& other) IP_NOEXCEPT : m_isJust(other.m_isJust), m_value(std::move(other.m_value)) {} void operator=(T value) { m_value = value; m_isJust = true; } T fromJust() const { DCHECK(m_isJust); return m_value; } T fromMaybe(const T& defaultValue) const { return m_isJust ? m_value : defaultValue; } bool isJust() const { return m_isJust; } T takeJust() { DCHECK(m_isJust); return m_value; } protected: bool m_isJust; T m_value; }; template<> class Maybe<bool> : public MaybeBase<bool> { public: Maybe() { m_value = false; } Maybe(bool value) : MaybeBase(value) { } Maybe(Maybe&& other) IP_NOEXCEPT : MaybeBase(std::move(other)) {} using MaybeBase::operator=; }; template<> class Maybe<int> : public MaybeBase<int> { public: Maybe() { m_value = 0; } Maybe(int value) : MaybeBase(value) { } Maybe(Maybe&& other) IP_NOEXCEPT : MaybeBase(std::move(other)) {} using MaybeBase::operator=; }; template<> class Maybe<double> : public MaybeBase<double> { public: Maybe() { m_value = 0; } Maybe(double value) : MaybeBase(value) { } Maybe(Maybe&& other) IP_NOEXCEPT : MaybeBase(std::move(other)) {} using MaybeBase::operator=; }; template<> class Maybe<String> : public MaybeBase<String> { public: Maybe() { } Maybe(const String& value) : MaybeBase(value) { } Maybe(Maybe&& other) IP_NOEXCEPT : MaybeBase(std::move(other)) {} using MaybeBase::operator=; }; template<> class Maybe<Binary> : public MaybeBase<Binary> { public: Maybe() { } Maybe(Binary value) : MaybeBase(value) { } Maybe(Maybe&& other) IP_NOEXCEPT : MaybeBase(std::move(other)) {} using MaybeBase::operator=; }; } // namespace node } // namespace inspector } // namespace protocol #undef IP_GNUC_PREREQ #undef IP_TARGET_ARCH_MIPS64 #undef IP_TARGET_ARCH_MIPS #undef IP_NOEXCEPT #endif // !defined(node_inspector_protocol_Maybe_h) // This file is generated by Array_h.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. #ifndef node_inspector_protocol_Array_h #define node_inspector_protocol_Array_h //#include "ErrorSupport.h" //#include "Forward.h" //#include "ValueConversions.h" //#include "Values.h" namespace node { namespace inspector { namespace protocol { template<typename T> class Array { public: static std::unique_ptr<Array<T>> create() { return std::unique_ptr<Array<T>>(new Array<T>()); } static std::unique_ptr<Array<T>> fromValue(protocol::Value* value, ErrorSupport* errors) { protocol::ListValue* array = ListValue::cast(value); if (!array) { errors->addError("array expected"); return nullptr; } std::unique_ptr<Array<T>> result(new Array<T>()); errors->push(); for (size_t i = 0; i < array->size(); ++i) { errors->setName(StringUtil::fromInteger(i)); std::unique_ptr<T> item = ValueConversions<T>::fromValue(array->at(i), errors); result->m_vector.push_back(std::move(item)); } errors->pop(); if (errors->hasErrors()) return nullptr; return result; } void addItem(std::unique_ptr<T> value) { m_vector.push_back(std::move(value)); } size_t length() { return m_vector.size(); } T* get(size_t index) { return m_vector[index].get(); } std::unique_ptr<protocol::ListValue> toValue() { std::unique_ptr<protocol::ListValue> result = ListValue::create(); for (auto& item : m_vector) result->pushValue(ValueConversions<T>::toValue(item)); return result; } private: std::vector<std::unique_ptr<T>> m_vector; }; template<typename T> class ArrayBase { public: static std::unique_ptr<Array<T>> create() { return std::unique_ptr<Array<T>>(new Array<T>()); } static std::unique_ptr<Array<T>> fromValue(protocol::Value* value, ErrorSupport* errors) { protocol::ListValue* array = ListValue::cast(value); if (!array) { errors->addError("array expected"); return nullptr; } errors->push(); std::unique_ptr<Array<T>> result(new Array<T>()); for (size_t i = 0; i < array->size(); ++i) { errors->setName(StringUtil::fromInteger(i)); T item = ValueConversions<T>::fromValue(array->at(i), errors); result->m_vector.push_back(item); } errors->pop(); if (errors->hasErrors()) return nullptr; return result; } void addItem(const T& value) { m_vector.push_back(value); } size_t length() { return m_vector.size(); } T get(size_t index) { return m_vector[index]; } std::unique_ptr<protocol::ListValue> toValue() { std::unique_ptr<protocol::ListValue> result = ListValue::create(); for (auto& item : m_vector) result->pushValue(ValueConversions<T>::toValue(item)); return result; } private: std::vector<T> m_vector; }; template<> class Array<String> : public ArrayBase<String> {}; template<> class Array<int> : public ArrayBase<int> {}; template<> class Array<double> : public ArrayBase<double> {}; template<> class Array<bool> : public ArrayBase<bool> {}; } // namespace node } // namespace inspector } // namespace protocol #endif // !defined(node_inspector_protocol_Array_h) // This file is generated by DispatcherBase_h.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. #ifndef node_inspector_protocol_DispatcherBase_h #define node_inspector_protocol_DispatcherBase_h //#include "Forward.h" //#include "ErrorSupport.h" //#include "Values.h" namespace node { namespace inspector { namespace protocol { class WeakPtr; class DispatchResponse { public: enum Status { kSuccess = 0, kError = 1, kFallThrough = 2, }; enum ErrorCode { kParseError = -32700, kInvalidRequest = -32600, kMethodNotFound = -32601, kInvalidParams = -32602, kInternalError = -32603, kServerError = -32000, }; Status status() const { return m_status; } const String& errorMessage() const { return m_errorMessage; } ErrorCode errorCode() const { return m_errorCode; } bool isSuccess() const { return m_status == kSuccess; } static DispatchResponse OK(); static DispatchResponse Error(const String&); static DispatchResponse InternalError(); static DispatchResponse InvalidParams(const String&); static DispatchResponse FallThrough(); private: Status m_status; String m_errorMessage; ErrorCode m_errorCode; }; class DispatcherBase { PROTOCOL_DISALLOW_COPY(DispatcherBase); public: static const char kInvalidParamsString[]; class WeakPtr { public: explicit WeakPtr(DispatcherBase*); ~WeakPtr(); DispatcherBase* get() { return m_dispatcher; } void dispose() { m_dispatcher = nullptr; } private: DispatcherBase* m_dispatcher; }; class Callback { public: Callback(std::unique_ptr<WeakPtr> backendImpl, int callId, const String& method, const ProtocolMessage& message); virtual ~Callback(); void dispose(); protected: void sendIfActive(std::unique_ptr<protocol::DictionaryValue> partialMessage, const DispatchResponse& response); void fallThroughIfActive(); private: std::unique_ptr<WeakPtr> m_backendImpl; int m_callId; String m_method; ProtocolMessage m_message; }; explicit DispatcherBase(FrontendChannel*); virtual ~DispatcherBase(); virtual bool canDispatch(const String& method) = 0; virtual void dispatch(int callId, const String& method, const ProtocolMessage& rawMessage, std::unique_ptr<protocol::DictionaryValue> messageObject) = 0; FrontendChannel* channel() { return m_frontendChannel; } void sendResponse(int callId, const DispatchResponse&, std::unique_ptr<protocol::DictionaryValue> result); void sendResponse(int callId, const DispatchResponse&); void reportProtocolError(int callId, DispatchResponse::ErrorCode, const String& errorMessage, ErrorSupport* errors); void clearFrontend(); std::unique_ptr<WeakPtr> weakPtr(); private: FrontendChannel* m_frontendChannel; std::unordered_set<WeakPtr*> m_weakPtrs; }; class UberDispatcher { PROTOCOL_DISALLOW_COPY(UberDispatcher); public: explicit UberDispatcher(FrontendChannel*); void registerBackend(const String& name, std::unique_ptr<protocol::DispatcherBase>); void setupRedirects(const std::unordered_map<String, String>&); bool parseCommand(Value* message, int* callId, String* method); bool canDispatch(const String& method); void dispatch(int callId, const String& method, std::unique_ptr<Value> message, const ProtocolMessage& rawMessage); FrontendChannel* channel() { return m_frontendChannel; } virtual ~UberDispatcher(); private: protocol::DispatcherBase* findDispatcher(const String& method); FrontendChannel* m_frontendChannel; std::unordered_map<String, String> m_redirects; std::unordered_map<String, std::unique_ptr<protocol::DispatcherBase>> m_dispatchers; }; class InternalResponse : public Serializable { PROTOCOL_DISALLOW_COPY(InternalResponse); public: static std::unique_ptr<InternalResponse> createResponse(int callId, std::unique_ptr<Serializable> params); static std::unique_ptr<InternalResponse> createNotification(const String& notification, std::unique_ptr<Serializable> params = nullptr); String serializeToJSON() override; std::vector<uint8_t> serializeToBinary() override; ~InternalResponse() override {} private: InternalResponse(int callId, const String& notification, std::unique_ptr<Serializable> params); int m_callId; String m_notification; std::unique_ptr<Serializable> m_params; }; class InternalRawNotification : public Serializable { public: static std::unique_ptr<InternalRawNotification> fromJSON(String notification) { return std::unique_ptr<InternalRawNotification>(new InternalRawNotification(std::move(notification))); } static std::unique_ptr<InternalRawNotification> fromBinary(std::vector<uint8_t> notification) { return std::unique_ptr<InternalRawNotification>(new InternalRawNotification(std::move(notification))); } ~InternalRawNotification() override {} String serializeToJSON() override { return std::move(m_jsonNotification); } std::vector<uint8_t> serializeToBinary() override { return std::move(m_binaryNotification); } private: explicit InternalRawNotification(String notification) : m_jsonNotification(std::move(notification)) { } explicit InternalRawNotification(std::vector<uint8_t> notification) : m_binaryNotification(std::move(notification)) { } String m_jsonNotification; std::vector<uint8_t> m_binaryNotification; }; } // namespace node } // namespace inspector } // namespace protocol #endif // !defined(node_inspector_protocol_DispatcherBase_h) // This file is generated by Parser_h.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. #ifndef node_inspector_protocol_Parser_h #define node_inspector_protocol_Parser_h //#include "Forward.h" //#include "Values.h" namespace node { namespace inspector { namespace protocol { std::unique_ptr<Value> parseJSONCharacters(const uint8_t*, unsigned); std::unique_ptr<Value> parseJSONCharacters(const uint16_t*, unsigned); } // namespace node } // namespace inspector } // namespace protocol #endif // !defined(node_inspector_protocol_Parser_h) // Generated by lib/encoding_h.template. // Copyright 2019 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. #ifndef node_inspector_protocol_encoding_h #define node_inspector_protocol_encoding_h #include <cstddef> #include <cstdint> #include <cstring> #include <limits> #include <memory> #include <string> #include <vector> namespace node { namespace inspector { namespace protocol { // ===== encoding/encoding.h ===== // ============================================================================= // span - sequence of bytes // ============================================================================= // This template is similar to std::span, which will be included in C++20. template <typename T> class span { public: using index_type = size_t; span() : data_(nullptr), size_(0) {} span(const T* data, index_type size) : data_(data), size_(size) {} const T* data() const { return data_; } const T* begin() const { return data_; } const T* end() const { return data_ + size_; } const T& operator[](index_type idx) const { return data_[idx]; } span<T> subspan(index_type offset, index_type count) const { return span(data_ + offset, count); } span<T> subspan(index_type offset) const { return span(data_ + offset, size_ - offset); } bool empty() const { return size_ == 0; } index_type size() const { return size_; } index_type size_bytes() const { return size_ * sizeof(T); } private: const T* data_; index_type size_; }; template <typename T> span<T> SpanFrom(const std::vector<T>& v) { return span<T>(v.data(), v.size()); } template <size_t N> span<uint8_t> SpanFrom(const char (&str)[N]) { return span<uint8_t>(reinterpret_cast<const uint8_t*>(str), N - 1); } inline span<uint8_t> SpanFrom(const char* str) { return str ? span<uint8_t>(reinterpret_cast<const uint8_t*>(str), strlen(str)) : span<uint8_t>(); } inline span<uint8_t> SpanFrom(const std::string& v) { return span<uint8_t>(reinterpret_cast<const uint8_t*>(v.data()), v.size()); } // ============================================================================= // Status and Error codes // ============================================================================= enum class Error { OK = 0, // JSON parsing errors - json_parser.{h,cc}. JSON_PARSER_UNPROCESSED_INPUT_REMAINS = 0x01, JSON_PARSER_STACK_LIMIT_EXCEEDED = 0x02, JSON_PARSER_NO_INPUT = 0x03, JSON_PARSER_INVALID_TOKEN = 0x04, JSON_PARSER_INVALID_NUMBER = 0x05, JSON_PARSER_INVALID_STRING = 0x06, JSON_PARSER_UNEXPECTED_ARRAY_END = 0x07, JSON_PARSER_COMMA_OR_ARRAY_END_EXPECTED = 0x08, JSON_PARSER_STRING_LITERAL_EXPECTED = 0x09, JSON_PARSER_COLON_EXPECTED = 0x0a, JSON_PARSER_UNEXPECTED_MAP_END = 0x0b, JSON_PARSER_COMMA_OR_MAP_END_EXPECTED = 0x0c, JSON_PARSER_VALUE_EXPECTED = 0x0d, CBOR_INVALID_INT32 = 0x0e, CBOR_INVALID_DOUBLE = 0x0f, CBOR_INVALID_ENVELOPE = 0x10, CBOR_INVALID_STRING8 = 0x11, CBOR_INVALID_STRING16 = 0x12, CBOR_INVALID_BINARY = 0x13, CBOR_UNSUPPORTED_VALUE = 0x14, CBOR_NO_INPUT = 0x15, CBOR_INVALID_START_BYTE = 0x16, CBOR_UNEXPECTED_EOF_EXPECTED_VALUE = 0x17, CBOR_UNEXPECTED_EOF_IN_ARRAY = 0x18, CBOR_UNEXPECTED_EOF_IN_MAP = 0x19, CBOR_INVALID_MAP_KEY = 0x1a, CBOR_STACK_LIMIT_EXCEEDED = 0x1b, CBOR_TRAILING_JUNK = 0x1c, CBOR_MAP_START_EXPECTED = 0x1d, CBOR_MAP_STOP_EXPECTED = 0x1e, CBOR_ENVELOPE_SIZE_LIMIT_EXCEEDED = 0x1f, }; // A status value with position that can be copied. The default status // is OK. Usually, error status values should come with a valid position. struct Status { static constexpr size_t npos() { return std::numeric_limits<size_t>::max(); } bool ok() const { return error == Error::OK; } Error error = Error::OK; size_t pos = npos(); Status(Error error, size_t pos) : error(error), pos(pos) {} Status() = default; // Returns a 7 bit US-ASCII string, either "OK" or an error message // that includes the position. std::string ToASCIIString() const; private: std::string ToASCIIString(const char* msg) const; }; // Handler interface for parser events emitted by a streaming parser. // See cbor::NewCBOREncoder, cbor::ParseCBOR, json::NewJSONEncoder, // json::ParseJSON. class StreamingParserHandler { public: virtual ~StreamingParserHandler() = default; virtual void HandleMapBegin() = 0; virtual void HandleMapEnd() = 0; virtual void HandleArrayBegin() = 0; virtual void HandleArrayEnd() = 0; virtual void HandleString8(span<uint8_t> chars) = 0; virtual void HandleString16(span<uint16_t> chars) = 0; virtual void HandleBinary(span<uint8_t> bytes) = 0; virtual void HandleDouble(double value) = 0; virtual void HandleInt32(int32_t value) = 0; virtual void HandleBool(bool value) = 0; virtual void HandleNull() = 0; // The parser may send one error even after other events have already // been received. Client code is reponsible to then discard the // already processed events. // |error| must be an eror, as in, |error.is_ok()| can't be true. virtual void HandleError(Status error) = 0; }; namespace cbor { // The binary encoding for the inspector protocol follows the CBOR specification // (RFC 7049). Additional constraints: // - Only indefinite length maps and arrays are supported. // - Maps and arrays are wrapped with an envelope, that is, a // CBOR tag with value 24 followed by a byte string specifying // the byte length of the enclosed map / array. The byte string // must use a 32 bit wide length. // - At the top level, a message must be an indefinite length map // wrapped by an envelope. // - Maximal size for messages is 2^32 (4 GiB). // - For scalars, we support only the int32_t range, encoded as // UNSIGNED/NEGATIVE (major types 0 / 1). // - UTF16 strings, including with unbalanced surrogate pairs, are encoded // as CBOR BYTE_STRING (major type 2). For such strings, the number of // bytes encoded must be even. // - UTF8 strings (major type 3) are supported. // - 7 bit US-ASCII strings must always be encoded as UTF8 strings, never // as UTF16 strings. // - Arbitrary byte arrays, in the inspector protocol called 'binary', // are encoded as BYTE_STRING (major type 2), prefixed with a byte // indicating base64 when rendered as JSON. // ============================================================================= // Detecting CBOR content // ============================================================================= // The first byte for an envelope, which we use for wrapping dictionaries // and arrays; and the byte that indicates a byte string with 32 bit length. // These two bytes start an envelope, and thereby also any CBOR message // produced or consumed by this protocol. See also |EnvelopeEncoder| below. uint8_t InitialByteForEnvelope(); uint8_t InitialByteFor32BitLengthByteString(); // Checks whether |msg| is a cbor message. bool IsCBORMessage(span<uint8_t> msg); // ============================================================================= // Encoding individual CBOR items // ============================================================================= // Some constants for CBOR tokens that only take a single byte on the wire. uint8_t EncodeTrue(); uint8_t EncodeFalse(); uint8_t EncodeNull(); uint8_t EncodeIndefiniteLengthArrayStart(); uint8_t EncodeIndefiniteLengthMapStart(); uint8_t EncodeStop(); // Encodes |value| as |UNSIGNED| (major type 0) iff >= 0, or |NEGATIVE| // (major type 1) iff < 0. void EncodeInt32(int32_t value, std::vector<uint8_t>* out); void EncodeInt32(int32_t value, std::string* out); // Encodes a UTF16 string as a BYTE_STRING (major type 2). Each utf16 // character in |in| is emitted with most significant byte first, // appending to |out|. void EncodeString16(span<uint16_t> in, std::vector<uint8_t>* out); void EncodeString16(span<uint16_t> in, std::string* out); // Encodes a UTF8 string |in| as STRING (major type 3). void EncodeString8(span<uint8_t> in, std::vector<uint8_t>* out); void EncodeString8(span<uint8_t> in, std::string* out); // Encodes the given |latin1| string as STRING8. // If any non-ASCII character is present, it will be represented // as a 2 byte UTF8 sequence. void EncodeFromLatin1(span<uint8_t> latin1, std::vector<uint8_t>* out); void EncodeFromLatin1(span<uint8_t> latin1, std::string* out); // Encodes the given |utf16| string as STRING8 if it's entirely US-ASCII. // Otherwise, encodes as STRING16. void EncodeFromUTF16(span<uint16_t> utf16, std::vector<uint8_t>* out); void EncodeFromUTF16(span<uint16_t> utf16, std::string* out); // Encodes arbitrary binary data in |in| as a BYTE_STRING (major type 2) with // definitive length, prefixed with tag 22 indicating expected conversion to // base64 (see RFC 7049, Table 3 and Section 2.4.4.2). void EncodeBinary(span<uint8_t> in, std::vector<uint8_t>* out); void EncodeBinary(span<uint8_t> in, std::string* out); // Encodes / decodes a double as Major type 7 (SIMPLE_VALUE), // with additional info = 27, followed by 8 bytes in big endian. void EncodeDouble(double value, std::vector<uint8_t>* out); void EncodeDouble(double value, std::string* out); // ============================================================================= // cbor::EnvelopeEncoder - for wrapping submessages // ============================================================================= // An envelope indicates the byte length of a wrapped item. // We use this for maps and array, which allows the decoder // to skip such (nested) values whole sale. // It's implemented as a CBOR tag (major type 6) with additional // info = 24, followed by a byte string with a 32 bit length value; // so the maximal structure that we can wrap is 2^32 bits long. // See also: https://tools.ietf.org/html/rfc7049#section-2.4.4.1 class EnvelopeEncoder { public: // Emits the envelope start bytes and records the position for the // byte size in |byte_size_pos_|. Also emits empty bytes for the // byte sisze so that encoding can continue. void EncodeStart(std::vector<uint8_t>* out); void EncodeStart(std::string* out); // This records the current size in |out| at position byte_size_pos_. // Returns true iff successful. bool EncodeStop(std::vector<uint8_t>* out); bool EncodeStop(std::string* out); private: size_t byte_size_pos_ = 0; }; // ============================================================================= // cbor::NewCBOREncoder - for encoding from a streaming parser // ============================================================================= // This can be used to convert to CBOR, by passing the return value to a parser // that drives it. The handler will encode into |out|, and iff an error occurs // it will set |status| to an error and clear |out|. Otherwise, |status.ok()| // will be |true|. std::unique_ptr<StreamingParserHandler> NewCBOREncoder( std::vector<uint8_t>* out, Status* status); std::unique_ptr<StreamingParserHandler> NewCBOREncoder(std::string* out, Status* status); // ============================================================================= // cbor::CBORTokenizer - for parsing individual CBOR items // ============================================================================= // Tags for the tokens within a CBOR message that CBORTokenizer understands. // Note that this is not the same terminology as the CBOR spec (RFC 7049), // but rather, our adaptation. For instance, we lump unsigned and signed // major type into INT32 here (and disallow values outside the int32_t range). enum class CBORTokenTag { // Encountered an error in the structure of the message. Consult // status() for details. ERROR_VALUE, // Booleans and NULL. TRUE_VALUE, FALSE_VALUE, NULL_VALUE, // An int32_t (signed 32 bit integer). INT32, // A double (64 bit floating point). DOUBLE, // A UTF8 string. STRING8, // A UTF16 string. STRING16, // A binary string. BINARY, // Starts an indefinite length map; after the map start we expect // alternating keys and values, followed by STOP. MAP_START, // Starts an indefinite length array; after the array start we // expect values, followed by STOP. ARRAY_START, // Ends a map or an array. STOP, // An envelope indicator, wrapping a map or array. // Internally this carries the byte length of the wrapped // map or array. While CBORTokenizer::Next() will read / skip the entire // envelope, CBORTokenizer::EnterEnvelope() reads the tokens // inside of it. ENVELOPE, // We've reached the end there is nothing else to read. DONE, }; // The major types from RFC 7049 Section 2.1. enum class MajorType { UNSIGNED = 0, NEGATIVE = 1, BYTE_STRING = 2, STRING = 3, ARRAY = 4, MAP = 5, TAG = 6, SIMPLE_VALUE = 7 }; // CBORTokenizer segments a CBOR message, presenting the tokens therein as // numbers, strings, etc. This is not a complete CBOR parser, but makes it much // easier to implement one (e.g. ParseCBOR, above). It can also be used to parse // messages partially. class CBORTokenizer { public: explicit CBORTokenizer(span<uint8_t> bytes); ~CBORTokenizer(); // Identifies the current token that we're looking at, // or ERROR_VALUE (in which ase ::Status() has details) // or DONE (if we're past the last token). CBORTokenTag TokenTag() const; // Advances to the next token. void Next(); // Can only be called if TokenTag() == CBORTokenTag::ENVELOPE. // While Next() would skip past the entire envelope / what it's // wrapping, EnterEnvelope positions the cursor inside of the envelope, // letting the client explore the nested structure. void EnterEnvelope(); // If TokenTag() is CBORTokenTag::ERROR_VALUE, then Status().error describes // the error more precisely; otherwise it'll be set to Error::OK. // In either case, Status().pos is the current position. struct Status Status() const; // The following methods retrieve the token values. They can only // be called if TokenTag() matches. // To be called only if ::TokenTag() == CBORTokenTag::INT32. int32_t GetInt32() const; // To be called only if ::TokenTag() == CBORTokenTag::DOUBLE. double GetDouble() const; // To be called only if ::TokenTag() == CBORTokenTag::STRING8. span<uint8_t> GetString8() const; // Wire representation for STRING16 is low byte first (little endian). // To be called only if ::TokenTag() == CBORTokenTag::STRING16. span<uint8_t> GetString16WireRep() const; // To be called only if ::TokenTag() == CBORTokenTag::BINARY. span<uint8_t> GetBinary() const; // To be called only if ::TokenTag() == CBORTokenTag::ENVELOPE. span<uint8_t> GetEnvelopeContents() const; private: void ReadNextToken(bool enter_envelope); void SetToken(CBORTokenTag token, size_t token_byte_length); void SetError(Error error); span<uint8_t> bytes_; CBORTokenTag token_tag_; struct Status status_; size_t token_byte_length_; MajorType token_start_type_; uint64_t token_start_internal_value_; }; // ============================================================================= // cbor::ParseCBOR - for receiving streaming parser events for CBOR messages // ============================================================================= // Parses a CBOR encoded message from |bytes|, sending events to // |out|. If an error occurs, sends |out->HandleError|, and parsing stops. // The client is responsible for discarding the already received information in // that case. void ParseCBOR(span<uint8_t> bytes, StreamingParserHandler* out); // ============================================================================= // cbor::AppendString8EntryToMap - for limited in-place editing of messages // ============================================================================= // Modifies the |cbor| message by appending a new key/value entry at the end // of the map. Patches up the envelope size; Status.ok() iff successful. // If not successful, |cbor| may be corrupted after this call. Status AppendString8EntryToCBORMap(span<uint8_t> string8_key, span<uint8_t> string8_value, std::vector<uint8_t>* cbor); Status AppendString8EntryToCBORMap(span<uint8_t> string8_key, span<uint8_t> string8_value, std::string* cbor); namespace internals { // Exposed only for writing tests. size_t ReadTokenStart(span<uint8_t> bytes, cbor::MajorType* type, uint64_t* value); void WriteTokenStart(cbor::MajorType type, uint64_t value, std::vector<uint8_t>* encoded); void WriteTokenStart(cbor::MajorType type, uint64_t value, std::string* encoded); } // namespace internals } // namespace cbor namespace json { // Client code must provide an instance. Implementation should delegate // to whatever is appropriate. class Platform { public: virtual ~Platform() = default; // Parses |str| into |result|. Returns false iff there are // leftover characters or parsing errors. virtual bool StrToD(const char* str, double* result) const = 0; // Prints |value| in a format suitable for JSON. virtual std::unique_ptr<char[]> DToStr(double value) const = 0; }; // ============================================================================= // json::NewJSONEncoder - for encoding streaming parser events as JSON // ============================================================================= // Returns a handler object which will write ascii characters to |out|. // |status->ok()| will be false iff the handler routine HandleError() is called. // In that case, we'll stop emitting output. // Except for calling the HandleError routine at any time, the client // code must call the Handle* methods in an order in which they'd occur // in valid JSON; otherwise we may crash (the code uses assert). std::unique_ptr<StreamingParserHandler> NewJSONEncoder( const Platform* platform, std::vector<uint8_t>* out, Status* status); std::unique_ptr<StreamingParserHandler> NewJSONEncoder(const Platform* platform, std::string* out, Status* status); // ============================================================================= // json::ParseJSON - for receiving streaming parser events for JSON // ============================================================================= void ParseJSON(const Platform& platform, span<uint8_t> chars, StreamingParserHandler* handler); void ParseJSON(const Platform& platform, span<uint16_t> chars, StreamingParserHandler* handler); // ============================================================================= // json::ConvertCBORToJSON, json::ConvertJSONToCBOR - for transcoding // ============================================================================= Status ConvertCBORToJSON(const Platform& platform, span<uint8_t> cbor, std::string* json); Status ConvertCBORToJSON(const Platform& platform, span<uint8_t> cbor, std::vector<uint8_t>* json); Status ConvertJSONToCBOR(const Platform& platform, span<uint8_t> json, std::vector<uint8_t>* cbor); Status ConvertJSONToCBOR(const Platform& platform, span<uint16_t> json, std::vector<uint8_t>* cbor); Status ConvertJSONToCBOR(const Platform& platform, span<uint8_t> json, std::string* cbor); Status ConvertJSONToCBOR(const Platform& platform, span<uint16_t> json, std::string* cbor); } // namespace json } // namespace node } // namespace inspector } // namespace protocol #endif // !defined(node_inspector_protocol_encoding_h)