libdap
Updated for version 3.17.0
|
00001 // -*- mode: c++; c-basic-offset:4 -*- 00002 00003 // This file is part of libdap, A C++ implementation of the OPeNDAP Data 00004 // Access Protocol. 00005 00006 // Copyright (c) 2013 OPeNDAP, Inc. 00007 // Author: James Gallagher <jgallagher@opendap.org> 00008 // 00009 // This library is free software; you can redistribute it and/or 00010 // modify it under the terms of the GNU Lesser General Public 00011 // License as published by the Free Software Foundation; either 00012 // version 2.1 of the License, or (at your option) any later version. 00013 // 00014 // This library is distributed in the hope that it will be useful, 00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 // Lesser General Public License for more details. 00018 // 00019 // You should have received a copy of the GNU Lesser General Public 00020 // License along with this library; if not, write to the Free Software 00021 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00022 // 00023 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112. 00024 // 00025 // Portions of this code were taken verbatim from Josuttis, 00026 // "The C++ Standard Library," p.672 00027 00028 #ifndef _chunkedostream_h 00029 #define _chunkedostream_h 00030 00031 #include "chunked_stream.h" 00032 00033 #include <streambuf> 00034 #include <ostream> 00035 #include <stdexcept> // std::out_of_range 00036 00037 #include "util.h" 00038 00039 namespace libdap { 00040 00041 class chunked_ostream; 00042 00053 class chunked_outbuf: public std::streambuf { 00054 friend class chunked_ostream; 00055 protected: 00056 std::ostream &d_os; // Write stuff here 00057 unsigned int d_buf_size; // Size of the data buffer 00058 char *d_buffer; // Data buffer 00059 bool d_big_endian; 00060 00061 public: 00062 chunked_outbuf(std::ostream &os, unsigned int buf_size) : d_os(os), d_buf_size(buf_size), d_buffer(0) { 00063 if (d_buf_size & CHUNK_TYPE_MASK) 00064 throw std::out_of_range("A chunked_outbuf (or chunked_ostream) was built using a buffer larger than 0x00ffffff"); 00065 00066 d_big_endian = is_host_big_endian(); 00067 d_buffer = new char[buf_size]; 00068 // Trick: making the pointers think the buffer is one char smaller than it 00069 // really is ensures that overflow() will be called when there's space for 00070 // one more character. 00071 setp(d_buffer, d_buffer + (buf_size - 1)); 00072 } 00073 00074 virtual ~chunked_outbuf() { 00075 // call end_chunk() and not sync() 00076 end_chunk(); 00077 00078 delete[] d_buffer; 00079 } 00080 00081 protected: 00082 // data_chunk and end_chunk might not be needed because they 00083 // are called via flush() and ~chunked_outbuf(), resp. jhrg 9/13/13 00084 int_type data_chunk(); // sync() and overflow() call this 00085 int_type end_chunk(); 00086 00087 int_type err_chunk(const std::string &msg); 00088 00089 virtual std::streamsize xsputn(const char *s, std::streamsize num); 00090 // Manipulate the buffer pointers using pbump() after filling the buffer 00091 // and then call data_chunk(). Leave remainder in buffer. Or copy logic 00092 // for data_chunk() into loop in this code. 00093 00094 virtual int_type overflow(int c); 00095 virtual int_type sync(); 00096 }; 00097 00120 class chunked_ostream: public std::ostream { 00121 protected: 00122 chunked_outbuf d_cbuf; 00123 public: 00129 chunked_ostream(std::ostream &os, unsigned int buf_size) : std::ostream(&d_cbuf), d_cbuf(os, buf_size) { } 00130 00139 int_type write_end_chunk() { return d_cbuf.end_chunk(); } 00140 00149 int_type write_data_chunk() { return d_cbuf.data_chunk(); } 00150 00159 int_type write_err_chunk(const std::string &msg) { return d_cbuf.err_chunk(msg); } 00160 }; 00161 00162 } 00163 00164 #endif // _chunkedostream_h