Bytecode format for LLVM 1.2 no longer explicitly encodes zeros in primitive
[oota-llvm.git] / lib / Bytecode / Reader / ReaderPrimitives.h
1 //===-- 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
21 namespace llvm {
22
23   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   }
29
30
31   // 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   }
45   
46   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   }
58   
59   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   
95 } // End llvm namespace
96
97 #endif