blob: 0b0cf2cb4f5acf05bdbd62d82b9df8ddb54e7d3f [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
23static 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
35static 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
49static inline bool read(const unsigned char *&Buf, const unsigned char *EndBuf,
50 int &Result) {
51 return read(Buf, EndBuf, (unsigned &)Result);
52}
53
54static 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//
62static 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
74static 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
86static 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
99static 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...
112static 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
118static 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
133static inline bool input_data(const unsigned char *&Buf,
134 const unsigned char *EndBuf,
Chris Lattner4e868362004-01-14 23:03:22 +0000135 void *Ptr, void *End) {
Chris Lattner3446ae82004-01-10 19:00:15 +0000136 unsigned char *Start = (unsigned char *)Ptr;
137 unsigned Amount = (unsigned char *)End - Start;
138 if (Buf+Amount > EndBuf) return true;
Chris Lattner3446ae82004-01-10 19:00:15 +0000139 std::copy(Buf, Buf+Amount, Start);
140 Buf += Amount;
Chris Lattner3446ae82004-01-10 19:00:15 +0000141 return false;
142}
143
144} // End llvm namespace
145
146#endif