xref: /aosp_15_r20/external/llvm/include/llvm/ObjectYAML/YAML.h (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===- YAML.h ---------------------------------------------------*- C++ -*-===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker 
10*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_OBJECTYAML_YAML_H
11*9880d681SAndroid Build Coastguard Worker #define LLVM_OBJECTYAML_YAML_H
12*9880d681SAndroid Build Coastguard Worker 
13*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/YAMLTraits.h"
14*9880d681SAndroid Build Coastguard Worker 
15*9880d681SAndroid Build Coastguard Worker namespace llvm {
16*9880d681SAndroid Build Coastguard Worker namespace yaml {
17*9880d681SAndroid Build Coastguard Worker /// \brief Specialized YAMLIO scalar type for representing a binary blob.
18*9880d681SAndroid Build Coastguard Worker ///
19*9880d681SAndroid Build Coastguard Worker /// A typical use case would be to represent the content of a section in a
20*9880d681SAndroid Build Coastguard Worker /// binary file.
21*9880d681SAndroid Build Coastguard Worker /// This class has custom YAMLIO traits for convenient reading and writing.
22*9880d681SAndroid Build Coastguard Worker /// It renders as a string of hex digits in a YAML file.
23*9880d681SAndroid Build Coastguard Worker /// For example, it might render as `DEADBEEFCAFEBABE` (YAML does not
24*9880d681SAndroid Build Coastguard Worker /// require the quotation marks, so for simplicity when outputting they are
25*9880d681SAndroid Build Coastguard Worker /// omitted).
26*9880d681SAndroid Build Coastguard Worker /// When reading, any string whose content is an even number of hex digits
27*9880d681SAndroid Build Coastguard Worker /// will be accepted.
28*9880d681SAndroid Build Coastguard Worker /// For example, all of the following are acceptable:
29*9880d681SAndroid Build Coastguard Worker /// `DEADBEEF`, `"DeADbEeF"`, `"\x44EADBEEF"` (Note: '\x44' == 'D')
30*9880d681SAndroid Build Coastguard Worker ///
31*9880d681SAndroid Build Coastguard Worker /// A significant advantage of using this class is that it never allocates
32*9880d681SAndroid Build Coastguard Worker /// temporary strings or buffers for any of its functionality.
33*9880d681SAndroid Build Coastguard Worker ///
34*9880d681SAndroid Build Coastguard Worker /// Example:
35*9880d681SAndroid Build Coastguard Worker ///
36*9880d681SAndroid Build Coastguard Worker /// The YAML mapping:
37*9880d681SAndroid Build Coastguard Worker /// \code
38*9880d681SAndroid Build Coastguard Worker /// Foo: DEADBEEFCAFEBABE
39*9880d681SAndroid Build Coastguard Worker /// \endcode
40*9880d681SAndroid Build Coastguard Worker ///
41*9880d681SAndroid Build Coastguard Worker /// Could be modeled in YAMLIO by the struct:
42*9880d681SAndroid Build Coastguard Worker /// \code
43*9880d681SAndroid Build Coastguard Worker /// struct FooHolder {
44*9880d681SAndroid Build Coastguard Worker ///   BinaryRef Foo;
45*9880d681SAndroid Build Coastguard Worker /// };
46*9880d681SAndroid Build Coastguard Worker /// namespace llvm {
47*9880d681SAndroid Build Coastguard Worker /// namespace yaml {
48*9880d681SAndroid Build Coastguard Worker /// template <>
49*9880d681SAndroid Build Coastguard Worker /// struct MappingTraits<FooHolder> {
50*9880d681SAndroid Build Coastguard Worker ///   static void mapping(IO &IO, FooHolder &FH) {
51*9880d681SAndroid Build Coastguard Worker ///     IO.mapRequired("Foo", FH.Foo);
52*9880d681SAndroid Build Coastguard Worker ///   }
53*9880d681SAndroid Build Coastguard Worker /// };
54*9880d681SAndroid Build Coastguard Worker /// } // end namespace yaml
55*9880d681SAndroid Build Coastguard Worker /// } // end namespace llvm
56*9880d681SAndroid Build Coastguard Worker /// \endcode
57*9880d681SAndroid Build Coastguard Worker class BinaryRef {
58*9880d681SAndroid Build Coastguard Worker   friend bool operator==(const BinaryRef &LHS, const BinaryRef &RHS);
59*9880d681SAndroid Build Coastguard Worker   /// \brief Either raw binary data, or a string of hex bytes (must always
60*9880d681SAndroid Build Coastguard Worker   /// be an even number of characters).
61*9880d681SAndroid Build Coastguard Worker   ArrayRef<uint8_t> Data;
62*9880d681SAndroid Build Coastguard Worker   /// \brief Discriminator between the two states of the `Data` member.
63*9880d681SAndroid Build Coastguard Worker   bool DataIsHexString;
64*9880d681SAndroid Build Coastguard Worker 
65*9880d681SAndroid Build Coastguard Worker public:
BinaryRef(ArrayRef<uint8_t> Data)66*9880d681SAndroid Build Coastguard Worker   BinaryRef(ArrayRef<uint8_t> Data) : Data(Data), DataIsHexString(false) {}
BinaryRef(StringRef Data)67*9880d681SAndroid Build Coastguard Worker   BinaryRef(StringRef Data)
68*9880d681SAndroid Build Coastguard Worker       : Data(reinterpret_cast<const uint8_t *>(Data.data()), Data.size()),
69*9880d681SAndroid Build Coastguard Worker         DataIsHexString(true) {}
BinaryRef()70*9880d681SAndroid Build Coastguard Worker   BinaryRef() : DataIsHexString(true) {}
71*9880d681SAndroid Build Coastguard Worker   /// \brief The number of bytes that are represented by this BinaryRef.
72*9880d681SAndroid Build Coastguard Worker   /// This is the number of bytes that writeAsBinary() will write.
binary_size()73*9880d681SAndroid Build Coastguard Worker   ArrayRef<uint8_t>::size_type binary_size() const {
74*9880d681SAndroid Build Coastguard Worker     if (DataIsHexString)
75*9880d681SAndroid Build Coastguard Worker       return Data.size() / 2;
76*9880d681SAndroid Build Coastguard Worker     return Data.size();
77*9880d681SAndroid Build Coastguard Worker   }
78*9880d681SAndroid Build Coastguard Worker   /// \brief Write the contents (regardless of whether it is binary or a
79*9880d681SAndroid Build Coastguard Worker   /// hex string) as binary to the given raw_ostream.
80*9880d681SAndroid Build Coastguard Worker   void writeAsBinary(raw_ostream &OS) const;
81*9880d681SAndroid Build Coastguard Worker   /// \brief Write the contents (regardless of whether it is binary or a
82*9880d681SAndroid Build Coastguard Worker   /// hex string) as hex to the given raw_ostream.
83*9880d681SAndroid Build Coastguard Worker   ///
84*9880d681SAndroid Build Coastguard Worker   /// For example, a possible output could be `DEADBEEFCAFEBABE`.
85*9880d681SAndroid Build Coastguard Worker   void writeAsHex(raw_ostream &OS) const;
86*9880d681SAndroid Build Coastguard Worker };
87*9880d681SAndroid Build Coastguard Worker 
88*9880d681SAndroid Build Coastguard Worker inline bool operator==(const BinaryRef &LHS, const BinaryRef &RHS) {
89*9880d681SAndroid Build Coastguard Worker   // Special case for default constructed BinaryRef.
90*9880d681SAndroid Build Coastguard Worker   if (LHS.Data.empty() && RHS.Data.empty())
91*9880d681SAndroid Build Coastguard Worker     return true;
92*9880d681SAndroid Build Coastguard Worker 
93*9880d681SAndroid Build Coastguard Worker   return LHS.DataIsHexString == RHS.DataIsHexString && LHS.Data == RHS.Data;
94*9880d681SAndroid Build Coastguard Worker }
95*9880d681SAndroid Build Coastguard Worker 
96*9880d681SAndroid Build Coastguard Worker template <> struct ScalarTraits<BinaryRef> {
97*9880d681SAndroid Build Coastguard Worker   static void output(const BinaryRef &, void *, llvm::raw_ostream &);
98*9880d681SAndroid Build Coastguard Worker   static StringRef input(StringRef, void *, BinaryRef &);
99*9880d681SAndroid Build Coastguard Worker   static bool mustQuote(StringRef S) { return needsQuotes(S); }
100*9880d681SAndroid Build Coastguard Worker };
101*9880d681SAndroid Build Coastguard Worker }
102*9880d681SAndroid Build Coastguard Worker }
103*9880d681SAndroid Build Coastguard Worker #endif
104