diff options
Diffstat (limited to 'lib/Bytecode/Analyzer/ReaderPrimitives.h')
-rw-r--r-- | lib/Bytecode/Analyzer/ReaderPrimitives.h | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/lib/Bytecode/Analyzer/ReaderPrimitives.h b/lib/Bytecode/Analyzer/ReaderPrimitives.h new file mode 100644 index 0000000000..496ab2a5b1 --- /dev/null +++ b/lib/Bytecode/Analyzer/ReaderPrimitives.h @@ -0,0 +1,101 @@ +//===-- ReaderPrimitives.h - Bytecode file format reading prims -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This header defines some basic functions for reading basic primitive types +// from a bytecode stream. +// +//===----------------------------------------------------------------------===// + +#ifndef READERPRIMITIVES_H +#define READERPRIMITIVES_H + +#include "Support/DataTypes.h" +#include <string> + +namespace llvm { + + static inline unsigned read(const unsigned char *&Buf, + const unsigned char *EndBuf) { + if (Buf+4 > EndBuf) throw std::string("Ran out of data!"); + Buf += 4; + return Buf[-4] | (Buf[-3] << 8) | (Buf[-2] << 16) | (Buf[-1] << 24); + } + + + // read_vbr - Read an unsigned integer encoded in variable bitrate format. + // + static inline unsigned read_vbr_uint(const unsigned char *&Buf, + const unsigned char *EndBuf) { + unsigned Shift = 0; + unsigned Result = 0; + + do { + if (Buf == EndBuf) throw std::string("Ran out of data!"); + Result |= (unsigned)((*Buf++) & 0x7F) << Shift; + Shift += 7; + } while (Buf[-1] & 0x80); + return Result; + } + + static inline uint64_t read_vbr_uint64(const unsigned char *&Buf, + const unsigned char *EndBuf) { + unsigned Shift = 0; + uint64_t Result = 0; + + do { + if (Buf == EndBuf) throw std::string("Ran out of data!"); + Result |= (uint64_t)((*Buf++) & 0x7F) << Shift; + Shift += 7; + } while (Buf[-1] & 0x80); + return Result; + } + + static inline int64_t read_vbr_int64(const unsigned char *&Buf, + const unsigned char *EndBuf) { + uint64_t R = read_vbr_uint64(Buf, EndBuf); + if (R & 1) { + if (R != 1) + return -(int64_t)(R >> 1); + else // There is no such thing as -0 with integers. "-0" really means + // 0x8000000000000000. + return 1LL << 63; + } else + return (int64_t)(R >> 1); + } + + // align32 - Round up to multiple of 32 bits... + static inline void align32(const unsigned char *&Buf, + const unsigned char *EndBuf) { + Buf = (const unsigned char *)((unsigned long)(Buf+3) & (~3UL)); + if (Buf > EndBuf) throw std::string("Ran out of data!"); + } + + static inline std::string read_str(const unsigned char *&Buf, + const unsigned char *EndBuf) { + unsigned Size = read_vbr_uint(Buf, EndBuf); + const unsigned char *OldBuf = Buf; + Buf += Size; + if (Buf > EndBuf) // Size invalid? + throw std::string("Ran out of data reading a string!"); + return std::string((char*)OldBuf, Size); + } + + static inline void input_data(const unsigned char *&Buf, + const unsigned char *EndBuf, + void *Ptr, void *End) { + unsigned char *Start = (unsigned char *)Ptr; + unsigned Amount = (unsigned char *)End - Start; + if (Buf+Amount > EndBuf) throw std::string("Ran out of data!"); + std::copy(Buf, Buf+Amount, Start); + Buf += Amount; + } + +} // End llvm namespace + +#endif |