stream.cpp 9.0 KB

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