Following figure shows CSCOwnCodeReader interface:
Figure I-3 FigureCSCOwnCodeReader interface
package jp.co.Hitachi.soft.csc.dt.uoc ;
import jp.co.Hitachi.soft.csc.dt.uoc.CSCOwnCodeConverterException ;
public interface CSCOwnCodeReader {
CSCOwnCodeReaderContext start( byte[] data, int offset, int length )
throws CSCOwnCodeConverterException ;
boolean readChar( CSCOwnCodeReaderContext context )
throws CSCOwnCodeConverterException ;
void end( CSCOwnCodeReaderContext context ) ;
}
Method name | Description |
---|---|
start method | This is the method to start the reading of character string of self-defined character code. |
readChar method | This is the method to read 1 character of self-defined character code characters. |
end method | This is the method to end the reading of character string of self-defined character code. |
When data transformation target is variable length character string and separator has been set in the binary format definition, data transformation executes the separator parsing process. Following figure shows the order of invoking each method of CSCOwnCodeReader and CSCOwnCodeReaderContext.
Figure I-4 FigureOrder of invoking each method of CSCOwnCodeReader and CSCOwnCodeReaderContext
public CSCOwnCodeReaderContext start( byte[] data, int offset, int length )
public boolean readChar( CSCOwnCodeReaderContext context )
public void end( CSCOwnCodeReaderContext context )
The exception class that occurs at the time of developing character code conversion UOC is as follows:
Implementation example (MS932) of CSCOwnCodeReader interface is as follows:
public class CSCOwnCodeReaderImpl implements CSCOwnCodeConverter, CSCOwnCodeReader {
private static final String UNICODE = "ISO-10646-UCS-2" ;
private final HJCOption option ;
private static byte[] charSizeTable = initCharSizeTable() ;
private static byte[] initCharSizeTable() {
final byte[] objTable = new byte[0x100] ;
for ( int i = 0; i <= 0xff; i++ ) {
if ( i <= 0x80
|| (i >= 0xA0 && i <= 0xDF)
|| (i >= 0xFD && i <= 0xFF) ) {
objTable[i] = 1 ;
}
else {
objTable[i] = 2 ;
}
}
return objTable ;
}
public CSCOwnCodeReaderImpl() {
option = new HJCOption() ;
try {
// Unicode is Big Endian
option.enableOption( HJCOption.COP_BIGENDIAN ) ;
}
catch ( Exception e ) {
e.printStackTrace() ;
}
}
@Override
public void setProperties( Properties properties )
throws CSCOwnCodeConverterException {
String codetablepath = null ;
if ( properties != null ) {
codetablepath = properties.getProperty( "codetablepath" ) ;
}
try {
if ( codetablepath == null ) {
option
.setTablePath( "C:\\Program Files\\HITACHI\\Cosminexus\\CSC\\lib\\external\\table" ) ;
}
else {
option.setTablePath( codetablepath ) ;
}
}
catch ( Exception e ) {
e.printStackTrace() ;
}
}
@Override
public int available( byte[] inBuffer ) throws CSCOwnCodeConverterException {
if ( inBuffer == null ) {
final String message = "You cannot convert blank character string" ;
throw new CSCOwnCodeConverterException( message ) ;
}
int retInt = -1 ;
final HJCResult result = new HJCResult() ;
final HJCString inStr = new HJCString( inBuffer ) ;
try {
HJCConverters.cs_ms932tounicode( inStr, result, option ) ;
}
catch ( Exception e ) {
e.printStackTrace() ;
throw new CSCOwnCodeConverterException( e ) ;
}
final byte[] resultData = result.getStrResult().getBytes() ;
final int resultState = result.getConvertState() ;
if ( resultState == HJCConvertState.CST_NORMAL ) {
// Conversion ended successfully
if ( resultData != null ) {
retInt = result.getResultLength() ;
}
}
else {
// Conversion ended abnormally
final byte[] bytes = new byte[result.getResultLength() - 1] ;
System.arraycopy(
inBuffer,
0,
bytes,
0,
result.getResultLength() - 1 ) ;
retInt = available( bytes ) ;
}
return retInt ;
}
@Override
public char[] ownCodeToUnicode( byte[] inBuffer )
throws CSCOwnCodeConverterException {
char[] retChar = null ;
final HJCResult result = new HJCResult() ;
final HJCString inStr = new HJCString( inBuffer ) ;
try {
HJCConverters.cs_ms932tounicode( inStr, result, option ) ;
final byte[] resultData = result.getStrResult().getBytes() ;
final String retstr = new String( resultData, UNICODE ) ;
retChar = retstr.toCharArray() ;
}
catch ( Exception e ) {
e.printStackTrace() ;
throw new CSCOwnCodeConverterException( e ) ;
}
return retChar ;
}
@Override
public byte[] unicodeToOwnCode( char[] inBuffer )
throws CSCOwnCodeConverterException {
byte[] retByte = null ;
final String data = new String( inBuffer ) ;
final HJCResult result = new HJCResult() ;
try {
final HJCString inStr = new HJCString( data.getBytes( UNICODE ) ) ;
HJCConverters.cs_unicodetoms932( inStr, result, option ) ;
retByte = result.getStrResult().getBytes() ;
}
catch ( Exception e ) {
e.printStackTrace() ;
throw new CSCOwnCodeConverterException( e ) ;
}
return retByte ;
}
@Override
public CSCOwnCodeReaderContext start( byte[] data, int offset, int length )
throws CSCOwnCodeConverterException {
return new CSCOwnCodeReaderContextImpl( Arrays.copyOfRange(
data,
offset,
length ) ) ;
}
@Override
public boolean readChar( CSCOwnCodeReaderContext context )
throws CSCOwnCodeConverterException {
final CSCOwnCodeReaderContextImpl contextImpl = (CSCOwnCodeReaderContextImpl)context ;
final int offset = contextImpl.getNextPosition() ;
contextImpl.setPosition( offset ) ;
final byte[] data = contextImpl.getData() ;
// Acquire maximum length of input data (not the size of character)
final int maxLength = data.length ;
if ( offset >= maxLength ) {
// Current position is outside the range of input data
return false ;
}
final int len = charSizeTable[data[offset] & 0xff] ;
contextImpl.setLength( len ) ;
final int next = offset + len ;
contextImpl.setNextPosition( next ) ;
if ( next > maxLength ) {
// Conversion result is error
// Occurs when input data is invalid
// Returns false and aborts the parsing
return false ;
}
return true ;
}
@Override
public void end( CSCOwnCodeReaderContext context )
throws CSCOwnCodeConverterException {
// No process is performed as resources to be released do not exist
}
}
Implementation example (IBM Kanji code) of CSCOwnCodeReader interface is as follows:
public class CSCOwnCodeReaderImpl
implements
CSCOwnCodeConverter,
CSCOwnCodeReader {
private static final String UNICODE = "ISO-10646-UCS-2" ;
private static final byte SHIFT_SINGLEBYTE = (byte)0x0f ;
private static final byte SHIFT_MULTIBYTE = (byte)0x0e ;
private final HJCOption option ;
public CSCOwnCodeReaderImpl() {
option = new HJCOption() ;
try {
// Unicode is Big Endian
option.enableOption( HJCOption.COP_BIGENDIAN ) ;
// EBCDIC
option.enableOption( HJCOption.COP_EBCDIC ) ;
}
catch ( Exception e ) {
e.printStackTrace() ;
}
}
@Override
public void setProperties( Properties properties )
throws CSCOwnCodeConverterException {
String codetablepath = null ;
if ( properties != null ) {
codetablepath = properties.getProperty( "codetablepath" ) ;
}
try {
if ( codetablepath == null ) {
option
.setTablePath( "C:\\Program Files\\HITACHI\\Cosminexus\\CSC\\lib\\external\\table" ) ;
}
else {
option.setTablePath( codetablepath ) ;
}
}
catch ( Exception e ) {
e.printStackTrace() ;
}
}
@Override
public int available( byte[] inBuffer ) throws CSCOwnCodeConverterException {
if ( inBuffer == null ) {
final String message = "You cannot convert blank character string." ;
throw new CSCOwnCodeConverterException( message ) ;
}
int retInt = -1 ;
final HJCResult result = new HJCResult() ;
final HJCString inStr = new HJCString( inBuffer ) ;
try {
HJCConverters.cs_ibmtounicode( inStr, result, option ) ;
}
catch ( Exception e ) {
e.printStackTrace() ;
throw new CSCOwnCodeConverterException( e ) ;
}
final byte[] resultData = result.getStrResult().getBytes() ;
final int resultState = result.getConvertState() ;
if ( resultState == HJCConvertState.CST_NORMAL ) {
// Conversion ends successfully
if ( resultData != null ) {
retInt = result.getResultLength() ;
}
}
else {
// Conversion ends abnormally
final byte[] bytes = new byte[result.getResultLength() - 1] ;
System.arraycopy(
inBuffer,
0,
bytes,
0,
result.getResultLength() - 1 ) ;
retInt = available( bytes ) ;
}
return retInt ;
}
@Override
public char[] ownCodeToUnicode( byte[] inBuffer )
throws CSCOwnCodeConverterException {
char[] retChar = null ;
final HJCResult result = new HJCResult() ;
final HJCString inStr = new HJCString( inBuffer ) ;
try {
HJCConverters.cs_ibmtounicode( inStr, result, option ) ;
final byte[] resultData = result.getStrResult().getBytes() ;
final String retstr = new String( resultData, UNICODE ) ;
retChar = retstr.toCharArray() ;
}
catch ( Exception e ) {
e.printStackTrace() ;
throw new CSCOwnCodeConverterException( e ) ;
}
return retChar ;
}
@Override
public byte[] unicodeToOwnCode( char[] inBuffer )
throws CSCOwnCodeConverterException {
byte[] retByte = null ;
final String data = new String( inBuffer ) ;
final HJCResult result = new HJCResult() ;
try {
final HJCString inStr = new HJCString( data.getBytes( UNICODE ) ) ;
HJCConverters.cs_unicodetoibm( inStr, result, option ) ;
retByte = result.getStrResult().getBytes() ;
}
catch ( Exception e ) {
e.printStackTrace() ;
throw new CSCOwnCodeConverterException( e ) ;
}
return retByte ;
}
@Override
public CSCOwnCodeReaderContext start( byte[] data, int offset, int length )
throws CSCOwnCodeConverterException {
final byte[] tempData = Arrays.copyOfRange( data, offset, length ) ;
// Start parsing from position of offset
return new CSCOwnCodeReaderContextImpl( tempData ) ;
}
@Override
public boolean readChar( CSCOwnCodeReaderContext context )
throws CSCOwnCodeConverterException {
final CSCOwnCodeReaderContextImpl contextImpl = (CSCOwnCodeReaderContextImpl)context ;
// Current position
final int position = contextImpl.getNextPosition() ;
// Byte string of parsing target character string
final byte[] data = contextImpl.getData() ;
// Upper limit of parsing is till end of input data
final int maxLength = data.length ;
// Parse 1 by 1 byte from current position
for ( int i = position; i < maxLength; i++ ) {
// Parse the next character
if ( data[i] == SHIFT_SINGLEBYTE ) {
// Transit to single byte mode
contextImpl.setLength( 1 ) ;
contextImpl.setCanSeparate( true ) ;
continue ;
}
else if ( data[i] == SHIFT_MULTIBYTE ) {
// Transit to multi-byte mode
contextImpl.setLength( 2 ) ;
contextImpl.setCanSeparate( false ) ;
continue ;
}
contextImpl.setPosition( i ) ;
contextImpl.setNextPosition( i + contextImpl.getLength() ) ;
if ( contextImpl.getNextPosition() > maxLength ) {
// Data is not sufficient
return false ;
}
// Parsing is successful
return true ;
}
contextImpl.setPosition( maxLength ) ;
contextImpl.setNextPosition( maxLength ) ;
return false ;
}
@Override
public void end( CSCOwnCodeReaderContext context )
throws CSCOwnCodeConverterException {
// Performs nothing as the resources to be parsed do not exist
}
}