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