]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/llvm/include/llvm/BinaryFormat/MsgPackReader.h
Move all sources from the llvm project into contrib/llvm-project.
[FreeBSD/FreeBSD.git] / contrib / llvm-project / llvm / include / llvm / BinaryFormat / MsgPackReader.h
1 //===- MsgPackReader.h - Simple MsgPack reader ------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 ///  \file
10 ///  This is a MessagePack reader.
11 ///
12 ///  See https://github.com/msgpack/msgpack/blob/master/spec.md for the full
13 ///  standard.
14 ///
15 ///  Typical usage:
16 ///  \code
17 ///  StringRef input = GetInput();
18 ///  msgpack::Reader MPReader(input);
19 ///  msgpack::Object Obj;
20 ///
21 ///  while (MPReader.read(Obj)) {
22 ///    switch (Obj.Kind) {
23 ///    case msgpack::Type::Int:
24 //       // Use Obj.Int
25 ///      break;
26 ///    // ...
27 ///    }
28 ///  }
29 ///  \endcode
30 ///
31 //===----------------------------------------------------------------------===//
32
33 #ifndef LLVM_SUPPORT_MSGPACKREADER_H
34 #define LLVM_SUPPORT_MSGPACKREADER_H
35
36 #include "llvm/Support/MemoryBuffer.h"
37 #include "llvm/Support/raw_ostream.h"
38 #include <cstdint>
39
40 namespace llvm {
41 namespace msgpack {
42
43 /// MessagePack types as defined in the standard, with the exception of Integer
44 /// being divided into a signed Int and unsigned UInt variant in order to map
45 /// directly to C++ types.
46 ///
47 /// The types map onto corresponding union members of the \c Object struct.
48 enum class Type : uint8_t {
49   Int,
50   UInt,
51   Nil,
52   Boolean,
53   Float,
54   String,
55   Binary,
56   Array,
57   Map,
58   Extension,
59 };
60
61 /// Extension types are composed of a user-defined type ID and an uninterpreted
62 /// sequence of bytes.
63 struct ExtensionType {
64   /// User-defined extension type.
65   int8_t Type;
66   /// Raw bytes of the extension object.
67   StringRef Bytes;
68 };
69
70 /// MessagePack object, represented as a tagged union of C++ types.
71 ///
72 /// All types except \c Type::Nil (which has only one value, and so is
73 /// completely represented by the \c Kind itself) map to a exactly one union
74 /// member.
75 struct Object {
76   Type Kind;
77   union {
78     /// Value for \c Type::Int.
79     int64_t Int;
80     /// Value for \c Type::Uint.
81     uint64_t UInt;
82     /// Value for \c Type::Boolean.
83     bool Bool;
84     /// Value for \c Type::Float.
85     double Float;
86     /// Value for \c Type::String and \c Type::Binary.
87     StringRef Raw;
88     /// Value for \c Type::Array and \c Type::Map.
89     size_t Length;
90     /// Value for \c Type::Extension.
91     ExtensionType Extension;
92   };
93
94   Object() : Kind(Type::Int), Int(0) {}
95 };
96
97 /// Reads MessagePack objects from memory, one at a time.
98 class Reader {
99 public:
100   /// Construct a reader, keeping a reference to the \p InputBuffer.
101   Reader(MemoryBufferRef InputBuffer);
102   /// Construct a reader, keeping a reference to the \p Input.
103   Reader(StringRef Input);
104
105   Reader(const Reader &) = delete;
106   Reader &operator=(const Reader &) = delete;
107
108   /// Read one object from the input buffer, advancing past it.
109   ///
110   /// The \p Obj is updated with the kind of the object read, and the
111   /// corresponding union member is updated.
112   ///
113   /// For the collection objects (Array and Map), only the length is read, and
114   /// the caller must make and additional \c N calls (in the case of Array) or
115   /// \c N*2 calls (in the case of Map) to \c Read to retrieve the collection
116   /// elements.
117   ///
118   /// \param [out] Obj filled with next object on success.
119   ///
120   /// \returns true when object successfully read, false when at end of
121   /// input (and so \p Obj was not updated), otherwise an error.
122   Expected<bool> read(Object &Obj);
123
124 private:
125   MemoryBufferRef InputBuffer;
126   StringRef::iterator Current;
127   StringRef::iterator End;
128
129   size_t remainingSpace() {
130     // The rest of the code maintains the invariant that End >= Current, so
131     // that this cast is always defined behavior.
132     return static_cast<size_t>(End - Current);
133   }
134
135   template <class T> Expected<bool> readRaw(Object &Obj);
136   template <class T> Expected<bool> readInt(Object &Obj);
137   template <class T> Expected<bool> readUInt(Object &Obj);
138   template <class T> Expected<bool> readLength(Object &Obj);
139   template <class T> Expected<bool> readExt(Object &Obj);
140   Expected<bool> createRaw(Object &Obj, uint32_t Size);
141   Expected<bool> createExt(Object &Obj, uint32_t Size);
142 };
143
144 } // end namespace msgpack
145 } // end namespace llvm
146
147 #endif // LLVM_SUPPORT_MSGPACKREADER_H