1 /*
2  *  Copyright (C) 2010  Regents of the University of Michigan
3  *
4  *   This program is free software: you can redistribute it and/or modify
5  *   it under the terms of the GNU General Public License as published by
6  *   the Free Software Foundation, either version 3 of the License, or
7  *   (at your option) any later version.
8  *
9  *   This program is distributed in the hope that it will be useful,
10  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *   GNU General Public License for more details.
13  *
14  *   You should have received a copy of the GNU General Public License
15  *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef __UNCOMPRESSEDFILETYPE_H__
19 #define __UNCOMPRESSEDFILETYPE_H__
20 
21 #include <iostream>
22 #include <stdio.h>
23 #include "FileType.h"
24 #include "knetfile.h"
25 
26 class UncompressedFileType : public FileType
27 {
28 public:
UncompressedFileType()29     UncompressedFileType()
30     {
31         filePtr = NULL;
32         kfilePtr = NULL;
33         keof = false;
34     }
35 
~UncompressedFileType()36     virtual ~UncompressedFileType()
37     {
38         if((filePtr != NULL) || (kfilePtr != NULL))
39         {
40             close();
41         }
42     }
43 
44     UncompressedFileType(const char * filename, const char * mode);
45 
46     bool operator == (void * rhs)
47     {
48         // No two file pointers are the same, so if rhs is not NULL, then
49         // the two pointers are different (false).
50         if (rhs != NULL)
51             return false;
52         // rhs is NULL.  They are the same if both filePtr & kfilePtr are NULL.
53         return((filePtr == rhs) && (kfilePtr == rhs));
54     }
55 
56     bool operator != (void * rhs)
57     {
58         // No two file pointers are the same, so if rhs is not NULL, then
59         // the two pointers are different (true).
60         if (rhs != NULL)
61             return true;
62         // rhs is NULL.  They are the different if either filePtr or kfilePtr
63         // are not NULL.
64         return((filePtr != rhs) || (kfilePtr != rhs));
65     }
66 
67     // Close the file.
close()68     inline int close()
69     {
70         if(filePtr != NULL)
71         {
72             if((filePtr != stdout) && (filePtr != stdin))
73             {
74                 int result = fclose(filePtr);
75                 filePtr = NULL;
76                 return result;
77             }
78             filePtr = NULL;
79         }
80         else if(kfilePtr != NULL)
81         {
82             int result = knet_close(kfilePtr);
83             kfilePtr = NULL;
84             return result;
85         }
86         return 0;
87     }
88 
89 
90     // Reset to the beginning of the file.
rewind()91     inline void rewind()
92     {
93         // Just call rewind to move to the beginning of the file.
94         if(filePtr != NULL)
95         {
96             ::rewind(filePtr);
97         }
98         else if (kfilePtr != NULL)
99         {
100             knet_seek(kfilePtr, 0, SEEK_SET);
101         }
102     }
103 
104     // Check to see if we have reached the EOF.
eof()105     inline int eof()
106     {
107         //  check the file for eof.
108         if(kfilePtr != NULL)
109         {
110             return(keof);
111         }
112         else
113         {
114             return feof(filePtr);
115         }
116     }
117 
118     // Check to see if the file is open.
isOpen()119     virtual inline bool isOpen()
120     {
121         if((filePtr != NULL) || (kfilePtr != NULL))
122         {
123             // filePtr is not null, so the file is open.
124             return(true);
125         }
126         return(false);
127     }
128 
129     // Write to the file
write(const void * buffer,unsigned int size)130     inline unsigned int write(const void * buffer, unsigned int size)
131     {
132         // knetfile is never used for writing.
133         return fwrite(buffer, 1, size, filePtr);
134     }
135 
136     // Read into a buffer from the file.  Since the buffer is passed in and
137     // this would bypass the fileBuffer used by this class, this method must
138     // be protected.
read(void * buffer,unsigned int size)139     inline int read(void * buffer, unsigned int size)
140     {
141         if(kfilePtr != NULL)
142         {
143             int bytesRead = knet_read(kfilePtr, buffer, size);
144             if((bytesRead == 0) && (size != 0))
145             {
146                 keof = true;
147             }
148             else if((bytesRead != (int)size) && (bytesRead >= 0))
149             {
150                 // Less then the requested size was read and an error
151                 // was not returned (bgzf_read returns -1 on error).
152                 keof = true;
153             }
154             else
155             {
156                 keof = false;
157             }
158             return(bytesRead);
159         }
160         return fread(buffer, 1, size, filePtr);
161     }
162 
163 
164     // Get current position in the file.
165     // -1 return value indicates an error.
tell()166     virtual inline int64_t tell()
167     {
168         if(kfilePtr != NULL)
169         {
170             return knet_tell(kfilePtr);
171         }
172         return ftell(filePtr);
173     }
174 
175 
176     // Seek to the specified offset from the origin.
177     // origin can be any of the following:
178     // Note: not all are valid for all filetypes.
179     //   SEEK_SET - Beginning of file
180     //   SEEK_CUR - Current position of the file pointer
181     //   SEEK_END - End of file
182     // Returns true on successful seek and false on a failed seek.
seek(int64_t offset,int origin)183     virtual inline bool seek(int64_t offset, int origin)
184     {
185         int returnVal = 0;
186         if(kfilePtr != NULL)
187         {
188             returnVal = knet_seek(kfilePtr, offset, origin);
189             keof = false;
190         }
191         else
192         {
193             returnVal = fseek(filePtr, offset, origin);
194         }
195         // Check for success - 0 return value.
196         if (returnVal == 0)
197         {
198             return true;
199         }
200         // Successful.
201         return false;
202     }
203 
204 
205 protected:
206     // A FILE Pointer is used.
207     FILE* filePtr;
208     knetFile *kfilePtr;
209     bool keof;
210 };
211 
212 #endif
213 
214 
215