Leaked source code of windows server 2003
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.

477 lines
11 KiB

  1. /*
  2. * Adobe Universal Font Library
  3. *
  4. * Copyright (c) 1996 Adobe Systems Inc.
  5. * All Rights Reserved
  6. *
  7. * UFLStrm.c
  8. *
  9. * UTL Output Stream Implementation
  10. *
  11. *
  12. * $Header:
  13. */
  14. /* -------------------------------------------------------------------------
  15. Header Includes
  16. --------------------------------------------------------------------------- */
  17. #include "UFLCnfig.h"
  18. #include "UFLPriv.h"
  19. #include "UFLMem.h"
  20. #include "UFLErr.h"
  21. #include "UFLStrm.h"
  22. #include "UFLStd.h"
  23. /* ---------------------------------------------------------------------------
  24. Constants
  25. --------------------------------------------------------------------------- */
  26. #define kEOLSpacing 60
  27. /* ---------------------------------------------------------------------------
  28. Global Variables
  29. --------------------------------------------------------------------------- */
  30. static char fHexBytes[16] = { '0', '1', '2', '3',
  31. '4', '5', '6', '7',
  32. '8', '9', 'a', 'b',
  33. 'c', 'd', 'e', 'f' };
  34. /* ---------------------------------------------------------------------------
  35. Implementation
  36. --------------------------------------------------------------------------- */
  37. /* ---------------------------------------------------------------------------
  38. Function UFLOutStream
  39. Constructor of the object.
  40. --------------------------------------------------------------------------- */
  41. UFLHANDLE
  42. StrmInit(
  43. const UFLMemObj *pMem,
  44. const UFLStream *stream,
  45. const UFLBool outputAscii
  46. )
  47. {
  48. UFLOutStream *pOut;
  49. pOut = (UFLOutStream *)UFLNewPtr( pMem, sizeof(UFLOutStream) );
  50. if ( pOut )
  51. {
  52. pOut->pMem = pMem;
  53. pOut->pStream = stream;
  54. pOut->flOutputAscii = outputAscii;
  55. pOut->lAddEOL = 0;
  56. }
  57. return (UFLHANDLE)pOut;
  58. }
  59. void
  60. StrmCleanUp(
  61. UFLHANDLE h
  62. )
  63. {
  64. UFLDeletePtr( ((UFLOutStream *)h)->pMem, h );
  65. }
  66. UFLErrCode
  67. StrmPutBytes (
  68. const UFLHANDLE h,
  69. const char *data,
  70. const UFLsize_t len,
  71. const UFLBool bAscii
  72. )
  73. {
  74. UFLsize_t cb = len;
  75. long selector;
  76. UFLOutStream *pOut = (UFLOutStream *)h;
  77. /* If we can output binary data then simply send out the data */
  78. if ( StrmCanOutputBinary(h) )
  79. selector = kUFLStreamPut;
  80. else /* otherwise, if the data is binary, request the stream to convert the data to the transport protocol */
  81. selector = ( bAscii ) ? kUFLStreamPut : kUFLStreamPutBinary;
  82. pOut->pStream->put( (UFLStream*)pOut->pStream, selector, (void*)data, &cb );
  83. if ( cb != (unsigned int)len )
  84. return kErrOutput;
  85. else return kNoErr;
  86. }
  87. UFLErrCode
  88. StrmPutAsciiHex(
  89. const UFLHANDLE h,
  90. const char *data,
  91. const unsigned long len
  92. )
  93. {
  94. unsigned long byteCount = 0;
  95. unsigned char *c = (unsigned char*)data, tmp, put[2];
  96. UFLErrCode retVal = kNoErr;
  97. UFLOutStream *pOut = (UFLOutStream *)h;
  98. char nullStr[] = "\0\0"; // An empty/Null string.
  99. while ( byteCount < len )
  100. {
  101. tmp = *c++;
  102. put[0] = fHexBytes[(tmp >> 4) & 0x0f];
  103. put[1] = fHexBytes[tmp & 0x0f];
  104. if ( (retVal = StrmPutBytes( h, (const char*)put, 2, 1 ) ) != kNoErr )
  105. {
  106. break;
  107. }
  108. pOut->lAddEOL += 2;
  109. if ( pOut->lAddEOL == kEOLSpacing )
  110. {
  111. if ( (retVal = StrmPutStringEOL( h, nullStr )) != kNoErr )
  112. {
  113. break;
  114. }
  115. }
  116. ++byteCount;
  117. }
  118. return retVal;
  119. }
  120. UFLErrCode
  121. StrmPutWordAsciiHex(
  122. const UFLHANDLE h,
  123. const unsigned short wData
  124. )
  125. {
  126. unsigned char tmp, put[5];
  127. UFLErrCode retVal;
  128. UFLOutStream *pOut = (UFLOutStream *)h;
  129. StrmPutString(h, "<");
  130. tmp = (unsigned char) GET_HIBYTE(wData);
  131. put[0] = fHexBytes[(tmp >> 4) & 0x0f];
  132. put[1] = fHexBytes[tmp & 0x0f];
  133. tmp = (unsigned char) GET_LOBYTE(wData);
  134. put[2] = fHexBytes[(tmp >> 4) & 0x0f];
  135. put[3] = fHexBytes[tmp & 0x0f];
  136. retVal = StrmPutBytes( h, (const char*)put, 4, 1 ); //last 1 == use ASCII format
  137. StrmPutString(h, ">");
  138. return retVal;
  139. }
  140. UFLErrCode
  141. StrmPutString(
  142. const UFLHANDLE h,
  143. const char *s
  144. )
  145. {
  146. if ( s )
  147. {
  148. if ( *s )
  149. return StrmPutBytes( h, s, UFLstrlen(s), 1 );
  150. else
  151. return kNoErr;
  152. }
  153. else return kErrInvalidParam;
  154. }
  155. UFLErrCode
  156. StrmPutStringEOL(
  157. const UFLHANDLE h,
  158. const char *s
  159. )
  160. {
  161. UFLErrCode retVal = kNoErr;
  162. #ifdef WIN_ENV
  163. static char c[2] = { kWinLineEnd, kLineEnd };
  164. #else
  165. static char c[1] = { kLineEnd };
  166. #endif
  167. if ( s == nil )
  168. return kErrInvalidParam;
  169. if ( *s )
  170. retVal = StrmPutString( h, s );
  171. if ( retVal == kNoErr ) {
  172. ((UFLOutStream *)h)->lAddEOL = 0; /* Initialize number of bytes in a line to 0 */
  173. #ifdef WIN_ENV
  174. retVal = StrmPutBytes( h, c, 2, 1 ); /* lfcr that the user sees */
  175. #else
  176. retVal = StrmPutBytes( h, c, 1, 1 );
  177. #endif
  178. }
  179. return retVal;
  180. }
  181. UFLErrCode
  182. StrmPutStringBinary(
  183. const UFLHANDLE h,
  184. const char *data,
  185. const unsigned long len
  186. )
  187. {
  188. char buf[128], c;
  189. char *pSrc, *pDest;
  190. short maxBuf, bufSize;
  191. unsigned long count;
  192. UFLErrCode retVal = kNoErr;
  193. if ( data == nil || len == 0 )
  194. return kNoErr;
  195. pSrc = (char*) data;
  196. maxBuf = sizeof( buf );
  197. count = (unsigned long) len;
  198. while ( count && retVal == kNoErr )
  199. {
  200. /* copy data to temp buffer */
  201. for ( pDest = (char*)buf, bufSize = 0; count && bufSize < maxBuf -1; )
  202. {
  203. c = *pSrc++;
  204. if ( ( c == '(' ) || ( c == ')' ) || ( c == '\\' ) ) { /* escape of those characters */
  205. *pDest++ = '\\' ; /* by preceding '\' */
  206. bufSize++;
  207. }
  208. *pDest++ = c; /* Add the byte itself */
  209. bufSize++;
  210. count--;
  211. }
  212. /* Send the escape data */
  213. if ( bufSize )
  214. retVal = StrmPutBytes( h, buf, bufSize, 0 );
  215. }
  216. return retVal;
  217. }
  218. UFLErrCode
  219. StrmPutInt(
  220. const UFLHANDLE h,
  221. const long int i
  222. )
  223. {
  224. char is[11]; /* One bigger than format */
  225. UFLsprintf((char *)is, CCHOF(is), "%ld", i);
  226. return StrmPutString( h, is );
  227. }
  228. static long convFract[] =
  229. {
  230. 65536L,
  231. 6553L,
  232. 655L,
  233. 66L,
  234. 6L
  235. };
  236. /* Convert a Fixed to a c string */
  237. static void Fixed2CString(
  238. UFLFixed f,
  239. char *s,
  240. short precision,
  241. char skipTrailSpace
  242. )
  243. {
  244. char u[12];
  245. char *t;
  246. short v;
  247. char sign;
  248. long fracPrec = (precision <= 4) ? convFract[precision] : 0L;
  249. if ((sign = f < 0) != 0)
  250. f = -f;
  251. /* If f started out as fixedMax or -fixedMax, the precision adjustment puts it
  252. out of bounds. Reset it correctly. */
  253. if (f >= 0x7FFF7FFF)
  254. f =(UFLFixed)0x7fffffff;
  255. else
  256. f += (fracPrec + 1) >> 1;
  257. v = (short)(f >> 16);
  258. f &= 0x0000ffff;
  259. if (sign && (v || f >= fracPrec))
  260. *s++ = '-';
  261. t = u;
  262. do
  263. {
  264. *t++ = v % 10 + '0';
  265. v /= 10;
  266. } while (v);
  267. for (; t > u;)
  268. *s++ = *--t;
  269. if (f >= fracPrec)
  270. {
  271. *s++ = '.';
  272. for (v = precision; v-- && f;)
  273. {
  274. f = (f << 3) + (f << 1);
  275. *s++ = (char)((f >> 16) + '0');
  276. f &= 0x0000ffff;
  277. }
  278. for (; *--s == '0';)
  279. ;
  280. if (*s != '.')
  281. s++;
  282. }
  283. if ( !skipTrailSpace )
  284. *s++ = ' ';
  285. *s = '\0';
  286. }
  287. UFLErrCode
  288. StrmPutFixed(
  289. const UFLHANDLE h,
  290. const UFLFixed fixed
  291. )
  292. {
  293. char str[32];
  294. Fixed2CString( fixed, str, 4, 0 );
  295. return StrmPutString( h, str );
  296. }
  297. UFLErrCode
  298. StrmPutMatrix(
  299. const UFLHANDLE h,
  300. const UFLFixedMatrix *matrix,
  301. const UFLBool skipEF
  302. )
  303. {
  304. UFLErrCode retVal;
  305. retVal = StrmPutString( h, "[" );
  306. if ( retVal == kNoErr )
  307. retVal = StrmPutFixed( h, matrix->a );
  308. if ( retVal == kNoErr )
  309. retVal = StrmPutFixed( h, matrix->b );
  310. if ( retVal == kNoErr )
  311. retVal = StrmPutFixed( h, matrix->c );
  312. if ( retVal == kNoErr )
  313. retVal = StrmPutFixed( h, matrix->d );
  314. if ( 0 == skipEF )
  315. {
  316. if ( retVal == kNoErr )
  317. retVal = StrmPutFixed( h, matrix->e );
  318. if ( retVal == kNoErr )
  319. retVal = StrmPutFixed( h, matrix->f );
  320. }
  321. if ( retVal == kNoErr )
  322. retVal = StrmPutString( h, "] " );
  323. return retVal;
  324. }
  325. UFLErrCode
  326. StrmPutAscii85(
  327. const UFLHANDLE h,
  328. const char *data,
  329. const unsigned long len
  330. )
  331. {
  332. char *cptr;
  333. short bCount;
  334. unsigned long val;
  335. UFLErrCode retVal = kNoErr;
  336. UFLOutStream *pOut = (UFLOutStream *)h;
  337. unsigned long i;
  338. /* encode the initial 4-tuples */
  339. cptr = (char *)data;
  340. val = 0UL;
  341. bCount = 0;
  342. pOut->lAddEOL = 0;
  343. for ( i = 0; retVal == kNoErr && i < len; i++ )
  344. {
  345. val <<= 8;
  346. val |= (unsigned char)*cptr++;
  347. if ( bCount == 3 )
  348. {
  349. retVal = Output85( h, val, 5 );
  350. val = 0UL;
  351. bCount = 0;
  352. }
  353. else
  354. {
  355. bCount ++;
  356. }
  357. }
  358. /* now do the last partial 4-tuple -- if there is one */
  359. /* see the Red Book spec for the rules on how this is done */
  360. if ( retVal == kNoErr && bCount > 0 )
  361. {
  362. short dex;
  363. short rem = 4 - bCount; /* count the remaining bytes */
  364. for ( dex = 0; dex < rem; dex ++ ) /* shift left for each of them */
  365. val <<= 8; /* (equivalent to adding in ZERO's)*/
  366. retVal = Output85( h, val, (short)(bCount + 1) ); /* output only meaningful bytes + 1 */
  367. }
  368. return retVal;
  369. }
  370. UFLErrCode
  371. Output85(
  372. const UFLHANDLE h,
  373. unsigned long inWord,
  374. short nBytes
  375. )
  376. {
  377. UFLErrCode retVal = kNoErr;
  378. unsigned char outChar;
  379. UFLOutStream *pOut = (UFLOutStream *)h;
  380. char nullStr[] = "\0\0"; // An empty/Null string.
  381. if ( (inWord == 0UL) && (nBytes == 5) )
  382. {
  383. outChar = 'z';
  384. StrmPutBytes( h, (const char*)&outChar, 1, 1 );
  385. pOut->lAddEOL++;
  386. }
  387. else
  388. {
  389. unsigned long power;
  390. short count;
  391. power = 52200625UL; // 85 ^ 4
  392. for ( count = 0; retVal == kNoErr && count < nBytes; count ++)
  393. {
  394. outChar = (unsigned char)( (unsigned long)(inWord / power) + (unsigned long)'!' );
  395. retVal = StrmPutBytes( h, (const char*)&outChar, 1, 1 );
  396. pOut->lAddEOL++;
  397. if ( count < 4 )
  398. {
  399. inWord %= power;
  400. power /= 85;
  401. }
  402. }
  403. }
  404. if ( pOut->lAddEOL >= kEOLSpacing )
  405. {
  406. retVal = StrmPutStringEOL( h, nullStr );
  407. }
  408. return retVal;
  409. }