summaryrefslogtreecommitdiff
path: root/include/llvm/Object/YAML.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/Object/YAML.h')
-rw-r--r--include/llvm/Object/YAML.h116
1 files changed, 116 insertions, 0 deletions
diff --git a/include/llvm/Object/YAML.h b/include/llvm/Object/YAML.h
new file mode 100644
index 0000000000000..89fe5047a86e9
--- /dev/null
+++ b/include/llvm/Object/YAML.h
@@ -0,0 +1,116 @@
+//===- YAML.h - YAMLIO utilities for object files ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares utility classes for handling the YAML representation of
+// object files.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_YAML_H
+#define LLVM_OBJECT_YAML_H
+
+#include "llvm/Support/YAMLTraits.h"
+
+namespace llvm {
+namespace object {
+namespace yaml {
+
+/// \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<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);
+ /// \brief Either raw binary data, or a string of hex bytes (must always
+ /// be an even number of characters).
+ ArrayRef<uint8_t> Data;
+ /// \brief Discriminator between the two states of the `Data` member.
+ bool DataIsHexString;
+
+public:
+ BinaryRef(ArrayRef<uint8_t> Data) : Data(Data), DataIsHexString(false) {}
+ BinaryRef(StringRef Data)
+ : Data(reinterpret_cast<const uint8_t *>(Data.data()), Data.size()),
+ 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<uint8_t>::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;
+}
+
+}
+}
+
+namespace yaml {
+template <> struct ScalarTraits<object::yaml::BinaryRef> {
+ static void output(const object::yaml::BinaryRef &, void *,
+ llvm::raw_ostream &);
+ static StringRef input(StringRef, void *, object::yaml::BinaryRef &);
+};
+}
+
+}
+
+#endif