libdap  Updated for version 3.20.6
libdap4 is an implementation of OPeNDAP's DAP protocol.
chunked_istream.h
1 // -*- mode: c++; c-basic-offset:4 -*-
2 
3 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
4 // Access Protocol.
5 
6 // Copyright (c) 2013 OPeNDAP, Inc.
7 // Author: James Gallagher <jgallagher@opendap.org>
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU Lesser General Public
11 // License as published by the Free Software Foundation; either
12 // version 2.1 of the License, or (at your option) any later version.
13 //
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // Lesser General Public License for more details.
18 //
19 // You should have received a copy of the GNU Lesser General Public
20 // License along with this library; if not, write to the Free Software
21 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 //
23 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
24 //
25 // Portions of this code were taken verbatim from Josuttis,
26 // "The C++ Standard Library," p.672
27 
28 #ifndef _chunked_istream_h
29 #define _chunked_istream_h
30 
31 #include "chunked_stream.h"
32 
33 #include <stdint.h>
34 
35 #include <streambuf>
36 #include <istream>
37 #include <stdexcept>
38 #include <string>
39 
40 namespace libdap {
41 
42 class chunked_inbuf: public std::streambuf {
43 private:
44  std::istream &d_is;
45 
46  uint32_t d_buf_size; // Size of the data buffer
47  char *d_buffer; // data buffer
48 
49  // In the original implementation of this class, the byte order of the data stream
50  // was passed in via constructors. When BYTE_ORDER_PREFIX is defined that is the
51  // case. However, when it is not defined, the byte order is read from the chunk
52  // header's high order byte (in bit position 2 - see chunked_stream.h). jhrg 11/24/13
53 
54  bool d_twiddle_bytes; // receiver-makes-right encoding (byte order)...
55  bool d_set_twiddle;
56 
57  // If an error chunk is read, save the message here
58  std::string d_error_message;
59  bool d_error;
60 
67  void m_buffer_alloc() {
68  delete[] d_buffer;
69  d_buffer = new char[d_buf_size];
70  setg(d_buffer, // beginning of put back area
71  d_buffer, // read position
72  d_buffer); // end position
73  }
74 
75 public:
98  chunked_inbuf(std::istream &is, int size)
99  : d_is(is), d_buf_size(size), d_buffer(0), d_twiddle_bytes(false), d_set_twiddle(false), d_error(false) {
100  if (d_buf_size & CHUNK_TYPE_MASK)
101  throw std::out_of_range("A chunked_outbuf (or chunked_ostream) was built using a buffer larger than 0x00ffffff");
102 
103  m_buffer_alloc();
104  }
105 
106  virtual ~chunked_inbuf() {
107  delete[] d_buffer;
108  }
109 
110  int_type read_next_chunk();
111 
112  int bytes_in_buffer() const { return (egptr() - gptr()); }
113 
114  // d_twiddle_bytes is false initially and is set to the correct value
115  // once the first chunk is read.
116  bool twiddle_bytes() const { return d_twiddle_bytes; }
117 
118  bool error() const { return d_error; }
119  std::string error_message() const { return d_error_message; }
120 
121 protected:
122  virtual int_type underflow();
123 
124  virtual std::streamsize xsgetn(char* s, std::streamsize num);
125 };
126 
127 class chunked_istream: public std::istream {
128 protected:
129  chunked_inbuf d_cbuf;
130 public:
131  chunked_istream(std::istream &is, int size) : std::istream(&d_cbuf), d_cbuf(is, size) { }
132 
133  int read_next_chunk() { return d_cbuf.read_next_chunk(); }
134 
139  int bytes_in_buffer() const { return d_cbuf.bytes_in_buffer(); }
140 
151  bool twiddle_bytes() const { return d_cbuf.twiddle_bytes(); }
152  bool error() const { return d_cbuf.error(); }
153  std::string error_message() const { return d_cbuf.error_message(); }
154 };
155 
156 }
157 
158 #endif // _chunked_istream_h
int_type read_next_chunk()
Read a chunk Normally the chunked nature of a chunked_istream/chunked_inbuf is hidden from the caller...
top level DAP object to house generic methods
Definition: AISConnect.cc:30
virtual int_type underflow()
Insert new characters into the buffer This specialization of underflow is called when the gptr() is a...
virtual std::streamsize xsgetn(char *s, std::streamsize num)
Read a block of data This specialization of xsgetn() reads num bytes and puts them in s first reading...
chunked_inbuf(std::istream &is, int size)
Build a chunked input buffer.