| //===-- 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 |