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