Bug 1850713: remove duplicated setting of early hint preloader id in `ScriptLoader...
[gecko.git] / xpcom / build / FileLocation.cpp
blobbb090c2b94d0c45357ab3c6381cab3982d00ee87
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 "FileLocation.h"
8 #include "nsZipArchive.h"
9 #include "nsURLHelper.h"
11 namespace mozilla {
13 FileLocation::FileLocation() = default;
15 FileLocation::~FileLocation() = default;
17 FileLocation::FileLocation(nsIFile* aFile) { Init(aFile); }
19 FileLocation::FileLocation(nsIFile* aFile, const char* aPath) {
20 Init(aFile, aPath);
23 FileLocation::FileLocation(nsZipArchive* aZip, const char* aPath) {
24 Init(aZip, aPath);
27 FileLocation::FileLocation(const FileLocation& aOther)
29 = default;
31 FileLocation::FileLocation(FileLocation&& aOther)
32 : mBaseFile(std::move(aOther.mBaseFile)),
33 mBaseZip(std::move(aOther.mBaseZip)),
34 mPath(std::move(aOther.mPath)) {
35 aOther.mPath.Truncate();
38 FileLocation::FileLocation(const FileLocation& aFile, const char* aPath) {
39 if (aFile.IsZip()) {
40 if (aFile.mBaseFile) {
41 Init(aFile.mBaseFile, aFile.mPath.get());
42 } else {
43 Init(aFile.mBaseZip, aFile.mPath.get());
45 if (aPath) {
46 int32_t i = mPath.RFindChar('/');
47 if (kNotFound == i) {
48 mPath.Truncate(0);
49 } else {
50 mPath.Truncate(i + 1);
52 mPath += aPath;
54 } else {
55 if (aPath) {
56 nsCOMPtr<nsIFile> cfile;
57 aFile.mBaseFile->GetParent(getter_AddRefs(cfile));
59 #if defined(XP_WIN)
60 nsAutoCString pathStr(aPath);
61 char* p;
62 uint32_t len = pathStr.GetMutableData(&p);
63 for (; len; ++p, --len) {
64 if ('/' == *p) {
65 *p = '\\';
68 cfile->AppendRelativeNativePath(pathStr);
69 #else
70 cfile->AppendRelativeNativePath(nsDependentCString(aPath));
71 #endif
72 Init(cfile);
73 } else {
74 Init(aFile.mBaseFile);
79 void FileLocation::Init(nsIFile* aFile) {
80 mBaseZip = nullptr;
81 mBaseFile = aFile;
82 mPath.Truncate();
85 void FileLocation::Init(nsIFile* aFile, const char* aPath) {
86 mBaseZip = nullptr;
87 mBaseFile = aFile;
88 mPath = aPath;
91 void FileLocation::Init(nsZipArchive* aZip, const char* aPath) {
92 mBaseZip = aZip;
93 mBaseFile = nullptr;
94 mPath = aPath;
97 void FileLocation::GetURIString(nsACString& aResult) const {
98 if (mBaseFile) {
99 net_GetURLSpecFromActualFile(mBaseFile, aResult);
100 } else if (mBaseZip) {
101 RefPtr<nsZipHandle> handler = mBaseZip->GetFD();
102 handler->mFile.GetURIString(aResult);
104 if (IsZip()) {
105 aResult.InsertLiteral("jar:", 0);
106 aResult += "!/";
107 aResult += mPath;
111 already_AddRefed<nsIFile> FileLocation::GetBaseFile() {
112 if (IsZip() && mBaseZip) {
113 RefPtr<nsZipHandle> handler = mBaseZip->GetFD();
114 if (handler) {
115 return handler->mFile.GetBaseFile();
117 return nullptr;
120 nsCOMPtr<nsIFile> file = mBaseFile;
121 return file.forget();
124 bool FileLocation::Equals(const FileLocation& aFile) const {
125 if (mPath != aFile.mPath) {
126 return false;
129 if (mBaseFile && aFile.mBaseFile) {
130 bool eq;
131 return NS_SUCCEEDED(mBaseFile->Equals(aFile.mBaseFile, &eq)) && eq;
134 const FileLocation* a = this;
135 const FileLocation* b = &aFile;
136 if (a->mBaseZip) {
137 RefPtr<nsZipHandle> handler = a->mBaseZip->GetFD();
138 a = &handler->mFile;
140 if (b->mBaseZip) {
141 RefPtr<nsZipHandle> handler = b->mBaseZip->GetFD();
142 b = &handler->mFile;
145 return a->Equals(*b);
148 nsresult FileLocation::GetData(Data& aData) {
149 if (!IsZip()) {
150 return mBaseFile->OpenNSPRFileDesc(PR_RDONLY, 0444, &aData.mFd.rwget());
152 aData.mZip = mBaseZip;
153 if (!aData.mZip) {
154 // this can return nullptr
155 aData.mZip = nsZipArchive::OpenArchive(mBaseFile);
157 if (aData.mZip) {
158 aData.mItem = aData.mZip->GetItem(mPath.get());
159 if (aData.mItem) {
160 return NS_OK;
163 return NS_ERROR_FILE_UNRECOGNIZED_PATH;
166 nsresult FileLocation::Data::GetSize(uint32_t* aResult) {
167 if (mFd) {
168 PRFileInfo64 fileInfo;
169 if (PR_SUCCESS != PR_GetOpenFileInfo64(mFd, &fileInfo)) {
170 return NS_ErrorAccordingToNSPR();
173 if (fileInfo.size > int64_t(UINT32_MAX)) {
174 return NS_ERROR_FILE_TOO_BIG;
177 *aResult = fileInfo.size;
178 return NS_OK;
180 if (mItem) {
181 *aResult = mItem->RealSize();
182 return NS_OK;
184 return NS_ERROR_NOT_INITIALIZED;
187 nsresult FileLocation::Data::Copy(char* aBuf, uint32_t aLen) {
188 if (mFd) {
189 for (uint32_t totalRead = 0; totalRead < aLen;) {
190 int32_t read = PR_Read(mFd, aBuf + totalRead,
191 XPCOM_MIN(aLen - totalRead, uint32_t(INT32_MAX)));
192 if (read < 0) {
193 return NS_ErrorAccordingToNSPR();
195 totalRead += read;
197 return NS_OK;
199 if (mItem) {
200 nsZipCursor cursor(mItem, mZip, reinterpret_cast<uint8_t*>(aBuf), aLen,
201 true);
202 uint32_t readLen;
203 cursor.Copy(&readLen);
204 if (readLen != aLen) {
205 return NS_ERROR_FILE_CORRUPTED;
207 return NS_OK;
209 return NS_ERROR_NOT_INITIALIZED;
212 } /* namespace mozilla */