X-Git-Url: http://git.tdb.fi/?p=libs%2Fcore.git;a=blobdiff_plain;f=source%2Fio%2Fslice.cpp;h=9ca5966c30acd1c03a18af313bbad5cc34737c81;hp=423c1a6c8cae85e73c2f6e15e9733786b31d700e;hb=HEAD;hpb=eedad559456b8e62ed3b9bd9e8253e5f8bcc02d6 diff --git a/source/io/slice.cpp b/source/io/slice.cpp index 423c1a6..9ca5966 100644 --- a/source/io/slice.cpp +++ b/source/io/slice.cpp @@ -1,4 +1,4 @@ -#include +#include #include "slice.h" using namespace std; @@ -9,17 +9,26 @@ namespace IO { Slice::Slice(Seekable &b, SeekOffset s, SeekOffset l): below(b), start_offset(s), - length(l), - position(0), - sync_position(true) + length(l) { if(s<0 || l<0) - throw invalid_argument("Slice"); + throw invalid_argument("Slice::Slice"); + Base::Synchronize sync(below); mode = below.get_mode()&M_RDWR; below.signal_flush_required.connect(sigc::mem_fun(this, &Slice::flush)); } +void Slice::set_block(bool) +{ + throw unsupported("Slice::set_block"); +} + +void Slice::set_inherit(bool) +{ + throw unsupported("Slice::set_inherit"); +} + void Slice::flush() { sync_position = true; @@ -30,9 +39,14 @@ unsigned Slice::prepare_op(unsigned size, Mode m) check_access(m); if(sync_position) - seek(position, S_BEG); - - SeekOffset remaining = start_offset+length-position; + { + SeekOffset pos = below.seek(start_offset+position, S_BEG)-start_offset; + if(pos!=position) + throw runtime_error("failed to restore position"); + sync_position = false; + } + + SeekOffset remaining = length-position; if(size>remaining) size = remaining; if(!size && m==M_READ) @@ -41,44 +55,48 @@ unsigned Slice::prepare_op(unsigned size, Mode m) return size; } -unsigned Slice::do_write(const char *data, unsigned size) +size_t Slice::do_write(const char *data, size_t size) { + Base::Synchronize sync(below); size = prepare_op(size, M_WRITE); if(!size) return 0; - unsigned len = below.write(data, size); + size_t len = below.write(data, size); position += len; return len; } -unsigned Slice::do_read(char *data, unsigned size) +size_t Slice::do_read(char *data, size_t size) { + Base::Synchronize sync(below); size = prepare_op(size, M_READ); if(!size) return 0; - unsigned len = below.read(data, size); + size_t len = below.read(data, size); if(!len && below.eof()) set_eof(); position += len; return len; } -unsigned Slice::put(char c) +size_t Slice::put(char c) { + Base::Synchronize sync(below); if(!prepare_op(1, M_WRITE)) return 0; - unsigned len = below.put(c); + size_t len = below.put(c); position += len; return len; } int Slice::get() { + Base::Synchronize sync(below); if(!prepare_op(1, M_READ)) - return 0; + return -1; int c = below.get(); if(c==-1 && below.eof()) @@ -88,14 +106,21 @@ int Slice::get() return c; } +const Handle &Slice::get_handle(Mode) +{ + throw unsupported("Slice::get_handle"); +} + SeekOffset Slice::seek(SeekOffset off, SeekType type) { - if(type==S_BEG) - off += start_offset; - else if(type==S_CUR) + Base::Synchronize sync(below); + off += start_offset; + if(type==S_CUR) off += position; else if(type==S_END) - off += start_offset+length; + off += length; + else if(type!=S_BEG) + throw invalid_argument("Slice::seek"); if(offstart_offset+length) throw bad_seek(off, type);