#ifndef LLVM_SUPPORT_OUTPUTBUFFER_H
#define LLVM_SUPPORT_OUTPUTBUFFER_H
#include <cassert>
#include <string>
#include <vector>
namespace llvm {
class OutputBuffer {
std::vector<unsigned char> &Output;
bool is64Bit, isLittleEndian;
public:
OutputBuffer(std::vector<unsigned char> &Out,
bool is64bit, bool le)
: Output(Out), is64Bit(is64bit), isLittleEndian(le) {}
void align(unsigned Boundary) {
assert(Boundary && (Boundary & (Boundary - 1)) == 0 &&
"Must align to 2^k boundary");
size_t Size = Output.size();
if (Size & (Boundary - 1)) {
size_t Pad = Boundary - (Size & (Boundary - 1));
Output.resize(Size + Pad);
}
}
void outbyte(unsigned char X) {
Output.push_back(X);
}
void outhalf(unsigned short X) {
if (isLittleEndian) {
Output.push_back(X & 255);
Output.push_back(X >> 8);
} else {
Output.push_back(X >> 8);
Output.push_back(X & 255);
}
}
void outword(unsigned X) {
if (isLittleEndian) {
Output.push_back((X >> 0) & 255);
Output.push_back((X >> 8) & 255);
Output.push_back((X >> 16) & 255);
Output.push_back((X >> 24) & 255);
} else {
Output.push_back((X >> 24) & 255);
Output.push_back((X >> 16) & 255);
Output.push_back((X >> 8) & 255);
Output.push_back((X >> 0) & 255);
}
}
void outxword(uint64_t X) {
if (isLittleEndian) {
Output.push_back(unsigned(X >> 0) & 255);
Output.push_back(unsigned(X >> 8) & 255);
Output.push_back(unsigned(X >> 16) & 255);
Output.push_back(unsigned(X >> 24) & 255);
Output.push_back(unsigned(X >> 32) & 255);
Output.push_back(unsigned(X >> 40) & 255);
Output.push_back(unsigned(X >> 48) & 255);
Output.push_back(unsigned(X >> 56) & 255);
} else {
Output.push_back(unsigned(X >> 56) & 255);
Output.push_back(unsigned(X >> 48) & 255);
Output.push_back(unsigned(X >> 40) & 255);
Output.push_back(unsigned(X >> 32) & 255);
Output.push_back(unsigned(X >> 24) & 255);
Output.push_back(unsigned(X >> 16) & 255);
Output.push_back(unsigned(X >> 8) & 255);
Output.push_back(unsigned(X >> 0) & 255);
}
}
void outaddr32(unsigned X) {
outword(X);
}
void outaddr64(uint64_t X) {
outxword(X);
}
void outaddr(uint64_t X) {
if (!is64Bit)
outword((unsigned)X);
else
outxword(X);
}
void outstring(const std::string &S, unsigned Length) {
unsigned len_to_copy = static_cast<unsigned>(S.length()) < Length
? static_cast<unsigned>(S.length()) : Length;
unsigned len_to_fill = static_cast<unsigned>(S.length()) < Length
? Length - static_cast<unsigned>(S.length()) : 0;
for (unsigned i = 0; i < len_to_copy; ++i)
outbyte(S[i]);
for (unsigned i = 0; i < len_to_fill; ++i)
outbyte(0);
}
void fixhalf(unsigned short X, unsigned Offset) {
unsigned char *P = &Output[Offset];
P[0] = (X >> (isLittleEndian ? 0 : 8)) & 255;
P[1] = (X >> (isLittleEndian ? 8 : 0)) & 255;
}
void fixword(unsigned X, unsigned Offset) {
unsigned char *P = &Output[Offset];
P[0] = (X >> (isLittleEndian ? 0 : 24)) & 255;
P[1] = (X >> (isLittleEndian ? 8 : 16)) & 255;
P[2] = (X >> (isLittleEndian ? 16 : 8)) & 255;
P[3] = (X >> (isLittleEndian ? 24 : 0)) & 255;
}
void fixxword(uint64_t X, unsigned Offset) {
unsigned char *P = &Output[Offset];
P[0] = (X >> (isLittleEndian ? 0 : 56)) & 255;
P[1] = (X >> (isLittleEndian ? 8 : 48)) & 255;
P[2] = (X >> (isLittleEndian ? 16 : 40)) & 255;
P[3] = (X >> (isLittleEndian ? 24 : 32)) & 255;
P[4] = (X >> (isLittleEndian ? 32 : 24)) & 255;
P[5] = (X >> (isLittleEndian ? 40 : 16)) & 255;
P[6] = (X >> (isLittleEndian ? 48 : 8)) & 255;
P[7] = (X >> (isLittleEndian ? 56 : 0)) & 255;
}
void fixaddr(uint64_t X, unsigned Offset) {
if (!is64Bit)
fixword((unsigned)X, Offset);
else
fixxword(X, Offset);
}
unsigned char &operator[](unsigned Index) {
return Output[Index];
}
const unsigned char &operator[](unsigned Index) const {
return Output[Index];
}
};
}
#endif // LLVM_SUPPORT_OUTPUTBUFFER_H