summaryrefslogtreecommitdiff
path: root/identity/support/include/cppbor/cppbor_parse.h
diff options
context:
space:
mode:
Diffstat (limited to 'identity/support/include/cppbor/cppbor_parse.h')
-rw-r--r--identity/support/include/cppbor/cppbor_parse.h133
1 files changed, 133 insertions, 0 deletions
diff --git a/identity/support/include/cppbor/cppbor_parse.h b/identity/support/include/cppbor/cppbor_parse.h
new file mode 100644
index 000000000..66cd5a3d6
--- /dev/null
+++ b/identity/support/include/cppbor/cppbor_parse.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "cppbor.h"
+
+namespace cppbor {
+
+using ParseResult = std::tuple<std::unique_ptr<Item> /* result */, const uint8_t* /* newPos */,
+ std::string /* errMsg */>;
+
+/**
+ * Parse the first CBOR data item (possibly compound) from the range [begin, end).
+ *
+ * Returns a tuple of Item pointer, buffer pointer and error message. If parsing is successful, the
+ * Item pointer is non-null, the buffer pointer points to the first byte after the
+ * successfully-parsed item and the error message string is empty. If parsing fails, the Item
+ * pointer is null, the buffer pointer points to the first byte that was unparseable (the first byte
+ * of a data item header that is malformed in some way, e.g. an invalid value, or a length that is
+ * too large for the remining buffer, etc.) and the string contains an error message describing the
+ * problem encountered.
+ */
+ParseResult parse(const uint8_t* begin, const uint8_t* end);
+
+/**
+ * Parse the first CBOR data item (possibly compound) from the byte vector.
+ *
+ * Returns a tuple of Item pointer, buffer pointer and error message. If parsing is successful, the
+ * Item pointer is non-null, the buffer pointer points to the first byte after the
+ * successfully-parsed item and the error message string is empty. If parsing fails, the Item
+ * pointer is null, the buffer pointer points to the first byte that was unparseable (the first byte
+ * of a data item header that is malformed in some way, e.g. an invalid value, or a length that is
+ * too large for the remining buffer, etc.) and the string contains an error message describing the
+ * problem encountered.
+ */
+inline ParseResult parse(const std::vector<uint8_t>& encoding) {
+ return parse(encoding.data(), encoding.data() + encoding.size());
+}
+
+/**
+ * Parse the first CBOR data item (possibly compound) from the range [begin, begin + size).
+ *
+ * Returns a tuple of Item pointer, buffer pointer and error message. If parsing is successful, the
+ * Item pointer is non-null, the buffer pointer points to the first byte after the
+ * successfully-parsed item and the error message string is empty. If parsing fails, the Item
+ * pointer is null, the buffer pointer points to the first byte that was unparseable (the first byte
+ * of a data item header that is malformed in some way, e.g. an invalid value, or a length that is
+ * too large for the remining buffer, etc.) and the string contains an error message describing the
+ * problem encountered.
+ */
+inline ParseResult parse(const uint8_t* begin, size_t size) {
+ return parse(begin, begin + size);
+}
+
+class ParseClient;
+
+/**
+ * Parse the CBOR data in the range [begin, end) in streaming fashion, calling methods on the
+ * provided ParseClient when elements are found.
+ */
+void parse(const uint8_t* begin, const uint8_t* end, ParseClient* parseClient);
+
+/**
+ * Parse the CBOR data in the vector in streaming fashion, calling methods on the
+ * provided ParseClient when elements are found.
+ */
+inline void parse(const std::vector<uint8_t>& encoding, ParseClient* parseClient) {
+ return parse(encoding.data(), encoding.data() + encoding.size(), parseClient);
+}
+
+/**
+ * A pure interface that callers of the streaming parse functions must implement.
+ */
+class ParseClient {
+ public:
+ virtual ~ParseClient() {}
+
+ /**
+ * Called when an item is found. The Item pointer points to the found item; use type() and
+ * the appropriate as*() method to examine the value. hdrBegin points to the first byte of the
+ * header, valueBegin points to the first byte of the value and end points one past the end of
+ * the item. In the case of header-only items, such as integers, and compound items (ARRAY,
+ * MAP or SEMANTIC) whose end has not yet been found, valueBegin and end are equal and point to
+ * the byte past the header.
+ *
+ * Note that for compound types (ARRAY, MAP, and SEMANTIC), the Item will have no content. For
+ * Map and Array items, the size() method will return a correct value, but the index operators
+ * are unsafe, and the object cannot be safely compared with another Array/Map.
+ *
+ * The method returns a ParseClient*. In most cases "return this;" will be the right answer,
+ * but a different ParseClient may be returned, which the parser will begin using. If the method
+ * returns nullptr, parsing will be aborted immediately.
+ */
+ virtual ParseClient* item(std::unique_ptr<Item>& item, const uint8_t* hdrBegin,
+ const uint8_t* valueBegin, const uint8_t* end) = 0;
+
+ /**
+ * Called when the end of a compound item (MAP or ARRAY) is found. The item argument will be
+ * the same one passed to the item() call -- and may be empty if item() moved its value out.
+ * hdrBegin, valueBegin and end point to the beginning of the item header, the beginning of the
+ * first contained value, and one past the end of the last contained value, respectively.
+ *
+ * Note that the Item will have no content.
+ *
+ * As with item(), itemEnd() can change the ParseClient by returning a different one, or end the
+ * parsing by returning nullptr;
+ */
+ virtual ParseClient* itemEnd(std::unique_ptr<Item>& item, const uint8_t* hdrBegin,
+ const uint8_t* valueBegin, const uint8_t* end) = 0;
+
+ /**
+ * Called when parsing encounters an error. position is set to the first unparsed byte (one
+ * past the last successfully-parsed byte) and errorMessage contains an message explaining what
+ * sort of error occurred.
+ */
+ virtual void error(const uint8_t* position, const std::string& errorMessage) = 0;
+};
+
+} // namespace cppbor