X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FObject%2FYAML.h;h=89fe5047a86e91c697cc0edf841ccad2ef75fe1b;hb=d8324e6983d06c3d56debcbfdc9ead0e0d4a817d;hp=e6f1da1e1d4253917c57f11847a9c35d490069ad;hpb=2b1068952ade3a1d2c704e7589c54e3d32dc0eb8;p=oota-llvm.git diff --git a/include/llvm/Object/YAML.h b/include/llvm/Object/YAML.h index e6f1da1e1d4..89fe5047a86 100644 --- a/include/llvm/Object/YAML.h +++ b/include/llvm/Object/YAML.h @@ -21,40 +21,85 @@ namespace llvm { namespace object { namespace yaml { -/// In an object file this is just a binary blob. In an yaml file it is an hex -/// string. Using this avoid having to allocate temporary strings. +/// \brief Specialized YAMLIO scalar type for representing a binary blob. +/// +/// A typical use case would be to represent the content of a section in a +/// binary file. +/// This class has custom YAMLIO traits for convenient reading and writing. +/// It renders as a string of hex digits in a YAML file. +/// For example, it might render as `DEADBEEFCAFEBABE` (YAML does not +/// require the quotation marks, so for simplicity when outputting they are +/// omitted). +/// When reading, any string whose content is an even number of hex digits +/// will be accepted. +/// For example, all of the following are acceptable: +/// `DEADBEEF`, `"DeADbEeF"`, `"\x44EADBEEF"` (Note: '\x44' == 'D') +/// +/// A significant advantage of using this class is that it never allocates +/// temporary strings or buffers for any of its functionality. +/// +/// Example: +/// +/// The YAML mapping: +/// \code +/// Foo: DEADBEEFCAFEBABE +/// \endcode +/// +/// Could be modeled in YAMLIO by the struct: +/// \code +/// struct FooHolder { +/// BinaryRef Foo; +/// }; +/// namespace llvm { +/// namespace yaml { +/// template <> +/// struct MappingTraits { +/// static void mapping(IO &IO, FooHolder &FH) { +/// IO.mapRequired("Foo", FH.Foo); +/// } +/// }; +/// } // end namespace yaml +/// } // end namespace llvm +/// \endcode class BinaryRef { + friend bool operator==(const BinaryRef &LHS, const BinaryRef &RHS); /// \brief Either raw binary data, or a string of hex bytes (must always /// be an even number of characters). ArrayRef Data; - bool isBinary; + /// \brief Discriminator between the two states of the `Data` member. + bool DataIsHexString; public: - BinaryRef(ArrayRef Data) : Data(Data), isBinary(true) {} + BinaryRef(ArrayRef Data) : Data(Data), DataIsHexString(false) {} BinaryRef(StringRef Data) : Data(reinterpret_cast(Data.data()), Data.size()), - isBinary(false) {} - BinaryRef() : isBinary(false) {} - StringRef getHex() const { - assert(!isBinary); - return StringRef(reinterpret_cast(Data.data()), Data.size()); - } - ArrayRef getBinary() const { - assert(isBinary); - return Data; - } - bool operator==(const BinaryRef &Ref) { - // Special case for default constructed BinaryRef. - if (Ref.Data.empty() && Data.empty()) - return true; - - return Ref.isBinary == isBinary && Ref.Data == Data; + DataIsHexString(true) {} + BinaryRef() : DataIsHexString(true) {} + /// \brief The number of bytes that are represented by this BinaryRef. + /// This is the number of bytes that writeAsBinary() will write. + ArrayRef::size_type binary_size() const { + if (DataIsHexString) + return Data.size() / 2; + return Data.size(); } /// \brief Write the contents (regardless of whether it is binary or a /// hex string) as binary to the given raw_ostream. void writeAsBinary(raw_ostream &OS) const; + /// \brief Write the contents (regardless of whether it is binary or a + /// hex string) as hex to the given raw_ostream. + /// + /// For example, a possible output could be `DEADBEEFCAFEBABE`. + void writeAsHex(raw_ostream &OS) const; }; +inline bool operator==(const BinaryRef &LHS, const BinaryRef &RHS) { + // Special case for default constructed BinaryRef. + if (LHS.Data.empty() && RHS.Data.empty()) + return true; + + return LHS.DataIsHexString == RHS.DataIsHexString && LHS.Data == RHS.Data; +} + } }