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