File indexing completed on 2026-05-10 08:43:22
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #ifndef LLVM_BINARYFORMAT_MSGPACKDOCUMENT_H
0018 #define LLVM_BINARYFORMAT_MSGPACKDOCUMENT_H
0019
0020 #include "llvm/BinaryFormat/MsgPackReader.h"
0021 #include <map>
0022
0023 namespace llvm {
0024 namespace msgpack {
0025
0026 class ArrayDocNode;
0027 class Document;
0028 class MapDocNode;
0029
0030
0031 struct KindAndDocument {
0032 Document *Doc;
0033 Type Kind;
0034 };
0035
0036
0037
0038 class DocNode {
0039 friend Document;
0040
0041 public:
0042 typedef std::map<DocNode, DocNode> MapTy;
0043 typedef std::vector<DocNode> ArrayTy;
0044
0045 private:
0046
0047
0048
0049
0050 const KindAndDocument *KindAndDoc;
0051
0052 protected:
0053
0054 union {
0055 int64_t Int;
0056 uint64_t UInt;
0057 bool Bool;
0058 double Float;
0059 StringRef Raw;
0060 ArrayTy *Array;
0061 MapTy *Map;
0062 };
0063
0064 public:
0065
0066
0067 DocNode() : KindAndDoc(nullptr) {}
0068
0069
0070 bool isMap() const { return getKind() == Type::Map; }
0071 bool isArray() const { return getKind() == Type::Array; }
0072 bool isScalar() const { return !isMap() && !isArray(); }
0073 bool isString() const { return getKind() == Type::String; }
0074
0075
0076
0077
0078 bool isEmpty() const { return !KindAndDoc || getKind() == Type::Empty; }
0079 Type getKind() const { return KindAndDoc->Kind; }
0080 Document *getDocument() const { return KindAndDoc->Doc; }
0081
0082 int64_t &getInt() {
0083 assert(getKind() == Type::Int);
0084 return Int;
0085 }
0086
0087 uint64_t &getUInt() {
0088 assert(getKind() == Type::UInt);
0089 return UInt;
0090 }
0091
0092 bool &getBool() {
0093 assert(getKind() == Type::Boolean);
0094 return Bool;
0095 }
0096
0097 double &getFloat() {
0098 assert(getKind() == Type::Float);
0099 return Float;
0100 }
0101
0102 int64_t getInt() const {
0103 assert(getKind() == Type::Int);
0104 return Int;
0105 }
0106
0107 uint64_t getUInt() const {
0108 assert(getKind() == Type::UInt);
0109 return UInt;
0110 }
0111
0112 bool getBool() const {
0113 assert(getKind() == Type::Boolean);
0114 return Bool;
0115 }
0116
0117 double getFloat() const {
0118 assert(getKind() == Type::Float);
0119 return Float;
0120 }
0121
0122 StringRef getString() const {
0123 assert(getKind() == Type::String);
0124 return Raw;
0125 }
0126
0127 MemoryBufferRef getBinary() const {
0128 assert(getKind() == Type::Binary);
0129 return MemoryBufferRef(Raw, "");
0130 }
0131
0132
0133
0134 ArrayDocNode &getArray(bool Convert = false) {
0135 if (getKind() != Type::Array) {
0136 assert(Convert);
0137 convertToArray();
0138 }
0139
0140 return *reinterpret_cast<ArrayDocNode *>(this);
0141 }
0142
0143
0144
0145 MapDocNode &getMap(bool Convert = false) {
0146 if (getKind() != Type::Map) {
0147 assert(Convert);
0148 convertToMap();
0149 }
0150
0151 return *reinterpret_cast<MapDocNode *>(this);
0152 }
0153
0154
0155 friend bool operator<(const DocNode &Lhs, const DocNode &Rhs) {
0156
0157
0158 if (Rhs.isEmpty())
0159 return false;
0160 if (Lhs.KindAndDoc != Rhs.KindAndDoc) {
0161 if (Lhs.isEmpty())
0162 return true;
0163 return (unsigned)Lhs.getKind() < (unsigned)Rhs.getKind();
0164 }
0165 switch (Lhs.getKind()) {
0166 case Type::Int:
0167 return Lhs.Int < Rhs.Int;
0168 case Type::UInt:
0169 return Lhs.UInt < Rhs.UInt;
0170 case Type::Nil:
0171 return false;
0172 case Type::Boolean:
0173 return Lhs.Bool < Rhs.Bool;
0174 case Type::Float:
0175 return Lhs.Float < Rhs.Float;
0176 case Type::String:
0177 case Type::Binary:
0178 return Lhs.Raw < Rhs.Raw;
0179 default:
0180 llvm_unreachable("bad map key type");
0181 }
0182 }
0183
0184
0185 friend bool operator==(const DocNode &Lhs, const DocNode &Rhs) {
0186 return !(Lhs < Rhs) && !(Rhs < Lhs);
0187 }
0188
0189
0190 friend bool operator!=(const DocNode &Lhs, const DocNode &Rhs) {
0191 return !(Lhs == Rhs);
0192 }
0193
0194
0195 std::string toString() const;
0196
0197
0198
0199
0200 StringRef fromString(StringRef S, StringRef Tag = "");
0201
0202
0203
0204
0205
0206
0207 DocNode &operator=(const char *Val) { return *this = StringRef(Val); }
0208 DocNode &operator=(StringRef Val);
0209 DocNode &operator=(MemoryBufferRef Val);
0210 DocNode &operator=(bool Val);
0211 DocNode &operator=(int Val);
0212 DocNode &operator=(unsigned Val);
0213 DocNode &operator=(int64_t Val);
0214 DocNode &operator=(uint64_t Val);
0215
0216 private:
0217
0218 DocNode(const KindAndDocument *KindAndDoc) : KindAndDoc(KindAndDoc) {}
0219
0220 void convertToArray();
0221 void convertToMap();
0222 };
0223
0224
0225 class MapDocNode : public DocNode {
0226 public:
0227 MapDocNode() = default;
0228 MapDocNode(DocNode &N) : DocNode(N) { assert(getKind() == Type::Map); }
0229
0230
0231 size_t size() const { return Map->size(); }
0232 bool empty() const { return !size(); }
0233 MapTy::iterator begin() { return Map->begin(); }
0234 MapTy::iterator end() { return Map->end(); }
0235 MapTy::iterator find(DocNode Key) { return Map->find(Key); }
0236 MapTy::iterator find(StringRef Key);
0237 MapTy::iterator erase(MapTy::const_iterator I) { return Map->erase(I); }
0238 size_t erase(DocNode Key) { return Map->erase(Key); }
0239 MapTy::iterator erase(MapTy::const_iterator First,
0240 MapTy::const_iterator Second) {
0241 return Map->erase(First, Second);
0242 }
0243
0244
0245 DocNode &operator[](StringRef S);
0246
0247 DocNode &operator[](DocNode Key);
0248 DocNode &operator[](int Key);
0249 DocNode &operator[](unsigned Key);
0250 DocNode &operator[](int64_t Key);
0251 DocNode &operator[](uint64_t Key);
0252 };
0253
0254
0255 class ArrayDocNode : public DocNode {
0256 public:
0257 ArrayDocNode() = default;
0258 ArrayDocNode(DocNode &N) : DocNode(N) { assert(getKind() == Type::Array); }
0259
0260
0261 size_t size() const { return Array->size(); }
0262 bool empty() const { return !size(); }
0263 DocNode &back() const { return Array->back(); }
0264 ArrayTy::iterator begin() { return Array->begin(); }
0265 ArrayTy::iterator end() { return Array->end(); }
0266 void push_back(DocNode N) {
0267 assert(N.isEmpty() || N.getDocument() == getDocument());
0268 Array->push_back(N);
0269 }
0270
0271
0272 DocNode &operator[](size_t Index);
0273 };
0274
0275
0276
0277
0278 class Document {
0279
0280
0281 std::vector<std::unique_ptr<DocNode::MapTy>> Maps;
0282 std::vector<std::unique_ptr<DocNode::ArrayTy>> Arrays;
0283 std::vector<std::unique_ptr<char[]>> Strings;
0284
0285
0286 DocNode Root;
0287
0288
0289 KindAndDocument KindAndDocs[size_t(Type::Empty) + 1];
0290
0291
0292 bool HexMode = false;
0293
0294 public:
0295 Document() {
0296 clear();
0297 for (unsigned T = 0; T != unsigned(Type::Empty) + 1; ++T)
0298 KindAndDocs[T] = {this, Type(T)};
0299 }
0300
0301
0302 DocNode &getRoot() { return Root; }
0303
0304
0305 void clear() { getRoot() = getEmptyNode(); }
0306
0307
0308 DocNode getEmptyNode() {
0309 auto N = DocNode(&KindAndDocs[size_t(Type::Empty)]);
0310 return N;
0311 }
0312
0313
0314 DocNode getNode() {
0315 auto N = DocNode(&KindAndDocs[size_t(Type::Nil)]);
0316 return N;
0317 }
0318
0319
0320 DocNode getNode(int64_t V) {
0321 auto N = DocNode(&KindAndDocs[size_t(Type::Int)]);
0322 N.Int = V;
0323 return N;
0324 }
0325
0326
0327 DocNode getNode(int V) {
0328 auto N = DocNode(&KindAndDocs[size_t(Type::Int)]);
0329 N.Int = V;
0330 return N;
0331 }
0332
0333
0334 DocNode getNode(uint64_t V) {
0335 auto N = DocNode(&KindAndDocs[size_t(Type::UInt)]);
0336 N.UInt = V;
0337 return N;
0338 }
0339
0340
0341 DocNode getNode(unsigned V) {
0342 auto N = DocNode(&KindAndDocs[size_t(Type::UInt)]);
0343 N.UInt = V;
0344 return N;
0345 }
0346
0347
0348 DocNode getNode(bool V) {
0349 auto N = DocNode(&KindAndDocs[size_t(Type::Boolean)]);
0350 N.Bool = V;
0351 return N;
0352 }
0353
0354
0355 DocNode getNode(double V) {
0356 auto N = DocNode(&KindAndDocs[size_t(Type::Float)]);
0357 N.Float = V;
0358 return N;
0359 }
0360
0361
0362
0363 DocNode getNode(StringRef V, bool Copy = false) {
0364 if (Copy)
0365 V = addString(V);
0366 auto N = DocNode(&KindAndDocs[size_t(Type::String)]);
0367 N.Raw = V;
0368 return N;
0369 }
0370
0371
0372
0373 DocNode getNode(const char *V, bool Copy = false) {
0374 return getNode(StringRef(V), Copy);
0375 }
0376
0377
0378
0379 DocNode getNode(MemoryBufferRef V, bool Copy = false) {
0380 auto Raw = V.getBuffer();
0381 if (Copy)
0382 Raw = addString(Raw);
0383 auto N = DocNode(&KindAndDocs[size_t(Type::Binary)]);
0384 N.Raw = Raw;
0385 return N;
0386 }
0387
0388
0389 MapDocNode getMapNode() {
0390 auto N = DocNode(&KindAndDocs[size_t(Type::Map)]);
0391 Maps.push_back(std::make_unique<DocNode::MapTy>());
0392 N.Map = Maps.back().get();
0393 return N.getMap();
0394 }
0395
0396
0397 ArrayDocNode getArrayNode() {
0398 auto N = DocNode(&KindAndDocs[size_t(Type::Array)]);
0399 Arrays.push_back(std::make_unique<DocNode::ArrayTy>());
0400 N.Array = Arrays.back().get();
0401 return N.getArray();
0402 }
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427 bool readFromBlob(
0428 StringRef Blob, bool Multi,
0429 function_ref<int(DocNode *DestNode, DocNode SrcNode, DocNode MapKey)>
0430 Merger = [](DocNode *DestNode, DocNode SrcNode, DocNode MapKey) {
0431 return -1;
0432 });
0433
0434
0435 void writeToBlob(std::string &Blob);
0436
0437
0438
0439 StringRef addString(StringRef S) {
0440 Strings.push_back(std::unique_ptr<char[]>(new char[S.size()]));
0441 memcpy(&Strings.back()[0], S.data(), S.size());
0442 return StringRef(&Strings.back()[0], S.size());
0443 }
0444
0445
0446 void setHexMode(bool Val = true) { HexMode = Val; }
0447
0448
0449 bool getHexMode() const { return HexMode; }
0450
0451
0452 void toYAML(raw_ostream &OS);
0453
0454
0455 bool fromYAML(StringRef S);
0456 };
0457
0458 }
0459 }
0460
0461 #endif