diff options
author | Jörg Frings-Fürst <jff@merkur> | 2014-05-18 16:08:14 +0200 |
---|---|---|
committer | Jörg Frings-Fürst <jff@merkur> | 2014-05-18 16:08:14 +0200 |
commit | a15cf65c44d5c224169c32ef5495b68c758134b7 (patch) | |
tree | 3419f58fc8e1b315ba8171910ee044c5d467c162 /libcult/cult/dr/xdr/output-stream.cxx |
Imported Upstream version 3.3.0.2upstream/3.3.0.2
Diffstat (limited to 'libcult/cult/dr/xdr/output-stream.cxx')
-rw-r--r-- | libcult/cult/dr/xdr/output-stream.cxx | 222 |
1 files changed, 222 insertions, 0 deletions
diff --git a/libcult/cult/dr/xdr/output-stream.cxx b/libcult/cult/dr/xdr/output-stream.cxx new file mode 100644 index 0000000..acda64c --- /dev/null +++ b/libcult/cult/dr/xdr/output-stream.cxx @@ -0,0 +1,222 @@ +// file : cult/dr/xdr/output-stream.cxx +// author : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include <cult/dr/xdr/output-stream.hxx> + +namespace Cult +{ + namespace DR + { + namespace XDR + { + OutputStream:: + OutputStream (Size hint) + : buffer_ (new Buffer (hint ? hint : 256)) + { + xdrmem_create (&xdr_, buffer_->data (), ~(u_int (0)), XDR_ENCODE); + } + + + OutputStream:: + ~OutputStream () + { + xdr_destroy (&xdr_); + } + + Shptr<Buffer> OutputStream:: + buffer () + { + return buffer_; + } + + Void OutputStream:: + ensure_space (Size size) + { + size += size % 4 ? 4 - size % 4 : 0; + + Size needed (size + xdr_getpos (&xdr_)); + + if (needed > buffer_->capacity ()) + { + Size new_size (buffer_->capacity () * 2); + + if (needed > new_size) + new_size = needed % 8 ? 8 - new_size % 8 : 0; + + if (buffer_->capacity (new_size)) + { + xdr_destroy (&xdr_); + + xdrmem_create (&xdr_, + buffer_->data () + buffer_->size (), + ~(u_int (0)), + XDR_ENCODE); + } + } + } + + Void OutputStream:: + update_position (Size position) + { + // Align to 4-boundary. + // + position += position % 4 ? 4 - position % 4 : 0; + + buffer_->size (buffer_->size () + position); + } + + OutputStream& OutputStream:: + operator<< (Boolean v) + { + ensure_space (4); + + bool_t b (v); + + if (!xdr_bool (&xdr_, &b)) + throw Insertion (); + + update_position (4); + return *this; + } + + OutputStream& OutputStream:: + operator<< (Int8 v) + { + ensure_space (4); + + if (!xdr_int8_t (&xdr_, &v)) + throw Insertion (); + + update_position (4); + + return *this; + } + + OutputStream& OutputStream:: + operator<< (UnsignedInt8 v) + { + ensure_space (4); + + if (!xdr_uint8_t (&xdr_, &v)) + throw Insertion (); + + update_position (4); + + return *this; + } + + OutputStream& OutputStream:: + operator<< (Int16 v) + { + ensure_space (4); + + if (!xdr_int16_t (&xdr_, &v)) + throw Insertion (); + + update_position (4); + + return *this; + } + + OutputStream& OutputStream:: + operator<< (UnsignedInt16 v) + { + ensure_space (4); + + if (!xdr_uint16_t (&xdr_, &v)) + throw Insertion (); + + update_position (4); + + return *this; + } + + OutputStream& OutputStream:: + operator<< (Int32 v) + { + ensure_space (4); + + if (!xdr_int32_t (&xdr_, &v)) + throw Insertion (); + + update_position (4); + + return *this; + } + + OutputStream& OutputStream:: + operator<< (UnsignedInt32 v) + { + ensure_space (4); + + if (!xdr_uint32_t (&xdr_, &v)) + throw Insertion (); + + update_position (4); + + return *this; + } + + OutputStream& OutputStream:: + operator<< (Int64 v) + { + ensure_space (8); + + if (!xdr_int64_t (&xdr_, (int64_t*)&v)) + throw Insertion (); + + update_position (8); + + return *this; + } + + OutputStream& OutputStream:: + operator<< (UnsignedInt64 v) + { + ensure_space (8); + + if (!xdr_uint64_t (&xdr_, (uint64_t*)&v)) + throw Insertion (); + + update_position (8); + + return *this; + } + + OutputStream& OutputStream:: + operator<< (String const& v) + { + UnsignedInt32 size (v.size ()); + + ensure_space (4 + size); + + Char* p (const_cast<Char*>(v.c_str ())); + + if (!xdr_string (&xdr_, &p, size)) + throw Insertion (); + + update_position (4 + size); + + return *this; + } + + Void OutputStream:: + write (Buffer const& buffer) + { + Size size (buffer.size () - buffer.position ()); + + ensure_space (size); + + if (!xdr_opaque ( + &xdr_, + const_cast<Char*> (buffer.data ()) + buffer.position (), + size)) + throw Insertion (); + + update_position (size); + } + } + } +} |