00001 /* 00002 * ExternalWriteStream.cc 00003 * 00004 * Smalltalk like class library for C++ 00005 * External write stream. 00006 * 00007 * Copyright (c) 2003 Milan Cermak 00008 */ 00009 /* 00010 * This library is free software; you can redistribute it and/or 00011 * modify it under the terms of the GNU Lesser General Public 00012 * License as published by the Free Software Foundation; either 00013 * version 2.1 of the License, or (at your option) any later version. 00014 * 00015 * This library is distributed in the hope that it will be useful, 00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 * Lesser General Public License for more details. 00019 * 00020 * You should have received a copy of the GNU Lesser General Public 00021 * License along with this library; if not, write to the Free Software 00022 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00023 */ 00024 #include <stdio.h> 00025 00026 #include <stlib/ExternalWriteStream.h> 00027 #include <stlib/ByteArray.h> 00028 #include <stlib/Character.h> 00029 #include <stlib/IOAccessor.h> 00030 #include <stlib/IOBuffer.h> 00031 #include <stlib/SequenceableCollection.h> 00032 #include <stlib/String.h> 00033 00034 #include <stlib/Error.h> 00035 00036 ExternalWriteStream::ExternalWriteStream(IOAccessor *accessor) 00037 : ExternalStream(accessor) 00038 { 00039 /* Does nothing */ 00040 } 00041 00042 /* Class-accessing protocol */ 00043 String *ExternalWriteStream::className(void) const 00044 { 00045 return new String("ExternalWriteStream"); 00046 } 00047 00048 /* Accessing protocol */ 00049 void ExternalWriteStream::flush(void) 00050 { 00051 if (write_limit == -1 || _position < 1) return; 00052 io_buffer->bufferChanged(); 00053 io_buffer->flushBufferUpTo(_position); 00054 collection = io_buffer->buffer(); 00055 _position = io_buffer->firstDataPosition(); 00056 write_limit = collection->size(); 00057 } 00058 00059 Object *ExternalWriteStream::next(void) 00060 { 00061 shouldNotImplement(new String(__PRETTY_FUNCTION__)); 00062 return nil; 00063 } 00064 00065 void ExternalWriteStream::nextPut(Object *object) 00066 { 00067 if (_position >= write_limit) { 00068 if (write_limit == -1) { 00069 write_limit = io_buffer->lastWriteablePosition(); 00070 if (_position >= write_limit) flush(); 00071 } else 00072 flush(); 00073 } 00074 collection->put(_position++, object); 00075 } 00076 00077 long ExternalWriteStream::size(void) 00078 { 00079 flush(); 00080 return io_accessor->dataSize(); 00081 } 00082 00083 /* Positioning protocol */ 00084 long ExternalWriteStream::position(void) 00085 { 00086 return writePosition(); 00087 } 00088 00089 void ExternalWriteStream::position(long position) 00090 { 00091 error(new String("ExternalWriteStreams cannot be positioned."), 00092 new String(__PRETTY_FUNCTION__)); 00093 } 00094 00095 long ExternalWriteStream::writePosition(void) 00096 { 00097 return io_accessor->dataSize() + _position; 00098 } 00099 00100 /* Testing protocol */ 00101 bool ExternalWriteStream::atEnd(void) 00102 { 00103 return true; 00104 } 00105 00106 bool ExternalWriteStream::isReadable(void) 00107 { 00108 return false; 00109 } 00110 00111 bool ExternalWriteStream::isWritable(void) 00112 { 00113 return true; 00114 } 00115 00116 /* Private protocol */ 00117 void ExternalWriteStream::closeConnection(void) 00118 { 00119 try { 00120 flush(); 00121 io_accessor->close(); 00122 } 00123 catch (Error *ex) { 00124 fprintf(stderr, "ExternalWriteStream: error occured %s\n", ex->printString()->asCString()); 00125 } 00126 _position = read_limit = 0; 00127 write_limit = -1; 00128 } 00129 00130 bool ExternalWriteStream::nextBuffer(void) 00131 { 00132 flush(); 00133 return true; 00134 }