webengine/osswebengine/WebKit/s60/plugins/PluginStream.cpp
changeset 0 dd21522fd290
child 10 a359256acfc6
equal deleted inserted replaced
-1:000000000000 0:dd21522fd290
       
     1 /*
       
     2 * Copyright (c) 2006 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 the License "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:  
       
    15 *
       
    16 */
       
    17 
       
    18 #include <SysUtil.h>
       
    19 #include "../../bidi.h"
       
    20 
       
    21 #include "Frame.h"
       
    22 
       
    23 #include "PluginStream.h"
       
    24 #include "PluginSkin.h"
       
    25 #include "PluginWin.h"
       
    26 #include "PluginHandler.h"
       
    27 #include "StaticObjectsContainer.h"
       
    28 #include "PluginStreamLoaderClient.h"
       
    29 
       
    30 _LIT(KPath,"c:\\system\\temp\\");
       
    31 
       
    32 using namespace WebCore;
       
    33 
       
    34 PluginStream::PluginStream(PluginSkin* pluginskin, 
       
    35         NetscapePlugInStreamLoaderClient* loaderclient, void* notifydata) :
       
    36                                                 m_notifydata(notifydata),
       
    37                                                 m_pluginskin(pluginskin),
       
    38                                                 m_loaderclient(loaderclient),
       
    39                                                 m_stream(0),                                                
       
    40                                                 m_type(NP_NORMAL),                                                
       
    41                                                 m_fileName(0),
       
    42                                                 m_streamDestroyed(false)
       
    43 {   
       
    44     m_pluginskin->addPluginStream(this);
       
    45 }
       
    46 
       
    47 PluginStream::~PluginStream()
       
    48 {        
       
    49     User::Free(m_stream);
       
    50     delete m_fileName;    
       
    51     m_pluginskin->removePluginStream(this);
       
    52 }
       
    53 
       
    54 void PluginStream::close()
       
    55 {
       
    56     m_loaderclient->stop();
       
    57 }
       
    58 
       
    59 void PluginStream::createNPStreamL(TPtrC8 url, TPtrC16 mimetype, long long length)
       
    60 {
       
    61     
       
    62     NPError error( NPERR_NO_ERROR );
       
    63         
       
    64     
       
    65     // convert to 16 bit
       
    66     HBufC* url16 = HBufC::NewLC(url.Length());                
       
    67     url16->Des().Copy(url);                
       
    68 
       
    69     // convert to 8 bit
       
    70     HBufC8* mime8 = HBufC8::NewLC(mimetype.Length());
       
    71     mime8->Des().Copy(mimetype);
       
    72         
       
    73 
       
    74     m_pluginskin->createPluginWinL(url, mimetype);         
       
    75     m_pluginskin->loadPluginL(*mime8);
       
    76     
       
    77     if (m_pluginskin->getNPP() && m_pluginskin->getNPPluginFucs()) {
       
    78         
       
    79         m_stream = (NPStream*) User::AllocL( sizeof(NPStream) );       
       
    80             
       
    81         if (m_stream) {        
       
    82             m_stream->pdata = m_pluginskin->getNPP()->pdata;
       
    83             m_stream->ndata =  m_pluginskin->pluginWin();        
       
    84             m_stream->url = url16->AllocL();
       
    85             m_stream->end = length;
       
    86             m_stream->lastmodified = 0; 
       
    87             m_stream->notifyData = m_notifydata;    
       
    88 
       
    89             
       
    90             error = m_pluginskin->getNPPluginFucs()->newstream ( m_pluginskin->getNPP(), 
       
    91                                                             *mime8, 
       
    92                                                             m_stream, 
       
    93                                                             EFalse,
       
    94                                                             &m_type );                                                
       
    95         }
       
    96 
       
    97     }
       
    98 
       
    99         
       
   100     CleanupStack::PopAndDestroy(2);  
       
   101 
       
   102     if (error == NPERR_NO_ERROR) {
       
   103         if (m_type == NP_ASFILEONLY || m_type == NP_ASFILE) {
       
   104             generateTempFileL();                    
       
   105         }                
       
   106     }
       
   107 
       
   108     switch ( error ) {
       
   109         case NPERR_OUT_OF_MEMORY_ERROR: {
       
   110             User::Leave( KErrNoMemory );
       
   111             break;
       
   112         }
       
   113         case NPERR_GENERIC_ERROR: {
       
   114             User::Leave( KErrNotSupported );
       
   115             break;
       
   116         }
       
   117     }    
       
   118 
       
   119 }
       
   120 
       
   121 void PluginStream::writeStreamL(const char* data, int length)
       
   122 {
       
   123 
       
   124     switch ( m_type ) {
       
   125         case NP_NORMAL: {
       
   126             writeStreamToPluginL( data, length );
       
   127             break;
       
   128         }
       
   129         case NP_ASFILEONLY: {
       
   130             writeStreamToFileL( data, length );
       
   131             break;
       
   132         }
       
   133         case NP_ASFILE: {
       
   134             writeStreamToFileL( data, length );
       
   135             writeStreamToPluginL( data, length );
       
   136             break;
       
   137         }
       
   138         case NP_SEEK:{    
       
   139             break;
       
   140         }
       
   141         default: {    
       
   142         break;
       
   143         }
       
   144     }
       
   145 
       
   146 }
       
   147 
       
   148 void PluginStream::writeStreamToPluginL(const char* data, int length)
       
   149 {
       
   150     int offset = 0;
       
   151     while (offset<length) {
       
   152             
       
   153         if (m_pluginskin->getNPPluginFucs())  {        
       
   154 
       
   155             int spaceavaiable = m_pluginskin->getNPPluginFucs()->writeready(m_pluginskin->getNPP(), m_stream);
       
   156             
       
   157             if (spaceavaiable <= 0) {                
       
   158                 User::Leave( KErrNotSupported );                
       
   159             }
       
   160              
       
   161             int len = (spaceavaiable > (length-offset))? (length-offset) : spaceavaiable;                                
       
   162             int bytesconsumed = m_pluginskin->getNPPluginFucs()->write( m_pluginskin->getNPP(), m_stream, offset, len, (void*)data);                
       
   163              
       
   164             if (bytesconsumed <= 0){
       
   165                 User::Leave( KErrNotSupported );                
       
   166             } 
       
   167                                            
       
   168             offset += bytesconsumed;
       
   169         
       
   170         }    
       
   171         
       
   172     }
       
   173 
       
   174 }
       
   175 
       
   176 
       
   177 void PluginStream::writeStreamToFileL(const char* data, int length)
       
   178 {
       
   179 
       
   180     if (m_fileName) {
       
   181 
       
   182         RFs&    rfs = StaticObjectsContainer::instance()->fsSession();
       
   183         RFile  file;    
       
   184 
       
   185                
       
   186         // Write to the file only if we are not below critical disk level
       
   187         if (SysUtil::DiskSpaceBelowCriticalLevelL (&rfs, length, EDriveC)) {
       
   188             User::Leave(KErrDiskFull);
       
   189         }
       
   190         
       
   191         User::LeaveIfError(file.Open(rfs, *m_fileName, EFileWrite));
       
   192         CleanupClosePushL(file);
       
   193         
       
   194         TInt   pos(0);
       
   195         User::LeaveIfError(file.Seek(ESeekEnd, pos));
       
   196                 
       
   197         TPtrC8 ptrc8((TUint8*)data,length);
       
   198         file.Write(ptrc8);
       
   199         file.Flush();
       
   200 
       
   201         CleanupStack::PopAndDestroy(); // file        
       
   202     }
       
   203 
       
   204 }
       
   205 
       
   206 void PluginStream::destroyStream(int reason)
       
   207 {
       
   208     if (m_streamDestroyed) return;
       
   209         m_streamDestroyed = true;
       
   210 
       
   211     TInt16 npreason( NPRES_BASE );
       
   212 
       
   213     if (m_type == NP_ASFILEONLY || m_type == NP_ASFILE) {
       
   214 
       
   215         if ( reason == KErrNone ) {
       
   216         
       
   217             if ( m_pluginskin->getNPPluginFucs() && m_pluginskin->getNPPluginFucs()->asfile ) {
       
   218                 m_pluginskin->getNPPluginFucs()->asfile( m_pluginskin->getNPP(), m_stream, *m_fileName );
       
   219             }
       
   220         }
       
   221     }
       
   222     
       
   223     switch ( reason ) {
       
   224         case KErrNone:
       
   225         npreason = NPRES_DONE;
       
   226         break;
       
   227 
       
   228         case KErrCancel:
       
   229         npreason = NPRES_USER_BREAK;
       
   230         break;
       
   231 
       
   232         default:
       
   233         npreason = NPRES_NETWORK_ERR;
       
   234         break;
       
   235     }
       
   236 
       
   237 
       
   238     if ( m_pluginskin->getNPPluginFucs() && m_pluginskin->getNPPluginFucs()->destroystream ) {            
       
   239         m_pluginskin->getNPPluginFucs()->destroystream( m_pluginskin->getNPP(), m_stream,  npreason);
       
   240     }
       
   241     
       
   242     if (reason == KErrNone) {
       
   243         m_pluginskin->forceRedraw(true);
       
   244     }
       
   245 }
       
   246 
       
   247 void PluginStream::generateTempFileL()
       
   248 {
       
   249 
       
   250     RFs&    rfs = StaticObjectsContainer::instance()->fsSession();
       
   251     RFile  file;    
       
   252 
       
   253     rfs.MkDirAll(KPath);
       
   254     
       
   255     // Create unique file name from the temp file name and file extension from Url
       
   256     TFileName tempFileName;
       
   257     User::LeaveIfError(file.Temp(rfs, KPath, tempFileName, EFileWrite));
       
   258     CleanupClosePushL(file);
       
   259 
       
   260     TParse p;
       
   261     p.Set(tempFileName,NULL,NULL);
       
   262     TPtrC fileNameOnly(p.Name());
       
   263 
       
   264     // Create a temp file with same file extension as the plugin content,
       
   265     // by extracting the file extension from the URL. Using example URL,
       
   266     // "http://www.xyz.com/flashy.swf?h=234&w=321&script=all.js"
       
   267     HBufC8* urlName = NULL;
       
   268     urlName = HBufC8::NewLC(m_stream->url->Length());
       
   269     urlName->Des().Copy(m_stream->url->Des());
       
   270     TPtrC8 fileExtPtr(urlName->Des());    
       
   271     if (fileExtPtr.Length() > 0) {
       
   272 
       
   273         // Ignore last character if it is '/'
       
   274         if ( fileExtPtr[fileExtPtr.Length() - 1] == '/' ) {
       
   275             fileExtPtr.Set(fileExtPtr.Left(fileExtPtr.Length() - 1));
       
   276         }
       
   277 
       
   278         // Trim anything right of the query '?', the url example
       
   279         // leaves us with "http://www.xyz.com/flashy.swf"
       
   280         TInt i = fileExtPtr.Locate('?');
       
   281         if (i >= 0) {
       
   282             fileExtPtr.Set(fileExtPtr.Left(i));
       
   283         }
       
   284 
       
   285         //  Trim anything left of path, the last '/'
       
   286         // "http://www.xyz.com/flashy.swf" -> "flashy.swf"
       
   287         i = fileExtPtr.LocateReverse('/');
       
   288         if (i >= 0) {
       
   289             fileExtPtr.Set(fileExtPtr.Mid(i+1));
       
   290         }
       
   291 
       
   292         // Trim the url to get the dot-extension, after the last '.'
       
   293         // "flashy.swf" -> ".swf". This works with "flashy.ad.swf".
       
   294         i = fileExtPtr.LocateReverse('.');
       
   295         if (i >= 0) {
       
   296             fileExtPtr.Set(fileExtPtr.Mid(i));
       
   297         }
       
   298     }
       
   299         
       
   300             
       
   301     TInt fileLen(KPath().Length() + fileNameOnly.Length() + fileExtPtr.Length());
       
   302     m_fileName = HBufC::NewL(fileLen);
       
   303     
       
   304     TPtr fNamePtr = m_fileName->Des();
       
   305     fNamePtr.Copy(fileExtPtr);
       
   306     fNamePtr.Insert(0, fileNameOnly);
       
   307     fNamePtr.Insert(0, KPath());
       
   308     file.Rename(m_fileName->Des());
       
   309     
       
   310     m_pluginskin->m_tempFilesArray.AppendL(m_fileName->Alloc());
       
   311     
       
   312     CleanupStack::PopAndDestroy(2); // file, urlName            
       
   313 
       
   314 }