source: nrEngine/src/FileStream.cpp @ 21

Revision 21, 6.5 KB checked in by art, 13 years ago (diff)

Bug in FileStream? corrected

Line 
1/***************************************************************************
2 *                                                                         *
3 *   (c) Art Tevs, MPI Informatik Saarbruecken                             *
4 *       mailto: <tevs@mpi-sb.mpg.de>                                      *
5 *                                                                         *
6 *   This program is free software; you can redistribute it and/or modify  *
7 *   it under the terms of the GNU General Public License as published by  *
8 *   the Free Software Foundation; either version 2 of the License, or     *
9 *   (at your option) any later version.                                   *
10 *                                                                         *
11 ***************************************************************************/
12
13
14//----------------------------------------------------------------------------------
15// Includes
16//----------------------------------------------------------------------------------
17#include "FileStream.h"
18#include "Log.h"
19
20namespace nrEngine {
21
22        //----------------------------------------------------------------------------------
23        FileStream::FileStream() : IStream(0), IResource("File")
24        {
25        }
26
27        //----------------------------------------------------------------------------------
28        FileStream::~FileStream()
29        {
30                unloadRes();
31        }
32
33        //----------------------------------------------------------------------------------
34        Result FileStream::unloadRes()
35        {
36                close();
37                mStream.reset();
38                return OK;
39        }
40
41        //----------------------------------------------------------------------------------
42        Result FileStream::open (const ::std::string& fileName)
43        {
44                // create a pointer to the stream object and open the file
45                mStream.reset (new ::std::ifstream(fileName.c_str()));
46
47                // check if the file could be found
48                if (!mStream->good())
49                {
50                        NR_Log(Log::LOG_ENGINE, Log::LL_ERROR, "The file \"%s\" was not found", fileName.c_str());
51                        return FILE_NOT_FOUND;
52                }
53
54                // calculate the size
55                mStream->seekg(0, ::std::ios_base::end);
56                mSize = mStream->tellg();
57                mStream->seekg(0, ::std::ios_base::beg);
58
59                return OK;
60        }
61
62        //----------------------------------------------------------------------------------
63        void FileStream::close()
64        {
65                if (!mStream) return;
66                mStream->close();
67                mStream.reset();
68                mSize = 0;
69        }
70
71        //----------------------------------------------------------------------------------
72        size_t FileStream::read(void *buf, size_t size, size_t nmemb)
73        {
74                if (!mStream) return 0;
75                mStream->read(static_cast<char*>(buf), size * nmemb);
76                return mStream->gcount();
77        }
78
79        //----------------------------------------------------------------------------------
80        size_t FileStream::readDelim(void* buf, size_t count, const ::std::string& delim)
81        {
82                if (!mStream) return 0;
83                if (delim.empty()){
84                        NR_Log(Log::LOG_ENGINE, Log::LL_ERROR, "FileStream::readDelim(): No delimiter provided");
85                        return 0;
86                }
87
88                if (delim.size() > 1){
89                        NR_Log(Log::LOG_ENGINE, Log::LL_WARNING,
90                                "FileStream::readDelim(): Only first character of delimiter \"%s\" is used", delim.c_str());
91                }
92
93                // Deal with both Unix & Windows LFs
94                bool trimCR = false;
95                if (delim.at(0) == '\n'){
96                        trimCR = true;
97                }
98
99                // maxCount + 1 since count excludes terminator in getline
100                mStream->getline(static_cast<char*>(buf), count+1, delim.at(0));
101                size_t ret = mStream->gcount();
102
103                if (mStream->fail()){
104                        // Did we fail because of maxCount hit?
105                        if (ret == count){
106                                // clear failbit for next time
107                                mStream->clear();
108                        }else{
109                                NR_Log(Log::LOG_ENGINE, Log::LL_ERROR, "FileStream::readDelim(): Error during reading the stream");
110                        }
111                }
112
113                if (!ret){
114                        (static_cast<char*>(buf))[1] = '\0';
115                }else{
116                        // trim off CR if we found CR/LF
117                        if (trimCR && (static_cast<char*>(buf))[ret] == '\r'){
118                                --ret;
119                                (static_cast<char*>(buf))[ret+1] = '\0';
120                        }
121                }
122
123                return ret;
124        }
125
126        //----------------------------------------------------------------------------------
127        size_t FileStream::tell() const
128        {
129                if (!mStream) return 0;
130                mStream->clear(); //Clear fail status in case eof was set
131                return mStream->tellg();
132        }
133
134        //----------------------------------------------------------------------------------
135        bool FileStream::eof() const
136        {
137                if (!mStream) return true;
138        return mStream->eof();
139        }
140
141        //----------------------------------------------------------------------------------
142        byte* FileStream::getData(size_t& count) const
143        {
144                if (!mStream || mSize <= 0) return NULL;
145
146                byte* data = new byte[mSize];
147
148                // read data
149                mStream->read((char*)data, mSize);
150
151                // get the size of readed data
152                count = mStream->gcount();
153                if (count < mSize){
154                        byte* ndata = new byte[count];
155                        memcpy(ndata, data, sizeof(byte) * count);
156                        delete [] data;
157                        return ndata;
158                }
159                return data;
160        }
161
162        //----------------------------------------------------------------------------------
163        bool FileStream::seek(int32 offset, int32 whence)
164        {
165                if (!mStream) return false;
166                mStream->clear(); //Clear fail status in case eof was set
167
168                std::_Ios_Seekdir sd;
169                if (whence == IStream::START)
170                        sd = std::ios::beg;
171                else if (whence == IStream::END)
172                        sd = std::ios::end;
173                else
174                        sd = std::ios::cur;
175
176                mStream->seekg(static_cast<std::ifstream::pos_type>(offset), sd);
177                return true;
178        }
179
180        //----------------------------------------------------------------------------------
181        EmptyFileStream::EmptyFileStream()
182        {
183
184        }
185
186        //----------------------------------------------------------------------------------
187        EmptyFileStream::~EmptyFileStream()
188        {
189
190        }
191
192        //----------------------------------------------------------------------------------
193        size_t EmptyFileStream::read(void *buf, size_t size, size_t nmemb)
194        {
195                return 0;
196        }
197
198        //----------------------------------------------------------------------------------
199        size_t EmptyFileStream::readDelim(void* buf, size_t count, const ::std::string& )
200        {
201                return 0;
202        }
203
204        //----------------------------------------------------------------------------------
205        size_t EmptyFileStream::tell() const{
206                return 0;
207        }
208
209        //----------------------------------------------------------------------------------
210        bool EmptyFileStream::eof() const{
211                return true;
212        }
213
214        //----------------------------------------------------------------------------------
215        byte* EmptyFileStream::getData(size_t& count) const{
216                count = 0;
217                return NULL;
218        }
219
220        //----------------------------------------------------------------------------------
221        bool EmptyFileStream::seek(int32 offset, int32 whence)
222        {
223                return true;
224        }
225
226        //----------------------------------------------------------------------------------
227        void EmptyFileStream::close ()
228        {
229                return;
230        }
231
232
233};
234
Note: See TracBrowser for help on using the repository browser.