2 Star 0 Fork 0

mirrors_android_source/libcppbor

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
Apache-2.0

LibCppBor: A Modern C++ CBOR Parser and Generator

LibCppBor provides a natural and easy-to-use syntax for constructing and parsing CBOR messages. It does not (yet) support all features of CBOR, nor (yet) support validation against CDDL schemata, though both are planned. CBOR features that aren't supported include:

  • Indefinite length values
  • Semantic tagging
  • Floating point

LibCppBor requires C++-17.

CBOR representation

LibCppBor represents CBOR data items as instances of the Item class or, more precisely, as instances of subclasses of Item, since Item is a pure interface. The subclasses of Item correspond almost one-to-one with CBOR major types, and are named to match the CDDL names to which they correspond. They are:

  • Uint corresponds to major type 0, and can hold unsigned integers up through (2^64 - 1).
  • Nint corresponds to major type 1. It can only hold values from -1 to -(2^63 - 1), since it's internal representation is an int64_t. This can be fixed, but it seems unlikely that applications will need the omitted range from -(2^63) to (2^64 - 1), since it's inconvenient to represent them in many programming languages.
  • Int is an abstract base of Uint and Nint that facilitates working with all signed integers representable with int64_t.
  • Bstr corresponds to major type 2, a byte string.
  • Tstr corresponds to major type 3, a text string.
  • Array corresponds to major type 4, an Array. It holds a variable-length array of Items.
  • Map corresponds to major type 5, a Map. It holds a variable-length array of pairs of Items.
  • Simple corresponds to major type 7. It's an abstract class since items require more specific type.
  • Bool is the only currently-implemented subclass of Simple.

Note that major type 6, semantic tag, is not yet implemented.

In practice, users of LibCppBor will rarely use most of these classes when generating CBOR encodings. This is because LibCppBor provides straightforward conversions from the obvious normal C++ types. Specifically, the following conversions are provided in appropriate contexts:

  • Signed and unsigned integers convert to Uint or Nint, as appropriate.
  • std::string, std::string_view, const char* and std::pair<char iterator, char iterator> convert to Tstr.
  • std::vector<uint8_t>, std::pair<uint8_t iterator, uint8_t iterator> and std::pair<uint8_t*, size_t> convert to Bstr.
  • bool converts to Bool.

CBOR generation

Complete tree generation

The set of encode methods in Item provide the interface for producing encoded CBOR. The basic process for "complete tree" generation (as opposed to "incremental" generation, which is discussed below) is to construct an Item which models the data to be encoded, and then call one of the encode methods, whichever is convenient for the encoding destination. A trivial example:

cppbor::Uint val(0);
std::vector<uint8_t> encoding = val.encode();
It's relatively rare that single values are encoded as above.  More often, the
"root" data item will be an `Array` or `Map` which contains a more complex structure.For example
:
using cppbor::Array;

std::vector<uint8_t> vec =  // ...
    Map val("key1", Array(Map("key_a", 99 "key_b", vec), "foo"), "key2", true);
std::vector<uint8_t> encoding = val.encode();

This creates a map with two entries, with Tstr keys "Outer1" and "Outer2", respectively. The "Outer1" entry has as its value an Array containing a Map and a Tstr. The "Outer2" entry has a Bool value.

This example demonstrates how automatic conversion of C++ types to LibCppBor Item subclass instances is done. Where the caller provides a C++ or C string, a Tstr entry is added. Where the caller provides an integer literal or variable, a Uint or Nint is added, depending on whether the value is positive or negative.

As an alternative, a more fluent-style API is provided for building up structures. For example:

using cppbor::Map;
using cppbor::Array;

std::vector<uint8_t> vec =  // ...
    Map val();
val.add("key1", Array().add(Map().add("key_a", 99).add("key_b", vec)).add("foo")).add("key2", true);
std::vector<uint8_t> encoding = val.encode();
An advantage of this interface over the constructor -
based creation approach above is that it need not be done all at once.
The `add` methods return a reference to the object added to to allow calls to be chained,
but chaining is not necessary; calls can be made
sequentially, as the data to add is available.

encode methods

There are several variations of Item::encode, all of which accomplish the same task but output the encoded data in different ways, and with somewhat different performance characteristics. The provided options are:

  • bool encode(uint8\_t** pos, const uint8\_t* end) encodes into the buffer referenced by the range [*pos, end). *pos is moved. If the encoding runs out of buffer space before finishing, the method returns false. This is the most efficient way to encode, into an already-allocated buffer.
  • void encode(EncodeCallback encodeCallback) calls encodeCallback for each encoded byte. It's the responsibility of the implementor of the callback to behave safely in the event that the output buffer (if applicable) is exhausted. This is less efficient than the prior method because it imposes an additional function call for each byte.
  • template </*...*/> void encode(OutputIterator i) encodes into the provided iterator. SFINAE ensures that the template doesn't match for non-iterators. The implementation actually uses the callback-based method, plus has whatever overhead the iterator adds.
  • std::vector<uint8_t> encode() creates a new std::vector, reserves sufficient capacity to hold the encoding, and inserts the encoded bytes with a std::pushback_iterator and the previous method.
  • std::string toString() does the same as the previous method, but returns a string instead of a vector.

Incremental generation

Incremental generation requires deeper understanding of CBOR, because the library can't do as much to ensure that the output is valid. The basic tool for intcremental generation is the encodeHeader function. There are two variations, one which writes into a buffer, and one which uses a callback. Both simply write out the bytes of a header. To construct the same map as in the above examples, incrementally, one might write:

using namespace cppbor;  // For example brevity

std::vector encoding;
auto iter = std::back_inserter(result);
encodeHeader(MAP, 2 /* # of map entries */, iter);
std::string s = "key1";
encodeHeader(TSTR, s.size(), iter);
std::copy(s.begin(), s.end(), iter);
encodeHeader(ARRAY, 2 /* # of array entries */, iter);
Map().add("key_a", 99).add("key_b", vec).encode(iter)
s = "foo";
encodeHeader(TSTR, foo.size(), iter);
std::copy(s.begin(), s.end(), iter);
s = "key2";
encodeHeader(TSTR, foo.size(), iter);
std::copy(s.begin(), s.end(), iter);
encodeHeader(SIMPLE, TRUE, iter);

As the above example demonstrates, the styles can be mixed -- Note the creation and encoding of the inner Map using the fluent style.

Parsing

LibCppBor also supports parsing of encoded CBOR data, with the same feature set as encoding. There are two basic approaches to parsing, "full" and "stream"

Full parsing

Full parsing means completely parsing a (possibly-compound) data item from a byte buffer. The parse functions that do not take a ParseClient pointer do this. They return a ParseResult which is a tuple of three values:

  • std::unique_ptr that points to the parsed item, or is nullptr if there was a parse error.
  • const uint8_t* that points to the byte after the end of the decoded item, or to the first unparseable byte in the event of an error.
  • std::string that is empty on success or contains an error message if a parse error occurred.

Assuming a successful parse, you can then use Item::type() to discover the type of the parsed item (e.g. MAP), and then use the appropriate Item::as*() method (e.g. Item::asMap()) to get a pointer to an interface which allows you to retrieve specific values.

Stream parsing

Stream parsing is more complex, but more flexible. To use StreamParsing, you must create your own subclass of ParseClient and call one of the parse functions that accepts it. See the ParseClient methods docstrings for details.

One unusual feature of stream parsing is that the ParseClient callback methods not only provide the parsed Item, but also pointers to the portion of the buffer that encode that Item. This is useful if, for example, you want to find an element inside of a structure, and then copy the encoding of that sub-structure, without bothering to parse the rest.

The full parser is implemented with the stream parser.

Disclaimer

This is not an officially supported Google product

Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] 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.

简介

暂无描述 展开 收起
README
Apache-2.0
取消

发行版

暂无发行版

贡献者

全部

近期动态

不能加载更多了
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/mirrors_android_source/libcppbor.git
git@gitee.com:mirrors_android_source/libcppbor.git
mirrors_android_source
libcppbor
libcppbor
main

搜索帮助