Tail * tail_open (const char *path, const char *name, TrieIOMode mode) { Tail *t; TrieIndex i; uint16 sig; long file_size; t = (Tail *) malloc (sizeof (Tail)); t->file = file_open (path, name, ".tl", mode); if (!t->file) goto exit1; file_size = file_length (t->file); if (file_size != 0 && file_read_int16 (t->file, (int16 *) &sig) && sig != TAIL_SIGNATURE) { goto exit2; } /* init tails data */ if (file_size == 0) { t->first_free = 0; t->num_tails = 0; t->tails = NULL; t->is_dirty = TRUE; } else { file_read_int16 (t->file, &t->first_free); file_read_int16 (t->file, &t->num_tails); t->tails = (TailBlock *) malloc (t->num_tails * sizeof (TailBlock)); if (!t->tails) goto exit2; for (i = 0; i < t->num_tails; i++) { int8 length; file_read_int16 (t->file, &t->tails[i].next_free); file_read_int16 (t->file, &t->tails[i].data); file_read_int8 (t->file, &length); t->tails[i].suffix = (TrieChar *) malloc (length + 1); if (length > 0) file_read_chars (t->file, (char *)t->tails[i].suffix, length); t->tails[i].suffix[length] = '\0'; } t->is_dirty = FALSE; } return t; exit2: fclose (t->file); exit1: free (t); return NULL; }
Tail * tail_read (FILE *file) { long save_pos; Tail *t; TrieIndex i; uint32 sig; /* check signature */ save_pos = ftell (file); if (!file_read_int32 (file, (int32 *) &sig) || TAIL_SIGNATURE != sig) goto exit_file_read; if (NULL == (t = (Tail *) malloc (sizeof (Tail)))) goto exit_file_read; if (!file_read_int32 (file, &t->first_free) || !file_read_int32 (file, &t->num_tails)) { goto exit_tail_created; } if (t->num_tails > SIZE_MAX / sizeof (TailBlock)) goto exit_tail_created; t->tails = (TailBlock *) malloc (t->num_tails * sizeof (TailBlock)); if (!t->tails) goto exit_tail_created; for (i = 0; i < t->num_tails; i++) { int16 length; if (!file_read_int32 (file, &t->tails[i].next_free) || !file_read_int32 (file, &t->tails[i].data) || !file_read_int16 (file, &length)) { goto exit_in_loop; } t->tails[i].suffix = (TrieChar *) malloc (length + 1); if (length > 0) { if (!file_read_chars (file, (char *)t->tails[i].suffix, length)) { free (t->tails[i].suffix); goto exit_in_loop; } } t->tails[i].suffix[length] = '\0'; } return t; exit_in_loop: while (i > 0) { free (t->tails[--i].suffix); } free (t->tails); exit_tail_created: free (t); exit_file_read: fseek (file, save_pos, SEEK_SET); return NULL; }