* finegrainify namespacification of ArchiveReader.cpp
[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 bool read(const unsigned char *&Buf, const unsigned char *EndBuf,
24                         unsigned &Result) {
25   if (Buf+4 > EndBuf) return true;
26 #ifdef ENDIAN_LITTLE
27   Result = *(unsigned*)Buf;
28 #else
29   Result = Buf[0] | (Buf[1] << 8) | (Buf[2] << 16) | (Buf[3] << 24);
30 #endif
31   Buf += 4;
32   return false;
33 }
34
35 static inline bool read(const unsigned char *&Buf, const unsigned char *EndBuf,
36                         uint64_t &Result) {
37   if (Buf+8 > EndBuf) return true;
38
39 #ifdef ENDIAN_LITTLE
40   Result = *(uint64_t*)Buf;
41 #else
42   Result = Buf[0] | (Buf[1] << 8) | (Buf[2] << 16) | (Buf[3] << 24) |
43     ((uint64_t)(Buf[4] | (Buf[5] << 8) | (Buf[6] << 16) | (Buf[7] << 24)) <<32);
44 #endif
45   Buf += 8;
46   return false;
47 }
48
49 static inline bool read(const unsigned char *&Buf, const unsigned char *EndBuf,
50                         int &Result) {
51   return read(Buf, EndBuf, (unsigned &)Result);
52 }
53
54 static inline bool read(const unsigned char *&Buf, const unsigned char *EndBuf,
55                         int64_t &Result) {
56   return read(Buf, EndBuf, (uint64_t &)Result);
57 }
58
59
60 // read_vbr - Read an unsigned integer encoded in variable bitrate format.
61 //
62 static inline bool read_vbr(const unsigned char *&Buf, 
63                             const unsigned char *EndBuf, unsigned &Result) {
64   unsigned Shift = Result = 0;
65
66   do {
67     Result |= (unsigned)((*Buf++) & 0x7F) << Shift;
68     Shift += 7;
69   } while (Buf[-1] & 0x80 && Buf < EndBuf);
70
71   return Buf > EndBuf;
72 }
73
74 static inline bool read_vbr(const unsigned char *&Buf, 
75                             const unsigned char *EndBuf, uint64_t &Result) {
76   unsigned Shift = 0; Result = 0;
77
78   do {
79     Result |= (uint64_t)((*Buf++) & 0x7F) << Shift;
80     Shift += 7;
81   } while (Buf[-1] & 0x80 && Buf < EndBuf);
82   return Buf > EndBuf;
83 }
84
85 // read_vbr (signed) - Read a signed number stored in sign-magnitude format
86 static inline bool read_vbr(const unsigned char *&Buf, 
87                             const unsigned char *EndBuf, int &Result) {
88   unsigned R;
89   if (read_vbr(Buf, EndBuf, R)) return true;
90   if (R & 1)
91     Result = -(int)(R >> 1);
92   else
93     Result =  (int)(R >> 1);
94   
95   return false;
96 }
97
98
99 static inline bool read_vbr(const unsigned char *&Buf, 
100                             const unsigned char *EndBuf, int64_t &Result) {
101   uint64_t R;
102   if (read_vbr(Buf, EndBuf, R)) return true;
103   if (R & 1)
104     Result = -(int64_t)(R >> 1);
105   else
106     Result =  (int64_t)(R >> 1);
107   
108   return false;
109 }
110
111 // align32 - Round up to multiple of 32 bits...
112 static inline bool align32(const unsigned char *&Buf, 
113                            const unsigned char *EndBuf) {
114   Buf = (const unsigned char *)((unsigned long)(Buf+3) & (~3UL));
115   return Buf > EndBuf;
116 }
117
118 static inline bool read(const unsigned char *&Buf, const unsigned char *EndBuf, 
119                         std::string &Result, bool Aligned = true) {
120   unsigned Size;
121   if (read_vbr(Buf, EndBuf, Size)) return true;   // Failure reading size?
122   if (Buf+Size > EndBuf) return true;             // Size invalid?
123
124   Result = std::string((char*)Buf, Size);
125   Buf += Size;
126
127   if (Aligned)        // If we should stay aligned do so...
128     if (align32(Buf, EndBuf)) return true;        // Failure aligning?
129
130   return false;
131 }
132
133 static inline bool input_data(const unsigned char *&Buf,
134                               const unsigned char *EndBuf, 
135                               void *Ptr, void *End, bool Align = false) {
136   unsigned char *Start = (unsigned char *)Ptr;
137   unsigned Amount = (unsigned char *)End - Start;
138   if (Buf+Amount > EndBuf) return true;
139 #ifdef ENDIAN_LITTLE
140   std::copy(Buf, Buf+Amount, Start);
141   Buf += Amount;
142 #else
143   unsigned char *E = (unsigned char *)End;
144   while (Ptr != E)
145     *--E = *Buf++;
146 #endif
147
148   if (Align) return align32(Buf, EndBuf);
149   return false;
150 }
151
152 } // End llvm namespace
153
154 #endif