stream.cpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  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. void Stream::readString(char buf[256])
  107. {
  108. U8 len;
  109. read(&len);
  110. read(S32(len), buf);
  111. buf[len] = 0;
  112. }
  113. const char *Stream::readSTString(bool casesens)
  114. {
  115. char buf[256];
  116. readString(buf);
  117. return StringTable->insert(buf, casesens);
  118. }
  119. void Stream::readLongString(U32 maxStringLen, char *stringBuf)
  120. {
  121. U32 len;
  122. read(&len);
  123. if(len > maxStringLen)
  124. {
  125. m_streamStatus = IOError;
  126. return;
  127. }
  128. read(len, stringBuf);
  129. stringBuf[len] = 0;
  130. }
  131. void Stream::writeLongString(U32 maxStringLen, const char *string)
  132. {
  133. U32 len = dStrlen(string);
  134. if(len > maxStringLen)
  135. len = maxStringLen;
  136. write(len);
  137. write(len, string);
  138. }
  139. void Stream::readLine(U8 *buffer, U32 bufferSize)
  140. {
  141. bufferSize--; // account for NULL terminator
  142. U8 *buff = buffer;
  143. U8 *buffEnd = buff + bufferSize;
  144. *buff = '\r';
  145. // strip off preceding white space
  146. while ( *buff == '\r' )
  147. {
  148. if ( !read(buff) || *buff == '\n' )
  149. {
  150. *buff = 0;
  151. return;
  152. }
  153. }
  154. // read line
  155. while ( buff != buffEnd && read(++buff) && *buff != '\n' )
  156. {
  157. if ( *buff == '\r' )
  158. {
  159. #if defined(TORQUE_OS_MAC)
  160. U32 pushPos = getPosition(); // in case we need to back up.
  161. if (read(buff)) // feeling free to overwrite the \r as the NULL below will overwrite again...
  162. if (*buff != '\n') // then push our position back.
  163. setPosition(pushPos);
  164. break; // we're always done after seeing the CR...
  165. #else
  166. buff--; // 'erases' the CR of a CRLF
  167. #endif
  168. }
  169. }
  170. *buff = 0;
  171. }
  172. void Stream::writeText(const char *text)
  173. {
  174. if (text && text[0])
  175. write(dStrlen(text), text);
  176. }
  177. void Stream::writeLine(const U8 *buffer)
  178. {
  179. write(dStrlen((const char *)buffer), buffer);
  180. write(2, "\r\n");
  181. }
  182. void Stream::_write(const String & str)
  183. {
  184. U32 len = str.length();
  185. if (len<255)
  186. write(U8(len));
  187. else
  188. {
  189. // longer string, write full length
  190. write(U8(255));
  191. // fail if longer than 16 bits (will truncate string modulo 2^16)
  192. AssertFatal(len < (1<<16),"String too long");
  193. len &= (1<<16)-1;
  194. write(U16(len));
  195. }
  196. write(len,str.c_str());
  197. }
  198. void Stream::_read(String * str)
  199. {
  200. U16 len;
  201. U8 len8;
  202. read(&len8);
  203. if (len8==255)
  204. read(&len);
  205. else
  206. len = len8;
  207. char * buffer = (char*)FrameAllocator::alloc(len);
  208. read(len, buffer);
  209. *str = String(buffer,len);
  210. }
  211. bool Stream::write(const ColorI& rColor)
  212. {
  213. bool success = write(rColor.red);
  214. success |= write(rColor.green);
  215. success |= write(rColor.blue);
  216. success |= write(rColor.alpha);
  217. return success;
  218. }
  219. bool Stream::write(const ColorF& rColor)
  220. {
  221. ColorI temp = rColor;
  222. return write(temp);
  223. }
  224. bool Stream::read(ColorI* pColor)
  225. {
  226. bool success = read(&pColor->red);
  227. success |= read(&pColor->green);
  228. success |= read(&pColor->blue);
  229. success |= read(&pColor->alpha);
  230. return success;
  231. }
  232. bool Stream::read(ColorF* pColor)
  233. {
  234. ColorI temp;
  235. bool success = read(&temp);
  236. *pColor = temp;
  237. return success;
  238. }
  239. bool Stream::write(const NetAddress &na)
  240. {
  241. bool success = write(na.type);
  242. success &= write(na.port);
  243. success &= write(na.netNum[0]);
  244. success &= write(na.netNum[1]);
  245. success &= write(na.netNum[2]);
  246. success &= write(na.netNum[3]);
  247. success &= write(na.nodeNum[0]);
  248. success &= write(na.nodeNum[1]);
  249. success &= write(na.nodeNum[2]);
  250. success &= write(na.nodeNum[3]);
  251. success &= write(na.nodeNum[4]);
  252. success &= write(na.nodeNum[5]);
  253. return success;
  254. }
  255. bool Stream::read(NetAddress *na)
  256. {
  257. bool success = read(&na->type);
  258. success &= read(&na->port);
  259. success &= read(&na->netNum[0]);
  260. success &= read(&na->netNum[1]);
  261. success &= read(&na->netNum[2]);
  262. success &= read(&na->netNum[3]);
  263. success &= read(&na->nodeNum[0]);
  264. success &= read(&na->nodeNum[1]);
  265. success &= read(&na->nodeNum[2]);
  266. success &= read(&na->nodeNum[3]);
  267. success &= read(&na->nodeNum[4]);
  268. success &= read(&na->nodeNum[5]);
  269. return success;
  270. }
  271. bool Stream::write(const RawData &rd)
  272. {
  273. bool s = write(rd.size);
  274. s &= write(rd.size, rd.data);
  275. return s;
  276. }
  277. bool Stream::read(RawData *rd)
  278. {
  279. U32 size = 0;
  280. bool s = read(&size);
  281. rd->alloc(size);
  282. s &= read(rd->size, rd->data);
  283. return s;
  284. }
  285. bool Stream::write(const Torque::ByteBuffer &rd)
  286. {
  287. bool s = write(rd.getBufferSize());
  288. s &= write(rd.getBufferSize(), rd.getBuffer());
  289. return s;
  290. }
  291. bool Stream::read(Torque::ByteBuffer *rd)
  292. {
  293. U32 size = 0;
  294. bool s = read(&size);
  295. rd->resize(size);
  296. s &= read(rd->getBufferSize(), rd->getBuffer());
  297. return s;
  298. }
  299. bool Stream::copyFrom(Stream *other)
  300. {
  301. U8 buffer[1024];
  302. U32 numBytes = other->getStreamSize() - other->getPosition();
  303. while((other->getStatus() != Stream::EOS) && numBytes > 0)
  304. {
  305. U32 numRead = numBytes > sizeof(buffer) ? sizeof(buffer) : numBytes;
  306. if(! other->read(numRead, buffer))
  307. return false;
  308. if(! write(numRead, buffer))
  309. return false;
  310. numBytes -= numRead;
  311. }
  312. return true;
  313. }
  314. Stream* Stream::clone() const
  315. {
  316. return NULL;
  317. }