diff -r 000000000000 -r 6474c204b198 xpcom/build/Omnijar.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xpcom/build/Omnijar.cpp Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,169 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "Omnijar.h" + +#include "nsDirectoryService.h" +#include "nsDirectoryServiceDefs.h" +#include "nsIFile.h" +#include "nsZipArchive.h" +#include "nsNetUtil.h" + +namespace mozilla { + +nsIFile *Omnijar::sPath[2] = { nullptr, nullptr }; +nsZipArchive *Omnijar::sReader[2] = { nullptr, nullptr }; +bool Omnijar::sInitialized = false; +static bool sIsUnified = false; +static bool sIsNested[2] = { false, false }; + +static const char *sProp[2] = + { NS_GRE_DIR, NS_XPCOM_CURRENT_PROCESS_DIR }; + +#define SPROP(Type) ((Type == mozilla::Omnijar::GRE) ? sProp[GRE] : sProp[APP]) + +void +Omnijar::CleanUpOne(Type aType) +{ + if (sReader[aType]) { + sReader[aType]->CloseArchive(); + NS_IF_RELEASE(sReader[aType]); + } + sReader[aType] = nullptr; + NS_IF_RELEASE(sPath[aType]); +} + +void +Omnijar::InitOne(nsIFile *aPath, Type aType) +{ + nsCOMPtr file; + if (aPath) { + file = aPath; + } else { + nsCOMPtr dir; + nsDirectoryService::gService->Get(SPROP(aType), NS_GET_IID(nsIFile), getter_AddRefs(dir)); + NS_NAMED_LITERAL_CSTRING (kOmnijarName, NS_STRINGIFY(OMNIJAR_NAME)); + if (NS_FAILED(dir->Clone(getter_AddRefs(file))) || + NS_FAILED(file->AppendNative(kOmnijarName))) + return; + } + bool isFile; + if (NS_FAILED(file->IsFile(&isFile)) || !isFile) { + // If we're not using an omni.jar for GRE, and we don't have an + // omni.jar for APP, check if both directories are the same. + if ((aType == APP) && (!sPath[GRE])) { + nsCOMPtr greDir, appDir; + bool equals; + nsDirectoryService::gService->Get(SPROP(GRE), NS_GET_IID(nsIFile), getter_AddRefs(greDir)); + nsDirectoryService::gService->Get(SPROP(APP), NS_GET_IID(nsIFile), getter_AddRefs(appDir)); + if (NS_SUCCEEDED(greDir->Equals(appDir, &equals)) && equals) + sIsUnified = true; + } + return; + } + + bool equals; + if ((aType == APP) && (sPath[GRE]) && + NS_SUCCEEDED(sPath[GRE]->Equals(file, &equals)) && equals) { + // If we're using omni.jar on both GRE and APP and their path + // is the same, we're in the unified case. + sIsUnified = true; + return; + } + + nsRefPtr zipReader = new nsZipArchive(); + if (NS_FAILED(zipReader->OpenArchive(file))) { + return; + } + + nsRefPtr handle; + if (NS_SUCCEEDED(nsZipHandle::Init(zipReader, NS_STRINGIFY(OMNIJAR_NAME), getter_AddRefs(handle)))) { + zipReader = new nsZipArchive(); + if (NS_FAILED(zipReader->OpenArchive(handle))) + return; + sIsNested[aType] = true; + } + + CleanUpOne(aType); + sReader[aType] = zipReader; + NS_IF_ADDREF(sReader[aType]); + sPath[aType] = file; + NS_IF_ADDREF(sPath[aType]); +} + +void +Omnijar::Init(nsIFile *aGrePath, nsIFile *aAppPath) +{ + InitOne(aGrePath, GRE); + InitOne(aAppPath, APP); + sInitialized = true; +} + +void +Omnijar::CleanUp() +{ + CleanUpOne(GRE); + CleanUpOne(APP); + sInitialized = false; +} + +already_AddRefed +Omnijar::GetReader(nsIFile *aPath) +{ + NS_ABORT_IF_FALSE(IsInitialized(), "Omnijar not initialized"); + + bool equals; + nsresult rv; + + if (sPath[GRE] && !sIsNested[GRE]) { + rv = sPath[GRE]->Equals(aPath, &equals); + if (NS_SUCCEEDED(rv) && equals) + return GetReader(GRE); + } + if (sPath[APP] && !sIsNested[APP]) { + rv = sPath[APP]->Equals(aPath, &equals); + if (NS_SUCCEEDED(rv) && equals) + return GetReader(APP); + } + return nullptr; +} + +nsresult +Omnijar::GetURIString(Type aType, nsACString &result) +{ + NS_ABORT_IF_FALSE(IsInitialized(), "Omnijar not initialized"); + + result.Truncate(); + + // Return an empty string for APP in the unified case. + if ((aType == APP) && sIsUnified) { + return NS_OK; + } + + nsAutoCString omniJarSpec; + if (sPath[aType]) { + nsresult rv = NS_GetURLSpecFromActualFile(sPath[aType], omniJarSpec); + if (NS_WARN_IF(NS_FAILED(rv))) + return rv; + + result = "jar:"; + if (sIsNested[aType]) + result += "jar:"; + result += omniJarSpec; + result += "!"; + if (sIsNested[aType]) + result += "/" NS_STRINGIFY(OMNIJAR_NAME) "!"; + } else { + nsCOMPtr dir; + nsDirectoryService::gService->Get(SPROP(aType), NS_GET_IID(nsIFile), getter_AddRefs(dir)); + nsresult rv = NS_GetURLSpecFromActualFile(dir, result); + if (NS_WARN_IF(NS_FAILED(rv))) + return rv; + } + result += "/"; + return NS_OK; +} + +} /* namespace mozilla */