1 /*************************************************************************** 2 * Copyright (C) 2005-2019 by the FIFE team * 3 * http://www.fifengine.net * 4 * This file is part of FIFE. * 5 * * 6 * FIFE is free software; you can redistribute it and/or * 7 * modify it under the terms of the GNU Lesser General Public * 8 * License as published by the Free Software Foundation; either * 9 * version 2.1 of the License, or (at your option) any later version. * 10 * * 11 * This library is distributed in the hope that it will be useful, * 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 14 * Lesser General Public License for more details. * 15 * * 16 * You should have received a copy of the GNU Lesser General Public * 17 * License along with this library; if not, write to the * 18 * Free Software Foundation, Inc., * 19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * 20 ***************************************************************************/ 21 22 #ifndef FIFE_VFS_RAW_RAWDATA_H 23 #define FIFE_VFS_RAW_RAWDATA_H 24 25 // Standard C++ library includes 26 #include <memory> 27 #include <vector> 28 29 // Platform specific includes 30 #include "util/base/fife_stdint.h" 31 32 // 3rd party library includes 33 34 // FIFE includes 35 // These includes are split up in two parts, separated by one empty line 36 // First block: files included from the FIFE root src directory 37 // Second block: files included from the same folder 38 39 #include "rawdatasource.h" 40 41 namespace FIFE { 42 43 /** Used to access diffrent kinds of data. 44 * 45 * RawData uses RawDataSource to get the real data - that way the user doesn't have to know where the data comes 46 * from (real files, files inside archives etc.) 47 */ 48 class RawData { 49 public: 50 RawData(RawDataSource* datasource); 51 virtual ~RawData(); 52 53 /** get the data as a vector of bytes 54 * This does not append a null terminator to the end 55 */ 56 std::vector<uint8_t> getDataInBytes(); 57 58 /** get the data in distinct lines 59 */ 60 std::vector<std::string> getDataInLines(); 61 62 63 /** get the complete datalength 64 * 65 * @return the complete datalength 66 */ 67 uint32_t getDataLength() const; 68 69 /** get the current index 70 * 71 * @return the current index 72 */ 73 uint32_t getCurrentIndex() const; 74 75 /** set the current index 76 * 77 * @param index the new index 78 * @throws IndexOverflow if index is >= getDataLength() 79 */ 80 void setIndex(uint32_t index); 81 82 /** move the current index 83 * 84 * @param offset the offset 85 * @throws IndexOverflow if we move outside the datalength 86 */ 87 void moveIndex(int32_t offset); 88 89 /** helper-function 90 * 91 * reads sizeof(T) bytes - should be used with fixed-size datatypes like uint32_t, uint16_t, uint8_t etc. 92 * @return the data 93 */ readSingle()94 template <typename T> T readSingle() { 95 T val; 96 readInto(reinterpret_cast<uint8_t*>(&val), sizeof(T)); 97 return val; 98 } 99 100 /** read len bytes into buffer 101 * 102 * @param buffer the data will be written into it 103 * @param len len bytes will be written 104 * @throws IndexOverflow if currentindex + len > getCurrentIndex() 105 */ 106 void readInto(uint8_t* buffer, size_t len); 107 108 /** reads 1 byte */ 109 uint8_t read8(); 110 111 /** reads a uint16_t littleEndian and converts them to the host-byteorder 112 * @throws IndexOverflow 113 */ 114 uint16_t read16Little(); 115 116 /** reads a uint16_t littleEndian and converts them to the host-byteorder 117 * 118 * @throws IndexOverflow 119 */ 120 uint32_t read32Little(); 121 122 /** reads a uint16_t bigEndian and converts them to the host-byteorder 123 * 124 * @throws IndexOverflow 125 */ 126 uint16_t read16Big(); 127 128 /** reads a uint16_t bigEndian and converts them to the host-byteorder 129 * 130 * @throws IndexOverflow 131 */ 132 uint32_t read32Big(); 133 134 /** read a string with len bytes, not assuming a terminating 0 135 * Appends a null terminator character to the end 136 * 137 * @param len the stringlen 138 * @return the string 139 * @throws IndexOverflow 140 */ 141 std::string readString(size_t len); 142 143 /** Reads all data into the buffer 144 * This does not append a null terminator to the end 145 * Created to especially fulfill python file interface requirements 146 */ 147 void read(std::string& outbuffer, int32_t size=-1); 148 149 /** reads until a \\n is encountered or no more data is available 150 * 151 * @param buffer if successfull the new string will be assigned to buffer 152 * @return true if data was available, false otherwise (in that case buffer won't be touched) 153 */ 154 bool getLine(std::string& buffer); 155 156 private: 157 RawDataSource* m_datasource; 158 size_t m_index_current; 159 littleToHost(T value)160 template <typename T> T littleToHost(T value) const { 161 if (littleEndian()) 162 return value; 163 else 164 return revert(value); 165 } 166 bigToHost(T value)167 template <typename T> T bigToHost(T value) const { 168 if (!littleEndian()) 169 return value; 170 else 171 return revert(value); 172 } 173 revert(T value)174 template <typename T> T revert(T value) const { 175 T retval; 176 for (uint32_t i = 0; i < sizeof(T); ++i) 177 reinterpret_cast<uint8_t*>(&retval)[i] = reinterpret_cast<uint8_t*>(&value)[sizeof(T)-1-i]; 178 179 return retval; 180 } 181 182 RawData(const RawData&); 183 RawData& operator=(const RawData&) { return *this; }; 184 185 static bool littleEndian(); 186 }; 187 typedef std::shared_ptr<RawData> RawDataPtr; 188 189 class IndexSaver { 190 public: IndexSaver(RawData * d)191 IndexSaver(RawData* d) : m_rd(d), m_index(m_rd->getCurrentIndex()) {} 192 ~IndexSaver()193 ~IndexSaver() { 194 m_rd->setIndex(m_index); 195 } 196 197 private: 198 RawData* m_rd; 199 uint32_t m_index; 200 201 IndexSaver(const IndexSaver&); 202 IndexSaver& operator=(const IndexSaver&) { return *this; } 203 }; 204 205 }//FIFE 206 207 #endif 208