stream.cpp

Engine/source/core/stream/stream.cpp

More...

Public Defines

define
IMPLEMENT_ENDIAN_OVERLOADED_READ(type)    bool (type* out_read)            \
   {                                            \
      type temp;                                \
      bool  = read(sizeof(type), &temp); \
      *out_read = convertLEndianToHost(temp);   \
      return ;                           \
   }
define
IMPLEMENT_ENDIAN_OVERLOADED_WRITE(type)    bool (type in_write)               \
   {                                               \
      type temp = convertHostToLEndian(in_write);  \
      return write(sizeof(type), &temp);           \
   }
define
IMPLEMENT_OVERLOADED_READ(type)    bool (type* out_read)         \
   {                                         \
      return read(sizeof(type), out_read);   \
   }
define
IMPLEMENT_OVERLOADED_WRITE(type)    bool (type in_write)            \
   {                                            \
      return write(sizeof(type), &in_write);    \
   }

Detailed Description

Public Defines

IMPLEMENT_ENDIAN_OVERLOADED_READ(type)    bool (type* out_read)            \
   {                                            \
      type temp;                                \
      bool  = read(sizeof(type), &temp); \
      *out_read = convertLEndianToHost(temp);   \
      return ;                           \
   }
IMPLEMENT_ENDIAN_OVERLOADED_WRITE(type)    bool (type in_write)               \
   {                                               \
      type temp = convertHostToLEndian(in_write);  \
      return write(sizeof(type), &temp);           \
   }
IMPLEMENT_OVERLOADED_READ(type)    bool (type* out_read)         \
   {                                         \
      return read(sizeof(type), out_read);   \
   }
IMPLEMENT_OVERLOADED_WRITE(type)    bool (type in_write)            \
   {                                            \
      return write(sizeof(type), &in_write);    \
   }
  1
  2//-----------------------------------------------------------------------------
  3// Copyright (c) 2012 GarageGames, LLC
  4//
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to
  7// deal in the Software without restriction, including without limitation the
  8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9// sell copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11//
 12// The above copyright notice and this permission notice shall be included in
 13// all copies or substantial portions of the Software.
 14//
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21// IN THE SOFTWARE.
 22//-----------------------------------------------------------------------------
 23
 24#include "core/color.h"
 25#include "core/util/rawData.h"
 26#include "core/frameAllocator.h"
 27#include "platform/platformNet.h"
 28
 29#include "core/stream/stream.h"
 30
 31#include "core/stringTable.h"
 32#include "core/strings/stringFunctions.h"
 33
 34#include "core/util/byteBuffer.h"
 35#include "core/util/endian.h"
 36#include "core/util/str.h"
 37
 38
 39#define IMPLEMENT_OVERLOADED_READ(type)      \
 40   bool Stream::read(type* out_read)         \
 41   {                                         \
 42      return read(sizeof(type), out_read);   \
 43   }
 44
 45#define IMPLEMENT_OVERLOADED_WRITE(type)        \
 46   bool Stream::write(type in_write)            \
 47   {                                            \
 48      return write(sizeof(type), &in_write);    \
 49   }
 50
 51#define IMPLEMENT_ENDIAN_OVERLOADED_READ(type)  \
 52   bool Stream::read(type* out_read)            \
 53   {                                            \
 54      type temp;                                \
 55      bool success = read(sizeof(type), &temp); \
 56      *out_read = convertLEndianToHost(temp);   \
 57      return success;                           \
 58   }
 59
 60#define IMPLEMENT_ENDIAN_OVERLOADED_WRITE(type)    \
 61   bool Stream::write(type in_write)               \
 62   {                                               \
 63      type temp = convertHostToLEndian(in_write);  \
 64      return write(sizeof(type), &temp);           \
 65   }
 66
 67IMPLEMENT_OVERLOADED_WRITE(S8)
 68IMPLEMENT_OVERLOADED_WRITE(U8)
 69
 70IMPLEMENT_ENDIAN_OVERLOADED_WRITE(S16)
 71IMPLEMENT_ENDIAN_OVERLOADED_WRITE(S32)
 72IMPLEMENT_ENDIAN_OVERLOADED_WRITE(U16)
 73IMPLEMENT_ENDIAN_OVERLOADED_WRITE(U32)
 74IMPLEMENT_ENDIAN_OVERLOADED_WRITE(U64)
 75IMPLEMENT_ENDIAN_OVERLOADED_WRITE(F32)
 76IMPLEMENT_ENDIAN_OVERLOADED_WRITE(F64)
 77
 78IMPLEMENT_OVERLOADED_READ(S8)
 79IMPLEMENT_OVERLOADED_READ(U8)
 80
 81IMPLEMENT_ENDIAN_OVERLOADED_READ(S16)
 82IMPLEMENT_ENDIAN_OVERLOADED_READ(S32)
 83IMPLEMENT_ENDIAN_OVERLOADED_READ(U16)
 84IMPLEMENT_ENDIAN_OVERLOADED_READ(U32)
 85IMPLEMENT_ENDIAN_OVERLOADED_READ(U64)
 86IMPLEMENT_ENDIAN_OVERLOADED_READ(F32)
 87IMPLEMENT_ENDIAN_OVERLOADED_READ(F64)
 88
 89
 90Stream::Stream()
 91 : m_streamStatus(Closed)
 92{
 93}
 94
 95const char* Stream::getStatusString(const StreamStatus in_status)
 96{
 97   switch (in_status) {
 98      case Ok:
 99         return "StreamOk";
100      case IOError:
101         return "StreamIOError";
102      case EOS:
103         return "StreamEOS";
104      case IllegalCall:
105         return "StreamIllegalCall";
106      case Closed:
107         return "StreamClosed";
108      case UnknownError:
109         return "StreamUnknownError";
110
111     default:
112      return "Invalid Stream::Status";
113   }
114}
115
116void Stream::writeString(const char *string, S32 maxLen)
117{
118   S32 len = string ? dStrlen(string) : 0;
119   if(len > maxLen)
120      len = maxLen;
121
122   write(U8(len));
123   if(len)
124      write(len, string);
125}
126
127bool Stream::writeFormattedBuffer(const char *format, ...)
128{
129   char buffer[4096];
130   va_list args;
131   va_start(args, format);
132   const S32 length = dVsprintf(buffer, sizeof(buffer), format, args);
133
134   // Sanity!
135   AssertFatal(length <= sizeof(buffer), "writeFormattedBuffer - String format exceeded buffer size.  This will cause corruption.");
136
137   return write(length, buffer);
138}
139
140void Stream::readString(char buf[256])
141{
142   U8 len;
143   read(&len);
144   read(S32(len), buf);
145   buf[len] = 0;
146}
147
148const char *Stream::readSTString(bool casesens)
149{
150   char buf[256];
151   readString(buf);
152   return StringTable->insert(buf, casesens);
153}
154
155void Stream::readLongString(U32 maxStringLen, char *stringBuf)
156{
157   U32 len;
158   read(&len);
159   if(len >= maxStringLen)
160   {
161      m_streamStatus = IOError;
162      return;
163   }
164   read(len, stringBuf);
165   stringBuf[len] = 0;
166}
167
168void Stream::writeLongString(U32 maxStringLen, const char *string)
169{
170   U32 len = dStrlen(string);
171   if(len > maxStringLen)
172      len = maxStringLen;
173   write(len);
174   write(len, string);
175}
176
177void Stream::readLine(U8 *buffer, U32 bufferSize)
178{
179   bufferSize--;  // account for NULL terminator
180   U8 *buff = buffer;
181   U8 *buffEnd = buff + bufferSize;
182   *buff = '\r';
183
184   // strip off preceding white space
185   while ( *buff == '\r' )
186   {
187      if ( !read(buff) || *buff == '\n' )
188      {
189         *buff = 0;
190         return;
191      }
192   }
193
194   // read line
195   while ( buff != buffEnd && read(++buff) && *buff != '\n' )
196   {
197      if ( *buff == '\r' )
198      {
199
200#if defined(TORQUE_OS_MAC)
201      U32 pushPos = getPosition(); // in case we need to back up.
202      if (read(buff)) // feeling free to overwrite the \r as the NULL below will overwrite again...
203         if (*buff != '\n') // then push our position back.
204            setPosition(pushPos);
205      break; // we're always done after seeing the CR...
206#else
207      buff--; // 'erases' the CR of a CRLF
208#endif
209
210      }
211   }
212   *buff = 0;
213}
214
215void Stream::writeText(const char *text)
216{
217   if (text && text[0])
218      write(dStrlen(text), text);
219}
220
221void Stream::writeLine(const U8 *buffer)
222{
223   write(dStrlen((const char *)buffer), buffer);
224   write(2, "\r\n");
225}
226
227void Stream::_write(const String & str)
228{
229   U32 len = str.length();
230
231   if (len<255)
232      write(U8(len));
233   else
234   {
235      // longer string, write full length
236      write(U8(255));
237
238      // fail if longer than 16 bits (will truncate string modulo 2^16)
239      AssertFatal(len < (1<<16),"String too long");
240
241      len &= (1<<16)-1;
242      write(U16(len));
243   }
244
245   write(len,str.c_str());
246}
247
248void Stream::_read(String * str)
249{
250   U16 len;
251
252   U8 len8;
253   read(&len8);
254   if (len8==255)
255      read(&len);
256   else
257      len = len8;
258
259   char * buffer = (char*)FrameAllocator::alloc(len);
260   read(len, buffer);
261   *str = String(buffer,len);
262}
263
264
265bool Stream::write(const ColorI& rColor)
266{
267   bool success = write(rColor.red);
268   success     |= write(rColor.green);
269   success     |= write(rColor.blue);
270   success     |= write(rColor.alpha);
271
272   return success;
273}
274
275bool Stream::write(const LinearColorF& rColor)
276{
277   ColorI temp = LinearColorF(rColor).toColorI();
278   return write(temp);
279}
280
281bool Stream::read(ColorI* pColor)
282{
283   bool success = read(&pColor->red);
284   success     |= read(&pColor->green);
285   success     |= read(&pColor->blue);
286   success     |= read(&pColor->alpha);
287
288   return success;
289}
290
291bool Stream::read(LinearColorF* pColor)
292{
293   ColorI temp;
294   bool success = read(&temp);
295
296   *pColor = temp;
297   return success;
298}
299
300bool Stream::write(const NetAddress &na)
301{
302   bool success = write(na.type);
303   success &= write(na.port);
304   success &= write(sizeof(na.address), &na.address);
305   return success;
306}
307
308bool Stream::read(NetAddress *na)
309{
310   bool success = read(&na->type);
311   success &= read(&na->port);
312   success &= read(sizeof(na->address), &na->address);
313   return success;
314}
315
316bool Stream::write(const NetSocket &so)
317{
318   return write(so.getHandle());
319}
320
321bool Stream::read(NetSocket* so)
322{
323   S32 handle = -1;
324   bool success = read(&handle);
325   *so = NetSocket::fromHandle(handle);
326   return success;
327}
328
329bool Stream::write(const RawData &rd)
330{
331   bool s = write(rd.size);
332   s &= write(rd.size, rd.data);
333   return s;
334}
335
336bool Stream::read(RawData *rd)
337{
338   U32 size = 0;
339   bool s = read(&size);
340
341   rd->alloc(size);
342   s &= read(rd->size, rd->data);
343
344   return s;
345}
346
347bool Stream::write(const Torque::ByteBuffer &rd)
348{
349   bool s = write(rd.getBufferSize());
350   s &= write(rd.getBufferSize(), rd.getBuffer());
351   return s;
352}
353
354bool Stream::read(Torque::ByteBuffer *rd)
355{
356   U32 size = 0;
357   bool s = read(&size);
358
359   rd->resize(size);
360   s &= read(rd->getBufferSize(), rd->getBuffer());
361
362   return s;
363}
364
365bool Stream::copyFrom(Stream *other)
366{
367   U8 buffer[1024];
368   U32 numBytes = other->getStreamSize() - other->getPosition();
369   while((other->getStatus() != Stream::EOS) && numBytes > 0)
370   {
371      U32 numRead = numBytes > sizeof(buffer) ? sizeof(buffer) : numBytes;
372      if(! other->read(numRead, buffer))
373         return false;
374
375      if(! write(numRead, buffer))
376         return false;
377
378      numBytes -= numRead;
379   }
380
381   return true;
382}
383
384Stream* Stream::clone() const
385{
386   return NULL;
387}
388