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

📄 erl_bits.c

📁 OTP是开放电信平台的简称
💻 C
📖 第 1 页 / 共 3 页
字号:
	byte* ptr = LSB; 	byte c = 1;	/* sign extend MSB */	*MSB |= ~MAKE_MASK(bits);	/* two's complement */	while (ptr <= MSB) {	    byte pd = ~(*ptr);	    byte d = pd + c;	    c = (d < pd);	    *ptr++ = d;	}	sgn = 1;    }    /* normalize */    while ((*MSB == 0) && (MSB > LSB)) {	MSB--;	bytes--;    }    /* check for guaranteed small num */    switch (bytes) {    case 1:	v32 = LSB[0];	goto big_small;    case 2:	v32 = LSB[0] + (LSB[1]<<8); 	goto big_small;     case 3: 	v32 = LSB[0] + (LSB[1]<<8) + (LSB[2]<<16); 	goto big_small;#if !defined(ARCH_64)    case 4:	v32 = (LSB[0] + (LSB[1]<<8) + (LSB[2]<<16) + (LSB[3]<<24));	if (!IS_USMALL(sgn, v32)) {	  goto make_big;	}#else    case 4:      ReadToVariable(v32, LSB, 4);					      goto big_small;    case 5:	      ReadToVariable(v32, LSB, 5);					      goto big_small;    case 6:	      ReadToVariable(v32, LSB, 6);      goto big_small;     case 7:      ReadToVariable(v32, LSB, 7);      goto big_small;     case 8:      ReadToVariable(v32, LSB, 8);      if (!IS_USMALL(sgn, v32)) {	goto make_big;   	}#endif       big_small:			/* v32 loaded with value which fits in fixnum */	if (sgn) {	    res = make_small(-((Sint)v32));	} else {	    res = make_small(v32);	}	break;    make_big:	hp = HeapOnlyAlloc(p, BIG_UINT_HEAP_SIZE);	if (sgn) {	  hp[0] = make_neg_bignum_header(1);	} else {	  hp[0] = make_pos_bignum_header(1);	}	BIG_DIGIT(hp,0) = DLOW(v32);	BIG_DIGIT(hp,1) = DHIGH(v32);	res = make_big(hp);	break;    default:	words_needed = 1+WSIZE(bytes);	hp = HeapOnlyAlloc(p, words_needed);	hp_end = hp + words_needed;	res = bytes_to_big(LSB, bytes, sgn, hp); 	if (is_small(res)) {	    p->htop = hp;	} else if ((actual = bignum_header_arity(*hp)+1) < words_needed) {	    p->htop = hp + actual;	}	break;    }    if (LSB != bigbuf) {	erts_free(ERTS_ALC_T_TMP, (void *) LSB);    }    return res;}Etermerts_bs_get_binary_2(Process *p, Uint num_bits, unsigned flags, ErlBinMatchBuffer* mb){    ErlSubBin* sb;    size_t num_bytes;		/* Number of bytes in binary. */    if (num_bits == 0) {		/* Empty binary. */	return new_binary(p, NULL, 0);    }    if (mb->size - mb->offset < num_bits) {	/* Asked for too many bits.  */	return THE_NON_VALUE;    }        /*     * From now on, we can't fail.     */    num_bytes = NBYTES(num_bits);    sb = (ErlSubBin *) HeapOnlyAlloc(p, ERL_SUB_BIN_SIZE);        sb->thing_word = HEADER_SUB_BIN;    sb->orig = mb->orig;    sb->size = BYTE_OFFSET(num_bits);    sb->bitsize = BIT_OFFSET(num_bits);    sb->offs = BYTE_OFFSET(mb->offset);    sb->bitoffs = BIT_OFFSET(mb->offset);    mb->offset += num_bits;        return make_binary(sb);}Etermerts_bs_get_float_2(Process *p, Uint num_bits, unsigned flags, ErlBinMatchBuffer* mb){    Eterm* hp;    float f32;    double f64;    byte* fptr;    FloatDef f;    if (num_bits == 0) {	f.fd = 0.0;	hp = HeapOnlyAlloc(p, FLOAT_SIZE_OBJECT);	PUT_DOUBLE(f, hp);	return make_float(hp);    }    if (mb->size - mb->offset < num_bits) {	/* Asked for too many bits.  */	return THE_NON_VALUE;    }    if (num_bits == 32) {	fptr = (byte *) &f32;    } else if (num_bits == 64) {	fptr = (byte *) &f64;    } else {	return THE_NON_VALUE;    }    if (BIT_IS_MACHINE_ENDIAN(flags)) {	erts_copy_bits(mb->base, mb->offset, 1,		  fptr, 0, 1,		  num_bits);    } else {	erts_copy_bits(mb->base, mb->offset, 1,		  fptr + NBYTES(num_bits) - 1, 0, -1,		  num_bits);    }    ERTS_FP_CHECK_INIT(p);    if (num_bits == 32) {	ERTS_FP_ERROR_THOROUGH(p, f32, return THE_NON_VALUE);	f.fd = f32;    } else {	ERTS_FP_ERROR_THOROUGH(p, f64, return THE_NON_VALUE);	f.fd = f64;    }    mb->offset += num_bits;    hp = HeapOnlyAlloc(p, FLOAT_SIZE_OBJECT);    PUT_DOUBLE(f, hp);    return make_float(hp);}Etermerts_bs_get_binary_all_2(Process *p, ErlBinMatchBuffer* mb){  ErlSubBin* sb;  Uint size;  size =  mb->size-mb->offset;  sb = (ErlSubBin *) HeapOnlyAlloc(p, ERL_SUB_BIN_SIZE);  sb->thing_word = HEADER_SUB_BIN;  sb->size = BYTE_OFFSET(size);  sb->bitsize = BIT_OFFSET(size);  sb->offs = BYTE_OFFSET(mb->offset);  sb->bitoffs = BIT_OFFSET(mb->offset);  sb->orig = mb->orig;  mb->offset = mb->size;    return make_binary(sb);}voiderts_bs_save_2(int index, ErlBinMatchState* ms){  ms->save_offset[index] = (ms->mb).offset;}void  erts_bs_restore_2(int index, ErlBinMatchState* ms){  (ms->mb).offset = ms->save_offset[index];}/**************************************************************** *** *** Building binaries *** ****************************************************************//* COPY_VAL: * copy sz byte from val to dst buffer,  * dst, val are updated!!! */#define COPY_VAL(dst,ddir,val,sz) do { \   Uint __sz = (sz); \   while(__sz) { \     switch(__sz) { \     default: \     case 4: *dst = (val&0xff); dst += ddir; val >>= 8; __sz--; \     case 3: *dst = (val&0xff); dst += ddir; val >>= 8; __sz--; \     case 2: *dst = (val&0xff); dst += ddir; val >>= 8; __sz--; \     case 1: *dst = (val&0xff); dst += ddir; val >>= 8; __sz--; \     } \   } \ } while(0)/* calculate a - *cp (carry)  (store result in b), *cp is updated! */#define SUBc(a, cp, b) do { \   byte __x = (a); \   byte __y = (__x - (*(cp))); \   (*cp) = (__y > __x); \   *(b) = ~__y; \ } while(0)  static intfmt_int(byte *buf, Uint sz, Eterm val, Uint size, Uint flags){    unsigned long offs;    if (size == 0) {	return 0;    }    offs = BIT_OFFSET(size);    if (is_small(val)) {	Sint v = signed_val(val);	if (flags & BSF_LITTLE) { /* Little endian */	    sz--;	    COPY_VAL(buf,1,v,sz);	    *buf = offs ? ((v << (8-offs)) & 0xff) : (v & 0xff);	} else {		/* Big endian */	    buf += (sz - 1);	    if (offs) {		*buf-- = (v << (8-offs)) & 0xff;		sz--;		v >>= offs;	    }	    COPY_VAL(buf,-1,v,sz);	}    } else if (is_big(val)) {	int sign   = big_sign(val);	Uint ds  = big_size(val)*sizeof(digit_t);  /* number of digits bytes */	digit_t* dp = big_v(val);	int n = MIN(sz,ds);	if (flags & BSF_LITTLE) {	    sz -= n;                       /* pad with this amount */	    if (sign) {		int c = 1;		while(n >= sizeof(digit_t)) {		    digit_t d = *dp++;		    int i;		    for(i = 0; i < sizeof(digit_t); ++i) {			SUBc((d&0xff), &c, buf);			buf++;			d >>= 8;		    }		    n -= sizeof(digit_t);		}		if (n) {		    digit_t d = *dp;		    do {			SUBc((d&0xff), &c, buf);			buf++;			d >>= 8;		    } while (--n > 0);		}		/* pad */		while(sz--) {		    SUBc(0, &c, buf);		    buf++;		}	    }	    else {		while(n >= sizeof(digit_t)) {		    digit_t d = *dp++;		    int i;		    for(i = 0; i < sizeof(digit_t); ++i) {			*buf++ = (d & 0xff);			d >>= 8;		    }		    n -= sizeof(digit_t);		}		if (n) {		    digit_t d = *dp;		    do {			*buf++ = (d & 0xff);			d >>= 8;		    } while (--n > 0);		}		/* pad */		while(sz) {		    *buf++ = 0;		    sz--;		}	    }	    /* adjust MSB!!! */	    if (offs) {		buf--;		*buf <<= (8 - offs);	    }	}	else {   /* BIG ENDIAN */	    Uint acc = 0;	/* acc must be large enough to fit two digits */	    buf += (sz - 1);              /* end of buffer */	    sz -= n;                      /* pad with this amount */	    offs = offs ? (8-offs) : 0;   /* shift offset */	    if (sign) { /* SIGNED */		int c = 1;		while(n >= sizeof(digit_t)) {		    int i;		    acc |= (*dp++ << offs);		    for(i = 0; i < sizeof(digit_t); ++i) {			SUBc((acc&0xff), &c, buf);			buf--;			acc >>= 8;		    }		    n -= sizeof(digit_t);		}		if (n) {		    acc |= (*dp << offs);		    do {			SUBc((acc & 0xff), &c, buf);			buf--;			acc >>= 8;		    } while (--n > 0);		}		/* pad */		while(sz--) {		    SUBc((acc & 0xff), &c, buf);		    buf--;		    acc >>= 8;		}	    }	    else { /* UNSIGNED */		while(n >= sizeof(digit_t)) {		    int i;		    acc |= (*dp++ << offs);		    for(i = 0; i < sizeof(digit_t); ++i) {			*buf-- = (acc & 0xff);			acc >>= 8;		    }		    n -= sizeof(digit_t);		}		if (n) {		    acc |= (*dp << offs);		    do {			*buf-- = acc & 0xff;			acc >>= 8;		    } while (--n > 0);		}		while(sz--) {		    *buf-- = acc & 0xff;		    acc >>= 8;		}	    }	}    } else {			/* Neither small nor big */	return -1;    }    return 0;}static voidERTS_INLINE need_byte_buf(ERL_BITS_PROTO_1(int need)){    if (byte_buf_len < need) {#ifdef ERTS_SMP	erts_smp_atomic_add(&bits_bufs_size, need - byte_buf_len);#endif	byte_buf_len = need;	byte_buf = erts_realloc(ERTS_ALC_T_BITS_BUF, byte_buf, byte_buf_len);    }}interts_new_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) {	if (fmt_int(erts_current_bin+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;	}	erts_copy_bits(iptr, 0, 1, erts_current_bin, bin_offset, 1, num_bits);    }    erts_bin_offset = bin_offset + num_bits;    return 1;}interts_new_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;    }    copy_binary_to_buffer(erts_current_bin, erts_bin_offset, bptr, bitoffs, num_bits);    erts_bin_offset += num_bits;    return 1;}interts_new_bs_put_binary_all(ERL_BITS_PROTO_1(Eterm arg)){   byte *bptr;   Uint bitoffs;   Uint bitsize;   Uint num_bits;   if (!is_binary(arg)) {       return 0;   }   ERTS_GET_BINARY_BYTES(arg, bptr, bitoffs, bitsize);   num_bits = 8*binary_size(arg)+bitsize;   copy_binary_to_buffer(erts_current_bin, erts_bin_offset, bptr, bitoffs, num_bits);   erts_bin_offset += num_bits;   return 1;}interts_new_bs_put_float(Process *c_p, Eterm arg, Uint num_bits, int flags){    ERL_BITS_DEFINE_STATEP(c_p);    if (BIT_OFFSET(erts_bin_offset) == 0) {	Uint32 a;	Uint32 b;		if (num_bits == 64) {	    union {		double f64;		Uint32 i32[2];	    } u;	    if (is_float(arg)) {		FloatDef *fdp = (FloatDef*)(float_val(arg) + 1);		a = fdp->fw[0];		b = fdp->fw[1];	    } else if (is_small(arg)) {		u.f64 = (double) signed_val(arg);		a = u.i32[0];		b = u.i32[1];	    } else if (is_big(arg)) {		if (big_to_double(arg, &u.f64) < 0) {		    return 0;		}		a = u.i32[0];		b = u.i32[1];	    } else {		return 0;	    }	} else if (num_bits == 32) {	    union {		float f32;		Uint32 i32;	    } u;	    b = 0;	    if (is_float(arg)) {		FloatDef f;		GET_DOUBLE(arg, f);		ERTS_FP_CHECK_INIT(c_p);		u.f32 = f.fd;		ERTS_FP_ERROR(c_p,u.f32,;);		a = u.i32;	    } else if (is_small(arg)) {		u.f32 = (float) signed_val(arg);		a = u.i32;	    } else if (is_big(arg)) {		double f64;		if (big_to_double(arg, &f64) < 0) {		    return 0;		}		ERTS_FP_CHECK_INIT(c_p);		u.f32 = (float) f64;		ERTS_FP_ERROR(c_p,u.f32,;);		a = u.i32;	    } else {		return 0;	    }	} else {	    return 0;	}	if (BIT_IS_MACHINE_ENDIAN(flags)) {	    byte* t = erts_current_bin+BYTE_OFFSET(erts_bin_offset);#ifdef WORDS_BIGENDIAN	    t[0] = a >> 24;	    t[1] = a >> 16;	    t[2] = a >> 8;	    t[3] = a;	    if (num_bits == 64) {		t[4] = b >> 24;		t[5] = b >> 16;		t[6] = b >> 8;		t[7] = b;	    }#else	    t[3] = a >> 24;	    t[2] = a >> 16;	    t[1] = a >> 8;	    t[0] = a;

⌨️ 快捷键说明

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