blob: 0366ee3a7926648fb6304e94d18baf803f227346 [file] [log] [blame]
Chris Lattner3446ae82004-01-10 19:00:15 +00001//===-- ReaderPrimitives.h - Bytecode file format reading prims -*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by the LLVM research group and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This header defines some basic functions for reading basic primitive types
11// from a bytecode stream.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef READERPRIMITIVES_H
16#define READERPRIMITIVES_H
17
18#include "Support/DataTypes.h"
19#include <string>
20
21namespace llvm {
22
Chris Lattner7969dc22004-01-15 06:13:09 +000023 static inline unsigned read(const unsigned char *&Buf,
24 const unsigned char *EndBuf) {
25 if (Buf+4 > EndBuf) throw std::string("Ran out of data!");
26 Buf += 4;
27 return Buf[-4] | (Buf[-3] << 8) | (Buf[-2] << 16) | (Buf[-1] << 24);
28 }
Chris Lattner3446ae82004-01-10 19:00:15 +000029
30
Chris Lattner7969dc22004-01-15 06:13:09 +000031 // read_vbr - Read an unsigned integer encoded in variable bitrate format.
32 //
33 static inline unsigned read_vbr_uint(const unsigned char *&Buf,
34 const unsigned char *EndBuf) {
35 unsigned Shift = 0;
36 unsigned Result = 0;
37
38 do {
39 if (Buf == EndBuf) throw std::string("Ran out of data!");
40 Result |= (unsigned)((*Buf++) & 0x7F) << Shift;
41 Shift += 7;
42 } while (Buf[-1] & 0x80);
43 return Result;
44 }
Chris Lattner3446ae82004-01-10 19:00:15 +000045
Chris Lattner7969dc22004-01-15 06:13:09 +000046 static inline uint64_t read_vbr_uint64(const unsigned char *&Buf,
47 const unsigned char *EndBuf) {
48 unsigned Shift = 0;
49 uint64_t Result = 0;
50
51 do {
52 if (Buf == EndBuf) throw std::string("Ran out of data!");
53 Result |= (uint64_t)((*Buf++) & 0x7F) << Shift;
54 Shift += 7;
55 } while (Buf[-1] & 0x80);
56 return Result;
57 }
Chris Lattner3446ae82004-01-10 19:00:15 +000058
Chris Lattner7969dc22004-01-15 06:13:09 +000059 static inline int64_t read_vbr_int64(const unsigned char *&Buf,
60 const unsigned char *EndBuf) {
61 uint64_t R = read_vbr_uint64(Buf, EndBuf);
62 if (R & 1)
63 return -(int64_t)(R >> 1);
64 else
65 return (int64_t)(R >> 1);
66 }
67
68 // align32 - Round up to multiple of 32 bits...
69 static inline void align32(const unsigned char *&Buf,
70 const unsigned char *EndBuf) {
71 Buf = (const unsigned char *)((unsigned long)(Buf+3) & (~3UL));
72 if (Buf > EndBuf) throw std::string("Ran out of data!");
73 }
74
75 static inline std::string read_str(const unsigned char *&Buf,
76 const unsigned char *EndBuf) {
77 unsigned Size = read_vbr_uint(Buf, EndBuf);
78 const unsigned char *OldBuf = Buf;
79 Buf += Size;
80 if (Buf > EndBuf) // Size invalid?
81 throw std::string("Ran out of data reading a string!");
82 return std::string((char*)OldBuf, Size);
83 }
84
85 static inline void input_data(const unsigned char *&Buf,
86 const unsigned char *EndBuf,
87 void *Ptr, void *End) {
88 unsigned char *Start = (unsigned char *)Ptr;
89 unsigned Amount = (unsigned char *)End - Start;
90 if (Buf+Amount > EndBuf) throw std::string("Ran out of data!");
91 std::copy(Buf, Buf+Amount, Start);
92 Buf += Amount;
93 }
94
Chris Lattner3446ae82004-01-10 19:00:15 +000095} // End llvm namespace
96
97#endif