v0.4.1
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) 2017, 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 #pragma once
42 
43 #include "support_global.h"
44 #include "../gmio_core/stream.h"
45 #include <cstring>
46 #include <iostream>
47 
49 template<typename CHAR, typename TRAITS>
50 gmio_stream gmio_istream_cpp(std::basic_istream<CHAR, TRAITS>* s);
51 
53 template<typename CHAR, typename TRAITS>
54 gmio_stream gmio_ostream_cpp(std::basic_ostream<CHAR, TRAITS>* s);
55 
56 
57 
58 
59 //
60 // Implementation
61 //
62 #ifndef DOXYGEN
63 
64 namespace gmio {
65 namespace internal {
66 
67 template<typename STREAM>
68 bool stream_cpp_at_end(void* cookie)
69 {
70  STREAM* s = static_cast<STREAM*>(cookie);
71  return s->eof();
72 }
73 
74 template<typename STREAM>
75 int stream_cpp_error(void* cookie)
76 {
77  STREAM* s = static_cast<STREAM*>(cookie);
78  return s->rdstate();
79 }
80 
81 template<typename STREAM>
82 size_t istream_cpp_read(
83  void* cookie, void* ptr, size_t item_size, size_t item_count)
84 {
85  STREAM* s = static_cast<STREAM*>(cookie);
86  s->read(static_cast<char*>(ptr), item_size * item_count);
87  return static_cast<size_t>(s->gcount() / item_size);
88 }
89 
90 template<typename STREAM>
91 size_t ostream_cpp_write(
92  void* cookie, const void* ptr, size_t item_size, size_t item_count)
93 {
94  STREAM* s = static_cast<STREAM*>(cookie);
95  s->write(static_cast<const char*>(ptr), item_size * item_count);
96  // TODO: return the number of bytes actually written
97  return item_size * item_count;
98 }
99 
100 template<typename STREAM>
101 gmio_streamsize_t istream_cpp_size(void* cookie)
102 {
103  STREAM* s = static_cast<STREAM*>(cookie);
104  std::streampos pos = s->tellg();
105  s->seekg(0, std::ios_base::beg);
106  std::streampos begin_pos = s->tellg();
107  s->seekg(0, std::ios_base::end);
108  std::streampos end_pos = s->tellg();
109  s->seekg(pos, std::ios_base::beg); // Restore pos
110  return end_pos - begin_pos;
111 }
112 
113 template<typename STREAM>
114 gmio_streamsize_t ostream_cpp_size(void* cookie)
115 {
116  STREAM* s = static_cast<STREAM*>(cookie);
117  std::streampos pos = s->tellp();
118  s->seekp(0, std::ios_base::beg);
119  std::streampos begin_pos = s->tellp();
120  s->seekp(0, std::ios_base::end);
121  std::streampos end_pos = s->tellp();
122  s->seekp(pos, std::ios_base::beg); // Restore pos
123  return end_pos - begin_pos;
124 }
125 
126 GMIO_INLINE void copy_cpp_streampos(gmio_streampos* pos, std::streampos spos)
127 {
128  std::memcpy(&pos->cookie[0], &spos, sizeof(std::streampos));
129 }
130 
131 GMIO_INLINE std::streampos to_cpp_streampos(const gmio_streampos* pos)
132 {
133  std::streampos spos;
134  std::memcpy(&spos, &pos->cookie[0], sizeof(std::streampos));
135  return spos;
136 }
137 
138 template<typename STREAM>
139 int istream_cpp_get_pos(void* cookie, gmio_streampos* pos)
140 {
141  copy_cpp_streampos(pos, static_cast<STREAM*>(cookie)->tellg());
142  return 0;
143 }
144 
145 template<typename STREAM>
146 int istream_cpp_set_pos(void* cookie, const gmio_streampos* pos)
147 {
148  static_cast<STREAM*>(cookie)->seekg(to_cpp_streampos(pos));
149  return 0; // TODO: return error code
150 }
151 
152 template<typename STREAM>
153 int ostream_cpp_get_pos(void* cookie, gmio_streampos* pos)
154 {
155  copy_cpp_streampos(pos, static_cast<STREAM*>(cookie)->tellp());
156  return 0;
157 }
158 
159 template<typename STREAM>
160 static int ostream_cpp_set_pos(void* cookie, const gmio_streampos* pos)
161 {
162  static_cast<STREAM*>(cookie)->seekp(to_cpp_streampos(pos));
163  return 0; // TODO: return error code
164 }
165 
166 template<typename STREAM>
167 void stream_cpp_init_common(STREAM* s, gmio_stream* stream)
168 {
169  *stream = gmio_stream_null();
170  stream->cookie = s;
171  stream->func_at_end = gmio::internal::stream_cpp_at_end<STREAM>;
172  stream->func_error = gmio::internal::stream_cpp_error<STREAM>;
173 }
174 
175 } // namespace internal
176 } // namespace gmio
177 
178 template<typename CHAR, typename TRAITS>
179 gmio_stream gmio_istream_cpp(std::basic_istream<CHAR, TRAITS>* s)
180 {
181  typedef std::basic_istream<CHAR, TRAITS> CppStream;
182  gmio_stream stream;
183  gmio::internal::stream_cpp_init_common(s, &stream);
184  stream.func_size = gmio::internal::istream_cpp_size<CppStream>;
185  stream.func_read = gmio::internal::istream_cpp_read<CppStream>;
186  stream.func_get_pos = gmio::internal::istream_cpp_get_pos<CppStream>;
187  stream.func_set_pos = gmio::internal::istream_cpp_set_pos<CppStream>;
188  return stream;
189 }
190 
191 template<typename CHAR, typename TRAITS>
192 gmio_stream gmio_ostream_cpp(std::basic_ostream<CHAR, TRAITS>* s)
193 {
194  typedef std::basic_ostream<CHAR, TRAITS> CppStream;
195  gmio_stream stream;
196  gmio::internal::stream_cpp_init_common(s, &stream);
197  stream.func_size = gmio::internal::ostream_cpp_size<CppStream>;
198  stream.func_write = gmio::internal::ostream_cpp_write<CppStream>;
199  stream.func_get_pos = gmio::internal::ostream_cpp_get_pos<CppStream>;
200  stream.func_set_pos = gmio::internal::ostream_cpp_set_pos<CppStream>;
201  return stream;
202 }
203 
204 #endif // !DOXYGEN
205 
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:178
int(* func_get_pos)(void *cookie, struct gmio_streampos *pos)
Function that retrieves the current position in the stream.
Definition: stream.h:138
bool(* func_at_end)(void *cookie)
Function that checks end-of-stream indicator.
Definition: stream.h:92
size_t(* func_write)(void *cookie, const void *ptr, size_t size, size_t count)
Function that writes block of data to stream.
Definition: stream.h:128
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)
Function that restores the current position in the stream to pos.
Definition: stream.h:146
size_t(* func_read)(void *cookie, void *ptr, size_t size, size_t count)
Function that reads block of data from stream.
Definition: stream.h:115
Specifies a position within a stream.
Definition: streampos.h:54
int64_or_long gmio_streamsize_t
Type able to represent the size(in bytes) of a stream.
Definition: stream.h:57
uint8_t cookie[GMIO_STREAMPOS_COOKIE_SIZE]
Stores the actual(concrete) stream position object.
Definition: streampos.h:57
Stream that can get input from an arbitrary data source or can write output to an arbitrary data sink...
Definition: stream.h:78
Global declarations for the support module.
void * cookie
Opaque pointer on the user stream, passed as first argument to hook functions.
Definition: stream.h:82
int(* func_error)(void *cookie)
Function that checks error indicator.
Definition: stream.h:102
gmio_streamsize_t(* func_size)(void *cookie)
Function that returns the size(in bytes) of the stream.
Definition: stream.h:131
struct gmio_stream gmio_stream_null()
Returns a null stream.
Fougue © 2017