⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 erl_bits.c

📁 OTP是开放电信平台的简称
💻 C
📖 第 1 页 / 共 3 页
字号:
	    if (num_bits == 64) {		t[7] = b >> 24;		t[6] = b >> 16;		t[5] = b >> 8;		t[4] = b;	    }#endif	} else {	    byte* t = erts_current_bin+BYTE_OFFSET(erts_bin_offset) + NBYTES(num_bits);#ifdef WORDS_BIGENDIAN	    t[-1] = a >> 24;	    t[-2] = a >> 16;	    t[-3] = a >> 8;	    t[-4] = a;	    if (num_bits == 64) {		t[-5] = b >> 24;		t[-6] = b >> 16;		t[-7] = b >> 8;		t[-8] = b;	    }#else	    t[-1] = a;	    t[-2] = a >> 8;	    t[-3] = a >> 16;	    t[-4] = a >> 24;	    if (num_bits == 64) {		t[-5] = b;		t[-6] = b >> 8;		t[-7] = b >> 16;		t[-8] = b >> 24;	    }#endif	}    } else {	byte *bptr;	double f64;	float f32;		if (num_bits == 64) {	    if (is_float(arg)) {		bptr = (byte *) (float_val(arg) + 1);	    } else if (is_small(arg)) {		f64 = (double) signed_val(arg);		bptr = (byte *) &f64;	    } else if (is_big(arg)) {		if (big_to_double(arg, &f64) < 0) {		    return 0;		}		bptr = (byte *) &f64;	    } else {		return 0;	    }	} else if (num_bits == 32) {	    if (is_float(arg)) {		FloatDef f;		GET_DOUBLE(arg, f);		ERTS_FP_CHECK_INIT(c_p);		f32 = f.fd;		ERTS_FP_ERROR(c_p,f32,;);		bptr = (byte *) &f32;	    } else if (is_small(arg)) {		f32 = (float) signed_val(arg);		bptr = (byte *) &f32;	    } else if (is_big(arg)) {		if (big_to_double(arg, &f64) < 0) {		    return 0;		}		ERTS_FP_CHECK_INIT(c_p);		f32 = (float) f64;		ERTS_FP_ERROR(c_p,f32,;);		bptr = (byte *) &f32;	    } else {		return 0;	    }	} else {	    return 0;	}	if (BIT_IS_MACHINE_ENDIAN(flags)) {	    erts_copy_bits(bptr, 0, 1,		      erts_current_bin,		      erts_bin_offset, 1, num_bits);	} else {	    erts_copy_bits(bptr+NBYTES(num_bits)-1, 0, -1,			   erts_current_bin, erts_bin_offset, 1,			   num_bits);	}    }    erts_bin_offset += num_bits;    return 1;}void erts_new_bs_put_string(ERL_BITS_PROTO_2(byte* iptr, Uint num_bytes)){    if (BIT_OFFSET(erts_bin_offset) != 0) {	erts_copy_bits(iptr, 0, 1, erts_current_bin, erts_bin_offset, 1, num_bytes*8);    } else {	sys_memcpy(erts_current_bin+BYTE_OFFSET(erts_bin_offset), iptr, num_bytes);    }    erts_bin_offset += num_bytes*8;}Etermerts_bs_final2(Process* p, Eterm bin){     ErlSubBin* sb;    ERL_BITS_DEFINE_STATEP(p);    if ((erts_bin_offset & 7) == 0) {return bin;}    sb = (ErlSubBin *) HeapOnlyAlloc(p, ERL_SUB_BIN_SIZE);    sb->thing_word = HEADER_SUB_BIN;    sb->size = (erts_bin_offset - (erts_bin_offset & 7))/8;    sb->bitsize = erts_bin_offset & 7;    sb->offs = 0;    sb->bitoffs = 0;    sb->orig = bin;    return make_binary(sb);}#if !defined(HEAP_FRAG_ELIM_TEST)/* * Old instructions for building binaries. */static voidERTS_INLINE need_bin_buf(ERL_BITS_PROTO_1(int need)){    if (erts_bin_buf_len < need) {#ifdef ERTS_SMP	erts_smp_atomic_add(&bits_bufs_size, need - erts_bin_buf_len);#endif	erts_bin_buf_len = need;	erts_bin_buf = erts_realloc(ERTS_ALC_T_BITS_BUF, erts_bin_buf, erts_bin_buf_len);    }}voiderts_bs_init(ERL_BITS_PROTO_0){    erts_bin_offset = 0;}Etermerts_bs_final(Process* p){    ERL_BITS_DEFINE_STATEP(p);    if (erts_bin_offset % 8 != 0) {	return THE_NON_VALUE;    }    return new_binary_arith(p, erts_bin_buf, erts_bin_offset / 8);}interts_bs_put_integer(ERL_BITS_PROTO_3(Eterm arg, Uint num_bits, unsigned flags)){    unsigned bin_offset = erts_bin_offset;    if (BIT_OFFSET(bin_offset) == 0) {	need_bin_buf(ERL_BITS_ARGS_1(NBYTES(num_bits+bin_offset)));	if (fmt_int(erts_bin_buf+BYTE_OFFSET(bin_offset),		    NBYTES(num_bits), arg, num_bits, flags) < 0) {	    return 0;	}    } else {	byte *iptr;	need_byte_buf(ERL_BITS_ARGS_1(NBYTES(num_bits)));	iptr = byte_buf;	if (fmt_int(iptr, NBYTES(num_bits), arg, num_bits, flags) < 0) {	    return 0;	}	need_bin_buf(ERL_BITS_ARGS_1(NBYTES(num_bits+bin_offset)));	erts_copy_bits(iptr, 0, 1, erts_bin_buf, bin_offset, 1, num_bits);    }    erts_bin_offset = bin_offset + num_bits;    return 1;}interts_bs_put_binary(ERL_BITS_PROTO_2(Eterm arg, Uint num_bits)){    byte *bptr;    Uint bitoffs;    Uint bitsize;    if (!is_binary(arg)) {	return 0;    }    ERTS_GET_BINARY_BYTES(arg, bptr, bitoffs, bitsize);    if (num_bits > 8*binary_size(arg)+bitsize) {	return 0;    }    need_bin_buf(ERL_BITS_ARGS_1(NBYTES(num_bits + erts_bin_offset)));    if ((BIT_OFFSET(erts_bin_offset) == 0) & (bitoffs == 0) & (BIT_OFFSET(num_bits) == 0)) {	sys_memcpy(erts_bin_buf+BYTE_OFFSET(erts_bin_offset),		   bptr, NBYTES(num_bits));    } else {	erts_copy_bits(bptr, bitoffs, 1, erts_bin_buf, erts_bin_offset, 1, num_bits);    }    erts_bin_offset += num_bits;    return 1;}interts_bs_put_binary_all(ERL_BITS_PROTO_1(Eterm arg)){    byte *bptr;    unsigned n;    Uint bitoffs;    Uint bitsize;    if (!is_binary(arg)) {	return 0;    }    ERTS_GET_BINARY_BYTES(arg, bptr, bitoffs, bitsize);    n = 8*binary_size(arg)+bitsize;     need_bin_buf(ERL_BITS_ARGS_1(NBYTES(n + erts_bin_offset)));    if ((BIT_OFFSET(erts_bin_offset) == 0) & (bitoffs == 0) & (bitsize == 0)) {	sys_memcpy(erts_bin_buf+BYTE_OFFSET(erts_bin_offset), bptr, NBYTES(n));    } else {	erts_copy_bits(bptr, bitoffs, 1, erts_bin_buf, erts_bin_offset, 1, n);    }    erts_bin_offset += n;    return 1;}interts_bs_put_float(Process *c_p, Eterm arg, Uint num_bits, int flags){    byte *bptr;    double f64;    float f32;    ERL_BITS_DEFINE_STATEP(c_p);    if (num_bits == 64) {	if (is_float(arg)) {	    bptr = (byte *) (float_val(arg) + 1);	} else if (is_small(arg)) {	    f64 = (double) signed_val(arg);	    bptr = (byte *) &f64;	} else if (is_big(arg)) {	    if (big_to_double(arg, &f64) < 0) {		return 0;	    }	    bptr = (byte *) &f64;	} else {	    return 0;	}    } else if (num_bits == 32) {	if (is_float(arg)) {	    FloatDef f;	    GET_DOUBLE(arg, f);	    ERTS_FP_CHECK_INIT(c_p);	    f32 = f.fd;	    ERTS_FP_ERROR(c_p,f32,;);	    bptr = (byte *) &f32;	} else if (is_small(arg)) {	    f32 = (float) signed_val(arg);	    bptr = (byte *) &f32;	} else if (is_big(arg)) {	    if (big_to_double(arg, &f64) < 0) {		return 0;	    }	    ERTS_FP_CHECK_INIT(c_p);	    f32 = (float) f64;	    ERTS_FP_ERROR(c_p,f32,;);	    bptr = (byte *) &f32;	} else {	    return 0;	}    } else {	return 0;    }    need_bin_buf(ERL_BITS_ARGS_1(NBYTES(num_bits + erts_bin_offset)));    if (BIT_OFFSET(erts_bin_offset) == 0) {	if (BIT_IS_MACHINE_ENDIAN(flags)) {	    byte* t = erts_bin_buf+BYTE_OFFSET(erts_bin_offset);	    t[0] = bptr[0];	    t[1] = bptr[1];	    t[2] = bptr[2];	    t[3] = bptr[3];	    if (num_bits == 64) {		t[4] = bptr[4];		t[5] = bptr[5];		t[6] = bptr[6];		t[7] = bptr[7];	    }	} else {	    byte* t = erts_bin_buf+BYTE_OFFSET(erts_bin_offset) + NBYTES(num_bits);	    t[-1] = bptr[0];	    t[-2] = bptr[1];	    t[-3] = bptr[2];	    t[-4] = bptr[3];	    if (num_bits == 64) {		t[-5] = bptr[4];		t[-6] = bptr[5];		t[-7] = bptr[6];		t[-8] = bptr[7];	    }	}    } else {	if (BIT_IS_MACHINE_ENDIAN(flags)) {	    erts_copy_bits(bptr, 0, 1,			   erts_bin_buf,			   erts_bin_offset, 1, num_bits);	} else {	    erts_copy_bits(bptr+NBYTES(num_bits)-1, 0, -1,			   erts_bin_buf, erts_bin_offset, 1,			   num_bits);	}    }    erts_bin_offset += num_bits;    return 1;}void erts_bs_put_string(ERL_BITS_PROTO_2(byte* iptr, Uint num_bytes)){    need_bin_buf(ERL_BITS_ARGS_1(num_bytes + NBYTES(erts_bin_offset)));    if (BIT_OFFSET(erts_bin_offset) != 0) {	erts_copy_bits(iptr, 0, 1, erts_bin_buf, erts_bin_offset, 1, num_bytes*8);    } else {	sys_memcpy(erts_bin_buf+BYTE_OFFSET(erts_bin_offset), iptr, num_bytes);    }    erts_bin_offset += num_bytes*8;}#endifstatic byteget_bit(byte b, size_t offs) {    return (b >> (7-offs)) & 1;}interts_cmp_bits(byte* a_ptr, size_t a_offs, byte* b_ptr, size_t b_offs, size_t size) {    byte a;    byte b;    byte a_bit;    byte b_bit;    Uint lshift;    Uint rshift;    int cmp;        if (((a_offs | b_offs | size) & 7) == 0) {	int byte_size = size >> 3;	return sys_memcmp(a_ptr, b_ptr, byte_size);    }    /* Compare bit by bit until a_ptr is aligned on byte boundary */    a = *a_ptr++;    b = *b_ptr++;    while (size > 0) {	a_bit = get_bit(a, a_offs);	b_bit = get_bit(b, b_offs);	if ((cmp = (a_bit-b_bit)) != 0) {	    return cmp;	}	size--;	b_offs++;	if (b_offs == 8) {	    b_offs = 0;	    b = *b_ptr++;	}	a_offs++;	if (a_offs == 8) {	    a_offs = 0;	    a = *a_ptr++;	    break;	}    }    /* Compare byte by byte as long as at least 8 bits remain */    lshift = b_offs;    rshift = 8 - lshift;    while (size >= 8) {	byte b_cmp = (b << lshift);	b = *b_ptr++;	b_cmp |= b >> rshift;	if ((cmp = (a - b_cmp)) != 0) {	    return cmp;	}	a = *a_ptr++;	size -= 8;    }    /* Compare the remaining bits bit by bit */    while (size > 0) {	a_bit = get_bit(a, a_offs);	b_bit = get_bit(b, b_offs);	if ((cmp = (a_bit-b_bit)) != 0) {	    return cmp;	}	a_offs++;	if (a_offs == 8) {	    a_offs = 0;	    a = *a_ptr++;	}	b_offs++;	if (b_offs == 8) {	    b_offs = 0;	    b = *b_ptr++;	}	size--;    }    return 0;}/* * The basic bit copy operation. Copies n bits from the source buffer to * the destination buffer. Depending on the directions, it can reverse the * copied bits. */void erts_copy_bits(byte* src,	/* Base pointer to source. */	       size_t soffs,	/* Bit offset for source relative to src. */	       int sdir,	/* Direction: 1 (forward) or -1 (backward). */	       byte* dst,	/* Base pointer to destination. */	       size_t doffs,	/* Bit offset for destination relative to dst. */	       int ddir,	/* Direction: 1 (forward) or -1 (backward). */	       size_t n)	/* Number of bits to copy. */{    Uint lmask;    Uint rmask;    Uint count;    Uint deoffs;    if (n == 0) {	return;    }    src += sdir*BYTE_OFFSET(soffs);    dst += ddir*BYTE_OFFSET(doffs);    soffs = BIT_OFFSET(soffs);    doffs = BIT_OFFSET(doffs);    deoffs = BIT_OFFSET(doffs+n);    lmask = (doffs) ? MAKE_MASK(8-doffs) : 0;    rmask = (deoffs) ? (MAKE_MASK(deoffs)<<(8-deoffs)) : 0;    /*     * Take care of the case that all bits are in the same byte.     */    if (doffs+n < 8) {		/* All bits are in the same byte */	lmask = (lmask & rmask) ? (lmask & rmask) : (lmask | rmask);	if (soffs == doffs) {	    *dst = MASK_BITS(*src,*dst,lmask);	} else if (soffs > doffs) {	    Uint bits = (*src << (soffs-doffs));	    if (soffs+n > 8) {		src += sdir;		bits |= (*src >> (8-(soffs-doffs)));	    }	    *dst = MASK_BITS(bits,*dst,lmask);	} else {	    *dst = MASK_BITS((*src >> (doffs-soffs)),*dst,lmask);	}	return;			/* We are done! */    }    /*     * At this point, we know that the bits are in 2 or more bytes.     */    count = ((lmask) ? (n - (8 - doffs)) : n) >> 3;    if (soffs == doffs) {	/*	 * The bits are aligned in the same way. We can just copy the bytes	 * (except for the first and last bytes). Note that the directions	 * might be different, so we can't just use memcpy().	 */	if (lmask) {	    *dst = MASK_BITS(*src, *dst, lmask);	    dst += ddir;	    src += sdir;	}	while (count--) {	    *dst = *src;	    dst += ddir;	    src += sdir;	}	if (rmask) {	    *dst = MASK_BITS(*src,*dst,rmask);	}    } else {	Uint bits;	Uint bits1;	Uint rshift;	Uint lshift;	/*	 * The tricky case. The bits must be shifted into position.	 */		if (soffs > doffs) {	    lshift = (soffs - doffs);	    rshift = 8 - lshift;	    bits = *src;	    if (soffs + n > 8) {		src += sdir;	    }	} else {	    rshift = (doffs - soffs);	    lshift = 8 - rshift;	    bits = 0;	}	    	if (lmask) {	    bits1 = bits << lshift;	    bits = *src;	    src += sdir;	    bits1 |= (bits >> rshift);	    *dst = MASK_BITS(bits1,*dst,lmask);	    dst += ddir;	}	while (count--) {	    bits1 = bits << lshift;	    bits = *src;	    src += sdir;	    *dst = bits1 | (bits >> rshift);	    dst += ddir;	}		if (rmask) {	    bits1 = bits << lshift;	    if ((rmask << rshift) & 0xff) {		bits = *src;		bits1 |= (bits >> rshift);	    }	    *dst = MASK_BITS(bits1,*dst,rmask);	}    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -