1 |
/* emacs settings information: -*- mode: c++; tab-width: 4; c-file-style: "glob2"; -*- */ |
2 |
/* |
3 |
Copyright (C) 2001-2004 Stephane Magnenat & Luc-Olivier de Charrière |
4 |
for any question or comment contact us at nct@ysagoon.com or nuage@ysagoon.com |
5 |
|
6 |
This program is free software; you can redistribute it and/or modify |
7 |
it under the terms of the GNU General Public License as published by |
8 |
the Free Software Foundation; either version 2 of the License, or |
9 |
(at your option) any later version. |
10 |
|
11 |
This program 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 |
14 |
GNU General Public License for more details. |
15 |
|
16 |
You should have received a copy of the GNU General Public License |
17 |
along with this program; if not, write to the Free Software |
18 |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 |
*/ |
20 |
|
21 |
#ifndef __BINARY_OSTREAM_H |
22 |
#define __BINARY_OSTREAM_H |
23 |
|
24 |
#include <netinet/in.h> |
25 |
#include <ostream> |
26 |
|
27 |
#ifndef __BINARY_ISTREAM_H |
28 |
template<class Ch> class Binary : public std::char_traits<Ch> {}; |
29 |
template<class Ch> class Text : public std::char_traits<Ch> {}; |
30 |
|
31 |
namespace std |
32 |
{ |
33 |
template<class Ch> |
34 |
class basic_streambuf<Ch, Binary<Ch> > : public basic_streambuf<Ch, char_traits<Ch> > |
35 |
{ |
36 |
typedef basic_streambuf<Ch, char_traits<Ch> > parent; |
37 |
public: |
38 |
basic_streambuf() : parent() {}; |
39 |
}; |
40 |
|
41 |
template<class Ch> |
42 |
class basic_streambuf<Ch, Text<Ch> > : public basic_streambuf<Ch, char_traits<Ch> > |
43 |
{ |
44 |
typedef basic_streambuf<Ch, char_traits<Ch> > parent; |
45 |
public: |
46 |
basic_streambuf() : parent() {}; |
47 |
}; |
48 |
}; |
49 |
#endif |
50 |
|
51 |
typedef std::basic_ostream<char, Binary<char> > obstream; |
52 |
|
53 |
template <class T> |
54 |
struct EnterSection |
55 |
{ |
56 |
const T data; |
57 |
EnterSection(const T d) : data(d) {}; |
58 |
}; |
59 |
template <class T> |
60 |
struct Title |
61 |
{ |
62 |
const T data; |
63 |
Title(const T d) : data(d) {}; |
64 |
}; |
65 |
|
66 |
template <class T> EnterSection<T> enterSection(const T d) { return EnterSection<T>(d); }; |
67 |
template <class T> Title<T> title(const T d) { return Title<T>(d); }; |
68 |
template<class Ch, class Tr> std::basic_ostream<Ch, Tr >& leaveSection(std::basic_ostream<Ch, Tr >& o) { return o.leaveSection(); }; |
69 |
|
70 |
namespace std |
71 |
{ |
72 |
template<class Ch> |
73 |
class basic_ostream<Ch, Binary<Ch> > : public basic_ostream<Ch, char_traits<Ch> > |
74 |
{ |
75 |
typedef char_traits<Ch> Tr; |
76 |
typedef basic_ostream<Ch, Tr> parent; |
77 |
typedef basic_streambuf<Ch, Tr> streambuf_type; |
78 |
typedef basic_ios<Ch, Tr> ios_type; |
79 |
|
80 |
protected: |
81 |
explicit basic_ostream() : parent() {} |
82 |
public: |
83 |
explicit basic_ostream(streambuf_type* sb) : parent(sb) {} |
84 |
|
85 |
//! Note: writing of floating point numbers has been removed from this library because architecture-neutral floats are non-trivial to implement |
86 |
basic_ostream& operator<<(Ch n) { parent::put(n); return *this; }; |
87 |
|
88 |
basic_ostream& operator<<( int8_t n) { parent::put(static_cast<Ch>(n)); return *this; }; |
89 |
basic_ostream& operator<<( int16_t n) { n=htons(n); parent::write(reinterpret_cast<Ch*>(&n), sizeof(int16_t)); return *this; }; |
90 |
basic_ostream& operator<<( int32_t n) { n=htonl(n); parent::write(reinterpret_cast<Ch*>(&n), sizeof(int32_t)); return *this; }; |
91 |
|
92 |
basic_ostream& operator<<(uint8_t n) { parent::put(n); return *this; }; |
93 |
basic_ostream& operator<<(uint16_t n) { n=htons(n); parent::write(reinterpret_cast<Ch*>(&n), sizeof(uint16_t)); return *this; }; |
94 |
basic_ostream& operator<<(uint32_t n) { n=htonl(n); parent::write(reinterpret_cast<Ch*>(&n), sizeof(uint32_t)); return *this; }; |
95 |
basic_ostream& operator<<(basic_string<Ch, Tr>& s) { operator<<(static_cast<uint32_t>(s.size())); *static_cast<parent*>(this) << s; return *this; }; |
96 |
|
97 |
basic_ostream& operator<<(basic_ostream& (*pf)(basic_ostream& )) { return pf(*this); }; |
98 |
basic_ostream& operator<<(ios_type& (*pf)(ios_type& )) { parent::operator<<(pf); return *this; }; |
99 |
basic_ostream& operator<<(ios_base& (*pf)(ios_base& )) { parent::operator<<(pf); return *this; }; |
100 |
|
101 |
basic_ostream& operator<<(streambuf_type* sb) { parent::operator<<(sb); return *this; }; |
102 |
|
103 |
template<class T> basic_ostream& operator<<(const Title<T> e) { return *this; }; |
104 |
template<class T> basic_ostream& operator<<(const EnterSection<T> e) { return *this; }; |
105 |
basic_ostream& leaveSection() { return *this; }; |
106 |
|
107 |
basic_ostream& flush() { parent::flush(); return *this; }; |
108 |
basic_ostream& seekp(typename parent::pos_type p) { parent::seekp(p); return *this; }; |
109 |
basic_ostream& seekp(typename parent::off_type p, ios_base::seekdir d) { parent::seekp(p, d); return *this; }; |
110 |
|
111 |
}; |
112 |
|
113 |
//! Write data in a human readable form |
114 |
template<class Ch> |
115 |
class basic_ostream<Ch, Text<Ch> > : public basic_ostream<Ch, char_traits<Ch> > |
116 |
{ |
117 |
typedef char_traits<Ch> Tr; |
118 |
typedef basic_ostream<Ch, Tr> parent; |
119 |
typedef basic_streambuf<Ch, Tr> streambuf_type; |
120 |
typedef basic_ios<Ch, Tr> ios_type; |
121 |
|
122 |
unsigned int level; |
123 |
|
124 |
static basic_ostream& newline(basic_ostream& o) { o << "\n"; for (unsigned int l=0; l<o.level; ++l) o.put('\t'); return o; }; |
125 |
|
126 |
protected: |
127 |
explicit basic_ostream() : parent(), level(0) {}; |
128 |
public: |
129 |
explicit basic_ostream(streambuf_type* sb) : parent(sb), level(0) {}; |
130 |
|
131 |
basic_ostream& operator<<(Ch n) { *static_cast<parent*>(this) << n; return *this; }; |
132 |
|
133 |
basic_ostream& operator<<( int8_t n) { *static_cast<parent*>(this) << n; return *this; }; |
134 |
basic_ostream& operator<<( int16_t n) { *static_cast<parent*>(this) << n; return *this; }; |
135 |
basic_ostream& operator<<( int32_t n) { *static_cast<parent*>(this) << n; return *this; }; |
136 |
|
137 |
basic_ostream& operator<<(uint8_t n) { *static_cast<parent*>(this) << n; return *this; }; |
138 |
basic_ostream& operator<<(uint16_t n) { *static_cast<parent*>(this) << n; return *this; }; |
139 |
basic_ostream& operator<<(uint32_t n) { *static_cast<parent*>(this) << n; return *this; }; |
140 |
basic_ostream& operator<<(basic_string<Ch, Tr>& s) |
141 |
{ |
142 |
typename basic_string<Ch, Tr>::size_type start=0; |
143 |
typename basic_string<Ch, Tr>::size_type end=s.find_first_of("\"\\"); |
144 |
*static_cast<parent*>(this) << '"'; |
145 |
while (end != basic_string<Ch, Tr>::npos) |
146 |
{ |
147 |
*static_cast<parent*>(this) << s.substr(start, end-start) << '\\'; |
148 |
start=end; |
149 |
end=s.find_first_of("\"\\", end+1); |
150 |
}; |
151 |
*static_cast<parent*>(this) << s.substr(start) << '"'; |
152 |
return *this; |
153 |
}; |
154 |
|
155 |
basic_ostream& operator<<(basic_ostream& (*pf)(basic_ostream& )) { return pf(*this); }; |
156 |
basic_ostream& operator<<(ios_type& (*pf)(ios_type& )) { parent::operator<<(pf); return *this; }; |
157 |
basic_ostream& operator<<(ios_base& (*pf)(ios_base& )) { parent::operator<<(pf); return *this; }; |
158 |
|
159 |
basic_ostream& operator<<(streambuf_type* sb) { parent::operator<<(sb); return *this; }; |
160 |
|
161 |
template<class T> basic_ostream& operator<<(const Title<T> e) { return *this << newline << e.data << " = "; }; |
162 |
template<class T> basic_ostream& operator<<(const EnterSection<T> e) { *this << newline << e.data << newline << '{'; ++level; return *this; }; |
163 |
basic_ostream& leaveSection() { --level; return *this << newline << '}'; }; |
164 |
|
165 |
basic_ostream& flush() { parent::flush(); return *this; }; |
166 |
basic_ostream& seekp(typename parent::pos_type p) { parent::seekp(p); return *this; }; |
167 |
basic_ostream& seekp(typename parent::off_type p, ios_base::seekdir d) { parent::seekp(p, d); return *this; }; |
168 |
|
169 |
}; |
170 |
|
171 |
}; |
172 |
|
173 |
#endif // __BINARY_OSTREAM_H |