|
|
/*
* Adobe Universal Font Library * * Copyright (c) 1996 Adobe Systems Inc. * All Rights Reserved * * UFLStrm.c * * UTL Output Stream Implementation * * * $Header: */
/* -------------------------------------------------------------------------
Header Includes --------------------------------------------------------------------------- */ #include "UFLCnfig.h"
#include "UFLPriv.h"
#include "UFLMem.h"
#include "UFLErr.h"
#include "UFLStrm.h"
#include "UFLStd.h"
/* ---------------------------------------------------------------------------
Constants --------------------------------------------------------------------------- */ #define kEOLSpacing 60
/* ---------------------------------------------------------------------------
Global Variables --------------------------------------------------------------------------- */ static char fHexBytes[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
/* ---------------------------------------------------------------------------
Implementation --------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------
Function UFLOutStream
Constructor of the object.
--------------------------------------------------------------------------- */
UFLHANDLE StrmInit( const UFLMemObj *pMem, const UFLStream *stream, const UFLBool outputAscii ) { UFLOutStream *pOut;
pOut = (UFLOutStream *)UFLNewPtr( pMem, sizeof(UFLOutStream) ); if ( pOut ) { pOut->pMem = pMem; pOut->pStream = stream; pOut->flOutputAscii = outputAscii; pOut->lAddEOL = 0; }
return (UFLHANDLE)pOut; }
void StrmCleanUp( UFLHANDLE h ) { UFLDeletePtr( ((UFLOutStream *)h)->pMem, h ); }
UFLErrCode StrmPutBytes ( const UFLHANDLE h, const char *data, const UFLsize_t len, const UFLBool bAscii ) { UFLsize_t cb = len; long selector; UFLOutStream *pOut = (UFLOutStream *)h;
/* If we can output binary data then simply send out the data */ if ( StrmCanOutputBinary(h) ) selector = kUFLStreamPut; else /* otherwise, if the data is binary, request the stream to convert the data to the transport protocol */ selector = ( bAscii ) ? kUFLStreamPut : kUFLStreamPutBinary;
pOut->pStream->put( (UFLStream*)pOut->pStream, selector, (void*)data, &cb ); if ( cb != (unsigned int)len ) return kErrOutput; else return kNoErr; }
UFLErrCode StrmPutAsciiHex( const UFLHANDLE h, const char *data, const unsigned long len ) { unsigned long byteCount = 0; unsigned char *c = (unsigned char*)data, tmp, put[2]; UFLErrCode retVal = kNoErr; UFLOutStream *pOut = (UFLOutStream *)h; char nullStr[] = "\0\0"; // An empty/Null string.
while ( byteCount < len ) { tmp = *c++; put[0] = fHexBytes[(tmp >> 4) & 0x0f]; put[1] = fHexBytes[tmp & 0x0f];
if ( (retVal = StrmPutBytes( h, (const char*)put, 2, 1 ) ) != kNoErr ) { break; }
pOut->lAddEOL += 2; if ( pOut->lAddEOL == kEOLSpacing ) { if ( (retVal = StrmPutStringEOL( h, nullStr )) != kNoErr ) { break; } } ++byteCount; } return retVal; }
UFLErrCode StrmPutWordAsciiHex( const UFLHANDLE h, const unsigned short wData ) { unsigned char tmp, put[5]; UFLErrCode retVal; UFLOutStream *pOut = (UFLOutStream *)h;
StrmPutString(h, "<");
tmp = (unsigned char) GET_HIBYTE(wData); put[0] = fHexBytes[(tmp >> 4) & 0x0f]; put[1] = fHexBytes[tmp & 0x0f];
tmp = (unsigned char) GET_LOBYTE(wData); put[2] = fHexBytes[(tmp >> 4) & 0x0f]; put[3] = fHexBytes[tmp & 0x0f];
retVal = StrmPutBytes( h, (const char*)put, 4, 1 ); //last 1 == use ASCII format
StrmPutString(h, ">");
return retVal; }
UFLErrCode StrmPutString( const UFLHANDLE h, const char *s ) { if ( s ) { if ( *s ) return StrmPutBytes( h, s, UFLstrlen(s), 1 ); else return kNoErr; } else return kErrInvalidParam; }
UFLErrCode StrmPutStringEOL( const UFLHANDLE h, const char *s ) { UFLErrCode retVal = kNoErr; #ifdef WIN_ENV
static char c[2] = { kWinLineEnd, kLineEnd }; #else
static char c[1] = { kLineEnd }; #endif
if ( s == nil ) return kErrInvalidParam;
if ( *s ) retVal = StrmPutString( h, s );
if ( retVal == kNoErr ) { ((UFLOutStream *)h)->lAddEOL = 0; /* Initialize number of bytes in a line to 0 */ #ifdef WIN_ENV
retVal = StrmPutBytes( h, c, 2, 1 ); /* lfcr that the user sees */ #else
retVal = StrmPutBytes( h, c, 1, 1 ); #endif
}
return retVal; }
UFLErrCode StrmPutStringBinary( const UFLHANDLE h, const char *data, const unsigned long len ) { char buf[128], c; char *pSrc, *pDest; short maxBuf, bufSize; unsigned long count; UFLErrCode retVal = kNoErr;
if ( data == nil || len == 0 ) return kNoErr;
pSrc = (char*) data; maxBuf = sizeof( buf ); count = (unsigned long) len; while ( count && retVal == kNoErr ) { /* copy data to temp buffer */ for ( pDest = (char*)buf, bufSize = 0; count && bufSize < maxBuf -1; ) { c = *pSrc++; if ( ( c == '(' ) || ( c == ')' ) || ( c == '\\' ) ) { /* escape of those characters */ *pDest++ = '\\' ; /* by preceding '\' */ bufSize++; } *pDest++ = c; /* Add the byte itself */ bufSize++; count--; }
/* Send the escape data */ if ( bufSize ) retVal = StrmPutBytes( h, buf, bufSize, 0 ); } return retVal; }
UFLErrCode StrmPutInt( const UFLHANDLE h, const long int i ) { char is[11]; /* One bigger than format */
UFLsprintf((char *)is, CCHOF(is), "%ld", i); return StrmPutString( h, is ); }
static long convFract[] = { 65536L, 6553L, 655L, 66L, 6L };
/* Convert a Fixed to a c string */ static void Fixed2CString( UFLFixed f, char *s, short precision, char skipTrailSpace ) { char u[12]; char *t; short v; char sign; long fracPrec = (precision <= 4) ? convFract[precision] : 0L;
if ((sign = f < 0) != 0) f = -f;
/* If f started out as fixedMax or -fixedMax, the precision adjustment puts it
out of bounds. Reset it correctly. */ if (f >= 0x7FFF7FFF) f =(UFLFixed)0x7fffffff; else f += (fracPrec + 1) >> 1;
v = (short)(f >> 16); f &= 0x0000ffff; if (sign && (v || f >= fracPrec)) *s++ = '-';
t = u; do { *t++ = v % 10 + '0'; v /= 10; } while (v);
for (; t > u;) *s++ = *--t;
if (f >= fracPrec) { *s++ = '.'; for (v = precision; v-- && f;) { f = (f << 3) + (f << 1); *s++ = (char)((f >> 16) + '0'); f &= 0x0000ffff; } for (; *--s == '0';) ; if (*s != '.') s++; } if ( !skipTrailSpace ) *s++ = ' '; *s = '\0'; }
UFLErrCode StrmPutFixed( const UFLHANDLE h, const UFLFixed fixed ) { char str[32];
Fixed2CString( fixed, str, 4, 0 ); return StrmPutString( h, str ); }
UFLErrCode StrmPutMatrix( const UFLHANDLE h, const UFLFixedMatrix *matrix, const UFLBool skipEF ) { UFLErrCode retVal;
retVal = StrmPutString( h, "[" ); if ( retVal == kNoErr ) retVal = StrmPutFixed( h, matrix->a ); if ( retVal == kNoErr ) retVal = StrmPutFixed( h, matrix->b ); if ( retVal == kNoErr ) retVal = StrmPutFixed( h, matrix->c ); if ( retVal == kNoErr ) retVal = StrmPutFixed( h, matrix->d );
if ( 0 == skipEF ) { if ( retVal == kNoErr ) retVal = StrmPutFixed( h, matrix->e ); if ( retVal == kNoErr ) retVal = StrmPutFixed( h, matrix->f ); }
if ( retVal == kNoErr ) retVal = StrmPutString( h, "] " );
return retVal; }
UFLErrCode StrmPutAscii85( const UFLHANDLE h, const char *data, const unsigned long len ) { char *cptr; short bCount; unsigned long val; UFLErrCode retVal = kNoErr; UFLOutStream *pOut = (UFLOutStream *)h; unsigned long i;
/* encode the initial 4-tuples */ cptr = (char *)data; val = 0UL; bCount = 0; pOut->lAddEOL = 0; for ( i = 0; retVal == kNoErr && i < len; i++ ) { val <<= 8; val |= (unsigned char)*cptr++; if ( bCount == 3 ) { retVal = Output85( h, val, 5 ); val = 0UL; bCount = 0; } else { bCount ++; } }
/* now do the last partial 4-tuple -- if there is one */ /* see the Red Book spec for the rules on how this is done */ if ( retVal == kNoErr && bCount > 0 ) { short dex; short rem = 4 - bCount; /* count the remaining bytes */
for ( dex = 0; dex < rem; dex ++ ) /* shift left for each of them */ val <<= 8; /* (equivalent to adding in ZERO's)*/ retVal = Output85( h, val, (short)(bCount + 1) ); /* output only meaningful bytes + 1 */ }
return retVal; }
UFLErrCode Output85( const UFLHANDLE h, unsigned long inWord, short nBytes ) { UFLErrCode retVal = kNoErr; unsigned char outChar; UFLOutStream *pOut = (UFLOutStream *)h; char nullStr[] = "\0\0"; // An empty/Null string.
if ( (inWord == 0UL) && (nBytes == 5) ) { outChar = 'z'; StrmPutBytes( h, (const char*)&outChar, 1, 1 ); pOut->lAddEOL++; } else { unsigned long power; short count;
power = 52200625UL; // 85 ^ 4
for ( count = 0; retVal == kNoErr && count < nBytes; count ++) { outChar = (unsigned char)( (unsigned long)(inWord / power) + (unsigned long)'!' ); retVal = StrmPutBytes( h, (const char*)&outChar, 1, 1 ); pOut->lAddEOL++; if ( count < 4 ) { inWord %= power; power /= 85; } } } if ( pOut->lAddEOL >= kEOLSpacing ) { retVal = StrmPutStringEOL( h, nullStr ); }
return retVal; }
|