1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
|
/*
* %CopyrightBegin%
*
* Copyright Ericsson AB 1999-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
*
* 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.
*
* %CopyrightEnd%
*/
#ifndef __ERL_BITS_H__
#define __ERL_BITS_H__
/*
* This structure represents a binary to be matched.
*/
typedef struct erl_bin_match_buffer {
Eterm orig; /* Original binary term. */
byte* base; /* Current position in binary. */
Uint offset; /* Offset in bits. */
size_t size; /* Size of binary in bits. */
} ErlBinMatchBuffer;
struct erl_bits_state {
/*
* Used for building binaries.
*/
byte *byte_buf_;
int byte_buf_len_;
/*
* Used for building binaries using the new instruction set.
*/
byte* erts_current_bin_; /* Pointer to beginning of current binary. */
/*
* Offset in bits into the current binary (new instruction set) or
* buffer (old instruction set).
*/
Uint erts_bin_offset_;
/*
* Whether the current binary is writable.
*/
unsigned erts_writable_bin_;
};
typedef struct erl_bin_match_struct{
Eterm thing_word;
ErlBinMatchBuffer mb; /* Present match buffer */
Eterm save_offset[1]; /* Saved offsets */
} ErlBinMatchState;
#define ERL_BIN_MATCHSTATE_SIZE(_Max) ((sizeof(ErlBinMatchState) + (_Max)*sizeof(Eterm))/sizeof(Eterm))
#define HEADER_BIN_MATCHSTATE(_Max) _make_header(ERL_BIN_MATCHSTATE_SIZE((_Max))-1, _TAG_HEADER_BIN_MATCHSTATE)
#define HEADER_NUM_SLOTS(hdr) (header_arity(hdr)-sizeof(ErlBinMatchState)/sizeof(Eterm)+1)
#define make_matchstate(_Ms) make_boxed((Eterm*)(_Ms))
#define ms_matchbuffer(_Ms) &(((ErlBinMatchState*) boxed_val(_Ms))->mb)
#if defined(ERTS_SMP)
#define ERL_BITS_REENTRANT
#else
/* uncomment to test the reentrant API in the non-SMP runtime system */
/* #define ERL_BITS_REENTRANT */
#endif
#ifdef ERL_BITS_REENTRANT
/*
* Reentrant API with the state passed as a parameter.
* (Except when the current Process* already is a parameter.)
*/
#ifdef ERTS_SMP
/* the state resides in the current process' scheduler data */
#define ERL_BITS_DECLARE_STATEP struct erl_bits_state *EBS
#define ERL_BITS_RELOAD_STATEP(P) do{EBS = &(P)->scheduler_data->erl_bits_state;}while(0)
#define ERL_BITS_DEFINE_STATEP(P) struct erl_bits_state *EBS = &(P)->scheduler_data->erl_bits_state
#else
/* reentrant API but with a hidden single global state, for testing only */
extern struct erl_bits_state ErlBitsState_;
#define ERL_BITS_DECLARE_STATEP struct erl_bits_state *EBS = &ErlBitsState_
#define ERL_BITS_RELOAD_STATEP(P) do{}while(0)
#define ERL_BITS_DEFINE_STATEP(P) ERL_BITS_DECLARE_STATEP
#endif
#define ErlBitsState (*EBS)
#define ERL_BITS_PROTO_0 struct erl_bits_state *EBS
#define ERL_BITS_PROTO_1(PARM1) struct erl_bits_state *EBS, PARM1
#define ERL_BITS_PROTO_2(PARM1,PARM2) struct erl_bits_state *EBS, PARM1, PARM2
#define ERL_BITS_PROTO_3(PARM1,PARM2,PARM3) struct erl_bits_state *EBS, PARM1, PARM2, PARM3
#define ERL_BITS_ARGS_0 EBS
#define ERL_BITS_ARGS_1(ARG1) EBS, ARG1
#define ERL_BITS_ARGS_2(ARG1,ARG2) EBS, ARG1, ARG2
#define ERL_BITS_ARGS_3(ARG1,ARG2,ARG3) EBS, ARG1, ARG2, ARG3
#else /* ERL_BITS_REENTRANT */
/*
* Non-reentrant API with a single global state.
*/
extern struct erl_bits_state ErlBitsState;
#define ERL_BITS_DECLARE_STATEP /*empty*/
#define ERL_BITS_RELOAD_STATEP(P) do{}while(0)
#define ERL_BITS_DEFINE_STATEP(P) /*empty*/
#define ERL_BITS_PROTO_0 void
#define ERL_BITS_PROTO_1(PARM1) PARM1
#define ERL_BITS_PROTO_2(PARM1,PARM2) PARM1, PARM2
#define ERL_BITS_PROTO_3(PARM1,PARM2,PARM3) PARM1, PARM2, PARM3
#define ERL_BITS_ARGS_0 /*empty*/
#define ERL_BITS_ARGS_1(ARG1) ARG1
#define ERL_BITS_ARGS_2(ARG1,ARG2) ARG1, ARG2
#define ERL_BITS_ARGS_3(ARG1,ARG2,ARG3) ARG1, ARG2, ARG3
#endif /* ERL_BITS_REENTRANT */
#define erts_bin_offset (ErlBitsState.erts_bin_offset_)
#define erts_current_bin (ErlBitsState.erts_current_bin_)
#define erts_writable_bin (ErlBitsState.erts_writable_bin_)
#define copy_binary_to_buffer(DstBuffer, DstBufOffset, SrcBuffer, SrcBufferOffset, NumBits) \
do { \
if (BIT_OFFSET(DstBufOffset) == 0 && (SrcBufferOffset == 0) && \
(BIT_OFFSET(NumBits)==0)) { \
sys_memcpy(DstBuffer+BYTE_OFFSET(DstBufOffset), \
SrcBuffer, NBYTES(NumBits)); \
} else { \
erts_copy_bits(SrcBuffer, SrcBufferOffset, 1, \
(byte*)DstBuffer, DstBufOffset, 1, NumBits); \
} \
} while (0)
void erts_init_bits(void); /* Initialization once. */
#ifdef ERTS_SMP
void erts_bits_init_state(ERL_BITS_PROTO_0);
void erts_bits_destroy_state(ERL_BITS_PROTO_0);
#endif
/*
* NBYTES(x) returns the number of bytes needed to store x bits.
*/
#define NBYTES(x) (((Uint64)(x) + (Uint64) 7) >> 3)
#define BYTE_OFFSET(ofs) ((Uint) (ofs) >> 3)
#define BIT_OFFSET(ofs) ((ofs) & 7)
/*
* Return number of Eterm words needed for allocation with HAlloc(),
* given a number of bytes.
*/
#define WSIZE(n) ((n + sizeof(Eterm) - 1) / sizeof(Eterm))
/*
* Binary matching.
*/
Eterm erts_bs_start_match_2(Process *p, Eterm Bin, Uint Max);
Eterm erts_bs_get_integer_2(Process *p, Uint num_bits, unsigned flags, ErlBinMatchBuffer* mb);
Eterm erts_bs_get_binary_2(Process *p, Uint num_bits, unsigned flags, ErlBinMatchBuffer* mb);
Eterm erts_bs_get_float_2(Process *p, Uint num_bits, unsigned flags, ErlBinMatchBuffer* mb);
Eterm erts_bs_get_binary_all_2(Process *p, ErlBinMatchBuffer* mb);
/*
* Binary construction, new instruction set.
*/
int erts_new_bs_put_integer(ERL_BITS_PROTO_3(Eterm Integer, Uint num_bits, unsigned flags));
int erts_bs_put_utf8(ERL_BITS_PROTO_1(Eterm Integer));
int erts_bs_put_utf16(ERL_BITS_PROTO_2(Eterm Integer, Uint flags));
int erts_new_bs_put_binary(ERL_BITS_PROTO_2(Eterm Bin, Uint num_bits));
int erts_new_bs_put_binary_all(ERL_BITS_PROTO_2(Eterm Bin, Uint unit));
int erts_new_bs_put_float(Process *c_p, Eterm Float, Uint num_bits, int flags);
void erts_new_bs_put_string(ERL_BITS_PROTO_2(byte* iptr, Uint num_bytes));
Uint erts_bits_bufs_size(void);
Uint32 erts_bs_get_unaligned_uint32(ErlBinMatchBuffer* mb);
void erts_align_utf8_bytes(ErlBinMatchBuffer* mb, byte* buf);
Eterm erts_bs_get_utf8(ErlBinMatchBuffer* mb);
Eterm erts_bs_get_utf16(ErlBinMatchBuffer* mb, Uint flags);
Eterm erts_bs_append(Process* p, Eterm* reg, Uint live, Eterm build_size_term,
Uint extra_words, Uint unit);
Eterm erts_bs_private_append(Process* p, Eterm bin, Eterm sz, Uint unit);
Eterm erts_bs_init_writable(Process* p, Eterm sz);
/*
* Common utilities.
*/
void erts_copy_bits(byte* src, size_t soffs, int sdir,
byte* dst, size_t doffs,int ddir, size_t n);
int erts_cmp_bits(byte* a_ptr, size_t a_offs, byte* b_ptr, size_t b_offs, size_t size);
/*
* Flags for bs_get_* / bs_put_* / bs_init* instructions.
*/
#define BSF_ALIGNED 1 /* Field is guaranteed to be byte-aligned. */
#define BSF_LITTLE 2 /* Field is little-endian (otherwise big-endian). */
#define BSF_SIGNED 4 /* Field is signed (otherwise unsigned). */
#define BSF_EXACT 8 /* Size in bs_init is exact. */
#define BSF_NATIVE 16 /* Native endian. */
#endif /* __ERL_BITS_H__ */
|