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/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
00033 String *UTF8StreamEncoder::className(void) const
00034 {
00035 return new String("UTF8StreamEncoder");
00036 }
00037
00038
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
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
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 };