// -*- mode: c++; c-set-style: "stroustrup"; tab-width: 4; -*- // // CFile.c // // Copyright (C) 2004 Koji Nakamaru // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software Foundation, // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // #include "common.h" #include #include #include "CFile.h" // public functions CFile::CFile() : _type(kFileNone), _fp(NULL), _pos(0) { memset(_name, 0, sizeof(_name)); } CFile::~CFile() { } bool CFile::open( char *name) { if (name == NULL) { _fp = stdin; _type = kFileStdIn; } else { FILE *fp; if ((fp = fopen(name, "r")) == NULL) { return false; } int c0 = fgetc(fp); int c1 = fgetc(fp); fclose(fp); if (c0 == 'B' && c1 == 'Z') { if ((_fp = (void *)BZ2_bzopen(name, "rb")) == NULL) { return false; } _type = kFileBZ; } else if (c0 == 037 && c1 == 0213) { if ((_fp = (void *)gzopen(name, "rb")) == NULL) { return false; } _type = kFileGZ; } else { if ((_fp = (void *)fopen(name, "r")) == NULL) { return false; } _type = kFileUZ; } strcpy(_name, name); } _pos = 0; return true; } void CFile::close() { switch (_type) { case kFileBZ: BZ2_bzclose((BZFILE *)_fp); break; case kFileGZ: gzclose((gzFile)_fp); break; case kFileUZ: fclose((FILE *)_fp); break; default: break; } _fp = NULL; _pos = 0; } bool CFile::stat( struct stat *stbuf) { switch (_type) { case kFileBZ: case kFileGZ: case kFileUZ: return ::stat(_name, stbuf) == 0; default: return false; } } char *CFile::gets( char *buf, size_t len) { memset(buf, 0, len--); char *bp = buf; int c; while ((c = getc()) != EOF && bp - buf < (int)len) { *bp++ = c; if (c == '\n') { return buf; } } return (bp > buf) ? buf : NULL; } int CFile::getc() { unsigned char buf[1]; if (read(buf, 1) == 0) { return EOF; } return buf[0]; } size_t CFile::read( void *buf, size_t len) { int count; switch (_type) { case kFileBZ: count = BZ2_bzread((BZFILE *)_fp, buf, len); break; case kFileGZ: count = gzread((gzFile)_fp, buf, len); break; case kFileStdIn: case kFileUZ: count = fread(buf, 1, len, (FILE *)_fp); break; default: return 0; }; _pos += count; return count; } bool CFile::seek( size_t pos) { switch (_type) { case kFileBZ: close(); if ((_fp = (void *)BZ2_bzopen(_name, "rb")) == NULL) { return false; } break; case kFileGZ: close(); if ((_fp = (void *)gzopen(_name, "rb")) == NULL) { return false; } break; case kFileStdIn: return false; break; case kFileUZ: default: break; } switch (_type) { case kFileBZ: case kFileGZ: while (_pos < pos) { char buf[BUFSIZ]; size_t off = pos - _pos; if (read(buf, (off > BUFSIZ) ? BUFSIZ : off) == 0) { return false; } } break; case kFileUZ: if (fseek((FILE *)_fp, pos, SEEK_SET) != 0) { return false; } break; default: break; } return false; } size_t CFile::tell() { return _pos; } // protected functions // private functions // local functions