Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:22

0001 //===- MsgPackReader.h - Simple MsgPack reader ------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 ///
0009 ///  \file
0010 ///  This is a MessagePack reader.
0011 ///
0012 ///  See https://github.com/msgpack/msgpack/blob/master/spec.md for the full
0013 ///  standard.
0014 ///
0015 ///  Typical usage:
0016 ///  \code
0017 ///  StringRef input = GetInput();
0018 ///  msgpack::Reader MPReader(input);
0019 ///  msgpack::Object Obj;
0020 ///
0021 ///  while (true) {
0022 ///    Expected<bool> ReadObj = MPReader.read(&Obj);
0023 ///    if (!ReadObj)
0024 ///      // Handle error...
0025 ///    if (!ReadObj.get())
0026 ///      break; // Reached end of input
0027 ///    switch (Obj.Kind) {
0028 ///    case msgpack::Type::Int:
0029 //       // Use Obj.Int
0030 ///      break;
0031 ///    // ...
0032 ///    }
0033 ///  }
0034 ///  \endcode
0035 ///
0036 //===----------------------------------------------------------------------===//
0037 
0038 #ifndef LLVM_BINARYFORMAT_MSGPACKREADER_H
0039 #define LLVM_BINARYFORMAT_MSGPACKREADER_H
0040 
0041 #include "llvm/Support/Error.h"
0042 #include "llvm/Support/MemoryBufferRef.h"
0043 #include <cstdint>
0044 
0045 namespace llvm {
0046 namespace msgpack {
0047 
0048 /// MessagePack types as defined in the standard, with the exception of Integer
0049 /// being divided into a signed Int and unsigned UInt variant in order to map
0050 /// directly to C++ types.
0051 ///
0052 /// The types map onto corresponding union members of the \c Object struct.
0053 enum class Type : uint8_t {
0054   Int,
0055   UInt,
0056   Nil,
0057   Boolean,
0058   Float,
0059   String,
0060   Binary,
0061   Array,
0062   Map,
0063   Extension,
0064   Empty, // Used by MsgPackDocument to represent an empty node
0065 };
0066 
0067 /// Extension types are composed of a user-defined type ID and an uninterpreted
0068 /// sequence of bytes.
0069 struct ExtensionType {
0070   /// User-defined extension type.
0071   int8_t Type;
0072   /// Raw bytes of the extension object.
0073   StringRef Bytes;
0074 };
0075 
0076 /// MessagePack object, represented as a tagged union of C++ types.
0077 ///
0078 /// All types except \c Type::Nil (which has only one value, and so is
0079 /// completely represented by the \c Kind itself) map to a exactly one union
0080 /// member.
0081 struct Object {
0082   Type Kind;
0083   union {
0084     /// Value for \c Type::Int.
0085     int64_t Int;
0086     /// Value for \c Type::Uint.
0087     uint64_t UInt;
0088     /// Value for \c Type::Boolean.
0089     bool Bool;
0090     /// Value for \c Type::Float.
0091     double Float;
0092     /// Value for \c Type::String and \c Type::Binary.
0093     StringRef Raw;
0094     /// Value for \c Type::Array and \c Type::Map.
0095     size_t Length;
0096     /// Value for \c Type::Extension.
0097     ExtensionType Extension;
0098   };
0099 
0100   Object() : Kind(Type::Int), Int(0) {}
0101 };
0102 
0103 /// Reads MessagePack objects from memory, one at a time.
0104 class Reader {
0105 public:
0106   /// Construct a reader, keeping a reference to the \p InputBuffer.
0107   Reader(MemoryBufferRef InputBuffer);
0108   /// Construct a reader, keeping a reference to the \p Input.
0109   Reader(StringRef Input);
0110 
0111   Reader(const Reader &) = delete;
0112   Reader &operator=(const Reader &) = delete;
0113 
0114   /// Read one object from the input buffer, advancing past it.
0115   ///
0116   /// The \p Obj is updated with the kind of the object read, and the
0117   /// corresponding union member is updated.
0118   ///
0119   /// For the collection objects (Array and Map), only the length is read, and
0120   /// the caller must make and additional \c N calls (in the case of Array) or
0121   /// \c N*2 calls (in the case of Map) to \c Read to retrieve the collection
0122   /// elements.
0123   ///
0124   /// \param [out] Obj filled with next object on success.
0125   ///
0126   /// \returns true when object successfully read, false when at end of
0127   /// input (and so \p Obj was not updated), otherwise an error.
0128   Expected<bool> read(Object &Obj);
0129 
0130 private:
0131   MemoryBufferRef InputBuffer;
0132   StringRef::iterator Current;
0133   StringRef::iterator End;
0134 
0135   size_t remainingSpace() {
0136     // The rest of the code maintains the invariant that End >= Current, so
0137     // that this cast is always defined behavior.
0138     return static_cast<size_t>(End - Current);
0139   }
0140 
0141   template <class T> Expected<bool> readRaw(Object &Obj);
0142   template <class T> Expected<bool> readInt(Object &Obj);
0143   template <class T> Expected<bool> readUInt(Object &Obj);
0144   template <class T> Expected<bool> readLength(Object &Obj);
0145   template <class T> Expected<bool> readExt(Object &Obj);
0146   Expected<bool> createRaw(Object &Obj, uint32_t Size);
0147   Expected<bool> createExt(Object &Obj, uint32_t Size);
0148 };
0149 
0150 } // end namespace msgpack
0151 } // end namespace llvm
0152 
0153 #endif // LLVM_BINARYFORMAT_MSGPACKREADER_H