javamanager/javarecognizer/src/recjar.cpp
changeset 21 2a9601315dfc
child 57 59b3b4473dc8
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:  This file contains an implementation of Symbian MIME type recognizer
       
    15  *                for MIME types application/java-archive (.jar) and
       
    16  *                text/vnd.sun.j2me.app-descriptor (.jad)
       
    17  *
       
    18 */
       
    19 
       
    20 
       
    21 #include <apmrec.h>
       
    22 #include <apmstd.h>
       
    23 #include <ecom/ecom.h>
       
    24 #include <ecom/implementationproxy.h>
       
    25 
       
    26 #include "javauids.h"
       
    27 #include "recjar.h"
       
    28 
       
    29 const TUid KJavaRecognizerTUid = { KJavaRecognizerDllUid};
       
    30 const TInt KJarNumMimeTypes = 2;
       
    31 
       
    32 const TInt KMaxBufferLength = 100;
       
    33 _LIT8(KDataTypeJavaArchive, "application/java-archive");
       
    34 _LIT8(KDataTypeAppDescriptor, "text/vnd.sun.j2me.app-descriptor");
       
    35 // First four bytes of a ZIP file
       
    36 _LIT8(KPkWareLocalFileHeader, "\x50\x4B\x03\x04");
       
    37 _LIT8(KMidlet,"Midlet-");
       
    38 
       
    39 CApaJarRecognizer::CApaJarRecognizer() :
       
    40         CApaDataRecognizerType(KJavaRecognizerTUid, CApaDataRecognizerType::EHigh)
       
    41 {
       
    42     iCountDataTypes = KJarNumMimeTypes;
       
    43 }
       
    44 
       
    45 TUint CApaJarRecognizer::PreferredBufSize()
       
    46 {
       
    47     return KMaxBufferLength;
       
    48 }
       
    49 
       
    50 TDataType CApaJarRecognizer::SupportedDataTypeL(TInt aIndex) const
       
    51 {
       
    52     __ASSERT_DEBUG(aIndex >= 0 && aIndex < KJarNumMimeTypes, User::Invariant());
       
    53     switch (aIndex)
       
    54     {
       
    55     case 0:
       
    56         return TDataType(KDataTypeJavaArchive);
       
    57     case 1:
       
    58         return TDataType(KDataTypeAppDescriptor);
       
    59     default:
       
    60         // Should not come here, keep GCC happy
       
    61         return TDataType(KDataTypeJavaArchive);
       
    62     }
       
    63 }
       
    64 
       
    65 void CApaJarRecognizer::DoRecognizeL(const TDesC& aName, const TDesC8& aBuffer)
       
    66 {
       
    67     if (aName.Length() > 4)
       
    68     {
       
    69         if (aName.Right(4).CompareF(_L(".jad")) == 0)
       
    70         {
       
    71             if (aBuffer.Length() > 0 && aBuffer.FindF(KMidlet())
       
    72                     != KErrNotFound)
       
    73             {
       
    74                 // The file contains the text "midlet-"
       
    75                 // so its almost certain to be a JAD file
       
    76                 iDataType = TDataType(KDataTypeAppDescriptor);
       
    77                 iConfidence = ECertain;
       
    78             }
       
    79             else
       
    80             {
       
    81                 // Did not find "midlet-" in the supplied buffer so
       
    82                 // try searching the rest of the file...
       
    83                 //
       
    84                 TBool weOwnFileHandle = EFalse;
       
    85                 // The following call only Leaves if user supplied file
       
    86                 // handle can not be rewound, this is not worth
       
    87                 // catching with a TRAP handler.
       
    88                 RFile *file = FilePassedByHandleL();
       
    89                 RFile ownFile;
       
    90                 RFs ownFs;
       
    91                 if (!file)
       
    92                 {
       
    93                     // We were not passed an RFile, so try and open the file directly.
       
    94                     User::LeaveIfError(ownFs.Connect());
       
    95                     CleanupClosePushL(ownFs);
       
    96                     User::LeaveIfError(ownFile.Open(ownFs, aName, EFileRead
       
    97                                                     | EFileShareReadersOrWriters | EFileStream));
       
    98                     CleanupClosePushL(ownFile);
       
    99                     file = &ownFile;
       
   100                     weOwnFileHandle = ETrue;
       
   101                 }
       
   102 
       
   103                 TInt fileRemaining;
       
   104                 User::LeaveIfError(file->Size(fileRemaining));
       
   105                 if (fileRemaining > aBuffer.Length())
       
   106                 {
       
   107                     // File is longer than buffer, so search remainder
       
   108                     // of file.
       
   109 
       
   110                     // Skip the start, which has already been read
       
   111                     TInt tmp = aBuffer.Length();
       
   112                     User::LeaveIfError(file->Seek(ESeekStart, tmp));
       
   113                     fileRemaining -= tmp;
       
   114 
       
   115                     // Buffer for processing the file
       
   116                     TUint8 buf[100]; // Must be at least 2*(KMidlet.Length()-1)
       
   117 
       
   118                     // Copy up to the last KMidlet.Length()-1 bytes
       
   119                     // from aBuffer, then append file data. This
       
   120                     // handles the case where the KMidlet string
       
   121                     // straddles the boundry by a byte (eg. buffer
       
   122                     // ends with "Midlet" and we are looking for
       
   123                     // "Midlet-").
       
   124                     TInt prefixLength = KMidlet().Length() - 1;
       
   125                     if (aBuffer.Length() < prefixLength)
       
   126                     {
       
   127                         prefixLength = aBuffer.Length();
       
   128                     }
       
   129                     TInt prefixOffset = aBuffer.Length() - prefixLength;
       
   130                     if (prefixOffset < 0)
       
   131                     {
       
   132                         prefixOffset = 0;
       
   133                     }
       
   134 
       
   135                     if (prefixLength)
       
   136                     {
       
   137                         // Copy prefix into buffer
       
   138                         TPtr8 prefixDes(&buf[0], prefixLength);
       
   139                         prefixDes = aBuffer.Mid(prefixOffset, prefixLength);
       
   140                     }
       
   141 
       
   142                     while (fileRemaining > 0)
       
   143                     {
       
   144                         // Read as much file data into the buffer as possible.
       
   145                         TPtr8 bufBodyDes(&buf[0] + prefixLength, sizeof(buf)
       
   146                                          - prefixLength);
       
   147                         User::LeaveIfError(file->Read(bufBodyDes));
       
   148                         fileRemaining -= bufBodyDes.Length();
       
   149 
       
   150                         TPtrC8 bufDes(&buf[0], prefixLength
       
   151                                       + bufBodyDes.Length());
       
   152                         if (bufDes.FindF(KMidlet()) != KErrNotFound)
       
   153                         {
       
   154                             // The file contains the text "midlet-"
       
   155                             // so its almost certain to be a JAD file
       
   156                             iDataType = TDataType(KDataTypeAppDescriptor);
       
   157                             iConfidence = ECertain;
       
   158                             break;
       
   159                         }
       
   160                         // Not found, copy prefix to start of buffer and try again.
       
   161                         if (bufDes.Length() == sizeof(buf))
       
   162                         {
       
   163                             // Copy prefix into buffer
       
   164                             prefixLength = KMidlet().Length() - 1;
       
   165                             TPtr8 prefixDes(buf, prefixLength);
       
   166                             prefixDes = bufDes.Mid(bufDes.Length()
       
   167                                                    - prefixLength, prefixLength);
       
   168                         }
       
   169                     }
       
   170                 }
       
   171 
       
   172                 if (weOwnFileHandle)
       
   173                 {
       
   174                     CleanupStack::PopAndDestroy(&ownFile);
       
   175                     CleanupStack::PopAndDestroy(&ownFs);
       
   176                 }
       
   177             }
       
   178         }
       
   179         else if (aName.Right(4).CompareF(_L(".jar")) == 0)
       
   180         {
       
   181             // if the first 4 bytes of the buffer match the first 4
       
   182             // bytes of a zip file it must be a JAR file
       
   183             if (aBuffer.Length() > KPkWareLocalFileHeader().Length()
       
   184                     && KPkWareLocalFileHeader().Compare(aBuffer.Left(4)) == 0)
       
   185             {
       
   186                 iDataType = TDataType(KDataTypeJavaArchive);
       
   187                 iConfidence = ECertain;
       
   188             }
       
   189         }
       
   190     }
       
   191 
       
   192     return;
       
   193 }
       
   194 
       
   195 CApaDataRecognizerType* CApaJarRecognizer::CreateRecognizerL()
       
   196 {
       
   197     return new(ELeave) CApaJarRecognizer();
       
   198 }
       
   199 
       
   200 const TImplementationProxy ImplementationTable[] =
       
   201 {
       
   202     IMPLEMENTATION_PROXY_ENTRY(KRecognizerEcomImplUid, CApaJarRecognizer::CreateRecognizerL)
       
   203 };
       
   204 
       
   205 EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
       
   206 {
       
   207     aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
       
   208     return ImplementationTable;
       
   209 }
       
   210