/*
Реализация спецификаций CLDC версии 1.1 (JSR-139), MIDP версии 2.1 (JSR-118)
и других спецификаций для функционирования компактных приложений на языке
Java (мидлетов) в среде программного обеспечения Малик Эмулятор.
Copyright © 2016–2017, 2019–2023 Малик Разработчик
Это свободная программа: вы можете перераспространять ее и/или изменять
ее на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
в каком она была опубликована Фондом свободного программного обеспечения;
либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
Эта программа распространяется в надежде, что она будет полезной,
но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
общественной лицензии GNU.
Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
вместе с этой программой. Если это не так, см.
<https://www.gnu.org/licenses/>.
*/
package malik.emulator.i18n.encoding.system;
import malik.emulator.i18n.*;
public class UTF_8_Codec extends Object implements TextCodec
{
public UTF_8_Codec() {
}
public char[] decode(byte[] src, int offset, int length) {
int newlength = 0;
char[] result = new char[length];
for(int limit = offset + length; offset < limit; )
{
int char1;
int char2;
int char3;
switch((char1 = src[offset++] & 0xff) >> 4)
{
default:
break;
case 0x00:
case 0x01:
case 0x02:
case 0x03:
case 0x04:
case 0x05:
case 0x06:
case 0x07:
result[newlength++] = (char) char1;
break;
case 0x0c:
case 0x0d:
char2 = offset >= limit ? 0x80 : src[offset++];
if((char2 & 0xc0) != 0x80)
{
offset--;
char2 = 0;
}
result[newlength++] = (char) ((char1 & 0x1f) << 6 | (char2 & 0x3f));
break;
case 0x0e:
char2 = offset >= limit ? 0x80 : src[offset++];
if((char2 & 0xc0) != 0x80)
{
offset--;
char2 = 0;
}
char3 = offset >= limit ? 0x80 : src[offset++];
if((char3 & 0xc0) != 0x80)
{
offset--;
char3 = 0;
}
result[newlength++] = (char) ((char1 & 0x0f) << 12 | (char2 & 0x3f) << 6 | (char3 & 0x3f));
break;
}
}
if(newlength < result.length) Array.copy(result, 0, result = new char[newlength], 0, newlength);
return result;
}
public byte[] encode(char[] src, int offset, int length) {
int newlength = 0;
byte[] result = new byte[3 * length];
for(int limit = offset + length; offset < limit; )
{
int character = src[offset++];
if(character > 0 && character <= 0x007f)
{
result[newlength++] = (byte) character;
}
else if(character <= 0x07ff)
{
result[newlength++] = (byte) (0xc0 + ((character >> 6) & 0x1f));
result[newlength++] = (byte) (0x80 + (character & 0x3f));
}
else
{
result[newlength++] = (byte) (0xe0 + ((character >> 12) & 0x0f));
result[newlength++] = (byte) (0x80 + ((character >> 6) & 0x3f));
result[newlength++] = (byte) (0x80 + (character & 0x3f));
}
}
if(newlength < result.length) Array.copy(result, 0, result = new byte[newlength], 0, newlength);
return result;
}
}