themeinstaller/source/src/com/nokia/tools/themeinstaller/odtconverter/ODTDataOutputStream.java
branchRCL_3
changeset 17 fe49e33862e2
parent 16 b685c59de105
child 18 04b7640f6fb5
equal deleted inserted replaced
16:b685c59de105 17:fe49e33862e2
     1 /*
       
     2 * Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Implements ODTDataOutputStream
       
    15  *
       
    16 */
       
    17 
       
    18 
       
    19 package com.nokia.tools.themeinstaller.odtconverter;
       
    20 
       
    21 import java.io.DataOutputStream;
       
    22 import java.io.IOException;
       
    23 import java.io.OutputStream;
       
    24 import java.nio.ByteBuffer;
       
    25 import java.nio.ByteOrder;
       
    26 
       
    27 import com.ibm.icu.text.UnicodeCompressor;
       
    28 
       
    29 /**
       
    30  * Implements ODTDataOutputStream. Helper class for writing strings
       
    31  * and numeric values to stream so that native implementation reads
       
    32  * them properly.
       
    33  *
       
    34  */
       
    35 public class ODTDataOutputStream extends DataOutputStream
       
    36     {
       
    37 
       
    38     public ODTDataOutputStream( OutputStream aStream )
       
    39         {
       
    40         super( aStream );
       
    41         }
       
    42 
       
    43     /**
       
    44      * Write unsigned 32-bit integer.
       
    45      * Using long as Java's Integer value is restricted to
       
    46      * range -2^31 ... 2^31-1
       
    47      * @param aValue the value as long
       
    48      * @throws IOException if writing to a stream fails
       
    49      * @throws ODTException if data conversion fails
       
    50      */
       
    51     public void writeUnsignedInt32( long aValue ) throws IOException, ODTException
       
    52         {
       
    53         // Using range of unsigned integer
       
    54         // Values bigger than 2^32-1 are not allowed
       
    55         if ( aValue < 0 || aValue > 0xFFFFFFFFL )
       
    56             {
       
    57             throw new ODTException(
       
    58                     "ODTDataOutputStream writeUnsignedInt32s failed, value out of range" );
       
    59             }
       
    60 
       
    61         byte[] bArray = new byte[ 4 ];
       
    62         bArray[ 3 ] = ( byte ) ( ( aValue & 0xFF000000L ) >> 24 );
       
    63         bArray[ 2 ] = ( byte ) ( ( aValue & 0x00FF0000L ) >> 16 );
       
    64         bArray[ 1 ] = ( byte ) ( ( aValue & 0x0000FF00L ) >> 8 );
       
    65         bArray[ 0 ] = ( byte ) ( aValue & 0x000000FFL );
       
    66 
       
    67         int len = bArray.length;
       
    68         super.write( bArray, 0, len );
       
    69         }
       
    70 
       
    71     /**
       
    72      * Writes int to stream for native Int32
       
    73      * @param aValue
       
    74      * @throws IOException if writing to a stream fails
       
    75      * @throws ODTException if data conversion fails
       
    76      */
       
    77     public void writeInt32( int aValue ) throws ODTException, IOException
       
    78         {
       
    79         byte[] bArray = new byte[4]; // we want 32 bit integer
       
    80         ByteBuffer buf = ByteBuffer.wrap( bArray );
       
    81         // byte order in native is LITTLE_ENDIAN
       
    82         buf.order( ByteOrder.LITTLE_ENDIAN );
       
    83         buf.putInt( aValue );
       
    84 
       
    85         if( buf.hasArray() )
       
    86             {
       
    87             bArray = buf.array();
       
    88             }
       
    89         else
       
    90             {
       
    91             throw new ODTException( "ODTDataOutputStream writeInt32 failed" );
       
    92             }
       
    93 
       
    94         int len = bArray.length;
       
    95         super.write( bArray, 0, len );
       
    96         }
       
    97 
       
    98     /**
       
    99      * Writes int to stream for native Int16
       
   100      * @param aValue
       
   101      * @throws IOException if writing to a stream fails
       
   102      * @throws ODTException if data conversion fails
       
   103      */
       
   104     public void writeInt16( int aValue ) throws ODTException, IOException
       
   105         {
       
   106         Integer value = new Integer( aValue );
       
   107         byte[] bArray = new byte[2]; // we want 16 bit integer
       
   108         ByteBuffer buf = ByteBuffer.wrap( bArray );
       
   109         // byte order in native is LITTLE_ENDIAN
       
   110         buf.order( ByteOrder.LITTLE_ENDIAN );
       
   111         buf.putShort( value.shortValue() );
       
   112 
       
   113         if( buf.hasArray() )
       
   114             {
       
   115             bArray = buf.array();
       
   116             }
       
   117         else
       
   118             {
       
   119             throw new ODTException( "ODTDataOutputStream writeInt16 failed" );
       
   120             }
       
   121 
       
   122         int len = bArray.length;
       
   123         super.write( bArray, 0, len );
       
   124         }
       
   125 
       
   126     /**
       
   127      * Writes double to stream for native TReal64
       
   128      * @param aValue
       
   129      * @throws ODTException
       
   130      * @throws IOException
       
   131      */
       
   132     public void writeTReal64( double aValue ) throws ODTException, IOException
       
   133         {
       
   134         byte[] bArray = new byte[8]; // we want 64 bit TReal
       
   135         ByteBuffer buf = ByteBuffer.wrap( bArray );
       
   136         buf.order( ByteOrder.LITTLE_ENDIAN );
       
   137         buf.putDouble( aValue );
       
   138 
       
   139         if( buf.hasArray() )
       
   140             {
       
   141             bArray = buf.array();
       
   142             }
       
   143         else
       
   144             {
       
   145             throw new ODTException( "ODTDataOutputStream writeTReal64 failed" );
       
   146             }
       
   147 
       
   148         int len = bArray.length;
       
   149         super.write( bArray, 0, len );
       
   150         }
       
   151 
       
   152     /**
       
   153      * Writes string to stream for native HBufC8
       
   154      *
       
   155      * See Symbian common sources for more information:
       
   156      *
       
   157      * src\common\generic\syslibs\store\USTRM\US_FUNC.CPP
       
   158      * ExternalizeL(const TDesC8& aDes8,RWriteStream& aStream)
       
   159      *
       
   160      * src\common\generic\syslibs\store\INC\U32STD.INL
       
   161      * TDesHeader::TDesHeader(const TDesC8& aDes8)
       
   162      *
       
   163      * @param aS String to write
       
   164      * @throws IOException if writing to a stream fails
       
   165      * @throws ODTException if data conversion fails
       
   166      */
       
   167     public void writeString8( String aS ) throws ODTException, IOException
       
   168         {
       
   169         byte[] ba = aS.getBytes();
       
   170         int len = ba.length;
       
   171 
       
   172         writeCardinality( len, true );
       
   173 
       
   174         super.write( ba, 0, len );
       
   175         }
       
   176 
       
   177     /**
       
   178      * Writes string to stream for native HBufC16.
       
   179      *
       
   180      * See Symbian common sources for more information:
       
   181      *
       
   182      * src\common\generic\syslibs\store\USTRM\US_FUNC.CPP
       
   183      * ExternalizeL(const TDesC16& aDes16,RWriteStream& aStream)
       
   184      *
       
   185      * src\common\generic\syslibs\store\INC\U32STD.INL
       
   186      * TDesHeader::TDesHeader(const TDesC16& aDes16)
       
   187      *
       
   188      * @param aS String to write
       
   189      * @throws IOException if writing to a stream fails
       
   190      * @throws ODTException if data conversion fails
       
   191      */
       
   192     public void writeString16( String aS ) throws ODTException, IOException
       
   193         {
       
   194         // Take length of the String for calculating the cardinality
       
   195         // The cardinality is calculated of the original length of the string
       
   196         // (before compress) because the original length is again valid when
       
   197         // the string is uncompressed in the Symbian side.
       
   198         int clen = aS.length();
       
   199 
       
   200         // Using UnicodeCopressor to compress string. The Unicode Compression
       
   201         // is also used in Unicode builds of Symbian.
       
   202         byte[] ba = UnicodeCompressor.compress( aS );
       
   203         int len = ba.length;
       
   204 
       
   205         writeCardinality( clen, false );
       
   206 
       
   207         super.write( ba, 0, len );
       
   208         }
       
   209 
       
   210     /**
       
   211      * Calculates HBufC8 and HBufC16 string length for native stream.
       
   212      *
       
   213      * See Symbian common sources for more information:
       
   214      *
       
   215      * src\common\generic\syslibs\store\USTRM\US_UTL.CPP
       
   216      * TCardinality::ExternalizeL(RWriteStream& aStream)
       
   217      *
       
   218      * src\common\generic\syslibs\store\INC\U32STD.INL
       
   219      * TDesHeader::TDesHeader(const TDesC16& aDes16)
       
   220      * TDesHeader::TDesHeader(const TDesC8& aDes8)
       
   221      *
       
   222      * @param aLenght string length
       
   223      * @param a8bit set true for 8-bit descriptors, this adds one to the count
       
   224      * @throws IOException if writing to a stream fails
       
   225      * @throws ODTException if data conversion fails
       
   226      */
       
   227     private void writeCardinality( int aLenght, boolean a8bit ) throws IOException, ODTException
       
   228         {
       
   229         int count = aLenght * 2;
       
   230 
       
   231         if( a8bit )
       
   232             {
       
   233             count = count + 1;
       
   234             }
       
   235 
       
   236         if( count <= ( Byte.MAX_VALUE ) )
       
   237             {
       
   238             super.writeByte( count << 1 );
       
   239             }
       
   240         else if( count <= ( 65535 >>> 2 ) )
       
   241             {
       
   242             writeInt16( ( count << 2 ) + 1 );
       
   243             }
       
   244         else
       
   245             {
       
   246             writeInt32( ( count << 3 ) + 3 );
       
   247             }
       
   248         }
       
   249 
       
   250     }