MsgPackReader.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  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. #ifndef LLVM_BINARYFORMAT_MSGPACKREADER_H
  33. #define LLVM_BINARYFORMAT_MSGPACKREADER_H
  34. #include "llvm/Support/Error.h"
  35. #include "llvm/Support/MemoryBuffer.h"
  36. #include "llvm/Support/raw_ostream.h"
  37. #include <cstdint>
  38. namespace llvm {
  39. namespace msgpack {
  40. /// MessagePack types as defined in the standard, with the exception of Integer
  41. /// being divided into a signed Int and unsigned UInt variant in order to map
  42. /// directly to C++ types.
  43. ///
  44. /// The types map onto corresponding union members of the \c Object struct.
  45. enum class Type : uint8_t {
  46. Int,
  47. UInt,
  48. Nil,
  49. Boolean,
  50. Float,
  51. String,
  52. Binary,
  53. Array,
  54. Map,
  55. Extension,
  56. Empty, // Used by MsgPackDocument to represent an empty node
  57. };
  58. /// Extension types are composed of a user-defined type ID and an uninterpreted
  59. /// sequence of bytes.
  60. struct ExtensionType {
  61. /// User-defined extension type.
  62. int8_t Type;
  63. /// Raw bytes of the extension object.
  64. StringRef Bytes;
  65. };
  66. /// MessagePack object, represented as a tagged union of C++ types.
  67. ///
  68. /// All types except \c Type::Nil (which has only one value, and so is
  69. /// completely represented by the \c Kind itself) map to a exactly one union
  70. /// member.
  71. struct Object {
  72. Type Kind;
  73. union {
  74. /// Value for \c Type::Int.
  75. int64_t Int;
  76. /// Value for \c Type::Uint.
  77. uint64_t UInt;
  78. /// Value for \c Type::Boolean.
  79. bool Bool;
  80. /// Value for \c Type::Float.
  81. double Float;
  82. /// Value for \c Type::String and \c Type::Binary.
  83. StringRef Raw;
  84. /// Value for \c Type::Array and \c Type::Map.
  85. size_t Length;
  86. /// Value for \c Type::Extension.
  87. ExtensionType Extension;
  88. };
  89. Object() : Kind(Type::Int), Int(0) {}
  90. };
  91. /// Reads MessagePack objects from memory, one at a time.
  92. class Reader {
  93. public:
  94. /// Construct a reader, keeping a reference to the \p InputBuffer.
  95. Reader(MemoryBufferRef InputBuffer);
  96. /// Construct a reader, keeping a reference to the \p Input.
  97. Reader(StringRef Input);
  98. Reader(const Reader &) = delete;
  99. Reader &operator=(const Reader &) = delete;
  100. /// Read one object from the input buffer, advancing past it.
  101. ///
  102. /// The \p Obj is updated with the kind of the object read, and the
  103. /// corresponding union member is updated.
  104. ///
  105. /// For the collection objects (Array and Map), only the length is read, and
  106. /// the caller must make and additional \c N calls (in the case of Array) or
  107. /// \c N*2 calls (in the case of Map) to \c Read to retrieve the collection
  108. /// elements.
  109. ///
  110. /// \param [out] Obj filled with next object on success.
  111. ///
  112. /// \returns true when object successfully read, false when at end of
  113. /// input (and so \p Obj was not updated), otherwise an error.
  114. Expected<bool> read(Object &Obj);
  115. private:
  116. MemoryBufferRef InputBuffer;
  117. StringRef::iterator Current;
  118. StringRef::iterator End;
  119. size_t remainingSpace() {
  120. // The rest of the code maintains the invariant that End >= Current, so
  121. // that this cast is always defined behavior.
  122. return static_cast<size_t>(End - Current);
  123. }
  124. template <class T> Expected<bool> readRaw(Object &Obj);
  125. template <class T> Expected<bool> readInt(Object &Obj);
  126. template <class T> Expected<bool> readUInt(Object &Obj);
  127. template <class T> Expected<bool> readLength(Object &Obj);
  128. template <class T> Expected<bool> readExt(Object &Obj);
  129. Expected<bool> createRaw(Object &Obj, uint32_t Size);
  130. Expected<bool> createExt(Object &Obj, uint32_t Size);
  131. };
  132. } // end namespace msgpack
  133. } // end namespace llvm
  134. #endif // LLVM_BINARYFORMAT_MSGPACKREADER_H