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

ByteCharacterEncoder.cc

Go to the documentation of this file.
00001 /*
00002  * ByteCharacterEncoder.cc
00003  *
00004  * Smalltalk like class library for C++
00005  * Character 8-bit encoding translator.
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/ByteCharacterEncoder.h>
00025 #include <stlib/Array.h>
00026 #include <stlib/Character.h>
00027 #include <stlib/Dictionary.h>
00028 #include <stlib/EncodedStream.h>
00029 #include <stlib/ExternalEncodedStreamFactory.h>
00030 #include <stlib/ExternalReadStream.h>
00031 #include <stlib/FileAccessor.h>
00032 #include <stlib/GenericException.h>
00033 #include <stlib/Integer.h>
00034 #include <stlib/String.h>
00035 #include <stlib/Stream.h>
00036 
00037 #include <fcntl.h>
00038 
00039 namespace Core {
00040 
00041 ByteCharacterEncoder::ByteCharacterEncoder(void)
00042 {
00043     decodeMap = new Array(256);
00044     encodeMap = new Dictionary(320); // 256 * 5/4 -> pregrowed
00045 }
00046 
00047 ByteCharacterEncoder::~ByteCharacterEncoder(void)
00048 {
00049     if (decodeMap != nil) delete decodeMap;
00050     if (encodeMap != nil) delete encodeMap;
00051 }
00052 
00053 /* Class-accessing protocol */
00054 String *ByteCharacterEncoder::className(void) const
00055 {
00056     return new String("ByteCharacterEncoder");
00057 }
00058 
00059 /* Initialize protocol */
00060 void ByteCharacterEncoder::loadFromFile(const char *filename)
00061 {
00062     FileAccessor *file = new FileAccessor(filename, O_RDONLY, 0);
00063     loadFrom(file->withEncoding("us-ascii")->readStream());
00064 }
00065 
00066 void ByteCharacterEncoder::loadFrom(Stream *stream)
00067 {
00068     _ensure(
00069         while (!stream->atEnd()) {
00070             parseLine(dynamic_cast<String *>(stream->nextLine()));
00071         }
00072     ,
00073         stream->close()
00074     );
00075 }
00076 
00077 ByteCharacterEncoder *ByteCharacterEncoder::forASCII(void)
00078 {
00079     ByteCharacterEncoder *ascii = new ByteCharacterEncoder;
00080     ascii->initializeAsciiEncoder();
00081     return ascii;
00082 }
00083 
00084 void ByteCharacterEncoder::initializeAsciiEncoder(void)
00085 {
00086     for (int i = 0; i < 0x7F; i++) {
00087         Character *character = Character::value(i);
00088         encodeMap->put(character, Integer::value(i));
00089         decodeMap->put(i, character);
00090     }
00091 }
00092 
00093 /* Accessing protocol */
00094 Character *ByteCharacterEncoder::decode(Integer *value)
00095 {
00096     Object *ch = decodeMap->at(value->asLong());
00097     if (ch == nil)
00098         error(new String("No character available"),
00099               new String(__PRETTY_FUNCTION__), value);
00100     return dynamic_cast<Character *>(ch);
00101 }
00102 
00103 Integer *ByteCharacterEncoder::encode(Character *character)
00104 {
00105     Integer *value = dynamic_cast<Integer *>(encodeMap->at(character, nil));
00106     if (value == nil)
00107         error(new String("No character available"),
00108               new String(__PRETTY_FUNCTION__), character);
00109     return value;
00110 }
00111 
00112 /* Private protocol */
00113 long ByteCharacterEncoder::integerValueFrom(String *strNumber)
00114 {
00115     unsigned long value = 0, index = 0, radix = 10;
00116     if (strNumber->startsWith("0x")) {
00117         index = 2;
00118         radix = 16;
00119     }
00120 
00121     for (; index < strNumber->size(); index++) {
00122         Character *ch = dynamic_cast<Character *>(strNumber->at(index));
00123         value = value * radix + ch->digitValue();
00124     }
00125     return value;
00126 }
00127     
00128 void ByteCharacterEncoder::parseLine(String *line)
00129 {
00130     long idx;
00131     unsigned long encValue, charValue;
00132     Character *character;
00133 
00134     line->replaceAll(Character::tab(), Character::space());
00135 
00136     /* Remove comments */
00137     idx = line->indexOf('#');
00138     if (idx > 0) line = dynamic_cast<String *>(line->copy(0, idx));
00139     line = line->trimBlanks();
00140     if (idx == 0 || line->isEmpty()) return;
00141 
00142     Array *pair = line->asArrayOfSubstrings();
00143     if (pair->size() >= 2) {  /* At least two items are needed */
00144         encValue = integerValueFrom(dynamic_cast<String *>(pair->at(0)));
00145         charValue = integerValueFrom(dynamic_cast<String *>(pair->at(1)));
00146     }
00147     character = Character::value(charValue);
00148     encodeMap->put(character, Integer::value(encValue));
00149     decodeMap->put(encValue, character);
00150 }
00151 
00152 };

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