/* bitpacker2.c * pakkaa tai purkaa kokonaislukutaulukon tiedostoon * tallettaen vain tarvittavan määrän bittejä per luku. * * tallennus: bitpacker w tiedostonimi tiedosto * */ #include #include #include #include "psave.h" #define SIZESTEP 1000 /* kuinka paljon taulukkoa kasvatetaan kerrallaan */ int main(int argc, char *argv[]) { unsigned num, maxnum, *a = NULL; int nums=0, count=0, i; char bits; FILE *f; if (argc!=3 || !strchr("rw",*argv[1])) { fprintf(stderr,"usage: %s r|w file\n", argv[0]); exit(EXIT_FAILURE); } switch(*argv[1]) { case 'w': while (1==scanf("%u", &num)) { /* kasvatetaan taulukkoa a jos se on jo täysi */ if (count>=nums && !(a = realloc(a, (nums+=SIZESTEP) * sizeof(num)))) { perror("realloc"); exit(EXIT_FAILURE); } maxnum = num > maxnum ? num : maxnum; a[count++] = num; } if (!(f = fopen(argv[2], "wb"))) { perror("fopen"); exit(EXIT_FAILURE); } /* talletetaan lukujen määrä kokonaislukuna */ fwrite(&count, sizeof(count), 1, f); /* lasketaan montako bittiä suurimmalle luvulle tarvitaan */ bits = 1; while (maxnum >>= 1) ++bits; /* talletetaan bittien määrä - char riittää */ fwrite(&bits, sizeof(bits), 1, f); psave(a, count, bits, f); fclose(f); break; case 'r': if (!(f = fopen(argv[2], "rb"))) { perror("fopen"); exit(EXIT_FAILURE); } fread(&nums, sizeof(nums), 1, f); /* luetaan lukujen määrä */ fread(&bits, sizeof(bits), 1, f); /* luetaan bittimäärä */ if (!(a=malloc(nums * sizeof(int)))) { perror("malloc"); exit(EXIT_FAILURE); } count = prestore(a, nums, bits, f); fclose(f); if (count < nums) fprintf(stderr, "Warning: restored only %d elements\n", count); for (i=0; i