Virtual Testbed
Ship dynamics simulator for extreme conditions
stream.hh
1 #ifndef VTESTBED_IGES_STREAM_HH
2 #define VTESTBED_IGES_STREAM_HH
3 
4 #include <ostream>
5 #include <streambuf>
6 
7 #include <vtestbed/iges/section.hh>
8 
9 namespace vtb {
10 
11  namespace iges {
12 
26 
27  public:
28  using std::streambuf::int_type;
29  using std::streambuf::char_type;
30  using std::streambuf::traits_type;
31  typedef char_type* pointer;
32  typedef const char_type* const_pointer;
33 
34  private:
35  std::streambuf* _sink = nullptr;
36  char_type _line[82];
37  Section _section = Section::Start;
38  size_t _lineno = 0;
39  size_t _number = 0;
40  std::streamsize _maxsize = 72;
41  char _parameter_delimiter = ',';
42  char _record_delimiter = ';';
43 
44  public:
45 
46  iges_ostreambuf() = default;
47  virtual ~iges_ostreambuf() = default;
48 
49  inline
50  iges_ostreambuf(std::streambuf* sink, char d1, char d2):
51  _sink{sink}, _parameter_delimiter{d1}, _record_delimiter{d2} {
52  reset();
53  }
54 
55  inline char
56  parameter_delimiter() const noexcept {
57  return this->_parameter_delimiter;
58  }
59 
60  inline char
61  record_delimiter() const noexcept {
62  return this->_record_delimiter;
63  }
64 
66  void
67  section(Section s);
68 
69  inline void
70  finish() {
71  if (this->pptr() != this->pbase()) {
72  this->newline();
73  }
74  }
75 
76  inline void
77  sink(std::streambuf* sink) {
78  this->_sink = sink;
79  }
80 
81  inline size_t
82  next_entity_number() {
83  return ++this->_number;
84  }
85 
86  inline size_t
87  line_number() const {
88  return _lineno+1;
89  }
90 
91  int_type
92  overflow(int_type ch) override;
93 
95  xsputn(const char_type* s, std::streamsize n) override;
96 
97  int_type
98  sync() override;
99 
100  private:
101 
102  inline pointer
103  data() noexcept {
104  return this->_line;
105  }
106 
107  inline const_pointer
108  data() const noexcept {
109  return this->_line;
110  }
111 
112  inline static std::streamsize
113  size() noexcept {
114  return sizeof(_line);
115  }
116 
117  inline std::streamsize
118  max_size() noexcept {
119  return this->_maxsize;
120  }
121 
122  inline char_type
123  section_character() const noexcept {
124  return static_cast<char_type>(_section);
125  }
126 
127  inline void
128  reset() {
129  this->setp(this->data(), this->data() + this->max_size());
130  }
131 
132  void
133  newline();
134 
135  };
136 
143  class iges_ostream: public std::ostream {
144 
145  private:
146  iges_ostreambuf _buffer;
147 
148  public:
149  using std::ostream::ostream;
150 
151  inline
152  iges_ostream(std::ios& sink, char d1, char d2):
153  iges_ostream(sink.rdbuf(), d1, d2) {}
154 
155  inline
156  iges_ostream(std::streambuf* sink, char d1, char d2):
157  _buffer(sink, d1, d2) {
158  init(&_buffer);
159  }
160 
161  inline char
162  parameter_delimiter() const noexcept {
163  return this->_buffer.parameter_delimiter();
164  }
165 
166  inline char
167  record_delimiter() const noexcept {
168  return this->_buffer.record_delimiter();
169  }
170 
171  inline size_t
172  next_entity_number() {
173  return this->_buffer.next_entity_number();
174  }
175 
176  inline size_t
177  line_number() const {
178  return this->_buffer.line_number();
179  }
180 
181  inline void
182  section(Section s) noexcept {
183  this->_buffer.section(s);
184  }
185 
186  inline void
187  finish() {
188  this->_buffer.finish();
189  }
190 
191  inline void
192  sink(std::streambuf* sink) {
193  this->_buffer.sink(sink);
194  }
195 
196  };
197 
198 
199  }
200 
201 }
202 
203 #endif // vim:filetype=cpp
T init(T... args)
Stream buffer that automatically wraps text for IGES files.
Definition: stream.hh:25
Main namespace.
Definition: convert.hh:9
Section
Section codes.
Definition: section.hh:9
T pptr(T... args)
Output stream that automatically wraps text for IGES files.
Definition: stream.hh:143
T setp(T... args)
void section(Section s)
Set section code to s.
Definition: stream.cc:6