1 /* 2 * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 #ifndef DATA_READER_H 6 #define DATA_READER_H 7 8 9 #include <string.h> 10 11 #include "Types.h" 12 13 14 class DataReader { 15 public: 16 DataReader() 17 : 18 fData(NULL), 19 fSize(0), 20 fInitialSize(0), 21 fAddressSize(4), 22 fOverflow(false) 23 { 24 } 25 26 DataReader(const void* data, off_t size, uint8 addressSize) 27 { 28 SetTo(data, size, addressSize); 29 } 30 31 void SetTo(const void* data, off_t size, uint8 addressSize) 32 { 33 fData = (const uint8*)data; 34 fInitialSize = fSize = size; 35 fAddressSize = addressSize; 36 fOverflow = false; 37 } 38 39 DataReader RestrictedReader() 40 { 41 return *this; 42 } 43 44 DataReader RestrictedReader(off_t maxLength) 45 { 46 return DataReader(fData, maxLength, fAddressSize); 47 } 48 49 DataReader RestrictedReader(off_t relativeOffset, off_t maxLength) 50 { 51 return DataReader(fData + relativeOffset, maxLength, fAddressSize); 52 } 53 54 bool HasData() const 55 { 56 return fSize > 0; 57 } 58 59 uint32 AddressSize() const 60 { 61 return fAddressSize; 62 } 63 64 void SetAddressSize(uint8 addressSize) 65 { 66 fAddressSize = addressSize; 67 } 68 69 bool HasOverflow() const 70 { 71 return fOverflow; 72 } 73 74 const void* Data() const 75 { 76 return fData; 77 } 78 79 off_t BytesRemaining() const 80 { 81 return fSize; 82 } 83 84 off_t Offset() const 85 { 86 return fInitialSize - fSize; 87 } 88 89 void SeekAbsolute(off_t offset) 90 { 91 if (offset < 0) 92 offset = 0; 93 else if (offset > fInitialSize) 94 offset = fInitialSize; 95 96 fData += offset - Offset(); 97 fSize = fInitialSize - offset; 98 } 99 100 template<typename Type> 101 Type Read(const Type& defaultValue) 102 { 103 if (fSize < (off_t)sizeof(Type)) { 104 fOverflow = true; 105 fSize = 0; 106 return defaultValue; 107 } 108 109 Type data; 110 memcpy(&data, fData, sizeof(Type)); 111 112 fData += sizeof(Type); 113 fSize -= sizeof(Type); 114 115 return data; 116 } 117 118 target_addr_t ReadAddress(target_addr_t defaultValue) 119 { 120 return fAddressSize == 4 121 ? (target_addr_t)Read<uint32>(defaultValue) 122 : (target_addr_t)Read<uint64>(defaultValue); 123 } 124 125 uint64 ReadUnsignedLEB128(uint64 defaultValue) 126 { 127 uint64 result = 0; 128 int shift = 0; 129 while (true) { 130 uint8 byte = Read<uint8>(0); 131 result |= uint64(byte & 0x7f) << shift; 132 if ((byte & 0x80) == 0) 133 break; 134 shift += 7; 135 } 136 137 return fOverflow ? defaultValue : result; 138 } 139 140 int64 ReadSignedLEB128(int64 defaultValue) 141 { 142 int64 result = 0; 143 int shift = 0; 144 while (true) { 145 uint8 byte = Read<uint8>(0); 146 result |= uint64(byte & 0x7f) << shift; 147 shift += 7; 148 149 if ((byte & 0x80) == 0) { 150 // sign extend 151 if ((byte & 0x40) != 0 && shift < 64) 152 result |= -((uint64)1 << shift); 153 break; 154 } 155 } 156 157 return fOverflow ? defaultValue : result; 158 } 159 160 uint32 ReadU24(uint32 defaultValue) 161 { 162 uint8 res1 = Read<uint8>(0); 163 uint8 res2 = Read<uint8>(0); 164 uint8 res3 = Read<uint8>(0); 165 #if defined(__HAIKU_LITTLE_ENDIAN) 166 uint32 result = res1 | (res2 << 8) | (res3 << 16); 167 #elif defined(__HAIKU_BIG_ENDIAN) 168 uint32 result = res3 | (res2 << 8) | (res1 << 16); 169 #else 170 #error endiannes not defined 171 #endif 172 return fOverflow ? defaultValue : result; 173 } 174 175 const char* ReadString() 176 { 177 const char* string = (const char*)fData; 178 while (fSize > 0) { 179 fData++; 180 fSize--; 181 182 if (fData[-1] == 0) 183 return string; 184 } 185 186 fOverflow = true; 187 return NULL; 188 } 189 190 uint64 ReadInitialLength(bool& _dwarf64) 191 { 192 uint64 length = Read<uint32>(0); 193 _dwarf64 = (length == 0xffffffff); 194 if (_dwarf64) 195 length = Read<uint64>(0); 196 return length; 197 } 198 199 bool Skip(off_t bytes) 200 { 201 if (bytes < 0) 202 return false; 203 204 if (bytes > fSize) { 205 fSize = 0; 206 fOverflow = true; 207 return false; 208 } 209 210 fData += bytes; 211 fSize -= bytes; 212 213 return true; 214 } 215 216 private: 217 const uint8* fData; 218 off_t fSize; 219 off_t fInitialSize; 220 uint8 fAddressSize; 221 bool fOverflow; 222 }; 223 224 225 #endif // DATA_READER_H 226