v0.3.0
Fast, portable C library for geometry input/output
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Modules
stream_cpp.h
Go to the documentation of this file.
1 /****************************************************************************
2 ** Copyright (c) 2016, Fougue Ltd. <http://www.fougue.pro>
3 ** All rights reserved.
4 **
5 ** Redistribution and use in source and binary forms, with or without
6 ** modification, are permitted provided that the following conditions
7 ** are met:
8 **
9 ** 1. Redistributions of source code must retain the above copyright
10 ** notice, this list of conditions and the following disclaimer.
11 **
12 ** 2. Redistributions in binary form must reproduce the above
13 ** copyright notice, this list of conditions and the following
14 ** disclaimer in the documentation and/or other materials provided
15 ** with the distribution.
16 **
17 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 ****************************************************************************/
29 
37 #ifndef __cplusplus
38 # error C++ compiler required
39 #endif
40 
41 #ifndef GMIO_SUPPORT_STREAM_CPP_H
42 #define GMIO_SUPPORT_STREAM_CPP_H
43 
44 #include "support_global.h"
45 #include "../gmio_core/stream.h"
46 
47 #include <cstring>
48 #include <iostream>
49 
51 template<typename CHAR, typename TRAITS>
52 gmio_stream gmio_istream_cpp(std::basic_istream<CHAR, TRAITS>* s);
53 
55 template<typename CHAR, typename TRAITS>
56 gmio_stream gmio_ostream_cpp(std::basic_ostream<CHAR, TRAITS>* s);
57 
58 
59 
60 
61 //
62 // Implementation
63 //
64 #ifndef DOXYGEN
65 
66 namespace gmio {
67 namespace internal {
68 
69 template<typename STREAM>
70 bool stream_cpp_at_end(void* cookie)
71 {
72  STREAM* s = static_cast<STREAM*>(cookie);
73  return s->eof();
74 }
75 
76 template<typename STREAM>
77 int stream_cpp_error(void* cookie)
78 {
79  STREAM* s = static_cast<STREAM*>(cookie);
80  return s->rdstate();
81 }
82 
83 template<typename STREAM>
84 size_t istream_cpp_read(
85  void* cookie, void* ptr, size_t item_size, size_t item_count)
86 {
87  STREAM* s = static_cast<STREAM*>(cookie);
88  s->read(static_cast<char*>(ptr), item_size * item_count);
89  return static_cast<size_t>(s->gcount() / item_size);
90 }
91 
92 template<typename STREAM>
93 size_t ostream_cpp_write(
94  void* cookie, const void* ptr, size_t item_size, size_t item_count)
95 {
96  STREAM* s = static_cast<STREAM*>(cookie);
97  s->write(static_cast<const char*>(ptr), item_size * item_count);
98  // TODO: return the number of bytes actually written
99  return item_size * item_count;
100 }
101 
102 template<typename STREAM>
103 gmio_streamsize_t istream_cpp_size(void* cookie)
104 {
105  STREAM* s = static_cast<STREAM*>(cookie);
106  std::streampos pos = s->tellg();
107  s->seekg(0, std::ios_base::beg);
108  std::streampos begin_pos = s->tellg();
109  s->seekg(0, std::ios_base::end);
110  std::streampos end_pos = s->tellg();
111  s->seekg(pos, std::ios_base::beg); // Restore pos
112  return end_pos - begin_pos;
113 }
114 
115 template<typename STREAM>
116 gmio_streamsize_t ostream_cpp_size(void* cookie)
117 {
118  STREAM* s = static_cast<STREAM*>(cookie);
119  std::streampos pos = s->tellp();
120  s->seekp(0, std::ios_base::beg);
121  std::streampos begin_pos = s->tellp();
122  s->seekp(0, std::ios_base::end);
123  std::streampos end_pos = s->tellp();
124  s->seekp(pos, std::ios_base::beg); // Restore pos
125  return end_pos - begin_pos;
126 }
127 
128 GMIO_INLINE void copy_cpp_streampos(gmio_streampos* pos, std::streampos spos)
129 {
130  std::memcpy(&pos->cookie[0], &spos, sizeof(std::streampos));
131 }
132 
133 GMIO_INLINE std::streampos to_cpp_streampos(const gmio_streampos* pos)
134 {
135  std::streampos spos;
136  std::memcpy(&spos, &pos->cookie[0], sizeof(std::streampos));
137  return spos;
138 }
139 
140 template<typename STREAM>
141 int istream_cpp_get_pos(void* cookie, gmio_streampos* pos)
142 {
143  copy_cpp_streampos(pos, static_cast<STREAM*>(cookie)->tellg());
144  return 0;
145 }
146 
147 template<typename STREAM>
148 int istream_cpp_set_pos(void* cookie, const gmio_streampos* pos)
149 {
150  static_cast<STREAM*>(cookie)->seekg(to_cpp_streampos(pos));
151  return 0; // TODO: return error code
152 }
153 
154 template<typename STREAM>
155 int ostream_cpp_get_pos(void* cookie, gmio_streampos* pos)
156 {
157  copy_cpp_streampos(pos, static_cast<STREAM*>(cookie)->tellp());
158  return 0;
159 }
160 
161 template<typename STREAM>
162 static int ostream_cpp_set_pos(void* cookie, const gmio_streampos* pos)
163 {
164  static_cast<STREAM*>(cookie)->seekp(to_cpp_streampos(pos));
165  return 0; // TODO: return error code
166 }
167 
168 template<typename STREAM>
169 void stream_cpp_init_common(STREAM* s, gmio_stream* stream)
170 {
171  *stream = gmio_stream_null();
172  stream->cookie = s;
173  stream->func_at_end = gmio::internal::stream_cpp_at_end<STREAM>;
174  stream->func_error = gmio::internal::stream_cpp_error<STREAM>;
175 }
176 
177 } // namespace internal
178 } // namespace gmio
179 
180 template<typename CHAR, typename TRAITS>
181 gmio_stream gmio_istream_cpp(std::basic_istream<CHAR, TRAITS>* s)
182 {
183  typedef std::basic_istream<CHAR, TRAITS> CppStream;
184  gmio_stream stream;
185  gmio::internal::stream_cpp_init_common(s, &stream);
186  stream.func_size = gmio::internal::istream_cpp_size<CppStream>;
187  stream.func_read = gmio::internal::istream_cpp_read<CppStream>;
188  stream.func_get_pos = gmio::internal::istream_cpp_get_pos<CppStream>;
189  stream.func_set_pos = gmio::internal::istream_cpp_set_pos<CppStream>;
190  return stream;
191 }
192 
193 template<typename CHAR, typename TRAITS>
194 gmio_stream gmio_ostream_cpp(std::basic_ostream<CHAR, TRAITS>* s)
195 {
196  typedef std::basic_ostream<CHAR, TRAITS> CppStream;
197  gmio_stream stream;
198  gmio::internal::stream_cpp_init_common(s, &stream);
199  stream.func_size = gmio::internal::ostream_cpp_size<CppStream>;
200  stream.func_write = gmio::internal::ostream_cpp_write<CppStream>;
201  stream.func_get_pos = gmio::internal::ostream_cpp_get_pos<CppStream>;
202  stream.func_set_pos = gmio::internal::ostream_cpp_set_pos<CppStream>;
203  return stream;
204 }
205 
206 #endif // !DOXYGEN
207 
208 #endif /* GMIO_SUPPORT_STREAM_CPP_H */
209 
gmio_stream gmio_istream_cpp(std::basic_istream< CHAR, TRAITS > *s)
Returns a gmio_stream for C++ input stream (cookie will hold s )
#define GMIO_INLINE
Expands to the C compiler specific inline keyword (if any)
Definition: global.h:170
int(* func_get_pos)(void *cookie, struct gmio_streampos *pos)
Pointer on a function that retrieves the current position in the stream.
Definition: stream.h:139
bool(* func_at_end)(void *cookie)
Pointer on a function that checks end-of-stream indicator.
Definition: stream.h:93
size_t(* func_write)(void *cookie, const void *ptr, size_t size, size_t count)
Pointer on a function that writes block of data to stream.
Definition: stream.h:129
gmio_stream gmio_ostream_cpp(std::basic_ostream< CHAR, TRAITS > *s)
Returns a gmio_stream for C++ output stream (cookie will hold s )
int(* func_set_pos)(void *cookie, const struct gmio_streampos *pos)
Pointer on a function that restores the current position in the stream to pos.
Definition: stream.h:147
size_t(* func_read)(void *cookie, void *ptr, size_t size, size_t count)
Pointer on a function that reads block of data from stream.
Definition: stream.h:116
Specifies a position within a stream.
Definition: streampos.h:55
int64_or_long gmio_streamsize_t
Type able to represent the size(in bytes) of a stream.
Definition: stream.h:58
uint8_t cookie[GMIO_STREAMPOS_COOKIE_SIZE]
Stores the actual(concrete) stream position object.
Definition: streampos.h:58
Stream that can get input from an arbitrary data source or can write output to an arbitrary data sink...
Definition: stream.h:79
Global declarations for the support module.
void * cookie
Opaque pointer on the user stream, passed as first argument to hook functions.
Definition: stream.h:83
int(* func_error)(void *cookie)
Pointer on a function that checks error indicator.
Definition: stream.h:103
gmio_streamsize_t(* func_size)(void *cookie)
Pointer on a function that returns the size(in bytes) of the stream.
Definition: stream.h:132
struct gmio_stream gmio_stream_null()
Returns a null stream.
Fougue © 2016