15fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola//===- YAML.cpp - YAMLIO utilities for object files -----------------------===//
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 defines utility classes for handling the YAML representation of
115fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola// object files.
125fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola//
135fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola//===----------------------------------------------------------------------===//
145fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola
15cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "llvm/MC/YAML.h"
169e8eafa0f0ad36c3e4397e97b67b8245b04ba618Dmitri Gribenko#include "llvm/ADT/StringExtras.h"
17639adc59f86d0526dbace4a1ecc4924c6c52e1cdSean Silva#include "llvm/Support/raw_ostream.h"
18e3ba15c794839abe076e3e2bdf6c626396a19d4dWill Dietz#include <cctype>
195fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola
205fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindolausing namespace llvm;
215fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola
22cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid yaml::ScalarTraits<yaml::BinaryRef>::output(
23cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    const yaml::BinaryRef &Val, void *, llvm::raw_ostream &Out) {
244370ddb8b821bda66478160c1a1c5714a1877d85Sean Silva  Val.writeAsHex(Out);
255fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola}
265fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola
27cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesStringRef yaml::ScalarTraits<yaml::BinaryRef>::input(StringRef Scalar, void *,
28cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                                     yaml::BinaryRef &Val) {
29639adc59f86d0526dbace4a1ecc4924c6c52e1cdSean Silva  if (Scalar.size() % 2 != 0)
30639adc59f86d0526dbace4a1ecc4924c6c52e1cdSean Silva    return "BinaryRef hex string must contain an even number of nybbles.";
31639adc59f86d0526dbace4a1ecc4924c6c52e1cdSean Silva  // TODO: Can we improve YAMLIO to permit a more accurate diagnostic here?
32639adc59f86d0526dbace4a1ecc4924c6c52e1cdSean Silva  // (e.g. a caret pointing to the offending character).
33639adc59f86d0526dbace4a1ecc4924c6c52e1cdSean Silva  for (unsigned I = 0, N = Scalar.size(); I != N; ++I)
34149d1a1894a92872ad5d28c452e813d34c3d2658Rafael Espindola    if (!isxdigit(Scalar[I]))
35639adc59f86d0526dbace4a1ecc4924c6c52e1cdSean Silva      return "BinaryRef hex string must contain only hex digits.";
36cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  Val = yaml::BinaryRef(Scalar);
375fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola  return StringRef();
385fd5fe0f7bfac0f7973475fcf7a5f8061d983538Rafael Espindola}
39639adc59f86d0526dbace4a1ecc4924c6c52e1cdSean Silva
40cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid yaml::BinaryRef::writeAsBinary(raw_ostream &OS) const {
416acc982e74cd8a10d097c10254d7215028e7f036Sean Silva  if (!DataIsHexString) {
42639adc59f86d0526dbace4a1ecc4924c6c52e1cdSean Silva    OS.write((const char *)Data.data(), Data.size());
43639adc59f86d0526dbace4a1ecc4924c6c52e1cdSean Silva    return;
44639adc59f86d0526dbace4a1ecc4924c6c52e1cdSean Silva  }
45639adc59f86d0526dbace4a1ecc4924c6c52e1cdSean Silva  for (unsigned I = 0, N = Data.size(); I != N; I += 2) {
46639adc59f86d0526dbace4a1ecc4924c6c52e1cdSean Silva    uint8_t Byte;
47639adc59f86d0526dbace4a1ecc4924c6c52e1cdSean Silva    StringRef((const char *)&Data[I],  2).getAsInteger(16, Byte);
48639adc59f86d0526dbace4a1ecc4924c6c52e1cdSean Silva    OS.write(Byte);
49639adc59f86d0526dbace4a1ecc4924c6c52e1cdSean Silva  }
50639adc59f86d0526dbace4a1ecc4924c6c52e1cdSean Silva}
514370ddb8b821bda66478160c1a1c5714a1877d85Sean Silva
52cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid yaml::BinaryRef::writeAsHex(raw_ostream &OS) const {
5336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (binary_size() == 0)
54845e196a52d52abcd789612750f6f34af3a2cc79Sean Silva    return;
554370ddb8b821bda66478160c1a1c5714a1877d85Sean Silva  if (DataIsHexString) {
564370ddb8b821bda66478160c1a1c5714a1877d85Sean Silva    OS.write((const char *)Data.data(), Data.size());
574370ddb8b821bda66478160c1a1c5714a1877d85Sean Silva    return;
584370ddb8b821bda66478160c1a1c5714a1877d85Sean Silva  }
594370ddb8b821bda66478160c1a1c5714a1877d85Sean Silva  for (ArrayRef<uint8_t>::iterator I = Data.begin(), E = Data.end(); I != E;
604370ddb8b821bda66478160c1a1c5714a1877d85Sean Silva       ++I) {
614370ddb8b821bda66478160c1a1c5714a1877d85Sean Silva    uint8_t Byte = *I;
624370ddb8b821bda66478160c1a1c5714a1877d85Sean Silva    OS << hexdigit(Byte >> 4);
634370ddb8b821bda66478160c1a1c5714a1877d85Sean Silva    OS << hexdigit(Byte & 0xf);
644370ddb8b821bda66478160c1a1c5714a1877d85Sean Silva  }
654370ddb8b821bda66478160c1a1c5714a1877d85Sean Silva}
66