Bug 1199384 - Add shell function for writing a typed array to a file, r=sfink.

This commit is contained in:
Brian Hackett 2015-09-13 15:19:33 -06:00
parent be0ddae533
commit c8a62d0aec
3 changed files with 69 additions and 9 deletions

View File

@ -125,7 +125,7 @@ FileAsTypedArray(JSContext* cx, const char* pathname)
JS_ReportError(cx, "can't open %s: %s", pathname, strerror(errno));
return nullptr;
}
AutoCloseInputFile autoClose(file);
AutoCloseFile autoClose(file);
RootedObject obj(cx);
if (fseek(file, 0, SEEK_END) != 0) {
@ -210,6 +210,50 @@ osfile_readRelativeToScript(JSContext* cx, unsigned argc, Value* vp)
return ReadFile(cx, argc, vp, true);
}
static bool
osfile_writeTypedArrayToFile(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
if (args.length() != 2 ||
!args[0].isString() ||
!args[1].isObject() ||
!args[1].toObject().is<TypedArrayObject>())
{
JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr,
JSSMSG_INVALID_ARGS, "writeTypedArrayToFile");
return false;
}
RootedString givenPath(cx, args[0].toString());
RootedString str(cx, ResolvePath(cx, givenPath, RootRelative));
if (!str)
return false;
JSAutoByteString filename(cx, str);
if (!filename)
return false;
FILE* file = fopen(filename.ptr(), "wb");
if (!file) {
JS_ReportError(cx, "can't open %s: %s", filename.ptr(), strerror(errno));
return false;
}
AutoCloseFile autoClose(file);
TypedArrayObject* obj = &args[1].toObject().as<TypedArrayObject>();
if (fwrite(obj->viewData(), obj->bytesPerElement(), obj->length(), file) != obj->length() ||
!autoClose.release())
{
JS_ReportError(cx, "can't write %s", filename.ptr());
return false;
}
args.rval().setUndefined();
return true;
}
static bool
Redirect(JSContext* cx, FILE* fp, HandleString relFilename)
{
@ -271,6 +315,10 @@ static const JSFunctionSpecWithHelp osfile_functions[] = {
};
static const JSFunctionSpecWithHelp osfile_unsafe_functions[] = {
JS_FN_HELP("writeTypedArrayToFile", osfile_writeTypedArrayToFile, 2, 0,
"writeTypedArrayToFile(filename, data)",
" Write the contents of a typed array to the named file."),
JS_FN_HELP("redirect", osfile_redirect, 2, 0,
"redirect(stdoutFilename[, stderrFilename])",
" Redirect stdout and/or stderr to the named file. Pass undefined to avoid\n"

View File

@ -573,7 +573,7 @@ Process(JSContext* cx, const char* filename, bool forceTTY)
return;
}
}
AutoCloseInputFile autoClose(file);
AutoCloseFile autoClose(file);
if (!forceTTY && !isatty(fileno(file))) {
// It's not interactive - just execute it.
@ -664,7 +664,7 @@ CreateMappedArrayBuffer(JSContext* cx, unsigned argc, Value* vp)
JSSMSG_CANT_OPEN, filename.ptr(), strerror(errno));
return false;
}
AutoCloseInputFile autoClose(file);
AutoCloseFile autoClose(file);
if (!sizeGiven) {
struct stat st;
@ -1294,7 +1294,7 @@ js::shell::FileAsString(JSContext* cx, const char* pathname)
JS_ReportError(cx, "can't open %s: %s", pathname, strerror(errno));
return nullptr;
}
AutoCloseInputFile autoClose(file);
AutoCloseFile autoClose(file);
if (fseek(file, 0, SEEK_END) != 0) {
JS_ReportError(cx, "can't seek end of %s", pathname);

View File

@ -1,3 +1,9 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef jsshell_js_h
#define jsshell_js_h
@ -23,15 +29,21 @@ my_ErrorReporter(JSContext* cx, const char* message, JSErrorReport* report);
JSString*
FileAsString(JSContext* cx, const char* pathname);
class AutoCloseInputFile
class AutoCloseFile
{
private:
FILE* f_;
public:
explicit AutoCloseInputFile(FILE* f) : f_(f) {}
~AutoCloseInputFile() {
if (f_ && f_ != stdin)
fclose(f_);
explicit AutoCloseFile(FILE* f) : f_(f) {}
~AutoCloseFile() {
(void) release();
}
bool release() {
bool success = true;
if (f_ && f_ != stdin && f_ != stdout && f_ != stderr)
success = !fclose(f_);
f_ = nullptr;
return success;
}
};