00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293 #include "bc_machdefs.h"
00294 #include "bc_util.h"
00295
00296
00297 static CC_SFILE *sopen_write (const char *f),
00298 *sopen_read (const char *f),
00299 *sdopen (int t),
00300 *sdopen_write (int t),
00301 *sdopen_read (int t),
00302 *sdopen_readwrite (int t);
00303
00304 static int swrite_buffer (CC_SFILE * f),
00305 sread_buffer (CC_SFILE * f),
00306 prepare_write (CC_SFILE * f),
00307 prepare_read (CC_SFILE * f);
00308
00309 static void sinit (CC_SFILE * s);
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337 #define SREAD 1
00338 #define SWRITE 2
00339 #define SRW_EMPTY 3
00340 #define SRW_READ 4
00341 #define SRW_WRITE 5
00342
00343 #define TFILE 1
00344 #define TDESC 2
00345 #define TNET 3
00346
00347 #define NBITMASK(n) ((1<<(n))-1)
00348 #define BITRANGE(x,start,length) (((x) >> (start)) & NBITMASK(length))
00349 #define BITS_PER_CHAR (8)
00350
00351 #ifndef O_BINARY
00352 #define O_BINARY 0
00353 #endif
00354 #ifndef O_EXCL
00355 #define O_EXCL 0
00356 #endif
00357
00358 CC_SFILE *CCutil_sopen (const char *f,
00359 const char *s)
00360 {
00361 if (strcmp (s, "r") == 0)
00362 {
00363 return sopen_read (f);
00364 }
00365 else if (strcmp (s, "w") == 0)
00366 {
00367 return sopen_write (f);
00368 }
00369 else
00370 {
00371 fprintf (stderr, "Need to specify read/write in CCutil_sopen\n");
00372 return (CC_SFILE *) NULL;
00373 }
00374 }
00375
00376 CC_SFILE *CCutil_sdopen (int d,
00377 const char *s)
00378 {
00379 if (strcmp (s, "r") == 0)
00380 {
00381 return sdopen_read (d);
00382 }
00383 else if (strcmp (s, "w") == 0)
00384 {
00385 return sdopen_write (d);
00386 }
00387 else if (strcmp (s, "rw") == 0)
00388 {
00389 return sdopen_readwrite (d);
00390 }
00391 else
00392 {
00393 fprintf (stderr, "Need to specify read/write in CCutil_sdopen\n");
00394 return (CC_SFILE *) NULL;
00395 }
00396 }
00397
00398 static CC_SFILE *sopen_write (const char *f)
00399 {
00400 CC_SFILE *s = (CC_SFILE *) NULL;
00401 int t;
00402 char fbuf[CC_SFNAME_SIZE];
00403 char fbuf_N[CC_SFNAME_SIZE + 32];
00404 char fbuf_Nx[CC_SFNAME_SIZE + 64];
00405
00406 strncpy (fbuf, f, sizeof (fbuf) - 12);
00407 fbuf[sizeof (fbuf) - 12] = '\0';
00408 sprintf (fbuf_N, "N%s", fbuf);
00409 sprintf (fbuf_Nx, "N%s~", fbuf);
00410
00411
00412 if (strcmp (f, "stdout") == 0 || strcmp (f, "-") == 0)
00413 {
00414 s = sdopen_write (1);
00415 }
00416 else if (strcmp (f, "stderr") == 0)
00417 {
00418 s = sdopen_write (2);
00419 }
00420 else
00421 {
00422 t = open (fbuf_N, O_WRONLY | O_CREAT | O_BINARY | O_EXCL, 0644);
00423 if (t == -1 && errno == EEXIST)
00424 {
00425 fprintf (stderr, "%s already exists, renaming to %s\n", fbuf_N, fbuf_Nx);
00426 if (rename (fbuf_N, fbuf_Nx))
00427 {
00428 perror (fbuf_Nx);
00429 fprintf (stderr, "Couldn't rename %s to %s\n", fbuf_N, fbuf_Nx);
00430 return (CC_SFILE *) NULL;
00431 }
00432 t = open (fbuf_N, O_WRONLY | O_CREAT | O_BINARY | O_EXCL, 0644);
00433 }
00434 if (t == -1)
00435 {
00436 perror (fbuf_N);
00437 fprintf (stderr, "Couldn't open %s for output\n", fbuf_N);
00438 return (CC_SFILE *) NULL;
00439 }
00440 s = sdopen_write (t);
00441 if (!s)
00442 {
00443 close (t);
00444 }
00445 else
00446 {
00447 s->type = TFILE;
00448 }
00449 }
00450 if (s)
00451 {
00452 strncpy (s->fname, fbuf, sizeof (s->fname));
00453 s->fname[sizeof (s->fname) - 1] = '\0';
00454 }
00455 return s;
00456 }
00457
00458 static CC_SFILE *sopen_read (const char *f)
00459 {
00460 CC_SFILE *s = (CC_SFILE *) NULL;
00461 int t;
00462
00463 if (strcmp (f, "stdin") == 0 || strcmp (f, "-") == 0)
00464 {
00465 s = sdopen_read (0);
00466 }
00467 else
00468 {
00469 t = open (f, O_RDONLY | O_BINARY, 0644);
00470 if (t == -1)
00471 {
00472 perror (f);
00473 fprintf (stderr, "Couldn't open for input\n");
00474 s = (CC_SFILE *) NULL;
00475 }
00476 s = sdopen_read (t);
00477 if (!s)
00478 {
00479 close (t);
00480 }
00481 else
00482 {
00483 s->type = TFILE;
00484 }
00485 }
00486 if (s)
00487 {
00488 strncpy (s->fname, f, sizeof (s->fname));
00489 s->fname[sizeof (s->fname) - 1] = '\0';
00490 }
00491 return s;
00492 }
00493
00494 static CC_SFILE *sdopen (int t)
00495 {
00496 CC_SFILE *s = (CC_SFILE *) NULL;
00497
00498 if (t < 0)
00499 {
00500 fprintf (stderr, "Invalid descriptor %d\n", t);
00501 return (CC_SFILE *) NULL;
00502 }
00503
00504 s = CC_SAFE_MALLOC (1, CC_SFILE);
00505 if (s == (CC_SFILE *) NULL)
00506 {
00507 return (CC_SFILE *) NULL;
00508 }
00509 sinit (s);
00510
00511 s->desc = t;
00512 s->type = TDESC;
00513 sprintf (s->fname, "descriptor %d", t);
00514 return s;
00515 }
00516
00517 static CC_SFILE *sdopen_write (int t)
00518 {
00519 CC_SFILE *s = (CC_SFILE *) NULL;
00520
00521 s = sdopen (t);
00522 if (s)
00523 {
00524 s->status = SWRITE;
00525 }
00526
00527 return s;
00528 }
00529
00530 static CC_SFILE *sdopen_read (int t)
00531 {
00532 CC_SFILE *s = (CC_SFILE *) NULL;
00533
00534 s = sdopen (t);
00535 if (s)
00536 {
00537 s->status = SREAD;
00538 }
00539
00540 return s;
00541 }
00542
00543 static CC_SFILE *sdopen_readwrite (int t)
00544 {
00545 CC_SFILE *s = (CC_SFILE *) NULL;
00546
00547 s = sdopen (t);
00548 if (s)
00549 {
00550 s->status = SRW_EMPTY;
00551 }
00552
00553 return s;
00554 }
00555
00556 int CCutil_swrite (CC_SFILE * f,
00557 char *buf,
00558 int size)
00559 {
00560 int i;
00561
00562 for (i = 0; i < size; i++)
00563 {
00564 if (CCutil_swrite_char (f, buf[i]))
00565 return -1;
00566 }
00567 return 0;
00568 }
00569
00570 int CCutil_swrite_bits (CC_SFILE * f,
00571 int x,
00572 int xbits)
00573 {
00574 if (x < 0)
00575 {
00576 fprintf (stderr, "CCutil_swrite_bits cannot write negative numbers\n");
00577 return -1;
00578 }
00579 return CCutil_swrite_ubits (f, (unsigned int) x, xbits);
00580 }
00581
00582 int CCutil_swrite_ubits (CC_SFILE * f,
00583 unsigned int x,
00584 int xbits)
00585 {
00586 int getbits;
00587 unsigned int v;
00588
00589 if (prepare_write (f))
00590 return -1;
00591
00592 while (xbits)
00593 {
00594 if (f->bits_in_last_char == 0)
00595 {
00596 if (f->chars_in_buffer == CC_SBUFFER_SIZE)
00597 {
00598 if (swrite_buffer (f))
00599 return -1;
00600 }
00601 f->buffer[f->chars_in_buffer++] = 0;
00602 f->bits_in_last_char = BITS_PER_CHAR;
00603 }
00604 getbits = f->bits_in_last_char;
00605 if (getbits > xbits)
00606 getbits = xbits;
00607 xbits -= getbits;
00608 f->bits_in_last_char -= getbits;
00609 v = BITRANGE (x, xbits, getbits);
00610 f->buffer[f->chars_in_buffer - 1] =
00611 (unsigned int) f->buffer[f->chars_in_buffer - 1] |
00612 (unsigned int) (v << f->bits_in_last_char);
00613 }
00614 return 0;
00615 }
00616
00617 int CCutil_swrite_char (CC_SFILE * f,
00618 int x)
00619 {
00620 unsigned char ux = (unsigned char) x;
00621
00622 if (prepare_write (f))
00623 return -1;
00624
00625 f->bits_in_last_char = 0;
00626 if (f->chars_in_buffer + 1 > CC_SBUFFER_SIZE)
00627 {
00628 if (swrite_buffer (f))
00629 return -1;
00630 }
00631 f->buffer[f->chars_in_buffer++] = ((unsigned int) ux) & 0xff;
00632 return 0;
00633 }
00634
00635 int CCutil_swrite_string (CC_SFILE * f,
00636 const char *s)
00637 {
00638 int rval;
00639
00640 while (*s)
00641 {
00642 rval = CCutil_swrite_char (f, *s);
00643 if (rval)
00644 return rval;
00645 s++;
00646 }
00647 CCutil_swrite_char (f, (unsigned) 0);
00648 return 0;
00649 }
00650
00651 int CCutil_swrite_short (CC_SFILE * f,
00652 short x)
00653 {
00654 return CCutil_swrite_ushort (f, (unsigned) x);
00655 }
00656
00657 int CCutil_swrite_ushort (CC_SFILE * f,
00658 unsigned x)
00659 {
00660 if (prepare_write (f))
00661 return -1;
00662
00663 f->bits_in_last_char = 0;
00664 if (f->chars_in_buffer + 2 > CC_SBUFFER_SIZE)
00665 {
00666 if (swrite_buffer (f))
00667 return -1;
00668 }
00669
00670 f->buffer[f->chars_in_buffer++] = (((unsigned int) x) >> 8) & 0xff;
00671 f->buffer[f->chars_in_buffer++] = ((unsigned int) x) & 0xff;
00672 return 0;
00673 }
00674
00675 int CCutil_swrite_int (CC_SFILE * f,
00676 int x)
00677 {
00678 return CCutil_swrite_uint (f, (unsigned int) x);
00679 }
00680
00681 int CCutil_swrite_uint (CC_SFILE * f,
00682 unsigned int x)
00683 {
00684 if (prepare_write (f))
00685 return -1;
00686
00687 f->bits_in_last_char = 0;
00688 if (f->chars_in_buffer + 4 > CC_SBUFFER_SIZE)
00689 {
00690 if (swrite_buffer (f))
00691 return -1;
00692 }
00693
00694 f->buffer[f->chars_in_buffer++] = (((unsigned int) x) >> 24) & 0xff;
00695 f->buffer[f->chars_in_buffer++] = (((unsigned int) x) >> 16) & 0xff;
00696 f->buffer[f->chars_in_buffer++] = (((unsigned int) x) >> 8) & 0xff;
00697 f->buffer[f->chars_in_buffer++] = ((unsigned int) x) & 0xff;
00698 return 0;
00699 }
00700
00701 int CCutil_swrite_double (CC_SFILE * f,
00702 double x)
00703 {
00704 unsigned short e;
00705 unsigned int m1;
00706 unsigned int m2;
00707
00708 e = 128;
00709
00710 if (x < 0)
00711 {
00712 e = (unsigned int) e + 256;
00713 x = -x;
00714 }
00715
00716 if (x >= 1.0)
00717 {
00718 #define MUNCH_HI_EXP(x,e,v,lv) if (x >= v) {e = (unsigned int) e + lv; x *= 1/v;}
00719 MUNCH_HI_EXP (x, e, 18446744073709551616.0, 64);
00720 MUNCH_HI_EXP (x, e, 4294967296.0, 32);
00721 MUNCH_HI_EXP (x, e, 65536.0, 16);
00722 MUNCH_HI_EXP (x, e, 256.0, 8);
00723 MUNCH_HI_EXP (x, e, 16.0, 4);
00724 MUNCH_HI_EXP (x, e, 4.0, 2);
00725 MUNCH_HI_EXP (x, e, 2.0, 1);
00726 #undef MUNCH_HI_EXP
00727 x /= 2;
00728 e = (unsigned int) e + 1;
00729 }
00730 else if (x < 0.5)
00731 {
00732 #define MUNCH_LO_EXP(x,e,v,lv) if (x < 1/v) {e = (unsigned int) e - lv; x *= v;}
00733 MUNCH_LO_EXP (x, e, 18446744073709551616.0, 64);
00734 MUNCH_LO_EXP (x, e, 4294967296.0, 32);
00735 MUNCH_LO_EXP (x, e, 65536.0, 16);
00736 MUNCH_LO_EXP (x, e, 256.0, 8);
00737 MUNCH_LO_EXP (x, e, 16.0, 4);
00738 MUNCH_LO_EXP (x, e, 4.0, 2);
00739 MUNCH_LO_EXP (x, e, 2.0, 1);
00740 #undef MUNCH_LP_EXP
00741 }
00742 x *= 4294967296.0;
00743 m1 = (unsigned int) x;
00744 m2 = (unsigned int) ((x - m1) * 4294967296.0);
00745 if (CCutil_swrite_ushort (f, e))
00746 return -1;
00747 if (CCutil_swrite_uint (f, m1))
00748 return -1;
00749 if (CCutil_swrite_uint (f, m2))
00750 return -1;
00751 return 0;
00752 }
00753
00754 int CCutil_sread (CC_SFILE * f,
00755 char *buf,
00756 int size)
00757 {
00758 int i;
00759
00760 for (i = 0; i < size; i++)
00761 {
00762 if (CCutil_sread_char (f, &buf[i]))
00763 return -1;
00764 }
00765 return 0;
00766 }
00767
00768 int CCutil_sread_bits (CC_SFILE * f,
00769 int *x,
00770 int xbits)
00771 {
00772 unsigned int ux = 0;
00773 int rval;
00774
00775 rval = CCutil_sread_ubits (f, &ux, xbits);
00776 *x = (int) ux;
00777 return rval;
00778 }
00779
00780 int CCutil_sread_ubits (CC_SFILE * f,
00781 unsigned int *x,
00782 int xbits)
00783 {
00784 int getbits;
00785 unsigned int v;
00786
00787 if (prepare_read (f))
00788 return -1;
00789
00790 *x = 0;
00791 while (xbits)
00792 {
00793 if (f->bits_in_last_char == 0)
00794 {
00795 if (f->current_buffer_char + 1 == f->chars_in_buffer)
00796 {
00797 if (sread_buffer (f))
00798 return -1;
00799 }
00800 f->current_buffer_char++;
00801 f->bits_in_last_char = BITS_PER_CHAR;
00802 }
00803 getbits = f->bits_in_last_char;
00804 if (getbits > xbits)
00805 getbits = xbits;
00806 f->bits_in_last_char -= getbits;
00807 xbits -= getbits;
00808 v = BITRANGE ((unsigned int) f->buffer[f->current_buffer_char],
00809 f->bits_in_last_char, getbits);
00810 *x |= v << xbits;
00811 }
00812 return 0;
00813 }
00814
00815 int CCutil_sread_char (CC_SFILE * f,
00816 char *x)
00817 {
00818 if (prepare_read (f))
00819 return -1;
00820
00821 f->bits_in_last_char = 0;
00822 if (f->current_buffer_char + 1 == f->chars_in_buffer)
00823 {
00824 if (sread_buffer (f))
00825 return -1;
00826 }
00827 *x = (char) (f->buffer[++f->current_buffer_char]);
00828 return 0;
00829 }
00830
00831 int CCutil_sread_string (CC_SFILE * f,
00832 char *x,
00833 int maxlen)
00834 {
00835 int i,
00836 rval;
00837
00838 maxlen--;
00839 for (i = 0; i < maxlen; i++, x++)
00840 {
00841 rval = CCutil_sread_char (f, x);
00842 if (rval)
00843 return rval;
00844 if (*x == 0)
00845 return 0;
00846 }
00847 *x = 0;
00848 return 0;
00849 }
00850
00851 int CCutil_sread_short (CC_SFILE * f,
00852 short *x)
00853 {
00854 unsigned short ux = 0;
00855 int rval;
00856
00857 rval = CCutil_sread_ushort (f, &ux);
00858 *x = (short) ux;
00859 return rval;
00860 }
00861
00862 int CCutil_sread_ushort (CC_SFILE * f,
00863 unsigned short *x)
00864 {
00865 if (prepare_read (f))
00866 return -1;
00867
00868 f->bits_in_last_char = 0;
00869 if (f->current_buffer_char + 1 == f->chars_in_buffer)
00870 {
00871 if (sread_buffer (f))
00872 return -1;
00873 }
00874 *x = ((unsigned int) f->buffer[++f->current_buffer_char]) << 8;
00875 if (f->current_buffer_char + 1 == f->chars_in_buffer)
00876 {
00877 if (sread_buffer (f))
00878 return -1;
00879 }
00880 *x = (unsigned int) *x | ((unsigned int) f->buffer[++f->current_buffer_char]);
00881 return 0;
00882 }
00883
00884 int CCutil_sread_short_r (CC_SFILE * f,
00885 short *x)
00886 {
00887 unsigned short ux = 0;
00888
00889 if (prepare_read (f))
00890 return -1;
00891
00892 f->bits_in_last_char = 0;
00893 if (f->current_buffer_char + 1 == f->chars_in_buffer)
00894 {
00895 if (sread_buffer (f))
00896 return -1;
00897 }
00898 ux = ((unsigned short) f->buffer[++f->current_buffer_char]);
00899 if (f->current_buffer_char + 1 == f->chars_in_buffer)
00900 {
00901 if (sread_buffer (f))
00902 return -1;
00903 }
00904 ux =
00905 (unsigned int) ux | ((unsigned int) f->
00906 buffer[++f->current_buffer_char]) << 8;
00907 *x = (short) ux;
00908 return 0;
00909 }
00910
00911 int CCutil_sread_int (CC_SFILE * f,
00912 int *x)
00913 {
00914 unsigned int ux = 0;
00915 int rval;
00916
00917 rval = CCutil_sread_uint (f, &ux);
00918 *x = (int) ux;
00919 return rval;
00920 }
00921
00922 int CCutil_sread_uint (CC_SFILE * f,
00923 unsigned int *x)
00924 {
00925 if (prepare_read (f))
00926 return -1;
00927
00928 f->bits_in_last_char = 0;
00929 if (f->current_buffer_char + 1 == f->chars_in_buffer)
00930 {
00931 if (sread_buffer (f))
00932 return -1;
00933 }
00934 *x = ((unsigned int) f->buffer[++f->current_buffer_char]) << 24;
00935 if (f->current_buffer_char + 1 == f->chars_in_buffer)
00936 {
00937 if (sread_buffer (f))
00938 return -1;
00939 }
00940 *x |= ((unsigned int) f->buffer[++f->current_buffer_char]) << 16;
00941 if (f->current_buffer_char + 1 == f->chars_in_buffer)
00942 {
00943 if (sread_buffer (f))
00944 return -1;
00945 }
00946 *x |= ((unsigned int) f->buffer[++f->current_buffer_char]) << 8;
00947 if (f->current_buffer_char + 1 == f->chars_in_buffer)
00948 {
00949 if (sread_buffer (f))
00950 return -1;
00951 }
00952 *x |= ((unsigned int) f->buffer[++f->current_buffer_char]);
00953 return 0;
00954 }
00955
00956 int CCutil_sread_int_r (CC_SFILE * f,
00957 int *x)
00958 {
00959 unsigned int ux = 0;
00960
00961 if (prepare_read (f))
00962 return -1;
00963
00964 f->bits_in_last_char = 0;
00965 if (f->current_buffer_char + 1 == f->chars_in_buffer)
00966 {
00967 if (sread_buffer (f))
00968 return -1;
00969 }
00970 ux = ((unsigned int) f->buffer[++f->current_buffer_char]);
00971 if (f->current_buffer_char + 1 == f->chars_in_buffer)
00972 {
00973 if (sread_buffer (f))
00974 return -1;
00975 }
00976 ux |= ((unsigned int) f->buffer[++f->current_buffer_char]) << 8;
00977 if (f->current_buffer_char + 1 == f->chars_in_buffer)
00978 {
00979 if (sread_buffer (f))
00980 return -1;
00981 }
00982 ux |= ((unsigned int) f->buffer[++f->current_buffer_char]) << 16;
00983 if (f->current_buffer_char + 1 == f->chars_in_buffer)
00984 {
00985 if (sread_buffer (f))
00986 return -1;
00987 }
00988 ux |= ((unsigned int) f->buffer[++f->current_buffer_char]) << 24;
00989 *x = (int) ux;
00990 return 0;
00991 }
00992
00993 int CCutil_sread_double (CC_SFILE * f,
00994 double *x)
00995 {
00996 unsigned short e;
00997 unsigned int m1;
00998 unsigned int m2;
00999
01000 if (CCutil_sread_ushort (f, &e))
01001 return -1;
01002 if (CCutil_sread_uint (f, &m1))
01003 return -1;
01004 if (CCutil_sread_uint (f, &m2))
01005 return -1;
01006
01007 *x = ((m2 / 4294967296.0) + m1) / 4294967296.0;
01008
01009 if ((unsigned int) e >= 256)
01010 {
01011 *x = -*x;
01012 e = (unsigned int) e - 256;
01013 }
01014
01015 if ((unsigned int) e > 128)
01016 {
01017 #define UNMUNCH_HI_EXP(x,e,v,lv) if ((unsigned int) e >= (unsigned int) (128 + lv)) \
01018 {e = (unsigned int) e - lv; x *= v;}
01019 UNMUNCH_HI_EXP (*x, e, 18446744073709551616.0, 64);
01020 UNMUNCH_HI_EXP (*x, e, 4294967296.0, 32);
01021 UNMUNCH_HI_EXP (*x, e, 65536.0, 16);
01022 UNMUNCH_HI_EXP (*x, e, 256.0, 8);
01023 UNMUNCH_HI_EXP (*x, e, 16.0, 4);
01024 UNMUNCH_HI_EXP (*x, e, 4.0, 2);
01025 UNMUNCH_HI_EXP (*x, e, 2.0, 1);
01026 #undef UNMUNCH_HI_EXP
01027 }
01028 else if ((unsigned int) e < 128)
01029 {
01030 #define UNMUNCH_LO_EXP(x,e,v,lv) if ((unsigned int) e <= (unsigned int) (128 - lv)) \
01031 {e = (unsigned int) e + lv; x *= 1/v;}
01032 UNMUNCH_LO_EXP (*x, e, 18446744073709551616.0, 64);
01033 UNMUNCH_LO_EXP (*x, e, 4294967296.0, 32);
01034 UNMUNCH_LO_EXP (*x, e, 65536.0, 16);
01035 UNMUNCH_LO_EXP (*x, e, 256.0, 8);
01036 UNMUNCH_LO_EXP (*x, e, 16.0, 4);
01037 UNMUNCH_LO_EXP (*x, e, 4.0, 2);
01038 UNMUNCH_LO_EXP (*x, e, 2.0, 1);
01039 #undef UNMUNCH_LO_EXP
01040 }
01041
01042 return 0;
01043 }
01044
01045 int CCutil_sread_double_r (CC_SFILE * f,
01046 double *x)
01047 {
01048 unsigned short e;
01049 unsigned int m1;
01050 unsigned int m2;
01051 short se;
01052 int sm1;
01053 int sm2;
01054
01055 if (CCutil_sread_short_r (f, &se))
01056 return -1;
01057 if (CCutil_sread_int_r (f, &sm1))
01058 return -1;
01059 if (CCutil_sread_int_r (f, &sm2))
01060 return -1;
01061 e = (unsigned short) se;
01062 m1 = (unsigned int) sm1;
01063 m2 = (unsigned int) sm2;
01064
01065 *x = ((m2 / 4294967296.0) + m1) / 4294967296.0;
01066
01067 if ((unsigned int) e >= 256)
01068 {
01069 *x = -*x;
01070 e = (unsigned int) e - 256;
01071 }
01072
01073 if ((unsigned int) e > 128)
01074 {
01075 #define UNMUNCH_HI_EXP(x,e,v,lv) if ((unsigned int) e >= (unsigned int) (128 + lv)) \
01076 {e = (unsigned int) e - lv; x *= v;}
01077 UNMUNCH_HI_EXP (*x, e, 18446744073709551616.0, 64);
01078 UNMUNCH_HI_EXP (*x, e, 4294967296.0, 32);
01079 UNMUNCH_HI_EXP (*x, e, 65536.0, 16);
01080 UNMUNCH_HI_EXP (*x, e, 256.0, 8);
01081 UNMUNCH_HI_EXP (*x, e, 16.0, 4);
01082 UNMUNCH_HI_EXP (*x, e, 4.0, 2);
01083 UNMUNCH_HI_EXP (*x, e, 2.0, 1);
01084 #undef UNMUNCH_HI_EXP
01085 }
01086 else if ((unsigned int) e < 128)
01087 {
01088 #define UNMUNCH_LO_EXP(x,e,v,lv) if ((unsigned int) e <= (unsigned int) (128 - lv)) \
01089 {e = (unsigned int) e + lv; x *= 1/v;}
01090 UNMUNCH_LO_EXP (*x, e, 18446744073709551616.0, 64);
01091 UNMUNCH_LO_EXP (*x, e, 4294967296.0, 32);
01092 UNMUNCH_LO_EXP (*x, e, 65536.0, 16);
01093 UNMUNCH_LO_EXP (*x, e, 256.0, 8);
01094 UNMUNCH_LO_EXP (*x, e, 16.0, 4);
01095 UNMUNCH_LO_EXP (*x, e, 4.0, 2);
01096 UNMUNCH_LO_EXP (*x, e, 2.0, 1);
01097 #undef UNMUNCH_LO_EXP
01098 }
01099
01100 return 0;
01101 }
01102
01103 int CCutil_sflush (CC_SFILE * f)
01104 {
01105 int rval;
01106
01107 if (f == (CC_SFILE *) NULL)
01108 {
01109 rval = -1;
01110 }
01111 else if (f->status == SREAD || f->status == SRW_READ)
01112 {
01113 f->bits_in_last_char = 0;
01114 rval = 0;
01115 }
01116 else if (f->status == SWRITE || f->status == SRW_WRITE)
01117 {
01118 rval = swrite_buffer (f);
01119 }
01120 else if (f->status == SRW_EMPTY)
01121 {
01122 rval = 0;
01123 }
01124 else
01125 {
01126 fprintf (stderr, "Buffer %s has invalid status %d\n", f->fname, f->status);
01127 rval = -1;
01128 }
01129
01130 return rval;
01131 }
01132
01133 int CCutil_stell (CC_SFILE * f)
01134 {
01135 if (!f)
01136 return -1;
01137 f->bits_in_last_char = 0;
01138 if (f->status == SREAD)
01139 {
01140 return f->pos - f->chars_in_buffer + f->current_buffer_char + 1;
01141 }
01142 else if (f->status == SWRITE)
01143 {
01144 return f->pos + f->chars_in_buffer;
01145 }
01146 else if (f->status == SRW_EMPTY || f->status == SRW_READ ||
01147 f->status == SRW_WRITE)
01148 {
01149 fprintf (stderr, "Cannot CCutil_stell for a r/w CC_SFILE\n");
01150 return -1;
01151 }
01152 else
01153 {
01154 fprintf (stderr, "Buffer %s has invalid status %d\n", f->fname, f->status);
01155 return -1;
01156 }
01157 }
01158
01159 int CCutil_sseek (CC_SFILE * f,
01160 int offset)
01161 {
01162 int curloc;
01163
01164 if (!f)
01165 return -1;
01166 if (CCutil_sflush (f))
01167 return -1;
01168 curloc = CCutil_stell (f);
01169 if (curloc < 0)
01170 return curloc;
01171 if (curloc == offset)
01172 return 0;
01173 if (lseek (f->desc, offset, SEEK_SET) < 0)
01174 {
01175 perror (f->fname);
01176 fprintf (stderr, "Unable to lseek on %s\n", f->fname);
01177 return -1;
01178 }
01179 f->chars_in_buffer = 0;
01180 f->current_buffer_char = -1;
01181 f->pos = offset;
01182
01183 return 0;
01184 }
01185
01186 int CCutil_srewind (CC_SFILE * f)
01187 {
01188 return CCutil_sseek (f, 0);
01189 }
01190
01191 int CCutil_sclose (CC_SFILE * f)
01192 {
01193 int retval = 0;
01194 char fbuf_O[CC_SFNAME_SIZE + 32];
01195 char fbuf_N[CC_SFNAME_SIZE + 32];
01196
01197 if (!f)
01198 return -1;
01199
01200 if ((f->status == SWRITE || f->status == SRW_WRITE) && f->chars_in_buffer)
01201 {
01202 if (swrite_buffer (f))
01203 retval = -1;
01204 }
01205
01206 if (f->desc >= 3)
01207 {
01208 if (close (f->desc))
01209 {
01210 perror ("close");
01211 fprintf (stderr, "Unable to close swrite file %s\n", f->fname);
01212 retval = -1;
01213 }
01214 if (f->status == SWRITE && f->type == TFILE)
01215 {
01216 sprintf (fbuf_N, "N%s", f->fname);
01217 sprintf (fbuf_O, "O%s", f->fname);
01218 rename (f->fname, fbuf_O);
01219 if (rename (fbuf_N, f->fname))
01220 {
01221 perror (f->fname);
01222 fprintf (stderr, "Couldn't rename %s to %s\n", fbuf_N, f->fname);
01223 retval = -1;
01224 }
01225 }
01226 }
01227
01228 CC_FREE (f, CC_SFILE);
01229
01230 return retval;
01231 }
01232
01233 static int swrite_buffer (CC_SFILE * f)
01234 {
01235 char *p;
01236 int nleft;
01237 int n;
01238
01239 if (!f)
01240 return -1;
01241 if (f->status != SWRITE && f->status != SRW_WRITE && f->status != SRW_EMPTY)
01242 {
01243 fprintf (stderr, "%s not open for output\n", f->fname);
01244 return -1;
01245 }
01246
01247 p = (char *) f->buffer;
01248 nleft = f->chars_in_buffer;
01249 while (nleft)
01250 {
01251 n = (int) write (f->desc, p, (unsigned) nleft);
01252 if (n == -1)
01253 {
01254 if (errno == EINTR)
01255 {
01256 fprintf (stderr, "swrite_buffer interrupted, retrying\n");
01257 continue;
01258 }
01259 perror ("write");
01260 fprintf (stderr, "swrite_buffer of %d chars to %s failed\n", nleft,
01261 f->fname);
01262 return -1;
01263 }
01264 nleft -= n;
01265 p += n;
01266 f->pos += n;
01267 }
01268 f->bits_in_last_char = 0;
01269 f->chars_in_buffer = 0;
01270 return 0;
01271 }
01272
01273 static int sread_buffer (CC_SFILE * f)
01274 {
01275 int n;
01276
01277 if (!f)
01278 return -1;
01279 if (f->status != SREAD && f->status != SRW_READ && f->status != SRW_EMPTY)
01280 {
01281 fprintf (stderr, "%s not open for input\n", f->fname);
01282 return -1;
01283 }
01284
01285 if (f->current_buffer_char + 1 == f->chars_in_buffer)
01286 {
01287 f->chars_in_buffer = 0;
01288 f->current_buffer_char = -1;
01289 }
01290 if (f->chars_in_buffer == CC_SBUFFER_SIZE)
01291 {
01292 fprintf (stderr, "sread_buffer for %s when buffer full\n", f->fname);
01293 return 0;
01294 }
01295
01296 retry:
01297 n = (int) read (f->desc, (char *) f->buffer + f->chars_in_buffer,
01298 (unsigned) (CC_SBUFFER_SIZE - f->chars_in_buffer));
01299
01300 if (n == -1)
01301 {
01302 if (errno == EINTR)
01303 {
01304 fprintf (stderr, "sread_buffer interrupted, retrying\n");
01305 goto retry;
01306 }
01307 perror ("read");
01308 fprintf (stderr, "sread_buffer failed\n");
01309 return -1;
01310 }
01311 if (n == 0)
01312 {
01313 fprintf (stderr, "sread_buffer encountered EOF\n");
01314 return -1;
01315 }
01316 f->pos += n;
01317 f->chars_in_buffer += n;
01318
01319 if (f->status == SRW_EMPTY)
01320 f->status = SRW_READ;
01321
01322 return 0;
01323 }
01324
01325 static void sinit (CC_SFILE * s)
01326 {
01327 s->status = 0;
01328 s->desc = -1;
01329 s->type = 0;
01330 s->chars_in_buffer = 0;
01331 s->current_buffer_char = -1;
01332 s->bits_in_last_char = 0;
01333 s->pos = 0;
01334 s->fname[0] = '\0';
01335 }
01336
01337 int CCutil_sbits (unsigned int x)
01338 {
01339 int i;
01340 int ux = x;
01341 unsigned int b;
01342
01343 i = 32;
01344 b = ((unsigned int) 1) << 31;
01345 while ((ux & b) == 0 && i > 1)
01346 {
01347 b >>= 1;
01348 i--;
01349 }
01350 return i;
01351 }
01352
01353 int CCutil_sdelete_file (const char *fname)
01354 {
01355 int rval;
01356
01357 rval = unlink (fname);
01358 if (rval)
01359 {
01360 perror (fname);
01361 fprintf (stderr, "unlink: could not delete %s\n", fname);
01362 }
01363 return rval;
01364 }
01365
01366 int CCutil_sdelete_file_backup (const char *fname)
01367 {
01368 int rval;
01369 char fbuf_O[CC_SFNAME_SIZE + 32];
01370
01371 sprintf (fbuf_O, "O%s", fname);
01372 rval = unlink (fbuf_O);
01373
01374 return rval;
01375 }
01376
01377 static int prepare_write (CC_SFILE * f)
01378 {
01379 if (!f)
01380 return -1;
01381 if (f->status == SREAD)
01382 {
01383 fprintf (stderr, "%s not open for output\n", f->fname);
01384 return -1;
01385 }
01386 else if (f->status == SRW_READ)
01387 {
01388 f->chars_in_buffer = 0;
01389 f->current_buffer_char = -1;
01390 f->bits_in_last_char = 0;
01391 f->status = SRW_WRITE;
01392 }
01393 else if (f->status == SRW_EMPTY)
01394 {
01395 f->status = SRW_WRITE;
01396 }
01397 else if (f->status != SWRITE && f->status != SRW_WRITE)
01398 {
01399 fprintf (stderr, "%s has bogus status %d\n", f->fname, f->status);
01400 return -1;
01401 }
01402
01403 return 0;
01404 }
01405
01406 static int prepare_read (CC_SFILE * f)
01407 {
01408 if (!f)
01409 return -1;
01410 if (f->status == SWRITE)
01411 {
01412 fprintf (stderr, "%s not open for input\n", f->fname);
01413 return -1;
01414 }
01415 else if (f->status == SRW_WRITE)
01416 {
01417 if (CCutil_sflush (f))
01418 return -1;
01419 f->chars_in_buffer = 0;
01420 f->current_buffer_char = -1;
01421 f->bits_in_last_char = 0;
01422 f->status = SRW_EMPTY;
01423 }
01424 else if (f->status != SREAD && f->status != SRW_READ &&
01425 f->status != SRW_EMPTY)
01426 {
01427 fprintf (stderr, "%s has bogus status %d\n", f->fname, f->status);
01428 return -1;
01429 }
01430
01431 return 0;
01432 }
01433
01434 #ifdef CC_NETREADY
01435
01436 CC_SFILE *CCutil_snet_open (const char *hname,
01437 unsigned p)
01438 {
01439 struct hostent *h;
01440 struct sockaddr_in hsock;
01441 int s;
01442 int nerror = 0;
01443 CC_SFILE *f = (CC_SFILE *) NULL;
01444
01445 memset ((void *) &hsock, 0, sizeof (hsock));
01446
01447 GETHOSTBYNAME:
01448 h = gethostbyname (hname);
01449 if (h == (struct hostent *) NULL)
01450 {
01451 perror ("gethostbyname");
01452 nerror++;
01453 if (nerror < 100)
01454 {
01455 fprintf (stderr, " sleep for 10 secnds and try again\n");
01456 sleep (10);
01457 goto GETHOSTBYNAME;
01458 }
01459 fprintf (stderr, "cannot get host info for %s\n", hname);
01460 return (CC_SFILE *) NULL;
01461 }
01462 memcpy ((void *) &hsock.sin_addr, (void *) h->h_addr, (unsigned) h->h_length);
01463 hsock.sin_family = AF_INET;
01464 hsock.sin_port = htons (p);
01465
01466 SOCKET:
01467 s = socket (AF_INET, SOCK_STREAM, 0);
01468 if (s < 0)
01469 {
01470 nerror++;
01471 perror ("socket");
01472 if (nerror < 100)
01473 {
01474 fprintf (stderr, " sleep for 10 secnds and try again\n");
01475 sleep (10);
01476 goto SOCKET;
01477 }
01478 fprintf (stderr, "Unable to get socket\n");
01479 return (CC_SFILE *) NULL;
01480 }
01481
01482 CONNECT:
01483 if (connect (s, (struct sockaddr *) &hsock, sizeof (hsock)) < 0)
01484 {
01485 nerror++;
01486 perror ("connect");
01487 if (nerror < 100)
01488 {
01489 fprintf (stderr, " sleep for 10 secnds and try again\n");
01490 sleep (10);
01491 goto CONNECT;
01492 }
01493 fprintf (stderr, "Unable to connect to %s\n", hname);
01494 return (CC_SFILE *) NULL;
01495 }
01496
01497 OPENRW:
01498 f = sdopen_readwrite (s);
01499 if (f == (CC_SFILE *) NULL)
01500 {
01501 nerror++;
01502 if (nerror < 100)
01503 {
01504 sleep (10);
01505 goto OPENRW;
01506 }
01507 fprintf (stderr, "sdopen_readwrite failed\n");
01508 return (CC_SFILE *) NULL;
01509 }
01510
01511 return f;
01512 }
01513
01514 CC_SFILE *CCutil_snet_receive (CC_SPORT * s)
01515 {
01516 struct sockaddr_in new;
01517 int l;
01518 int t;
01519 CC_SFILE *f = (CC_SFILE *) NULL;
01520
01521 memset ((void *) &new, 0, sizeof (new));
01522 new.sin_family = AF_INET;
01523 new.sin_addr.s_addr = INADDR_ANY;
01524 new.sin_port = 0;
01525 l = sizeof (new);
01526
01527 t = accept (s->t, (struct sockaddr *) &new, (unsigned *) (&l));
01528 if (t < 0)
01529 {
01530 perror ("accept");
01531 fprintf (stderr, "accept failed\n");
01532 return (CC_SFILE *) NULL;
01533 }
01534
01535 f = sdopen_readwrite (t);
01536 if (f == (CC_SFILE *) NULL)
01537 {
01538 fprintf (stderr, "sdopen_readwrite failed\n");
01539 return (CC_SFILE *) NULL;
01540 }
01541
01542 return f;
01543 }
01544
01545 CC_SPORT *CCutil_snet_listen (unsigned p)
01546 {
01547 int s = -1;
01548 struct sockaddr_in me;
01549 CC_SPORT *sp = (CC_SPORT *) NULL;
01550
01551 s = socket (AF_INET, SOCK_STREAM, 0);
01552 if (s < 0)
01553 {
01554 perror ("socket");
01555 fprintf (stderr, "Unable to get socket\n");
01556 goto FAILURE;
01557 }
01558
01559 memset ((void *) &me, 0, sizeof (me));
01560
01561 me.sin_addr.s_addr = INADDR_ANY;
01562 me.sin_family = AF_INET;
01563 me.sin_port = htons ((uint16_t) p);
01564
01565 if (bind (s, (struct sockaddr *) &me, sizeof (me)) < 0)
01566 {
01567 perror ("bind");
01568 fprintf (stderr, "Cannot bind socket\n");
01569 goto FAILURE;
01570 }
01571
01572 if (listen (s, 100) < 0)
01573 {
01574 perror ("listen");
01575 fprintf (stderr, "Cannot listen to socket\n");
01576 goto FAILURE;
01577 }
01578
01579 sp = CC_SAFE_MALLOC (1, CC_SPORT);
01580 if (sp == (CC_SPORT *) NULL)
01581 {
01582 fprintf (stderr, "Out of memory in CCutil_snet_listen\n");
01583 goto FAILURE;
01584 }
01585
01586 sp->t = s;
01587 sp->port = p;
01588
01589 return sp;
01590
01591 FAILURE:
01592 if (s >= 0)
01593 close (s);
01594 CC_IFFREE (sp, CC_SPORT);
01595 return (CC_SPORT *) NULL;
01596 }
01597
01598 void CCutil_snet_unlisten (CC_SPORT * s)
01599 {
01600 if (s != (CC_SPORT *) NULL)
01601 {
01602 close (s->t);
01603 CC_FREE (s, CC_SPORT);
01604 }
01605 }
01606
01607 #endif