1 // Copyright 2019 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_CRDTP_STATUS_H_ 6 #define V8_CRDTP_STATUS_H_ 7 8 #include <cassert> 9 #include <cstddef> 10 #include <limits> 11 #include <string> 12 13 #include "export.h" 14 15 namespace v8_crdtp { 16 // ============================================================================= 17 // Status and Error codes 18 // ============================================================================= 19 20 enum class Error { 21 OK = 0, 22 23 // JSON parsing errors; checked when parsing / converting from JSON. 24 // See json.{h,cc}. 25 JSON_PARSER_UNPROCESSED_INPUT_REMAINS = 0x01, 26 JSON_PARSER_STACK_LIMIT_EXCEEDED = 0x02, 27 JSON_PARSER_NO_INPUT = 0x03, 28 JSON_PARSER_INVALID_TOKEN = 0x04, 29 JSON_PARSER_INVALID_NUMBER = 0x05, 30 JSON_PARSER_INVALID_STRING = 0x06, 31 JSON_PARSER_UNEXPECTED_ARRAY_END = 0x07, 32 JSON_PARSER_COMMA_OR_ARRAY_END_EXPECTED = 0x08, 33 JSON_PARSER_STRING_LITERAL_EXPECTED = 0x09, 34 JSON_PARSER_COLON_EXPECTED = 0x0a, 35 JSON_PARSER_UNEXPECTED_MAP_END = 0x0b, 36 JSON_PARSER_COMMA_OR_MAP_END_EXPECTED = 0x0c, 37 JSON_PARSER_VALUE_EXPECTED = 0x0d, 38 39 // CBOR parsing errors; checked when parsing / converting from CBOR. 40 CBOR_INVALID_INT32 = 0x0e, 41 CBOR_INVALID_DOUBLE = 0x0f, 42 CBOR_INVALID_ENVELOPE = 0x10, 43 CBOR_ENVELOPE_CONTENTS_LENGTH_MISMATCH = 0x11, 44 CBOR_MAP_OR_ARRAY_EXPECTED_IN_ENVELOPE = 0x12, 45 CBOR_INVALID_STRING8 = 0x13, 46 CBOR_INVALID_STRING16 = 0x14, 47 CBOR_INVALID_BINARY = 0x15, 48 CBOR_UNSUPPORTED_VALUE = 0x16, 49 CBOR_NO_INPUT = 0x17, 50 CBOR_INVALID_START_BYTE = 0x18, 51 CBOR_UNEXPECTED_EOF_EXPECTED_VALUE = 0x19, 52 CBOR_UNEXPECTED_EOF_IN_ARRAY = 0x1a, 53 CBOR_UNEXPECTED_EOF_IN_MAP = 0x1b, 54 CBOR_INVALID_MAP_KEY = 0x1c, 55 CBOR_DUPLICATE_MAP_KEY = 0x1d, 56 CBOR_STACK_LIMIT_EXCEEDED = 0x1e, 57 CBOR_TRAILING_JUNK = 0x1f, 58 CBOR_MAP_START_EXPECTED = 0x20, 59 CBOR_MAP_STOP_EXPECTED = 0x21, 60 CBOR_ARRAY_START_EXPECTED = 0x22, 61 CBOR_ENVELOPE_SIZE_LIMIT_EXCEEDED = 0x23, 62 63 // Message errors are constraints we place on protocol messages coming 64 // from a protocol client; these are checked in crdtp::Dispatchable 65 // (see dispatch.h) as it performs a shallow parse. 66 MESSAGE_MUST_BE_AN_OBJECT = 0x24, 67 MESSAGE_MUST_HAVE_INTEGER_ID_PROPERTY = 0x25, 68 MESSAGE_MUST_HAVE_STRING_METHOD_PROPERTY = 0x26, 69 MESSAGE_MAY_HAVE_STRING_SESSION_ID_PROPERTY = 0x27, 70 MESSAGE_MAY_HAVE_OBJECT_PARAMS_PROPERTY = 0x28, 71 MESSAGE_HAS_UNKNOWN_PROPERTY = 0x29, 72 73 BINDINGS_MANDATORY_FIELD_MISSING = 0x30, 74 BINDINGS_BOOL_VALUE_EXPECTED = 0x31, 75 BINDINGS_INT32_VALUE_EXPECTED = 0x32, 76 BINDINGS_DOUBLE_VALUE_EXPECTED = 0x33, 77 BINDINGS_STRING_VALUE_EXPECTED = 0x34, 78 BINDINGS_STRING8_VALUE_EXPECTED = 0x35, 79 BINDINGS_BINARY_VALUE_EXPECTED = 0x36, 80 BINDINGS_DICTIONARY_VALUE_EXPECTED = 0x37, 81 }; 82 83 // A status value with position that can be copied. The default status 84 // is OK. Usually, error status values should come with a valid position. 85 struct Status { nposStatus86 static constexpr size_t npos() { return std::numeric_limits<size_t>::max(); } 87 okStatus88 bool ok() const { return error == Error::OK; } 89 90 Error error = Error::OK; 91 size_t pos = npos(); StatusStatus92 Status(Error error, size_t pos) : error(error), pos(pos) {} 93 Status() = default; 94 IsMessageErrorStatus95 bool IsMessageError() const { 96 return error >= Error::MESSAGE_MUST_BE_AN_OBJECT && 97 error <= Error::MESSAGE_HAS_UNKNOWN_PROPERTY; 98 } 99 100 // Returns 7 bit US-ASCII string, either "OK" or an error message without 101 // position. 102 std::string Message() const; 103 104 // Returns a 7 bit US-ASCII string, either "OK" or an error message that 105 // includes the position. 106 std::string ToASCIIString() const; 107 }; 108 109 template <typename T> 110 class StatusOr { 111 public: StatusOr(const T & value)112 explicit StatusOr(const T& value) : value_(value) {} StatusOr(T && value)113 explicit StatusOr(T&& value) : value_(std::move(value)) {} StatusOr(const Status & status)114 explicit StatusOr(const Status& status) : status_(status) {} 115 ok()116 bool ok() const { return status_.ok(); } 117 T& operator*() & { 118 assert(ok()); 119 return value_; 120 } 121 const T& operator*() const& { return value(); } 122 T&& operator*() && { return value(); } status()123 const Status& status() const { return status_; } 124 value()125 T& value() & { return *this; } value()126 T&& value() && { 127 assert(ok()); 128 return std::move(value_); 129 } value()130 const T& value() const& { return *this; } 131 132 private: 133 Status status_; 134 T value_; 135 }; 136 137 } // namespace v8_crdtp 138 139 #endif // V8_CRDTP_STATUS_H_ 140