LCOV - code coverage report
Current view: directory - startupcache - StartupCacheUtils.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 101 92 91.1 %
Date: 2012-06-02 Functions: 5 5 100.0 %

       1                 : /* ***** BEGIN LICENSE BLOCK *****
       2                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       3                 :  *
       4                 :  * The contents of this file are subject to the Mozilla Public License Version
       5                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       6                 :  * the License. You may obtain a copy of the License at
       7                 :  * http://www.mozilla.org/MPL/
       8                 :  *
       9                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      10                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      11                 :  * for the specific language governing rights and limitations under the
      12                 :  * License.
      13                 :  *
      14                 :  * The Original Code is Startup Cache.
      15                 :  *
      16                 :  * The Initial Developer of the Original Code is
      17                 :  * The Mozilla Foundation <http://www.mozilla.org/>.
      18                 :  * Portions created by the Initial Developer are Copyright (C) 2009-2011
      19                 :  * the Initial Developer. All Rights Reserved.
      20                 :  *
      21                 :  * Contributor(s):
      22                 :  *  Benedict Hsieh <bhsieh@mozilla.com>
      23                 :  *  Taras Glek <tglek@mozilla.com>
      24                 :  *  Mike Hommey <mh@glandium.org>
      25                 :  *
      26                 :  * Alternatively, the contents of this file may be used under the terms of
      27                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      28                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      29                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      30                 :  * of those above. If you wish to allow use of your version of this file only
      31                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      32                 :  * use your version of this file under the terms of the MPL, indicate your
      33                 :  * decision by deleting the provisions above and replace them with the notice
      34                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      35                 :  * the provisions above, a recipient may use your version of this file under
      36                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      37                 :  *
      38                 :  * ***** END LICENSE BLOCK ***** */
      39                 : 
      40                 : #include "nsCOMPtr.h"
      41                 : #include "nsIInputStream.h"
      42                 : #include "nsIStringStream.h"
      43                 : #include "nsNetUtil.h"
      44                 : #include "nsIJARURI.h"
      45                 : #include "nsIResProtocolHandler.h"
      46                 : #include "nsIChromeRegistry.h"
      47                 : #include "nsAutoPtr.h"
      48                 : #include "StartupCacheUtils.h"
      49                 : #include "mozilla/scache/StartupCache.h"
      50                 : #include "mozilla/Omnijar.h"
      51                 : 
      52                 : namespace mozilla {
      53                 : namespace scache {
      54                 : 
      55                 : NS_EXPORT nsresult
      56             643 : NewObjectInputStreamFromBuffer(char* buffer, PRUint32 len, 
      57                 :                                nsIObjectInputStream** stream)
      58                 : {
      59                 :   nsCOMPtr<nsIStringInputStream> stringStream
      60            1286 :     = do_CreateInstance("@mozilla.org/io/string-input-stream;1");
      61                 :   nsCOMPtr<nsIObjectInputStream> objectInput 
      62            1286 :     = do_CreateInstance("@mozilla.org/binaryinputstream;1");
      63                 :   
      64             643 :   stringStream->AdoptData(buffer, len);
      65             643 :   objectInput->SetInputStream(stringStream);
      66                 :   
      67             643 :   objectInput.forget(stream);
      68             643 :   return NS_OK;
      69                 : }
      70                 : 
      71                 : NS_EXPORT nsresult
      72            7375 : NewObjectOutputWrappedStorageStream(nsIObjectOutputStream **wrapperStream,
      73                 :                                     nsIStorageStream** stream,
      74                 :                                     bool wantDebugStream)
      75                 : {
      76           14750 :   nsCOMPtr<nsIStorageStream> storageStream;
      77                 : 
      78            7375 :   nsresult rv = NS_NewStorageStream(256, PR_UINT32_MAX, getter_AddRefs(storageStream));
      79            7375 :   NS_ENSURE_SUCCESS(rv, rv);
      80                 : 
      81                 :   nsCOMPtr<nsIObjectOutputStream> objectOutput
      82           14750 :     = do_CreateInstance("@mozilla.org/binaryoutputstream;1");
      83                 :   nsCOMPtr<nsIOutputStream> outputStream
      84           14750 :     = do_QueryInterface(storageStream);
      85                 :   
      86            7375 :   objectOutput->SetOutputStream(outputStream);
      87                 :   
      88                 : #ifdef DEBUG
      89            7375 :   if (wantDebugStream) {
      90                 :     // Wrap in debug stream to detect unsupported writes of 
      91                 :     // multiply-referenced non-singleton objects
      92            7375 :     StartupCache* sc = StartupCache::GetSingleton();
      93            7375 :     NS_ENSURE_TRUE(sc, NS_ERROR_UNEXPECTED);
      94           14750 :     nsCOMPtr<nsIObjectOutputStream> debugStream;
      95            7375 :     sc->GetDebugObjectOutputStream(objectOutput, getter_AddRefs(debugStream));
      96            7375 :     debugStream.forget(wrapperStream);
      97                 :   } else {
      98               0 :     objectOutput.forget(wrapperStream);
      99                 :   }
     100                 : #else
     101                 :   objectOutput.forget(wrapperStream);
     102                 : #endif
     103                 :   
     104            7375 :   storageStream.forget(stream);
     105            7375 :   return NS_OK;
     106                 : }
     107                 : 
     108                 : NS_EXPORT nsresult
     109            7376 : NewBufferFromStorageStream(nsIStorageStream *storageStream, 
     110                 :                            char** buffer, PRUint32* len) 
     111                 : {
     112                 :   nsresult rv;
     113           14752 :   nsCOMPtr<nsIInputStream> inputStream;
     114            7376 :   rv = storageStream->NewInputStream(0, getter_AddRefs(inputStream));
     115            7376 :   NS_ENSURE_SUCCESS(rv, rv);
     116                 :   
     117                 :   PRUint32 avail, read;
     118            7376 :   rv = inputStream->Available(&avail);
     119            7376 :   NS_ENSURE_SUCCESS(rv, rv);
     120                 :   
     121           22128 :   nsAutoArrayPtr<char> temp (new char[avail]);
     122            7376 :   rv = inputStream->Read(temp, avail, &read);
     123            7376 :   if (NS_SUCCEEDED(rv) && avail != read)
     124               0 :     rv = NS_ERROR_UNEXPECTED;
     125                 :   
     126            7376 :   if (NS_FAILED(rv)) {
     127               0 :     return rv;
     128                 :   }
     129                 :   
     130            7376 :   *len = avail;
     131            7376 :   *buffer = temp.forget();
     132            7376 :   return NS_OK;
     133                 : }
     134                 : 
     135                 : static const char baseName[2][5] = { "gre/", "app/" };
     136                 : 
     137                 : static inline bool
     138           13651 : canonicalizeBase(nsCAutoString &spec,
     139                 :                  nsACString &out,
     140                 :                  mozilla::Omnijar::Type aType)
     141                 : {
     142           27302 :     nsCAutoString base;
     143           13651 :     nsresult rv = mozilla::Omnijar::GetURIString(aType, base);
     144                 : 
     145           13651 :     if (NS_FAILED(rv) || !base.Length())
     146             892 :         return false;
     147                 : 
     148           12759 :     if (base.Compare(spec.get(), false, base.Length()))
     149             892 :         return false;
     150                 : 
     151           11867 :     out.Append("/resource/");
     152           11867 :     out.Append(baseName[aType]);
     153           11867 :     out.Append(Substring(spec, base.Length()));
     154           11867 :     return true;
     155                 : }
     156                 : 
     157                 : /**
     158                 :  * PathifyURI transforms uris into useful zip paths
     159                 :  * to make it easier to manipulate startup cache entries
     160                 :  * using standard zip tools.
     161                 :  * Transformations applied:
     162                 :  *  * resource:// URIs are resolved to their corresponding file/jar URI to
     163                 :  *    canonicalize resources URIs other than gre and app.
     164                 :  *  * Paths under GRE or APP directory have their base path replaced with
     165                 :  *    resource/gre or resource/app to avoid depending on install location.
     166                 :  *  * jar:file:///path/to/file.jar!/sub/path urls are replaced with
     167                 :  *    /path/to/file.jar/sub/path
     168                 :  *
     169                 :  *  The result is appended to the string passed in. Adding a prefix before
     170                 :  *  calling is recommended to avoid colliding with other cache users.
     171                 :  *
     172                 :  * For example, in the js loader (string is prefixed with jsloader by caller):
     173                 :  *  resource://gre/modules/XPCOMUtils.jsm or
     174                 :  *  file://$GRE_DIR/modules/XPCOMUtils.jsm or
     175                 :  *  jar:file://$GRE_DIR/omni.jar!/modules/XPCOMUtils.jsm becomes
     176                 :  *     jsloader/resource/gre/modules/XPCOMUtils.jsm
     177                 :  *  file://$PROFILE_DIR/extensions/{uuid}/components/component.js becomes
     178                 :  *     jsloader/$PROFILE_DIR/extensions/%7Buuid%7D/components/component.js
     179                 :  *  jar:file://$PROFILE_DIR/extensions/some.xpi!/components/component.js becomes
     180                 :  *     jsloader/$PROFILE_DIR/extensions/some.xpi/components/component.js
     181                 :  */
     182                 : NS_EXPORT nsresult
     183           12763 : PathifyURI(nsIURI *in, nsACString &out)
     184                 : {
     185                 :     bool equals;
     186                 :     nsresult rv;
     187           25526 :     nsCOMPtr<nsIURI> uri = in;
     188           25526 :     nsCAutoString spec;
     189                 : 
     190                 :     // Resolve resource:// URIs. At the end of this if/else block, we
     191                 :     // have both spec and uri variables identifying the same URI.
     192           12763 :     if (NS_SUCCEEDED(in->SchemeIs("resource", &equals)) && equals) {
     193           19356 :         nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv);
     194            9678 :         NS_ENSURE_SUCCESS(rv, rv);
     195                 : 
     196           19356 :         nsCOMPtr<nsIProtocolHandler> ph;
     197            9678 :         rv = ioService->GetProtocolHandler("resource", getter_AddRefs(ph));
     198            9678 :         NS_ENSURE_SUCCESS(rv, rv);
     199                 : 
     200           19356 :         nsCOMPtr<nsIResProtocolHandler> irph(do_QueryInterface(ph, &rv));
     201            9678 :         NS_ENSURE_SUCCESS(rv, rv);
     202                 : 
     203            9678 :         rv = irph->ResolveURI(in, spec);
     204            9678 :         NS_ENSURE_SUCCESS(rv, rv);
     205                 : 
     206            9678 :         rv = ioService->NewURI(spec, nsnull, nsnull, getter_AddRefs(uri));
     207            9678 :         NS_ENSURE_SUCCESS(rv, rv);
     208                 :     } else {
     209            3085 :         if (NS_SUCCEEDED(in->SchemeIs("chrome", &equals)) && equals) {
     210                 :             nsCOMPtr<nsIChromeRegistry> chromeReg =
     211             414 :                 mozilla::services::GetChromeRegistryService();
     212             207 :             if (!chromeReg)
     213               0 :                 return NS_ERROR_UNEXPECTED;
     214                 : 
     215             207 :             rv = chromeReg->ConvertChromeURL(in, getter_AddRefs(uri));
     216             207 :             NS_ENSURE_SUCCESS(rv, rv);
     217                 :         }
     218                 : 
     219            3081 :         rv = uri->GetSpec(spec);
     220            3081 :         NS_ENSURE_SUCCESS(rv, rv);
     221                 :     }
     222                 : 
     223           13651 :     if (!canonicalizeBase(spec, out, mozilla::Omnijar::GRE) &&
     224             892 :         !canonicalizeBase(spec, out, mozilla::Omnijar::APP)) {
     225             892 :         if (NS_SUCCEEDED(uri->SchemeIs("file", &equals)) && equals) {
     226            1336 :             nsCOMPtr<nsIFileURL> baseFileURL;
     227             668 :             baseFileURL = do_QueryInterface(uri, &rv);
     228             668 :             NS_ENSURE_SUCCESS(rv, rv);
     229                 : 
     230            1336 :             nsCAutoString path;
     231             668 :             rv = baseFileURL->GetPath(path);
     232             668 :             NS_ENSURE_SUCCESS(rv, rv);
     233                 : 
     234            1336 :             out.Append(path);
     235             224 :         } else if (NS_SUCCEEDED(uri->SchemeIs("jar", &equals)) && equals) {
     236             448 :             nsCOMPtr<nsIJARURI> jarURI = do_QueryInterface(uri, &rv);
     237             224 :             NS_ENSURE_SUCCESS(rv, rv);
     238                 : 
     239             448 :             nsCOMPtr<nsIURI> jarFileURI;
     240             224 :             rv = jarURI->GetJARFile(getter_AddRefs(jarFileURI));
     241             224 :             NS_ENSURE_SUCCESS(rv, rv);
     242                 : 
     243             224 :             rv = PathifyURI(jarFileURI, out);
     244             224 :             NS_ENSURE_SUCCESS(rv, rv);
     245                 : 
     246             448 :             nsCAutoString path;
     247             224 :             rv = jarURI->GetJAREntry(path);
     248             224 :             NS_ENSURE_SUCCESS(rv, rv);
     249             224 :             out.Append("/");
     250             448 :             out.Append(path);
     251                 :         } else { // Very unlikely
     252               0 :             nsCAutoString spec;
     253               0 :             rv = uri->GetSpec(spec);
     254               0 :             NS_ENSURE_SUCCESS(rv, rv);
     255                 : 
     256               0 :             out.Append("/");
     257               0 :             out.Append(spec);
     258                 :         }
     259                 :     }
     260           12759 :     return NS_OK;
     261                 : }
     262                 : 
     263                 : }
     264                 : }

Generated by: LCOV version 1.7