xpcom/build/FileLocation.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 #include "FileLocation.h"
michael@0 6 #include "nsZipArchive.h"
michael@0 7 #include "nsURLHelper.h"
michael@0 8
michael@0 9 namespace mozilla {
michael@0 10
michael@0 11 FileLocation::FileLocation()
michael@0 12 {
michael@0 13 }
michael@0 14
michael@0 15 FileLocation::~FileLocation()
michael@0 16 {
michael@0 17 }
michael@0 18
michael@0 19 FileLocation::FileLocation(nsIFile* file)
michael@0 20 {
michael@0 21 Init(file);
michael@0 22 }
michael@0 23
michael@0 24 FileLocation::FileLocation(nsIFile* file, const char *path)
michael@0 25 {
michael@0 26 Init(file, path);
michael@0 27 }
michael@0 28
michael@0 29 FileLocation::FileLocation(const FileLocation &file, const char *path)
michael@0 30 {
michael@0 31 if (file.IsZip()) {
michael@0 32 if (file.mBaseFile) {
michael@0 33 Init(file.mBaseFile, file.mPath.get());
michael@0 34 } else {
michael@0 35 Init(file.mBaseZip, file.mPath.get());
michael@0 36 }
michael@0 37 if (path) {
michael@0 38 int32_t i = mPath.RFindChar('/');
michael@0 39 if (kNotFound == i) {
michael@0 40 mPath.Truncate(0);
michael@0 41 } else {
michael@0 42 mPath.Truncate(i + 1);
michael@0 43 }
michael@0 44 mPath += path;
michael@0 45 }
michael@0 46 } else {
michael@0 47 if (path) {
michael@0 48 nsCOMPtr<nsIFile> cfile;
michael@0 49 file.mBaseFile->GetParent(getter_AddRefs(cfile));
michael@0 50
michael@0 51 #if defined(XP_WIN)
michael@0 52 nsAutoCString pathStr(path);
michael@0 53 char *p;
michael@0 54 uint32_t len = pathStr.GetMutableData(&p);
michael@0 55 for (; len; ++p, --len) {
michael@0 56 if ('/' == *p) {
michael@0 57 *p = '\\';
michael@0 58 }
michael@0 59 }
michael@0 60 cfile->AppendRelativeNativePath(pathStr);
michael@0 61 #else
michael@0 62 cfile->AppendRelativeNativePath(nsDependentCString(path));
michael@0 63 #endif
michael@0 64 Init(cfile);
michael@0 65 } else {
michael@0 66 Init(file.mBaseFile);
michael@0 67 }
michael@0 68 }
michael@0 69 }
michael@0 70
michael@0 71 void
michael@0 72 FileLocation::Init(nsIFile* file)
michael@0 73 {
michael@0 74 mBaseZip = nullptr;
michael@0 75 mBaseFile = file;
michael@0 76 mPath.Truncate();
michael@0 77 }
michael@0 78
michael@0 79 void
michael@0 80 FileLocation::Init(nsIFile* file, const char* path)
michael@0 81 {
michael@0 82 mBaseZip = nullptr;
michael@0 83 mBaseFile = file;
michael@0 84 mPath = path;
michael@0 85 }
michael@0 86
michael@0 87 void
michael@0 88 FileLocation::Init(nsZipArchive* zip, const char* path)
michael@0 89 {
michael@0 90 mBaseZip = zip;
michael@0 91 mBaseFile = nullptr;
michael@0 92 mPath = path;
michael@0 93 }
michael@0 94
michael@0 95 void
michael@0 96 FileLocation::GetURIString(nsACString &result) const
michael@0 97 {
michael@0 98 if (mBaseFile) {
michael@0 99 net_GetURLSpecFromActualFile(mBaseFile, result);
michael@0 100 } else if (mBaseZip) {
michael@0 101 nsRefPtr<nsZipHandle> handler = mBaseZip->GetFD();
michael@0 102 handler->mFile.GetURIString(result);
michael@0 103 }
michael@0 104 if (IsZip()) {
michael@0 105 result.Insert("jar:", 0);
michael@0 106 result += "!/";
michael@0 107 result += mPath;
michael@0 108 }
michael@0 109 }
michael@0 110
michael@0 111 already_AddRefed<nsIFile>
michael@0 112 FileLocation::GetBaseFile()
michael@0 113 {
michael@0 114 if (IsZip() && mBaseZip) {
michael@0 115 nsRefPtr<nsZipHandle> handler = mBaseZip->GetFD();
michael@0 116 if (handler)
michael@0 117 return handler->mFile.GetBaseFile();
michael@0 118 return nullptr;
michael@0 119 }
michael@0 120
michael@0 121 nsCOMPtr<nsIFile> file = mBaseFile;
michael@0 122 return file.forget();
michael@0 123 }
michael@0 124
michael@0 125 bool
michael@0 126 FileLocation::Equals(const FileLocation &file) const
michael@0 127 {
michael@0 128 if (mPath != file.mPath)
michael@0 129 return false;
michael@0 130
michael@0 131 if (mBaseFile && file.mBaseFile) {
michael@0 132 bool eq;
michael@0 133 return NS_SUCCEEDED(mBaseFile->Equals(file.mBaseFile, &eq)) && eq;
michael@0 134 }
michael@0 135
michael@0 136 const FileLocation *a = this, *b = &file;
michael@0 137 if (a->mBaseZip) {
michael@0 138 nsRefPtr<nsZipHandle> handler = a->mBaseZip->GetFD();
michael@0 139 a = &handler->mFile;
michael@0 140 }
michael@0 141 if (b->mBaseZip) {
michael@0 142 nsRefPtr<nsZipHandle> handler = b->mBaseZip->GetFD();
michael@0 143 b = &handler->mFile;
michael@0 144 }
michael@0 145 return a->Equals(*b);
michael@0 146 }
michael@0 147
michael@0 148 nsresult
michael@0 149 FileLocation::GetData(Data &data)
michael@0 150 {
michael@0 151 if (!IsZip()) {
michael@0 152 return mBaseFile->OpenNSPRFileDesc(PR_RDONLY, 0444, &data.mFd.rwget());
michael@0 153 }
michael@0 154 data.mZip = mBaseZip;
michael@0 155 if (!data.mZip) {
michael@0 156 data.mZip = new nsZipArchive();
michael@0 157 data.mZip->OpenArchive(mBaseFile);
michael@0 158 }
michael@0 159 data.mItem = data.mZip->GetItem(mPath.get());
michael@0 160 if (data.mItem)
michael@0 161 return NS_OK;
michael@0 162 return NS_ERROR_FILE_UNRECOGNIZED_PATH;
michael@0 163 }
michael@0 164
michael@0 165 nsresult
michael@0 166 FileLocation::Data::GetSize(uint32_t *result)
michael@0 167 {
michael@0 168 if (mFd) {
michael@0 169 PRFileInfo64 fileInfo;
michael@0 170 if (PR_SUCCESS != PR_GetOpenFileInfo64(mFd, &fileInfo))
michael@0 171 return NS_ErrorAccordingToNSPR();
michael@0 172
michael@0 173 if (fileInfo.size > int64_t(UINT32_MAX))
michael@0 174 return NS_ERROR_FILE_TOO_BIG;
michael@0 175
michael@0 176 *result = fileInfo.size;
michael@0 177 return NS_OK;
michael@0 178 } else if (mItem) {
michael@0 179 *result = mItem->RealSize();
michael@0 180 return NS_OK;
michael@0 181 }
michael@0 182 return NS_ERROR_NOT_INITIALIZED;
michael@0 183 }
michael@0 184
michael@0 185 nsresult
michael@0 186 FileLocation::Data::Copy(char *buf, uint32_t len)
michael@0 187 {
michael@0 188 if (mFd) {
michael@0 189 for (uint32_t totalRead = 0; totalRead < len; ) {
michael@0 190 int32_t read = PR_Read(mFd, buf + totalRead, XPCOM_MIN(len - totalRead, uint32_t(INT32_MAX)));
michael@0 191 if (read < 0)
michael@0 192 return NS_ErrorAccordingToNSPR();
michael@0 193 totalRead += read;
michael@0 194 }
michael@0 195 return NS_OK;
michael@0 196 } else if (mItem) {
michael@0 197 nsZipCursor cursor(mItem, mZip, reinterpret_cast<uint8_t *>(buf), len, true);
michael@0 198 uint32_t readLen;
michael@0 199 cursor.Copy(&readLen);
michael@0 200 return (readLen == len) ? NS_OK : NS_ERROR_FILE_CORRUPTED;
michael@0 201 }
michael@0 202 return NS_ERROR_NOT_INITIALIZED;
michael@0 203 }
michael@0 204
michael@0 205 } /* namespace mozilla */

mercurial