15fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola//===- YAML.h - YAMLIO utilities for object files ---------------*- C++ -*-===// 25fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola// 35fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola// The LLVM Compiler Infrastructure 45fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola// 55fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola// This file is distributed under the University of Illinois Open Source 65fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola// License. See LICENSE.TXT for details. 75fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola// 85fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola//===----------------------------------------------------------------------===// 95fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola// 105fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola// This file declares utility classes for handling the YAML representation of 115fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola// object files. 125fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola// 135fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola//===----------------------------------------------------------------------===// 145fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola 155fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola#ifndef LLVM_OBJECT_YAML_H 165fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola#define LLVM_OBJECT_YAML_H 175fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola 185fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola#include "llvm/Support/YAMLTraits.h" 195fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola 205fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindolanamespace llvm { 215fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindolanamespace object { 225fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindolanamespace yaml { 235fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola 24272d881234dac8d51bccf90d52550ee4da888c94Sean Silva/// \brief Specialized YAMLIO scalar type for representing a binary blob. 25272d881234dac8d51bccf90d52550ee4da888c94Sean Silva/// 26272d881234dac8d51bccf90d52550ee4da888c94Sean Silva/// A typical use case would be to represent the content of a section in a 27272d881234dac8d51bccf90d52550ee4da888c94Sean Silva/// binary file. 28272d881234dac8d51bccf90d52550ee4da888c94Sean Silva/// This class has custom YAMLIO traits for convenient reading and writing. 29272d881234dac8d51bccf90d52550ee4da888c94Sean Silva/// It renders as a string of hex digits in a YAML file. 30272d881234dac8d51bccf90d52550ee4da888c94Sean Silva/// For example, it might render as `DEADBEEFCAFEBABE` (YAML does not 31272d881234dac8d51bccf90d52550ee4da888c94Sean Silva/// require the quotation marks, so for simplicity when outputting they are 32272d881234dac8d51bccf90d52550ee4da888c94Sean Silva/// omitted). 33272d881234dac8d51bccf90d52550ee4da888c94Sean Silva/// When reading, any string whose content is an even number of hex digits 34272d881234dac8d51bccf90d52550ee4da888c94Sean Silva/// will be accepted. 35272d881234dac8d51bccf90d52550ee4da888c94Sean Silva/// For example, all of the following are acceptable: 36272d881234dac8d51bccf90d52550ee4da888c94Sean Silva/// `DEADBEEF`, `"DeADbEeF"`, `"\x44EADBEEF"` (Note: '\x44' == 'D') 37272d881234dac8d51bccf90d52550ee4da888c94Sean Silva/// 38272d881234dac8d51bccf90d52550ee4da888c94Sean Silva/// A significant advantage of using this class is that it never allocates 39272d881234dac8d51bccf90d52550ee4da888c94Sean Silva/// temporary strings or buffers for any of its functionality. 40272d881234dac8d51bccf90d52550ee4da888c94Sean Silva/// 41272d881234dac8d51bccf90d52550ee4da888c94Sean Silva/// Example: 42272d881234dac8d51bccf90d52550ee4da888c94Sean Silva/// 43272d881234dac8d51bccf90d52550ee4da888c94Sean Silva/// The YAML mapping: 44272d881234dac8d51bccf90d52550ee4da888c94Sean Silva/// \code 45272d881234dac8d51bccf90d52550ee4da888c94Sean Silva/// Foo: DEADBEEFCAFEBABE 46272d881234dac8d51bccf90d52550ee4da888c94Sean Silva/// \endcode 47272d881234dac8d51bccf90d52550ee4da888c94Sean Silva/// 48272d881234dac8d51bccf90d52550ee4da888c94Sean Silva/// Could be modeled in YAMLIO by the struct: 49272d881234dac8d51bccf90d52550ee4da888c94Sean Silva/// \code 50272d881234dac8d51bccf90d52550ee4da888c94Sean Silva/// struct FooHolder { 51272d881234dac8d51bccf90d52550ee4da888c94Sean Silva/// BinaryRef Foo; 52272d881234dac8d51bccf90d52550ee4da888c94Sean Silva/// }; 53272d881234dac8d51bccf90d52550ee4da888c94Sean Silva/// namespace llvm { 54272d881234dac8d51bccf90d52550ee4da888c94Sean Silva/// namespace yaml { 55272d881234dac8d51bccf90d52550ee4da888c94Sean Silva/// template <> 56272d881234dac8d51bccf90d52550ee4da888c94Sean Silva/// struct MappingTraits<FooHolder> { 57272d881234dac8d51bccf90d52550ee4da888c94Sean Silva/// static void mapping(IO &IO, FooHolder &FH) { 58272d881234dac8d51bccf90d52550ee4da888c94Sean Silva/// IO.mapRequired("Foo", FH.Foo); 59272d881234dac8d51bccf90d52550ee4da888c94Sean Silva/// } 60272d881234dac8d51bccf90d52550ee4da888c94Sean Silva/// }; 61272d881234dac8d51bccf90d52550ee4da888c94Sean Silva/// } // end namespace yaml 62272d881234dac8d51bccf90d52550ee4da888c94Sean Silva/// } // end namespace llvm 63272d881234dac8d51bccf90d52550ee4da888c94Sean Silva/// \endcode 645fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindolaclass BinaryRef { 65814b52710ad53e6d613aebaca8df8e962a432f50Rafael Espindola friend bool operator==(const BinaryRef &LHS, const BinaryRef &RHS); 662b1068952ade3a1d2c704e7589c54e3d32dc0eb8Sean Silva /// \brief Either raw binary data, or a string of hex bytes (must always 672b1068952ade3a1d2c704e7589c54e3d32dc0eb8Sean Silva /// be an even number of characters). 685fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola ArrayRef<uint8_t> Data; 696acc982e74cd8a10d097c10254d7215028e7f036Sean Silva /// \brief Discriminator between the two states of the `Data` member. 706acc982e74cd8a10d097c10254d7215028e7f036Sean Silva bool DataIsHexString; 715fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola 725fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindolapublic: 736acc982e74cd8a10d097c10254d7215028e7f036Sean Silva BinaryRef(ArrayRef<uint8_t> Data) : Data(Data), DataIsHexString(false) {} 745fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola BinaryRef(StringRef Data) 755fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola : Data(reinterpret_cast<const uint8_t *>(Data.data()), Data.size()), 766acc982e74cd8a10d097c10254d7215028e7f036Sean Silva DataIsHexString(true) {} 776acc982e74cd8a10d097c10254d7215028e7f036Sean Silva BinaryRef() : DataIsHexString(true) {} 7863958fba58716ed435563321944f7d4663d2ee2dSean Silva /// \brief The number of bytes that are represented by this BinaryRef. 7963958fba58716ed435563321944f7d4663d2ee2dSean Silva /// This is the number of bytes that writeAsBinary() will write. 8063958fba58716ed435563321944f7d4663d2ee2dSean Silva ArrayRef<uint8_t>::size_type binary_size() const { 816acc982e74cd8a10d097c10254d7215028e7f036Sean Silva if (DataIsHexString) 8263958fba58716ed435563321944f7d4663d2ee2dSean Silva return Data.size() / 2; 8363958fba58716ed435563321944f7d4663d2ee2dSean Silva return Data.size(); 8463958fba58716ed435563321944f7d4663d2ee2dSean Silva } 85639adc59f86d0526dbace4a1ecc4924c6c52e1cdSean Silva /// \brief Write the contents (regardless of whether it is binary or a 86639adc59f86d0526dbace4a1ecc4924c6c52e1cdSean Silva /// hex string) as binary to the given raw_ostream. 87639adc59f86d0526dbace4a1ecc4924c6c52e1cdSean Silva void writeAsBinary(raw_ostream &OS) const; 884370ddb8b821bda66478160c1a1c5714a1877d85Sean Silva /// \brief Write the contents (regardless of whether it is binary or a 894370ddb8b821bda66478160c1a1c5714a1877d85Sean Silva /// hex string) as hex to the given raw_ostream. 904370ddb8b821bda66478160c1a1c5714a1877d85Sean Silva /// 914370ddb8b821bda66478160c1a1c5714a1877d85Sean Silva /// For example, a possible output could be `DEADBEEFCAFEBABE`. 924370ddb8b821bda66478160c1a1c5714a1877d85Sean Silva void writeAsHex(raw_ostream &OS) const; 935fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola}; 945fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola 95814b52710ad53e6d613aebaca8df8e962a432f50Rafael Espindolainline bool operator==(const BinaryRef &LHS, const BinaryRef &RHS) { 96814b52710ad53e6d613aebaca8df8e962a432f50Rafael Espindola // Special case for default constructed BinaryRef. 97814b52710ad53e6d613aebaca8df8e962a432f50Rafael Espindola if (LHS.Data.empty() && RHS.Data.empty()) 98814b52710ad53e6d613aebaca8df8e962a432f50Rafael Espindola return true; 99814b52710ad53e6d613aebaca8df8e962a432f50Rafael Espindola 100814b52710ad53e6d613aebaca8df8e962a432f50Rafael Espindola return LHS.DataIsHexString == RHS.DataIsHexString && LHS.Data == RHS.Data; 101814b52710ad53e6d613aebaca8df8e962a432f50Rafael Espindola} 102814b52710ad53e6d613aebaca8df8e962a432f50Rafael Espindola 1035fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola} 1045fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola} 1055fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola 1065fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindolanamespace yaml { 1075fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindolatemplate <> struct ScalarTraits<object::yaml::BinaryRef> { 1085fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola static void output(const object::yaml::BinaryRef &, void *, 1095fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola llvm::raw_ostream &); 1105fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola static StringRef input(StringRef, void *, object::yaml::BinaryRef &); 1115fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola}; 1125fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola} 1135fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola 1145fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola} 1155fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola 1165fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola#endif 117