blob: 496ab2a5b13eeb6a15bd47ed26fc2914b4bd98db [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);
Chris Lattner62f8bf02004-01-20 19:13:07 +000062 if (R & 1) {
63 if (R != 1)
64 return -(int64_t)(R >> 1);
65 else // There is no such thing as -0 with integers. "-0" really means
66 // 0x8000000000000000.
67 return 1LL << 63;
68 } else
Chris Lattner7969dc22004-01-15 06:13:09 +000069 return (int64_t)(R >> 1);
70 }
71
72 // align32 - Round up to multiple of 32 bits...
73 static inline void align32(const unsigned char *&Buf,
74 const unsigned char *EndBuf) {
75 Buf = (const unsigned char *)((unsigned long)(Buf+3) & (~3UL));
76 if (Buf > EndBuf) throw std::string("Ran out of data!");
77 }
78
79 static inline std::string read_str(const unsigned char *&Buf,
80 const unsigned char *EndBuf) {
81 unsigned Size = read_vbr_uint(Buf, EndBuf);
82 const unsigned char *OldBuf = Buf;
83 Buf += Size;
84 if (Buf > EndBuf) // Size invalid?
85 throw std::string("Ran out of data reading a string!");
86 return std::string((char*)OldBuf, Size);
87 }
88
89 static inline void input_data(const unsigned char *&Buf,
90 const unsigned char *EndBuf,
91 void *Ptr, void *End) {
92 unsigned char *Start = (unsigned char *)Ptr;
93 unsigned Amount = (unsigned char *)End - Start;
94 if (Buf+Amount > EndBuf) throw std::string("Ran out of data!");
95 std::copy(Buf, Buf+Amount, Start);
96 Buf += Amount;
97 }
98
Chris Lattner3446ae82004-01-10 19:00:15 +000099} // End llvm namespace
100
101#endif