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 const char* ReadString() 161 { 162 const char* string = (const char*)fData; 163 while (fSize > 0) { 164 fData++; 165 fSize--; 166 167 if (fData[-1] == 0) 168 return string; 169 } 170 171 fOverflow = true; 172 return NULL; 173 } 174 175 uint64 ReadInitialLength(bool& _dwarf64) 176 { 177 uint64 length = Read<uint32>(0); 178 _dwarf64 = (length == 0xffffffff); 179 if (_dwarf64) 180 length = Read<uint64>(0); 181 return length; 182 } 183 184 bool Skip(off_t bytes) 185 { 186 if (bytes < 0) 187 return false; 188 189 if (bytes > fSize) { 190 fSize = 0; 191 fOverflow = true; 192 return false; 193 } 194 195 fData += bytes; 196 fSize -= bytes; 197 198 return true; 199 } 200 201 private: 202 const uint8* fData; 203 off_t fSize; 204 off_t fInitialSize; 205 uint8 fAddressSize; 206 bool fOverflow; 207 }; 208 209 210 #endif // DATA_READER_H 211