javacommons/utils/src.s60/s60commonutils.cpp
changeset 21 2a9601315dfc
child 34 71c436fe3ce0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javacommons/utils/src.s60/s60commonutils.cpp	Mon May 03 12:27:20 2010 +0300
@@ -0,0 +1,448 @@
+/*
+* Copyright (c) 2008 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:  ?Description
+*
+*/
+
+
+#include <e32def.h>
+#include <e32cmn.h>
+#include <e32std.h>
+
+#include "s60commonutils.h"
+#include "jni.h"
+#include <f32file.h>
+#include <bautils.h>                    // BaflUtils
+#include <driveinfo.h>                  // DriveInfo
+#include <data_caging_path_literals.hrh> // KDC_* constant strings
+
+using namespace java::util;
+
+enum TJavaArrayPanic
+{
+    EBadOffsetIntoJavaArray,
+    EWritingOverEndOfJavaArray,
+    EBadOffsetIntoJavaArrayForRead,
+    EReadingOverEndOfJavaArray,
+};
+
+
+
+/**
+ * Copies the java buffer to native descriptor.
+ * @param aJni The JNI environment.
+ * @param aJavaBuffer The Java buffer to copy data from.
+ * @param aOffset Start of data in Java buffer to copy. This is assumed to be valid.
+ * @param aLength Amount of data to copy. This is assumed to be valid.
+ * @param aNativeBuffer Target for data. This is assumed to be long enough.
+ * @returns An error code.
+ */
+OS_EXPORT TInt S60CommonUtils::CopyToNative(JNIEnv& aJni, jbyteArray aJavaBuffer,
+        TInt aOffset, TInt aLength, TDes8& aNativeBuffer)
+{
+    __ASSERT_DEBUG(aOffset <= aJni.GetArrayLength(aJavaBuffer),
+                   User::Panic(_L("S60CommonUtils"), EBadOffsetIntoJavaArrayForRead));
+    __ASSERT_DEBUG(aLength <= aJni.GetArrayLength(aJavaBuffer) - aOffset,
+                   User::Panic(_L("S60CommonUtils"), EReadingOverEndOfJavaArray));
+
+    aNativeBuffer.SetLength(aLength);
+    TUint8* nativeBufPtr = const_cast<TUint8*>(aNativeBuffer.Ptr());
+    jbyte* jNativeBufPtr = reinterpret_cast<jbyte*>(nativeBufPtr);
+    aJni.GetByteArrayRegion(aJavaBuffer, aOffset, aLength, jNativeBufPtr);
+    return KErrNone;
+}
+
+
+
+/**
+ * Copies data from the native to the Java array.
+ * @return The number of bytes copied.
+ */
+OS_EXPORT TInt S60CommonUtils::CopyToJava(JNIEnv& aJni, const TDesC8& aNativeBuffer,
+        jbyteArray aJavaBuffer, TInt aOffset, TInt aLength)
+{
+    __ASSERT_DEBUG(aOffset <= aJni.GetArrayLength(aJavaBuffer),
+                   User::Panic(_L("S60CommonUtils"), EBadOffsetIntoJavaArray));
+    __ASSERT_DEBUG(aLength <= aJni.GetArrayLength(aJavaBuffer) - aOffset,
+                   User::Panic(_L("S60CommonUtils"), EWritingOverEndOfJavaArray));
+
+    TInt nativeBufLength = aNativeBuffer.Length();
+    TInt length = (nativeBufLength < aLength) ? nativeBufLength : aLength;
+    TUint8* nativeBufPtr = const_cast<TUint8*>(aNativeBuffer.Ptr());
+    jbyte* jNativeBufPtr = reinterpret_cast<jbyte*>(nativeBufPtr);
+    aJni.SetByteArrayRegion(aJavaBuffer, aOffset, length, jNativeBufPtr);
+    return length;
+}
+
+OS_EXPORT jstring S60CommonUtils::NativeToJavaString(JNIEnv& aJni, const TDesC16& aNativeString)
+{
+    const jchar* ptr = aNativeString.Ptr();
+    const jsize len = aNativeString.Length();
+    jstring javaString = aJni.NewString(ptr, len);
+    return javaString;
+}
+
+/**
+ * Creates a Java array of strings from a native array of descriptors allocated
+ * on the heap.
+ * @param aJni The JNI environment.
+ * @param aNativeArray The array of descriptors.
+ * @return The newly created Java array of String objects, or NULL on error.
+ */
+OS_EXPORT jobjectArray S60CommonUtils::NativeToJavaStringArray(JNIEnv& aJni,
+        const RPointerArray<HBufC>& aNativeArray)
+{
+    jclass stringClass = aJni.FindClass("java/lang/String");
+    if (stringClass == NULL)
+    {
+        return NULL;
+    }
+
+    TInt count = aNativeArray.Count();
+    jobjectArray jObjArray = aJni.NewObjectArray(count, stringClass, NULL);
+    if (jObjArray == NULL)
+    {
+        return NULL;
+    }
+
+    for (int i = 0; i< count; i++)
+    {
+        //TPtr16 temp =  aNativeArray[i]->Des();
+        jstring javaString = S60CommonUtils::NativeToJavaString(aJni, *aNativeArray[i]);
+        if (javaString == NULL)
+        {
+            aJni.DeleteLocalRef(jObjArray);
+            return NULL;
+        }
+
+        aJni.SetObjectArrayElement(jObjArray, i, javaString);
+        aJni.DeleteLocalRef(javaString);
+    }
+
+    return jObjArray;
+}
+
+/* Converts wchar_t to descriptor */
+OS_EXPORT HBufC* S60CommonUtils::wstringToDes(const wchar_t* cStr)
+{
+    HBufC* descStr = NULL;
+    int length = wcslen(cStr);
+    if (length > 0)
+    {
+        descStr = HBufC::New(length + 1);
+        if (descStr == NULL)
+        {
+            return descStr;
+        }
+        TPtr ptr = descStr->Des();
+        TPtr ptr16((TUint16*)cStr,length);
+        ptr16.SetLength(length);
+        ptr.Copy(ptr16);
+        ptr.ZeroTerminate();
+    }
+    return descStr;
+}
+
+OS_EXPORT TTime S60CommonUtils::JavaTimeToTTime(jlong aJavaTime)
+{
+    // Convert jlong to a TInt64
+    TInt64 milliSeconds = *reinterpret_cast<TInt64*>(&aJavaTime);
+    // Create a TTime object that represents the Java Date 'epoch' time of 00:00, 1 Jan 1970
+    TInt64 javaEpocTimeNum = MAKE_TINT64(JavaUpperEpocTime, JavaLowerEpocTime);
+    TTime time(javaEpocTimeNum);
+    TTimeIntervalMicroSeconds timeInterval(milliSeconds * 1000);
+    return time + timeInterval;
+}
+
+OS_EXPORT jlong S60CommonUtils::TTimeToJavaTime(TTime aEpocTime)
+{
+    // Create a TTime object that represents the Java Date 'epoch' time of 00:00, 1 Jan 1970
+    TInt64 javaEpocTimeNum = MAKE_TINT64(JavaUpperEpocTime, JavaLowerEpocTime);
+    TTime javaEpochTime(javaEpocTimeNum);
+    // Find difference in microseconds between 'epoch' and EPOC date and adjust to milliseconds
+    TTimeIntervalMicroSeconds microInterval = aEpocTime.MicroSecondsFrom(javaEpochTime);
+    TInt64 timeInterval = microInterval.Int64();
+    timeInterval = timeInterval/1000;
+    jlong javaTimeInterval = *reinterpret_cast<jlong*>(&timeInterval);
+    return javaTimeInterval;
+}
+
+
+//------------------------------------------------------------------------------
+// public static ConvertWiderToNarrowL(const TDesC& aSource,TDesC8& aDestination)
+//
+//------------------------------------------------------------------------------
+OS_EXPORT TInt S60CommonUtils::ConvertWiderToNarrowLC(const TDesC& aSource,
+        TDesC8*& aDestination)
+{
+    TBool value = (!&aSource) || (aSource.Length() < 1);
+    if (value)
+    {
+        // we are poping in NON CleanupStack version.
+        CleanupStack::PushL(aDestination);
+        return 0;
+    }
+
+    HBufC8* buffer = HBufC8::NewLC(aSource.Length());
+    TPtr8 ptr = buffer->Des();
+    ptr.Copy(aSource);
+    aDestination = buffer;
+
+    return aDestination->Length();
+}
+//------------------------------------------------------------------------------
+// public static ConvertWiderToNarrowL(const TDesC& aSource,TDesC8& aDestination)
+// DO NOT LEAVE IT ON THE CLEANUP STACK
+//------------------------------------------------------------------------------
+OS_EXPORT TInt S60CommonUtils::ConvertWiderToNarrowL(const TDesC& aSource,
+        TDesC8*& aDestination)
+{
+    ConvertWiderToNarrowLC(aSource, aDestination);
+    CleanupStack::Pop(aDestination); //aDestination
+
+    if (aDestination)
+        return aDestination->Length();
+    else
+        return 0;
+}
+//------------------------------------------------------------------------------
+// public static ConvertNarrowToWiderL(const TDesC& aSource,TDesC8& aDestination)
+// Leave the TDesC on cleanup stack
+//------------------------------------------------------------------------------
+OS_EXPORT TInt S60CommonUtils::ConvertNarrowToWiderLC(const TDesC8& aSource,
+        TDesC*& aDestination)
+{
+    TBool value = (!&aSource) || (aSource.Length() < 1);
+    if (value)
+    {
+        // we are poping in NON CleanupStack version.
+        CleanupStack::PushL(aDestination);
+        return 0;
+    }
+    HBufC16* buffer = HBufC16::NewLC(aSource.Length());
+    TPtr16 ptr = buffer->Des();
+    ptr.Copy(aSource);
+    aDestination = buffer;
+
+    return aDestination->Length();
+}
+//------------------------------------------------------------------------------
+// public static ConvertNarrowToWiderL(const TDesC& aSource,TDesC8& aDestination)
+// DO NOT LEAVE IT ON THE CLEANUP STACK
+//------------------------------------------------------------------------------
+OS_EXPORT TInt S60CommonUtils::ConvertNarrowToWiderL(const TDesC8& aSource,
+        TDesC*& aDestination)
+{
+    ConvertNarrowToWiderLC(aSource, aDestination);
+    CleanupStack::Pop(aDestination); //aDestination
+
+    if (aDestination)
+        return aDestination->Length();
+    else
+        return 0;
+}
+//------------------------------------------------------------------------------
+// public static ConvertNarrowToWiderL(const TDesC& aSource,TDesC8& aDestination)
+// Leave the TDesC on cleanup stack
+//------------------------------------------------------------------------------
+OS_EXPORT TInt S60CommonUtils::CopyNarrowLC(const TDesC8& aSource,
+        TDesC8*& aDestination)
+{
+    TBool value = (!&aSource) || (aSource.Length() < 1);
+    if (value)
+    {
+        // we are poping in NON CleanupStack version.
+        CleanupStack::PushL(aDestination);
+        return 0;
+    }
+    HBufC8* buffer = HBufC8::NewLC(aSource.Length());
+    TPtr8 ptr = buffer->Des();
+    ptr.Copy(aSource);
+    aDestination = buffer;
+
+    return aDestination->Length();
+}
+//-------------------------------------------------------------------------------
+// public static ConvertNarrowToWiderL(const TDesC& aSource,TDesC8& aDestination)
+// DO NOT LEAVE IT ON THE CLEANUP STACK
+//-------------------------------------------------------------------------------
+OS_EXPORT TInt S60CommonUtils::CopyNarrowL(const TDesC8& aSource,
+        TDesC8*& aDestination)
+{
+    CopyNarrowLC(aSource, aDestination);
+    CleanupStack::Pop(aDestination); //aDestination
+    if (aDestination)
+        return aDestination->Length();
+    else
+        return 0;
+}
+//------------------------------------------------------------------------------
+// public static ConvertNarrowToWiderL(const TDesC& aSource,TDesC8& aDestination)
+// Leave the TDesC on cleanup stack
+//------------------------------------------------------------------------------
+OS_EXPORT TInt S60CommonUtils::CopyWiderLC(const TDesC16& aSource,
+        TDesC16*& aDestination)
+{
+    TBool value = (!&aSource) || (aSource.Length() < 1);
+    if (value)
+    {
+        // we are poping in NON CleanupStack version.
+        CleanupStack::PushL(aDestination);
+        return 0;
+    }
+    HBufC16* buffer = HBufC16::NewLC(aSource.Length());
+    TPtr16 ptr = buffer->Des();
+    ptr.Copy(aSource);
+    aDestination = buffer;
+
+    return aDestination->Length();
+}
+//------------------------------------------------------------------------------
+// public static ConvertNarrowToWiderL(const TDesC& aSource,TDesC8& aDestination)
+// DO NOT LEAVE IT ON THE CLEANUP STACK
+//------------------------------------------------------------------------------
+OS_EXPORT TInt S60CommonUtils::CopyWiderL(const TDesC16& aSource,
+        TDesC16*& aDestination)
+{
+    CopyWiderLC(aSource, aDestination);
+    CleanupStack::Pop(aDestination); //aDestination
+    if (aDestination)
+        return aDestination->Length();
+    else
+        return 0;
+}
+
+OS_EXPORT TFileName S60CommonUtils::ResourceLanguageFileNameL(const TDesC& aResourceFileName)
+{
+    // get the name of the running process
+    TFileName* dllFileName = new(ELeave) TFileName;
+    CleanupStack::PushL(dllFileName);
+    Dll::FileName(*dllFileName);
+
+    // create the full path without drive letter
+    TFileName* tmp = new(ELeave) TFileName;
+    CleanupStack::PushL(tmp);
+    tmp->Append(KDC_RESOURCE_FILES_DIR);
+    tmp->Append(_L("java\\"));
+    tmp->Append(aResourceFileName);
+
+    // add the drive letter of the DLL's file name
+    TParse p;
+    p.Set(*tmp, dllFileName, NULL);
+    CleanupStack::PopAndDestroy(tmp);
+    CleanupStack::PopAndDestroy(dllFileName);
+
+    // check if the resource exists
+    TFileName resourceFullName = p.FullName();
+    RFs fs;
+    User::LeaveIfError(fs.Connect());
+    CleanupClosePushL(fs);
+    BaflUtils::NearestLanguageFile(fs, resourceFullName);
+    if (!BaflUtils::FileExists(fs, resourceFullName))
+    {
+        // try the ROM drive
+        TChar romDriveLetter;
+        User::LeaveIfError(DriveInfo::GetDefaultDrive(DriveInfo::EDefaultRom, romDriveLetter));
+        // replace resourceFullName's drive letter with romDriveLetter
+        resourceFullName[0] = romDriveLetter;
+        BaflUtils::NearestLanguageFile(fs, resourceFullName);
+    }
+    CleanupStack::PopAndDestroy(&fs);
+
+    // return
+    return resourceFullName;
+}
+
+
+OS_EXPORT TFileName S60CommonUtils::VerifiedFileNameL(const TDesC& aFileName)
+{
+    _LIT(KColonChar, ":");
+
+    RFs fs;
+    User::LeaveIfError(fs.Connect());
+    CleanupClosePushL(fs);
+
+    // Does the file name specify drive ?
+    // If the second char is ':' assume that the first one is drive
+    TBool fileNameContainsDrive(EFalse);
+    TChar originalDriveLetter(0);
+    TUint attr(0);
+    TInt  err(KErrNone);
+    TFileName fullName = aFileName;
+    if (aFileName.Find(KColonChar) == 1)
+    {
+        fileNameContainsDrive = ETrue;
+        // Is the file in current drive?
+        err = fs.Att(aFileName, attr);
+        if (KErrNone == err)
+        {
+            CleanupStack::PopAndDestroy(&fs);
+            return fullName;
+        }
+
+        // Must search from other drives. Remember the current drive;
+        originalDriveLetter = aFileName[0];
+        originalDriveLetter.UpperCase();
+    }
+
+    // First check system drive
+    TChar driveLetter;
+    User::LeaveIfError(DriveInfo::GetDefaultDrive(DriveInfo::EDefaultSystem, driveLetter));
+    // Check system drive if it has not yet been checked
+    if (originalDriveLetter != driveLetter)
+    {
+        if (fileNameContainsDrive)
+        {
+            fullName[0] = driveLetter;
+        }
+        else
+        {
+            fullName.Zero();
+            fullName.Append(driveLetter);
+            fullName.Append(KColonChar);
+            fullName.Append(aFileName);
+        }
+
+        err = fs.Att(fullName, attr);
+        if (KErrNone == err)
+        {
+            CleanupStack::PopAndDestroy(&fs);
+            return fullName;
+        }
+    }
+
+    // Next try to find file from ROM if the ROM drive has not yet been checked
+    User::LeaveIfError(DriveInfo::GetDefaultDrive(DriveInfo::EDefaultRom, driveLetter));
+    if (originalDriveLetter != driveLetter)
+    {
+        if (fileNameContainsDrive)
+        {
+            fullName[0] = driveLetter;
+        }
+        else
+        {
+            fullName.Zero();
+            fullName.Append(driveLetter);
+            fullName.Append(KColonChar);
+            fullName.Append(aFileName);
+        }
+
+        err = fs.Att(fullName, attr);
+    }
+    User::LeaveIfError(err);
+
+    CleanupStack::PopAndDestroy(&fs);
+    return fullName;
+}
+