bool File::setOpenMode(OpenMode openMode) { _mutex.lock(); if(_openMode == 0 || openMode == _openMode) return true; if(isOpen()) { FileImpl *impl = new FileImpl; if(!impl->open(_filePath, openMode)) { delete impl; return false; } _impl->close(); delete _impl; _impl = impl; } _openMode = openMode; return true; }
bool File::setPath(const String &filePath) { _mutex.lock(); if(isOpen()) { if(filePath.isEmpty()) return false; FileImpl *impl = new FileImpl; if(!impl->open(filePath, _openMode)) { delete _impl; return false; } _impl->close(); delete _impl; _impl = impl; } _filePath = absolutePath(filePath); return true; }
nsresult MultipartFileImpl::GetInternalStream(nsIInputStream** aStream) { nsresult rv; *aStream = nullptr; nsCOMPtr<nsIMultiplexInputStream> stream = do_CreateInstance("@mozilla.org/io/multiplex-input-stream;1"); NS_ENSURE_TRUE(stream, NS_ERROR_FAILURE); uint32_t i; for (i = 0; i < mBlobImpls.Length(); i++) { nsCOMPtr<nsIInputStream> scratchStream; FileImpl* blobImpl = mBlobImpls.ElementAt(i).get(); rv = blobImpl->GetInternalStream(getter_AddRefs(scratchStream)); NS_ENSURE_SUCCESS(rv, rv); rv = stream->AppendStream(scratchStream); NS_ENSURE_SUCCESS(rv, rv); } stream.forget(aStream); return NS_OK; }
void MultipartFileImpl::GetMozFullPathInternal(nsAString& aFilename, ErrorResult& aRv) { if (!mIsFromNsIFile || mBlobImpls.Length() == 0) { FileImplBase::GetMozFullPathInternal(aFilename, aRv); return; } FileImpl* blobImpl = mBlobImpls.ElementAt(0).get(); if (!blobImpl) { FileImplBase::GetMozFullPathInternal(aFilename, aRv); return; } blobImpl->GetMozFullPathInternal(aFilename, aRv); }
already_AddRefed<FileImpl> MultipartFileImpl::CreateSlice(uint64_t aStart, uint64_t aLength, const nsAString& aContentType, ErrorResult& aRv) { // If we clamped to nothing we create an empty blob nsTArray<nsRefPtr<FileImpl>> blobImpls; uint64_t length = aLength; uint64_t skipStart = aStart; // Prune the list of blobs if we can uint32_t i; for (i = 0; length && skipStart && i < mBlobImpls.Length(); i++) { FileImpl* blobImpl = mBlobImpls[i].get(); uint64_t l = blobImpl->GetSize(aRv); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } if (skipStart < l) { uint64_t upperBound = std::min<uint64_t>(l - skipStart, length); nsRefPtr<FileImpl> firstBlobImpl = blobImpl->CreateSlice(skipStart, upperBound, aContentType, aRv); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } // Avoid wrapping a single blob inside an MultipartFileImpl if (length == upperBound) { return firstBlobImpl.forget(); } blobImpls.AppendElement(firstBlobImpl); length -= upperBound; i++; break; } skipStart -= l; } // Now append enough blobs until we're done for (; length && i < mBlobImpls.Length(); i++) { FileImpl* blobImpl = mBlobImpls[i].get(); uint64_t l = blobImpl->GetSize(aRv); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } if (length < l) { nsRefPtr<FileImpl> lastBlobImpl = blobImpl->CreateSlice(0, length, aContentType, aRv); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } blobImpls.AppendElement(lastBlobImpl); } else { blobImpls.AppendElement(blobImpl); } length -= std::min<uint64_t>(l, length); } // we can create our blob now nsRefPtr<FileImpl> impl = new MultipartFileImpl(blobImpls, aContentType); return impl.forget(); }
nsresult FetchDriver::BasicFetch() { nsAutoCString url; mRequest->GetURL(url); nsCOMPtr<nsIURI> uri; nsresult rv = NS_NewURI(getter_AddRefs(uri), url, nullptr, nullptr); if (NS_WARN_IF(NS_FAILED(rv))) { FailWithNetworkError(); return rv; } nsAutoCString scheme; rv = uri->GetScheme(scheme); if (NS_WARN_IF(NS_FAILED(rv))) { FailWithNetworkError(); return rv; } if (scheme.LowerCaseEqualsLiteral("about")) { if (url.EqualsLiteral("about:blank")) { nsRefPtr<InternalResponse> response = new InternalResponse(200, NS_LITERAL_CSTRING("OK")); ErrorResult result; response->Headers()->Append(NS_LITERAL_CSTRING("content-type"), NS_LITERAL_CSTRING("text/html;charset=utf-8"), result); MOZ_ASSERT(!result.Failed()); nsCOMPtr<nsIInputStream> body; rv = NS_NewCStringInputStream(getter_AddRefs(body), EmptyCString()); if (NS_WARN_IF(NS_FAILED(rv))) { FailWithNetworkError(); return rv; } response->SetBody(body); BeginResponse(response); return SucceedWithResponse(); } return FailWithNetworkError(); } if (scheme.LowerCaseEqualsLiteral("blob")) { nsRefPtr<FileImpl> blobImpl; rv = NS_GetBlobForBlobURI(uri, getter_AddRefs(blobImpl)); FileImpl* blob = static_cast<FileImpl*>(blobImpl.get()); if (NS_WARN_IF(NS_FAILED(rv))) { FailWithNetworkError(); return rv; } nsRefPtr<InternalResponse> response = new InternalResponse(200, NS_LITERAL_CSTRING("OK")); { ErrorResult result; uint64_t size = blob->GetSize(result); if (NS_WARN_IF(result.Failed())) { FailWithNetworkError(); return result.ErrorCode(); } nsAutoString sizeStr; sizeStr.AppendInt(size); response->Headers()->Append(NS_LITERAL_CSTRING("Content-Length"), NS_ConvertUTF16toUTF8(sizeStr), result); if (NS_WARN_IF(result.Failed())) { FailWithNetworkError(); return result.ErrorCode(); } nsAutoString type; blob->GetType(type); response->Headers()->Append(NS_LITERAL_CSTRING("Content-Type"), NS_ConvertUTF16toUTF8(type), result); if (NS_WARN_IF(result.Failed())) { FailWithNetworkError(); return result.ErrorCode(); } } nsCOMPtr<nsIInputStream> stream; rv = blob->GetInternalStream(getter_AddRefs(stream)); if (NS_WARN_IF(NS_FAILED(rv))) { FailWithNetworkError(); return rv; } response->SetBody(stream); BeginResponse(response); return SucceedWithResponse(); } if (scheme.LowerCaseEqualsLiteral("data")) { nsAutoCString method; mRequest->GetMethod(method); if (method.LowerCaseEqualsASCII("get")) { // Use nsDataHandler directly so that we can extract the content type. // XXX(nsm): Is there a way to acquire the charset without such tight // coupling with the DataHandler? nsIProtocolHandler does not provide // anything similar. nsAutoCString contentType, contentCharset, dataBuffer, hashRef; bool isBase64; rv = nsDataHandler::ParseURI(url, contentType, contentCharset, isBase64, dataBuffer, hashRef); if (NS_SUCCEEDED(rv)) { ErrorResult result; nsRefPtr<InternalResponse> response = new InternalResponse(200, NS_LITERAL_CSTRING("OK")); if (!contentCharset.IsEmpty()) { contentType.Append(";charset="); contentType.Append(contentCharset); } response->Headers()->Append(NS_LITERAL_CSTRING("Content-Type"), contentType, result); if (!result.Failed()) { nsCOMPtr<nsIInputStream> stream; rv = NS_NewCStringInputStream(getter_AddRefs(stream), dataBuffer); if (NS_SUCCEEDED(rv)) { response->SetBody(stream); BeginResponse(response); return SucceedWithResponse(); } } } } return FailWithNetworkError(); } if (scheme.LowerCaseEqualsLiteral("file")) { } else if (scheme.LowerCaseEqualsLiteral("http") || scheme.LowerCaseEqualsLiteral("https")) { return HttpFetch(); } return FailWithNetworkError(); }