v0.2.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 ** gmio
3 ** Copyright Fougue (24 Jun. 2016)
4 ** contact@fougue.pro
5 **
6 ** This software is a reusable library whose purpose is to provide complete
7 ** I/O support for various CAD file formats (eg. STL)
8 **
9 ** This software is governed by the CeCILL-B license under French law and
10 ** abiding by the rules of distribution of free software. You can use,
11 ** modify and/ or redistribute the software under the terms of the CeCILL-B
12 ** license as circulated by CEA, CNRS and INRIA at the following URL
13 ** "http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html".
14 ****************************************************************************/
15 
23 #ifndef __cplusplus
24 # error C++ compiler required
25 #endif
26 
27 #ifndef GMIO_SUPPORT_STREAM_CPP_H
28 #define GMIO_SUPPORT_STREAM_CPP_H
29 
30 #include "support_global.h"
31 #include "../gmio_core/stream.h"
32 
33 #include <cstring>
34 #include <iostream>
35 
37 template<typename CHAR, typename TRAITS>
38 gmio_stream gmio_istream_cpp(std::basic_istream<CHAR, TRAITS>* s);
39 
41 template<typename CHAR, typename TRAITS>
42 gmio_stream gmio_ostream_cpp(std::basic_ostream<CHAR, TRAITS>* s);
43 
44 
45 
46 
47 //
48 // Implementation
49 //
50 #ifndef DOXYGEN
51 
52 namespace gmio {
53 namespace internal {
54 
55 template<typename STREAM>
56 bool stream_cpp_at_end(void* cookie)
57 {
58  STREAM* s = static_cast<STREAM*>(cookie);
59  return s->eof();
60 }
61 
62 template<typename STREAM>
63 int stream_cpp_error(void* cookie)
64 {
65  STREAM* s = static_cast<STREAM*>(cookie);
66  return s->rdstate();
67 }
68 
69 template<typename STREAM>
70 size_t istream_cpp_read(
71  void* cookie, void* ptr, size_t item_size, size_t item_count)
72 {
73  STREAM* s = static_cast<STREAM*>(cookie);
74  s->read(static_cast<char*>(ptr), item_size * item_count);
75  return static_cast<size_t>(s->gcount() / item_size);
76 }
77 
78 template<typename STREAM>
79 size_t ostream_cpp_write(
80  void* cookie, const void* ptr, size_t item_size, size_t item_count)
81 {
82  STREAM* s = static_cast<STREAM*>(cookie);
83  s->write(static_cast<const char*>(ptr), item_size * item_count);
84  // TODO: return the number of bytes actually written
85  return item_size * item_count;
86 }
87 
88 template<typename STREAM>
89 gmio_streamsize_t istream_cpp_size(void* cookie)
90 {
91  STREAM* s = static_cast<STREAM*>(cookie);
92  std::streampos pos = s->tellg();
93  s->seekg(0, std::ios_base::beg);
94  std::streampos begin_pos = s->tellg();
95  s->seekg(0, std::ios_base::end);
96  std::streampos end_pos = s->tellg();
97  s->seekg(pos, std::ios_base::beg); // Restore pos
98  return end_pos - begin_pos;
99 }
100 
101 template<typename STREAM>
102 gmio_streamsize_t ostream_cpp_size(void* cookie)
103 {
104  STREAM* s = static_cast<STREAM*>(cookie);
105  std::streampos pos = s->tellp();
106  s->seekp(0, std::ios_base::beg);
107  std::streampos begin_pos = s->tellp();
108  s->seekp(0, std::ios_base::end);
109  std::streampos end_pos = s->tellp();
110  s->seekp(pos, std::ios_base::beg); // Restore pos
111  return end_pos - begin_pos;
112 }
113 
114 GMIO_INLINE void copy_cpp_streampos(gmio_streampos* pos, std::streampos spos)
115 {
116  std::memcpy(&pos->cookie[0], &spos, sizeof(std::streampos));
117 }
118 
119 GMIO_INLINE std::streampos to_cpp_streampos(const gmio_streampos* pos)
120 {
121  std::streampos spos;
122  std::memcpy(&spos, &pos->cookie[0], sizeof(std::streampos));
123  return spos;
124 }
125 
126 template<typename STREAM>
127 int istream_cpp_get_pos(void* cookie, gmio_streampos* pos)
128 {
129  copy_cpp_streampos(pos, static_cast<STREAM*>(cookie)->tellg());
130  return 0;
131 }
132 
133 template<typename STREAM>
134 int istream_cpp_set_pos(void* cookie, const gmio_streampos* pos)
135 {
136  static_cast<STREAM*>(cookie)->seekg(to_cpp_streampos(pos));
137  return 0; // TODO: return error code
138 }
139 
140 template<typename STREAM>
141 int ostream_cpp_get_pos(void* cookie, gmio_streampos* pos)
142 {
143  copy_cpp_streampos(pos, static_cast<STREAM*>(cookie)->tellp());
144  return 0;
145 }
146 
147 template<typename STREAM>
148 static int ostream_cpp_set_pos(void* cookie, const gmio_streampos* pos)
149 {
150  static_cast<STREAM*>(cookie)->seekp(to_cpp_streampos(pos));
151  return 0; // TODO: return error code
152 }
153 
154 template<typename STREAM>
155 void stream_cpp_init_common(STREAM* s, gmio_stream* stream)
156 {
157  *stream = gmio_stream_null();
158  stream->cookie = s;
159  stream->func_at_end = gmio::internal::stream_cpp_at_end<STREAM>;
160  stream->func_error = gmio::internal::stream_cpp_error<STREAM>;
161 }
162 
163 } // namespace internal
164 } // namespace gmio
165 
166 template<typename CHAR, typename TRAITS>
167 gmio_stream gmio_istream_cpp(std::basic_istream<CHAR, TRAITS>* s)
168 {
169  typedef std::basic_istream<CHAR, TRAITS> CppStream;
170  gmio_stream stream;
171  gmio::internal::stream_cpp_init_common(s, &stream);
172  stream.func_size = gmio::internal::istream_cpp_size<CppStream>;
173  stream.func_read = gmio::internal::istream_cpp_read<CppStream>;
174  stream.func_get_pos = gmio::internal::istream_cpp_get_pos<CppStream>;
175  stream.func_set_pos = gmio::internal::istream_cpp_set_pos<CppStream>;
176  return stream;
177 }
178 
179 template<typename CHAR, typename TRAITS>
180 gmio_stream gmio_ostream_cpp(std::basic_ostream<CHAR, TRAITS>* s)
181 {
182  typedef std::basic_ostream<CHAR, TRAITS> CppStream;
183  gmio_stream stream;
184  gmio::internal::stream_cpp_init_common(s, &stream);
185  stream.func_size = gmio::internal::ostream_cpp_size<CppStream>;
186  stream.func_write = gmio::internal::ostream_cpp_write<CppStream>;
187  stream.func_get_pos = gmio::internal::ostream_cpp_get_pos<CppStream>;
188  stream.func_set_pos = gmio::internal::ostream_cpp_set_pos<CppStream>;
189  return stream;
190 }
191 
192 #endif // !DOXYGEN
193 
194 #endif /* GMIO_SUPPORT_STREAM_CPP_H */
195 
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:156
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:125
bool(* func_at_end)(void *cookie)
Pointer on a function that checks end-of-stream indicator.
Definition: stream.h:79
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:115
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:133
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:102
Specifies a position within a stream.
Definition: streampos.h:41
int64_or_long gmio_streamsize_t
Type able to represent the size(in bytes) of a stream.
Definition: stream.h:44
uint8_t cookie[GMIO_STREAMPOS_COOKIE_SIZE]
Stores the actual(concrete) stream position object.
Definition: streampos.h:44
Stream that can get input from an arbitrary data source or can write output to an arbitrary data sink...
Definition: stream.h:65
Global declarations for the support module.
void * cookie
Opaque pointer on the user stream, passed as first argument to hook functions.
Definition: stream.h:69
int(* func_error)(void *cookie)
Pointer on a function that checks error indicator.
Definition: stream.h:89
gmio_streamsize_t(* func_size)(void *cookie)
Pointer on a function that returns the size(in bytes) of the stream.
Definition: stream.h:118
struct gmio_stream gmio_stream_null()
Returns a null stream.
Fougue © 2016