📄 erl_bits.h
字号:
/* ``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 via the world wide web 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. * * The Initial Developer of the Original Code is Ericsson Utvecklings AB. * Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings * AB. All Rights Reserved.'' * * $Id$ */#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 {#if !defined(HEAP_FRAG_ELIM_TEST) /* * Used for matching. */ ErlBinMatchBuffer erts_mb_; /* Current match buffer. */ ErlBinMatchBuffer erts_save_mb_[MAX_REG]; /* Saved match buffers. */#endif /* * 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). */ unsigned erts_bin_offset_;#if !defined(HEAP_FRAG_ELIM_TEST) /* * The following variables are only used for building binaries * using the old instructions. */ byte* erts_bin_buf_; unsigned erts_bin_buf_len_;#endif};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-1)*sizeof(Eterm))/sizeof(Eterm)) #define HEADER_BIN_MATCHSTATE(_Max) _make_header(ERL_BIN_MATCHSTATE_SIZE(_Max)-1, _TAG_HEADER_BIN_MATCHSTATE)#define make_matchstate(_Ms) make_boxed((Eterm*)(_Ms)) #define ms_matchbuffer(_Ms) &(((ErlBinMatchState*)(_Ms - TAG_PRIMARY_BOXED))->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 */#if !defined(HEAP_FRAG_ELIM_TEST)# define erts_mb (ErlBitsState.erts_mb_)# define erts_save_mb (ErlBitsState.erts_save_mb_)#endif#define erts_bin_offset (ErlBitsState.erts_bin_offset_)#define erts_current_bin (ErlBitsState.erts_current_bin_)#if !defined(HEAP_FRAG_ELIM_TEST)#define erts_bin_buf (ErlBitsState.erts_bin_buf_)#define erts_bin_buf_len (ErlBitsState.erts_bin_buf_len_)#define erts_InitMatchBuf(Src, Fail) \do { \ Eterm _Bin = (Src); \ if (!is_binary(_Bin)) { \ Fail; \ } else { \ Eterm _orig; \ Uint _offs; \ Uint _bitoffs; \ Uint _bitsize; \ \ ERTS_GET_REAL_BIN(_Bin, _orig, _offs, _bitoffs, _bitsize); \ erts_mb.orig = _orig; \ erts_mb.base = binary_bytes(_orig); \ erts_mb.offset = 8 * _offs+_bitoffs; \ erts_mb.size = binary_size(_Bin) * 8 + erts_mb.offset+_bitsize; \ } \} while (0)#endif#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_SMPvoid 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) (((x) + 7) >> 3) #define BYTE_OFFSET(ofs) ((unsigned) (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. */int erts_bs_start_match(ERL_BITS_PROTO_1(Eterm Bin));int erts_bs_skip_bits(ERL_BITS_PROTO_1(Uint num_bits));int erts_bs_skip_bits_all(ERL_BITS_PROTO_0);int erts_bs_test_tail(ERL_BITS_PROTO_1(Uint num_bits));void erts_bs_save(ERL_BITS_PROTO_1(int index));void erts_bs_restore(ERL_BITS_PROTO_1(int index));Eterm erts_bs_get_integer(Process *p, Uint num_bits, unsigned flags);Eterm erts_bs_get_binary(Process *p, Uint num_bits, unsigned flags);Eterm erts_bs_get_float(Process *p, Uint num_bits, unsigned flags);Eterm erts_bs_get_binary_all(Process *p);Eterm erts_bs_start_match_2(Process *p, Eterm Bin, Uint Max);void erts_bs_save_2(int index, ErlBinMatchState* ms);void erts_bs_restore_2(int index, ErlBinMatchState* ms);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_new_bs_put_binary(ERL_BITS_PROTO_2(Eterm Bin, Uint num_bits));int erts_new_bs_put_binary_all(ERL_BITS_PROTO_1(Eterm Bin));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));/* * Binary construction, old instruction set. */void erts_bs_init(ERL_BITS_PROTO_0);Eterm erts_bs_final(Process* p);Eterm erts_bs_final2(Process* p, Eterm bin);Uint erts_bits_bufs_size(void);int erts_bs_put_integer(ERL_BITS_PROTO_3(Eterm Integer, Uint num_bits, unsigned flags));int erts_bs_put_binary(ERL_BITS_PROTO_2(Eterm Bin, Uint num_bits));int erts_bs_put_binary_all(ERL_BITS_PROTO_1(Eterm Bin));int erts_bs_put_float(Process *c_p, Eterm Float, Uint num_bits, int flags);void erts_bs_put_string(ERL_BITS_PROTO_2(byte* iptr, Uint num_bytes));/* * 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__ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -