00001 /* 00002 * EncodedStream.cc 00003 * 00004 * Smalltalk like class library for C++ 00005 * Stream with encoding translation capability. 00006 * 00007 * Copyright (c) 2004-6 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 <stlib/EncodedStream.h> 00025 #include <stlib/ByteArray.h> 00026 #include <stlib/Character.h> 00027 #include <stlib/InternalEncodedStreamFactory.h> 00028 #include <stlib/StreamEncoder.h> 00029 #include <stlib/String.h> 00030 00031 #include <stlib/Error.h> 00032 00033 namespace Core { 00034 00035 EncodedStream::EncodedStream(Stream *stream, StreamEncoder *encoder) 00036 : StreamDecorator(stream) 00037 { 00038 this->encoder = encoder; 00039 _replacement = nil; 00040 } 00041 00042 /* Class-accessing protocol */ 00043 String *EncodedStream::className(void) const 00044 { 00045 return new String("EncodedStream"); 00046 } 00047 00048 /* Instance creation protocol */ 00049 EncodedStream *EncodedStream::on(String *encoding, Stream *stream) 00050 { 00051 InternalEncodedStreamFactory *factory = new InternalEncodedStreamFactory(new ByteArray, encoding); 00052 return new EncodedStream(stream, factory->getEncoder()); 00053 } 00054 00055 /* Initialize protocol */ 00056 void EncodedStream::replacementCharacter(Character *ch) 00057 { 00058 _replacement = ch; 00059 } 00060 00061 void EncodedStream::bigEndian(void) 00062 { 00063 encoder->bigEndian(); 00064 } 00065 00066 void EncodedStream::littleEndian(void) 00067 { 00068 encoder->littleEndian(); 00069 } 00070 00071 /* Accessing protocol */ 00072 Object *EncodedStream::next(void) 00073 { 00074 try { 00075 return encoder->decodeFrom(underlying_stream); 00076 } 00077 catch (Error *ex) { 00078 if (_replacement == nil) ex->pass(); 00079 return _replacement; 00080 } 00081 } 00082 00083 void EncodedStream::nextPut(Object *object) 00084 { 00085 try { 00086 encoder->encodeTo(underlying_stream, dynamic_cast<Character *>(object)); 00087 } 00088 catch (Error *ex) { 00089 if (_replacement == nil) 00090 ex->pass(); 00091 else 00092 encoder->encodeTo(underlying_stream, _replacement); 00093 } 00094 } 00095 00096 /* Testing protocol */ 00097 bool EncodedStream::isBinary(void) 00098 { 00099 return false; 00100 } 00101 00102 /* Private protocol */ 00103 SequenceableCollection *EncodedStream::contentSpeciesFor(long items) 00104 { 00105 return new String(items); 00106 } 00107 00108 }; /* namespace Core */