Bug 1732219 - Add API for fetching the preview image. r=geckoview-reviewers,agi,mconley
[gecko.git] / xpcom / build / Omnijar.cpp
blob36a8a511cbeb097c402323a289255148614e9b81
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "Omnijar.h"
9 #include "nsDirectoryService.h"
10 #include "nsDirectoryServiceDefs.h"
11 #include "nsIFile.h"
12 #include "nsZipArchive.h"
13 #include "nsNetUtil.h"
15 namespace mozilla {
17 StaticRefPtr<nsIFile> Omnijar::sPath[2];
18 StaticRefPtr<nsZipArchive> Omnijar::sReader[2];
19 StaticRefPtr<nsZipArchive> Omnijar::sOuterReader[2];
20 bool Omnijar::sInitialized = false;
21 bool Omnijar::sIsUnified = false;
23 static const char* sProp[2] = {NS_GRE_DIR, NS_XPCOM_CURRENT_PROCESS_DIR};
25 #define SPROP(Type) ((Type == mozilla::Omnijar::GRE) ? sProp[GRE] : sProp[APP])
27 void Omnijar::CleanUpOne(Type aType) {
28 if (sReader[aType]) {
29 sReader[aType]->CloseArchive();
30 sReader[aType] = nullptr;
32 if (sOuterReader[aType]) {
33 sOuterReader[aType]->CloseArchive();
34 sOuterReader[aType] = nullptr;
36 sPath[aType] = nullptr;
39 void Omnijar::InitOne(nsIFile* aPath, Type aType) {
40 nsCOMPtr<nsIFile> file;
41 if (aPath) {
42 file = aPath;
43 } else {
44 nsCOMPtr<nsIFile> dir;
45 nsDirectoryService::gService->Get(SPROP(aType), NS_GET_IID(nsIFile),
46 getter_AddRefs(dir));
47 constexpr auto kOmnijarName = nsLiteralCString{MOZ_STRINGIFY(OMNIJAR_NAME)};
48 if (NS_FAILED(dir->Clone(getter_AddRefs(file))) ||
49 NS_FAILED(file->AppendNative(kOmnijarName))) {
50 return;
53 bool isFile;
54 if (NS_FAILED(file->IsFile(&isFile)) || !isFile) {
55 // If we're not using an omni.jar for GRE, and we don't have an
56 // omni.jar for APP, check if both directories are the same.
57 if ((aType == APP) && (!sPath[GRE])) {
58 nsCOMPtr<nsIFile> greDir, appDir;
59 bool equals;
60 nsDirectoryService::gService->Get(sProp[GRE], NS_GET_IID(nsIFile),
61 getter_AddRefs(greDir));
62 nsDirectoryService::gService->Get(sProp[APP], NS_GET_IID(nsIFile),
63 getter_AddRefs(appDir));
64 if (NS_SUCCEEDED(greDir->Equals(appDir, &equals)) && equals) {
65 sIsUnified = true;
68 return;
71 bool equals;
72 if ((aType == APP) && (sPath[GRE]) &&
73 NS_SUCCEEDED(sPath[GRE]->Equals(file, &equals)) && equals) {
74 // If we're using omni.jar on both GRE and APP and their path
75 // is the same, we're in the unified case.
76 sIsUnified = true;
77 return;
80 RefPtr<nsZipArchive> zipReader = new nsZipArchive();
81 if (NS_FAILED(zipReader->OpenArchive(file))) {
82 return;
85 RefPtr<nsZipArchive> outerReader;
86 RefPtr<nsZipHandle> handle;
87 if (NS_SUCCEEDED(nsZipHandle::Init(zipReader, MOZ_STRINGIFY(OMNIJAR_NAME),
88 getter_AddRefs(handle)))) {
89 outerReader = zipReader;
90 zipReader = new nsZipArchive();
91 if (NS_FAILED(zipReader->OpenArchive(handle))) {
92 return;
96 CleanUpOne(aType);
97 sReader[aType] = zipReader;
98 sOuterReader[aType] = outerReader;
99 sPath[aType] = file;
102 void Omnijar::Init(nsIFile* aGrePath, nsIFile* aAppPath) {
103 InitOne(aGrePath, GRE);
104 InitOne(aAppPath, APP);
105 sInitialized = true;
108 void Omnijar::CleanUp() {
109 CleanUpOne(GRE);
110 CleanUpOne(APP);
111 sInitialized = false;
114 already_AddRefed<nsZipArchive> Omnijar::GetReader(nsIFile* aPath) {
115 MOZ_ASSERT(IsInitialized(), "Omnijar not initialized");
117 bool equals;
118 nsresult rv;
120 if (sPath[GRE]) {
121 rv = sPath[GRE]->Equals(aPath, &equals);
122 if (NS_SUCCEEDED(rv) && equals) {
123 return IsNested(GRE) ? GetOuterReader(GRE) : GetReader(GRE);
126 if (sPath[APP]) {
127 rv = sPath[APP]->Equals(aPath, &equals);
128 if (NS_SUCCEEDED(rv) && equals) {
129 return IsNested(APP) ? GetOuterReader(APP) : GetReader(APP);
132 return nullptr;
135 already_AddRefed<nsZipArchive> Omnijar::GetInnerReader(
136 nsIFile* aPath, const nsACString& aEntry) {
137 MOZ_ASSERT(IsInitialized(), "Omnijar not initialized");
139 if (!aEntry.EqualsLiteral(MOZ_STRINGIFY(OMNIJAR_NAME))) {
140 return nullptr;
143 bool equals;
144 nsresult rv;
146 if (sPath[GRE]) {
147 rv = sPath[GRE]->Equals(aPath, &equals);
148 if (NS_SUCCEEDED(rv) && equals) {
149 return IsNested(GRE) ? GetReader(GRE) : nullptr;
152 if (sPath[APP]) {
153 rv = sPath[APP]->Equals(aPath, &equals);
154 if (NS_SUCCEEDED(rv) && equals) {
155 return IsNested(APP) ? GetReader(APP) : nullptr;
158 return nullptr;
161 nsresult Omnijar::GetURIString(Type aType, nsACString& aResult) {
162 MOZ_ASSERT(IsInitialized(), "Omnijar not initialized");
164 aResult.Truncate();
166 // Return an empty string for APP in the unified case.
167 if ((aType == APP) && sIsUnified) {
168 return NS_OK;
171 nsAutoCString omniJarSpec;
172 if (sPath[aType]) {
173 nsresult rv = NS_GetURLSpecFromActualFile(sPath[aType], omniJarSpec);
174 if (NS_WARN_IF(NS_FAILED(rv))) {
175 return rv;
178 aResult = "jar:";
179 if (IsNested(aType)) {
180 aResult += "jar:";
182 aResult += omniJarSpec;
183 aResult += "!";
184 if (IsNested(aType)) {
185 aResult += "/" MOZ_STRINGIFY(OMNIJAR_NAME) "!";
187 } else {
188 nsCOMPtr<nsIFile> dir;
189 nsDirectoryService::gService->Get(SPROP(aType), NS_GET_IID(nsIFile),
190 getter_AddRefs(dir));
191 nsresult rv = NS_GetURLSpecFromActualFile(dir, aResult);
192 if (NS_WARN_IF(NS_FAILED(rv))) {
193 return rv;
196 aResult += "/";
197 return NS_OK;
200 } /* namespace mozilla */