00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
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
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
00081 String *EncodedStreamFactory::encoding(void)
00082 {
00083 return _encoding;
00084 }
00085
00086
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
00104 CharacterEncoder *EncodedStreamFactory::createCharacterEncoder(void)
00105 {
00106
00107
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 };