javacommons/utils/src.s60/s60commonutils.cpp
changeset 21 2a9601315dfc
child 34 71c436fe3ce0
equal deleted inserted replaced
18:e8e63152f320 21:2a9601315dfc
       
     1 /*
       
     2 * Copyright (c) 2008 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:  ?Description
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <e32def.h>
       
    20 #include <e32cmn.h>
       
    21 #include <e32std.h>
       
    22 
       
    23 #include "s60commonutils.h"
       
    24 #include "jni.h"
       
    25 #include <f32file.h>
       
    26 #include <bautils.h>                    // BaflUtils
       
    27 #include <driveinfo.h>                  // DriveInfo
       
    28 #include <data_caging_path_literals.hrh> // KDC_* constant strings
       
    29 
       
    30 using namespace java::util;
       
    31 
       
    32 enum TJavaArrayPanic
       
    33 {
       
    34     EBadOffsetIntoJavaArray,
       
    35     EWritingOverEndOfJavaArray,
       
    36     EBadOffsetIntoJavaArrayForRead,
       
    37     EReadingOverEndOfJavaArray,
       
    38 };
       
    39 
       
    40 
       
    41 
       
    42 /**
       
    43  * Copies the java buffer to native descriptor.
       
    44  * @param aJni The JNI environment.
       
    45  * @param aJavaBuffer The Java buffer to copy data from.
       
    46  * @param aOffset Start of data in Java buffer to copy. This is assumed to be valid.
       
    47  * @param aLength Amount of data to copy. This is assumed to be valid.
       
    48  * @param aNativeBuffer Target for data. This is assumed to be long enough.
       
    49  * @returns An error code.
       
    50  */
       
    51 OS_EXPORT TInt S60CommonUtils::CopyToNative(JNIEnv& aJni, jbyteArray aJavaBuffer,
       
    52         TInt aOffset, TInt aLength, TDes8& aNativeBuffer)
       
    53 {
       
    54     __ASSERT_DEBUG(aOffset <= aJni.GetArrayLength(aJavaBuffer),
       
    55                    User::Panic(_L("S60CommonUtils"), EBadOffsetIntoJavaArrayForRead));
       
    56     __ASSERT_DEBUG(aLength <= aJni.GetArrayLength(aJavaBuffer) - aOffset,
       
    57                    User::Panic(_L("S60CommonUtils"), EReadingOverEndOfJavaArray));
       
    58 
       
    59     aNativeBuffer.SetLength(aLength);
       
    60     TUint8* nativeBufPtr = const_cast<TUint8*>(aNativeBuffer.Ptr());
       
    61     jbyte* jNativeBufPtr = reinterpret_cast<jbyte*>(nativeBufPtr);
       
    62     aJni.GetByteArrayRegion(aJavaBuffer, aOffset, aLength, jNativeBufPtr);
       
    63     return KErrNone;
       
    64 }
       
    65 
       
    66 
       
    67 
       
    68 /**
       
    69  * Copies data from the native to the Java array.
       
    70  * @return The number of bytes copied.
       
    71  */
       
    72 OS_EXPORT TInt S60CommonUtils::CopyToJava(JNIEnv& aJni, const TDesC8& aNativeBuffer,
       
    73         jbyteArray aJavaBuffer, TInt aOffset, TInt aLength)
       
    74 {
       
    75     __ASSERT_DEBUG(aOffset <= aJni.GetArrayLength(aJavaBuffer),
       
    76                    User::Panic(_L("S60CommonUtils"), EBadOffsetIntoJavaArray));
       
    77     __ASSERT_DEBUG(aLength <= aJni.GetArrayLength(aJavaBuffer) - aOffset,
       
    78                    User::Panic(_L("S60CommonUtils"), EWritingOverEndOfJavaArray));
       
    79 
       
    80     TInt nativeBufLength = aNativeBuffer.Length();
       
    81     TInt length = (nativeBufLength < aLength) ? nativeBufLength : aLength;
       
    82     TUint8* nativeBufPtr = const_cast<TUint8*>(aNativeBuffer.Ptr());
       
    83     jbyte* jNativeBufPtr = reinterpret_cast<jbyte*>(nativeBufPtr);
       
    84     aJni.SetByteArrayRegion(aJavaBuffer, aOffset, length, jNativeBufPtr);
       
    85     return length;
       
    86 }
       
    87 
       
    88 OS_EXPORT jstring S60CommonUtils::NativeToJavaString(JNIEnv& aJni, const TDesC16& aNativeString)
       
    89 {
       
    90     const jchar* ptr = aNativeString.Ptr();
       
    91     const jsize len = aNativeString.Length();
       
    92     jstring javaString = aJni.NewString(ptr, len);
       
    93     return javaString;
       
    94 }
       
    95 
       
    96 /**
       
    97  * Creates a Java array of strings from a native array of descriptors allocated
       
    98  * on the heap.
       
    99  * @param aJni The JNI environment.
       
   100  * @param aNativeArray The array of descriptors.
       
   101  * @return The newly created Java array of String objects, or NULL on error.
       
   102  */
       
   103 OS_EXPORT jobjectArray S60CommonUtils::NativeToJavaStringArray(JNIEnv& aJni,
       
   104         const RPointerArray<HBufC>& aNativeArray)
       
   105 {
       
   106     jclass stringClass = aJni.FindClass("java/lang/String");
       
   107     if (stringClass == NULL)
       
   108     {
       
   109         return NULL;
       
   110     }
       
   111 
       
   112     TInt count = aNativeArray.Count();
       
   113     jobjectArray jObjArray = aJni.NewObjectArray(count, stringClass, NULL);
       
   114     if (jObjArray == NULL)
       
   115     {
       
   116         return NULL;
       
   117     }
       
   118 
       
   119     for (int i = 0; i< count; i++)
       
   120     {
       
   121         //TPtr16 temp =  aNativeArray[i]->Des();
       
   122         jstring javaString = S60CommonUtils::NativeToJavaString(aJni, *aNativeArray[i]);
       
   123         if (javaString == NULL)
       
   124         {
       
   125             aJni.DeleteLocalRef(jObjArray);
       
   126             return NULL;
       
   127         }
       
   128 
       
   129         aJni.SetObjectArrayElement(jObjArray, i, javaString);
       
   130         aJni.DeleteLocalRef(javaString);
       
   131     }
       
   132 
       
   133     return jObjArray;
       
   134 }
       
   135 
       
   136 /* Converts wchar_t to descriptor */
       
   137 OS_EXPORT HBufC* S60CommonUtils::wstringToDes(const wchar_t* cStr)
       
   138 {
       
   139     HBufC* descStr = NULL;
       
   140     int length = wcslen(cStr);
       
   141     if (length > 0)
       
   142     {
       
   143         descStr = HBufC::New(length + 1);
       
   144         if (descStr == NULL)
       
   145         {
       
   146             return descStr;
       
   147         }
       
   148         TPtr ptr = descStr->Des();
       
   149         TPtr ptr16((TUint16*)cStr,length);
       
   150         ptr16.SetLength(length);
       
   151         ptr.Copy(ptr16);
       
   152         ptr.ZeroTerminate();
       
   153     }
       
   154     return descStr;
       
   155 }
       
   156 
       
   157 OS_EXPORT TTime S60CommonUtils::JavaTimeToTTime(jlong aJavaTime)
       
   158 {
       
   159     // Convert jlong to a TInt64
       
   160     TInt64 milliSeconds = *reinterpret_cast<TInt64*>(&aJavaTime);
       
   161     // Create a TTime object that represents the Java Date 'epoch' time of 00:00, 1 Jan 1970
       
   162     TInt64 javaEpocTimeNum = MAKE_TINT64(JavaUpperEpocTime, JavaLowerEpocTime);
       
   163     TTime time(javaEpocTimeNum);
       
   164     TTimeIntervalMicroSeconds timeInterval(milliSeconds * 1000);
       
   165     return time + timeInterval;
       
   166 }
       
   167 
       
   168 OS_EXPORT jlong S60CommonUtils::TTimeToJavaTime(TTime aEpocTime)
       
   169 {
       
   170     // Create a TTime object that represents the Java Date 'epoch' time of 00:00, 1 Jan 1970
       
   171     TInt64 javaEpocTimeNum = MAKE_TINT64(JavaUpperEpocTime, JavaLowerEpocTime);
       
   172     TTime javaEpochTime(javaEpocTimeNum);
       
   173     // Find difference in microseconds between 'epoch' and EPOC date and adjust to milliseconds
       
   174     TTimeIntervalMicroSeconds microInterval = aEpocTime.MicroSecondsFrom(javaEpochTime);
       
   175     TInt64 timeInterval = microInterval.Int64();
       
   176     timeInterval = timeInterval/1000;
       
   177     jlong javaTimeInterval = *reinterpret_cast<jlong*>(&timeInterval);
       
   178     return javaTimeInterval;
       
   179 }
       
   180 
       
   181 
       
   182 //------------------------------------------------------------------------------
       
   183 // public static ConvertWiderToNarrowL(const TDesC& aSource,TDesC8& aDestination)
       
   184 //
       
   185 //------------------------------------------------------------------------------
       
   186 OS_EXPORT TInt S60CommonUtils::ConvertWiderToNarrowLC(const TDesC& aSource,
       
   187         TDesC8*& aDestination)
       
   188 {
       
   189     TBool value = (!&aSource) || (aSource.Length() < 1);
       
   190     if (value)
       
   191     {
       
   192         // we are poping in NON CleanupStack version.
       
   193         CleanupStack::PushL(aDestination);
       
   194         return 0;
       
   195     }
       
   196 
       
   197     HBufC8* buffer = HBufC8::NewLC(aSource.Length());
       
   198     TPtr8 ptr = buffer->Des();
       
   199     ptr.Copy(aSource);
       
   200     aDestination = buffer;
       
   201 
       
   202     return aDestination->Length();
       
   203 }
       
   204 //------------------------------------------------------------------------------
       
   205 // public static ConvertWiderToNarrowL(const TDesC& aSource,TDesC8& aDestination)
       
   206 // DO NOT LEAVE IT ON THE CLEANUP STACK
       
   207 //------------------------------------------------------------------------------
       
   208 OS_EXPORT TInt S60CommonUtils::ConvertWiderToNarrowL(const TDesC& aSource,
       
   209         TDesC8*& aDestination)
       
   210 {
       
   211     ConvertWiderToNarrowLC(aSource, aDestination);
       
   212     CleanupStack::Pop(aDestination); //aDestination
       
   213 
       
   214     if (aDestination)
       
   215         return aDestination->Length();
       
   216     else
       
   217         return 0;
       
   218 }
       
   219 //------------------------------------------------------------------------------
       
   220 // public static ConvertNarrowToWiderL(const TDesC& aSource,TDesC8& aDestination)
       
   221 // Leave the TDesC on cleanup stack
       
   222 //------------------------------------------------------------------------------
       
   223 OS_EXPORT TInt S60CommonUtils::ConvertNarrowToWiderLC(const TDesC8& aSource,
       
   224         TDesC*& aDestination)
       
   225 {
       
   226     TBool value = (!&aSource) || (aSource.Length() < 1);
       
   227     if (value)
       
   228     {
       
   229         // we are poping in NON CleanupStack version.
       
   230         CleanupStack::PushL(aDestination);
       
   231         return 0;
       
   232     }
       
   233     HBufC16* buffer = HBufC16::NewLC(aSource.Length());
       
   234     TPtr16 ptr = buffer->Des();
       
   235     ptr.Copy(aSource);
       
   236     aDestination = buffer;
       
   237 
       
   238     return aDestination->Length();
       
   239 }
       
   240 //------------------------------------------------------------------------------
       
   241 // public static ConvertNarrowToWiderL(const TDesC& aSource,TDesC8& aDestination)
       
   242 // DO NOT LEAVE IT ON THE CLEANUP STACK
       
   243 //------------------------------------------------------------------------------
       
   244 OS_EXPORT TInt S60CommonUtils::ConvertNarrowToWiderL(const TDesC8& aSource,
       
   245         TDesC*& aDestination)
       
   246 {
       
   247     ConvertNarrowToWiderLC(aSource, aDestination);
       
   248     CleanupStack::Pop(aDestination); //aDestination
       
   249 
       
   250     if (aDestination)
       
   251         return aDestination->Length();
       
   252     else
       
   253         return 0;
       
   254 }
       
   255 //------------------------------------------------------------------------------
       
   256 // public static ConvertNarrowToWiderL(const TDesC& aSource,TDesC8& aDestination)
       
   257 // Leave the TDesC on cleanup stack
       
   258 //------------------------------------------------------------------------------
       
   259 OS_EXPORT TInt S60CommonUtils::CopyNarrowLC(const TDesC8& aSource,
       
   260         TDesC8*& aDestination)
       
   261 {
       
   262     TBool value = (!&aSource) || (aSource.Length() < 1);
       
   263     if (value)
       
   264     {
       
   265         // we are poping in NON CleanupStack version.
       
   266         CleanupStack::PushL(aDestination);
       
   267         return 0;
       
   268     }
       
   269     HBufC8* buffer = HBufC8::NewLC(aSource.Length());
       
   270     TPtr8 ptr = buffer->Des();
       
   271     ptr.Copy(aSource);
       
   272     aDestination = buffer;
       
   273 
       
   274     return aDestination->Length();
       
   275 }
       
   276 //-------------------------------------------------------------------------------
       
   277 // public static ConvertNarrowToWiderL(const TDesC& aSource,TDesC8& aDestination)
       
   278 // DO NOT LEAVE IT ON THE CLEANUP STACK
       
   279 //-------------------------------------------------------------------------------
       
   280 OS_EXPORT TInt S60CommonUtils::CopyNarrowL(const TDesC8& aSource,
       
   281         TDesC8*& aDestination)
       
   282 {
       
   283     CopyNarrowLC(aSource, aDestination);
       
   284     CleanupStack::Pop(aDestination); //aDestination
       
   285     if (aDestination)
       
   286         return aDestination->Length();
       
   287     else
       
   288         return 0;
       
   289 }
       
   290 //------------------------------------------------------------------------------
       
   291 // public static ConvertNarrowToWiderL(const TDesC& aSource,TDesC8& aDestination)
       
   292 // Leave the TDesC on cleanup stack
       
   293 //------------------------------------------------------------------------------
       
   294 OS_EXPORT TInt S60CommonUtils::CopyWiderLC(const TDesC16& aSource,
       
   295         TDesC16*& aDestination)
       
   296 {
       
   297     TBool value = (!&aSource) || (aSource.Length() < 1);
       
   298     if (value)
       
   299     {
       
   300         // we are poping in NON CleanupStack version.
       
   301         CleanupStack::PushL(aDestination);
       
   302         return 0;
       
   303     }
       
   304     HBufC16* buffer = HBufC16::NewLC(aSource.Length());
       
   305     TPtr16 ptr = buffer->Des();
       
   306     ptr.Copy(aSource);
       
   307     aDestination = buffer;
       
   308 
       
   309     return aDestination->Length();
       
   310 }
       
   311 //------------------------------------------------------------------------------
       
   312 // public static ConvertNarrowToWiderL(const TDesC& aSource,TDesC8& aDestination)
       
   313 // DO NOT LEAVE IT ON THE CLEANUP STACK
       
   314 //------------------------------------------------------------------------------
       
   315 OS_EXPORT TInt S60CommonUtils::CopyWiderL(const TDesC16& aSource,
       
   316         TDesC16*& aDestination)
       
   317 {
       
   318     CopyWiderLC(aSource, aDestination);
       
   319     CleanupStack::Pop(aDestination); //aDestination
       
   320     if (aDestination)
       
   321         return aDestination->Length();
       
   322     else
       
   323         return 0;
       
   324 }
       
   325 
       
   326 OS_EXPORT TFileName S60CommonUtils::ResourceLanguageFileNameL(const TDesC& aResourceFileName)
       
   327 {
       
   328     // get the name of the running process
       
   329     TFileName* dllFileName = new(ELeave) TFileName;
       
   330     CleanupStack::PushL(dllFileName);
       
   331     Dll::FileName(*dllFileName);
       
   332 
       
   333     // create the full path without drive letter
       
   334     TFileName* tmp = new(ELeave) TFileName;
       
   335     CleanupStack::PushL(tmp);
       
   336     tmp->Append(KDC_RESOURCE_FILES_DIR);
       
   337     tmp->Append(_L("java\\"));
       
   338     tmp->Append(aResourceFileName);
       
   339 
       
   340     // add the drive letter of the DLL's file name
       
   341     TParse p;
       
   342     p.Set(*tmp, dllFileName, NULL);
       
   343     CleanupStack::PopAndDestroy(tmp);
       
   344     CleanupStack::PopAndDestroy(dllFileName);
       
   345 
       
   346     // check if the resource exists
       
   347     TFileName resourceFullName = p.FullName();
       
   348     RFs fs;
       
   349     User::LeaveIfError(fs.Connect());
       
   350     CleanupClosePushL(fs);
       
   351     BaflUtils::NearestLanguageFile(fs, resourceFullName);
       
   352     if (!BaflUtils::FileExists(fs, resourceFullName))
       
   353     {
       
   354         // try the ROM drive
       
   355         TChar romDriveLetter;
       
   356         User::LeaveIfError(DriveInfo::GetDefaultDrive(DriveInfo::EDefaultRom, romDriveLetter));
       
   357         // replace resourceFullName's drive letter with romDriveLetter
       
   358         resourceFullName[0] = romDriveLetter;
       
   359         BaflUtils::NearestLanguageFile(fs, resourceFullName);
       
   360     }
       
   361     CleanupStack::PopAndDestroy(&fs);
       
   362 
       
   363     // return
       
   364     return resourceFullName;
       
   365 }
       
   366 
       
   367 
       
   368 OS_EXPORT TFileName S60CommonUtils::VerifiedFileNameL(const TDesC& aFileName)
       
   369 {
       
   370     _LIT(KColonChar, ":");
       
   371 
       
   372     RFs fs;
       
   373     User::LeaveIfError(fs.Connect());
       
   374     CleanupClosePushL(fs);
       
   375 
       
   376     // Does the file name specify drive ?
       
   377     // If the second char is ':' assume that the first one is drive
       
   378     TBool fileNameContainsDrive(EFalse);
       
   379     TChar originalDriveLetter(0);
       
   380     TUint attr(0);
       
   381     TInt  err(KErrNone);
       
   382     TFileName fullName = aFileName;
       
   383     if (aFileName.Find(KColonChar) == 1)
       
   384     {
       
   385         fileNameContainsDrive = ETrue;
       
   386         // Is the file in current drive?
       
   387         err = fs.Att(aFileName, attr);
       
   388         if (KErrNone == err)
       
   389         {
       
   390             CleanupStack::PopAndDestroy(&fs);
       
   391             return fullName;
       
   392         }
       
   393 
       
   394         // Must search from other drives. Remember the current drive;
       
   395         originalDriveLetter = aFileName[0];
       
   396         originalDriveLetter.UpperCase();
       
   397     }
       
   398 
       
   399     // First check system drive
       
   400     TChar driveLetter;
       
   401     User::LeaveIfError(DriveInfo::GetDefaultDrive(DriveInfo::EDefaultSystem, driveLetter));
       
   402     // Check system drive if it has not yet been checked
       
   403     if (originalDriveLetter != driveLetter)
       
   404     {
       
   405         if (fileNameContainsDrive)
       
   406         {
       
   407             fullName[0] = driveLetter;
       
   408         }
       
   409         else
       
   410         {
       
   411             fullName.Zero();
       
   412             fullName.Append(driveLetter);
       
   413             fullName.Append(KColonChar);
       
   414             fullName.Append(aFileName);
       
   415         }
       
   416 
       
   417         err = fs.Att(fullName, attr);
       
   418         if (KErrNone == err)
       
   419         {
       
   420             CleanupStack::PopAndDestroy(&fs);
       
   421             return fullName;
       
   422         }
       
   423     }
       
   424 
       
   425     // Next try to find file from ROM if the ROM drive has not yet been checked
       
   426     User::LeaveIfError(DriveInfo::GetDefaultDrive(DriveInfo::EDefaultRom, driveLetter));
       
   427     if (originalDriveLetter != driveLetter)
       
   428     {
       
   429         if (fileNameContainsDrive)
       
   430         {
       
   431             fullName[0] = driveLetter;
       
   432         }
       
   433         else
       
   434         {
       
   435             fullName.Zero();
       
   436             fullName.Append(driveLetter);
       
   437             fullName.Append(KColonChar);
       
   438             fullName.Append(aFileName);
       
   439         }
       
   440 
       
   441         err = fs.Att(fullName, attr);
       
   442     }
       
   443     User::LeaveIfError(err);
       
   444 
       
   445     CleanupStack::PopAndDestroy(&fs);
       
   446     return fullName;
       
   447 }
       
   448