OutputBuffer.h revision 6b5788edb17bad161bbe7a21f38a45f92bba892f
1//=== OutputBuffer.h - Output Buffer ----------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// Methods to output values to a data buffer. 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef LLVM_SUPPORT_OUTPUTBUFFER_H 15#define LLVM_SUPPORT_OUTPUTBUFFER_H 16 17#include <string> 18#include <vector> 19 20namespace llvm { 21 22 class OutputBuffer { 23 /// Output buffer. 24 std::vector<unsigned char> &Output; 25 26 /// is64Bit/isLittleEndian - This information is inferred from the target 27 /// machine directly, indicating what header values and flags to set. 28 bool is64Bit, isLittleEndian; 29 public: 30 OutputBuffer(std::vector<unsigned char> &Out, 31 bool is64bit, bool le) 32 : Output(Out), is64Bit(is64bit), isLittleEndian(le) {} 33 34 // align - Emit padding into the file until the current output position is 35 // aligned to the specified power of two boundary. 36 void align(unsigned Boundary) { 37 assert(Boundary && (Boundary & (Boundary - 1)) == 0 && 38 "Must align to 2^k boundary"); 39 size_t Size = Output.size(); 40 41 if (Size & (Boundary - 1)) { 42 // Add padding to get alignment to the correct place. 43 size_t Pad = Boundary - (Size & (Boundary - 1)); 44 Output.resize(Size + Pad); 45 } 46 } 47 48 //===------------------------------------------------------------------===// 49 // Out Functions - Output the specified value to the data buffer. 50 51 void outbyte(unsigned char X) { 52 Output.push_back(X); 53 } 54 void outhalf(unsigned short X) { 55 if (isLittleEndian) { 56 Output.push_back(X & 255); 57 Output.push_back(X >> 8); 58 } else { 59 Output.push_back(X >> 8); 60 Output.push_back(X & 255); 61 } 62 } 63 void outword(unsigned X) { 64 if (isLittleEndian) { 65 Output.push_back((X >> 0) & 255); 66 Output.push_back((X >> 8) & 255); 67 Output.push_back((X >> 16) & 255); 68 Output.push_back((X >> 24) & 255); 69 } else { 70 Output.push_back((X >> 24) & 255); 71 Output.push_back((X >> 16) & 255); 72 Output.push_back((X >> 8) & 255); 73 Output.push_back((X >> 0) & 255); 74 } 75 } 76 void outxword(uint64_t X) { 77 if (isLittleEndian) { 78 Output.push_back(unsigned(X >> 0) & 255); 79 Output.push_back(unsigned(X >> 8) & 255); 80 Output.push_back(unsigned(X >> 16) & 255); 81 Output.push_back(unsigned(X >> 24) & 255); 82 Output.push_back(unsigned(X >> 32) & 255); 83 Output.push_back(unsigned(X >> 40) & 255); 84 Output.push_back(unsigned(X >> 48) & 255); 85 Output.push_back(unsigned(X >> 56) & 255); 86 } else { 87 Output.push_back(unsigned(X >> 56) & 255); 88 Output.push_back(unsigned(X >> 48) & 255); 89 Output.push_back(unsigned(X >> 40) & 255); 90 Output.push_back(unsigned(X >> 32) & 255); 91 Output.push_back(unsigned(X >> 24) & 255); 92 Output.push_back(unsigned(X >> 16) & 255); 93 Output.push_back(unsigned(X >> 8) & 255); 94 Output.push_back(unsigned(X >> 0) & 255); 95 } 96 } 97 void outaddr32(unsigned X) { 98 outword(X); 99 } 100 void outaddr64(uint64_t X) { 101 outxword(X); 102 } 103 void outaddr(uint64_t X) { 104 if (!is64Bit) 105 outword((unsigned)X); 106 else 107 outxword(X); 108 } 109 void outstring(const std::string &S, unsigned Length) { 110 unsigned len_to_copy = static_cast<unsigned>(S.length()) < Length 111 ? static_cast<unsigned>(S.length()) : Length; 112 unsigned len_to_fill = static_cast<unsigned>(S.length()) < Length 113 ? Length - static_cast<unsigned>(S.length()) : 0; 114 115 for (unsigned i = 0; i < len_to_copy; ++i) 116 outbyte(S[i]); 117 118 for (unsigned i = 0; i < len_to_fill; ++i) 119 outbyte(0); 120 } 121 122 //===------------------------------------------------------------------===// 123 // Fix Functions - Replace an existing entry at an offset. 124 125 void fixhalf(unsigned short X, unsigned Offset) { 126 unsigned char *P = &Output[Offset]; 127 P[0] = (X >> (isLittleEndian ? 0 : 8)) & 255; 128 P[1] = (X >> (isLittleEndian ? 8 : 0)) & 255; 129 } 130 void fixword(unsigned X, unsigned Offset) { 131 unsigned char *P = &Output[Offset]; 132 P[0] = (X >> (isLittleEndian ? 0 : 24)) & 255; 133 P[1] = (X >> (isLittleEndian ? 8 : 16)) & 255; 134 P[2] = (X >> (isLittleEndian ? 16 : 8)) & 255; 135 P[3] = (X >> (isLittleEndian ? 24 : 0)) & 255; 136 } 137 void fixxword(uint64_t X, unsigned Offset) { 138 unsigned char *P = &Output[Offset]; 139 P[0] = (X >> (isLittleEndian ? 0 : 56)) & 255; 140 P[1] = (X >> (isLittleEndian ? 8 : 48)) & 255; 141 P[2] = (X >> (isLittleEndian ? 16 : 40)) & 255; 142 P[3] = (X >> (isLittleEndian ? 24 : 32)) & 255; 143 P[4] = (X >> (isLittleEndian ? 32 : 24)) & 255; 144 P[5] = (X >> (isLittleEndian ? 40 : 16)) & 255; 145 P[6] = (X >> (isLittleEndian ? 48 : 8)) & 255; 146 P[7] = (X >> (isLittleEndian ? 56 : 0)) & 255; 147 } 148 void fixaddr(uint64_t X, unsigned Offset) { 149 if (!is64Bit) 150 fixword((unsigned)X, Offset); 151 else 152 fixxword(X, Offset); 153 } 154 155 unsigned char &operator[](unsigned Index) { 156 return Output[Index]; 157 } 158 const unsigned char &operator[](unsigned Index) const { 159 return Output[Index]; 160 } 161 }; 162 163} // end llvm namespace 164 165#endif // LLVM_SUPPORT_OUTPUTBUFFER_H 166