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