?? stream.cc
字號(hào):
: File(), mFilename(aFilename){ mOpenMode = om; file = NULL; own_file = false; offset = 0; int e = LocalFile::setAccessMode(am); if (e) throw IOException(e); mOpenMode = FOM_EXISTS;}/** * map a file stream [FILE*] */LocalFile::LocalFile(SYS_FILE *f, bool own_f, IOAccessMode am) : File(){ file = f; own_file = own_f; File::setAccessMode(am);}LocalFile::~LocalFile(){ if (own_file && file) sys_fclose(file);}String &LocalFile::getDesc(String &result) const{ result = mFilename; return result;}String &LocalFile::getFilename(String &result) const{ result = mFilename; return result;}FileOfs LocalFile::getSize() const{ FileOfs t = tell(); sys_fseek(file, 0, SYS_SEEK_END); FileOfs r = sys_ftell(file); sys_fseek(file, t, SYS_SEEK_SET); return r;}void LocalFile::pstat(pstat_t &s) const{ sys_pstat_file(s, file);}uint LocalFile::read(void *buf, uint size){ if (!(getAccessMode() & IOAM_READ)) throw IOException(EACCES); errno = 0; uint r = sys_fread(file, (byte*)buf, size); if (errno) throw IOException(errno); offset += r; return r;}void LocalFile::seek(FileOfs o){ int e = sys_fseek(file, o, SYS_SEEK_SET); if (e) throw IOException(e); offset = o;}int LocalFile::setAccessMode(IOAccessMode am){ IOAccessMode orig_access_mode = getAccessMode(); int e = setAccessModeInternal(am); if (e && setAccessModeInternal(orig_access_mode)) throw IOException(e); return e;}int LocalFile::setAccessModeInternal(IOAccessMode am){//RETRY: if (getAccessMode() == am) return 0; int e = 0; if (am != IOAM_NULL) { pstat_t s; if (file) { file = sys_freopen(mFilename.contentChar(), mOpenMode, am, file); if (!file) setAccessMode(IOAM_NULL); } else { file = sys_fopen(mFilename.contentChar(), mOpenMode, am); } if (!file) e = errno; if (!e) { own_file = true; e = sys_pstat_file(s, file); if (!e) { if (HT_S_ISDIR(s.mode)) { e = EISDIR; } else if (!HT_S_ISREG(s.mode) && !HT_S_ISBLK(s.mode)) { e = EINVAL; } } } } else { if (file) { sys_fclose(file); file = NULL; } } return e ? e : File::setAccessMode(am);}FileOfs LocalFile::tell() const{ return offset;}void LocalFile::truncate(FileOfs newsize){ errno = 0; IOAccessMode old_am = getAccessMode(); int e; e = setAccessMode(IOAM_NULL); if (!e) { e = sys_truncate(mFilename.contentChar(), newsize); if (errno) e = errno; } if (!e) e = setAccessMode(old_am); if (e) throw IOException(e);}int LocalFile::vcntl(uint cmd, va_list vargs){ switch (cmd) { case FCNTL_FLUSH_STAT: { IOAccessMode m = getAccessMode(); int e, f; e = setAccessMode(IOAM_NULL); f = setAccessMode(m); return e ? e : f; } case FCNTL_GET_FD: // (int &fd)/* if (file) { int *pfd = va_arg(vargs, int*); *pfd = fileno(file); return 0; }*/ // FIXME: assert(0); break; } return File::vcntl(cmd, vargs);}uint LocalFile::write(const void *buf, uint size){ if (!(getAccessMode() & IOAM_WRITE)) throw IOException(EACCES); errno = 0; uint r = sys_fwrite(file, (byte*)buf, size); if (errno) throw IOException(errno); offset += r; return r;}/* * TempFile */TempFile::TempFile(uint am) : LocalFile(tmpfile(), true, am){}String &TempFile::getDesc(String &result) const{ result = "temporary file"; return result;}void TempFile::pstat(pstat_t &s) const{ s.caps = pstat_size; s.size = getSize();}/* * MemMapFile */MemMapFile::MemMapFile(void *b, uint s, FileOfs ofs) : ConstMemMapFile(b, s, ofs){}uint MemMapFile::write(const void *b, uint size){ if (pos > this->size) return 0; // or throw exception? if (pos+size > this->size) size = this->size - pos; memcpy(((byte*)buf) + pos, b, size); pos += size; return size;}/* * ConstMemMapFile */ConstMemMapFile::ConstMemMapFile(const void *b, uint s, FileOfs o): File(){ buf = b; pos = 0; size = s; ofs = o;}String &ConstMemMapFile::getDesc(String &result) const{ result = "ConstMemMapFile"; return result;}FileOfs ConstMemMapFile::getSize() const{ return size;}uint ConstMemMapFile::read(void *b, uint size){ if (pos > this->size) return 0; if (pos+size > this->size) size = this->size - pos; memcpy(b, (const byte*)buf+pos, size); pos += size; return size;}void ConstMemMapFile::seek(FileOfs offset){ pos = offset - ofs;}FileOfs ConstMemMapFile::tell() const{ return pos + ofs;}/* * NullFile */NullFile::NullFile() : File(){}void NullFile::extend(FileOfs newsize){ if (newsize != 0) throw IOException(EINVAL);}String &NullFile::getDesc(String &result) const{ result = "null device"; return result;}FileOfs NullFile::getSize() const{ return 0;}void NullFile::pstat(pstat_t &s) const{ s.caps = pstat_size; s.size = getSize();}uint NullFile::read(void *buf, uint size){ return 0;}void NullFile::seek(FileOfs offset){ if (offset != 0) throw IOException(EINVAL);}int NullFile::setAccessMode(IOAccessMode am){ return (am == getAccessMode()) ? 0 : EACCES;}FileOfs NullFile::tell() const{ return 0;}void NullFile::truncate(FileOfs newsize){ if (newsize != 0) throw IOException(EINVAL);}uint NullFile::write(const void *buf, uint size){ return 0;}/* * MemoryFile */#define MEMORYFILE_GROW_FACTOR_NUM 4#define MEMORYFILE_GROW_FACTOR_DENOM 3#define MEMORYFILE_MIN_BUFSIZE 32MemoryFile::MemoryFile(FileOfs o, uint size, IOAccessMode mode) : File(){ ofs = o; dsize = size; buf = NULL; ibufsize = size; if (ibufsize < MEMORYFILE_MIN_BUFSIZE) ibufsize = MEMORYFILE_MIN_BUFSIZE; resizeBuf(ibufsize); memset(buf, 0, dsize); mcount = 0; pos = 0; int e = setAccessMode(mode); if (e) throw IOException(e);}MemoryFile::~MemoryFile(){ free(buf);}byte *MemoryFile::getBufPtr() const{ return buf;}void MemoryFile::extend(FileOfs newsize){ // MemoryFiles may not be > 2G if (newsize > 0x7fffffff) throw IOException(EINVAL); if (newsize < getSize()) throw IOException(EINVAL); if (newsize == getSize()) return; while (bufsize<newsize) extendBuf(); memset(buf+dsize, 0, newsize-dsize); dsize = newsize; mcount++;}void MemoryFile::extendBuf(){ resizeBuf(extendBufSize(bufsize));}uint MemoryFile::extendBufSize(uint bufsize){ return bufsize * MEMORYFILE_GROW_FACTOR_NUM / MEMORYFILE_GROW_FACTOR_DENOM;}IOAccessMode MemoryFile::getAccessMode() const{ return Stream::getAccessMode();}String &MemoryFile::getDesc(String &result) const{ result = "MemoryFile"; return result;}FileOfs MemoryFile::getSize() const{ return dsize;}void MemoryFile::pstat(pstat_t &s) const{ s.caps = pstat_size; s.size = getSize();}uint MemoryFile::read(void *b, uint size){ if (pos+size > dsize) { if (pos >= dsize) return 0; size = dsize-pos; } memcpy(b, buf+pos, size); pos += size; return size;}void MemoryFile::resizeBuf(uint newsize){ bufsize = newsize; assert(dsize <= bufsize); buf = (byte*)realloc(buf, bufsize ? bufsize : 1); if (!buf) throw std::bad_alloc();}void MemoryFile::seek(FileOfs o){ if (o<ofs) throw IOException(EINVAL); pos = o-ofs;}int MemoryFile::setAccessMode(IOAccessMode mode){ int e = Stream::setAccessMode(mode); if (e) return e; seek(ofs); return 0;}uint MemoryFile::shrinkBufSize(uint bufsize){ return bufsize * MEMORYFILE_GROW_FACTOR_DENOM / MEMORYFILE_GROW_FACTOR_NUM;}void MemoryFile::shrinkBuf(){ resizeBuf(shrinkBufSize(bufsize));}FileOfs MemoryFile::tell() const{ return pos+ofs;}void MemoryFile::truncate(FileOfs newsize){ dsize = newsize; uint s = ibufsize; while (s<dsize) s = extendBufSize(s); resizeBuf(s); mcount++;}uint MemoryFile::write(const void *b, uint size){ while (pos+size >= bufsize) extendBuf(); memcpy(((byte*)buf) + pos, b, size); pos += size; if (pos > dsize) dsize = pos; mcount++; return size;}/* * A file layer, representing a cropped version of a file */CroppedFile::CroppedFile(File *file, bool own_file, FileOfs aCropStart, FileOfs aCropSize): FileLayer(file, own_file){ mCropStart = aCropStart; mHasCropSize = true; mCropSize = aCropSize; seek(0);}CroppedFile::CroppedFile(File *file, bool own_file, FileOfs aCropStart): FileLayer(file, own_file){ mCropStart = aCropStart; mHasCropSize = false; seek(0);}void CroppedFile::extend(FileOfs newsize){ throw IOException(ENOSYS);}String &CroppedFile::getDesc(String &result) const{ String s; if (mHasCropSize) { result.assignFormat("[->%qx,%qx] of %y", mCropStart, mCropSize, &FileLayer::getDesc(s)); } else { result.assignFormat("[->%qx,...] of %y", mCropStart, &FileLayer::getDesc(s)); } return result;}FileOfs CroppedFile::getSize() const{ FileOfs lsize = FileLayer::getSize(); if (lsize < mCropStart) return 0; lsize -= mCropStart; if (mHasCropSize) { if (lsize > mCropSize) lsize = mCropSize; } return lsize;}void CroppedFile::pstat(pstat_t &s) const{ FileLayer::pstat(s); if (s.caps & pstat_size) { s.size = getSize(); }}uint CroppedFile::read(void *buf, uint size){ FileOfs offset = FileLayer::tell(); if (offset<mCropStart) return 0; if (mHasCropSize) { if (offset >= mCropStart+mCropSize) return 0; if (offset+size >= mCropStart+mCropSize) size = mCropStart+mCropSize-offset; } return FileLayer::read(buf, size);}void CroppedFile::seek(FileOfs offset){/* if (mHasCropSize) {... if (offset>mCropStart) throw IOException(EIO); }*/ FileLayer::seek(offset+mCropStart);}FileOfs CroppedFile::tell() const{ FileOfs offset = FileLayer::tell(); if (offset < mCropStart) throw IOException(EIO); return offset - mCropStart;}void CroppedFile::truncate(FileOfs newsize){ // not implemented because not considered safe throw IOException(ENOSYS);}uint CroppedFile::write(const void *buf, uint size){ FileOfs offset = FileLayer::tell(); if (offset<mCropStart) return 0; if (mHasCropSize) { if (offset >= mCropStart+mCropSize) return 0; if (offset+size >= mCropStart+mCropSize) size = mCropStart+mCropSize-offset; } return FileLayer::write(buf, size);}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -