00001 #include "stlib/LineEndConvertor.h" 00002 00003 #include "stlib/Character.h" 00004 #include "stlib/String.h" 00005 00006 namespace Core { 00007 00008 LineEndConvertor::LineEndConvertor(LineEndConvention convention, Stream *stream) 00009 : StreamDecorator(stream) 00010 { 00011 line_end_convention = convention; 00012 setLineEndCharacter(); 00013 } 00014 00015 /* Instance creation protocol */ 00016 LineEndConvertor *LineEndConvertor::lineEndCROn(Stream *stream) 00017 { 00018 return new LineEndConvertor(LineEndCR, stream); 00019 } 00020 00021 LineEndConvertor *LineEndConvertor::lineEndLFOn(Stream *stream) 00022 { 00023 return new LineEndConvertor(LineEndLF, stream); 00024 } 00025 00026 LineEndConvertor *LineEndConvertor::lineEndCRLFOn(Stream *stream) 00027 { 00028 return new LineEndConvertor(LineEndCRLF, stream); 00029 } 00030 00031 /* Accessing protocol */ 00032 Object *LineEndConvertor::next(void) 00033 { 00034 Character *ch = dynamic_cast<Character *>(underlying_stream->next()); 00035 if (line_end_character == nil || !line_end_character->isEqual(ch)) 00036 return ch; 00037 if (line_end_convention == LineEndCR) return Character::lf(); 00038 if (line_end_convention == LineEndCRLF) { 00039 ch = dynamic_cast<Character *>(underlying_stream->next()); 00040 if (ch == nil) return Character::lf(); 00041 if (!ch->isEqual(Character::lf())) underlying_stream->skip(-1); 00042 } 00043 return Character::lf(); 00044 } 00045 00046 void LineEndConvertor::nextPut(Object *object) 00047 { 00048 if (object->isEqual(Character::lf())) { 00049 switch (line_end_convention) { 00050 case LineEndCR : 00051 underlying_stream->nextPut(Character::cr()); 00052 break; 00053 case LineEndCRLF : 00054 underlying_stream->nextPut(Character::cr()); 00055 underlying_stream->nextPut(object); 00056 break; 00057 case LineEndLF : 00058 case LineEndTransparent : 00059 underlying_stream->nextPut(object); 00060 break; 00061 } 00062 } else 00063 underlying_stream->nextPut(object); 00064 } 00065 00066 /* Testing protocol */ 00067 bool LineEndConvertor::isBinary(void) 00068 { 00069 return false; 00070 } 00071 00072 /* Private protocol */ 00073 void LineEndConvertor::setLineEndCharacter(void) 00074 { 00075 line_end_character = nil; 00076 if (line_end_convention == LineEndCRLF || 00077 line_end_convention == LineEndCR) 00078 line_end_character = Character::cr(); 00079 } 00080 00081 SequenceableCollection *LineEndConvertor::contentSpeciesFor(long items) 00082 { 00083 return new String(items); 00084 } 00085 00086 }; /* namespace Core */