diff options
Diffstat (limited to 'clang-r353983/include/llvm/ObjectYAML/YAML.h')
| -rw-r--r-- | clang-r353983/include/llvm/ObjectYAML/YAML.h | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/clang-r353983/include/llvm/ObjectYAML/YAML.h b/clang-r353983/include/llvm/ObjectYAML/YAML.h new file mode 100644 index 00000000..a14bfbc5 --- /dev/null +++ b/clang-r353983/include/llvm/ObjectYAML/YAML.h @@ -0,0 +1,116 @@ +//===- YAML.h ---------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_OBJECTYAML_YAML_H +#define LLVM_OBJECTYAML_YAML_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/YAMLTraits.h" +#include <cstdint> + +namespace llvm { + +class raw_ostream; + +namespace yaml { + +/// 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<FooHolder> { +/// 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); + + /// Either raw binary data, or a string of hex bytes (must always + /// be an even number of characters). + ArrayRef<uint8_t> Data; + + /// Discriminator between the two states of the `Data` member. + bool DataIsHexString = true; + +public: + BinaryRef() = default; + BinaryRef(ArrayRef<uint8_t> Data) : Data(Data), DataIsHexString(false) {} + BinaryRef(StringRef Data) + : Data(reinterpret_cast<const uint8_t *>(Data.data()), Data.size()) {} + + /// The number of bytes that are represented by this BinaryRef. + /// This is the number of bytes that writeAsBinary() will write. + ArrayRef<uint8_t>::size_type binary_size() const { + if (DataIsHexString) + return Data.size() / 2; + return Data.size(); + } + + /// 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; + + /// 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; +} + +template <> struct ScalarTraits<BinaryRef> { + static void output(const BinaryRef &, void *, raw_ostream &); + static StringRef input(StringRef, void *, BinaryRef &); + static QuotingType mustQuote(StringRef S) { return needsQuotes(S); } +}; + +} // end namespace yaml + +} // end namespace llvm + +#endif // LLVM_OBJECTYAML_YAML_H |
