#include "EXTERN.h" #include "perl.h" #include "XSUB.h" /* set by scan_fat, used by next */ short *fat = NULL; int type_size, nb_clusters, bad_cluster_value; char *fat_flag_map; unsigned int next(unsigned int cluster) { short *p = fat + type_size * cluster; if (cluster > nb_clusters + 2) croak("fat::next: cluster %d outside filesystem", cluster); return type_size == 1 ? *p : *((unsigned int *) p); } MODULE = resize_fat::c_rewritten PACKAGE = resize_fat::c_rewritten void scan_fat(fat_, nb_clusters_, type_size_) char *fat_ int nb_clusters_ int type_size_ PPCODE: unsigned int v; int free = 0, bad = 0, used = 0; short *p; fat = (short*) fat_; type_size = type_size_; nb_clusters = nb_clusters_; bad_cluster_value = type_size ? 0xffffff7 : 0xfff7; if (type_size % 16) fprintf(stderr, "unable to handle type_size"), exit(1); type_size /= 16; for (p = fat + 2 * type_size; p < fat + type_size * (nb_clusters + 2); p += type_size) { v = type_size == 1 ? *p : *((unsigned int *) p); if (v == 0) free++; else if (v == bad_cluster_value) bad++; } used = nb_clusters - free - bad; EXTEND(SP, 3); PUSHs(sv_2mortal(newSViv(free))); PUSHs(sv_2mortal(newSViv(bad))); PUSHs(sv_2mortal(newSViv(used))); unsigned int next(unused, cluster) void *unused unsigned int cluster CODE: RETVAL = next(cluster); OUTPUT: RETVAL int checkFat(fat_flag_map_, cluster, type, name) char *fat_flag_map_ unsigned int cluster int type char *name CODE: int nb = 0; fat_flag_map = fat_flag_map_; for (; cluster < bad_cluster_value; cluster = next(cluster)) { if (cluster == 0) croak("Bad FAT: unterminated chain for %s\n", name); if (fat_flag_map[cluster]) croak("Bad FAT: cluster $cluster is cross-linked for %s\n", name); fat_flag_map[cluster] = type; nb++; } RETVAL = nb; OUTPUT: RETVAL unsigned int flag(cluster) unsigned int cluster CODE: RETVAL = fat_flag_map[cluster]; OUTPUT: RETVAL void set_flag(cluster, flag) unsigned int cluster int flag CODE: fat_flag_map[cluster] = flag;