ssize_t btFiles::IO(char *buf, u_int64_t off, size_t len, const int iotype) { u_int64_t n = 0; size_t pos,nio; BTFILE *pbf = m_btfhead; if( ( off + (u_int64_t)len ) > m_total_files_length) return -1; for(; pbf; pbf = pbf->bf_next){ n += (u_int64_t) pbf->bf_length; if(n > off) break; } if( !pbf ) return -1; pos = (size_t) (off - (n - pbf->bf_length)); for(; len ;){ if( !pbf->bf_flag_opened ){ if( _btf_open(pbf) < 0 ) return -1; } if( m_flag_automanage ) time(&pbf->bf_last_timestamp); if( fseek(pbf->bf_fp,(long) pos,SEEK_SET) < 0) return -1; nio = (len < pbf->bf_length - pos) ? len : (pbf->bf_length - pos); if(0 == iotype){ if( 1 != fread(buf,nio,1,pbf->bf_fp) ) return -1; }else{ if( 1 != fwrite(buf,nio,1,pbf->bf_fp) ) return -1; } len -= nio; buf += nio; if( len ){ pbf = pbf->bf_next; if( !pbf ) return -1; pos = 0; } } // end for return 0; }
ssize_t btFiles::IO(char *buf, uint64_t off, size_t len, const int iotype) { uint64_t n = 0; off_t pos,nio; BTFILE *pbf = m_btfhead; if( (off + (uint64_t)len) > m_total_files_length ){ CONSOLE.Warning(1, "error, data offset %llu length %lu out of range", (unsigned long long)off, (unsigned long)len); return -1; } for(; pbf; pbf = pbf->bf_next){ n += (uint64_t) pbf->bf_length; if(n > off) break; } if( !pbf ){ CONSOLE.Warning(1, "error, failed to find file for offset %llu", (unsigned long long)off); return -1; } pos = off - (n - pbf->bf_length); for(; len ;){ if( (!pbf->bf_flag_opened || (iotype && pbf->bf_flag_readonly)) && _btf_open(pbf, iotype) < 0 ){ CONSOLE.Warning(1, "error, failed to open file \"%s\": %s", pbf->bf_filename, strerror(errno)); return -1; } pbf->bf_last_timestamp = now; #ifdef HAVE_FSEEKO if( fseeko(pbf->bf_fp,pos,SEEK_SET) < 0 ){ #else if( fseek(pbf->bf_fp,(long) pos,SEEK_SET) < 0 ){ #endif CONSOLE.Warning(1, "error, failed to seek to %llu on file \"%s\": %s", (unsigned long long)pos, pbf->bf_filename, strerror(errno)); return -1; } // } nio = (len < pbf->bf_length - pos) ? len : (pbf->bf_length - pos); if(0 == iotype){ errno = 0; if( 1 != fread(buf,nio,1,pbf->bf_fp) && ferror(pbf->bf_fp) ){ CONSOLE.Warning(1, "error, read failed at %llu on file \"%s\": %s", (unsigned long long)pos, pbf->bf_filename, strerror(errno)); return -1; } }else{ errno = 0; if( 1 != fwrite(buf,nio,1,pbf->bf_fp) ){ CONSOLE.Warning(1, "error, write failed at %llu on file \"%s\": %s", (unsigned long long)pos, pbf->bf_filename, strerror(errno)); return -1; } if( fflush(pbf->bf_fp) == EOF ){ CONSOLE.Warning(1, "error, flush failed at %llu on file \"%s\": %s", (unsigned long long)pos, pbf->bf_filename, strerror(errno)); return -1; } } len -= nio; buf += nio; if( len ){ do{ pbf = pbf->bf_next; if( !pbf ){ CONSOLE.Warning(1, "error, data left over with no more files to write"); return -1; } }while( 0==pbf->bf_length ); pos = 0; } } // end for return 0; } int btFiles::_btf_destroy() { BTFILE *pbf,*pbf_next; for(pbf = m_btfhead; pbf;){ pbf_next = pbf->bf_next; if( pbf->bf_fp && pbf->bf_flag_opened ) fclose( pbf->bf_fp ); if( pbf->bf_filename ) delete []pbf->bf_filename; if( pbf->bf_buffer ) delete []pbf->bf_buffer; delete pbf; pbf = pbf_next; } m_btfhead = (BTFILE*) 0; m_total_files_length = (uint64_t) 0; m_total_opened = 0; return 0; }