diff -r e8e63152f320 -r 2a9601315dfc javacommons/utils/src.s60/s60commonutils.cpp --- /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 +#include +#include + +#include "s60commonutils.h" +#include "jni.h" +#include +#include // BaflUtils +#include // DriveInfo +#include // 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(aNativeBuffer.Ptr()); + jbyte* jNativeBufPtr = reinterpret_cast(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(aNativeBuffer.Ptr()); + jbyte* jNativeBufPtr = reinterpret_cast(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& 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(&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(&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; +} +