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

📄 utils.c

📁 OTP是开放电信平台的简称
💻 C
📖 第 1 页 / 共 5 页
字号:
		}	    case (_TAG_HEADER_EXTERNAL_PID >> _TAG_PRIMARY_SIZE):		if (is_internal_pid(b)) {		    bnode = erts_this_node;		    bdata = internal_pid_data(b);		} else if (is_external_pid(b)) {		    bnode = external_pid_node(b);		    bdata = external_pid_data(b);		} else {		    a_tag = EXTERNAL_PID_DEF;		    goto mixed_types;		}		anode = external_pid_node(a);		adata = external_pid_data(a);		goto pid_common;	    case (_TAG_HEADER_EXTERNAL_PORT >> _TAG_PRIMARY_SIZE):		if (is_internal_port(b)) {		    bnode = erts_this_node;		    bdata = internal_port_data(b);		} else if (is_external_port(b)) {		    bnode = external_port_node(b);		    bdata = external_port_data(b);		} else {		    a_tag = EXTERNAL_PORT_DEF;		    goto mixed_types;		}		anode = external_port_node(a);		adata = external_port_data(a);		goto port_common;	    case (_TAG_HEADER_REF >> _TAG_PRIMARY_SIZE):		/*		 * Note! When comparing refs we need to compare ref numbers		 * (32-bit words), *not* ref data words.		 */				if (is_internal_ref(b)) {		    bnode = erts_this_node;		    bnum = internal_ref_numbers(b);		    blen = internal_ref_no_of_numbers(b);		} else if(is_external_ref(b)) {		    bnode = external_ref_node(b);		    bnum = external_ref_numbers(b);		    blen = external_ref_no_of_numbers(b);		} else {		    a_tag = REF_DEF;		    goto mixed_types;		}		anode = erts_this_node;		anum = internal_ref_numbers(a);		alen = internal_ref_no_of_numbers(a);			    ref_common:		CMP_NODES(anode, bnode);				ASSERT(alen > 0 && blen > 0);		if (alen != blen) {		    if (alen > blen) {			do {			    if (anum[alen - 1] != 0)				return 1;			    alen--;			} while (alen > blen);		    }		    else {			do {			    if (bnum[blen - 1] != 0)				return -1;			    blen--;			} while (alen < blen);		    }		}				ASSERT(alen == blen);		for (i = (Sint) alen - 1; i >= 0; i--)		    if (anum[i] != bnum[i])			return anum[i] < bnum[i] ? -1 : 1;		return 0;	    case (_TAG_HEADER_EXTERNAL_REF >> _TAG_PRIMARY_SIZE):		if (is_internal_ref(b)) {		    bnode = erts_this_node;		    bnum = internal_ref_numbers(b);		    blen = internal_ref_no_of_numbers(b);		} else if (is_external_ref(b)) {		    bnode = external_ref_node(b);		    bnum = external_ref_numbers(b);		    blen = external_ref_no_of_numbers(b);		} else {		    a_tag = EXTERNAL_REF_DEF;		    goto mixed_types;		}		anode = external_ref_node(a);		anum = external_ref_numbers(a);		alen = external_ref_no_of_numbers(a);		goto ref_common;	    default:		/* Must be a binary */		ASSERT(is_binary(a));		if (is_not_binary(b)) {		    a_tag = BINARY_DEF;		    goto mixed_types;		} else {		    Uint a_size = binary_size(a);		    Uint b_size = binary_size(b);		    Uint a_bitsize;		    Uint b_bitsize;		    Uint a_bitoffs;		    Uint b_bitoffs;		    Uint min_size;		    int cmp;		    byte* a_ptr;		    byte* b_ptr;		    ERTS_GET_BINARY_BYTES(a, a_ptr, a_bitoffs, a_bitsize);		    ERTS_GET_BINARY_BYTES(b, b_ptr, b_bitoffs, b_bitsize);		    if ((a_bitsize | b_bitsize | a_bitoffs | b_bitoffs) == 0) {			min_size = (a_size < b_size) ? a_size : b_size;			if ((cmp = sys_memcmp(a_ptr, b_ptr, min_size)) != 0) {			    return cmp;			} else {			    return a_size - b_size;			}		    }		    else {			a_size = (a_size << 3) + a_bitsize;			b_size = (b_size << 3) + b_bitsize;			min_size = (a_size < b_size) ? a_size : b_size;			if ((cmp = erts_cmp_bits(a_ptr,a_bitoffs,						 b_ptr,b_bitoffs,min_size)) != 0) {			    return cmp;			}			else {			    return a_size - b_size;			}		    }		}	    }	}    }    /*     * Take care of the case that the tags are different.     */ mixed_types:    b_tag = tag_val_def(b);    {	FloatDef f1, f2;	Eterm big;	switch(_NUMBER_CODE(a_tag, b_tag)) {	case SMALL_BIG:	    big = small_to_big(signed_val(a), big_buf);	    return big_comp(big, b);	case SMALL_FLOAT:	    f1.fd = signed_val(a);	    GET_DOUBLE(b, f2);	    return float_comp(f1.fd, f2.fd);	case BIG_SMALL:	    big = small_to_big(signed_val(b), big_buf);	    return big_comp(a, big);	case BIG_FLOAT:	    if (big_to_double(a, &f1.fd) < 0) {		return big_sign(a) ? -1 : 1;	    }	    GET_DOUBLE(b, f2);	    return float_comp(f1.fd, f2.fd);	case FLOAT_SMALL:	    GET_DOUBLE(a, f1);	    f2.fd = signed_val(b);	    return float_comp(f1.fd, f2.fd);	case FLOAT_BIG:	    if (big_to_double(b, &f2.fd) < 0) {		return big_sign(b) ? 1 : -1;	    }	    GET_DOUBLE(a, f1);	    return float_comp(f1.fd, f2.fd);	default:	    return b_tag - a_tag;	}    }#undef CMP_NODES}voiderts_cleanup_externals(ExternalThing *etp){    ExternalThing *tetp;    tetp = etp;    while(tetp) {	erts_deref_node_entry(tetp->node);	tetp = tetp->next;    }}Etermstore_external_or_ref_(Uint **hpp, ExternalThing **etpp, Eterm ns){    Uint i;    Uint size;    Uint *from_hp;    Uint *to_hp = *hpp;    ASSERT(is_external(ns) || is_internal_ref(ns));    if(is_external(ns)) {	from_hp = external_val(ns);	size = thing_arityval(*from_hp) + 1;	*hpp += size;	for(i = 0; i < size; i++)	    to_hp[i] = from_hp[i];	erts_refc_inc(&((ExternalThing *) to_hp)->node->refc, 2);	((ExternalThing *) to_hp)->next = *etpp;	*etpp = (ExternalThing *) to_hp;	return make_external(to_hp);    }    /* Internal ref */    from_hp = internal_ref_val(ns);    size = thing_arityval(*from_hp) + 1;    *hpp += size;    for(i = 0; i < size; i++)	to_hp[i] = from_hp[i];    return make_internal_ref(to_hp);}Etermstore_external_or_ref_in_proc_(Process *proc, Eterm ns){    Uint sz;    Uint *hp;    ASSERT(is_external(ns) || is_internal_ref(ns));    sz = NC_HEAP_SIZE(ns);    ASSERT(sz > 0);    hp = HAlloc(proc, sz);    return store_external_or_ref_(&hp, &MSO(proc).externals, ns);}/*  *  member(X,Y) *  returns 0 if X is a member of list Y *  returns 1 if X is not a member of list Y *  returns 2 if Y is not a list or is a badly formed list */intmember(Eterm x, Eterm y){    Eterm* z;    if (is_nil(y)) return(1); /* empty list */    if (is_not_list(y)) return(2); /* bad argument */    z = list_val(y);    for (;;) {	if (eq(*z, x)) return(0);	if (is_nil(*(z + 1))) return(1); /* end of list */	if (is_not_list(*(z + 1))) return(2); /* badly formed list */	z = list_val(*(z + 1));    }}void bin_write(int to, void *to_arg, byte* buf, int sz){    int i;    for (i=0;i<sz;i++) {	if (IS_DIGIT(buf[i]))	    erts_print(to, to_arg, "%d,", buf[i]);	else if (IS_PRINT(buf[i])) {	    erts_print(to, to_arg, "%c,", buf[i]);	}	else	    erts_print(to, to_arg, "%d,", buf[i]);    }    erts_putc(to, to_arg, '\n');}/* Fill buf with the contents of bytelist list    return number of chars in list or -1 for error */intintlist_to_buf(Eterm list, char *buf, int len){    Eterm* listptr;    int sz = 0;    if (is_nil(list)) 	return 0;    if (is_not_list(list))	return -1;    listptr = list_val(list);    while (sz < len) {	if (!is_byte(*listptr)) 	    return -1;	buf[sz++] = unsigned_val(*listptr);	if (is_nil(*(listptr + 1)))	    return(sz);	if (is_not_list(*(listptr + 1))) 	    return -1;	listptr = list_val(*(listptr + 1));    }    return -1;			/* not enough space */}/*** Convert an integer to a byte list** return pointer to converted stuff (need not to be at start of buf!)*/char* Sint_to_buf(Sint n, struct Sint_buf *buf){    char* p = &buf->s[sizeof(buf->s)-1];    int sign = 0;    *p-- = '\0'; /* null terminate */    if (n == 0)	*p-- = '0';    else if (n < 0) {	sign = 1;	n = -n;    }    while (n != 0) {	*p-- = (n % 10) + '0';	n /= 10;    }    if (sign)	*p-- = '-';    return p+1;}/* Build a list of integers in some safe memory area** Memory must be pre allocated prio call 2*len in size** hp is a pointer to the "heap" pointer on return** this pointer is updated to point after the list*/Etermbuf_to_intlist(Eterm** hpp, char *buf, int len, Eterm tail){    Eterm* hp = *hpp;    buf += (len-1);    while(len > 0) {	tail = CONS(hp, make_small((byte)*buf), tail);	hp += 2;	buf--;	len--;    }    *hpp = hp;    return tail;}/*** Write io list in to a buffer.**** An iolist is defined as:**** iohead ::= Binary**        |   Byte (i.e integer in range [0..255]**        |   iolist**        ;**** iotail ::= []**        |   Binary  (added by tony)**        |   iolist**        ;**** iolist ::= []**        |   Binary**        |   [ iohead | iotail]**        ;** ** Return remaining bytes in buffer on success**        -1 on overflow**        -2 on type error (including that result would not be a whole number of bytes)*/int io_list_to_buf(Eterm obj, char* buf, int len){    Eterm* objp;    DECLARE_ESTACK(s);    goto L_again;        while (!ESTACK_ISEMPTY(s)) {	obj = ESTACK_POP(s);    L_again:	if (is_list(obj)) {	L_iter_list:	    objp = list_val(obj);	    obj = CAR(objp);	    if (is_byte(obj)) {		if (len == 0) {		    goto L_overflow;		}		*buf++ = unsigned_val(obj);		len--;	    } else if (is_binary(obj)) {		byte* bptr;		size_t size = binary_size(obj);		Uint bitsize;		Uint bitoffs;		Uint num_bits;				if (len < size) {		    goto L_overflow;		}		ERTS_GET_BINARY_BYTES(obj, bptr, bitoffs, bitsize);		if (bitsize != 0) {		    goto L_type_error;		}		num_bits = 8*size;		copy_binary_to_buffer(buf, 0, bptr, bitoffs, num_bits);		buf += size;		len -= size;	    } else if (is_list(obj)) {		ESTACK_PUSH(s, CDR(objp));		goto L_iter_list; /* on head */	    } else if (is_not_nil(obj)) {		goto L_type_error;	    }	    obj = CDR(objp);	    if (is_list(obj)) {		goto L_iter_list; /* on tail */	    } else if (is_binary(obj)) {		byte* bptr;		size_t size = binary_size(obj);		Uint bitsize;		Uint bitoffs;		Uint num_bits;		if (len < size) {		    goto L_overflow;		}		ERTS_GET_BINARY_BYTES(obj, bptr, bitoffs, bitsize);		if (bitsize != 0) {		    goto L_type_error;		}		num_bits = 8*size;		copy_binary_to_buffer(buf, 0, bptr, bitoffs, num_bits);		buf += size;		len -= size;	    } else if (is_not_nil(obj)) {		goto L_type_error;	    }	} else if (is_binary(obj)) {	    byte* bptr;	    size_t size = binary_size(obj);	    Uint bitsize;	    Uint bitoffs;	    Uint num_bits;	    if (len < size) {		goto L_overflow;	    }	    ERTS_GET_BINARY_BYTES(obj, bptr, bitoffs, bitsize);	    if (bitsize != 0) {		goto L_type_error;	    }	    num_bits = 8*size;	    copy_binary_to_buffer(buf, 0, bptr, bitoffs, num_bits);	    buf += size;	    len -= size;	} else if (is_not_nil(obj)) {	    goto L_type_error;	}    }          DESTROY_ESTACK(s);    return len; L_type_error:    DESTROY_ESTACK(s);    return -2; L_overflow:    DESTROY_ESTACK(s);    return -1;}int io_list_len(Eterm obj){    Eterm* objp;    Sint len = 0;    DECLARE_ESTACK(s);    goto L_again;    while (!ESTACK_ISEMPTY(s)) {	obj = ESTACK_POP(s);    L_again:	if (is_list(obj)) {	L_iter_list:	    objp = list_val(obj);	    /* Head */	    obj = CAR(objp);	    if (is_byte(obj)) {		len++;	    } else if (is_binary(obj) && binary_bitsize(obj) == 0) {		len += binary_size(obj);	    } else if (is_list(obj)) {		ESTACK_PUSH(s, CDR(objp));		goto L_iter_list; /* on head */	    } else if (is_not_nil(obj)) {		goto L_type_error;	    }	    /* Tail */	    obj = CDR(objp);	    if (is_list(obj))		goto L_iter_list; /* on tail */	    else if (is_binary(obj) && binary_bitsize(obj) == 0) {		len += binary_size(obj);	    } else if (is_not_nil(obj)) {		goto L_type_error;	    }	} else if (is_binary(obj) && binary_bitsize(obj) == 0) { /* Tail was binary */	    len += binary_size(obj);	} else if (is_not_nil(obj)) {	    goto L_type_error;	}    }    DESTROY_ESTACK(s);    return len; L_type_error:    DESTROY_ESTACK(s);    return -1;}/* return 0 if item is not a non-empty flat list of bytes */intis_string(Eterm list){    int len = 0;    while(is_list(list)) {	Eterm* consp = list_val(list);	Eterm hd = CAR(consp);	if (!is_byte(hd))	    return 0;	len++;	list = CDR(con

⌨️ 快捷键说明

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