InputFile.cpp

00001 /*
00002  *  Copyright (C) 2010  Regents of the University of Michigan
00003  *
00004  *   This program is free software: you can redistribute it and/or modify
00005  *   it under the terms of the GNU General Public License as published by
00006  *   the Free Software Foundation, either version 3 of the License, or
00007  *   (at your option) any later version.
00008  *
00009  *   This program is distributed in the hope that it will be useful,
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *   GNU General Public License for more details.
00013  *
00014  *   You should have received a copy of the GNU General Public License
00015  *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016  */
00017 
00018 #include "InputFile.h"
00019 #include "StringBasics.h"
00020 #include "GzipHeader.h"
00021 #include "BgzfFileType.h"
00022 #include "GzipFileType.h"
00023 #include "UncompressedFileType.h"
00024 
00025 #include <stdarg.h>
00026 
00027 InputFile::InputFile(const char * filename, const char * mode,
00028                      InputFile::ifileCompression compressionMode)
00029 {
00030     myFileTypePtr = NULL;
00031     myBufferIndex = 0;
00032     myCurrentBufferSize = 0;
00033 
00034     openFile(filename, mode, compressionMode);
00035 }
00036 
00037 
00038 #ifdef __ZLIB_AVAILABLE__
00039 
00040 // Open a file. Called by the constructor.
00041 // Returns true if the file was successfully opened, false otherwise.
00042 bool InputFile::openFile(const char * filename, const char * mode,
00043                          InputFile::ifileCompression compressionMode)
00044 {
00045     // If a file is for write, just open a new file.
00046     if (mode[0] == 'w' || mode[0] == 'W')
00047     {
00048         openFileUsingMode(filename, mode, compressionMode);
00049     }
00050     else
00051     {
00052         // Check if reading from stdin.
00053         if(strcmp(filename, "-") == 0)
00054         {
00055             // Reading from stdin, open it based on the 
00056             // compression mode.
00057             openFileUsingMode(filename, mode, compressionMode);
00058         }
00059         else
00060         {
00061             // Not from stdin, so determine the file type.
00062 
00063             // Open the file read only to determine file type.
00064             FILE* filePtr = fopen(filename, "r");
00065             
00066             // If the file could not be opened, either create a new one or
00067             // return failure.
00068             if (filePtr == NULL)
00069             {
00070                 // If the mode is for read, then the file must exist, otherwise,
00071                 // create a new file.
00072                 if (mode[0] == 'r' || mode[0] == 'R')
00073                 {
00074                     // File must exist.
00075                     if (myFileTypePtr != NULL)
00076                     {
00077                         delete myFileTypePtr;
00078                         myFileTypePtr = NULL;
00079                     }
00080                     // Return false, was not opened.
00081                     return false;
00082                 }
00083                 else
00084                 {
00085                     openFileUsingMode(filename, mode, compressionMode);
00086                 }
00087             }
00088             else
00089             {
00090                 // File was successfully opened, so try to determine the
00091                 // filetype from the file.
00092                 // Read the file to see if it a gzip file.
00093                 GzipHeader gzipHeader;
00094                 bool isGzip = gzipHeader.readHeader(filePtr);
00095                 
00096                 // The file header has been read, so close the file, so it can
00097                 // be re-opened as the correct type.
00098                 fclose(filePtr);
00099 
00100                 if (isGzip)
00101                 {
00102                     // This file is a gzip file.
00103                     // Check to see if it is BGZF Compression.
00104                     if (gzipHeader.isBgzfFile())
00105                     {
00106                         // This file has BGZF Compression, so set the file
00107                         // pointer.
00108                         myFileTypePtr = new BgzfFileType(filename, mode);
00109                     }
00110                     else
00111                     {
00112                         // Not BGZF, just a normal gzip.
00113                         myFileTypePtr = new GzipFileType(filename, mode);
00114                     }
00115                 }
00116                 else
00117                 {
00118                     // The file is a uncompressed, uncompressed file,
00119                     // so set the myFileTypePtr accordingly.
00120                     myFileTypePtr = new UncompressedFileType(filename, mode);
00121                 }
00122             }
00123         }
00124     }
00125 
00126     if (!myFileTypePtr->isOpen())
00127     {
00128         // The file was not opened, so delete the pointer and set to null.
00129         delete myFileTypePtr;
00130         myFileTypePtr = NULL;
00131         return false;
00132     }
00133     return true;
00134 }
00135 
00136 
00137 // Open a file.  This method will open a file with the specified name and
00138 // mode with the fileTypePtr associated with the specified compressionMode.
00139 void InputFile::openFileUsingMode(const char * filename, const char * mode,
00140                                   ifileCompression compressionMode)
00141 {
00142     switch (compressionMode)
00143     {
00144         case GZIP:
00145             // Gzipped.
00146             myFileTypePtr = new GzipFileType(filename, mode);
00147             break;
00148         case BGZF:
00149             // BGZF compression.
00150             myFileTypePtr = new BgzfFileType(filename, mode);
00151             break;
00152         case UNCOMPRESSED:
00153             myFileTypePtr = new UncompressedFileType(filename, mode);
00154             break;
00155         case InputFile::DEFAULT:
00156         default:
00157             // Check the extension. If it is ".gz", treat as gzip.
00158             // otherwise treat it as UNCOMPRESSED.
00159             int lastchar = 0;
00160             while (filename[lastchar] != 0) lastchar++;
00161             if ((lastchar >= 3 &&
00162                     filename[lastchar - 3] == '.' &&
00163                     filename[lastchar - 2] == 'g' &&
00164                     filename[lastchar - 1] == 'z'))
00165             {
00166                 // .gz files files should be gzipped.
00167                 myFileTypePtr = new GzipFileType(filename, mode);
00168             }
00169             else
00170             {
00171                 // Create an uncompressed file.
00172                 myFileTypePtr = new UncompressedFileType(filename, mode);
00173             }
00174             break;
00175     }
00176 }
00177 
00178 #else
00179 
00180 // No zlib, so just treat all files as std files.
00181 // Open a file. Called by the constructor.
00182 // Returns true if the file was successfully opened, false otherwise.
00183 bool InputFile::openFile(const char * filename, const char * mode)
00184 {
00185     //  No zlib, so it is a uncompressed, uncompressed file.
00186     myFileTypePtr = new UncompressedFileType(filename, mode);
00187 
00188     if (!myFileTypePtr->isOpen())
00189     {
00190         // The file was not opened, so delete the pointer and set to null.
00191         delete myFileTypePtr;
00192         myFileTypePtr = NULL;
00193         return false;
00194     }
00195     return true;
00196 }
00197 
00198 #endif
00199 
00200 
00201 InputFile::~InputFile()
00202 {
00203     delete myFileTypePtr;
00204     myFileTypePtr = NULL;
00205 }
00206 
00207 
00208 int ifprintf(IFILE output, char * format, ...)
00209 {
00210     String buffer;
00211 
00212     va_list  ap;
00213     va_start(ap, format);
00214 
00215     buffer.vprintf(format, ap);
00216 
00217     va_end(ap);
00218 
00219     return ::ifwrite(output, (const char *) buffer, buffer.Length());
00220 }
00221 
00222 
Generated on Wed Nov 17 15:38:28 2010 for StatGen Software by  doxygen 1.6.3