MsgPackReader.h 4.5 KB

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