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