10b57cec5SDimitry Andric //===- YAML.cpp - YAMLIO utilities for object files -----------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file defines utility classes for handling the YAML representation of
100b57cec5SDimitry Andric // object files.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric
140b57cec5SDimitry Andric #include "llvm/ObjectYAML/YAML.h"
150b57cec5SDimitry Andric #include "llvm/ADT/StringExtras.h"
160b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
170b57cec5SDimitry Andric #include <cctype>
180b57cec5SDimitry Andric #include <cstdint>
190b57cec5SDimitry Andric
200b57cec5SDimitry Andric using namespace llvm;
210b57cec5SDimitry Andric
output(const yaml::BinaryRef & Val,void *,raw_ostream & Out)220b57cec5SDimitry Andric void yaml::ScalarTraits<yaml::BinaryRef>::output(
230b57cec5SDimitry Andric const yaml::BinaryRef &Val, void *, raw_ostream &Out) {
240b57cec5SDimitry Andric Val.writeAsHex(Out);
250b57cec5SDimitry Andric }
260b57cec5SDimitry Andric
input(StringRef Scalar,void *,yaml::BinaryRef & Val)270b57cec5SDimitry Andric StringRef yaml::ScalarTraits<yaml::BinaryRef>::input(StringRef Scalar, void *,
280b57cec5SDimitry Andric yaml::BinaryRef &Val) {
290b57cec5SDimitry Andric if (Scalar.size() % 2 != 0)
300b57cec5SDimitry Andric return "BinaryRef hex string must contain an even number of nybbles.";
310b57cec5SDimitry Andric // TODO: Can we improve YAMLIO to permit a more accurate diagnostic here?
320b57cec5SDimitry Andric // (e.g. a caret pointing to the offending character).
33*0eae32dcSDimitry Andric if (!llvm::all_of(Scalar, llvm::isHexDigit))
340b57cec5SDimitry Andric return "BinaryRef hex string must contain only hex digits.";
350b57cec5SDimitry Andric Val = yaml::BinaryRef(Scalar);
360b57cec5SDimitry Andric return {};
370b57cec5SDimitry Andric }
380b57cec5SDimitry Andric
writeAsBinary(raw_ostream & OS,uint64_t N) const39480093f4SDimitry Andric void yaml::BinaryRef::writeAsBinary(raw_ostream &OS, uint64_t N) const {
400b57cec5SDimitry Andric if (!DataIsHexString) {
41480093f4SDimitry Andric OS.write((const char *)Data.data(), std::min<uint64_t>(N, Data.size()));
420b57cec5SDimitry Andric return;
430b57cec5SDimitry Andric }
44480093f4SDimitry Andric
45480093f4SDimitry Andric for (uint64_t I = 0, E = std::min<uint64_t>(N, Data.size() / 2); I != E;
46480093f4SDimitry Andric ++I) {
47480093f4SDimitry Andric uint8_t Byte = llvm::hexDigitValue(Data[I * 2]);
480b57cec5SDimitry Andric Byte <<= 4;
49480093f4SDimitry Andric Byte |= llvm::hexDigitValue(Data[I * 2 + 1]);
500b57cec5SDimitry Andric OS.write(Byte);
510b57cec5SDimitry Andric }
520b57cec5SDimitry Andric }
530b57cec5SDimitry Andric
writeAsHex(raw_ostream & OS) const540b57cec5SDimitry Andric void yaml::BinaryRef::writeAsHex(raw_ostream &OS) const {
550b57cec5SDimitry Andric if (binary_size() == 0)
560b57cec5SDimitry Andric return;
570b57cec5SDimitry Andric if (DataIsHexString) {
580b57cec5SDimitry Andric OS.write((const char *)Data.data(), Data.size());
590b57cec5SDimitry Andric return;
600b57cec5SDimitry Andric }
610b57cec5SDimitry Andric for (uint8_t Byte : Data)
620b57cec5SDimitry Andric OS << hexdigit(Byte >> 4) << hexdigit(Byte & 0xf);
630b57cec5SDimitry Andric }
64