Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

EncodedStreamFactory.cc

Go to the documentation of this file.
00001 /*
00002  * EncodedStreamFactory.cc
00003  *
00004  * Smalltalk like class library for C++
00005  * EncodedStream constructor.
00006  *
00007  * Copyright (c) 2005 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/EncodedStreamFactory.h>
00025 #include <stlib/ByteArray.h>
00026 #include <stlib/Dictionary.h>
00027 #include <stlib/Locale.h>
00028 #include <stlib/String.h>
00029 #include <stlib/WriteStream.h>
00030 
00031 #include <stlib/StreamEncoder.h>
00032 #include <stlib/ByteStreamEncoder.h>
00033 #include <stlib/UCS2StreamEncoder.h>
00034 #include <stlib/UTF8StreamEncoder.h>
00035 #include <stlib/WriteStream.h>
00036 
00037 #include <stlib/ByteCharacterEncoder.h>
00038 
00039 #include <string.h>
00040 
00041 #ifndef DATADIR
00042 #error DATADIR must be defined!
00043 #endif
00044 
00045 namespace Core {
00046 
00047 Dictionary *EncodedStreamFactory::encoding_map = nil;
00048 
00049 EncodedStreamFactory::EncodedStreamFactory(String *encoding)
00050 {
00051     _encoding = encoding->asLowercase();
00052     if (_encoding->isEqual("default"))
00053         _encoding = Locale::current()->encoding()->asLowercase();
00054     normalized_encoding = nil;
00055     initializeAsciiEncoder();
00056 }
00057 
00058 /* Class-accessing protocol */
00059 String *EncodedStreamFactory::className(void) const
00060 {
00061     return new String("EncodedStreamFactory");
00062 }
00063 
00064 Dictionary *EncodedStreamFactory::encodingMap(void)
00065 {
00066     if (encoding_map == nil)
00067         encoding_map = new Dictionary;
00068     return encoding_map;
00069 }
00070 
00071 /* Initialize protocol */
00072 void EncodedStreamFactory::initializeAsciiEncoder(void)
00073 {
00074     ByteArray *key = new ByteArray("usascii", 7);
00075     if (!encodingMap()->includesKey(key)) {
00076         encodingMap()->put(key, ByteCharacterEncoder::forASCII());
00077     }
00078 }
00079 
00080 /* Accessing protocol */
00081 String *EncodedStreamFactory::encoding(void)
00082 {
00083     return _encoding;
00084 }
00085 
00086 /* Utilities protocol */
00087 ByteArray *EncodedStreamFactory::normalizedEncoding(void)
00088 {
00089     if (normalized_encoding == nil) {
00090         Stream *stream = (new ByteArray(10))->writeStream();
00091         for (int i = 0; i < _encoding->size(); i++) {
00092             Character *ch = dynamic_cast<Character *>(_encoding->at(i));
00093             int chValue = ch->asInteger();
00094             if (ch->isDigit() || (chValue >= 'a' && chValue <= 'z')) {
00095                 stream->nextPut(Integer::value(chValue));
00096             }
00097         }
00098         normalized_encoding = dynamic_cast<ByteArray *>(stream->contents());
00099     }
00100     return normalized_encoding;
00101 }
00102 
00103 /* Private protocol */
00104 CharacterEncoder *EncodedStreamFactory::createCharacterEncoder(void)
00105 {
00106     /* All charset conversions must be avoided in this method!
00107      * That's why this is written with C functions.
00108      */
00109 
00110     ByteArray *enc = normalizedEncoding();
00111     int length = 20 + enc->size() + strlen(DATADIR);
00112     char filename[length];
00113     sprintf(filename, "%s/encodings/%s.enc", DATADIR, enc->asCString());
00114 
00115     ByteCharacterEncoder *encoder = new ByteCharacterEncoder;
00116     encoder->loadFromFile(filename);
00117     return encoder;
00118 }
00119 
00120 CharacterEncoder *EncodedStreamFactory::getCharacterEncoder(void)
00121 {
00122     CharacterEncoder *encoder = dynamic_cast<CharacterEncoder *>(encodingMap()->at(_encoding, nil));
00123     if (encoder == nil) {
00124         encoder = dynamic_cast<CharacterEncoder *>(encodingMap()->at(normalizedEncoding(), nil));
00125     }
00126     if (encoder == nil) {
00127         encoder = createCharacterEncoder();
00128         encodingMap()->put(normalizedEncoding(), encoder);
00129     }
00130     encodingMap()->put(_encoding, encoder);
00131     return encoder;
00132 }
00133 
00134 StreamEncoder *EncodedStreamFactory::getEncoder(void)
00135 {
00136     if (strcmp(normalizedEncoding()->asCString(), "utf8") == 0)
00137         return new UTF8StreamEncoder;
00138     if (strcmp(normalizedEncoding()->asCString(), "ucs2") == 0)
00139         return new UCS2StreamEncoder;
00140 
00141     return new ByteStreamEncoder(getCharacterEncoder());
00142 }
00143 
00144 }; /* namespace Core */

Generated on Mon Nov 27 09:47:55 2006 for Smalltalk like C++ Class Library by  doxygen 1.4.2