Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

408 lines
13 KiB

  1. /*
  2. ** Copyright 1995-2095, Silicon Graphics, Inc.
  3. ** All Rights Reserved.
  4. **
  5. ** This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6. ** the contents of this file may not be disclosed to third parties, copied or
  7. ** duplicated in any form, in whole or in part, without the prior written
  8. ** permission of Silicon Graphics, Inc.
  9. **
  10. ** RESTRICTED RIGHTS LEGEND:
  11. ** Use, duplication or disclosure by the Government is subject to restrictions
  12. ** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13. ** and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14. ** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15. ** rights reserved under the Copyright Laws of the United States.
  16. */
  17. #include "glslib.h"
  18. #include <stdlib.h>
  19. #include <string.h>
  20. /******************************************************************************
  21. __GLSreadStream
  22. ******************************************************************************/
  23. __GLSreadStream* __glsReadStream_create(const GLubyte *inName) {
  24. __GLScontext *const ctx = __GLS_CONTEXT;
  25. __GLSreadStream *const outStream = __glsCalloc(
  26. 1, sizeof(__GLSreadStream)
  27. );
  28. if (!outStream) return GLS_NONE;
  29. __glsString_init(&outStream->name);
  30. outStream->unreadFunc = ctx->unreadFunc;
  31. if (inName[0]) {
  32. const GLubyte *openName;
  33. __GLS_ITERLIST_FIRST(&ctx->readPrefixList);
  34. while (ctx->readPrefixList.iterElem) {
  35. if (
  36. !__glsListString_prefix(
  37. ctx->readPrefixList.iterElem, inName, &outStream->name
  38. ) ||
  39. !(openName = __glsUCS1String(outStream->name.head))
  40. ) {
  41. return __glsReadStream_destroy(outStream);
  42. }
  43. outStream->channel = fopen((const char *)openName, "rb");
  44. if (openName != outStream->name.head) free((GLvoid *)openName);
  45. if (outStream->channel) {
  46. setbuf(outStream->channel, GLS_NONE);
  47. outStream->opened = GL_TRUE;
  48. return outStream;
  49. }
  50. __GLS_ITERLIST_NEXT(&ctx->readPrefixList);
  51. }
  52. if (
  53. !__glsListString_prefix(
  54. ctx->writePrefix, inName, &outStream->name
  55. ) ||
  56. !(openName = __glsUCS1String(outStream->name.head))
  57. ) {
  58. return __glsReadStream_destroy(outStream);
  59. }
  60. outStream->channel = fopen((const char *)openName, "rb");
  61. if (openName != outStream->name.head) free((GLvoid *)openName);
  62. if (outStream->channel) {
  63. setbuf(outStream->channel, GLS_NONE);
  64. outStream->opened = GL_TRUE;
  65. return outStream;
  66. }
  67. return __glsReadStream_destroy(outStream);
  68. } else {
  69. outStream->readFunc = ctx->readFunc;
  70. if (!outStream->readFunc) outStream->channel = ctx->defaultReadChannel;
  71. return outStream;
  72. }
  73. }
  74. __GLSreadStream* __glsReadStream_destroy(__GLSreadStream *inStream) {
  75. if (!inStream) return GLS_NONE;
  76. if (inStream->opened && fclose(inStream->channel)) {
  77. __GLS_RAISE_ERROR(GLS_STREAM_CLOSE_ERROR);
  78. }
  79. __glsString_final(&inStream->name);
  80. free(inStream);
  81. return GLS_NONE;
  82. }
  83. GLbitfield __glsReadStream_getAttrib(const __GLSreadStream *inStream) {
  84. GLbitfield outVal = GLS_STREAM_READABLE_BIT;
  85. if (inStream->opened) {
  86. const GLubyte *const openName = __glsUCS1String(inStream->name.head);
  87. FILE *channel;
  88. if (!openName) return GLS_NONE;
  89. channel = fopen((const char *)openName, "ab");
  90. if (openName != inStream->name.head) free((GLvoid *)openName);
  91. if (channel) {
  92. fclose(channel);
  93. outVal |= GLS_STREAM_WRITABLE_BIT;
  94. }
  95. outVal |= GLS_STREAM_NAMED_BIT;
  96. }
  97. if (!fseek(inStream->channel, 0, SEEK_CUR)) {
  98. outVal |= GLS_STREAM_SEEKABLE_BIT;
  99. }
  100. return outVal;
  101. }
  102. size_t __glsReadStream_getByteCount(const __GLSreadStream *inStream) {
  103. long outVal;
  104. fpos_t pos;
  105. if (!inStream->channel) return 0;
  106. if (
  107. fgetpos(inStream->channel, &pos) ||
  108. fseek(inStream->channel, 0, SEEK_END)
  109. ) {
  110. return 0;
  111. }
  112. outVal = ftell(inStream->channel);
  113. fsetpos(inStream->channel, &pos);
  114. return outVal == -1L ? 0 : (size_t)outVal;
  115. }
  116. GLuint __glsReadStream_getCRC32(const __GLSreadStream *inStream) {
  117. GLubyte buf[__GLS_CHECKSUM_BUF_BYTES];
  118. size_t i, n;
  119. GLuint outVal = 0xffffffff;
  120. fpos_t pos;
  121. if (!inStream->channel) return 0;
  122. if (
  123. fgetpos(inStream->channel, &pos) ||
  124. fseek(inStream->channel, 0, SEEK_SET)
  125. ) {
  126. return 0;
  127. }
  128. while (n = fread(buf, 1, __GLS_CHECKSUM_BUF_BYTES, inStream->channel)) {
  129. for (i = 0 ; i < n ; ++i) __GLS_CRC32_STEP(outVal, buf[i]);
  130. }
  131. fsetpos(inStream->channel, &pos);
  132. if (ferror(inStream->channel)) {
  133. __GLS_RAISE_ERROR(GLS_STREAM_READ_ERROR);
  134. clearerr(inStream->channel);
  135. return 0;
  136. }
  137. return ~outVal;
  138. }
  139. GLSenum __glsReadStream_getType(const __GLSreadStream *inStream) {
  140. __GLSreader reader;
  141. if (!inStream->channel) return GLS_NONE;
  142. if (fseek(inStream->channel, 0, SEEK_CUR)) return GLS_UNKNOWN;
  143. if (__glsReader_init_stream(&reader, inStream, 256)) {
  144. const GLenum outType = reader.type;
  145. __glsReader_final(&reader);
  146. return outType;
  147. } else {
  148. return GLS_NONE;
  149. }
  150. }
  151. /******************************************************************************
  152. __GLSreader
  153. ******************************************************************************/
  154. GLvoid* __glsReader_allocCallBuf(
  155. __GLSreader *inoutReader, size_t inByteCount
  156. ) {
  157. GLvoid *outVal;
  158. if (inoutReader->error) return GLS_NONE;
  159. outVal = __glsMalloc(inByteCount);
  160. if (!outVal) __glsReader_raiseError(inoutReader, GLS_OUT_OF_MEMORY);
  161. return outVal;
  162. }
  163. GLvoid* __glsReader_allocFeedbackBuf(
  164. __GLSreader *inoutReader, size_t inByteCount
  165. ) {
  166. GLvoid *outVal;
  167. if (inoutReader->error) return GLS_NONE;
  168. outVal = __glsContext_allocFeedbackBuf(__GLS_CONTEXT, inByteCount);
  169. if (!outVal) __glsReader_raiseError(inoutReader, GLS_OUT_OF_MEMORY);
  170. return outVal;
  171. }
  172. GLvoid* __glsReader_allocSelectBuf(
  173. __GLSreader *inoutReader, size_t inByteCount
  174. ) {
  175. GLvoid *outVal;
  176. if (inoutReader->error) return GLS_NONE;
  177. outVal = __glsContext_allocSelectBuf(__GLS_CONTEXT, inByteCount);
  178. if (!outVal) __glsReader_raiseError(inoutReader, GLS_OUT_OF_MEMORY);
  179. return outVal;
  180. }
  181. #if __GL_EXT_vertex_array
  182. GLvoid* __glsReader_allocVertexArrayBuf(
  183. __GLSreader *inoutReader, GLSopcode inOpcode, size_t inByteCount
  184. ) {
  185. GLvoid *outVal;
  186. if (inoutReader->error) return GLS_NONE;
  187. outVal = __glsContext_allocVertexArrayBuf(
  188. __GLS_CONTEXT, inOpcode, inByteCount
  189. );
  190. if (!outVal) __glsReader_raiseError(inoutReader, GLS_OUT_OF_MEMORY);
  191. return outVal;
  192. }
  193. #endif /* __GL_EXT_vertex_array */
  194. void __glsReader_call(__GLSreader *inoutReader) {
  195. GLboolean callSave;
  196. __GLScontext *const ctx = __GLS_CONTEXT;
  197. callSave = ctx->contextCall;
  198. ctx->contextCall = GL_FALSE;
  199. while (inoutReader->type != GLS_NONE) {
  200. #ifndef __GLS_PLATFORM_WIN32
  201. // DrewB
  202. ctx->dispatchDecode_bin[GLS_OP_glsBeginGLS](
  203. (GLubyte *)&inoutReader->version
  204. );
  205. #else
  206. ctx->dispatchDecode_bin[GLS_OP_glsBeginGLS](
  207. ctx, (GLubyte *)&inoutReader->version
  208. );
  209. #endif
  210. if (inoutReader->type == GLS_TEXT) {
  211. if (!__glsReader_call_text(inoutReader)) break;
  212. inoutReader->readHead = inoutReader->readPtr;
  213. __GLS_GET_SPACE(inoutReader);
  214. } else if (inoutReader->type == __GLS_BINARY_SWAP0) {
  215. if (!__glsReader_call_bin(inoutReader)) break;
  216. inoutReader->readHead = inoutReader->readPtr;
  217. } else {
  218. if (!__glsReader_call_bin_swap(inoutReader)) break;
  219. inoutReader->readHead = inoutReader->readPtr;
  220. }
  221. #ifndef __GLS_PLATFORM_WIN32
  222. // DrewB
  223. ctx->dispatchDecode_bin[GLS_OP_glsEndGLS](GLS_NONE);
  224. #else
  225. ctx->dispatchDecode_bin[GLS_OP_glsEndGLS](ctx, GLS_NONE);
  226. #endif
  227. inoutReader->type = __glsReader_readBeginGLS_bin(
  228. inoutReader, &inoutReader->version
  229. );
  230. if (inoutReader->type == GLS_NONE) {
  231. inoutReader->type = __glsReader_readBeginGLS_text(
  232. inoutReader, &inoutReader->version
  233. );
  234. }
  235. if (inoutReader->type == GLS_NONE) {
  236. inoutReader->readPtr = inoutReader->readHead;
  237. }
  238. inoutReader->readHead = GLS_NONE;
  239. }
  240. ctx->contextCall = callSave;
  241. }
  242. __GLSreader* __glsReader_final(__GLSreader *inoutReader) {
  243. if (inoutReader && inoutReader->stream) {
  244. const ptrdiff_t excess = inoutReader->readTail - inoutReader->readPtr;
  245. if (excess > 0) {
  246. if (
  247. (
  248. !inoutReader->stream->channel ||
  249. fseek(
  250. inoutReader->stream->channel,
  251. -1 * (long)excess,
  252. SEEK_CUR
  253. )
  254. ) &&
  255. __GLS_CONTEXT->unreadFunc
  256. ) {
  257. __GLS_CONTEXT->unreadFunc(
  258. (size_t)excess, inoutReader->readPtr
  259. );
  260. }
  261. }
  262. free(inoutReader->buf);
  263. }
  264. return GLS_NONE;
  265. }
  266. GLboolean __glsReader_fillBuf(
  267. __GLSreader *inoutReader, size_t inMinBytes, GLboolean inRealign
  268. ) {
  269. FILE *channel;
  270. size_t keepBytes, needBytes, padBytes, unreadBytes;
  271. GLubyte *ptr, *readHead;
  272. if (!inoutReader->readPtr || !inoutReader->stream) return GL_FALSE;
  273. readHead = (
  274. inoutReader->readHead ? inoutReader->readHead : inoutReader->readPtr
  275. );
  276. keepBytes = (size_t)((ULONG_PTR)(inoutReader->readPtr - readHead));
  277. unreadBytes = (size_t)((ULONG_PTR)(inoutReader->readTail - inoutReader->readPtr));
  278. if (inRealign) {
  279. padBytes = (size_t)((ULONG_PTR)(readHead - inoutReader->buf) & (__GLS_MAX_ALIGN_BYTES - 4));
  280. } else if (keepBytes % __GLS_MAX_ALIGN_BYTES) {
  281. padBytes = __GLS_MAX_ALIGN_BYTES - keepBytes % __GLS_MAX_ALIGN_BYTES;
  282. } else {
  283. padBytes = 0;
  284. }
  285. needBytes = padBytes + keepBytes + __GLS_MAX(inMinBytes, unreadBytes);
  286. if (needBytes > inoutReader->bufSize) {
  287. GLubyte *const buf = __glsMalloc(needBytes);
  288. if (!buf) goto eos;
  289. ptr = buf + padBytes;
  290. while (readHead < inoutReader->readTail) *ptr++ = *readHead++;
  291. free(inoutReader->buf);
  292. inoutReader->buf = buf;
  293. inoutReader->bufSize = needBytes;
  294. } else {
  295. ptr = inoutReader->buf + padBytes;
  296. if (ptr != readHead) memmove(ptr, readHead, keepBytes + unreadBytes);
  297. }
  298. readHead = inoutReader->buf + padBytes;
  299. if (inoutReader->readHead) inoutReader->readHead = readHead;
  300. inoutReader->readPtr = readHead + keepBytes;
  301. inoutReader->readTail = inoutReader->readPtr + unreadBytes;
  302. channel = inoutReader->stream->channel;
  303. for (;;) {
  304. if (
  305. (size_t)(inoutReader->readTail - inoutReader->readPtr) >=
  306. inMinBytes
  307. ) {
  308. return GL_TRUE;
  309. }
  310. ptr = inoutReader->readTail;
  311. if (channel) {
  312. inoutReader->readTail += fread(
  313. ptr,
  314. 1,
  315. (size_t)((ULONG_PTR)(inoutReader->buf + inoutReader->bufSize - ptr)),
  316. channel
  317. );
  318. if (ferror(channel)) {
  319. __GLS_RAISE_ERROR(GLS_STREAM_READ_ERROR);
  320. clearerr(channel);
  321. }
  322. } else {
  323. inoutReader->readTail += inoutReader->stream->readFunc(
  324. (size_t)((ULONG_PTR)(inoutReader->buf + inoutReader->bufSize - ptr)), ptr
  325. );
  326. }
  327. if (inoutReader->readTail <= ptr) break;
  328. }
  329. eos:
  330. inoutReader->readHead = GLS_NONE;
  331. inoutReader->readPtr = GLS_NONE;
  332. inoutReader->readTail = GLS_NONE;
  333. return GL_FALSE;
  334. }
  335. __GLSreader* __glsReader_init_array(
  336. __GLSreader *outReader, const GLubyte *inArray, size_t inCount
  337. ) {
  338. memset(outReader, 0, sizeof(__GLSreader));
  339. outReader->buf = (GLubyte *)inArray;
  340. outReader->bufSize = inCount;
  341. outReader->readPtr = outReader->buf;
  342. outReader->readTail = outReader->buf + inCount;
  343. return outReader;
  344. }
  345. __GLSreader* __glsReader_init_stream(
  346. __GLSreader *outReader, const __GLSreadStream *inStream, size_t inBufSize
  347. ) {
  348. memset(outReader, 0, sizeof(__GLSreader));
  349. outReader->stream = inStream;
  350. outReader->buf = __glsMalloc(inBufSize);
  351. if (!outReader->buf) return __glsReader_final(outReader);
  352. outReader->bufSize = inBufSize;
  353. outReader->readPtr = outReader->buf;
  354. outReader->readTail = outReader->buf;
  355. outReader->readHead = outReader->readPtr;
  356. outReader->type = __glsReader_readBeginGLS_bin(
  357. outReader, &outReader->version
  358. );
  359. if (outReader->type == GLS_NONE) {
  360. outReader->type = __glsReader_readBeginGLS_text(
  361. outReader, &outReader->version
  362. );
  363. }
  364. if (outReader->type == GLS_NONE) {
  365. outReader->readPtr = outReader->readHead;
  366. return __glsReader_final(outReader);
  367. }
  368. outReader->readHead = GLS_NONE;
  369. return outReader;
  370. }
  371. void __glsReader_raiseError(__GLSreader *inoutReader, GLSenum inError) {
  372. if (!inoutReader->error) inoutReader->error = inError;
  373. }