1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/xpcom/build/Omnijar.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,169 @@ 1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- 1.5 + * This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "Omnijar.h" 1.10 + 1.11 +#include "nsDirectoryService.h" 1.12 +#include "nsDirectoryServiceDefs.h" 1.13 +#include "nsIFile.h" 1.14 +#include "nsZipArchive.h" 1.15 +#include "nsNetUtil.h" 1.16 + 1.17 +namespace mozilla { 1.18 + 1.19 +nsIFile *Omnijar::sPath[2] = { nullptr, nullptr }; 1.20 +nsZipArchive *Omnijar::sReader[2] = { nullptr, nullptr }; 1.21 +bool Omnijar::sInitialized = false; 1.22 +static bool sIsUnified = false; 1.23 +static bool sIsNested[2] = { false, false }; 1.24 + 1.25 +static const char *sProp[2] = 1.26 + { NS_GRE_DIR, NS_XPCOM_CURRENT_PROCESS_DIR }; 1.27 + 1.28 +#define SPROP(Type) ((Type == mozilla::Omnijar::GRE) ? sProp[GRE] : sProp[APP]) 1.29 + 1.30 +void 1.31 +Omnijar::CleanUpOne(Type aType) 1.32 +{ 1.33 + if (sReader[aType]) { 1.34 + sReader[aType]->CloseArchive(); 1.35 + NS_IF_RELEASE(sReader[aType]); 1.36 + } 1.37 + sReader[aType] = nullptr; 1.38 + NS_IF_RELEASE(sPath[aType]); 1.39 +} 1.40 + 1.41 +void 1.42 +Omnijar::InitOne(nsIFile *aPath, Type aType) 1.43 +{ 1.44 + nsCOMPtr<nsIFile> file; 1.45 + if (aPath) { 1.46 + file = aPath; 1.47 + } else { 1.48 + nsCOMPtr<nsIFile> dir; 1.49 + nsDirectoryService::gService->Get(SPROP(aType), NS_GET_IID(nsIFile), getter_AddRefs(dir)); 1.50 + NS_NAMED_LITERAL_CSTRING (kOmnijarName, NS_STRINGIFY(OMNIJAR_NAME)); 1.51 + if (NS_FAILED(dir->Clone(getter_AddRefs(file))) || 1.52 + NS_FAILED(file->AppendNative(kOmnijarName))) 1.53 + return; 1.54 + } 1.55 + bool isFile; 1.56 + if (NS_FAILED(file->IsFile(&isFile)) || !isFile) { 1.57 + // If we're not using an omni.jar for GRE, and we don't have an 1.58 + // omni.jar for APP, check if both directories are the same. 1.59 + if ((aType == APP) && (!sPath[GRE])) { 1.60 + nsCOMPtr<nsIFile> greDir, appDir; 1.61 + bool equals; 1.62 + nsDirectoryService::gService->Get(SPROP(GRE), NS_GET_IID(nsIFile), getter_AddRefs(greDir)); 1.63 + nsDirectoryService::gService->Get(SPROP(APP), NS_GET_IID(nsIFile), getter_AddRefs(appDir)); 1.64 + if (NS_SUCCEEDED(greDir->Equals(appDir, &equals)) && equals) 1.65 + sIsUnified = true; 1.66 + } 1.67 + return; 1.68 + } 1.69 + 1.70 + bool equals; 1.71 + if ((aType == APP) && (sPath[GRE]) && 1.72 + NS_SUCCEEDED(sPath[GRE]->Equals(file, &equals)) && equals) { 1.73 + // If we're using omni.jar on both GRE and APP and their path 1.74 + // is the same, we're in the unified case. 1.75 + sIsUnified = true; 1.76 + return; 1.77 + } 1.78 + 1.79 + nsRefPtr<nsZipArchive> zipReader = new nsZipArchive(); 1.80 + if (NS_FAILED(zipReader->OpenArchive(file))) { 1.81 + return; 1.82 + } 1.83 + 1.84 + nsRefPtr<nsZipHandle> handle; 1.85 + if (NS_SUCCEEDED(nsZipHandle::Init(zipReader, NS_STRINGIFY(OMNIJAR_NAME), getter_AddRefs(handle)))) { 1.86 + zipReader = new nsZipArchive(); 1.87 + if (NS_FAILED(zipReader->OpenArchive(handle))) 1.88 + return; 1.89 + sIsNested[aType] = true; 1.90 + } 1.91 + 1.92 + CleanUpOne(aType); 1.93 + sReader[aType] = zipReader; 1.94 + NS_IF_ADDREF(sReader[aType]); 1.95 + sPath[aType] = file; 1.96 + NS_IF_ADDREF(sPath[aType]); 1.97 +} 1.98 + 1.99 +void 1.100 +Omnijar::Init(nsIFile *aGrePath, nsIFile *aAppPath) 1.101 +{ 1.102 + InitOne(aGrePath, GRE); 1.103 + InitOne(aAppPath, APP); 1.104 + sInitialized = true; 1.105 +} 1.106 + 1.107 +void 1.108 +Omnijar::CleanUp() 1.109 +{ 1.110 + CleanUpOne(GRE); 1.111 + CleanUpOne(APP); 1.112 + sInitialized = false; 1.113 +} 1.114 + 1.115 +already_AddRefed<nsZipArchive> 1.116 +Omnijar::GetReader(nsIFile *aPath) 1.117 +{ 1.118 + NS_ABORT_IF_FALSE(IsInitialized(), "Omnijar not initialized"); 1.119 + 1.120 + bool equals; 1.121 + nsresult rv; 1.122 + 1.123 + if (sPath[GRE] && !sIsNested[GRE]) { 1.124 + rv = sPath[GRE]->Equals(aPath, &equals); 1.125 + if (NS_SUCCEEDED(rv) && equals) 1.126 + return GetReader(GRE); 1.127 + } 1.128 + if (sPath[APP] && !sIsNested[APP]) { 1.129 + rv = sPath[APP]->Equals(aPath, &equals); 1.130 + if (NS_SUCCEEDED(rv) && equals) 1.131 + return GetReader(APP); 1.132 + } 1.133 + return nullptr; 1.134 +} 1.135 + 1.136 +nsresult 1.137 +Omnijar::GetURIString(Type aType, nsACString &result) 1.138 +{ 1.139 + NS_ABORT_IF_FALSE(IsInitialized(), "Omnijar not initialized"); 1.140 + 1.141 + result.Truncate(); 1.142 + 1.143 + // Return an empty string for APP in the unified case. 1.144 + if ((aType == APP) && sIsUnified) { 1.145 + return NS_OK; 1.146 + } 1.147 + 1.148 + nsAutoCString omniJarSpec; 1.149 + if (sPath[aType]) { 1.150 + nsresult rv = NS_GetURLSpecFromActualFile(sPath[aType], omniJarSpec); 1.151 + if (NS_WARN_IF(NS_FAILED(rv))) 1.152 + return rv; 1.153 + 1.154 + result = "jar:"; 1.155 + if (sIsNested[aType]) 1.156 + result += "jar:"; 1.157 + result += omniJarSpec; 1.158 + result += "!"; 1.159 + if (sIsNested[aType]) 1.160 + result += "/" NS_STRINGIFY(OMNIJAR_NAME) "!"; 1.161 + } else { 1.162 + nsCOMPtr<nsIFile> dir; 1.163 + nsDirectoryService::gService->Get(SPROP(aType), NS_GET_IID(nsIFile), getter_AddRefs(dir)); 1.164 + nsresult rv = NS_GetURLSpecFromActualFile(dir, result); 1.165 + if (NS_WARN_IF(NS_FAILED(rv))) 1.166 + return rv; 1.167 + } 1.168 + result += "/"; 1.169 + return NS_OK; 1.170 +} 1.171 + 1.172 +} /* namespace mozilla */