00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifdef _WIN32
00018 #include <spl/configwin32.h>
00019 #else
00020 #include <spl/autoconf/config.h>
00021 #endif
00022
00023 #include <spl/io/FileStream.h>
00024
00025 #ifdef HAVE_IO_H
00026 #include <io.h>
00027 #endif
00028 #ifdef HAVE_FCNTL_H
00029 #include <fcntl.h>
00030 #endif
00031 #ifdef HAVE_SYS_FCNTL_H
00032 #include <sys/fcntl.h>
00033 #endif
00034
00035 #ifdef HAVE_UNISTD_H
00036 #include <unistd.h>
00037 #endif
00038 #ifdef HAVE_ERRNO_H
00039 #include <errno.h>
00040 #endif
00041
00042 using namespace spl;
00043
00044 class FdStreamState_Closed : public IStreamState
00045 {
00046 public:
00047 FdStreamState_Closed(spl::IStream *parent, IStreamState **parentStateVar);
00048 virtual ~FdStreamState_Closed();
00049
00050 virtual void OnLeave(IStreamState *newState);
00051 virtual void OnEnter(IStreamState *oldState);
00052
00053 virtual void Close();
00054 virtual void Flush();
00055 virtual int Read(Array<byte>& buffer, const int offset, int count);
00056 virtual int ReadByte();
00057 virtual long Seek(const long offset, const SeekOrigin origin);
00058 virtual void Write(const Array<byte>& buffer, const int offset, const int count);
00059 virtual void WriteByte(byte value);
00060
00061 virtual bool CanRead() const;
00062 virtual bool CanSeek() const;
00063 virtual bool CanWrite() const;
00064
00065 virtual long Length() const;
00066 virtual long Position() const;
00067 #ifdef DEBUG
00068 virtual void ValidateMem() const;
00069 virtual void CheckMem() const;
00070 #endif
00071 };
00072
00073 FdStreamState_Closed::FdStreamState_Closed
00074 (
00075 spl::IStream *parent,
00076 IStreamState **parentStateVar
00077 )
00078 : IStreamState(parent, parentStateVar)
00079 {
00080 }
00081
00082 FdStreamState_Closed::~FdStreamState_Closed()
00083 {
00084 }
00085
00086 void FdStreamState_Closed::OnLeave(IStreamState *newState)
00087 {
00088 }
00089
00090 void FdStreamState_Closed::OnEnter(IStreamState *oldState)
00091 {
00092 }
00093
00094 void FdStreamState_Closed::Close()
00095 {
00096 throw new IOException("File is closed, so it can't be closed again.");
00097 }
00098
00099 void FdStreamState_Closed::Flush()
00100 {
00101 throw new IOException("File is closed, so it can't be flushed");
00102 }
00103
00104 int FdStreamState_Closed::Read(Array<byte>& buffer, const int offset, int count)
00105 {
00106 throw new IOException("File is closed, so it can't be read");
00107 }
00108
00109 int FdStreamState_Closed::ReadByte()
00110 {
00111 throw new IOException("File is closed, so it can't be read");
00112 }
00113
00114 long FdStreamState_Closed::Seek(const long offset, const SeekOrigin origin)
00115 {
00116 throw new IOException("File is closed, so it can't be seeked");
00117 }
00118
00119 void FdStreamState_Closed::Write(const Array<byte>& buffer, const int offset, const int count)
00120 {
00121 throw new IOException("File is closed, so it can't be written");
00122 }
00123
00124 void FdStreamState_Closed::WriteByte(byte value)
00125 {
00126 throw new IOException("File is closed, so it can't be written");
00127 }
00128
00129 bool FdStreamState_Closed::CanRead() const
00130 {
00131 throw new NotImplementedException();
00132 }
00133
00134 bool FdStreamState_Closed::CanSeek() const
00135 {
00136 throw new NotImplementedException();
00137 }
00138
00139 bool FdStreamState_Closed::CanWrite() const
00140 {
00141 throw new NotImplementedException();
00142 }
00143
00144 long FdStreamState_Closed::Length() const
00145 {
00146 throw new IOException("File is closed");
00147 }
00148
00149 long FdStreamState_Closed::Position() const
00150 {
00151 throw new IOException("File is closed");
00152 }
00153
00154 #ifdef DEBUG
00155 void FdStreamState_Closed::ValidateMem() const
00156 {
00157 }
00158
00159 void FdStreamState_Closed::CheckMem() const
00160 {
00161 }
00162 #endif
00163
00164 class FdStreamState_Open : public IStreamState
00165 {
00166 public:
00167 FdStreamState_Open(IStream *parent, IStreamState **parentStateVar);
00168 virtual ~FdStreamState_Open();
00169
00170 virtual void OnLeave(IStreamState *newState);
00171 virtual void OnEnter(IStreamState *oldState);
00172
00173 virtual void Close();
00174 virtual void Flush();
00175 virtual int Read(Array<byte>& buffer, const int offset, int count);
00176 virtual int ReadByte();
00177 virtual long Seek(const long offset, const SeekOrigin origin);
00178 virtual void Write(const Array<byte>& buffer, const int offset, const int count);
00179 virtual void WriteByte(byte value);
00180
00181 virtual bool CanRead() const;
00182 virtual bool CanSeek() const;
00183 virtual bool CanWrite() const;
00184
00185 virtual long Length() const;
00186 virtual long Position() const;
00187 #ifdef DEBUG
00188 virtual void ValidateMem() const;
00189 virtual void CheckMem() const;
00190 #endif
00191 };
00192
00193 FdStreamState_Open::FdStreamState_Open
00194 (
00195 IStream* parent,
00196 IStreamState **parentStateVar
00197 )
00198 : IStreamState(parent, parentStateVar)
00199 {
00200 }
00201
00202 FdStreamState_Open::~FdStreamState_Open()
00203 {
00204 }
00205
00206 void FdStreamState_Open::OnLeave(IStreamState *newState)
00207 {
00208 if ( ((FdStream *)m_parent)->m_canClose )
00209 {
00210 close( ((FdStream *)m_parent)->m_fd );
00211 }
00212 }
00213
00214 void FdStreamState_Open::OnEnter(IStreamState *oldState)
00215 {
00216 }
00217
00218 void FdStreamState_Open::Close()
00219 {
00220 IStreamState *newstate = new FdStreamState_Closed(m_parent, m_holder);
00221 ChangeState(newstate);
00222 }
00223
00224 void FdStreamState_Open::Flush()
00225 {
00226
00227 }
00228
00229 int FdStreamState_Open::Read(Array<byte>& buffer, const int offset, int count)
00230 {
00231 ASSERT(offset + count <= buffer.Length());
00232
00233 int ret = (int)read(((FdStream *)m_parent)->m_fd, &(buffer.Data()[offset]), count);
00234 ((FdStream *)m_parent)->m_lasterr = errno;
00235 return ret;
00236 }
00237
00238 int FdStreamState_Open::ReadByte()
00239 {
00240 byte b;
00241 read(((FdStream *)m_parent)->m_fd, &b, 1);
00242 return b;
00243 }
00244
00245 long FdStreamState_Open::Seek(const long offset, const SeekOrigin origin)
00246 {
00247 throw new NotImplementedException();
00248 }
00249
00250 void FdStreamState_Open::Write(const Array<byte>& buffer, const int offset, const int count)
00251 {
00252 ASSERT(offset + count <= buffer.Length());
00253
00254 write(((FdStream *)m_parent)->m_fd, &(buffer.Data()[offset]), count);
00255 ((FdStream *)m_parent)->m_lasterr = errno;
00256 }
00257
00258 void FdStreamState_Open::WriteByte(byte value)
00259 {
00260 write(((FdStream *)m_parent)->m_fd, &value, 1);
00261 ((FdStream *)m_parent)->m_lasterr = errno;
00262 }
00263
00264 bool FdStreamState_Open::CanRead() const
00265 {
00266 throw new NotImplementedException();
00267 }
00268
00269 bool FdStreamState_Open::CanSeek() const
00270 {
00271 throw new NotImplementedException();
00272 }
00273
00274 bool FdStreamState_Open::CanWrite() const
00275 {
00276 throw new NotImplementedException();
00277 }
00278
00279 long FdStreamState_Open::Length() const
00280 {
00281 throw new NotImplementedException();
00282 }
00283
00284 long FdStreamState_Open::Position() const
00285 {
00286 throw new NotImplementedException();
00287
00288 }
00289
00290 #ifdef DEBUG
00291 void FdStreamState_Open::ValidateMem() const
00292 {
00293 }
00294
00295 void FdStreamState_Open::CheckMem() const
00296 {
00297 }
00298 #endif
00299
00300 FdStream::FdStream(int fp, File::FileAccess access, bool canClose)
00301 : m_filepathname(""), m_mode(File::FILEMODE_Open), m_access(access), m_canClose(canClose), m_lasterr(0), m_state(NULL)
00302 {
00303 m_fd = fp;
00304 m_state = new FdStreamState_Open(this, &m_state);
00305 }
00306
00307 FdStream::FdStream(const String& path, File::FileMode mode, File::FileAccess access)
00308 : m_filepathname(path), m_mode(mode), m_access(access),
00309 m_canClose(true), m_lasterr(0), m_state(NULL)
00310 {
00311 if ( File::Exists(path) )
00312 {
00313 if ( File::FILEMODE_CreateNew == mode )
00314 {
00315 throw new IOException("File exists");
00316 }
00317 if ( File::FILEMODE_Truncate == mode )
00318 {
00319 if ( 0 > (m_fd = open(path.GetChars(), O_WRONLY)) )
00320 {
00321 close(m_fd);
00322 }
00323 }
00324 }
00325 else if ( File::FILEMODE_Open == mode )
00326 {
00327 throw new IOException("File not found");
00328 }
00329 else
00330 {
00331
00332 if ( 0 > (m_fd = open(path.GetChars(), O_APPEND)) )
00333 {
00334 close(m_fd);
00335 }
00336 }
00337 if ( File::FILEMODE_Append == mode )
00338 {
00339 if ( File::FILEACC_Read == access )
00340 {
00341 m_fd = open(path.GetChars(), O_APPEND);
00342 }
00343 else
00344 {
00345 m_fd = open(path.GetChars(), O_APPEND);
00346 }
00347 }
00348 else
00349 {
00350 if ( File::FILEACC_Read == access )
00351 {
00352 m_fd = open(path.GetChars(), O_RDONLY);
00353 }
00354 else if ( File::FILEACC_Write == access )
00355 {
00356 m_fd = open(path.GetChars(), O_RDONLY);
00357 }
00358 else
00359 {
00360 m_fd = open(path.GetChars(), O_RDONLY);
00361 }
00362 }
00363 if ( 0 > m_fd )
00364 {
00365 throw new IOException("Can't open file");
00366 }
00367 else
00368 {
00369 m_state = new FdStreamState_Open(this, &m_state);
00370 }
00371 }
00372
00373 FdStream::~FdStream()
00374 {
00375 Close();
00376 delete m_state;
00377 }
00378
00379 void FdStream::Close()
00380 {
00381 m_state->Close();
00382 }
00383
00384 void FdStream::Flush()
00385 {
00386 m_state->Flush();
00387 }
00388
00389 int FdStream::Read(Array<byte>& buffer, const int offset, int count)
00390 {
00391 return m_state->Read(buffer, offset, count);
00392 }
00393
00394 int FdStream::ReadByte()
00395 {
00396 return m_state->ReadByte();
00397 }
00398
00399 long FdStream::Seek(const long offset, const SeekOrigin origin)
00400 {
00401 return m_state->Seek(offset, origin);
00402 }
00403
00404 void FdStream::Write(const Array<byte>& buffer, const int offset, const int count)
00405 {
00406 m_state->Write(buffer, offset, count);
00407 }
00408
00409 void FdStream::WriteByte(byte value)
00410 {
00411 m_state->WriteByte(value);
00412 }
00413
00414 bool FdStream::CanRead() const
00415 {
00416 return m_access != File::FILEACC_Write;
00417 }
00418
00419 bool FdStream::CanSeek() const
00420 {
00421 return true;
00422 }
00423
00424 bool FdStream::CanWrite() const
00425 {
00426 return m_access != File::FILEACC_Read;
00427 }
00428
00429 long FdStream::Length() const
00430 {
00431 return m_state->Length();
00432 }
00433
00434 long FdStream::Position() const
00435 {
00436 return m_state->Position();
00437 }
00438
00439 #ifdef DEBUG
00440 void FdStream::ValidateMem() const
00441 {
00442 m_filepathname.ValidateMem();
00443 ASSERT_PTR( m_state );
00444 m_state->ValidateMem();
00445 }
00446
00447 void FdStream::CheckMem() const
00448 {
00449 m_filepathname.CheckMem();
00450 DEBUG_NOTE_MEM( m_state );
00451 m_state->CheckMem();
00452 }
00453 #endif