michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* vim: set ts=2 et sw=2 tw=80: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this file, michael@0: * You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "MetadataHelper.h" michael@0: michael@0: #include "LockedFile.h" michael@0: michael@0: USING_FILE_NAMESPACE michael@0: michael@0: nsresult michael@0: MetadataHelper::DoAsyncRun(nsISupports* aStream) michael@0: { michael@0: bool readWrite = mLockedFile->mMode == FileMode::Readwrite; michael@0: michael@0: nsRefPtr getter = michael@0: new AsyncMetadataGetter(aStream, mParams, readWrite); michael@0: michael@0: nsresult rv = getter->AsyncWork(this, nullptr); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult michael@0: MetadataHelper::GetSuccessResult(JSContext* aCx, michael@0: JS::MutableHandle aVal) michael@0: { michael@0: JS::Rooted obj(aCx, JS_NewObject(aCx, nullptr, JS::NullPtr(), michael@0: JS::NullPtr())); michael@0: NS_ENSURE_TRUE(obj, NS_ERROR_OUT_OF_MEMORY); michael@0: michael@0: if (mParams->SizeRequested()) { michael@0: JS::Rooted val(aCx, JS_NumberValue(mParams->Size())); michael@0: michael@0: if (!JS_DefineProperty(aCx, obj, "size", val, JSPROP_ENUMERATE)) { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: } michael@0: michael@0: if (mParams->LastModifiedRequested()) { michael@0: double msec = mParams->LastModified(); michael@0: JSObject *date = JS_NewDateObjectMsec(aCx, msec); michael@0: NS_ENSURE_TRUE(date, NS_ERROR_OUT_OF_MEMORY); michael@0: michael@0: JS::Rooted dateRoot(aCx, JS::ObjectValue(*date)); michael@0: if (!JS_DefineProperty(aCx, obj, "lastModified", dateRoot, michael@0: JSPROP_ENUMERATE)) { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: } michael@0: michael@0: aVal.setObject(*obj); michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult michael@0: MetadataHelper::AsyncMetadataGetter::DoStreamWork(nsISupports* aStream) michael@0: { michael@0: nsresult rv; michael@0: michael@0: if (mReadWrite) { michael@0: // Force a flush (so all pending writes are flushed to the disk and file michael@0: // metadata is updated too). michael@0: michael@0: nsCOMPtr ostream = do_QueryInterface(aStream); michael@0: NS_ASSERTION(ostream, "This should always succeed!"); michael@0: michael@0: rv = ostream->Flush(); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: } michael@0: michael@0: nsCOMPtr metadata = do_QueryInterface(aStream); michael@0: michael@0: if (mParams->SizeRequested()) { michael@0: int64_t size; michael@0: rv = metadata->GetSize(&size); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: NS_ENSURE_TRUE(size >= 0, NS_ERROR_FAILURE); michael@0: michael@0: mParams->mSize = uint64_t(size); michael@0: } michael@0: michael@0: if (mParams->LastModifiedRequested()) { michael@0: int64_t lastModified; michael@0: rv = metadata->GetLastModified(&lastModified); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: mParams->mLastModified = lastModified; michael@0: } michael@0: michael@0: return NS_OK; michael@0: }