1 #ifndef __GNUC__
2 #pragma once
3 #endif
4 #ifndef __XR_WRITER_H__
5 #define __XR_WRITER_H__
6 
7 #include <string>
8 #include <vector>
9 #include <stack>
10 #include <functional>
11 #include "xr_vector2.h"
12 #include "xr_vector3.h"
13 #include "xr_color.h"
14 
15 namespace xray_re {
16 
17 class xr_packet;
18 class xr_ini_packet;
19 
20 class xr_writer {
21 public:
22 			xr_writer();
23 	virtual		~xr_writer();
24 
25 	virtual void	w_raw(const void* data, size_t size) = 0;
26 	virtual void	seek(size_t pos) = 0;
27 	virtual size_t	tell() = 0;
28 
29 	void		open_chunk(uint32_t id);
30 	void		close_chunk();
31 	void		w_raw_chunk(uint32_t id, const void* data, size_t size);
32 
33 	void		w_chunk(uint32_t id, const std::string& s);
34 
35 	template<typename T> void		w_chunk(uint32_t id, const T& value);
36 	template<typename T, typename F> void	w_chunks(const T& container, F write);
37 	template<typename T, typename F> void	w_seq(const T& container, F write);
38 	template<typename T> void		w_seq(const T& container);
39 	template<typename T> void		w_cseq(size_t n, const T values[]);
40 	template<typename T, typename F> void	w_cseq(size_t n, const T values[], F write);
41 	template<typename T> void		w(const T& value);
42 
43 	void		w_sz(const std::string& value);
44 	void		w_sz(const char* value);
45 	void		w_sf(const char* format, ...);
46 	void		w_s(const std::string& value);
47 	void		w_s(const char* value);
48 	void		w_u32(uint32_t value);
49 	void		w_s32(int32_t value);
50 	void		w_u24(uint32_t value);
51 	void		w_u16(uint16_t value);
52 	void		w_s16(int16_t value);
53 	void		w_u8(uint8_t value);
54 	void		w_s8(int8_t value);
55 	void		w_bool(bool value);
56 	void		w_float(float value);
57 	void		w_float_q16(float value, float min = 0, float max = 1.f);
58 	void		w_float_q8(float value, float min = 0, float max = 1.f);
59 	void		w_fvector3(const fvector3& v);
60 	void		w_fvector2(const fvector2& v);
61 	void		w_i32vector2(const i32vector2& v);
62 	void		w_fcolor(const fcolor& c);
63 	void		w_dir(const fvector3& v);
64 	void		w_sdir(const fvector3& v);
65 	void		w_size_u32(size_t value);
66 	void		w_size_u16(size_t value);
67 	void		w_size_u8(size_t value);
68 
69 	void		w_packet(const xr_packet& packet);
70 
71 	template<typename T> struct f_w: public std::binary_function<T, xr_writer, void> {};
72 	struct f_w_sz: public f_w<std::string> {
operatorf_w_sz73 		void operator()(const std::string& s, xr_writer& w) { w.w_sz(s); }
74 	};
75 	template<typename T> struct f_w_const: public std::const_mem_fun1_t<void, T, xr_writer&> {
f_w_constf_w_const76 		explicit f_w_const(void (T::*_pmf)(xr_writer& w) const): std::const_mem_fun1_t<void, T, xr_writer&>(_pmf) {}
77 	};
78 
79 private:
80 	std::stack<size_t>	m_open_chunks;
81 
82 	char buf[8192];
83 };
84 
85 class xr_fake_writer: public xr_writer {
86 public:
87 			xr_fake_writer();
88 	virtual		~xr_fake_writer();
89 	virtual void	w_raw(const void* data, size_t size);
90 	virtual void	seek(size_t pos);
91 	virtual size_t	tell();
92 
93 private:
94 	size_t		m_pos;
95 	size_t		m_size;
96 };
97 
98 class xr_memory_writer: public xr_writer {
99 public:
100 			xr_memory_writer();
101 			~xr_memory_writer();
102 
103 	virtual void	w_raw(const void* data, size_t size);
104 	virtual void	seek(size_t pos);
105 	virtual size_t	tell();
106 
107 	const uint8_t*	data() const;
108 
109 	bool		save_to(const char* path);
110 	bool		save_to(const std::string& path);
111 	bool		save_to(const char* path, const std::string& name);
112 
113 private:
114 	std::vector<uint8_t>	m_buffer;
115 	size_t			m_pos;
116 };
117 
118 struct xr_guid;
119 
120 class xr_ini_writer: public xr_memory_writer {
121 public:
122 				xr_ini_writer();
123 
124 	void			open_section(const char *name);
125 	void			open_section(std::string format, ...);
126 	void			close_section();
127 	void			write(const char *key, const char *value, bool enclose = true);
128 	void			write(const char *key, std::string value, bool enclose = true);
129 	//void			write(const char *key, std::string& value, bool enclose = true);
130 	void			write(const char *key, float value);
131 	void			write(const char *key, int8_t value);
132 	void			write(const char *key, int16_t value);
133 	void			write(const char *key, int32_t value);
134 	void			write(const char *key, int64_t value);
135 	void			write(const char *key, uint8_t value);
136 	void			write(const char *key, uint16_t value);
137 	void			write(const char *key, uint32_t value);
138 	void			write(const char *key, uint64_t value);
139 	void			write(const char *key, fvector2 value);
140 	void			write(const char *key, fvector3 value);
141 	void			write(const char *key, fcolor value);
142 	void			write(const char *key, xr_guid *value);
143 	template<typename T, typename F> inline void w_sections(const T& container, F write, const char* prefix = "object");
144 	template<typename T> inline void w_ini_seq(const T& container, const char* prefix);
145 	template<typename T, typename F> inline void w_ini_seq(const T& container, F write, const char* prefix);
146 	template<typename T, typename F> inline void w_ini_seq(const T& container, F write);
147 
148 
149 	void		write_packet(xr_ini_packet* packet);
150 private:
151 	std::stack<std::string> m_section_stack;
152 };
153 
xr_writer()154 inline xr_writer::xr_writer() {}
~xr_writer()155 inline xr_writer::~xr_writer() {}
w(const T & value)156 template<typename T> inline void xr_writer::w(const T& value) { w_raw(&value, sizeof(T)); }
w_u32(uint32_t value)157 inline void xr_writer::w_u32(uint32_t value) { w<uint32_t>(value); }
w_s32(int32_t value)158 inline void xr_writer::w_s32(int32_t value) { w<int32_t>(value); }
w_u24(uint32_t value)159 inline void xr_writer::w_u24(uint32_t value) { w_raw(&value, 3); }
w_u16(uint16_t value)160 inline void xr_writer::w_u16(uint16_t value) { w<uint16_t>(value); }
w_s16(int16_t value)161 inline void xr_writer::w_s16(int16_t value) { w<int16_t>(value); }
w_u8(uint8_t value)162 inline void xr_writer::w_u8(uint8_t value) { w<uint8_t>(value); }
w_s8(int8_t value)163 inline void xr_writer::w_s8(int8_t value) { w<int8_t>(value); }
w_bool(bool value)164 inline void xr_writer::w_bool(bool value) { w_u8(value ? 1 : 0); }
w_float(float value)165 inline void xr_writer::w_float(float value) { w<float>(value); }
w_fvector3(const fvector3 & v)166 inline void xr_writer::w_fvector3(const fvector3& v)
167 {
168 	w_float(v.x);
169 	w_float(v.y);
170 	w_float(v.z);
171 }
w_fvector2(const fvector2 & v)172 inline void xr_writer::w_fvector2(const fvector2& v)
173 {
174 	w_float(v.x);
175 	w_float(v.y);
176 }
w_i32vector2(const i32vector2 & v)177 inline void xr_writer::w_i32vector2(const i32vector2& v)
178 {
179 	w_s32(v.x);
180 	w_s32(v.y);
181 }
w_fcolor(const fcolor & c)182 inline void xr_writer::w_fcolor(const fcolor&c)
183 {
184 	w_float(c.r);
185 	w_float(c.g);
186 	w_float(c.b);
187 	w_float(c.a);
188 }
189 
w_size_u32(size_t value)190 inline void xr_writer::w_size_u32(size_t value) { w_u32(static_cast<uint32_t>(value & UINT32_MAX)); }
w_size_u16(size_t value)191 inline void xr_writer::w_size_u16(size_t value) { w_u16(static_cast<uint16_t>(value & UINT16_MAX)); }
w_size_u8(size_t value)192 inline void xr_writer::w_size_u8(size_t value) { w_u8(static_cast<uint8_t>(value & UINT8_MAX)); }
193 
w_cseq(size_t n,const T values[])194 template<typename T> inline void xr_writer::w_cseq(size_t n, const T values[])
195 {
196 	if (n)
197 		w_raw(values, n*sizeof(T));
198 }
199 
w_cseq(size_t n,const T values[],F write)200 template<typename T, typename F> inline void xr_writer::w_cseq(size_t n, const T values[], F write)
201 {
202 	for (const T *p = values, *end = p + n; p != end; ++p)
203 		write(*p, *this);
204 }
205 
w_seq(const T & container)206 template<typename T> inline void xr_writer::w_seq(const T& container)
207 {
208 	if (!container.empty())
209 		w_raw(&container[0], container.size()*sizeof(typename T::value_type));
210 }
211 
w_seq(const T & container,F write)212 template<typename T, typename F> inline void xr_writer::w_seq(const T& container, F write)
213 {
214 	for (typename T::const_iterator it = container.begin(),
215 			end = container.end(); it != end; ++it) {
216 		write(*it, *this);
217 	}
218 }
219 
w_chunk(uint32_t id,const std::string & s)220 inline void xr_writer::w_chunk(uint32_t id, const std::string& s)
221 {
222 	open_chunk(id);
223 	w_sz(s);
224 	close_chunk();
225 }
226 
w_chunk(uint32_t id,const T & value)227 template<typename T> inline void xr_writer::w_chunk(uint32_t id, const T& value)
228 {
229 	w_raw_chunk(id, &value, sizeof(T));
230 }
231 
w_chunks(const T & container,F write)232 template<typename T, typename F> inline void xr_writer::w_chunks(const T& container, F write)
233 {
234 	typename T::const_iterator it = container.begin(), end = container.end();
235 	for (uint32_t id = 0; it != end; ++it) {
236 		open_chunk(id++);
237 		write(*it, *this);
238 		close_chunk();
239 	}
240 }
241 
w_ini_seq(const T & container,const char * prefix)242 template<typename T> inline void xr_ini_writer::w_ini_seq(const T& container, const char* prefix)
243 {
244 	char buf[1024];
245 
246 	typename T::const_iterator it = container.begin(), end = container.end();
247 	for (uint32_t id = 0; it != end; ++it) {
248 #if defined(_MSC_VER) && _MSC_VER >= 1400
249 		int n = sprintf_s(buf, sizeof(buf), "%s_%04d", prefix, id);
250 #else
251 		int n = snprintf(buf, sizeof(buf), "%s_%04d", prefix, id);
252 #endif
253 		if (n > 0)
254 			write(buf, *it);
255 		id++;
256 	}
257 }
258 
w_ini_seq(const T & container,F write)259 template<typename T, typename F> inline void xr_ini_writer::w_ini_seq(const T& container, F write)
260 {
261 	uint32_t id = 0;
262 	for (typename T::const_iterator it = container.begin(),
263 			end = container.end(); it != end; ++it, ++id) {
264 		write(*it, this, id);
265 	}
266 }
267 
w_ini_seq(const T & container,F write,const char * prefix)268 template<typename T, typename F> inline void xr_ini_writer::w_ini_seq(const T& container, F write, const char* prefix)
269 {
270 	char buf[1024];
271 	typename T::const_iterator it = container.begin(), end = container.end();
272 
273 	for (uint32_t id = 0; it != end; ++it, ++id) {
274 #if defined(_MSC_VER) && _MSC_VER >= 1400
275 		int n = sprintf_s(buf, sizeof(buf), "%s_%04d", prefix, id);
276 #else
277 		int n = snprintf(buf, sizeof(buf), "%s_%04d", prefix, id);
278 #endif
279 		if (n > 0)
280 			write(*it, *this, buf);
281 	}
282 }
283 
w_sections(const T & container,F write,const char * prefix)284 template<typename T, typename F> inline void xr_ini_writer::w_sections(const T& container, F write, const char* prefix)
285 {
286 	typename T::const_iterator it = container.begin(), end = container.end();
287 	for (uint32_t id = 0; it != end; ++it) {
288 		open_section("%s_%d", prefix, id++);
289 		write(*it, this);
290 		close_section();
291 	}
292 }
293 
data()294 inline const uint8_t* xr_memory_writer::data() const { return &m_buffer[0]; }
295 
296 } // end of namespace xray_re
297 
298 #endif
299