src.com.ibm.as400.access.ConvTable1208 Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jt400 Show documentation
Show all versions of jt400 Show documentation
The Open Source version of the IBM Toolbox for Java
///////////////////////////////////////////////////////////////////////////////
//
// JTOpen (IBM Toolbox for Java - OSS version)
//
// Filename: ConvTable1208.java
//
// The source code contained herein is licensed under the IBM Public License
// Version 1.0, which has been approved by the Open Source Initiative.
// Copyright (C) 1997-2004 International Business Machines Corporation and
// others. All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////
package com.ibm.as400.access;
import java.io.CharConversionException;
class ConvTable1208 extends ConvTable
{
private static final String copyright = "Copyright (C) 1997-2004 International Business Machines Corporation and others.";
ConvTable1208()
{
super(1208);
}
// Perform an OS/400 CCSID to Unicode conversion.
final String byteArrayToString(byte[] buf, int offset, int length, BidiConversionProperties properties)
{
if (Trace.traceConversion_) Trace.log(Trace.CONVERSION, "Converting byte array to string for ccsid: " + ccsid_, buf, offset, length);
char[] out = new char[length];
int outCount = 0;
for (int i=offset; i 0x00FFFF) // Surrogate pair.
{
out[outCount++] = (char)((c - 0x10000) / 0x400 + 0xD800);
out[outCount++] = (char)((c - 0x10000) % 0x400 + 0xDC00);
}
else
{
out[outCount++] = (char)c;
}
}
if (Trace.traceConversion_) Trace.log(Trace.CONVERSION, "Destination string for ccsid: " + ccsid_, ConvTable.dumpCharArray(out));
return String.copyValueOf(out, 0, outCount);
}
// Perform a Unicode to OS/400 CCSID conversion.
final byte[] stringToByteArray(String source, BidiConversionProperties properties)
{
if (Trace.traceConversion_) Trace.log(Trace.CONVERSION, "Converting string to byte array for ccsid: " + ccsid_, ConvTable.dumpCharArray(source.toCharArray(), 0, source.length()));
int len = source.length();
byte[] buf = new byte[len * 4];
int bufCount = 0;
for (int i = 0; i < len; ++i)
{
int c = source.charAt(i) & 0x00FFFF;
if (c > 0xD7FF && c < 0xDC00)
{
if (++i < len)
{
c = (c - 0xD800) * 0x400 + ((source.charAt(i) & 0x00FFFF) - 0xDC00) + 0x10000;
}
else if (!CharConverter.isFaultTolerantConversion())
{
throw new ArrayIndexOutOfBoundsException();
}
else
{
// We're fault tolerant, ignore the high surrogate and just return.
byte[] ret = new byte[bufCount];
System.arraycopy(buf, 0, ret, 0, bufCount);
if (Trace.traceConversion_) Trace.log(Trace.CONVERSION, "Fault-tolerant in mid-surrogate. Destination byte array for ccsid: " + ccsid_, ret);
return ret;
}
}
if (c < 0x80)
{
buf[bufCount++] = (byte)c;
}
else if (c < 0x800)
{
buf[bufCount++] = (byte)(0xC0 | (c >> 6));
buf[bufCount++] = (byte)(0x80 | (c & 0x3F));
}
else if (c < 0x10000)
{
buf[bufCount++] = (byte)(0xE0 | (c >> 12));
buf[bufCount++] = (byte)(0x80 | ((c >> 6) & 0x3F));
buf[bufCount++] = (byte)(0x80 | (c & 0x3F));
}
else
{
buf[bufCount++] = (byte)(0xF0 | (c >> 18));
buf[bufCount++] = (byte)(0x80 | ((c >> 12) & 0x3F));
buf[bufCount++] = (byte)(0x80 | ((c >> 6) & 0x3F));
buf[bufCount++] = (byte)(0x80 | (c & 0x3F));
}
}
byte[] ret = new byte[bufCount];
System.arraycopy(buf, 0, ret, 0, bufCount);
if (Trace.traceConversion_) Trace.log(Trace.CONVERSION, "Destination byte array for ccsid: " + ccsid_, ret);
return ret;
}
public final byte[] stringToByteArray(char[] src, int offset, int length)
{
if (Trace.traceConversion_) Trace.log(Trace.CONVERSION, "Converting string to byte array for ccsid: " + ccsid_, ConvTable.dumpCharArray(src, offset, length));
byte[] buf = new byte[src.length * 4];
int bufCount = 0;
int len = offset + length;
for (int i = offset; i < len; ++i)
{
int c = src[i] & 0x00FFFF;
if (c > 0xD7FF && c < 0xDC00)
{
if (++i < len)
{
c = (c - 0xD800) * 0x400 + ((src[i] & 0x00FFFF) - 0xDC00) + 0x10000;
}
else if (!CharConverter.isFaultTolerantConversion())
{
throw new ArrayIndexOutOfBoundsException();
}
else
{
// We're fault tolerant, ignore the high surrogate and just return.
byte[] ret = new byte[bufCount];
System.arraycopy(buf, 0, ret, 0, bufCount);
if (Trace.traceConversion_) Trace.log(Trace.CONVERSION, "Fault-tolerant in mid-surrogate. Destination byte array for ccsid: " + ccsid_, ret);
return ret;
}
}
if (c < 0x80)
{
buf[bufCount++] = (byte)c;
}
else if (c < 0x800)
{
buf[bufCount++] = (byte)(0xC0 | (c >> 6));
buf[bufCount++] = (byte)(0x80 | (c & 0x3F));
}
else if (c < 0x10000)
{
buf[bufCount++] = (byte)(0xE0 | (c >> 12));
buf[bufCount++] = (byte)(0x80 | ((c >> 6) & 0x3F));
buf[bufCount++] = (byte)(0x80 | (c & 0x3F));
}
else
{
buf[bufCount++] = (byte)(0xF0 | (c >> 18));
buf[bufCount++] = (byte)(0x80 | ((c >> 12) & 0x3F));
buf[bufCount++] = (byte)(0x80 | ((c >> 6) & 0x3F));
buf[bufCount++] = (byte)(0x80 | (c & 0x3F));
}
}
byte[] ret = new byte[bufCount];
System.arraycopy(buf, 0, ret, 0, bufCount);
if (Trace.traceConversion_) Trace.log(Trace.CONVERSION, "Destination byte array for ccsid: " + ccsid_, ret);
return ret;
}
public final void stringToByteArray(String source, byte[] buf, int offset) throws CharConversionException
{
int bufCount = offset;
if (Trace.traceConversion_) Trace.log(Trace.CONVERSION, "Converting string to byte array for ccsid: " + ccsid_, ConvTable.dumpCharArray(source.toCharArray()));
try
{
int len = source.length();
for (int i = 0; i < len; ++i)
{
int c = source.charAt(i) & 0x00FFFF;
if (c > 0xD7FF && c < 0xDC00)
{
if (++i < len)
{
c = (c - 0xD800) * 0x400 + ((source.charAt(i) & 0x00FFFF) - 0xDC00) + 0x10000;
}
else if (!CharConverter.isFaultTolerantConversion())
{
throw new CharConversionException();
}
else
{
// We're fault tolerant, ignore the high surrogate and just return.
if (Trace.traceConversion_) Trace.log(Trace.CONVERSION, "Fault-tolerant in mid-surrogate. Destination byte array for ccsid: " + ccsid_, buf, offset, bufCount - offset);
return;
}
}
if (c < 0x80)
{
buf[bufCount++] = (byte)c;
}
else if (c < 0x800)
{
buf[bufCount++] = (byte)(0xC0 | (c >> 6));
buf[bufCount++] = (byte)(0x80 | (c & 0x3F));
}
else if (c < 0x10000)
{
buf[bufCount++] = (byte)(0xE0 | (c >> 12));
buf[bufCount++] = (byte)(0x80 | ((c >> 6) & 0x3F));
buf[bufCount++] = (byte)(0x80 | (c & 0x3F));
}
else
{
buf[bufCount++] = (byte)(0xF0 | (c >> 18));
buf[bufCount++] = (byte)(0x80 | ((c >> 12) & 0x3F));
buf[bufCount++] = (byte)(0x80 | ((c >> 6) & 0x3F));
buf[bufCount++] = (byte)(0x80 | (c & 0x3F));
}
}
}
catch (ArrayIndexOutOfBoundsException aioobe)
{
throw new CharConversionException();
}
if (Trace.traceConversion_) Trace.log(Trace.CONVERSION, "Destination byte array for ccsid: " + ccsid_, buf, offset, bufCount - offset);
}
public final void stringToByteArray(String source, byte[] buf, int offset, int length) throws CharConversionException {
stringToByteArrayTruncation(source, buf, offset, length);
}
/* detected truncation @H2C*/
final int stringToByteArrayTruncation(String source, byte[] buf, int offset, int length) throws CharConversionException
{
int truncated = 0; /*@H2A*/
if (Trace.traceConversion_) Trace.log(Trace.CONVERSION, "Converting string to byte array for ccsid: " + ccsid_, ConvTable.dumpCharArray(source.toCharArray()));
try
{
int len = source.length();
int bufCount = offset;
int max = offset+length;
for (int i = 0; i < len ; ++i) /*@H2C*/
{
int c = source.charAt(i) & 0x00FFFF;
if (c > 0xD7FF && c < 0xDC00)
{
if (++i < len)
{
c = (c - 0xD800) * 0x400 + ((source.charAt(i) & 0x00FFFF) - 0xDC00) + 0x10000;
}
else if (!CharConverter.isFaultTolerantConversion())
{
throw new CharConversionException();
}
else
{
// We're fault tolerant, ignore the high surrogate and just return.
if (Trace.traceConversion_) Trace.log(Trace.CONVERSION, "Fault-tolerant in mid-surrogate. Destination byte array for ccsid: " + ccsid_, buf, offset, length);
return truncated ; /*@H2A*/
}
}
if (c < 0x80)
{
if (bufCount < max) { /*@H2A*/
buf[bufCount++] = (byte)c;
} else {
// Don't report the truncation of spaces @H7A
if (c == ' ') {
// No need to count truncation
} else {
truncated ++;
}
}
}
else if (c < 0x800)
{
if (bufCount < max) { /*@H2A*/
buf[bufCount++] = (byte)(0xC0 | (c >> 6));
} else {
truncated ++;
}
if (bufCount < max) {
buf[bufCount++] = (byte)(0x80 | (c & 0x3F));
} else {
truncated ++; /*@H2A*/
}
}
else if (c < 0x10000)
{
if (bufCount < max) {
buf[bufCount++] = (byte) (0xE0 | (c >> 12));
} else {
truncated++; /*@H2A*/
}
if (bufCount < max) {
buf[bufCount++] = (byte) (0x80 | ((c >> 6) & 0x3F));
} else {
truncated++; /*@H2A*/
}
if (bufCount < max) {
buf[bufCount++] = (byte) (0x80 | (c & 0x3F));
} else {
truncated++; /*@H2A*/
}
}
else
{
if (bufCount < max) {
buf[bufCount++] = (byte)(0xF0 | (c >> 18));
} else {
truncated++; /*@H2A*/
}
if (bufCount < max) { buf[bufCount++] = (byte)(0x80 | ((c >> 12) & 0x3F));
} else {
truncated++; /*@H2A*/
}
if (bufCount < max) { buf[bufCount++] = (byte)(0x80 | ((c >> 6) & 0x3F));
} else {
truncated++; /*@H2A*/
}
if (bufCount < max) { buf[bufCount++] = (byte)(0x80 | (c & 0x3F));
} else {
truncated++; /*@H2A*/
}
}
}
}
catch (ArrayIndexOutOfBoundsException aioobe)
{
throw new CharConversionException();
}
if (Trace.traceConversion_) Trace.log(Trace.CONVERSION, "Destination byte array for ccsid: " + ccsid_, buf, offset, length);
return truncated; /*@H2A*/
}
/**
* Place the string into the specified buffer, beginning at offset for length.
* This returns the number of bytes that did not fit (i.e. number of bytes truncated).
* @param source String to convert
* @param buf output buffer
* @param offset offset in buffer to put information
* @param length maximum number of bytes to add to the buffer
* @param properties BidiConversionProperties
* @return number of bytes that were truncated
* @throws CharConversionException
*/
public final int stringToByteArray(String source, byte[] buf, int offset, int length, BidiConversionProperties properties) throws CharConversionException
{
// Don't have a Bidi string type for UTF-8.
return stringToByteArrayTruncation(source, buf, offset, length); /*@H2C*/
}
// Scan the data. If valid return length, otherwise fixup and return the changed length,
// padding with spaces as needed.
// @X4A
public int validateData( byte[] buf, int offset, int length) {
int endOffset = offset+length;
int previousCharOffset = offset;
int nextCharOffset = offset;
while (nextCharOffset < endOffset) {
previousCharOffset = nextCharOffset;
int b = 0xFF & buf[nextCharOffset];
if (b < 0x80) {
nextCharOffset++;
} else if( b >= 0xC0 && b < 0xE0) { // For two bytes, the first byte is 110xxxxx
nextCharOffset += 2;
} else if (b >= 0xE0 && b < 0xF0 ) { // For three bytes, the first byte is1110xxxx
nextCharOffset += 3;
} else {
nextCharOffset += 4;
}
}
if (nextCharOffset > endOffset) {
// The previous character is incomplete
length = previousCharOffset - offset;
for (int i = previousCharOffset; i < endOffset; i++) {
buf[i] = ' ';
}
}
return length;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy