//===-- 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 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) return -(int64_t)(R >> 1); 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