source: branches/blt4/src/core2/RpSerialBuffer.cc @ 4988

Last change on this file since 4988 was 3959, checked in by gah, 11 years ago

sync with trunk

File size: 4.4 KB
Line 
1/*
2 * ======================================================================
3 *  Rappture::SerialBuffer
4 *
5 *  AUTHOR:  Michael McLennan, Purdue University
6 *           Carol X Song, Purdue University
7 *
8 *  Copyright (c) 2004-2012  HUBzero Foundation, LLC
9 * ----------------------------------------------------------------------
10 *  See the file "license.terms" for information on usage and
11 *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
12 * ======================================================================
13 */
14#include "RpSerialBuffer.h"
15
16#ifdef BIGENDIAN
17#  define ENDIAN_FOR_LOOP(var,size)  \
18     for (var=size-1; var >= 0; var--)
19#else
20#  define ENDIAN_FOR_LOOP(var,size)  \
21     for (var=0; var < size; var++)
22#endif
23
24using namespace Rappture;
25
26/**
27 * Construct an empty SerialBuffer.
28 */
29SerialBuffer::SerialBuffer()
30  : _buffer(),
31    _pos(0)
32{
33}
34
35/**
36 * Construct a SerialBuffer loaded with bytes produced by another
37 * SerialBuffer.  This is used to decode information from the buffer.
38 *
39 * @param bytes pointer to bytes being decoded.
40 * @param nbytes number of bytes being decoded.
41 */
42SerialBuffer::SerialBuffer(const char* bytes, int nbytes)
43  : _buffer(),
44    _pos(0)
45{
46    _buffer.reserve(nbytes);
47    while (nbytes-- > 0) {
48        _buffer.push_back( *bytes++ );
49    }
50}
51
52/**
53 * Copy constructor
54 */
55SerialBuffer::SerialBuffer(const SerialBuffer& sb)
56  : _buffer(sb._buffer),
57    _pos(0)  // auto-rewind
58{
59}
60
61/**
62 * Assignment operator
63 */
64SerialBuffer&
65SerialBuffer::operator=(const SerialBuffer& sb)
66{
67    _buffer = sb._buffer;
68    _pos = 0;  // auto-rewind
69    return *this;
70}
71
72SerialBuffer::~SerialBuffer()
73{
74}
75
76/**
77 * Get the bytes currently stored in the buffer.  These bytes can
78 * be stored, and used later to construct another SerialBuffer to
79 * decode the information.
80 *
81 * @return Pointer to the bytes in the buffer.
82 */
83const char*
84SerialBuffer::bytes() const
85{
86    return &_buffer[0];
87}
88
89/**
90 * Get the number of bytes currently stored in the buffer.
91 * @return Number of the bytes in the buffer.
92 */
93int
94SerialBuffer::size() const
95{
96    return _buffer.size();
97}
98
99/**
100 * Clear the buffer, making it empty.
101 */
102SerialBuffer&
103SerialBuffer::clear()
104{
105    _buffer.clear();
106    return *this;
107}
108
109SerialBuffer&
110SerialBuffer::writeChar(char cval)
111{
112    _buffer.push_back(cval);
113    return *this;
114}
115
116SerialBuffer&
117SerialBuffer::writeInt(int ival)
118{
119    char *ptr = (char*)(&ival);
120    unsigned int i = 0;
121
122    ENDIAN_FOR_LOOP(i, sizeof(int)) {
123        _buffer.push_back(ptr[i]);
124    }
125    return *this;
126}
127
128SerialBuffer&
129SerialBuffer::writeDouble(double dval)
130{
131    char *ptr = (char*)(&dval);
132    unsigned int i = 0;
133
134    ENDIAN_FOR_LOOP(i, sizeof(double)) {
135        _buffer.push_back(ptr[i]);
136    }
137    return *this;
138}
139
140SerialBuffer&
141SerialBuffer::writeString(const char* sval)
142{
143    while (*sval != '\0') {
144        _buffer.push_back(*sval++);
145    }
146    _buffer.push_back('\0');
147    return *this;
148}
149
150SerialBuffer&
151SerialBuffer::writeBytes(const char* bval, int nbytes)
152{
153    writeInt(nbytes);
154    while (nbytes-- > 0) {
155        _buffer.push_back(*bval++);
156    }
157    return *this;
158}
159
160void
161SerialBuffer::rewind()
162{
163    _pos = 0;
164}
165
166int
167SerialBuffer::atEnd() const
168{
169    return ((unsigned int)_pos >= _buffer.size());
170}
171
172char
173SerialBuffer::readChar()
174{
175    char c = '\0';
176    if ((unsigned int)_pos < _buffer.size()) {
177        c = _buffer[_pos++];
178    }
179    return c;
180}
181
182int
183SerialBuffer::readInt()
184{
185    int ival = 0;
186    char *ptr = (char*)(&ival);
187    unsigned int i = 0;
188
189    ENDIAN_FOR_LOOP(i, sizeof(int)) {
190        if ((unsigned int)_pos < _buffer.size()) {
191            ptr[i] = _buffer[_pos++];
192        }
193    }
194    return ival;
195}
196
197double
198SerialBuffer::readDouble()
199{
200    double dval = 0;
201    char *ptr = (char*)(&dval);
202    unsigned int i = 0;
203
204    ENDIAN_FOR_LOOP(i, sizeof(double)) {
205        if ((unsigned int)_pos < _buffer.size()) {
206            ptr[i] = _buffer[_pos++];
207        }
208    }
209    return dval;
210}
211
212std::string
213SerialBuffer::readString()
214{
215    std::string sval;
216    char c;
217    while ((unsigned int)_pos < _buffer.size()) {
218        c = _buffer[_pos++];
219        if (c == '\0') {
220            break;
221        } else {
222            sval.push_back(c);
223        }
224    }
225    return sval;
226}
227
228std::vector<char>
229SerialBuffer::readBytes()
230{
231    int nbytes;
232    std::vector<char> bval;
233
234    nbytes = readInt();
235    while ((unsigned int)_pos < _buffer.size() && nbytes-- > 0) {
236        bval.push_back( _buffer[_pos++] );
237    }
238    return bval;
239}
Note: See TracBrowser for help on using the repository browser.