1 /*  IO.c  */
2 
3 #include "../IVL.h"
4 
5 static const char *suffixb = ".ivlb" ;
6 static const char *suffixf = ".ivlf" ;
7 
8 /*--------------------------------------------------------------------*/
9 /*
10    -----------------------------------------------
11    purpose -- to read in an IVL object from a file
12 
13    input --
14 
15       fn -- filename, must be *.ivlb or *.ivlf
16 
17    return value -- 1 if success, 0 if failure
18 
19    created -- 95sep29, cca
20    -----------------------------------------------
21 */
22 int
IVL_readFromFile(IVL * ivl,char * fn)23 IVL_readFromFile (
24    IVL    *ivl,
25    char   *fn
26 ) {
27 FILE   *fp ;
28 int    fnlength, rc, sulength ;
29 /*
30    ---------------
31    check the input
32    ---------------
33 */
34 if ( ivl == NULL || fn == NULL ) {
35    fprintf(stderr,
36     "\n error in IVL_readFromFile(%p,%s), file %s, line %d"
37     "\n bad input\n", ivl, fn, __FILE__, __LINE__) ;
38    return(0) ;
39 }
40 switch ( ivl->type ) {
41 case IVL_CHUNKED :
42 case IVL_SOLO    :
43 case IVL_UNKNOWN :
44    break ;
45 default :
46    fprintf(stderr, "\n error in IVL_readFromFile(%p,%s)"
47     "\n bad type = %d", ivl, fn, ivl->type) ;
48    return(0) ;
49 }
50 /*
51    -------------
52    read the file
53    -------------
54 */
55 fnlength = strlen(fn) ;
56 sulength = strlen(suffixb) ;
57 if ( fnlength > sulength ) {
58    if ( strcmp(&fn[fnlength-sulength], suffixb) == 0 ) {
59       if ( (fp = fopen(fn, "rb")) == NULL ) {
60          fprintf(stderr, "\n error in IVL_readFromFile(%p,%s)"
61                  "\n unable to open file %s", ivl, fn, fn) ;
62          rc = 0 ;
63       } else {
64          rc = IVL_readFromBinaryFile(ivl, fp) ;
65          fclose(fp) ;
66       }
67    } else if ( strcmp(&fn[fnlength-sulength], suffixf) == 0 ) {
68       if ( (fp = fopen(fn, "r")) == NULL ) {
69          fprintf(stderr, "\n error in IVL_readFromFile(%p,%s)"
70                  "\n unable to open file %s", ivl, fn, fn) ;
71          rc = 0 ;
72       } else {
73          rc = IVL_readFromFormattedFile(ivl, fp) ;
74          fclose(fp) ;
75       }
76    } else {
77       fprintf(stderr, "\n error in IVL_readFromFile(%p,%s)"
78               "\n bad IVL file name %s,"
79               "\n must end in %s (binary) or %s (formatted)\n",
80               ivl, fn, fn, suffixb, suffixf) ;
81       rc = 0 ;
82    }
83 } else {
84    fprintf(stderr, "\n error in IVL_readFromFile(%p,%s)"
85        "\n bad IVL file name %s,"
86        "\n must end in %s (binary) or %s (formatted)\n",
87        ivl, fn, fn, suffixb, suffixf) ;
88    rc = 0 ;
89 }
90 return(rc) ; }
91 
92 /*--------------------------------------------------------------------*/
93 /*
94    ------------------------------------------------------
95    purpose -- to read an IVL object from a formatted file
96 
97    return value -- 1 if success, 0 if failure
98 
99    created -- 95sep29, cca
100    ------------------------------------------------------
101 */
102 int
IVL_readFromFormattedFile(IVL * ivl,FILE * fp)103 IVL_readFromFormattedFile (
104    IVL    *ivl,
105    FILE   *fp
106 ) {
107 int   nlist, rc, type ;
108 int   itemp[3] ;
109 int   *sizes ;
110 /*
111    ---------------
112    check the input
113    ---------------
114 */
115 if ( ivl == NULL || fp == NULL ) {
116    fprintf(stderr, "\n error in IVL_readFromFormattedFile(%p,%p)"
117            "\n bad input\n", ivl, fp) ;
118    return(0) ;
119 }
120 switch ( ivl->type ) {
121 case IVL_CHUNKED :
122 case IVL_SOLO    :
123    break ;
124 default :
125    fprintf(stderr, "\n error in IVL_readFormattedFile(%p,%p)"
126     "\n bad type = %d", ivl, fp, ivl->type) ;
127    return(0) ;
128 }
129 /*
130    -------------------------------------------
131    save the ivl type and clear the data fields
132    -------------------------------------------
133 */
134 type = ivl->type ;
135 IVL_clearData(ivl) ;
136 /*
137    -----------------------------------
138    read in the three scalar parameters
139    type, # of lists, # of indices
140    -----------------------------------
141 */
142 if ( (rc = IVfscanf(fp, 3, itemp)) != 3 ) {
143    fprintf(stderr, "\n error in IVL_readFromFormattedFile(%p,%p)"
144            "\n %d items of %d read\n", ivl, fp, rc, 3) ;
145    return(0) ;
146 }
147 nlist = itemp[1] ;
148 /*
149 fprintf(stdout, "\n itemp = { %d %d %d } ",
150         itemp[0], itemp[1], itemp[2]) ;
151 */
152 /*
153    --------------------------
154    read in the sizes[] vector
155    --------------------------
156 */
157 sizes = IVinit(nlist, 0) ;
158 if ( (rc = IVfscanf(fp, nlist, sizes)) != nlist ) {
159    fprintf(stderr, "\n error in IVL_readFromFormattedFile(%p,%p)"
160            "\n %d items of %d read\n", ivl, fp, rc, nlist) ;
161    return(0) ;
162 }
163 /*
164    ---------------------
165    initialize the object
166    ---------------------
167 */
168 IVL_init3(ivl, type, nlist, sizes) ;
169 IVfree(sizes) ;
170 /*
171    -----------------------
172    now read in the indices
173    -----------------------
174 */
175 switch ( type ) {
176 case IVL_SOLO : {
177    int   ilist, size ;
178    int   *ind ;
179 
180    for ( ilist = 0 ; ilist < nlist ; ilist++ ) {
181       IVL_listAndSize(ivl, ilist, &size, &ind) ;
182       if ( size > 0 ) {
183          if ( (rc = IVfscanf(fp, size, ind)) != size ) {
184             fprintf(stderr,
185                     "\n error in IVL_readFromFormattedFile(%p,%p)"
186                     "\n list %d, %d items of %d read\n",
187                     ivl, fp, ilist, rc, size) ;
188             return(0) ;
189          }
190       }
191    }
192    } break ;
193 case IVL_CHUNKED : {
194 /*
195    --------------------------------------------------------
196    read in the indices into the contiguous block of storage
197    --------------------------------------------------------
198 */
199    if ( (rc = IVfscanf(fp, ivl->tsize, ivl->chunk->base))
200         != ivl->tsize ) {
201       fprintf(stderr, "\n error in IVL_readFromFormattedFile(%p,%p)"
202               "\n %d items of %d read\n", ivl, fp, rc, ivl->tsize) ;
203       return(0) ;
204    }
205    } break ;
206 }
207 return(1) ; }
208 
209 /*--------------------------------------------------------------------*/
210 /*
211    ---------------------------------------------------
212    purpose -- to read an IVL object from a binary file
213 
214    return value -- 1 if success, 0  if failure
215 
216    created -- 95sep29, cca
217    ---------------------------------------------------
218 */
219 int
IVL_readFromBinaryFile(IVL * ivl,FILE * fp)220 IVL_readFromBinaryFile (
221    IVL    *ivl,
222    FILE   *fp
223 ) {
224 int   nlist, rc, type ;
225 int   itemp[3] ;
226 int   *sizes ;
227 /*
228    ---------------
229    check the input
230    ---------------
231 */
232 if ( ivl == NULL || fp == NULL ) {
233    fprintf(stderr, "\n fatal error in IVL_readFromBinaryFile(%p,%p)"
234            "\n bad input\n", ivl, fp) ;
235    return(0) ;
236 }
237 switch ( ivl->type ) {
238 case IVL_CHUNKED :
239 case IVL_SOLO    :
240    break ;
241 default :
242    fprintf(stderr, "\n error in IVL_readBinaryFile(%p,%p)"
243     "\n bad type = %d", ivl, fp, ivl->type) ;
244    return(0) ;
245 }
246 /*
247    -------------------------------------------
248    save the ivl type and clear the data fields
249    -------------------------------------------
250 */
251 type = ivl->type ;
252 IVL_clearData(ivl) ;
253 /*
254    -----------------------------------
255    read in the three scalar parameters
256    type, # of lists, # of indices
257    -----------------------------------
258 */
259 if ( (rc = fread((void *) itemp, sizeof(int), 3, fp)) != 3 ) {
260    fprintf(stderr, "\n error in IVL_readFromBinaryFile(%p,%p)"
261            "\n itemp(3) : %d items of %d read\n", ivl, fp, rc, 3) ;
262    return(0) ;
263 }
264 nlist = itemp[1] ;
265 /*
266    --------------------------
267    read in the sizes[] vector
268    --------------------------
269 */
270 sizes = IVinit(nlist, 0) ;
271 if ( (rc = fread((void *) sizes, sizeof(int), nlist, fp)) != nlist ) {
272    fprintf(stderr, "\n error in IVL_readFromBinaryFile(%p,%p)"
273            "\n sizes(%d) : %d items of %d read\n",
274            ivl, fp, nlist, rc, nlist) ;
275    return(0) ;
276 }
277 /*
278    ---------------------
279    initialize the object
280    ---------------------
281 */
282 IVL_init3(ivl, type, nlist, sizes) ;
283 IVfree(sizes) ;
284 /*
285    -------------------
286    read in the indices
287    -------------------
288 */
289 switch ( type ) {
290 case IVL_SOLO : {
291    int   ilist, size ;
292    int   *ind ;
293 
294    for ( ilist = 0 ; ilist < nlist ; ilist++ ) {
295       IVL_listAndSize(ivl, ilist, &size, &ind) ;
296       if ( (rc = fread((void *) ind, sizeof(int), size, fp)) != size ) {
297          fprintf(stderr, "\n error in IVL_readFromBinaryFile(%p,%p)"
298                  "\n list %d, %d items of %d read\n",
299                  ivl, fp, ilist, rc, size) ;
300          return(0) ;
301       }
302    }
303    } break ;
304 case IVL_CHUNKED : {
305 /*
306    --------------------------------------------------------
307    read in the indices into the contiguous block of storage
308    --------------------------------------------------------
309 */
310    if ( (rc = fread((void *) ivl->chunk->base,
311                     sizeof(int), ivl->tsize, fp)) != ivl->tsize ) {
312       fprintf(stderr, "\n error in IVL_readFromBinaryFile(%p,%p)"
313               "\n indices(%d) : %d items of %d read\n",
314               ivl, fp, ivl->tsize, rc, ivl->tsize) ;
315       return(0) ;
316    }
317    } break ;
318 }
319 return(1) ; }
320 
321 /*--------------------------------------------------------------------*/
322 /*
323    -------------------------------------------
324    purpose -- to write an IVL object to a file
325 
326    input --
327 
328       fn -- filename
329         *.ivlb -- binary
330         *.ivlf -- formatted
331         anything else -- for human eye
332 
333    return value -- 1 if success, 0 otherwise
334 
335    created -- 95sep29, cca
336    -------------------------------------------
337 */
338 int
IVL_writeToFile(IVL * ivl,char * fn)339 IVL_writeToFile (
340    IVL    *ivl,
341    char   *fn
342 ) {
343 FILE   *fp ;
344 int    fnlength, rc, sulength ;
345 /*
346    ---------------
347    check the input
348    ---------------
349 */
350 if ( ivl == NULL || fn == NULL ) {
351    fprintf(stderr, "\n fatal error in IVL_writeToFile(%p,%s)"
352     "\n bad input\n", ivl, fn) ;
353 }
354 switch ( ivl->type ) {
355 case IVL_CHUNKED :
356 case IVL_SOLO    :
357 case IVL_UNKNOWN :
358    break ;
359 default :
360    fprintf(stderr, "\n fatal error in IVL_writeToFile(%p,%s)"
361            "\n bad type = %d", ivl, fn, ivl->type) ;
362    return(0) ;
363 }
364 /*
365    ------------------
366    write out the file
367    ------------------
368 */
369 fnlength = strlen(fn) ;
370 sulength = strlen(suffixb) ;
371 if ( fnlength > sulength ) {
372    if ( strcmp(&fn[fnlength-sulength], suffixb) == 0 ) {
373       if ( (fp = fopen(fn, "wb")) == NULL ) {
374          fprintf(stderr, "\n error in IVL_writeToFile(%p,%s)"
375                  "\n unable to open file %s", ivl, fn, fn) ;
376          rc = 0 ;
377       } else {
378          rc = IVL_writeToBinaryFile(ivl, fp) ;
379          fclose(fp) ;
380       }
381    } else if ( strcmp(&fn[fnlength-sulength], suffixf) == 0 ) {
382       if ( (fp = fopen(fn, "w")) == NULL ) {
383          fprintf(stderr, "\n error in IVL_writeToFile(%p,%s)"
384                  "\n unable to open file %s", ivl, fn, fn) ;
385          rc = 0 ;
386       } else {
387          rc = IVL_writeToFormattedFile(ivl, fp) ;
388          fclose(fp) ;
389       }
390    } else {
391       if ( (fp = fopen(fn, "a")) == NULL ) {
392          fprintf(stderr, "\n error in IVL_writeToFile(%p,%s)"
393                  "\n unable to open file %s", ivl, fn, fn) ;
394          rc = 0 ;
395       } else {
396          rc = IVL_writeForHumanEye(ivl, fp) ;
397          fclose(fp) ;
398       }
399    }
400 } else {
401    if ( (fp = fopen(fn, "a")) == NULL ) {
402       fprintf(stderr, "\n error in IVL_writeToFile(%p,%s)"
403               "\n unable to open file %s", ivl, fn, fn) ;
404       rc = 0 ;
405    } else {
406       rc = IVL_writeForHumanEye(ivl, fp) ;
407       fclose(fp) ;
408    }
409 }
410 return(rc) ; }
411 
412 /*--------------------------------------------------------------------*/
413 /*
414    -----------------------------------------------------
415    purpose -- to write an IVL object to a formatted file
416 
417    return value -- 1 if success, 0 otherwise
418 
419    created -- 95sep29, cca
420    -----------------------------------------------------
421 */
422 int
IVL_writeToFormattedFile(IVL * ivl,FILE * fp)423 IVL_writeToFormattedFile (
424    IVL    *ivl,
425    FILE   *fp
426 ) {
427 int   count, ierr, j, jsize, nlist, rc ;
428 int   *jind ;
429 /*
430    ---------------
431    check the input
432    ---------------
433 */
434 if ( ivl == NULL || fp == NULL || (nlist = ivl->nlist) <= 0 ) {
435    fprintf(stderr, "\n fatal error in IVL_writeToFormattedFile(%p,%p)"
436            "\n bad input\n", ivl, fp) ;
437    exit(-1) ;
438 }
439 /*
440    -------------------------------------
441    write out the three scalar parameters
442    -------------------------------------
443 */
444 rc = fprintf(fp, "\n %d %d %d", ivl->type, ivl->nlist, ivl->tsize) ;
445 if ( rc < 0 ) {
446    fprintf(stderr, "\n fatal error in IVL_writeToFormattedFile(%p,%p)"
447            "\n rc = %d, return from first fprintf\n", ivl, fp, rc) ;
448    return(0) ;
449 }
450 if ( ivl->nlist > 0 ) {
451    IVfp80(fp, ivl->nlist, ivl->sizes, 80, &ierr) ;
452    if ( ierr < 0 ) {
453       fprintf(stderr,
454               "\n fatal error in IVL_writeToFormattedFile(%p,%p)"
455               "\n ierr = %d, return from sizes[] IVfp80\n",
456               ivl, fp, ierr) ;
457       return(0) ;
458    }
459 }
460 switch ( ivl->type ) {
461 case IVL_NOTYPE :
462    break ;
463 case IVL_UNKNOWN :
464 case IVL_CHUNKED :
465 case IVL_SOLO    :
466    for ( j = 0, count = 80 ; j < ivl->nlist ; j++ ) {
467       IVL_listAndSize(ivl, j, &jsize, &jind) ;
468       if ( jsize > 0 ) {
469          count = IVfp80(fp, jsize, jind, count, &ierr) ;
470          if ( ierr < 0 ) {
471             fprintf(stderr,
472                     "\n fatal error in IVL_writeToFormattedFile(%p,%p)"
473                     "\n ierr = %d, return from IVfp80, list %d\n",
474                     ivl, fp, ierr, j) ;
475             return(0) ;
476          }
477       }
478    }
479    break ;
480 }
481 
482 return(1) ; }
483 
484 /*--------------------------------------------------------------------*/
485 /*
486    --------------------------------------------------
487    purpose -- to write an IVL object to a binary file
488 
489    return value -- 1 if success, 0 otherwise
490 
491    created -- 95sep29, cca
492    --------------------------------------------------
493 */
494 int
IVL_writeToBinaryFile(IVL * ivl,FILE * fp)495 IVL_writeToBinaryFile (
496    IVL    *ivl,
497    FILE   *fp
498 ) {
499 int   j, jsize, nlist, rc ;
500 int   *jind ;
501 int   itemp[3] ;
502 /*
503    ---------------
504    check the input
505    ---------------
506 */
507 if ( ivl == NULL || fp == NULL || (nlist = ivl->nlist) <= 0 ) {
508    fprintf(stderr, "\n fatal error in IVL_writeToBinaryFile(%p,%p)"
509            "\n bad input\n", ivl, fp) ;
510    exit(-1) ;
511 }
512 itemp[0] = ivl->type ;
513 itemp[1] = ivl->nlist ;
514 itemp[2] = ivl->tsize ;
515 rc = fwrite((void *) itemp, sizeof(int), 3, fp) ;
516 if ( rc != 3 ) {
517    fprintf(stderr, "\n error in IVL_writeToBinaryFile(%p,%p)"
518            "\n %d of %d scalar items written\n", ivl, fp, rc, 3) ;
519    return(0) ;
520 }
521 rc = fwrite((void *) ivl->sizes, sizeof(int), ivl->nlist, fp) ;
522 if ( rc != ivl->nlist ) {
523    fprintf(stderr, "\n error in IVL_writeToBinaryFile(%p,%p)"
524            "\n ivl->sizes, %d of %d items written\n",
525            ivl, fp, rc, ivl->nlist) ;
526    return(0) ;
527 }
528 switch ( ivl->type ) {
529 case IVL_NOTYPE :
530    break ;
531 case IVL_CHUNKED :
532 case IVL_SOLO    :
533 case IVL_UNKNOWN :
534    for ( j = 0 ; j < ivl->nlist ; j++ ) {
535       IVL_listAndSize(ivl, j, &jsize, &jind) ;
536       if ( jsize > 0 ) {
537          rc = fwrite((void *) jind, sizeof(int), jsize, fp) ;
538          if ( rc != jsize ) {
539             fprintf(stderr, "\n error in IVL_writeToBinaryFile(%p,%p)"
540                     "\n list %d, %d of %d items written\n",
541                     ivl, fp, j, rc, jsize) ;
542             return(0) ;
543          }
544       }
545    }
546    break ;
547 }
548 
549 return(1) ; }
550 
551 /*--------------------------------------------------------------------*/
552 /*
553    -------------------------------------------------
554    purpose -- to write an IVL object for a human eye
555 
556    return value -- 1 if success, 0 otherwise
557 
558    created -- 95sep29, cca
559    -------------------------------------------------
560 */
561 int
IVL_writeForHumanEye(IVL * ivl,FILE * fp)562 IVL_writeForHumanEye (
563    IVL    *ivl,
564    FILE   *fp
565 ) {
566 int   ierr, j, size, rc ;
567 int   *ind ;
568 
569 if ( ivl == NULL || fp == NULL ) {
570    fprintf(stderr, "\n fatal error in IVL_writeForHumanEye(%p,%p)"
571            "\n bad input\n", ivl, fp) ;
572    exit(-1) ;
573 }
574 if ( (rc = IVL_writeStats(ivl, fp)) == 0 ) {
575    fprintf(stderr, "\n fatal error in IVL_writeForHumanEye(%p,%p)"
576            "\n rc = %d, return from IVL_writeStats(%p,%p)\n",
577            ivl, fp, rc, ivl, fp) ;
578    return(0) ;
579 }
580 for ( j = 0 ; j < ivl->nlist ; j++ ) {
581    IVL_listAndSize(ivl, j, &size, &ind) ;
582    if ( size > 0 ) {
583       fprintf(fp, "\n %5d :", j) ;
584       IVfp80(fp, size, ind, 8, &ierr) ;
585       if ( ierr < 0 ) {
586          fprintf(stderr, "\n fatal error in IVL_writeForHumanEye(%p,%p)"
587                  "\n ierr = %d, return from IVfp80, list %d\n",
588                  ivl, fp, ierr, j) ;
589          return(0) ;
590       }
591    }
592 }
593 
594 return(1) ; }
595 
596 /*--------------------------------------------------------------------*/
597 /*
598    ---------------------------------------------------------
599    purpose -- to write out the statistics for the IVL object
600 
601    return value -- 1 if success, 0 otherwise
602 
603    created -- 95sep29, cca
604    ---------------------------------------------------------
605 */
606 int
IVL_writeStats(IVL * ivl,FILE * fp)607 IVL_writeStats (
608    IVL    *ivl,
609    FILE   *fp
610 ) {
611 int   nactive, rc ;
612 /*
613    ---------------
614    check the input
615    ---------------
616 */
617 if ( ivl == NULL || fp == NULL ) {
618    fprintf(stderr, "\n error in IVL_writeStats(%p,%p)"
619            "\n bad input\n", ivl, fp) ;
620    exit(-1) ;
621 }
622 nactive = 0 ;
623 if ( ivl->nlist > 0 ) {
624    nactive = IVsum(ivl->nlist, ivl->sizes) ;
625 }
626 rc = fprintf(fp, "\n IVL : integer vector list object :") ;
627 if ( rc < 0 ) { goto IO_error ; }
628 rc = fprintf(fp, "\n type %d", ivl->type) ;
629 if ( rc < 0 ) { goto IO_error ; }
630 switch ( ivl->type ) {
631 case IVL_CHUNKED : rc = fprintf(fp, ", chunked storage") ; break ;
632 case IVL_SOLO    : rc = fprintf(fp, ", solo storage")    ; break ;
633 case IVL_UNKNOWN : rc = fprintf(fp, ", unknown storage") ; break ;
634 }
635 if ( rc < 0 ) { goto IO_error ; }
636 rc = fprintf(fp,
637              "\n %d lists, %d maximum lists, %d tsize, %d total bytes",
638              ivl->nlist, ivl->maxnlist, ivl->tsize, IVL_sizeOf(ivl)) ;
639 if ( rc < 0 ) { goto IO_error ; }
640 switch ( ivl->type ) {
641 case IVL_CHUNKED : {
642    Ichunk   *chunk ;
643    int      nalloc, nchunk ;
644 
645    nalloc = nchunk = 0 ;
646    for ( chunk = ivl->chunk ; chunk != NULL ; chunk = chunk->next){
647       nchunk++ ;
648       nalloc += chunk->size ;
649    }
650    rc = fprintf(fp, "\n %d chunks, %d active entries, %d allocated",
651                 nchunk, nactive, nalloc) ;
652    if ( rc < 0 ) { goto IO_error ; }
653    if ( nalloc > 0 ) {
654       rc = fprintf(fp, ", %.2f %% used", (100.*nactive)/nalloc) ;
655       if ( rc < 0 ) { goto IO_error ; }
656    }
657    } break ;
658 case IVL_SOLO :
659    rc = fprintf(fp,
660                 "\n %d lists separately allocated, %d active entries",
661                 ivl->nlist, nactive) ;
662   if ( rc < 0 ) { goto IO_error ; }
663    break ;
664 }
665 return(1) ;
666 
667 IO_error :
668    fprintf(stderr, "\n fatal error in IVL_writeStats(%p,%p)"
669            "\n rc = %d, return from fprintf\n", ivl, fp, rc) ;
670    return(0) ;
671 }
672 
673 /*--------------------------------------------------------------------*/
674