themeinstaller/source/src/com/nokia/tools/themeinstaller/odtconverter/ODTDataOutputStream.java
branchRCL_3
changeset 18 04b7640f6fb5
parent 0 05da4621cfb2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/themeinstaller/source/src/com/nokia/tools/themeinstaller/odtconverter/ODTDataOutputStream.java	Wed Sep 01 12:32:13 2010 +0100
@@ -0,0 +1,250 @@
+/*
+* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Implements ODTDataOutputStream
+ *
+*/
+
+
+package com.nokia.tools.themeinstaller.odtconverter;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+import com.ibm.icu.text.UnicodeCompressor;
+
+/**
+ * Implements ODTDataOutputStream. Helper class for writing strings
+ * and numeric values to stream so that native implementation reads
+ * them properly.
+ *
+ */
+public class ODTDataOutputStream extends DataOutputStream
+    {
+
+    public ODTDataOutputStream( OutputStream aStream )
+        {
+        super( aStream );
+        }
+
+    /**
+     * Write unsigned 32-bit integer.
+     * Using long as Java's Integer value is restricted to
+     * range -2^31 ... 2^31-1
+     * @param aValue the value as long
+     * @throws IOException if writing to a stream fails
+     * @throws ODTException if data conversion fails
+     */
+    public void writeUnsignedInt32( long aValue ) throws IOException, ODTException
+        {
+        // Using range of unsigned integer
+        // Values bigger than 2^32-1 are not allowed
+        if ( aValue < 0 || aValue > 0xFFFFFFFFL )
+            {
+            throw new ODTException(
+                    "ODTDataOutputStream writeUnsignedInt32s failed, value out of range" );
+            }
+
+        byte[] bArray = new byte[ 4 ];
+        bArray[ 3 ] = ( byte ) ( ( aValue & 0xFF000000L ) >> 24 );
+        bArray[ 2 ] = ( byte ) ( ( aValue & 0x00FF0000L ) >> 16 );
+        bArray[ 1 ] = ( byte ) ( ( aValue & 0x0000FF00L ) >> 8 );
+        bArray[ 0 ] = ( byte ) ( aValue & 0x000000FFL );
+
+        int len = bArray.length;
+        super.write( bArray, 0, len );
+        }
+
+    /**
+     * Writes int to stream for native Int32
+     * @param aValue
+     * @throws IOException if writing to a stream fails
+     * @throws ODTException if data conversion fails
+     */
+    public void writeInt32( int aValue ) throws ODTException, IOException
+        {
+        byte[] bArray = new byte[4]; // we want 32 bit integer
+        ByteBuffer buf = ByteBuffer.wrap( bArray );
+        // byte order in native is LITTLE_ENDIAN
+        buf.order( ByteOrder.LITTLE_ENDIAN );
+        buf.putInt( aValue );
+
+        if( buf.hasArray() )
+            {
+            bArray = buf.array();
+            }
+        else
+            {
+            throw new ODTException( "ODTDataOutputStream writeInt32 failed" );
+            }
+
+        int len = bArray.length;
+        super.write( bArray, 0, len );
+        }
+
+    /**
+     * Writes int to stream for native Int16
+     * @param aValue
+     * @throws IOException if writing to a stream fails
+     * @throws ODTException if data conversion fails
+     */
+    public void writeInt16( int aValue ) throws ODTException, IOException
+        {
+        Integer value = new Integer( aValue );
+        byte[] bArray = new byte[2]; // we want 16 bit integer
+        ByteBuffer buf = ByteBuffer.wrap( bArray );
+        // byte order in native is LITTLE_ENDIAN
+        buf.order( ByteOrder.LITTLE_ENDIAN );
+        buf.putShort( value.shortValue() );
+
+        if( buf.hasArray() )
+            {
+            bArray = buf.array();
+            }
+        else
+            {
+            throw new ODTException( "ODTDataOutputStream writeInt16 failed" );
+            }
+
+        int len = bArray.length;
+        super.write( bArray, 0, len );
+        }
+
+    /**
+     * Writes double to stream for native TReal64
+     * @param aValue
+     * @throws ODTException
+     * @throws IOException
+     */
+    public void writeTReal64( double aValue ) throws ODTException, IOException
+        {
+        byte[] bArray = new byte[8]; // we want 64 bit TReal
+        ByteBuffer buf = ByteBuffer.wrap( bArray );
+        buf.order( ByteOrder.LITTLE_ENDIAN );
+        buf.putDouble( aValue );
+
+        if( buf.hasArray() )
+            {
+            bArray = buf.array();
+            }
+        else
+            {
+            throw new ODTException( "ODTDataOutputStream writeTReal64 failed" );
+            }
+
+        int len = bArray.length;
+        super.write( bArray, 0, len );
+        }
+
+    /**
+     * Writes string to stream for native HBufC8
+     *
+     * See Symbian common sources for more information:
+     *
+     * src\common\generic\syslibs\store\USTRM\US_FUNC.CPP
+     * ExternalizeL(const TDesC8& aDes8,RWriteStream& aStream)
+     *
+     * src\common\generic\syslibs\store\INC\U32STD.INL
+     * TDesHeader::TDesHeader(const TDesC8& aDes8)
+     *
+     * @param aS String to write
+     * @throws IOException if writing to a stream fails
+     * @throws ODTException if data conversion fails
+     */
+    public void writeString8( String aS ) throws ODTException, IOException
+        {
+        byte[] ba = aS.getBytes();
+        int len = ba.length;
+
+        writeCardinality( len, true );
+
+        super.write( ba, 0, len );
+        }
+
+    /**
+     * Writes string to stream for native HBufC16.
+     *
+     * See Symbian common sources for more information:
+     *
+     * src\common\generic\syslibs\store\USTRM\US_FUNC.CPP
+     * ExternalizeL(const TDesC16& aDes16,RWriteStream& aStream)
+     *
+     * src\common\generic\syslibs\store\INC\U32STD.INL
+     * TDesHeader::TDesHeader(const TDesC16& aDes16)
+     *
+     * @param aS String to write
+     * @throws IOException if writing to a stream fails
+     * @throws ODTException if data conversion fails
+     */
+    public void writeString16( String aS ) throws ODTException, IOException
+        {
+        // Take length of the String for calculating the cardinality
+        // The cardinality is calculated of the original length of the string
+        // (before compress) because the original length is again valid when
+        // the string is uncompressed in the Symbian side.
+        int clen = aS.length();
+
+        // Using UnicodeCopressor to compress string. The Unicode Compression
+        // is also used in Unicode builds of Symbian.
+        byte[] ba = UnicodeCompressor.compress( aS );
+        int len = ba.length;
+
+        writeCardinality( clen, false );
+
+        super.write( ba, 0, len );
+        }
+
+    /**
+     * Calculates HBufC8 and HBufC16 string length for native stream.
+     *
+     * See Symbian common sources for more information:
+     *
+     * src\common\generic\syslibs\store\USTRM\US_UTL.CPP
+     * TCardinality::ExternalizeL(RWriteStream& aStream)
+     *
+     * src\common\generic\syslibs\store\INC\U32STD.INL
+     * TDesHeader::TDesHeader(const TDesC16& aDes16)
+     * TDesHeader::TDesHeader(const TDesC8& aDes8)
+     *
+     * @param aLenght string length
+     * @param a8bit set true for 8-bit descriptors, this adds one to the count
+     * @throws IOException if writing to a stream fails
+     * @throws ODTException if data conversion fails
+     */
+    private void writeCardinality( int aLenght, boolean a8bit ) throws IOException, ODTException
+        {
+        int count = aLenght * 2;
+
+        if( a8bit )
+            {
+            count = count + 1;
+            }
+
+        if( count <= ( Byte.MAX_VALUE ) )
+            {
+            super.writeByte( count << 1 );
+            }
+        else if( count <= ( 65535 >>> 2 ) )
+            {
+            writeInt16( ( count << 2 ) + 1 );
+            }
+        else
+            {
+            writeInt32( ( count << 3 ) + 3 );
+            }
+        }
+
+    }