00001
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005
00006
00007 #include "vil1_stream_core.h"
00008
00009 #include <vcl_cassert.h>
00010
00011 vil1_stream_core::~vil1_stream_core()
00012 {
00013 for (unsigned i=0; i<block_.size(); ++i)
00014 delete [] block_[i];
00015 block_.clear();
00016 }
00017
00018
00019
00020 vil1_streampos vil1_stream_core::read (void *buf, vil1_streampos n)
00021 {
00022 assert(n>=0);
00023
00024 vil1_streampos rv = m_transfer((char*)buf, curpos_, n, true );
00025 curpos_ += rv;
00026 return rv;
00027 }
00028
00029 vil1_streampos vil1_stream_core::write(void const *buf, vil1_streampos n)
00030 {
00031 assert(n>=0);
00032 vil1_streampos rv = m_transfer((char*)(const_cast<void*>(buf)), curpos_, n, false);
00033 curpos_ += rv;
00034 return rv;
00035 }
00036
00037
00038
00039 vil1_streampos vil1_stream_core::m_transfer(char *buf, vil1_streampos pos, vil1_streampos n, bool read)
00040 {
00041 assert(n>=0);
00042 assert(pos>=0);
00043
00044 if (read)
00045 {
00046 if (pos+n > tailpos_)
00047 {
00048 if (pos > tailpos_)
00049 n = 0;
00050 else
00051 n = tailpos_ - pos;
00052 }
00053 if (n==0L) return 0;
00054 }
00055 else
00056
00057 while (blocksize_*block_.size() < (unsigned long)(pos+n))
00058 block_.push_back(new char [blocksize_]);
00059
00060
00061 {
00062 char *tbuf = buf;
00063 vil1_streampos tpos = pos;
00064 vil1_streampos tn = n;
00065 while (tn>0) {
00066 vil1_streampos bl = tpos/(long)blocksize_;
00067 vil1_streampos s = tpos - (long)blocksize_*bl;
00068 vil1_streampos z = ((tn+s > (long)blocksize_) ? (long)blocksize_-s : tn);
00069 char *tmp = block_[bl];
00070 if (read)
00071 for (vil1_streampos k=0; k<z; ++k)
00072 tbuf[k] = tmp[s+k];
00073 else
00074 {
00075 assert (s+z <= (long)blocksize_);
00076 for (vil1_streampos k=0; k<z; ++k)
00077 tmp[s+k] = tbuf[k];
00078 }
00079 tbuf += z;
00080 tn -= z;
00081 tpos += z;
00082 }
00083 }
00084
00085
00086 if (tailpos_ < pos+n)
00087 tailpos_ = pos+n;
00088
00089
00090 return n;
00091 }