00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "_dicelib.h"
00025 #include "hash.h"
00026 #include <string.h>
00027 #include <stdlib.h>
00028 #include <errno.h>
00029 #ifndef WINDOWS
00030 # ifdef USE_LTDL
00031 # include <ltdl.h>
00032 # endif
00033 #ifdef HAVE_IEEE754_H
00034 #include <ieee754.h>
00035 #endif
00036 #endif
00037
00038 static HashTable dice_type_table;
00039
00040 struct _dice_type {
00041 char * (*pack_func) (void *data, int *n);
00042 void * (*unpack_func) (char *data, int *n);
00043 void (*free_func) (void *data);
00044 };
00045
00046 int dice_type_is_valid ( char *type ) {
00047 if ( hash_data(&dice_type_table, type) )
00048 return 1;
00049 return 0;
00050 }
00051
00052 #define FUNCTION "DICE_type_register"
00053
00092 #ifdef USE_LTDL
00093 int DICE_type_register ( char *type ) {
00094 struct _dice_type *dt;
00095 char *buffer;
00096 int len;
00097
00098 _dice_debug(3, dice_printf(FUNCTION, "(%s)\n", type);)
00099
00100 if ( !type ) {
00101 _dice_debug(1, dice_printf(FUNCTION, "NULL type name\n");)
00102 return -1;
00103 }
00104
00105 dt = (struct _dice_type *)malloc(sizeof(struct _dice_type));
00106 if ( !dt ) {
00107 _dice_debug(1, dice_printf(FUNCTION, "NULL malloc\n");)
00108 return -1;
00109 }
00110
00111 len = strlen(type)+1+7;
00112 buffer = (char *)malloc(len*sizeof(char));
00113 if ( !buffer ) {
00114 _dice_debug(1, dice_printf(FUNCTION, "NULL malloc2\n");)
00115 return -1;
00116 }
00117 strcpy(buffer, type);
00118 strcat(buffer, "_pack");
00119 dt->pack_func = lt_dlsym(dice_data.handle, buffer);
00120 if ( !dt->pack_func ) {
00121 _dice_debug(1, dice_printf(FUNCTION, "_pack: %s\n", lt_dlerror());)
00122 return -1;
00123 }
00124 strcpy(buffer, type);
00125 strcat(buffer, "_unpack");
00126 dt->unpack_func = lt_dlsym(dice_data.handle, buffer);
00127 if ( !dt->unpack_func ) {
00128 _dice_debug(1, dice_printf(FUNCTION, "_unpack: %s\n", lt_dlerror());)
00129 return -1;
00130 }
00131 strcpy(buffer, type);
00132 strcat(buffer, "_free");
00133 dt->free_func = lt_dlsym(dice_data.handle, buffer);
00134 if ( !dt->free_func ) {
00135 _dice_debug(1, dice_printf(FUNCTION, "_free: %s\n", lt_dlerror());)
00136 return -1;
00137 }
00138
00139 if ( hash_insert(&dice_type_table, type, (void *)dt) == -1 ) {
00140 _dice_debug(1, dice_printf(FUNCTION, "HashInsert returned -1 name\n");)
00141 return -1;
00142 }
00143 free(buffer);
00144 return 0;
00145 }
00146 #else
00147 int dice_type_register ( DICE_Type *t ) {
00148 struct _dice_type *dt;
00149
00150 _dice_debug(3, dice_printf(FUNCTION, "(%p)\n", t);)
00151
00152 if ( !t ) {
00153 _dice_debug(1, dice_printf(FUNCTION, "NULL type name\n");)
00154 return -1;
00155 }
00156
00157 if ( !t->name || !t->pack_func || !t->unpack_func || !t->free_func ) {
00158 _dice_debug(1, dice_printf(FUNCTION, "NULL pack, unpack or free function.");)
00159 return -1;
00160 }
00161
00162 dt = (struct _dice_type *)malloc(sizeof(struct _dice_type));
00163 if ( !dt ) {
00164 _dice_debug(1, dice_printf(FUNCTION, "NULL malloc\n");)
00165 return -1;
00166 }
00167 dt->pack_func = t->pack_func;
00168 dt->unpack_func = t->unpack_func;
00169 dt->free_func = t->free_func;
00170 if ( hash_insert(&dice_type_table, t->name, (void *)dt) == -1 ) {
00171 _dice_debug(1, dice_printf(FUNCTION, "HashInsert returned -1 name\n");)
00172 return -1;
00173 }
00174 return 0;
00175 }
00176 #endif
00177
00178 #undef FUNCTION
00179 #define FUNCTION "DICE_type_free"
00180
00191 int DICE_type_free ( char *type, void *data ) {
00192 struct _dice_type *dt;
00193
00194 _dice_debug(3, dice_printf(FUNCTION, "(%s,%p)\n",
00195 type, data);)
00196
00197 if ( !type ) {
00198 _dice_debug(1, dice_printf(FUNCTION, "NULL type name\n");)
00199 return -1;
00200 }
00201 if ( (dt = hash_data(&dice_type_table, type)) == NULL ) {
00202 _dice_debug(1, dice_printf(FUNCTION, "type %s not found\n");)
00203 return -1;
00204 }
00205 if ( dt->free_func )
00206 dt->free_func(data);
00207 return 0;
00208 }
00209
00210 #undef FUNCTION
00211 #define FUNCTION "DICE_type_pack"
00212
00225 char *DICE_type_pack ( char *type, void *data, int *n ) {
00226 struct _dice_type *dt;
00227
00228 _dice_debug(3, dice_printf(FUNCTION, "(%s,%p)\n",
00229 type, data);)
00230
00231 if ( !type ) {
00232 _dice_debug(1, dice_printf(FUNCTION, "NULL type name\n");)
00233 return NULL;
00234 }
00235 if ( (dt = hash_data(&dice_type_table, type)) == NULL ) {
00236 _dice_debug(1, dice_printf(FUNCTION, "type %s not found\n");)
00237 return NULL;
00238 }
00239 return dt->pack_func(data, n);
00240 }
00241
00242
00243 #undef FUNCTION
00244 #define FUNCTION "DICE_type_unpack"
00245
00255 void *DICE_type_unpack ( char *type, char *packet, int *n ) {
00256 struct _dice_type *dt;
00257
00258 _dice_debug(3, dice_printf(FUNCTION, "(%s,%p)\n",
00259 type, packet);)
00260
00261 if ( !type ) {
00262 _dice_debug(1, dice_printf(FUNCTION, "NULL type name\n");)
00263 return NULL;
00264 }
00265 if ( (dt = hash_data(&dice_type_table, type)) == NULL ) {
00266 _dice_debug(1, dice_printf(FUNCTION, "type %s not found\n");)
00267 return NULL;
00268 }
00269
00270 return dt->unpack_func(packet, n);
00271 }
00272
00273
00274
00275
00276
00277
00278 void dice_free ( void *data ) {
00279 _dice_debug(4, dice_printf("dice_free", "(%p)\n", data);)
00280 if ( data )
00281 free(data);
00282 }
00283
00284
00285 char *unsigned_char_pack ( void *data, int *n ) {
00286 char *buf;
00287 buf = malloc(4);
00288 if ( !buf || !data ) {
00289 *n = -1;
00290 return NULL;
00291 }
00292 memset(buf, 0, 4);
00293 buf[3] = *(unsigned char *)data;
00294 *n = 4;
00295 return buf;
00296 }
00297 void *unsigned_char_unpack ( char *data, int *n ) {
00298 unsigned char *c;
00299 c = (unsigned char *)malloc(1);
00300 if ( !c )
00301 return NULL;
00302 *c = data[3];
00303 *n = 4;
00304 return (void *)c;
00305 }
00306 void unsigned_char_free ( void *data ) {
00307 dice_free(data);
00308 }
00309
00310
00311 char *signed_char_pack ( void *data, int *n ) {
00312 return unsigned_char_pack(data, n);
00313 }
00314 void *signed_char_unpack ( char *data, int *n ) {
00315 return unsigned_char_unpack(data, n);
00316 }
00317 void signed_char_free ( void *data ) {
00318 dice_free(data);
00319 }
00320
00321
00322 char *unsigned_short_pack ( void *data, int *n ) {
00323 char *buf;
00324 unsigned short *s;
00325 buf = malloc(4);
00326 if ( !buf || !data ) {
00327 *n = -1;
00328 return NULL;
00329 }
00330 memset(buf, 0, 4);
00331 s = (unsigned short *)data;
00332 buf[3] = (char) (*s) & 0xFF;
00333 buf[2] = (char)((*s)>>8) & 0xFF;
00334 *n = 4;
00335 return buf;
00336 }
00337 void *unsigned_short_unpack ( char *data, int *n ) {
00338 unsigned short *s;
00339 s = (unsigned short *)malloc(sizeof(unsigned short));
00340 if ( !s )
00341 return NULL;
00342 *s = (unsigned short)(data[3]&0xFF) + ((data[2] << 8)&0xFF00);
00343 *n = 4;
00344 return (void *)s;
00345 }
00346 void unsigned_short_free ( void *data ) {
00347 dice_free(data);
00348 }
00349
00350
00351 char *signed_short_pack ( void *data, int *n ) {
00352 return unsigned_short_pack(data, n);
00353 }
00354 void *signed_short_unpack ( char *data, int *n ) {
00355 return unsigned_short_unpack(data, n);
00356 }
00357 void signed_short_free ( void *data ) {
00358 dice_free(data);
00359 }
00360
00361
00362 char *unsigned_long_pack ( void *data, int *n ) {
00363 char *buf;
00364 unsigned long *l;
00365 l = (unsigned long *)data;
00366 buf = malloc(4);
00367 if ( !buf || !data ) {
00368 *n = -1;
00369 return NULL;
00370 }
00371 buf[3] = (char)(*l)&0xFF;
00372 buf[2] = (char)((*l)>>8)&0xFF;
00373 buf[1] = (char)((*l)>>16)&0xFF;
00374 buf[0] = (char)((*l)>>24)&0xFF;
00375 *n = 4;
00376 return buf;
00377 }
00378 void *unsigned_long_unpack ( char *data, int *n ) {
00379 unsigned long *l;
00380 l = (unsigned long *)malloc(sizeof(unsigned long));
00381 if ( !l )
00382 return NULL;
00383 *l = (unsigned long)(data[3]&0xFF) + ((data[2] << 8)&0xFF00) +
00384 ((data[1] << 16)&0xFF0000) + ((data[0] << 24)&0xFF000000);
00385 *n = 4;
00386
00387 return (void *)l;
00388 }
00389 void unsigned_long_free ( void *data ) {
00390 dice_free(data);
00391 }
00392
00393
00394 char *signed_long_pack ( void *data, int *n ) {
00395 return unsigned_long_pack(data, n);
00396 }
00397 void *signed_long_unpack ( char *data, int *n ) {
00398 return unsigned_long_unpack(data, n);
00399 }
00400 void signed_long_free ( void *data ) {
00401 dice_free(data);
00402 }
00403
00404 static char _digit_encode ( char c ) {
00405 if ( c >= '0' && c <= '9' )
00406 return c - 48;
00407 else if ( c == '-' )
00408 return 0xA;
00409 else if ( c == '+' )
00410 return 0xB;
00411 else if ( c == 'e' || c == 'E' )
00412 return 0xC;
00413 else if ( c == '.' )
00414 return 0xD;
00415 else if ( c == ' ' )
00416 return 0xE;
00417 else {
00418 return 0xF;
00419 }
00420 }
00421 static char _digit_decode ( char d ) {
00422 if ( d >= 0 && d <= 9 )
00423 return d + 48;
00424 else if ( d == 0xA )
00425 return '-';
00426 else if ( d == 0xB )
00427 return '+';
00428 else if ( d == 0xC )
00429 return 'e';
00430 else if ( d == 0xD )
00431 return '.';
00432 else if ( d == 0xE )
00433 return ' ';
00434 else {
00435 return ' ';
00436 }
00437 }
00438
00439
00440 char *float_pack ( void *data, int *n ) {
00441 char *buf;
00442 char temp[13];
00443 float f;
00444 int i;
00445
00446 f = *(float *)data;
00447 buf = (char *)malloc(6);
00448 if ( !buf ) {
00449 *n = -1;
00450 return NULL;
00451 }
00452 snprintf(temp, 13, "%#.5e", f);
00453 for ( i = 0; i < 6; i++ )
00454 buf[i] = (_digit_encode(temp[i<<1]))+
00455 (_digit_encode(temp[(i<<1)+1])<<4);
00456 *n = 6;
00457 return buf;
00458 }
00459 void *float_unpack ( char *data, int *n ) {
00460 float *g;
00461 char temp[13];
00462 int i;
00463
00464 g = (float *)malloc(sizeof(float));
00465 if ( !g )
00466 return NULL;
00467 for ( i = 0; i < 6; i++ ) {
00468 temp[i<<1] = _digit_decode(data[i] & 0xF);
00469 temp[(i<<1)+1] = _digit_decode((data[i]>>4) & 0xF);
00470 }
00471 temp[12] = '\0';
00472 *n = 6;
00473 *g = (float)strtod(temp, NULL);
00474 return g;
00475 }
00476 void float_free ( void *data ) {
00477 dice_free(data);
00478 }
00479
00480
00481 char *double_pack ( void *data, int *n ) {
00482 char *buf;
00483 char temp[23];
00484 double f;
00485 int i;
00486
00487 f = *(double *)data;
00488 buf = (char *)malloc(12);
00489 if ( !buf ) {
00490 *n = -1;
00491 return NULL;
00492 }
00493 snprintf(buf, 23, "%#.15e", f);
00494 for ( i = 0; i < 12; i++ )
00495 buf[i] = (_digit_encode(temp[i<<1]))+
00496 (_digit_encode(temp[(i<<1)+1])<<4);
00497 *n = 12;
00498 return buf;
00499 }
00500 void *double_unpack ( char *data, int *n ) {
00501 double *g;
00502 char temp[23];
00503 int i;
00504
00505 g = (double *)malloc(sizeof(double));
00506 if ( !g )
00507 return NULL;
00508 for ( i = 0; i < 6; i++ ) {
00509 temp[i<<1] = _digit_decode(data[i] & 0xF);
00510 temp[(i<<1)+1] = _digit_decode((data[i]>>4) & 0xF);
00511 }
00512 temp[22] = '\0';
00513 *n = 12;
00514 *g = (double)strtod(data, NULL);
00515 return g;
00516 }
00517 void double_free ( void *data ) {
00518 dice_free(data);
00519 }
00520
00521 #ifdef HAVE_IEEE754_H
00522
00523 char *float754_pack ( void *data, int *n ) {
00524 char *buf;
00525 union ieee754_float f;
00526
00527 f.f = *(float *)data;
00528 buf = (char *)malloc(4);
00529 if ( !buf ) {
00530 *n = -1;
00531 return NULL;
00532 }
00533 buf[0] = (f.ieee.negative<<7) | ((f.ieee.exponent>>1)&0x7F);
00534 buf[1] = ((f.ieee.exponent&0x01)<<7) | ((f.ieee.mantissa>>16)&0x7F);
00535 buf[2] = (f.ieee.mantissa>>8) & 0xFF;
00536 buf[3] = (f.ieee.mantissa)&0xFF;
00537 *n = 4;
00538 return buf;
00539 }
00540 void *float754_unpack ( char *data, int *n ) {
00541 union ieee754_float f;
00542 float *g;
00543 g = (float *)malloc(sizeof(float));
00544 if ( !g )
00545 return NULL;
00546 f.ieee.negative = data[0]>>7;
00547 f.ieee.exponent = ((data[0]<<1)&0xFE) + ((data[1]>>7)&0x01);
00548 f.ieee.mantissa = (data[3]&0xFF) + ((data[2]<<8)&0xFF00) +
00549 (((data[1]&0x7F)<<16)&0xFF0000);
00550 *n = 4;
00551 *g = f.f;
00552 return g;
00553 }
00554 void float754_free ( void *data ) {
00555 dice_free(data);
00556 }
00557
00558
00559 char *double754_pack ( void *data, int *n ) {
00560 char *buf;
00561 union ieee754_double d;
00562
00563 d.d = *(double *)data;
00564 buf = (char *)malloc(8);
00565 if ( !buf ) {
00566 *n = -1;
00567 return NULL;
00568 }
00569 buf[0] = (d.ieee.negative<<7) + ((d.ieee.exponent>>4)&0x7F);
00570 buf[1] = (((d.ieee.exponent)<<4)&0xF0) + ((d.ieee.mantissa0>>16)&0x0F);
00571 buf[2] = (d.ieee.mantissa0>>8) & 0xFF;
00572 buf[3] = (d.ieee.mantissa0)&0xFF;
00573 buf[4] = (d.ieee.mantissa1>>24) & 0xFF;
00574 buf[5] = (d.ieee.mantissa1>>16) & 0xFF;
00575 buf[6] = (d.ieee.mantissa1>>8) & 0xFF;
00576 buf[7] = (d.ieee.mantissa1) & 0xFF;
00577 *n = 8;
00578 return buf;
00579 }
00580 void *double754_unpack ( char *data, int *n ) {
00581 union ieee754_double d;
00582 double *e;
00583 e = (double *)malloc(sizeof(double));
00584 if ( !e ) {
00585 return NULL;
00586 }
00587 d.ieee.negative = data[0]>>7;
00588 d.ieee.exponent = ((data[0]<<4)&0x7F0) + ((data[1]>>4)&0x0F);
00589 d.ieee.mantissa0 = (data[3]&0xFF) + ((data[2]<<8)&0xFF00)
00590 + (((data[1]&0x0F)<<16)&0xFF0000);
00591 d.ieee.mantissa1 = (data[7]&0xFF) + ((data[6]<<8)&0xFF00)
00592 + ((data[5]<<16)&0xFF0000) + ((data[4]<<24)&0xFF000000);
00593 *n = 8;
00594 *e = d.d;
00595 return e;
00596 }
00597 void double754_free ( void *data ) {
00598 dice_free(data);
00599 }
00600 #endif
00601
00602
00603 char *string_pack ( void *data, int *n ) {
00604 char *buf;
00605 int length, total;
00606
00607 length = strlen((char *)data);
00608 total = length + 4-(length%4 == 0 ? 4 : length %4) + 4;
00609 buf = (char *)malloc(total);
00610 if ( !buf )
00611 dice_printf(NULL, "error");
00612 memset(buf, 0, total);
00613 buf[3] = (char)(length)&0xFF;
00614 buf[2] = (char)((length)>>8)&0xFF;
00615 buf[1] = (char)((length)>>16)&0xFF;
00616 buf[0] = (char)((length)>>24)&0xFF;
00617 memcpy(buf+4, data, length);
00618 *n = total;
00619 return buf;
00620 }
00621 void *string_unpack ( char *data, int *n ) {
00622 char *buf;
00623 int length;
00624 length = (int)(data[3]&0xFF) + (((int)data[2] << 8)&0xFF00) +
00625 (((int)data[1] << 16)&0xFF0000) + (((int)data[0] << 24)&0xFF000000);
00626
00627 buf = malloc(length+1);
00628 if ( !buf ) {
00629 dice_printf("awer", "%s", strerror(errno));
00630 }
00631 memcpy(buf, data+4, length);
00632 buf[length] = '\0';
00633 *n = length + 4-(length%4 == 0 ? 4 : length %4) + 4;
00634 return (void *)buf;
00635 }
00636 void string_free ( void *data ) {
00637 dice_free(data);
00638 }
00639
00640 #undef FUNCTION
00641 #define FUNCTION "dice_default_types"
00642 int dice_type_init_defaults ( void ) {
00643 #ifdef USE_LTDL
00644 char *default_names[] = {
00645 "unsigned_char",
00646 "signed_char",
00647 "unsigned_short",
00648 "signed_short",
00649 "unsigned_long",
00650 "signed_long",
00651 "float",
00652 "double",
00653 #ifdef HAVE_IEEE754_H
00654 "float754",
00655 "double754",
00656 #endif
00657 "string"
00658 };
00659 #else
00660 DICE_Type default_types[] = {
00661 { "unsigned_char", unsigned_char_pack, unsigned_char_unpack, unsigned_char_free },
00662 { "signed_char", signed_char_pack, signed_char_unpack, signed_char_free },
00663 { "unsigned_short", unsigned_short_pack, unsigned_short_unpack, unsigned_short_free },
00664 { "signed_short", signed_short_pack, signed_short_unpack, signed_short_free },
00665 { "unsigned_long", unsigned_long_pack, unsigned_long_unpack, unsigned_long_free },
00666 { "signed_long", signed_long_pack, signed_long_unpack, signed_long_free },
00667 { "float", float_pack, float_unpack, float_free },
00668 { "double", double_pack, double_unpack, double_free },
00669 #ifdef HAVE_IEEE754_H
00670 { "float754", float754_pack, float754_unpack, float754_free },
00671 { "double754", double754_pack, double754_unpack, double754_free },
00672 #endif
00673 { "string", string_pack, string_unpack, string_free } };
00674 DICE_Type *t;
00675 #endif
00676 int i;
00677
00678 _dice_debug(3, dice_printf(FUNCTION, "\n");)
00679
00680 hash_init(&dice_type_table, 64, NULL);
00681 for ( i = 0; i < sizeof(default_types)/sizeof(DICE_Type); i++ ) {
00682 #ifdef USE_LTDL
00683 if ( DICE_type_register(default_names[i]) == -1 ) {
00684 _dice_debug(1, dice_printf(FUNCTION, "Could not register %s\n", default_names[i]);)
00685 #else
00686 if ( dice_type_register(&default_types[i]) == -1 ) {
00687 _dice_debug(1, dice_printf(FUNCTION, "Could not register %s\n", default_types->name);)
00688 #endif
00689 return -1;
00690 }
00691 }
00692 #ifndef USE_LTDL
00693 t = DICE_MyTypes;
00694 while (t->name) {
00695 if ( dice_type_register(t) == -1 ) {
00696 _dice_debug(1, dice_printf(FUNCTION, "Could not register %s\n", t->name);)
00697 return -1;
00698 }
00699 t++;
00700 }
00701 #endif
00702 return 0;
00703 }
00704
00705 void dice_type_free_all ( void ) {
00706 hash_free(&dice_type_table, dice_free);
00707 }