Github User Fetcher 1.0.0
C Application with Server and GUI
Loading...
Searching...
No Matches
duktape-1.8.0/src-separate/duk_hbufferobject.h
Go to the documentation of this file.
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
95struct duk_hbufferobject {
96 /* Shared object part. */
98
99 /* Underlying buffer (refcounted), may be NULL. */
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)
129#endif
132
133#endif /* DUK_HBUFFEROBJECT_H_INCLUDED */
unsigned int duk_small_uint_t
duk_uint_fast32_t duk_uint_t
DUK_INTERNAL_DECL duk_uint_t duk_hbufferobject_clamp_bytelength(duk_hbufferobject *h_bufobj, duk_uint_t len)
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)
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)