LCOV - app.info - startupcache/StartupCacheUtils.cpp

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-04-21 | 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             642 : NewObjectInputStreamFromBuffer(char* buffer, PRUint32 len,
          57                 :                                nsIObjectInputStream** stream)
          58                 : {
          59                 :   nsCOMPtr<nsIStringInputStream> stringStream
          60            1284 :     = do_CreateInstance("@mozilla.org/io/string-input-stream;1");
          61                 :   nsCOMPtr<nsIObjectInputStream> objectInput
          62            1284 :     = do_CreateInstance("@mozilla.org/binaryinputstream;1");
          63                 :
          64             642 :   stringStream->AdoptData(buffer, len);
          65             642 :   objectInput->SetInputStream(stringStream);
          66                 :
          67             642 :   objectInput.forget(stream);
          68             642 :   return NS_OK;
          69                 : }
          70                 :
          71                 : NS_EXPORT nsresult
          72            7362 : NewObjectOutputWrappedStorageStream(nsIObjectOutputStream **wrapperStream,
          73                 :                                     nsIStorageStream** stream,
          74                 :                                     bool wantDebugStream)
          75                 : {
          76           14724 :   nsCOMPtr<nsIStorageStream> storageStream;
          77                 :
          78            7362 :   nsresult rv = NS_NewStorageStream(256, PR_UINT32_MAX, getter_AddRefs(storageStream));
          79            7362 :   NS_ENSURE_SUCCESS(rv, rv);
          80                 :
          81                 :   nsCOMPtr<nsIObjectOutputStream> objectOutput
          82           14724 :     = do_CreateInstance("@mozilla.org/binaryoutputstream;1");
          83                 :   nsCOMPtr<nsIOutputStream> outputStream
          84           14724 :     = do_QueryInterface(storageStream);
          85                 :
          86            7362 :   objectOutput->SetOutputStream(outputStream);
          87                 :
          88                 : #ifdef DEBUG
          89            7362 :   if (wantDebugStream) {
          90                 :     // Wrap in debug stream to detect unsupported writes of
          91                 :     // multiply-referenced non-singleton objects
          92            7362 :     StartupCache* sc = StartupCache::GetSingleton();
          93            7362 :     NS_ENSURE_TRUE(sc, NS_ERROR_UNEXPECTED);
          94           14724 :     nsCOMPtr<nsIObjectOutputStream> debugStream;
          95            7362 :     sc->GetDebugObjectOutputStream(objectOutput, getter_AddRefs(debugStream));
          96            7362 :     debugStream.forget(wrapperStream);
          97                 :   } else {
          98               0 :     objectOutput.forget(wrapperStream);
          99                 :   }
         100                 : #else
         101                 :   objectOutput.forget(wrapperStream);
         102                 : #endif
         103                 :
         104            7362 :   storageStream.forget(stream);
         105            7362 :   return NS_OK;
         106                 : }
         107                 :
         108                 : NS_EXPORT nsresult
         109            7362 : NewBufferFromStorageStream(nsIStorageStream *storageStream,
         110                 :                            char** buffer, PRUint32* len)
         111                 : {
         112                 :   nsresult rv;
         113           14724 :   nsCOMPtr<nsIInputStream> inputStream;
         114            7362 :   rv = storageStream->NewInputStream(0, getter_AddRefs(inputStream));
         115            7362 :   NS_ENSURE_SUCCESS(rv, rv);
         116                 :
         117                 :   PRUint32 avail, read;
         118            7362 :   rv = inputStream->Available(&avail);
         119            7362 :   NS_ENSURE_SUCCESS(rv, rv);
         120                 :
         121           22086 :   nsAutoArrayPtr<char> temp (new char[avail]);
         122            7362 :   rv = inputStream->Read(temp, avail, &read);
         123            7362 :   if (NS_SUCCEEDED(rv) && avail != read)
         124               0 :     rv = NS_ERROR_UNEXPECTED;
         125                 :
         126            7362 :   if (NS_FAILED(rv)) {
         127               0 :     return rv;
         128                 :   }
         129                 :
         130            7362 :   *len = avail;
         131            7362 :   *buffer = temp.forget();
         132            7362 :   return NS_OK;
         133                 : }
         134                 :
         135                 : static const char baseName[2][5] = { "gre/", "app/" };
         136                 :
         137                 : static inline bool
         138           13621 : canonicalizeBase(nsCAutoString &spec,
         139                 :                  nsACString &out,
         140                 :                  mozilla::Omnijar::Type aType)
         141                 : {
         142           27242 :     nsCAutoString base;
         143           13621 :     nsresult rv = mozilla::Omnijar::GetURIString(aType, base);
         144                 :
         145           13621 :     if (NS_FAILED(rv) || !base.Length())
         146             886 :         return false;
         147                 :
         148           12735 :     if (base.Compare(spec.get(), false, base.Length()))
         149             886 :         return false;
         150                 :
         151           11849 :     out.Append("/resource/");
         152           11849 :     out.Append(baseName[aType]);
         153           11849 :     out.Append(Substring(spec, base.Length()));
         154           11849 :     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           12739 : PathifyURI(nsIURI *in, nsACString &out)
         184                 : {
         185                 :     bool equals;
         186                 :     nsresult rv;
         187           25478 :     nsCOMPtr<nsIURI> uri = in;
         188           25478 :     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           12739 :     if (NS_SUCCEEDED(in->SchemeIs("resource", &equals)) && equals) {
         193           19328 :         nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv);
         194            9664 :         NS_ENSURE_SUCCESS(rv, rv);
         195                 :
         196           19328 :         nsCOMPtr<nsIProtocolHandler> ph;
         197            9664 :         rv = ioService->GetProtocolHandler("resource", getter_AddRefs(ph));
         198            9664 :         NS_ENSURE_SUCCESS(rv, rv);
         199                 :
         200           19328 :         nsCOMPtr<nsIResProtocolHandler> irph(do_QueryInterface(ph, &rv));
         201            9664 :         NS_ENSURE_SUCCESS(rv, rv);
         202                 :
         203            9664 :         rv = irph->ResolveURI(in, spec);
         204            9664 :         NS_ENSURE_SUCCESS(rv, rv);
         205                 :
         206            9664 :         rv = ioService->NewURI(spec, nsnull, nsnull, getter_AddRefs(uri));
         207            9664 :         NS_ENSURE_SUCCESS(rv, rv);
         208                 :     } else {
         209            3075 :         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            3071 :         rv = uri->GetSpec(spec);
         220            3071 :         NS_ENSURE_SUCCESS(rv, rv);
         221                 :     }
         222                 :
         223           13621 :     if (!canonicalizeBase(spec, out, mozilla::Omnijar::GRE) &&
         224             886 :         !canonicalizeBase(spec, out, mozilla::Omnijar::APP)) {
         225             886 :         if (NS_SUCCEEDED(uri->SchemeIs("file", &equals)) && equals) {
         226            1326 :             nsCOMPtr<nsIFileURL> baseFileURL;
         227             663 :             baseFileURL = do_QueryInterface(uri, &rv);
         228             663 :             NS_ENSURE_SUCCESS(rv, rv);
         229                 :
         230            1326 :             nsCAutoString path;
         231             663 :             rv = baseFileURL->GetPath(path);
         232             663 :             NS_ENSURE_SUCCESS(rv, rv);
         233                 :
         234            1326 :             out.Append(path);
         235             223 :         } else if (NS_SUCCEEDED(uri->SchemeIs("jar", &equals)) && equals) {
         236             446 :             nsCOMPtr<nsIJARURI> jarURI = do_QueryInterface(uri, &rv);
         237             223 :             NS_ENSURE_SUCCESS(rv, rv);
         238                 :
         239             446 :             nsCOMPtr<nsIURI> jarFileURI;
         240             223 :             rv = jarURI->GetJARFile(getter_AddRefs(jarFileURI));
         241             223 :             NS_ENSURE_SUCCESS(rv, rv);
         242                 :
         243             223 :             rv = PathifyURI(jarFileURI, out);
         244             223 :             NS_ENSURE_SUCCESS(rv, rv);
         245                 :
         246             446 :             nsCAutoString path;
         247             223 :             rv = jarURI->GetJAREntry(path);
         248             223 :             NS_ENSURE_SUCCESS(rv, rv);
         249             223 :             out.Append("/");
         250             446 :             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           12735 :     return NS_OK;
         261                 : }
         262                 :
         263                 : }
         264                 : }

Generated by: LCOV version 1.7