/* Returns the name and offset of the last segment */ int af_last_seg(AFFILE *af,char *last_segname,int last_segname_len,int64 *pos) { /* Find the name of the last segment */ fseeko(af->aseg,0,SEEK_END); af_backspace(af); // back up one segment *pos = ftello(af->aseg); // remember where it is last_segname[0] = 0; return af_probe_next_seg(af,last_segname,last_segname_len,0,0,0,0); }
static int aff_write_ignore(AFFILE *af,size_t bytes) { int64_t startpos = ftello(af->aseg); // remember start position int r = 0; if(af_trace) fprintf(af_trace,"aff_write_ignore(%p,%d)\n",af,(int)bytes); /* First write the ignore */ r = aff_write_ignore2(af,bytes); /* If the next one is also an ignore, * then we should go back and make the ignore_size bigger. * We could do this recursively, * but it's probably not worth the added complexity. */ char next[AF_MAX_NAME_LEN]; size_t segsize2=0; int count=0; while(af_probe_next_seg(af,next,sizeof(next),0,0,&segsize2,1)==0 && next[0]==0 && segsize2>=0){ count++; if(count>10) break; // something is wrong; just get out. //printf("*** next %d segment at %qd len=%d will be deleted\n",count,ftello(af->aseg),segsize2); bytes += segsize2; fseeko(af->aseg,startpos,SEEK_SET); r = aff_write_ignore2(af,bytes); if(r!=0) return r; } /* See if the previous segment is also blank; if so, collapse them */ fseeko(af->aseg,startpos,SEEK_SET); if(af_backspace(af)==0){ uint64_t prev_segment_loc = ftello(af->aseg); // remember where we are char prev_segment_name[AF_MAX_NAME_LEN]; size_t prev_segment_size=0; if(af_probe_next_seg(af,prev_segment_name,sizeof(prev_segment_name),0,0,&prev_segment_size,1)==0){ //printf("** prev segment name='%s' len=%d\n",prev_segment_name,prev_segment_size); if(prev_segment_name[0]==0){ bytes += prev_segment_size; fseeko(af->aseg,prev_segment_loc,SEEK_SET); r = aff_write_ignore2(af,bytes); fseeko(af->aseg,prev_segment_loc,SEEK_SET); } } } return(r); }
/* Removes the last segment of an AFF file if it is blank. * @return 0 for success, -1 for error */ int af_truncate_blank(AFFILE *af) { uint64_t last_loc = ftello(af->aseg); // remember where we are if(af_backspace(af)==0){ uint64_t backspace_loc = ftello(af->aseg); // remember where we are char next_segment_name[AF_MAX_NAME_LEN]; if(af_probe_next_seg(af,next_segment_name,sizeof(next_segment_name),0,0,0,1)==0){ if(next_segment_name[0]==0){ /* Remove it */ fflush(af->aseg); if(ftruncate(fileno(af->aseg),backspace_loc)<0) return -1; return 0; } } } fseeko(af->aseg,last_loc,SEEK_SET); // return to where we were return -1; // say that we couldn't do it. }