musrfit 1.10.0
mud_encode.c
Go to the documentation of this file.
1/*
2 * mud_encode.c -- encode/decode,
3 * Routines for converting encoding and byte order between the MUD standard and the
4 * local machine standard.
5 *
6 * Copyright (C) 1994 TRIUMF (Vancouver, Canada)
7 *
8 * Authors: T. Whidden, D. Arseneau, S. Daviel
9 *
10 * Released under the GNU LGPL - see http://www.gnu.org/licenses
11 *
12 * This program is free software; you can distribute it and/or modify it under
13 * the terms of the Lesser GNU General Public License as published by the Free
14 * Software Foundation; either version 2 of the License, or any later version.
15 * Accordingly, this program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 * or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public License
18 * for more details.
19 *
20 * Float conversions adapted from Sun RPC xdr_float.c, which is covered by a separate
21 * license (unrestricted use).
22 */
23
24#include "mud.h"
25
26
27void
28bdecode_2( void* b, void* p )
29{
30#ifdef MUD_BIG_ENDIAN
31 UINT16 i;
32 bcopy( b, &i, 2 );
33 i = _swap2bytes(i);
34 bcopy( &i, p, 2 );
35#else
36 bcopy( b, p, 2 );
37#endif /* MUD_BIG_ENDIAN */
38}
39
40void
41bencode_2( void* b, void* p )
42{
43#ifdef MUD_BIG_ENDIAN
44 UINT16 i;
45 bcopy( p, &i, 2 );
46#ifdef DEBUG
47 printf( "bencode_2: got %04X,", i );
48#endif
49 i = _swap2bytes(i);
50#ifdef DEBUG
51 printf( "coded %04X\n", i );
52#endif
53 bcopy( &i, b, 2 );
54#else
55 bcopy( p, b, 2 );
56#endif /* MUD_BIG_ENDIAN */
57}
58
59void
60bdecode_4( void* b,void* p )
61{
62#ifdef MUD_BIG_ENDIAN
63 UINT32 i;
64 bcopy( b, &i, 4 );
65 i = _swap4bytes(i);
66 bcopy( &i, p, 4 );
67#else
68 bcopy( b, p, 4 );
69#endif /* MUD_BIG_ENDIAN */
70}
71
72void
73bencode_4( void* b, void* p )
74{
75#ifdef MUD_BIG_ENDIAN
76 UINT32 i;
77 bcopy( p, &i, 4 );
78 i = _swap4bytes(i);
79 bcopy( &i, b, 4 );
80#else
81 bcopy( p, b, 4 );
82#endif /* MUD_BIG_ENDIAN */
83}
84
85void
86bdecode_8( void* b, void* p )
87{
88#ifdef MUD_BIG_ENDIAN
89 UINT32 i[2], i2[2];
90 bcopy( b, i, 8 );
91 i2[1] = _swap4bytes(i[0]);
92 i2[0] = _swap4bytes(i[1]);
93 bcopy( i2, p, 8 );
94#else
95 bcopy( b, p, 8 );
96#endif /* MUD_BIG_ENDIAN */
97}
98
99void
100bencode_8( void* b, void* p )
101{
102#ifdef MUD_BIG_ENDIAN
103 UINT32 i[2], i2[2];
104 bcopy( p, i, 8 );
105 i2[1] = _swap4bytes(i[0]);
106 i2[0] = _swap4bytes(i[1]);
107 bcopy( i2, b, 8 );
108#else
109 bcopy( p, b, 8 );
110#endif /* MUD_BIG_ENDIAN */
111}
112
113
114void
115decode_str( BUF* pB, char** ps )
116{
118
119#ifdef DEBUG
120 printf( "buf pos = %d\n", pB->pos );
121 printf( "decoding string length...\n" );
122#endif /* DEBUG */
123 bdecode_2( (void*)&(pB->buf[pB->pos]), (void*)&len );
124#ifdef DEBUG
125 printf( "string len %d\n", len );
126#endif /* DEBUG */
127 pB->pos += 2;
128 pB->size += 2;
129 if( *ps == NULL ) *ps = (char*)zalloc( len+1 );
130 strncpy( *ps, &pB->buf[pB->pos], len );
131 pB->pos += len;
132 pB->size += len;
133#ifdef DEBUG
134 printf( "string:\"%s\"\n", *ps );
135#endif /* DEBUG */
136}
137
138
139void
140encode_str( BUF* pB, char** ps )
141{
143
144 len = _strlen( *ps );
145 bencode_2( (void*)&pB->buf[pB->pos], (void*)&len );
146 pB->pos += 2;
147 pB->size += 2;
148 strncpy( &pB->buf[pB->pos], *ps, len );
149 pB->pos += len;
150 pB->size += len;
151}
152
153
154#ifndef VMS
155
156#ifdef MUD_LITTLE_ENDIAN
157struct ieee_single {
158 unsigned int mantissa2 : 16;
159 unsigned int mantissa1 : 7;
160 unsigned int exp : 8;
161 unsigned int sign : 1;
162};
163struct vax_single {
164 unsigned int mantissa1 : 7;
165 unsigned int exp : 8;
166 unsigned int sign : 1;
167 unsigned int mantissa2 : 16;
168};
169static struct sgl_limits {
170 struct vax_single s;
171 struct ieee_single ieee;
172} sgl_limits[2] = {
173 {{ 0x7f, 0xff, 0x0, 0xffff }, /* Max Vax */
174 { 0x0, 0x0, 0xff, 0x0 }}, /* Max IEEE */
175 {{ 0x0, 0x0, 0x0, 0x0 }, /* Min Vax */
176 { 0x0, 0x0, 0x0, 0x0 }} /* Min IEEE */
177};
178#else
180 unsigned int sign : 1;
181 unsigned int exp : 8;
182 unsigned int mantissa1 : 7;
183 unsigned int mantissa2 : 16;
184};
186 unsigned int mantissa2 : 16;
187 unsigned int sign : 1;
188 unsigned int exp : 8;
189 unsigned int mantissa1 : 7;
190};
191static struct sgl_limits {
192 struct vax_single s;
194} sgl_limits[2] = {
195 {{ 0xffff, 0x0, 0xff, 0x7f }, /* Max Vax */
196 { 0x0, 0xff, 0x0, 0x0 }}, /* Max IEEE */
197 {{ 0x0, 0x0, 0x0, 0x0 }, /* Min Vax */
198 { 0x0, 0x0, 0x0, 0x0 }} /* Min IEEE */
200#endif /* ENDIAN */
201
202#define VAX_SNG_BIAS 0x81
203#define IEEE_SNG_BIAS 0x7f
204
205#endif /* !VMS */
206
207void
208bencode_float( char* buf, float* fp )
209{
210#ifndef VMS
211 struct ieee_single is;
212 struct vax_single vs;
213 struct sgl_limits *lim;
214 int i;
215#endif /* !VMS */
216
217#ifdef VMS
218 bencode_4( buf, fp );
219#else
220 is = *((struct ieee_single*)fp);
221
222 for( i = 0, lim = sgl_limits;
223 i < sizeof(sgl_limits)/sizeof(struct sgl_limits);
224 i++, lim++)
225 {
226 if( ( is.mantissa1 == lim->ieee.mantissa1 ) &&
227 ( is.mantissa2 == lim->ieee.mantissa2 ) &&
228 ( is.exp == lim->ieee.exp ) )
229 {
230 vs = lim->s;
231 goto shipit;
232 }
233 }
234 vs.exp = is.exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
235 vs.mantissa2 = is.mantissa2;
236 vs.mantissa1 = is.mantissa1;
237shipit:
238 vs.sign = is.sign;
239 bencode_4( (void*)buf, (void*)&vs );
240#endif /* VMS */
241}
242
243void
244encode_float( BUF* pBuf, float* fp )
245{
246 bencode_float( &(pBuf->buf[pBuf->pos]), fp );
247 pBuf->pos += 4;
248 pBuf->size += 4;
249}
250
251void
252bdecode_float( char* buf, float* fp )
253{
254#ifndef VMS
255 struct ieee_single *isp;
256 struct vax_single vs;
257 struct sgl_limits *lim;
258 int i;
259#endif /* !VMS */
260
261#ifdef VMS
262 bdecode_4( (void*)buf, (void*)fp );
263#else
264 bdecode_4( (void*)buf, (void*)&vs );
265
266#ifdef DEBUG
267 printf( "man1:%d man2:%d exp:%d sign:%d\n",
268 vs.mantissa1, vs.mantissa2, vs.exp, vs.sign );
269#endif /* DEBUG */
270
271 isp = (struct ieee_single*)fp;
272 for( i = 0, lim = sgl_limits;
273 i < sizeof(sgl_limits)/sizeof(struct sgl_limits);
274 i++, lim++ )
275 {
276 if( ( vs.mantissa2 == lim->s.mantissa2 ) &&
277 ( vs.exp == lim->s.exp ) &&
278 ( vs.mantissa1 == lim->s.mantissa1 ) )
279 {
280 *isp = lim->ieee;
281 goto shipit;
282 }
283 }
284 isp->exp = vs.exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
285 isp->mantissa1 = vs.mantissa1;
286 isp->mantissa2 = vs.mantissa2;
287shipit:
288 isp->sign = vs.sign;
289#endif
290}
291
292void
293decode_float( BUF* pBuf, float* fp )
294{
295 bdecode_float( &(pBuf->buf[pBuf->pos]), fp );
296 pBuf->pos += 4;
297 pBuf->size += 4;
298}
299
300/*
301 * This routine works on Suns (Sky / 68000's) and Vaxen.
302 */
303
304#ifndef VMS
305
306#ifdef MUD_LITTLE_ENDIAN
307struct ieee_double {
308 unsigned int mantissa4 : 16;
309 unsigned int mantissa3 : 16;
310 unsigned int mantissa2 : 16;
311 unsigned int mantissa1 : 4;
312 unsigned int exp : 11;
313 unsigned int sign : 1;
314};
315struct vax_double {
316 unsigned int mantissa1 : 7;
317 unsigned int exp : 8;
318 unsigned int sign : 1;
319 unsigned int mantissa2 : 16;
320 unsigned int mantissa3 : 16;
321 unsigned int mantissa4 : 16;
322};
323static struct dbl_limits {
324 struct vax_double d;
325 struct ieee_double ieee;
326} dbl_limits[2] = {
327 {{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff }, /* Max Vax */
328 { 0x0, 0x0, 0x0, 0x0, 0x7ff, 0x0 }}, /* Max IEEE */
329 {{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* Min Vax */
330 { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }} /* Min IEEE */
331};
332#else
334 unsigned int sign : 1;
335 unsigned int exp : 11;
336 unsigned int mantissa1 : 4;
337 unsigned int mantissa2 : 16;
338 unsigned int mantissa3 : 16;
339 unsigned int mantissa4 : 16;
340};
342 unsigned int mantissa4 : 16;
343 unsigned int mantissa3 : 16;
344 unsigned int mantissa2 : 16;
345 unsigned int sign : 1;
346 unsigned int exp : 8;
347 unsigned int mantissa1 : 7;
348};
349static struct dbl_limits {
350 struct vax_double d;
352} dbl_limits[2] = {
353 {{ 0xffff, 0xffff, 0xffff, 0x0, 0xff, 0x7f }, /* Max Vax */
354 { 0x0, 0x7ff, 0x0, 0x0, 0x0, 0x0 }}, /* Max IEEE */
355 {{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* Min Vax */
356 { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }} /* Min IEEE */
358#endif /* ENDIAN */
359
360#define VAX_DBL_BIAS 0x81
361#define IEEE_DBL_BIAS 0x3ff
362#define MASK(nbits) ((1 << nbits) - 1)
363
364#endif /* !VMS */
365
366
367void
368bencode_double( char* buf, double* dp )
369{
370#ifndef VMS
371 struct ieee_double id;
372 struct vax_double vd;
373 register struct dbl_limits *lim;
374 int i;
375#endif /* !VMS */
376
377#ifdef VMS
378 bencode_8( buf, dp );
379#else
380 id = *((struct ieee_double*)dp);
381 for( i = 0, lim = dbl_limits;
382 i < sizeof(dbl_limits)/sizeof(struct dbl_limits);
383 i++, lim++)
384 {
385 if( ( id.mantissa2 == lim->ieee.mantissa2 ) &&
386 ( id.mantissa1 == lim->ieee.mantissa1 ) &&
387 ( id.mantissa3 == lim->ieee.mantissa3 ) &&
388 ( id.mantissa4 == lim->ieee.mantissa4 ) &&
389 ( id.exp == lim->ieee.exp ) )
390 {
391 vd = lim->d;
392 goto shipit;
393 }
394 }
395 vd.exp = id.exp - IEEE_DBL_BIAS + VAX_DBL_BIAS;
396 vd.mantissa1 = ( id.mantissa1 << 3 ) | (id.mantissa2 >> 13);
397 vd.mantissa2 = (id.mantissa2 << 3) | (id.mantissa3 >> 13);
398 vd.mantissa3 = (id.mantissa3 << 3) | (id.mantissa4 >> 13);
399 vd.mantissa4 = (id.mantissa4 << 3);
400shipit:
401 vd.sign = id.sign;
402 bencode_8( buf, &vd );
403#endif /* VMS */
404}
405
406void
407encode_double( BUF* pBuf, double* fp )
408{
409 bencode_double( &(pBuf->buf[pBuf->pos]), fp );
410 pBuf->pos += 8;
411 pBuf->size += 8;
412}
413
414void
415bdecode_double( char* buf, double* dp )
416{
417#ifndef VMS
418 struct ieee_double *idp;
419 struct vax_double vd;
420 register struct dbl_limits *lim;
421 int i;
422#endif /* !VMS */
423
424#ifdef VMS
425 bdecode_8( buf, dp );
426#else
427 bdecode_8( buf, &vd );
428 idp = (struct ieee_double*)dp;
429 for( i = 0, lim = dbl_limits;
430 i < sizeof(dbl_limits)/sizeof(struct dbl_limits);
431 i++, lim++)
432 {
433 if( ( vd.mantissa4 == lim->d.mantissa4 ) &&
434 ( vd.mantissa3 == lim->d.mantissa3 ) &&
435 ( vd.mantissa2 == lim->d.mantissa2 ) &&
436 ( vd.mantissa1 == lim->d.mantissa1 ) &&
437 ( vd.exp == lim->d.exp ) )
438 {
439 *idp = lim->ieee;
440 goto shipit;
441 }
442 }
443 idp->exp = vd.exp - VAX_DBL_BIAS + IEEE_DBL_BIAS;
444 idp->mantissa1 = vd.mantissa1 >> 3;
445 idp->mantissa2 = (vd.mantissa1 << 13) | (vd.mantissa2 >> 3);
446 idp->mantissa3 = (vd.mantissa2 << 13) | (vd.mantissa3 >> 3);
447 idp->mantissa4 = (vd.mantissa3 << 13) | (vd.mantissa4 >> 3);
448shipit:
449 idp->sign = vd.sign;
450#endif /* VMS */
451}
452
453void
454decode_double( BUF* pBuf, double* fp )
455{
456 bdecode_double( &(pBuf->buf[pBuf->pos]), fp );
457 pBuf->pos += 8;
458 pBuf->size += 8;
459}
460
#define NULL
Definition mud.h:167
UINT16 MUD_STR_LEN_TYPE
Definition mud.h:474
unsigned short UINT16
Definition mud.h:140
unsigned long UINT32
Definition mud.h:146
#define zalloc(n)
Definition mud.h:201
#define _swap4bytes(l)
Definition mud.h:437
#define _swap2bytes(s)
Definition mud.h:436
#define _strlen(s)
Definition mud.h:193
#define IEEE_DBL_BIAS
Definition mud_encode.c:361
#define VAX_SNG_BIAS
Definition mud_encode.c:202
#define VAX_DBL_BIAS
Definition mud_encode.c:360
void encode_str(BUF *pB, char **ps)
Definition mud_encode.c:140
void bdecode_float(char *buf, float *fp)
Definition mud_encode.c:252
void bdecode_double(char *buf, double *dp)
Definition mud_encode.c:415
void encode_float(BUF *pBuf, float *fp)
Definition mud_encode.c:244
void bencode_4(void *b, void *p)
Definition mud_encode.c:73
void bdecode_4(void *b, void *p)
Definition mud_encode.c:60
void bdecode_8(void *b, void *p)
Definition mud_encode.c:86
void bencode_float(char *buf, float *fp)
Definition mud_encode.c:208
void encode_double(BUF *pBuf, double *fp)
Definition mud_encode.c:407
void bencode_2(void *b, void *p)
Definition mud_encode.c:41
#define IEEE_SNG_BIAS
Definition mud_encode.c:203
void decode_double(BUF *pBuf, double *fp)
Definition mud_encode.c:454
void bdecode_2(void *b, void *p)
Definition mud_encode.c:28
void bencode_8(void *b, void *p)
Definition mud_encode.c:100
void decode_str(BUF *pB, char **ps)
Definition mud_encode.c:115
void decode_float(BUF *pBuf, float *fp)
Definition mud_encode.c:293
void bencode_double(char *buf, double *dp)
Definition mud_encode.c:368
Definition mud.h:253
unsigned int size
Definition mud.h:256
int pos
Definition mud.h:255
caddr_t buf
Definition mud.h:254
struct ieee_double ieee
Definition mud_encode.c:351
struct vax_double d
Definition mud_encode.c:350
unsigned int mantissa4
Definition mud_encode.c:339
unsigned int exp
Definition mud_encode.c:335
unsigned int mantissa1
Definition mud_encode.c:336
unsigned int mantissa3
Definition mud_encode.c:338
unsigned int sign
Definition mud_encode.c:334
unsigned int mantissa2
Definition mud_encode.c:337
unsigned int mantissa2
Definition mud_encode.c:183
unsigned int sign
Definition mud_encode.c:180
unsigned int exp
Definition mud_encode.c:181
unsigned int mantissa1
Definition mud_encode.c:182
struct vax_single s
Definition mud_encode.c:192
struct ieee_single ieee
Definition mud_encode.c:193
unsigned int mantissa2
Definition mud_encode.c:344
unsigned int mantissa3
Definition mud_encode.c:343
unsigned int sign
Definition mud_encode.c:345
unsigned int exp
Definition mud_encode.c:346
unsigned int mantissa1
Definition mud_encode.c:347
unsigned int mantissa4
Definition mud_encode.c:342
unsigned int mantissa2
Definition mud_encode.c:186
unsigned int sign
Definition mud_encode.c:187
unsigned int mantissa1
Definition mud_encode.c:189
unsigned int exp
Definition mud_encode.c:188