js/public/StructuredClone.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/js/public/StructuredClone.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,245 @@
     1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     1.5 + * vim: set ts=8 sts=4 et sw=4 tw=99:
     1.6 + * This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +#ifndef js_StructuredClone_h
    1.11 +#define js_StructuredClone_h
    1.12 +
    1.13 +#include "mozilla/NullPtr.h"
    1.14 +
    1.15 +#include <stdint.h>
    1.16 +
    1.17 +#include "jstypes.h"
    1.18 +
    1.19 +#include "js/RootingAPI.h"
    1.20 +#include "js/TypeDecls.h"
    1.21 +#include "js/Value.h"
    1.22 +
    1.23 +struct JSRuntime;
    1.24 +struct JSStructuredCloneReader;
    1.25 +struct JSStructuredCloneWriter;
    1.26 +
    1.27 +// API for the HTML5 internal structured cloning algorithm.
    1.28 +
    1.29 +namespace JS {
    1.30 +enum TransferableOwnership {
    1.31 +    // Transferable data has not been filled in yet
    1.32 +    SCTAG_TMO_UNFILLED = 0,
    1.33 +
    1.34 +    // Structured clone buffer does not yet own the data
    1.35 +    SCTAG_TMO_UNOWNED = 1,
    1.36 +
    1.37 +    // All values at least this large are owned by the clone buffer
    1.38 +    SCTAG_TMO_FIRST_OWNED = 2,
    1.39 +
    1.40 +    // Data is a pointer that can be freed
    1.41 +    SCTAG_TMO_ALLOC_DATA = 2,
    1.42 +
    1.43 +    // Data is a SharedArrayBufferObject's buffer
    1.44 +    SCTAG_TMO_SHARED_BUFFER = 3,
    1.45 +
    1.46 +    // Data is a memory mapped pointer
    1.47 +    SCTAG_TMO_MAPPED_DATA = 4,
    1.48 +
    1.49 +    // Data is embedding-specific. The engine can free it by calling the
    1.50 +    // freeTransfer op. The embedding can also use SCTAG_TMO_USER_MIN and
    1.51 +    // greater, up to 32 bits, to distinguish specific ownership variants.
    1.52 +    SCTAG_TMO_CUSTOM = 5,
    1.53 +
    1.54 +    SCTAG_TMO_USER_MIN
    1.55 +};
    1.56 +} /* namespace JS */
    1.57 +
    1.58 +// Read structured data from the reader r. This hook is used to read a value
    1.59 +// previously serialized by a call to the WriteStructuredCloneOp hook.
    1.60 +//
    1.61 +// tag and data are the pair of uint32_t values from the header. The callback
    1.62 +// may use the JS_Read* APIs to read any other relevant parts of the object
    1.63 +// from the reader r. closure is any value passed to the JS_ReadStructuredClone
    1.64 +// function. Return the new object on success, nullptr on error/exception.
    1.65 +typedef JSObject *(*ReadStructuredCloneOp)(JSContext *cx, JSStructuredCloneReader *r,
    1.66 +                                           uint32_t tag, uint32_t data, void *closure);
    1.67 +
    1.68 +// Structured data serialization hook. The engine can write primitive values,
    1.69 +// Objects, Arrays, Dates, RegExps, TypedArrays, and ArrayBuffers. Any other
    1.70 +// type of object requires application support. This callback must first use
    1.71 +// the JS_WriteUint32Pair API to write an object header, passing a value
    1.72 +// greater than JS_SCTAG_USER to the tag parameter. Then it can use the
    1.73 +// JS_Write* APIs to write any other relevant parts of the value v to the
    1.74 +// writer w. closure is any value passed to the JS_WriteStructuredCLone function.
    1.75 +//
    1.76 +// Return true on success, false on error/exception.
    1.77 +typedef bool (*WriteStructuredCloneOp)(JSContext *cx, JSStructuredCloneWriter *w,
    1.78 +                                       JS::HandleObject obj, void *closure);
    1.79 +
    1.80 +// This is called when JS_WriteStructuredClone is given an invalid transferable.
    1.81 +// To follow HTML5, the application must throw a DATA_CLONE_ERR DOMException
    1.82 +// with error set to one of the JS_SCERR_* values.
    1.83 +typedef void (*StructuredCloneErrorOp)(JSContext *cx, uint32_t errorid);
    1.84 +
    1.85 +// This is called when JS_ReadStructuredClone receives a transferable object
    1.86 +// not known to the engine. If this hook does not exist or returns false, the
    1.87 +// JS engine calls the reportError op if set, otherwise it throws a
    1.88 +// DATA_CLONE_ERR DOM Exception. This method is called before any other
    1.89 +// callback and must return a non-null object in returnObject on success.
    1.90 +typedef bool (*ReadTransferStructuredCloneOp)(JSContext *cx, JSStructuredCloneReader *r,
    1.91 +                                              uint32_t tag, void *content, uint64_t extraData,
    1.92 +                                              void *closure,
    1.93 +                                              JS::MutableHandleObject returnObject);
    1.94 +
    1.95 +// Called when JS_WriteStructuredClone receives a transferable object not
    1.96 +// handled by the engine. If this hook does not exist or returns false, the JS
    1.97 +// engine will call the reportError hook or fall back to throwing a
    1.98 +// DATA_CLONE_ERR DOM Exception. This method is called before any other
    1.99 +// callback.
   1.100 +//
   1.101 +//  tag: indicates what type of transferable this is. Must be greater than
   1.102 +//       0xFFFF0201 (value of the internal SCTAG_TRANSFER_MAP_PENDING_ENTRY)
   1.103 +//
   1.104 +//  ownership: see TransferableOwnership, above. Used to communicate any needed
   1.105 +//       ownership info to the FreeTransferStructuredCloneOp.
   1.106 +//
   1.107 +//  content, extraData: what the ReadTransferStructuredCloneOp will receive
   1.108 +//
   1.109 +typedef bool (*TransferStructuredCloneOp)(JSContext *cx,
   1.110 +                                          JS::Handle<JSObject*> obj,
   1.111 +                                          void *closure,
   1.112 +                                          // Output:
   1.113 +                                          uint32_t *tag,
   1.114 +                                          JS::TransferableOwnership *ownership,
   1.115 +                                          void **content,
   1.116 +                                          uint64_t *extraData);
   1.117 +
   1.118 +// Called when JS_ClearStructuredClone has to free an unknown transferable
   1.119 +// object. Note that it should never trigger a garbage collection (and will
   1.120 +// assert in a debug build if it does.)
   1.121 +typedef void (*FreeTransferStructuredCloneOp)(uint32_t tag, JS::TransferableOwnership ownership,
   1.122 +                                              void *content, uint64_t extraData, void *closure);
   1.123 +
   1.124 +// The maximum supported structured-clone serialization format version. Note
   1.125 +// that this does not need to be bumped for Transferable-only changes, since
   1.126 +// they are never saved to persistent storage.
   1.127 +#define JS_STRUCTURED_CLONE_VERSION 2
   1.128 +
   1.129 +struct JSStructuredCloneCallbacks {
   1.130 +    ReadStructuredCloneOp read;
   1.131 +    WriteStructuredCloneOp write;
   1.132 +    StructuredCloneErrorOp reportError;
   1.133 +    ReadTransferStructuredCloneOp readTransfer;
   1.134 +    TransferStructuredCloneOp writeTransfer;
   1.135 +    FreeTransferStructuredCloneOp freeTransfer;
   1.136 +};
   1.137 +
   1.138 +// Note: if the *data contains transferable objects, it can be read only once.
   1.139 +JS_PUBLIC_API(bool)
   1.140 +JS_ReadStructuredClone(JSContext *cx, uint64_t *data, size_t nbytes, uint32_t version,
   1.141 +                       JS::MutableHandleValue vp,
   1.142 +                       const JSStructuredCloneCallbacks *optionalCallbacks, void *closure);
   1.143 +
   1.144 +// Note: On success, the caller is responsible for calling
   1.145 +// JS_ClearStructuredClone(*datap, nbytes, optionalCallbacks, closure).
   1.146 +JS_PUBLIC_API(bool)
   1.147 +JS_WriteStructuredClone(JSContext *cx, JS::HandleValue v, uint64_t **datap, size_t *nbytesp,
   1.148 +                        const JSStructuredCloneCallbacks *optionalCallbacks,
   1.149 +                        void *closure, JS::HandleValue transferable);
   1.150 +
   1.151 +JS_PUBLIC_API(bool)
   1.152 +JS_ClearStructuredClone(uint64_t *data, size_t nbytes,
   1.153 +                        const JSStructuredCloneCallbacks *optionalCallbacks,
   1.154 +                        void *closure);
   1.155 +
   1.156 +JS_PUBLIC_API(bool)
   1.157 +JS_StructuredCloneHasTransferables(const uint64_t *data, size_t nbytes, bool *hasTransferable);
   1.158 +
   1.159 +JS_PUBLIC_API(bool)
   1.160 +JS_StructuredClone(JSContext *cx, JS::HandleValue v, JS::MutableHandleValue vp,
   1.161 +                   const JSStructuredCloneCallbacks *optionalCallbacks, void *closure);
   1.162 +
   1.163 +// RAII sugar for JS_WriteStructuredClone.
   1.164 +class JS_PUBLIC_API(JSAutoStructuredCloneBuffer) {
   1.165 +    uint64_t *data_;
   1.166 +    size_t nbytes_;
   1.167 +    uint32_t version_;
   1.168 +    const JSStructuredCloneCallbacks *callbacks_;
   1.169 +    void *closure_;
   1.170 +
   1.171 +  public:
   1.172 +    JSAutoStructuredCloneBuffer()
   1.173 +        : data_(nullptr), nbytes_(0), version_(JS_STRUCTURED_CLONE_VERSION),
   1.174 +          callbacks_(nullptr), closure_(nullptr)
   1.175 +    {}
   1.176 +
   1.177 +    JSAutoStructuredCloneBuffer(const JSStructuredCloneCallbacks *callbacks, void *closure)
   1.178 +        : data_(nullptr), nbytes_(0), version_(JS_STRUCTURED_CLONE_VERSION),
   1.179 +          callbacks_(callbacks), closure_(closure)
   1.180 +    {}
   1.181 +
   1.182 +    JSAutoStructuredCloneBuffer(JSAutoStructuredCloneBuffer &&other);
   1.183 +    JSAutoStructuredCloneBuffer &operator=(JSAutoStructuredCloneBuffer &&other);
   1.184 +
   1.185 +    ~JSAutoStructuredCloneBuffer() { clear(); }
   1.186 +
   1.187 +    uint64_t *data() const { return data_; }
   1.188 +    size_t nbytes() const { return nbytes_; }
   1.189 +
   1.190 +    void clear();
   1.191 +
   1.192 +    // Copy some memory. It will be automatically freed by the destructor.
   1.193 +    bool copy(const uint64_t *data, size_t nbytes, uint32_t version=JS_STRUCTURED_CLONE_VERSION);
   1.194 +
   1.195 +    // Adopt some memory. It will be automatically freed by the destructor.
   1.196 +    // data must have been allocated by the JS engine (e.g., extracted via
   1.197 +    // JSAutoStructuredCloneBuffer::steal).
   1.198 +    void adopt(uint64_t *data, size_t nbytes, uint32_t version=JS_STRUCTURED_CLONE_VERSION);
   1.199 +
   1.200 +    // Remove the buffer so that it will not be automatically freed.
   1.201 +    // After this, the caller is responsible for feeding the memory back to
   1.202 +    // JSAutoStructuredCloneBuffer::adopt.
   1.203 +    void steal(uint64_t **datap, size_t *nbytesp, uint32_t *versionp=nullptr);
   1.204 +
   1.205 +    bool read(JSContext *cx, JS::MutableHandleValue vp,
   1.206 +              const JSStructuredCloneCallbacks *optionalCallbacks=nullptr, void *closure=nullptr);
   1.207 +
   1.208 +    bool write(JSContext *cx, JS::HandleValue v,
   1.209 +               const JSStructuredCloneCallbacks *optionalCallbacks=nullptr, void *closure=nullptr);
   1.210 +
   1.211 +    bool write(JSContext *cx, JS::HandleValue v, JS::HandleValue transferable,
   1.212 +               const JSStructuredCloneCallbacks *optionalCallbacks=nullptr, void *closure=nullptr);
   1.213 +
   1.214 +  private:
   1.215 +    // Copy and assignment are not supported.
   1.216 +    JSAutoStructuredCloneBuffer(const JSAutoStructuredCloneBuffer &other) MOZ_DELETE;
   1.217 +    JSAutoStructuredCloneBuffer &operator=(const JSAutoStructuredCloneBuffer &other) MOZ_DELETE;
   1.218 +};
   1.219 +
   1.220 +// The range of tag values the application may use for its own custom object types.
   1.221 +#define JS_SCTAG_USER_MIN  ((uint32_t) 0xFFFF8000)
   1.222 +#define JS_SCTAG_USER_MAX  ((uint32_t) 0xFFFFFFFF)
   1.223 +
   1.224 +#define JS_SCERR_RECURSION 0
   1.225 +#define JS_SCERR_TRANSFERABLE 1
   1.226 +
   1.227 +JS_PUBLIC_API(void)
   1.228 +JS_SetStructuredCloneCallbacks(JSRuntime *rt, const JSStructuredCloneCallbacks *callbacks);
   1.229 +
   1.230 +JS_PUBLIC_API(bool)
   1.231 +JS_ReadUint32Pair(JSStructuredCloneReader *r, uint32_t *p1, uint32_t *p2);
   1.232 +
   1.233 +JS_PUBLIC_API(bool)
   1.234 +JS_ReadBytes(JSStructuredCloneReader *r, void *p, size_t len);
   1.235 +
   1.236 +JS_PUBLIC_API(bool)
   1.237 +JS_ReadTypedArray(JSStructuredCloneReader *r, JS::MutableHandleValue vp);
   1.238 +
   1.239 +JS_PUBLIC_API(bool)
   1.240 +JS_WriteUint32Pair(JSStructuredCloneWriter *w, uint32_t tag, uint32_t data);
   1.241 +
   1.242 +JS_PUBLIC_API(bool)
   1.243 +JS_WriteBytes(JSStructuredCloneWriter *w, const void *p, size_t len);
   1.244 +
   1.245 +JS_PUBLIC_API(bool)
   1.246 +JS_WriteTypedArray(JSStructuredCloneWriter *w, JS::HandleValue v);
   1.247 +
   1.248 +#endif  /* js_StructuredClone_h */

mercurial