bc_safe_io.c

Go to the documentation of this file.
00001 /****************************************************************************/
00002 /*                                                                          */
00003 /*  This file is part of CONCORDE                                           */
00004 /*                                                                          */
00005 /*  (c) Copyright 1995--1999 by David Applegate, Robert Bixby,              */
00006 /*  Vasek Chvatal, and William Cook                                         */
00007 /*                                                                          */
00008 /*  Permission is granted for academic research use.  For other uses,       */
00009 /*  contact the authors for licensing options.                              */
00010 /*                                                                          */
00011 /*  Use at your own risk.  We make no guarantees about the                  */
00012 /*  correctness or usefulness of this code.                                 */
00013 /*                                                                          */
00014 /****************************************************************************/
00015 
00016 /****************************************************************************/
00017 /*                                                                          */
00018 /*                    INPUT/OUTPUT ROUTINES                                 */
00019 /*                                                                          */
00020 /*                           TSP CODE                                       */
00021 /*                                                                          */
00022 /* Written by:  Applegate, Bixby, Chvatal, and Cook                         */
00023 /* Date: February 13, 1995                                                  */
00024 /*       September 30, 1997 (dave)                                          */
00025 /*                                                                          */
00026 /*    EXPORTED FUNCTIONS:                                                   */
00027 /*                                                                          */
00028 /*  CC_SFILE *CCutil_sopen (char *f, char *s)                               */
00029 /*      Opens a file for buffered binary I/O.  The buffered binary I/O      */
00030 /*      routines using CC_SFILE's attempt to be machine independent,        */
00031 /*      and only compatible with themselves.  Comparable to the stdio       */
00032 /*      routine fopen().  If the file already exists and is being           */
00033 /*      opened for output, the old file is renamed by prepending an O       */
00034 /*      to is name.                                                         */
00035 /*    f - the filename to open.  "stdin" means descriptor 0, "stdout"       */
00036 /*        descriptor 1, and "stderr" descriptor 2.  "-" means               */
00037 /*        descriptor 0 or 1, depending on wither the file is opened         */
00038 /*        for reading or writing.                                           */
00039 /*    s - the mode to open, either "r" for input, or "w" for output.        */
00040 /*    returns a pointer to the opened file, or NULL if there is an          */
00041 /*        error.                                                            */
00042 /*                                                                          */
00043 /*  CC_SFILE *CCutil_sdopen (int d, char *s)                                */
00044 /*      Opens a descriptor for buffered binary I/O.  The buffered binary    */
00045 /*      I/O routines using CC_SFILE's attempt to be machine independent,    */
00046 /*      and only compatible with themselves.  Comparable to the stdio       */
00047 /*      routine fdopen().                                                   */
00048 /*    d - the descriptor to open.                                           */
00049 /*    s - the mode to open, either "r" for input, "w" for output, or        */
00050 /*        "rw" for both input and output.                                   */
00051 /*    returns a pointer to the opened file, or NULL if there is an          */
00052 /*        error.                                                            */
00053 /*                                                                          */
00054 /*  int CCutil_swrite (CC_SFILE *f, char *buf, int size)                    */
00055 /*      writes to a buffered binary I/O file.                               */
00056 /*    f - the CC_SFILE to write to                                          */
00057 /*    buf - the data to write                                               */
00058 /*    size - the number of bytes to write.                                  */
00059 /*    returns 0 if succesful, nonzero if failure.                           */
00060 /*                                                                          */
00061 /*  int CCutil_swrite_bits (CC_SFILE *f, int x, int xbits)                  */
00062 /*      writes bits to a buffered binary I/O file.                          */
00063 /*    f - the CC_SFILE to write to                                          */
00064 /*    x - an int containing the data to write                               */
00065 /*    xbits - the number of bits to write.  The lowest order xbits          */
00066 /*            bits of x will be written.                                    */
00067 /*    returns 0 if succesful, nonzero if failure.                           */
00068 /*                                                                          */
00069 /*  int CCutil_swrite_ubits (CC_SFILE *f, unsigned int x, int xbits)        */
00070 /*      writes bits to a buffered binary I/O file.                          */
00071 /*    f - the CC_SFILE to write to                                          */
00072 /*    x - an unsigned int int containing the data to write                  */
00073 /*    xbits - the number of bits to write.  The lowest order xbits          */
00074 /*            bits of x will be written.                                    */
00075 /*    returns 0 if succesful, nonzero if failure.                           */
00076 /*                                                                          */
00077 /*  int CCutil_swrite_char (CC_SFILE *f, char x)                            */
00078 /*      writes a char to a buffered binary I/O file.                        */
00079 /*    f - the CC_SFILE to write to                                          */
00080 /*    x - the char to write                                                 */
00081 /*    returns 0 if succesful, nonzero if failure.                           */
00082 /*                                                                          */
00083 /*  int CCutil_swrite_string (CC_SFILE *f, const char *s)                   */
00084 /*      writes a string to a buffered binary I/O file.                      */
00085 /*    f - the CC_SFILE to write to                                          */
00086 /*    s - the string to write.  The array of characters in s up to and      */
00087 /*        including the first NULL are written.                             */
00088 /*    returns 0 if succesful, nonzero if failure.                           */
00089 /*                                                                          */
00090 /*  int CCutil_swrite_short (CC_SFILE *f, short x)                          */
00091 /*      writes a short to a buffered binary I/O file.                       */
00092 /*    f - the CC_SFILE to write to                                          */
00093 /*    x - the short to write                                                */
00094 /*    returns 0 if succesful, nonzero if failure.                           */
00095 /*                                                                          */
00096 /*  int CCutil_swrite_ushort (CC_SFILE *f, unsigned short x)                */
00097 /*      writes an unsigned short to a buffered binary I/O file.             */
00098 /*    f - the CC_SFILE to write to                                          */
00099 /*    x - the unsigned short to write                                       */
00100 /*    returns 0 if succesful, nonzero if failure.                           */
00101 /*                                                                          */
00102 /*  int CCutil_swrite_int (CC_SFILE *f, int x)                              */
00103 /*      writes an int to a buffered binary I/O file.                        */
00104 /*    f - the CC_SFILE to write to                                          */
00105 /*    x - the int to write                                                  */
00106 /*    returns 0 if succesful, nonzero if failure.                           */
00107 /*                                                                          */
00108 /*  int CCutil_swrite_uint (CC_SFILE *f, unsigned int x)                    */
00109 /*      writes an unsigned int to a buffered binary I/O file.               */
00110 /*    f - the CC_SFILE to write to                                          */
00111 /*    x - the unsigned int to write                                         */
00112 /*    returns 0 if succesful, nonzero if failure.                           */
00113 /*                                                                          */
00114 /*  int CCutil_swrite_double (CC_SFILE *f, double x)                        */
00115 /*      writes a double to a buffered binary I/O file.                      */
00116 /*    f - the CC_SFILE to write to                                          */
00117 /*    x - the double to write                                               */
00118 /*    returns 0 if succesful, nonzero if failure.                           */
00119 /*                                                                          */
00120 /*  int CCutil_sread (CC_SFILE *f, char *buf, int size)                     */
00121 /*      reads from a buffered binary I/O file.                              */
00122 /*    f - the CC_SFILE to read from.                                        */
00123 /*    buf - a buffer in which to store the data read.  buf should have      */
00124 /*          space for size characters.                                      */
00125 /*    size - the number of bytes to read.                                   */
00126 /*    returns 0 if succesful, nonzero if failure.                           */
00127 /*                                                                          */
00128 /*  int CCutil_sread_bits (CC_SFILE *f, int *x, int xbits)                  */
00129 /*      reads bits from a buffered binary I/O file.                         */
00130 /*    f - the CC_SFILE to read from.                                        */
00131 /*    x - on return, will contain the bits read (in the low-order           */
00132 /*        xbits bits).                                                      */
00133 /*    xbits - the number of bits read.                                      */
00134 /*    returns 0 if succesful, nonzero if failure.                           */
00135 /*                                                                          */
00136 /*  int CCutil_sread_ubits (CC_SFILE *f, unsigned int *x, int xbits)        */
00137 /*      reads bits from a buffered binary I/O file.                         */
00138 /*    f - the CC_SFILE to read from.                                        */
00139 /*    x - on return, will contain the bits read (in the low-order           */
00140 /*        xbits bits).                                                      */
00141 /*    xbits - the number of bits read.                                      */
00142 /*    returns 0 if succesful, nonzero if failure.                           */
00143 /*                                                                          */
00144 /*  int CCutil_sread_char (CC_SFILE *f, char *x)                            */
00145 /*      reads a char from a buffered binary I/O file.                       */
00146 /*    f - the CC_SFILE to read from.                                        */
00147 /*    x - on return, will contain the char read                             */
00148 /*    returns 0 if succesful, nonzero if failure.                           */
00149 /*                                                                          */
00150 /*  int CCutil_sread_string (CC_SFILE *f, char *x, int maxlen)              */
00151 /*      reads a string from a buffered binary I/O file.                     */
00152 /*    f - the CC_SFILE to read from.                                        */
00153 /*    x - on return, will contain the string read.                          */
00154 /*    maxlen - the maximum number of characters to read.                    */
00155 /*    returns 0 if succesful, nonzero if failure.                           */
00156 /*                                                                          */
00157 /*  int CCutil_sread_short (CC_SFILE *f, short *x)                          */
00158 /*      reads a short from a buffered binary I/O file.                      */
00159 /*    f - the CC_SFILE to read from.                                        */
00160 /*    x - on return, will contain the short read                            */
00161 /*    returns 0 if succesful, nonzero if failure.                           */
00162 /*                                                                          */
00163 /*  int CCutil_sread_ushort (CC_SFILE *f, unsigned short *x)                */
00164 /*      reads an unsigned short from a buffered binary I/O file.            */
00165 /*    f - the CC_SFILE to read from.                                        */
00166 /*    x - on return, will contain the unsigned short read                   */
00167 /*    returns 0 if succesful, nonzero if failure.                           */
00168 /*                                                                          */
00169 /*  int CCutil_sread_short_r (CC_SFILE *f, short *x)                        */
00170 /*      reads a reversed short from a buffered binary I/O file.             */
00171 /*    f - the CC_SFILE to read from.                                        */
00172 /*    x - on return, will contain the short read                            */
00173 /*    returns 0 if succesful, nonzero if failure.                           */
00174 /*    CCutil_sread_short_r is provided for compatability with some          */
00175 /*    binary files written by other tools which use a different byte        */
00176 /*    order.                                                                */
00177 /*                                                                          */
00178 /*  int CCutil_sread_int (CC_SFILE *f, int *x)                              */
00179 /*      reads an int from a buffered binary I/O file.                       */
00180 /*    f - the CC_SFILE to read from.                                        */
00181 /*    x - on return, will contain the int read                              */
00182 /*    returns 0 if succesful, nonzero if failure.                           */
00183 /*                                                                          */
00184 /*  int CCutil_sread_uint (CC_SFILE *f, unsigned int *x)                    */
00185 /*      reads an unsigned int from a buffered binary I/O file.              */
00186 /*    f - the CC_SFILE to read from.                                        */
00187 /*    x - on return, will contain the unsigned int read                     */
00188 /*    returns 0 if succesful, nonzero if failure.                           */
00189 /*                                                                          */
00190 /*  int CCutil_sread_int_r (CC_SFILE *f, int *x)                            */
00191 /*      reads a reversed int from a buffered binary I/O file.               */
00192 /*    f - the CC_SFILE to read from.                                        */
00193 /*    x - on return, will contain the int read                              */
00194 /*    returns 0 if succesful, nonzero if failure.                           */
00195 /*    CCutil_sread_int_r is provided for compatability with some            */
00196 /*    binary files written by other tools which use a different byte        */
00197 /*    order.                                                                */
00198 /*                                                                          */
00199 /*  int CCutil_sread_double (CC_SFILE *f, double *x)                        */
00200 /*      reads a double from a buffered binary I/O file.                     */
00201 /*    f - the CC_SFILE to read from.                                        */
00202 /*    x - on return, will contain the double read                           */
00203 /*    returns 0 if succesful, nonzero if failure.                           */
00204 /*                                                                          */
00205 /*  int CCutil_sread_double_r (CC_SFILE *f, double *x)                      */
00206 /*      reads a reversed double from a buffered binary I/O file.            */
00207 /*    f - the CC_SFILE to read from.                                        */
00208 /*    x - on return, will contain the double read                           */
00209 /*    returns 0 if succesful, nonzero if failure.                           */
00210 /*    CCutil_sread_double_r is provided for compatability with some         */
00211 /*    binary files written by other tools which use a different byte        */
00212 /*    order.                                                                */
00213 /*                                                                          */
00214 /*  int CCutil_sflush (CC_SFILE *f)                                         */
00215 /*      flushes the buffer of a buffered binary I/O file.                   */
00216 /*    f - the CC_SFILE to flush                                             */
00217 /*    returns 0 if succesful, nonzero if failure.                           */
00218 /*                                                                          */
00219 /*  int CCutil_stell (CC_SFILE *f)                                          */
00220 /*      returns the current location in a buffered binary I/O file.         */
00221 /*      Comparable to the stdio function ftell().                           */
00222 /*    f - the CC_SFILE                                                      */
00223 /*    returns the current location, or -1 for failure.                      */
00224 /*                                                                          */
00225 /*  int CCutil_sseek (CC_SFILE *f, int offset)                              */
00226 /*      changes the current location in a buffered binary I/O file.         */
00227 /*      Comparable to the stdio function fseek().                           */
00228 /*    f - the CC_SFILE                                                      */
00229 /*    offset - a value returned by CCutil_stell().                          */
00230 /*    returns 0 for success, nonzero for failure.                           */
00231 /*                                                                          */
00232 /*  int CCutil_srewind (CC_SFILE *f)                                        */
00233 /*      changes the current location in a buffered binary I/O file to       */
00234 /*      the beginning.  Comparable to the stdio function rewind().          */
00235 /*    f - the CC_SFILE                                                      */
00236 /*    returns 0 for success, nonzero for failure.                           */
00237 /*                                                                          */
00238 /*  int CCutil_sclose (CC_SFILE *f)                                         */
00239 /*      closes a CC_SFILE.                                                  */
00240 /*    f - the CC_SFILE to close                                             */
00241 /*    returns 0 for success, nonzero for failure.                           */
00242 /*                                                                          */
00243 /*  int CCutil_sbits (unsigned int x)                                       */
00244 /*      computes the number of bits necessary to represent all              */
00245 /*      nonnegative integers <= x                                           */
00246 /*    x - a number                                                          */
00247 /*    returns the number of bits necessary to represent x.                  */
00248 /*                                                                          */
00249 /*  int CCutil_sdelete_file (const char *fname)                             */
00250 /*      deletes a file.                                                     */
00251 /*    fname - the file to delete                                            */
00252 /*    returns 0 for success, nonzero for failure.                           */
00253 /*                                                                          */
00254 /*  int CCutil_sdelete_file_backup (const char *fname)                      */
00255 /*      deletes the backup file for fname (created if fname was             */
00256 /*      overwritten by CCutil_sopen).                                       */
00257 /*    fname - the file name whose backup is to be deleted.                  */
00258 /*    returns 0 for success, nonzero for failure.                           */
00259 /*                                                                          */
00260 /*  CC_SFILE *CCutil_snet_open (char *h, unsigned p)                  */
00261 /*      Opens a network connection to a port on a remote host               */
00262 /*    h - the name of the host to connect to                                */
00263 /*    p - the port on the host to connect to                                */
00264 /*    returns a CC_SFILE (opened for input and output) for buffered         */
00265 /*            binary I/O to the specified port on the remote host,          */
00266 /*            or NULL if there is a failure.                                */
00267 /*    Only exists if CC_NETREADY is defined                                 */
00268 /*                                                                          */
00269 /*  CC_SFILE *CCutil_snet_receive (CC_SPORT *s)                             */
00270 /*      Accepts a network connection on a port.                             */
00271 /*    s - the CC_SPORT to accept a connection from.  Must be the            */
00272 /*        returned result of a successfull CCutil_snet_listen call.         */
00273 /*    returns a CC_SFILE (opened for input and output) for buffered         */
00274 /*        binary I/O on the specified port, or NULL if there is a           */
00275 /*        failure.                                                          */
00276 /*    Only exists if CC_NETREADY is defined                                 */
00277 /*                                                                          */
00278 /*  CC_SPORT *CCutil_snet_listen (unsigned p)                         */
00279 /*      Prepares to accept network connections on a port.                   */
00280 /*    p - the port on which to accept connections.                          */
00281 /*    returns a CC_SPORT for accepting connections on the specified         */
00282 /*        port.  This return value is passed to CCutil_snet_receive to      */
00283 /*        accept a connection.  Returns NULL if there is a failure.         */
00284 /*    Only exists if CC_NETREADY is defined                                 */
00285 /*                                                                          */
00286 /*  void CCutil_snet_unlisten (CC_SPORT *s)                                 */
00287 /*      Ceases accepting network connections from an CC_SPORT.              */
00288 /*    s - the CC_SPORT to close.                                            */
00289 /*    Only exists if CC_NETREADY is defined                                 */
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 /* VERSION A3 */
00314 
00315 /* CCutil_sopen interprets filenames "stdin" as descriptor 0, "stdout" as
00316  * descriptor 1, and "stderr" as descriptor 2.  "-" is interpreted as
00317  * 0 or 1, depending on whether the file is opened for reading or writing.
00318  *
00319  * CCutil_sclose doesn't close descriptors 0, 1, and 2.
00320  */
00321 
00322 /* When writing, written data extends from buffer[0] bit 7 through
00323  * buffer[chars_in_buffer-1] bit bits_in_last_char.  Empty space extends
00324  * from buffer[chars_in_buffer-1] bit bits_in_last_char-1 through
00325  * buffer[CC_SBUFFER_SIZE-1] bit 0.
00326  *
00327  * When reading, read data extends from buffer[0] bit 7 through
00328  * buffer[current_buffer_char] bit bits_in_last_char.  unread data
00329  * extends from buffer[current_buffer_char] bit bits_in_last_char-1
00330  * through buffer[chars_in_buffer-1] bit 0.  Empty space extends from
00331  * buffer[chars_in_buffer] bit 7 through buffer[CC_SBUFFER_SIZE-1] bit 0.
00332  */
00333 
00334 /* If the routines detect an error, they return -1.
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 /* CC_NETREADY */

Generated on Thu Oct 20 14:58:40 2005 for DominoParitySeparator by  doxygen 1.4.5