uCosminexus Service Platform, Basic Development Guide

[Contents][Glossary][Index][Back][Next]

Appendix I.4 CSCOwnCodeReader interface

Organization of this subsection
(1) Interface
(2) Exception class
(3) Implementation example (MS932)
(4) Implementation example(IBM Kanji code)

(1) Interface

Following figure shows CSCOwnCodeReader interface:

Figure I-3 FigureCSCOwnCodeReader interface

[Figure]

Interface name
CSCOwnCodeReader interface

Description
This is the interface for reading the character string of self-defined character code.
Package of CSCOwnCodeReader is jp.co.Hitachi.soft.csc.dt.uoc.CSCOwnCodeReader.
In the binary character string reading process, when you parse the separator without converting the character code, you can relax the restrictions of conversion in which bytes count or character count is changed and improve the conversion performance.
Implementation of this interface is optional. If you do not implement, the separator is parsed by executing the character code conversion.
As the instances of this interface are shared in multiple threads, you must set thread safe at the time of implementation.

Format
 
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
Following table describes the methods of CSCOwnCodeReader interface.
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

[Figure]

  1. Generating an instance
    Generate an instance of CSCOwnCodeReader, by data transformation.
  2. CSCOwnCodeReader#start method
    Generate instance of self-thread dedicated CSCOwnCodeReaderContext. From here onwards, delivery of value with CSCOwnCodeReader is executed through instance of CSCOwnCodeReaderContext saved by the self thread.
  3. CSCOwnCodeReader#readChar method
    When executing readChar, data transformation process passes the instance of CSCOwnCodeReaderContext to the argument. In readChar process, parsing result is set to the instance of CSCOwnCodeReaderContext. The set parsing result is used for parsing the separator in the data transformation process.
  4. getPosition method, getLength method, canSeparate method
    Respective methods are invoked from the data transformation. Execution order of method depends on the message format.
    • getPosition method
      This method returns the current character position.
    • getLength method
      This method returns the current character length.
    • canSeparate method
      This method returns whether to consider the current character as the separator parsing target.
  5. CSCOwnCodeReader#end method
    If the process to release implementation class of CSCOwnCodeReaderContext is required, execute end method.
(a) start method

Description
Starts the reading of character string of self-defined character code.

Format
public CSCOwnCodeReaderContext start( byte[] data, int offset, int length )
 

Parameter
data:
This is reading target data.
offset:
This is reading start position.
length:
This is length from the reading start position.

Exception
CSCOwnCodeConverterException:
Entire data transformation process was aborted, as error occurred during the character code conversion process.

Return value
This is instance of the implementation class of CSCOwnCodeReaderContext. You cannot use this instance in any other thread.
(b) readChar method

Description
Reads 1 character of self-defined character code character.
You can acquire character position and length by CSCOwnCodeReaderContext#getPosition, CSCOwnCodeReaderContext#getLength.

Format
 
public boolean readChar( CSCOwnCodeReaderContext context )
 

Parameter
context:
This is instance of implementation class of CSCOwnCodeReaderContext, which is returned in #start.

Exception
CSCOwnCodeConverterException:
Entire data transformation process was aborted, as error occurred during the character code conversion process.

Return value
When upper limit for reading is exceeded and character cannot be converted, returns false. Otherwise, returns true.
(c) end method

Description
Ends the reading of character string of the self-defined character code.
This method is always called regardless of success or failure (error) in reading process.

Format
 
public void end( CSCOwnCodeReaderContext context )
 

Parameter
context:
This is instance of implementation class of CSCOwnCodeReaderContext, which is returned in #start.

Exception
CSCOwnCodeConverterException:
Entire data transformation process was aborted, as error occurred during the character code conversion process.

Return value
None

(2) Exception class

The exception class that occurs at the time of developing character code conversion UOC is as follows:

Class name
CSCOwnCodeConverterException class

Description
This is the exception, which is sent when error occurs in character code conversion process.
When this exception occurs, entire data transformation process is aborted.

(3) Implementation example (MS932)

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
    }
 
}

(4) Implementation example(IBM Kanji code)

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
    }
 
}