/
bytestreamutils.h
161 lines (131 loc) · 4.35 KB
/
bytestreamutils.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/*
Copyright (C) 2001-2006, William Joseph.
All Rights Reserved.
This file is part of GtkRadiant.
GtkRadiant is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
GtkRadiant is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GtkRadiant; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#if defined(__GNUC__)
#define _ISOC9X_SOURCE 1
#define _ISOC99_SOURCE 1
#define __USE_ISOC9X 1
#define __USE_ISOC99 1
#include <stdint.h>
#endif
#include <ostream>
#include <algorithm>
// if C99 is unavailable, fall back to the types most likely to be the right sizes
#if !defined(int16_t)
typedef signed short int16_t;
#endif
#if !defined(uint16_t)
typedef unsigned short uint16_t;
#endif
#if !defined(int32_t)
typedef signed int int32_t;
#endif
#if !defined(uint32_t)
typedef unsigned int uint32_t;
#endif
namespace stream
{
/**
* greebo: Writes the given number value to the given output stream in Big Endian byte order,
* regardless of the calling platform's endianness.
*/
template<typename ValueType>
void writeBigEndian(std::ostream& stream, ValueType value)
{
ValueType output = value;
#ifndef __BIG_ENDIAN__
std::reverse(reinterpret_cast<char*>(&output), reinterpret_cast<char*>(&output) + sizeof(ValueType));
#endif
stream.write(reinterpret_cast<const char*>(&output), sizeof(ValueType));
}
/**
* greebo: Writes the given number value to the given output stream in Little Endian byte order,
* regardless of the calling platform's endianness.
*/
template<typename ValueType>
void writeLittleEndian(std::ostream& stream, ValueType value)
{
ValueType output = value;
#ifdef __BIG_ENDIAN__
std::reverse(reinterpret_cast<char*>(&output), reinterpret_cast<char*>(&output) + sizeof(ValueType));
#endif
stream.write(reinterpret_cast<const char*>(&output), sizeof(ValueType));
}
}
template<typename InputStreamType, typename Type>
inline void istream_read_little_endian(InputStreamType& istream, Type& value)
{
istream.read(reinterpret_cast<typename InputStreamType::byte_type*>(&value), sizeof(Type));
#if defined(__BIG_ENDIAN__)
std::reverse(reinterpret_cast<typename InputStreamType::byte_type*>(&value), reinterpret_cast<typename InputStreamType::byte_type*>(&value) + sizeof(Type));
#endif
}
template<typename InputStreamType, typename Type>
inline void istream_read_big_endian(InputStreamType& istream, Type& value)
{
istream.read(reinterpret_cast<typename InputStreamType::byte_type*>(&value), sizeof(Type));
#if !defined(__BIG_ENDIAN__)
std::reverse(reinterpret_cast<typename InputStreamType::byte_type*>(&value), reinterpret_cast<typename InputStreamType::byte_type*>(&value) + sizeof(Type));
#endif
}
template<typename InputStreamType>
inline void istream_read_byte(InputStreamType& istream, typename InputStreamType::byte_type& b)
{
istream.read(&b, 1);
}
template<typename InputStreamType>
inline int16_t istream_read_int16_le(InputStreamType& istream)
{
int16_t value;
istream_read_little_endian(istream, value);
return value;
}
template<typename InputStreamType>
inline uint16_t istream_read_uint16_le(InputStreamType& istream)
{
uint16_t value;
istream_read_little_endian(istream, value);
return value;
}
template<typename InputStreamType>
inline int32_t istream_read_int32_le(InputStreamType& istream)
{
int32_t value;
istream_read_little_endian(istream, value);
return value;
}
template<typename InputStreamType>
inline uint32_t istream_read_uint32_le(InputStreamType& istream)
{
uint32_t value;
istream_read_little_endian(istream, value);
return value;
}
template<typename InputStreamType>
inline float istream_read_float32_le(InputStreamType& istream)
{
float value;
istream_read_little_endian(istream, value);
return value;
}
template<typename InputStreamType>
inline typename InputStreamType::byte_type istream_read_byte(InputStreamType& istream)
{
typename InputStreamType::byte_type b;
istream.read(&b, sizeof(typename InputStreamType::byte_type));
return b;
}