PageRenderTime 47ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/quakeforge/branches/net_svc/libs/util/msg.c

#
C | 381 lines | 273 code | 63 blank | 45 comment | 35 complexity | ad91042acdd90fb6a491e85376ab2f6b MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, AGPL-3.0, AGPL-1.0, Unlicense
  1. /*
  2. msg.c
  3. (description)
  4. Copyright (C) 1996-1997 Id Software, Inc.
  5. This program is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU General Public License
  7. as published by the Free Software Foundation; either version 2
  8. of the License, or (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. See the GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to:
  15. Free Software Foundation, Inc.
  16. 59 Temple Place - Suite 330
  17. Boston, MA 02111-1307, USA
  18. */
  19. static const char rcsid[] =
  20. "$Id: msg.c 6535 2001-11-10 23:52:35Z rhamphoryncus $";
  21. #ifdef HAVE_CONFIG_H
  22. # include "config.h"
  23. #endif
  24. #ifdef HAVE_STRING_H
  25. # include <string.h>
  26. #endif
  27. #ifdef HAVE_STRINGS_H
  28. # include <strings.h>
  29. #endif
  30. #include "QF/msg.h"
  31. #include "QF/qendian.h"
  32. #include "QF/sys.h"
  33. #include "QF/string.h"
  34. #include "compat.h"
  35. /*
  36. MESSAGE IO FUNCTIONS
  37. Handles byte ordering and avoids alignment errors
  38. */
  39. // writing functions
  40. void
  41. MSG_WriteChar (sizebuf_t *sb, int c)
  42. {
  43. #ifdef PARANOID
  44. if (c < -128 || c > 127)
  45. Sys_Error ("MSG_WriteChar: range error");
  46. #endif
  47. if (sb->overflowed || sb->cursize + 1 > sb->maxsize) {
  48. if (!sb->allowoverflow)
  49. Sys_Error (__func__ ": overflow");
  50. sb->overflowed = true;
  51. return;
  52. }
  53. sb->data[sb->cursize] = c; // FIXME: this need a cast?
  54. sb->cursize++;
  55. }
  56. void
  57. MSG_WriteByte (sizebuf_t *sb, int c)
  58. {
  59. #ifdef PARANOID
  60. if (c < 0 || c > 255)
  61. Sys_Error ("MSG_WriteByte: range error");
  62. #endif
  63. if (sb->overflowed || sb->cursize + 1 > sb->maxsize) {
  64. if (!sb->allowoverflow)
  65. Sys_Error (__func__ ": overflow");
  66. sb->overflowed = true;
  67. return;
  68. }
  69. sb->data[sb->cursize] = c;
  70. sb->cursize++;
  71. }
  72. void
  73. MSG_WriteShort (sizebuf_t *sb, int c)
  74. {
  75. #ifdef PARANOID
  76. if (c < ((short) 0x8000) || c > (short) 0x7fff)
  77. Sys_Error ("MSG_WriteShort: range error");
  78. #endif
  79. if (sb->overflowed || sb->cursize + 2 > sb->maxsize) {
  80. if (!sb->allowoverflow)
  81. Sys_Error (__func__ ": overflow");
  82. sb->overflowed = true;
  83. return;
  84. }
  85. sb->data[sb->cursize] = c & 0xff;
  86. sb->data[sb->cursize + 1] = c >> 8;
  87. sb->cursize += 2;
  88. }
  89. void
  90. MSG_WriteLong (sizebuf_t *sb, int c)
  91. {
  92. if (sb->overflowed || sb->cursize + 4 > sb->maxsize) {
  93. if (!sb->allowoverflow)
  94. Sys_Error (__func__ ": overflow");
  95. sb->overflowed = true;
  96. return;
  97. }
  98. sb->data[sb->cursize] = c & 0xff;
  99. sb->data[sb->cursize + 1] = (c >> 8) & 0xff;
  100. sb->data[sb->cursize + 2] = (c >> 16) & 0xff;
  101. sb->data[sb->cursize + 3] = c >> 24;
  102. sb->cursize += 4;
  103. }
  104. void
  105. MSG_WriteFloat (sizebuf_t *sb, float f)
  106. {
  107. MSG_WriteLong (sb, *(int *)&f);
  108. /*
  109. union {
  110. float f;
  111. int l;
  112. } dat;
  113. dat.f = f;
  114. dat.l = LittleLong (dat.l);
  115. SZ_Write (sb, &dat.l, 4);
  116. */
  117. }
  118. void
  119. MSG_WriteBlock (sizebuf_t *sb, const byte *data, int size)
  120. {
  121. if (sb->overflowed || sb->cursize + size > sb->maxsize) {
  122. if (!sb->allowoverflow)
  123. Sys_Error (__func__ ": overflow");
  124. sb->overflowed = true;
  125. return;
  126. }
  127. memcpy (&sb->data[sb->cursize], data, size);
  128. sb->cursize += size;
  129. }
  130. void
  131. MSG_WriteString (sizebuf_t *sb, const char *s)
  132. {
  133. if (!s)
  134. MSG_WriteBlock (sb, "", 1);
  135. else
  136. MSG_WriteBlock (sb, s, strlen (s) + 1);
  137. }
  138. void
  139. MSG_WriteCoord (sizebuf_t *sb, float f)
  140. {
  141. MSG_WriteShort (sb, (int) (f * 8));
  142. }
  143. void
  144. MSG_WriteAngle (sizebuf_t *sb, float f)
  145. {
  146. MSG_WriteByte (sb, (int) (f * 256 / 360) & 255);
  147. }
  148. void
  149. MSG_WriteAngle16 (sizebuf_t *sb, float f)
  150. {
  151. MSG_WriteShort (sb, (int) (f * 65536 / 360) & 65535);
  152. }
  153. // reading functions
  154. void
  155. MSG_BeginReading (msg_t *msg)
  156. {
  157. msg->readcount = 0;
  158. msg->badread = false;
  159. }
  160. int
  161. MSG_GetReadCount (msg_t *msg)
  162. {
  163. return msg->readcount;
  164. }
  165. // returns -1 and sets msg->badread if no more characters are available
  166. int
  167. MSG_ReadChar (msg_t *msg)
  168. {
  169. int c;
  170. if (msg->readcount + 1 > msg->message->cursize) {
  171. msg->badread = true;
  172. return -1;
  173. }
  174. c = (signed char) msg->message->data[msg->readcount];
  175. msg->readcount++;
  176. return c;
  177. }
  178. int
  179. MSG_ReadByte (msg_t *msg)
  180. {
  181. int c;
  182. if (msg->readcount + 1 > msg->message->cursize) {
  183. msg->badread = true;
  184. return -1;
  185. }
  186. c = (unsigned char) msg->message->data[msg->readcount];
  187. msg->readcount++;
  188. return c;
  189. }
  190. int
  191. MSG_ReadShort (msg_t *msg)
  192. {
  193. int c;
  194. if (msg->readcount + 2 > msg->message->cursize) {
  195. msg->readcount = msg->message->cursize;
  196. msg->badread = true;
  197. return -1;
  198. }
  199. c = (short) (msg->message->data[msg->readcount]
  200. + (msg->message->data[msg->readcount + 1] << 8));
  201. msg->readcount += 2;
  202. return c;
  203. }
  204. int
  205. MSG_ReadLong (msg_t *msg)
  206. {
  207. int c;
  208. if (msg->readcount + 4 > msg->message->cursize) {
  209. msg->readcount = msg->message->cursize;
  210. msg->badread = true;
  211. return -1;
  212. }
  213. c = msg->message->data[msg->readcount]
  214. + (msg->message->data[msg->readcount + 1] << 8)
  215. + (msg->message->data[msg->readcount + 2] << 16)
  216. + (msg->message->data[msg->readcount + 3] << 24);
  217. msg->readcount += 4;
  218. return c;
  219. }
  220. float
  221. MSG_ReadFloat (msg_t *msg)
  222. {
  223. union {
  224. byte b[4];
  225. float f;
  226. int l;
  227. } dat;
  228. if (msg->readcount + 4 > msg->message->cursize) {
  229. msg->readcount = msg->message->cursize;
  230. msg->badread = true;
  231. return -1;
  232. }
  233. dat.b[0] = msg->message->data[msg->readcount];
  234. dat.b[1] = msg->message->data[msg->readcount + 1];
  235. dat.b[2] = msg->message->data[msg->readcount + 2];
  236. dat.b[3] = msg->message->data[msg->readcount + 3];
  237. msg->readcount += 4;
  238. dat.l = LittleLong (dat.l);
  239. return dat.f;
  240. }
  241. const byte *
  242. MSG_ReadBlock (msg_t *msg, int size)
  243. {
  244. const byte *data;
  245. if (msg->readcount + size > msg->message->cursize) {
  246. msg->readcount = msg->message->cursize;
  247. msg->badread = true;
  248. return 0;
  249. }
  250. data = &msg->message->data[msg->readcount];
  251. msg->readcount += size;
  252. return data;
  253. }
  254. const char *
  255. MSG_ReadString (msg_t *msg)
  256. {
  257. char *string;
  258. int len, maxlen;
  259. if (msg->badread || msg->readcount + 1 > msg->message->cursize) {
  260. msg->badread = true;
  261. return "";
  262. }
  263. string = &msg->message->data[msg->readcount];
  264. maxlen = msg->message->cursize - msg->readcount;
  265. len = strnlen (string, maxlen);
  266. if (len == maxlen) {
  267. msg->readcount = msg->readcount;
  268. msg->badread = true;
  269. if (len + 1 > msg->badread_string_size) {
  270. if (msg->badread_string)
  271. free (msg->badread_string);
  272. msg->badread_string = malloc (len + 1);
  273. msg->badread_string_size = len + 1;
  274. }
  275. if (!msg->badread_string)
  276. Sys_Error ("MSG_ReadString: out of memory\n");
  277. strncpy (msg->badread_string, string, len);
  278. msg->badread_string[len] = 0;
  279. return msg->badread_string;
  280. }
  281. msg->readcount += len + 1;
  282. return string;
  283. }
  284. float
  285. MSG_ReadCoord (msg_t *msg)
  286. {
  287. return MSG_ReadShort (msg) * (1.0 / 8);
  288. }
  289. float
  290. MSG_ReadAngle (msg_t *msg)
  291. {
  292. return MSG_ReadChar (msg) * (360.0 / 256);
  293. }
  294. float
  295. MSG_ReadAngle16 (msg_t *msg)
  296. {
  297. return MSG_ReadShort (msg) * (360.0 / 65536);
  298. }
  299. int
  300. MSG_PeekByte (msg_t *msg)
  301. {
  302. int c;
  303. int readcount = msg->readcount;
  304. c = MSG_ReadByte (msg);
  305. msg->readcount = readcount;
  306. return c;
  307. }