LLVM API Documentation

YAML.h
Go to the documentation of this file.
00001 #ifndef LLVM_MC_YAML_H
00002 #define LLVM_MC_YAML_H
00003 
00004 #include "llvm/Support/YAMLTraits.h"
00005 
00006 namespace llvm {
00007 namespace yaml {
00008 /// \brief Specialized YAMLIO scalar type for representing a binary blob.
00009 ///
00010 /// A typical use case would be to represent the content of a section in a
00011 /// binary file.
00012 /// This class has custom YAMLIO traits for convenient reading and writing.
00013 /// It renders as a string of hex digits in a YAML file.
00014 /// For example, it might render as `DEADBEEFCAFEBABE` (YAML does not
00015 /// require the quotation marks, so for simplicity when outputting they are
00016 /// omitted).
00017 /// When reading, any string whose content is an even number of hex digits
00018 /// will be accepted.
00019 /// For example, all of the following are acceptable:
00020 /// `DEADBEEF`, `"DeADbEeF"`, `"\x44EADBEEF"` (Note: '\x44' == 'D')
00021 ///
00022 /// A significant advantage of using this class is that it never allocates
00023 /// temporary strings or buffers for any of its functionality.
00024 ///
00025 /// Example:
00026 ///
00027 /// The YAML mapping:
00028 /// \code
00029 /// Foo: DEADBEEFCAFEBABE
00030 /// \endcode
00031 ///
00032 /// Could be modeled in YAMLIO by the struct:
00033 /// \code
00034 /// struct FooHolder {
00035 ///   BinaryRef Foo;
00036 /// };
00037 /// namespace llvm {
00038 /// namespace yaml {
00039 /// template <>
00040 /// struct MappingTraits<FooHolder> {
00041 ///   static void mapping(IO &IO, FooHolder &FH) {
00042 ///     IO.mapRequired("Foo", FH.Foo);
00043 ///   }
00044 /// };
00045 /// } // end namespace yaml
00046 /// } // end namespace llvm
00047 /// \endcode
00048 class BinaryRef {
00049   friend bool operator==(const BinaryRef &LHS, const BinaryRef &RHS);
00050   /// \brief Either raw binary data, or a string of hex bytes (must always
00051   /// be an even number of characters).
00052   ArrayRef<uint8_t> Data;
00053   /// \brief Discriminator between the two states of the `Data` member.
00054   bool DataIsHexString;
00055 
00056 public:
00057   BinaryRef(ArrayRef<uint8_t> Data) : Data(Data), DataIsHexString(false) {}
00058   BinaryRef(StringRef Data)
00059       : Data(reinterpret_cast<const uint8_t *>(Data.data()), Data.size()),
00060         DataIsHexString(true) {}
00061   BinaryRef() : DataIsHexString(true) {}
00062   /// \brief The number of bytes that are represented by this BinaryRef.
00063   /// This is the number of bytes that writeAsBinary() will write.
00064   ArrayRef<uint8_t>::size_type binary_size() const {
00065     if (DataIsHexString)
00066       return Data.size() / 2;
00067     return Data.size();
00068   }
00069   /// \brief Write the contents (regardless of whether it is binary or a
00070   /// hex string) as binary to the given raw_ostream.
00071   void writeAsBinary(raw_ostream &OS) const;
00072   /// \brief Write the contents (regardless of whether it is binary or a
00073   /// hex string) as hex to the given raw_ostream.
00074   ///
00075   /// For example, a possible output could be `DEADBEEFCAFEBABE`.
00076   void writeAsHex(raw_ostream &OS) const;
00077 };
00078 
00079 inline bool operator==(const BinaryRef &LHS, const BinaryRef &RHS) {
00080   // Special case for default constructed BinaryRef.
00081   if (LHS.Data.empty() && RHS.Data.empty())
00082     return true;
00083 
00084   return LHS.DataIsHexString == RHS.DataIsHexString && LHS.Data == RHS.Data;
00085 }
00086 
00087 template <> struct ScalarTraits<BinaryRef> {
00088   static void output(const BinaryRef &, void *, llvm::raw_ostream &);
00089   static StringRef input(StringRef, void *, BinaryRef &);
00090   static bool mustQuote(StringRef S) { return needsQuotes(S); }
00091 };
00092 }
00093 }
00094 #endif