xref: /freebsd-src/contrib/llvm-project/llvm/lib/ObjectYAML/YAML.cpp (revision 0eae32dcef82f6f06de6419a0d623d7def0cc8f6)
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