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

UTF8StreamEncoder.cc

Go to the documentation of this file.
00001 /*
00002  * UTF8StreamEncoder.cc
00003  *
00004  * Smalltalk like class library for C++
00005  * UTF-8 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/UTF8StreamEncoder.h>
00025 #include <stlib/Character.h>
00026 #include <stlib/Integer.h>
00027 #include <stlib/Stream.h>
00028 #include <stlib/String.h>
00029 
00030 namespace Core {
00031 
00032 /* Class-accessing protocol */
00033 String *UTF8StreamEncoder::className(void) const
00034 {
00035     return new String("UTF8StreamEncoder");
00036 }
00037 
00038 /* Accessing protocol */
00039 Character *UTF8StreamEncoder::decodeFrom(Stream *stream)
00040 {
00041     unsigned long charValue = 0;
00042     unsigned char byteCount;
00043     int byteValue;
00044 
00045     Object *item = stream->next();
00046     if (item == nil) {
00047         /* End of stream reached */
00048         return nil;
00049     }
00050 
00051     byteValue = dynamic_cast<Integer *>(item)->asLong();
00052     if (byteValue < 128) {
00053         byteCount = 0;
00054     } else if (byteValue < 224) {
00055         byteCount = 1;
00056         byteValue = byteValue & 31;
00057     } else if (byteValue < 240) {
00058         byteCount = 2;
00059         byteValue = byteValue & 15;
00060     } else if (byteValue < 248) {
00061         byteCount = 3;
00062         byteValue = byteValue & 7;
00063     } else if (byteValue < 252) {
00064         byteCount = 4;
00065         byteValue = byteValue & 3;
00066     } else if (byteValue < 254) {
00067         byteCount = 5;
00068         byteValue = byteValue & 1;
00069     } else {
00070         error(new String("Illegal UTF-8 code."), new String(__PRETTY_FUNCTION__));
00071     }
00072     charValue = byteValue;
00073     for (int i = 0; i < byteCount; i++) {
00074         byteValue = dynamic_cast<Integer *>(stream->next())->asLong();
00075         charValue = (charValue << 6) + (byteValue & 63);
00076     }
00077     return Character::value(charValue);
00078 }
00079 
00080 void UTF8StreamEncoder::encodeTo(Stream *stream, Character *character)
00081 {
00082     unsigned long value = character->asInteger();
00083     unsigned char bitfill = 0, byteCounter = 0;
00084     unsigned char buffer[6];
00085 
00086     if (value < 128) {
00087         stream->nextPut(Integer::value(value));
00088         return;
00089     }
00090     /* value is greater than 127 => need more bytes to encode */
00091     do {
00092         int byteValue;
00093         bitfill = (bitfill << 1) + 1;
00094         byteCounter++;
00095         byteValue = value & 63;
00096         value = value >> 6;
00097         if (value > 0)
00098             buffer[byteCounter-1] = 0x80 | byteValue;
00099         else
00100             buffer[byteCounter-1] = (bitfill << (8 - byteCounter)) | byteValue;
00101     } while (value > 0);
00102 
00103     for (int i = byteCounter - 1; i >= 0; i--) {
00104         stream->nextPut(Integer::value(buffer[i]));
00105     }
00106 }
00107 
00108 }; /* namespace Core */

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