Imported Upstream version 1.0.0
[platform/upstream/js.git] / js / src / jsclone.h
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2  * ***** BEGIN LICENSE BLOCK *****
3  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4  *
5  * The contents of this file are subject to the Mozilla Public License Version
6  * 1.1 (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  * http://www.mozilla.org/MPL/
9  *
10  * Software distributed under the License is distributed on an "AS IS" basis,
11  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12  * for the specific language governing rights and limitations under the
13  * License.
14  *
15  * The Original Code is JavaScript structured data serialization.
16  *
17  * The Initial Developer of the Original Code is
18  * the Mozilla Foundation.
19  * Portions created by the Initial Developer are Copyright (C) 2010
20  * the Initial Developer. All Rights Reserved.
21  *
22  * Contributor(s):
23  *   Jason Orendorff <jorendorff@mozilla.com>
24  *
25  * Alternatively, the contents of this file may be used under the terms of
26  * either the GNU General Public License Version 2 or later (the "GPL"), or
27  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28  * in which case the provisions of the GPL or the LGPL are applicable instead
29  * of those above. If you wish to allow use of your version of this file only
30  * under the terms of either the GPL or the LGPL, and not to allow others to
31  * use your version of this file under the terms of the MPL, indicate your
32  * decision by deleting the provisions above and replace them with the notice
33  * and other provisions required by the GPL or the LGPL. If you do not delete
34  * the provisions above, a recipient may use your version of this file under
35  * the terms of any one of the MPL, the GPL or the LGPL.
36  *
37  * ***** END LICENSE BLOCK ***** */
38
39 #ifndef jsclone_h___
40 #define jsclone_h___
41
42 #include "jsapi.h"
43 #include "jscntxt.h"
44 #include "jshashtable.h"
45 #include "jsstdint.h"
46 #include "jsvector.h"
47 #include "jsvalue.h"
48
49 namespace js {
50
51 bool
52 WriteStructuredClone(JSContext *cx, const Value &v, uint64_t **bufp, size_t *nbytesp,
53                      const JSStructuredCloneCallbacks *cb, void *cbClosure);
54
55 bool
56 ReadStructuredClone(JSContext *cx, const uint64_t *data, size_t nbytes, Value *vp,
57                     const JSStructuredCloneCallbacks *cb, void *cbClosure);
58
59 struct SCOutput {
60   public:
61     explicit SCOutput(JSContext *cx);
62
63     JSContext *context() const { return cx; }
64
65     bool write(uint64_t u);
66     bool writePair(uint32_t tag, uint32_t data);
67     bool writeDouble(jsdouble d);
68     bool writeBytes(const void *p, size_t nbytes);
69     bool writeChars(const jschar *p, size_t nchars);
70
71     template <class T>
72     bool writeArray(const T *p, size_t nbytes);
73
74     bool extractBuffer(uint64_t **datap, size_t *sizep);
75
76   private:
77     JSContext *cx;
78     js::Vector<uint64_t> buf;
79 };
80
81 struct SCInput {
82   public:
83     SCInput(JSContext *cx, const uint64_t *data, size_t nbytes);
84
85     JSContext *context() const { return cx; }
86
87     bool read(uint64_t *p);
88     bool readPair(uint32_t *tagp, uint32_t *datap);
89     bool readDouble(jsdouble *p);
90     bool readBytes(void *p, size_t nbytes);
91     bool readChars(jschar *p, size_t nchars);
92
93     template <class T>
94     bool readArray(T *p, size_t nelems);
95
96   private:
97     bool eof();
98
99     void staticAssertions() {
100         JS_STATIC_ASSERT(sizeof(jschar) == 2);
101         JS_STATIC_ASSERT(sizeof(uint32_t) == 4);
102         JS_STATIC_ASSERT(sizeof(jsdouble) == 8);
103     }
104
105     JSContext *cx;
106     const uint64_t *point;
107     const uint64_t *end;
108 };
109
110 }
111
112 struct JSStructuredCloneReader {
113   public:
114     explicit JSStructuredCloneReader(js::SCInput &in, const JSStructuredCloneCallbacks *cb,
115                                      void *cbClosure)
116         : in(in), objs(in.context()), callbacks(cb), closure(cbClosure) { }
117
118     js::SCInput &input() { return in; }
119     bool read(js::Value *vp);
120
121   private:
122     JSContext *context() { return in.context(); }
123
124     bool checkDouble(jsdouble d);
125     JSString *readString(uint32_t nchars);
126     bool readTypedArray(uint32_t tag, uint32_t nelems, js::Value *vp);
127     bool readArrayBuffer(uint32_t nbytes, js::Value *vp);
128     bool readId(jsid *idp);
129     bool startRead(js::Value *vp);
130
131     js::SCInput &in;
132
133     // Stack of objects with properties remaining to be read.
134     js::AutoValueVector objs;
135
136     // The user defined callbacks that will be used for cloning.
137     const JSStructuredCloneCallbacks *callbacks;
138
139     // Any value passed to JS_ReadStructuredClone.
140     void *closure;
141 };
142
143 struct JSStructuredCloneWriter {
144   public:
145     explicit JSStructuredCloneWriter(js::SCOutput &out, const JSStructuredCloneCallbacks *cb,
146                                      void *cbClosure)
147         : out(out), objs(out.context()), counts(out.context()), ids(out.context()),
148           memory(out.context()), callbacks(cb), closure(cbClosure) { }
149
150     bool init() { return memory.init(); }
151
152     bool write(const js::Value &v);
153
154     js::SCOutput &output() { return out; }
155
156   private:
157     JSContext *context() { return out.context(); }
158
159     bool writeString(uint32_t tag, JSString *str);
160     bool writeId(jsid id);
161     bool writeArrayBuffer(JSObject *obj);
162     bool writeTypedArray(JSObject *obj);
163     bool startObject(JSObject *obj);
164     bool startWrite(const js::Value &v);
165
166     inline void checkStack();
167
168     js::SCOutput &out;
169
170     // Stack of objects with properties remaining to be written.
171     js::AutoValueVector objs;
172
173     // counts[i] is the number of properties of objs[i] remaining to be written.
174     // counts.length() == objs.length() and sum(counts) == ids.length().
175     js::Vector<size_t> counts;
176
177     // Ids of properties remaining to be written.
178     js::AutoIdVector ids;
179
180     // The "memory" list described in the HTML5 internal structured cloning algorithm.
181     // memory has the same elements as objs.
182     js::HashSet<JSObject *> memory;
183
184     // The user defined callbacks that will be used for cloning.
185     const JSStructuredCloneCallbacks *callbacks;
186
187     // Any value passed to JS_WriteStructuredClone.
188     void *closure;
189 };
190
191 #endif /* jsclone_h___ */