/* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ /* yaSSL buffer header defines input and output buffers to simulate streaming * with SSL types and sockets */ #ifndef yaSSL_BUFFER_HPP #define yaSSL_BUFFER_HPP #include // assert #include "yassl_types.hpp" // ysDelete #include "memory.hpp" // mySTL::auto_ptr #include STL_ALGORITHM_FILE namespace STL = STL_NAMESPACE; #ifdef _MSC_VER // disable truncated debug symbols #pragma warning(disable:4786) #endif namespace yaSSL { typedef unsigned char byte; typedef unsigned int uint; const uint AUTO = 0xFEEDBEEF; struct NoCheck { int check(uint, uint); }; struct Check { int check(uint, uint); }; /* input_buffer operates like a smart c style array with a checking option, * meant to be read from through [] with AUTO index or read(). * Should only write to at/near construction with assign() or raw (e.g., recv) * followed by add_size with the number of elements added by raw write. * * Not using vector because need checked []access, offset, and the ability to * write to the buffer bulk wise and have the correct size */ class input_buffer : public Check { uint size_; // number of elements in buffer uint current_; // current offset position in buffer byte* buffer_; // storage for buffer byte* end_; // end of storage marker int error_; // error number byte zero_; // for returning const reference to zero byte public: input_buffer(); explicit input_buffer(uint s); // with assign input_buffer(uint s, const byte* t, uint len); ~input_buffer(); // users can pass defualt zero length buffer and then allocate void allocate(uint s); // for passing to raw writing functions at beginning, then use add_size byte* get_buffer() const; // after a raw write user can set new size // if you know the size before the write use assign() void add_size(uint i); uint get_capacity() const; uint get_current() const; uint get_size() const; uint get_remaining() const; int get_error() const; void set_error(); void set_current(uint i); // read only access through [], advance current // user passes in AUTO index for ease of use const byte& operator[](uint i); // end of input test bool eof(); // peek ahead byte peek(); // write function, should use at/near construction void assign(const byte* t, uint s); // use read to query input, adjusts current void read(byte* dst, uint length); private: input_buffer(const input_buffer&); // hide copy input_buffer& operator=(const input_buffer&); // and assign }; /* output_buffer operates like a smart c style array with a checking option. * Meant to be written to through [] with AUTO index or write(). * Size (current) counter increases when written to. Can be constructed with * zero length buffer but be sure to allocate before first use. * Don't use add write for a couple bytes, use [] instead, way less overhead. * * Not using vector because need checked []access and the ability to * write to the buffer bulk wise and retain correct size */ class output_buffer : public NoCheck { uint current_; // current offset and elements in buffer byte* buffer_; // storage for buffer byte* end_; // end of storage marker public: // default output_buffer(); // with allocate explicit output_buffer(uint s); // with assign output_buffer(uint s, const byte* t, uint len); ~output_buffer(); uint get_size() const; uint get_capacity() const; void set_current(uint c); // users can pass defualt zero length buffer and then allocate void allocate(uint s); // for passing to reading functions when finished const byte* get_buffer() const; // allow write access through [], update current // user passes in AUTO as index for ease of use byte& operator[](uint i); // end of output test bool eof(); void write(const byte* t, uint s); private: output_buffer(const output_buffer&); // hide copy output_buffer& operator=(const output_buffer&); // and assign }; // turn delete an incomplete type into comipler error instead of warning template inline void checked_delete(T* p) { typedef char complete_type[sizeof(T) ? 1 : -1]; (void)sizeof(complete_type); ysDelete(p); } // checked delete functor increases effeciency, no indirection on function call // sets pointer to zero so safe for std conatiners struct del_ptr_zero { template void operator()(T*& p) const { T* tmp = 0; STL::swap(tmp, p); checked_delete(tmp); } }; } // naemspace #endif // yaSSL_BUUFER_HPP