00001
00002
00003 #ifndef VGS_ByteInBuffer_H
00004 #define VGS_ByteInBuffer_H
00005
00006 #include <stdlib.h>
00007 #include <assert.h>
00008
00009 #include <utility>
00010 #include <string>
00011 #include <stdexcept>
00012
00013 #include "ByteBuffer.h"
00014
00015 namespace VGServer {
00016
00021 class ByteInBuffer
00022 {
00023 private:
00025 const ByteBuffer &buff;
00026
00028 size_t _curr;
00029
00031 inline void check_sizeof() {
00032 assert( sizeof(char) == 1 );
00033 assert( sizeof(short) == 2 );
00034 assert( sizeof(int) == 4 );
00035 }
00036
00037 public:
00039 inline ByteInBuffer(const ByteBuffer &_buff)
00040 : buff(_buff), _curr(0)
00041 {
00042 check_sizeof();
00043 }
00044
00046 inline ByteInBuffer(const ByteInBuffer &o)
00047 : buff(o.buff), _curr(o._curr)
00048 {
00049 }
00050
00051
00052
00054 inline void rewind()
00055 { _curr = 0; }
00056
00058 inline size_t cursor() const
00059 { return _curr; }
00060
00062 inline size_t remaining() const
00063 { return (_curr < buff.size()) ? (buff.size() - _curr) : 0; }
00064
00066 inline bool cursor_available(unsigned int n) const
00067 { return (_curr + n <= buff.size()); }
00068
00070 inline void check_available(unsigned int n) const
00071 { if (!cursor_available(n)) throw(std::underflow_error("ByteInBuffer underrun")); }
00072
00075 template <typename Tp>
00076 inline Tp fetch()
00077 {
00078 check_available(sizeof(Tp));
00079
00080 Tp ret = *reinterpret_cast<const Tp*>(buff.data() + _curr);
00081 _curr += sizeof(Tp);
00082
00083 return ret;
00084 }
00085
00086
00087
00088
00089 inline unsigned char fetch_unsigned_char()
00090 { return fetch<unsigned char>(); }
00091
00092 inline unsigned short fetch_unsigned_short()
00093 { return fetch<unsigned short>(); }
00094
00095 inline unsigned int fetch_unsigned_int()
00096 { return fetch<unsigned int>(); }
00097
00099 inline std::string fetchString()
00100 {
00101 unsigned char slen = fetch<unsigned char>();
00102
00103 check_available(slen);
00104 std::string ret(buff.data() + _curr, slen);
00105
00106 _curr += slen;
00107 return ret;
00108 }
00109
00111 inline std::string fetchLongString()
00112 {
00113 unsigned int slen = fetch<unsigned int>();
00114
00115 check_available(slen);
00116 std::string ret(buff.data() + _curr, slen);
00117
00118 _curr += slen;
00119 return ret;
00120 }
00121
00123 inline void fetchBytes(char *dest, unsigned int len)
00124 {
00125 check_available(len);
00126 memcpy(dest, buff.data() + _curr, len);
00127
00128 _curr += len;
00129 }
00130
00132 inline void fetchBytes(ByteBuffer &dest, unsigned int len)
00133 {
00134 check_available(len);
00135 dest.assign_copy(buff.data() + _curr, len);
00136
00137 _curr += len;
00138 }
00139
00142 void fetchAnyType(class AnyType &v);
00143 };
00144
00145 }
00146
00147 #endif // VGS_ByteInBuffer_H