1 /**************************************************************************
3 * Copyright 2013-2014 RAD Game Tools and Valve Software
4 * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 **************************************************************************/
27 // File: data_stream_serializer.h
30 #include "vogl_core.h"
31 #include "vogl_data_stream.h"
35 // Defaults to little endian mode.
36 class data_stream_serializer
39 data_stream_serializer()
40 : m_pStream(NULL), m_little_endian(true)
43 data_stream_serializer(data_stream *pStream)
44 : m_pStream(pStream), m_little_endian(true)
47 data_stream_serializer(data_stream &stream)
48 : m_pStream(&stream), m_little_endian(true)
51 data_stream_serializer(const data_stream_serializer &other)
52 : m_pStream(other.m_pStream), m_little_endian(other.m_little_endian)
56 data_stream_serializer &operator=(const data_stream_serializer &rhs)
58 m_pStream = rhs.m_pStream;
59 m_little_endian = rhs.m_little_endian;
63 data_stream *get_stream() const
67 void set_stream(data_stream *pStream)
72 const dynamic_string &get_name() const
74 return m_pStream ? m_pStream->get_name() : g_empty_dynamic_string;
77 // true if stream has latched an error
80 return m_pStream ? m_pStream->get_error() : false;
83 bool get_little_endian() const
85 return m_little_endian;
87 void set_little_endian(bool little_endian)
89 m_little_endian = little_endian;
92 bool write(const void *pBuf, uint len)
94 return m_pStream->write(pBuf, len) == len;
97 bool read(void *pBuf, uint len)
99 return m_pStream->read(pBuf, len) == len;
102 // size = size of each element, count = number of elements, returns actual count of elements written
103 uint write(const void *pBuf, uint size, uint count)
105 uint actual_size = size * count;
108 uint n = m_pStream->write(pBuf, actual_size);
109 if (n == actual_size)
114 // size = size of each element, count = number of elements, returns actual count of elements read
115 uint read(void *pBuf, uint size, uint count)
117 uint actual_size = size * count;
120 uint n = m_pStream->read(pBuf, actual_size);
121 if (n == actual_size)
126 bool write_chars(const char *pBuf, uint len)
128 return write(pBuf, len);
131 bool read_chars(char *pBuf, uint len)
133 return read(pBuf, len);
138 return m_pStream->skip(len) == len;
141 template <typename T>
142 bool write_object(const T &obj)
144 if (m_little_endian == c_vogl_little_endian_platform)
145 return write(&obj, sizeof(obj));
148 uint8 buf[sizeof(T)];
149 uint buf_size = sizeof(T);
151 utils::write_obj(obj, pBuf, buf_size, m_little_endian);
153 return write(buf, sizeof(T));
157 template <typename T>
158 bool read_object(T &obj)
160 if (m_little_endian == c_vogl_little_endian_platform)
161 return read(&obj, sizeof(obj));
164 uint8 buf[sizeof(T)];
165 if (!read(buf, sizeof(T)))
168 uint buf_size = sizeof(T);
169 const void *pBuf = buf;
170 utils::read_obj(obj, pBuf, buf_size, m_little_endian);
176 template <typename T>
177 bool write_value(T value)
179 return write_object(value);
182 template <typename T>
183 T read_value(const T &on_error_value = T())
186 if (!read_object(result))
187 result = on_error_value;
191 int8 read_int8(int8 def = 0)
194 if (!read_object(result))
199 uint8 read_uint8(uint8 def = 0)
202 if (!read_object(result))
207 int16 read_int16(int16 def = 0)
210 if (!read_object(result))
215 uint16 read_uint16(uint16 def = 0)
218 if (!read_object(result))
223 int32 read_int32(int32 def = 0)
226 if (!read_object(result))
231 uint32 read_uint32(uint32 def = 0)
234 if (!read_object(result))
239 float read_float(float def = 0)
242 if (!read_object(result))
247 double read_double(double def = 0)
250 if (!read_object(result))
255 int64_t read_int64(int64_t def = 0)
258 if (!read_object(result))
263 uint64_t read_uint64(uint64_t def = 0)
266 if (!read_object(result))
271 template <typename T>
274 int val = static_cast<int>(e);
275 return write_object(val);
278 template <typename T>
281 return static_cast<T>(read_value<int>());
284 // Writes uint using a simple variable length code (VLC).
285 bool write_uint_vlc(uint val)
289 uint8 c = static_cast<uint8>(val) & 0x7F;
302 // Reads uint using a simple variable length code (VLC).
303 bool read_uint_vlc(uint &val)
317 val |= ((c & 0x7F) << shift);
327 bool write_c_str(const char *p)
329 uint len = static_cast<uint>(strlen(p));
330 if (!write_uint_vlc(len))
333 return write_chars(p, len);
336 bool read_c_str(char *pBuf, uint buf_size)
339 if (!read_uint_vlc(len))
341 if ((len + 1) > buf_size)
346 return read_chars(pBuf, len);
349 bool write_string(const dynamic_string &str)
351 if (!write_uint_vlc(str.get_len()))
354 return write_chars(str.get_ptr(), str.get_len());
357 bool read_string(dynamic_string &str)
360 if (!read_uint_vlc(len))
363 if (!str.set_len(len))
368 if (!read_chars(str.get_ptr_raw(), len))
371 if (memchr(str.get_ptr(), 0, len) != NULL)
381 template <typename T>
382 bool write_vector(const T &vec)
384 if (!write_uint_vlc(vec.size()))
387 for (uint i = 0; i < vec.size(); i++)
397 template <typename T>
398 bool read_vector(T &vec, uint num_expected = UINT_MAX)
401 if (!read_uint_vlc(size))
404 if ((size * sizeof(T::value_type)) >= 2U * 1024U * 1024U * 1024U)
407 if ((num_expected != UINT_MAX) && (size != num_expected))
411 for (uint i = 0; i < vec.size(); i++)
422 bool read_entire_file(vogl::vector<uint8> &buf)
424 return m_pStream->read_array(buf);
427 bool write_entire_file(const vogl::vector<uint8> &buf)
429 return m_pStream->write_array(buf);
432 // Got this idea from the Molly Rocket forums.
433 // fmt may contain the characters "1", "2", or "4".
434 bool writef(char *fmt, ...)
445 const uint8 x = static_cast<uint8>(va_arg(v, uint));
451 const uint16 x = static_cast<uint16>(va_arg(v, uint));
457 const uint32 x = static_cast<uint32>(va_arg(v, uint));
478 // Got this idea from the Molly Rocket forums.
479 // fmt may contain the characters "1", "2", or "4".
480 bool readf(char *fmt, ...)
491 uint8 *x = va_arg(v, uint8 *);
493 if (!read_object(*x))
498 uint16 *x = va_arg(v, uint16 *);
500 if (!read_object(*x))
505 uint32 *x = va_arg(v, uint32 *);
507 if (!read_object(*x))
528 data_stream *m_pStream;
530 bool m_little_endian;
534 inline data_stream_serializer &operator<<(data_stream_serializer &serializer, bool val)
536 serializer.write_value(val);
539 inline data_stream_serializer &operator<<(data_stream_serializer &serializer, int8 val)
541 serializer.write_value(val);
544 inline data_stream_serializer &operator<<(data_stream_serializer &serializer, uint8 val)
546 serializer.write_value(val);
549 inline data_stream_serializer &operator<<(data_stream_serializer &serializer, int16 val)
551 serializer.write_value(val);
554 inline data_stream_serializer &operator<<(data_stream_serializer &serializer, uint16 val)
556 serializer.write_value(val);
559 inline data_stream_serializer &operator<<(data_stream_serializer &serializer, int32 val)
561 serializer.write_value(val);
564 inline data_stream_serializer &operator<<(data_stream_serializer &serializer, uint32 val)
566 serializer.write_uint_vlc(val);
569 inline data_stream_serializer &operator<<(data_stream_serializer &serializer, int64_t val)
571 serializer.write_value(val);
574 inline data_stream_serializer &operator<<(data_stream_serializer &serializer, uint64_t val)
576 serializer.write_value(val);
579 inline data_stream_serializer &operator<<(data_stream_serializer &serializer, float val)
581 serializer.write_value(val);
584 inline data_stream_serializer &operator<<(data_stream_serializer &serializer, double val)
586 serializer.write_value(val);
589 inline data_stream_serializer &operator<<(data_stream_serializer &serializer, const char *p)
591 serializer.write_c_str(p);
595 inline data_stream_serializer &operator<<(data_stream_serializer &serializer, const dynamic_string &str)
597 serializer.write_string(str);
601 template <typename T>
602 inline data_stream_serializer &operator<<(data_stream_serializer &serializer, const vogl::vector<T> &vec)
604 serializer.write_vector(vec);
608 template <typename T>
609 inline data_stream_serializer &operator<<(data_stream_serializer &serializer, const T *p)
611 serializer.write_object(*p);
616 inline data_stream_serializer &operator>>(data_stream_serializer &serializer, bool &val)
618 serializer.read_object(val);
621 inline data_stream_serializer &operator>>(data_stream_serializer &serializer, int8 &val)
623 serializer.read_object(val);
626 inline data_stream_serializer &operator>>(data_stream_serializer &serializer, uint8 &val)
628 serializer.read_object(val);
631 inline data_stream_serializer &operator>>(data_stream_serializer &serializer, int16 &val)
633 serializer.read_object(val);
636 inline data_stream_serializer &operator>>(data_stream_serializer &serializer, uint16 &val)
638 serializer.read_object(val);
641 inline data_stream_serializer &operator>>(data_stream_serializer &serializer, int32 &val)
643 serializer.read_object(val);
646 inline data_stream_serializer &operator>>(data_stream_serializer &serializer, uint32 &val)
648 serializer.read_uint_vlc(val);
651 inline data_stream_serializer &operator>>(data_stream_serializer &serializer, int64_t &val)
653 serializer.read_object(val);
656 inline data_stream_serializer &operator>>(data_stream_serializer &serializer, uint64_t &val)
658 serializer.read_object(val);
661 #ifdef NEVER // __amd64__
662 inline data_stream_serializer &operator>>(data_stream_serializer &serializer, long &val)
664 serializer.read_object(val);
667 inline data_stream_serializer &operator>>(data_stream_serializer &serializer, unsigned long &val)
669 serializer.read_object(val);
673 inline data_stream_serializer &operator>>(data_stream_serializer &serializer, float &val)
675 serializer.read_object(val);
678 inline data_stream_serializer &operator>>(data_stream_serializer &serializer, double &val)
680 serializer.read_object(val);
684 inline data_stream_serializer &operator>>(data_stream_serializer &serializer, dynamic_string &str)
686 serializer.read_string(str);
690 template <typename T>
691 inline data_stream_serializer &operator>>(data_stream_serializer &serializer, vogl::vector<T> &vec)
693 serializer.read_vector(vec);
697 template <typename T>
698 inline data_stream_serializer &operator>>(data_stream_serializer &serializer, T *p)
700 serializer.read_object(*p);