1 /************************************************************************/
2 /* */
3 /* Simple io streams, recursive use for hexadecimal data. */
4 /* */
5 /* Do not forget to manually add the '>' at the end if you use these */
6 /* streams in conjuntion with '/ASCIIHexDecode filter' in PostScript. */
7 /* */
8 /************************************************************************/
9
10 # include "appUtilConfig.h"
11
12 # include <stdlib.h>
13
14 # include "sioHex.h"
15 # include <appDebugon.h>
16
17
18 /************************************************************************/
19 /* */
20 /* For Hexadecimal decoding. */
21 /* */
22 /************************************************************************/
23
24 static const unsigned char SioHexDigitsU[]= "0123456789ABCDEF";
25 static const unsigned char SioHexDigitsL[]= "0123456789abcdef";
26 static unsigned char SioHexIndices[256];
27
28 /************************************************************************/
29 /* */
30 /* Exchange of hexed binary data. */
31 /* */
32 /************************************************************************/
33
sioInHexClose(void * voids)34 static int sioInHexClose( void * voids )
35 { return 0; }
36
sioInHexReadBytes(void * voidsis,unsigned char * buffer,unsigned int count)37 static int sioInHexReadBytes( void * voidsis,
38 unsigned char * buffer,
39 unsigned int count )
40 {
41 SimpleInputStream * sis= (SimpleInputStream *)voidsis;
42 int done= 0;
43
44 while( done < count )
45 {
46 int c;
47
48 c= sioInGetByte( sis );
49
50 while( c == ' ' || c == '\r' || c == '\n' )
51 { c= sioInGetByte( sis ); }
52
53 if ( c == EOF )
54 { return done; }
55 else{
56 if ( SioHexIndices[c] == 0xff )
57 { sioInUngetLastRead( sis ); return done; }
58 else{ buffer[0]= SioHexIndices[c]; }
59 }
60
61 c= sioInGetByte( sis );
62
63 buffer[0] *= 16;
64
65 while( c == ' ' || c == '\r' || c == '\n' )
66 { c= sioInGetByte( sis ); }
67
68 if ( c == EOF )
69 { LDEB(c); return -1; }
70
71 if ( SioHexIndices[c] == 0xff )
72 { CDEB(c); return -1; }
73 else{ buffer[0] += SioHexIndices[c]; }
74
75 buffer++; done++;
76 }
77
78 return done;
79 }
80
81
sioInHexOpen(SimpleInputStream * sisHex)82 SimpleInputStream * sioInHexOpen( SimpleInputStream * sisHex )
83 {
84 SimpleInputStream * sis;
85
86 if ( SioHexIndices[0] == 0 )
87 {
88 unsigned int i;
89
90 for ( i= 0; i < sizeof(SioHexIndices); i++ )
91 { SioHexIndices[i]= 0xff; }
92
93 i= 0;
94 while( SioHexDigitsU[i] )
95 { SioHexIndices[SioHexDigitsU[i]]= i; i++; }
96 i= 0;
97 while( SioHexDigitsL[i] )
98 { SioHexIndices[SioHexDigitsL[i]]= i; i++; }
99 }
100
101 sis= sioInOpen( (void *)sisHex, sioInHexReadBytes, sioInHexClose );
102
103 if ( ! sis )
104 { XDEB(sis); return (SimpleInputStream *)0; }
105
106 return sis;
107 }
108
109 /************************************************************************/
110 /* */
111 /* Output. */
112 /* */
113 /************************************************************************/
114
115 typedef struct HexOutputStream
116 {
117 SimpleOutputStream * hosSosHex;
118 int hosWide;
119 int hosLastNl;
120 int hosColumn;
121 } HexOutputStream;
122
sioOutHexClose(void * voidhos)123 static int sioOutHexClose( void * voidhos )
124 {
125 int rval= 0;
126 HexOutputStream * hos= (HexOutputStream *)voidhos;
127 SimpleOutputStream * sos= hos->hosSosHex;
128
129 if ( hos->hosWide > 0 && hos->hosLastNl && hos->hosColumn > 0 )
130 {
131 if ( sioOutPutByte( '\n', sos ) < 0 )
132 { rval= -1; }
133 hos->hosColumn= 0;
134 }
135
136 free( hos );
137
138 return rval;
139 }
140
sioOutHexWriteBytes(void * voidhos,const unsigned char * buffer,int count)141 static int sioOutHexWriteBytes( void * voidhos,
142 const unsigned char * buffer,
143 int count )
144 {
145 HexOutputStream * hos= (HexOutputStream *)voidhos;
146 SimpleOutputStream * sos= hos->hosSosHex;
147 int done= 0;
148
149 while( done < count )
150 {
151 if ( hos->hosWide > 0 && hos->hosColumn >= hos->hosWide )
152 {
153 if ( sioOutPutByte( '\n', sos ) < 0 )
154 { return -1; }
155 hos->hosColumn= 0;
156 }
157
158 if ( sioOutPutByte( SioHexDigitsL[ ( (*buffer) >> 4 ) & 0x0f ], sos ) < 0 )
159 { return -1; }
160 if ( sioOutPutByte( SioHexDigitsL[ ( (*buffer) >> 0 ) & 0x0f ], sos ) < 0 )
161 { return -1; }
162
163 if ( hos->hosWide > 0 )
164 { hos->hosColumn += 2; }
165
166 buffer++; done++;
167 }
168
169 return count;
170 }
171
sioOutHexOpenFolded(SimpleOutputStream * sosHex,int wide,int lastNl)172 SimpleOutputStream * sioOutHexOpenFolded(
173 SimpleOutputStream * sosHex,
174 int wide,
175 int lastNl )
176 {
177 HexOutputStream * hos= (HexOutputStream *)malloc( sizeof(HexOutputStream) );
178 SimpleOutputStream * sos;
179
180 if ( ! hos )
181 { XDEB(hos); return (SimpleOutputStream *)0; }
182
183 hos->hosSosHex= sosHex;
184 hos->hosWide= wide;
185 hos->hosLastNl= lastNl;
186 hos->hosColumn= 0;
187
188 sos= sioOutOpen( (void *)hos, sioOutHexWriteBytes, sioOutHexClose );
189
190 if ( ! sos )
191 { XDEB(sos); free( hos ); return (SimpleOutputStream *)0; }
192
193 return sos;
194 }
195
sioOutHexOpen(SimpleOutputStream * sosHex)196 SimpleOutputStream * sioOutHexOpen( SimpleOutputStream * sosHex )
197 {
198 return sioOutHexOpenFolded( sosHex, 0, 0 );
199 }
200
201