mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
203 lines
6.3 KiB
C++
203 lines
6.3 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
* ***** BEGIN LICENSE BLOCK *****
|
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
*
|
|
* The contents of this file are subject to the Mozilla Public License Version
|
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
* http://www.mozilla.org/MPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
* for the specific language governing rights and limitations under the
|
|
* License.
|
|
*
|
|
* The Original Code is JavaScript structured data serialization.
|
|
*
|
|
* The Initial Developer of the Original Code is
|
|
* the Mozilla Foundation.
|
|
* Portions created by the Initial Developer are Copyright (C) 2010
|
|
* the Initial Developer. All Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
* Jason Orendorff <jorendorff@mozilla.com>
|
|
*
|
|
* Alternatively, the contents of this file may be used under the terms of
|
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
* of those above. If you wish to allow use of your version of this file only
|
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
* use your version of this file under the terms of the MPL, indicate your
|
|
* decision by deleting the provisions above and replace them with the notice
|
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
* the provisions above, a recipient may use your version of this file under
|
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
|
*
|
|
* ***** END LICENSE BLOCK ***** */
|
|
|
|
#ifndef jsclone_h___
|
|
#define jsclone_h___
|
|
|
|
#include "jsapi.h"
|
|
#include "jscntxt.h"
|
|
#include "jshashtable.h"
|
|
#include "jsstdint.h"
|
|
#include "jsvector.h"
|
|
#include "jsvalue.h"
|
|
|
|
JS_FRIEND_API(uint64_t)
|
|
js_GetSCOffset(JSStructuredCloneWriter* writer);
|
|
|
|
namespace js {
|
|
|
|
bool
|
|
WriteStructuredClone(JSContext *cx, const Value &v, uint64_t **bufp, size_t *nbytesp,
|
|
const JSStructuredCloneCallbacks *cb, void *cbClosure);
|
|
|
|
bool
|
|
ReadStructuredClone(JSContext *cx, const uint64_t *data, size_t nbytes, Value *vp,
|
|
const JSStructuredCloneCallbacks *cb, void *cbClosure);
|
|
|
|
struct SCOutput {
|
|
public:
|
|
explicit SCOutput(JSContext *cx);
|
|
|
|
JSContext *context() const { return cx; }
|
|
|
|
bool write(uint64_t u);
|
|
bool writePair(uint32_t tag, uint32_t data);
|
|
bool writeDouble(jsdouble d);
|
|
bool writeBytes(const void *p, size_t nbytes);
|
|
bool writeChars(const jschar *p, size_t nchars);
|
|
|
|
template <class T>
|
|
bool writeArray(const T *p, size_t nbytes);
|
|
|
|
bool extractBuffer(uint64_t **datap, size_t *sizep);
|
|
|
|
uint64_t count() { return buf.length(); }
|
|
|
|
private:
|
|
JSContext *cx;
|
|
js::Vector<uint64_t> buf;
|
|
};
|
|
|
|
struct SCInput {
|
|
public:
|
|
SCInput(JSContext *cx, const uint64_t *data, size_t nbytes);
|
|
|
|
JSContext *context() const { return cx; }
|
|
|
|
bool read(uint64_t *p);
|
|
bool readPair(uint32_t *tagp, uint32_t *datap);
|
|
bool readDouble(jsdouble *p);
|
|
bool readBytes(void *p, size_t nbytes);
|
|
bool readChars(jschar *p, size_t nchars);
|
|
|
|
template <class T>
|
|
bool readArray(T *p, size_t nelems);
|
|
|
|
private:
|
|
bool eof();
|
|
|
|
void staticAssertions() {
|
|
JS_STATIC_ASSERT(sizeof(jschar) == 2);
|
|
JS_STATIC_ASSERT(sizeof(uint32_t) == 4);
|
|
JS_STATIC_ASSERT(sizeof(jsdouble) == 8);
|
|
}
|
|
|
|
JSContext *cx;
|
|
const uint64_t *point;
|
|
const uint64_t *end;
|
|
};
|
|
|
|
}
|
|
|
|
struct JSStructuredCloneReader {
|
|
public:
|
|
explicit JSStructuredCloneReader(js::SCInput &in, const JSStructuredCloneCallbacks *cb,
|
|
void *cbClosure)
|
|
: in(in), objs(in.context()), allObjs(in.context()),
|
|
callbacks(cb), closure(cbClosure) { }
|
|
|
|
js::SCInput &input() { return in; }
|
|
bool read(js::Value *vp);
|
|
|
|
private:
|
|
JSContext *context() { return in.context(); }
|
|
|
|
bool checkDouble(jsdouble d);
|
|
JSString *readString(uint32_t nchars);
|
|
bool readTypedArray(uint32_t tag, uint32_t nelems, js::Value *vp);
|
|
bool readArrayBuffer(uint32_t nbytes, js::Value *vp);
|
|
bool readId(jsid *idp);
|
|
bool startRead(js::Value *vp);
|
|
|
|
js::SCInput ∈
|
|
|
|
// Stack of objects with properties remaining to be read.
|
|
js::AutoValueVector objs;
|
|
|
|
// Stack of all objects read during this deserialization
|
|
js::AutoValueVector allObjs;
|
|
|
|
// The user defined callbacks that will be used for cloning.
|
|
const JSStructuredCloneCallbacks *callbacks;
|
|
|
|
// Any value passed to JS_ReadStructuredClone.
|
|
void *closure;
|
|
};
|
|
|
|
struct JSStructuredCloneWriter {
|
|
public:
|
|
explicit JSStructuredCloneWriter(js::SCOutput &out, const JSStructuredCloneCallbacks *cb,
|
|
void *cbClosure)
|
|
: out(out), objs(out.context()), counts(out.context()), ids(out.context()),
|
|
memory(out.context()), callbacks(cb), closure(cbClosure) { }
|
|
|
|
bool init() { return memory.init(); }
|
|
|
|
bool write(const js::Value &v);
|
|
|
|
js::SCOutput &output() { return out; }
|
|
|
|
private:
|
|
JSContext *context() { return out.context(); }
|
|
|
|
bool writeString(uint32_t tag, JSString *str);
|
|
bool writeId(jsid id);
|
|
bool writeArrayBuffer(JSObject *obj);
|
|
bool writeTypedArray(JSObject *obj);
|
|
bool startObject(JSObject *obj);
|
|
bool startWrite(const js::Value &v);
|
|
|
|
inline void checkStack();
|
|
|
|
js::SCOutput &out;
|
|
|
|
// Vector of objects with properties remaining to be written.
|
|
js::AutoValueVector objs;
|
|
|
|
// counts[i] is the number of properties of objs[i] remaining to be written.
|
|
// counts.length() == objs.length() and sum(counts) == ids.length().
|
|
js::Vector<size_t> counts;
|
|
|
|
// Ids of properties remaining to be written.
|
|
js::AutoIdVector ids;
|
|
|
|
// The "memory" list described in the HTML5 internal structured cloning algorithm.
|
|
// memory is a superset of objs; items are never removed from Memory
|
|
// until a serialization operation is finished
|
|
typedef js::HashMap<JSObject *, uint32> CloneMemory;
|
|
CloneMemory memory;
|
|
|
|
// The user defined callbacks that will be used for cloning.
|
|
const JSStructuredCloneCallbacks *callbacks;
|
|
|
|
// Any value passed to JS_WriteStructuredClone.
|
|
void *closure;
|
|
};
|
|
|
|
#endif /* jsclone_h___ */
|