]> git.proxmox.com Git - ceph.git/blob - ceph/src/civetweb/src/third_party/duktape-1.5.2/src-separate/duk_hbufferobject.h
buildsys: switch source download to quincy
[ceph.git] / ceph / src / civetweb / src / third_party / duktape-1.5.2 / src-separate / duk_hbufferobject.h
1 /*
2 * Heap Buffer object representation. Used for all Buffer variants.
3 */
4
5 #ifndef DUK_HBUFFEROBJECT_H_INCLUDED
6 #define DUK_HBUFFEROBJECT_H_INCLUDED
7
8 /* All element accessors are host endian now (driven by TypedArray spec). */
9 #define DUK_HBUFFEROBJECT_ELEM_UINT8 0
10 #define DUK_HBUFFEROBJECT_ELEM_UINT8CLAMPED 1
11 #define DUK_HBUFFEROBJECT_ELEM_INT8 2
12 #define DUK_HBUFFEROBJECT_ELEM_UINT16 3
13 #define DUK_HBUFFEROBJECT_ELEM_INT16 4
14 #define DUK_HBUFFEROBJECT_ELEM_UINT32 5
15 #define DUK_HBUFFEROBJECT_ELEM_INT32 6
16 #define DUK_HBUFFEROBJECT_ELEM_FLOAT32 7
17 #define DUK_HBUFFEROBJECT_ELEM_FLOAT64 8
18 #define DUK_HBUFFEROBJECT_ELEM_MAX 8
19
20 #define DUK_ASSERT_HBUFFEROBJECT_VALID(h) do { \
21 DUK_ASSERT((h) != NULL); \
22 DUK_ASSERT((h)->shift <= 3); \
23 DUK_ASSERT((h)->elem_type <= DUK_HBUFFEROBJECT_ELEM_MAX); \
24 DUK_ASSERT(((h)->shift == 0 && (h)->elem_type == DUK_HBUFFEROBJECT_ELEM_UINT8) || \
25 ((h)->shift == 0 && (h)->elem_type == DUK_HBUFFEROBJECT_ELEM_UINT8CLAMPED) || \
26 ((h)->shift == 0 && (h)->elem_type == DUK_HBUFFEROBJECT_ELEM_INT8) || \
27 ((h)->shift == 1 && (h)->elem_type == DUK_HBUFFEROBJECT_ELEM_UINT16) || \
28 ((h)->shift == 1 && (h)->elem_type == DUK_HBUFFEROBJECT_ELEM_INT16) || \
29 ((h)->shift == 2 && (h)->elem_type == DUK_HBUFFEROBJECT_ELEM_UINT32) || \
30 ((h)->shift == 2 && (h)->elem_type == DUK_HBUFFEROBJECT_ELEM_INT32) || \
31 ((h)->shift == 2 && (h)->elem_type == DUK_HBUFFEROBJECT_ELEM_FLOAT32) || \
32 ((h)->shift == 3 && (h)->elem_type == DUK_HBUFFEROBJECT_ELEM_FLOAT64)); \
33 DUK_ASSERT((h)->is_view == 0 || (h)->is_view == 1); \
34 DUK_ASSERT(DUK_HOBJECT_IS_BUFFEROBJECT((duk_hobject *) (h))); \
35 if ((h)->buf == NULL) { \
36 DUK_ASSERT((h)->offset == 0); \
37 DUK_ASSERT((h)->length == 0); \
38 } else { \
39 /* No assertions for offset or length; in particular, \
40 * it's OK for length to be longer than underlying \
41 * buffer. Just ensure they don't wrap when added. \
42 */ \
43 DUK_ASSERT((h)->offset + (h)->length >= (h)->offset); \
44 } \
45 } while (0)
46
47 /* Get the current data pointer (caller must ensure buf != NULL) as a
48 * duk_uint8_t ptr.
49 */
50 #define DUK_HBUFFEROBJECT_GET_SLICE_BASE(heap,h) \
51 (DUK_ASSERT_EXPR((h) != NULL), DUK_ASSERT_EXPR((h)->buf != NULL), \
52 (((duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR((heap), (h)->buf)) + (h)->offset))
53
54 /* True if slice is full, i.e. offset is zero and length covers the entire
55 * buffer. This status may change independently of the duk_hbufferobject if
56 * the underlying buffer is dynamic and changes without the hbufferobject
57 * being changed.
58 */
59 #define DUK_HBUFFEROBJECT_FULL_SLICE(h) \
60 (DUK_ASSERT_EXPR((h) != NULL), DUK_ASSERT_EXPR((h)->buf != NULL), \
61 ((h)->offset == 0 && (h)->length == DUK_HBUFFER_GET_SIZE((h)->buf)))
62
63 /* Validate that the whole slice [0,length[ is contained in the underlying
64 * buffer. Caller must ensure 'buf' != NULL.
65 */
66 #define DUK_HBUFFEROBJECT_VALID_SLICE(h) \
67 (DUK_ASSERT_EXPR((h) != NULL), DUK_ASSERT_EXPR((h)->buf != NULL), \
68 ((h)->offset + (h)->length <= DUK_HBUFFER_GET_SIZE((h)->buf)))
69
70 /* Validate byte read/write for virtual 'offset', i.e. check that the
71 * offset, taking into account h->offset, is within the underlying
72 * buffer size. This is a safety check which is needed to ensure
73 * that even a misconfigured duk_hbufferobject never causes memory
74 * unsafe behavior (e.g. if an underlying dynamic buffer changes
75 * after being setup). Caller must ensure 'buf' != NULL.
76 */
77 #define DUK_HBUFFEROBJECT_VALID_BYTEOFFSET_INCL(h,off) \
78 (DUK_ASSERT_EXPR((h) != NULL), DUK_ASSERT_EXPR((h)->buf != NULL), \
79 ((h)->offset + (off) < DUK_HBUFFER_GET_SIZE((h)->buf)))
80
81 #define DUK_HBUFFEROBJECT_VALID_BYTEOFFSET_EXCL(h,off) \
82 (DUK_ASSERT_EXPR((h) != NULL), DUK_ASSERT_EXPR((h)->buf != NULL), \
83 ((h)->offset + (off) <= DUK_HBUFFER_GET_SIZE((h)->buf)))
84
85 /* Clamp an input byte length (already assumed to be within the nominal
86 * duk_hbufferobject 'length') to the current dynamic buffer limits to
87 * yield a byte length limit that's safe for memory accesses. This value
88 * can be invalidated by any side effect because it may trigger a user
89 * callback that resizes the underlying buffer.
90 */
91 #define DUK_HBUFFEROBJECT_CLAMP_BYTELENGTH(h,len) \
92 (DUK_ASSERT_EXPR((h) != NULL), \
93 duk_hbufferobject_clamp_bytelength((h), (len)))
94
95 struct duk_hbufferobject {
96 /* Shared object part. */
97 duk_hobject obj;
98
99 /* Underlying buffer (refcounted), may be NULL. */
100 duk_hbuffer *buf;
101
102 /* Slice and accessor information.
103 *
104 * Because the underlying buffer may be dynamic, these may be
105 * invalidated by the buffer being modified so that both offset
106 * and length should be validated before every access. Behavior
107 * when the underlying buffer has changed doesn't need to be clean:
108 * virtual 'length' doesn't need to be affected, reads can return
109 * zero/NaN, and writes can be ignored.
110 *
111 * Note that a data pointer cannot be precomputed because 'buf' may
112 * be dynamic and its pointer unstable.
113 */
114
115 duk_uint_t offset; /* byte offset to buf */
116 duk_uint_t length; /* byte index limit for element access, exclusive */
117 duk_uint8_t shift; /* element size shift:
118 * 0 = u8/i8
119 * 1 = u16/i16
120 * 2 = u32/i32/float
121 * 3 = double
122 */
123 duk_uint8_t elem_type; /* element type */
124 duk_uint8_t is_view;
125 };
126
127 #if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
128 DUK_INTERNAL_DECL duk_uint_t duk_hbufferobject_clamp_bytelength(duk_hbufferobject *h_bufobj, duk_uint_t len);
129 #endif
130 DUK_INTERNAL_DECL void duk_hbufferobject_push_validated_read(duk_context *ctx, duk_hbufferobject *h_bufobj, duk_uint8_t *p, duk_small_uint_t elem_size);
131 DUK_INTERNAL_DECL void duk_hbufferobject_validated_write(duk_context *ctx, duk_hbufferobject *h_bufobj, duk_uint8_t *p, duk_small_uint_t elem_size);
132
133 #endif /* DUK_HBUFFEROBJECT_H_INCLUDED */