📄 asn1_erl_driver.c
字号:
case 21: /* in this case the next two bytes in_ptr points at holds the number of following bytes that holds the value that will be inserted in the completed buffer */ no_bytes = (int)*(++in_ptr); no_bytes = no_bytes << 8; no_bytes = no_bytes | (int)*(++in_ptr); counter -= (2 + no_bytes); if ((counter<0) || (ret=insert_octets(no_bytes,&in_ptr,&ptr,&unused)) == ASN1_ERROR) return ASN1_ERROR; buf_space -= ret; break; case 30: /* If we call the following bytes, in the buffer in_ptr points at, By1,By2,Rest then Rest is the value that will be transfered to the completed buffer. By1 tells how many of the rightmost bits in Rest that should not be used. By2 is the length of Rest in bytes.*/ in_unused = (int)*(++in_ptr); no_bytes = (int)*(++in_ptr); counter -= (2 + no_bytes);/* printf("%d: case 30: in_unused=%d, no_bytes=%d,counter=%d\n\r",__LINE__,in_unused,no_bytes,counter); */ ret = -4711; if ((counter<0) || (ret=insert_octets_except_unused(no_bytes,&in_ptr,&ptr,&unused,in_unused)) == ASN1_ERROR) return ASN1_ERROR;/* printf("%d: ret=%d\n\r",__LINE__, ret); */ buf_space -= ret; break; case 31: /* If we call the following bytes, in the buffer in_ptr points at, By1,By2,By3,Rest then Rest is the value that will be transfered to the completed buffer. By1 tells how many of the rightmost bits in Rest that should not be used. By2 and By3 is the length of Rest in bytes.*/ in_unused = (int)*(++in_ptr); no_bytes = (int)*(++in_ptr); no_bytes = no_bytes << 8; no_bytes = no_bytes | (int)*(++in_ptr); counter -= (3 + no_bytes); if ((counter<0) || (ret=insert_octets_except_unused(no_bytes,&in_ptr,&ptr,&unused,in_unused)) == ASN1_ERROR) return ASN1_ERROR; buf_space -= ret; break; case 40: /* This case implies that next byte,By1,(..,By1,By2,Bin,...) is the desired length of the completed value, maybe needs padding zero bits or removal of trailing zero bits from Bin. By2 is the length of Bin and Bin is the value that will be put into the completed buffer. Each byte in Bin has the value 1 or 0.*/ desired_len = (int)*(++in_ptr); no_bytes=(int)*(++in_ptr); /* This is the algorithm for need of memory reallocation: Only when padding (cases 40 - 43,45 - 47) more memory may be used than allocated. Therefore one has to keep track of how much of the allocated memory that has been saved, i.e. the difference between the number of parsed bytes of the input buffer and the number of used bytes of the output buffer. If saved memory is less than needed for the padding then we need more memory. */ saved_mem = buf_space - counter; pad_bits = desired_len - no_bytes - unused; needed = (pad_bits > 0) ? CEIL(pad_bits,8) : 0; if (saved_mem < needed) { /* Have to allocate more memory */ buf_size += needed; buf_space += needed; if (realloc_memory(drv_binary,buf_size,&ptr, &complete_buf) == ASN1_ERROR) return ASN1_ERROR; } counter -= (2 + no_bytes); if ((counter<0) || (ret=insert_octets_as_bits_exact_len(desired_len,no_bytes,&in_ptr, &ptr,&unused)) == ASN1_ERROR) return ASN1_ERROR; buf_space -= ret; break; case 41: /* Same as case 40 apart from By2, the length of Bin, which is in two bytes*/ desired_len = (int)*(++in_ptr); no_bytes=(int)*(++in_ptr); no_bytes = no_bytes << 8; no_bytes = no_bytes | (int)*(++in_ptr); saved_mem = buf_space - counter; needed = CEIL((desired_len-unused),8) - no_bytes; if (saved_mem < needed) { /* Have to allocate more memory */ buf_size += needed; buf_space += needed; if (realloc_memory(drv_binary,buf_size,&ptr, &complete_buf) == ASN1_ERROR) return ASN1_ERROR; } counter -= (3 + no_bytes); if ((counter<0) || (ret=insert_octets_as_bits_exact_len(desired_len,no_bytes,&in_ptr, &ptr,&unused)) == ASN1_ERROR) return ASN1_ERROR; buf_space -= ret; break; case 42: /* Same as case 40 apart from By1, the desired length, which is in two bytes*/ desired_len = (int)*(++in_ptr); desired_len = desired_len << 8; desired_len = desired_len | (int)*(++in_ptr); no_bytes=(int)*(++in_ptr); saved_mem = buf_space - counter; needed = CEIL((desired_len-unused),8) - no_bytes; if (saved_mem < needed) { /* Have to allocate more memory */ buf_size += needed; buf_space += needed; if (realloc_memory(drv_binary,buf_size,&ptr, &complete_buf) == ASN1_ERROR) return ASN1_ERROR; } counter -= (3 + no_bytes); if ((counter<0) || (ret=insert_octets_as_bits_exact_len(desired_len,no_bytes,&in_ptr, &ptr,&unused)) == ASN1_ERROR) return ASN1_ERROR; buf_space -= ret; break; case 43: /* Same as case 40 apart from By1 and By2, the desired length and the length of Bin, which are in two bytes each. */ desired_len = (int)*(++in_ptr); desired_len = desired_len << 8; desired_len = desired_len | (int)*(++in_ptr); no_bytes=(int)*(++in_ptr); no_bytes = no_bytes << 8; no_bytes = no_bytes | (int)*(++in_ptr); saved_mem = buf_space - counter; needed = CEIL((desired_len-unused),8) - no_bytes; if (saved_mem < needed) { /* Have to allocate more memory */ buf_size += needed; buf_space += needed; if (realloc_memory(drv_binary,buf_size,&ptr, &complete_buf) == ASN1_ERROR) return ASN1_ERROR; } counter -= (4 + no_bytes); if ((counter<0) || (ret=insert_octets_as_bits_exact_len(desired_len,no_bytes,&in_ptr, &ptr,&unused)) == ASN1_ERROR) return ASN1_ERROR; buf_space -= ret; break; case 45: /* This case assumes that the following bytes in the incoming buffer (called By1,By2,Bin) is By1, which is the number of bits (n) that will be inserted in the completed buffer. By2 is the number of bytes in Bin. Each bit in the buffer Bin should be inserted from the leftmost until the nth.*/ desired_len = (int)*(++in_ptr); no_bytes=(int)*(++in_ptr); saved_mem = buf_space - counter; needed = CEIL((desired_len-unused),8) - no_bytes;/* printf("buf_space=%d, counter=%d, needed=%d",buf_space,counter,needed); */ if (saved_mem < needed) { /* Have to allocate more memory */ buf_size += needed; buf_space += needed; if (realloc_memory(drv_binary,buf_size,&ptr, &complete_buf) == ASN1_ERROR) return ASN1_ERROR; } counter -= (2 + no_bytes);/* printf("calling insert_bits_as_bits: desired_len=%d, no_bytes=%d\n\r",desired_len,no_bytes); *//* printf("1in_ptr=%d\n\r",in_ptr); */ if((counter<0) || (ret=insert_bits_as_bits(desired_len,no_bytes,&in_ptr, &ptr,&unused)) == ASN1_ERROR) return ASN1_ERROR;/* printf("2in_ptr=%d, ptr=%d, complete_buf=%d\n\r",in_ptr,ptr,complete_buf); *//* printf("buf_space=%d, ret=%d, counter=%d\n\r",buf_space,ret,counter); */ buf_space -= ret; break; case 46: /* Same as case 45 apart from By1, the desired length, which is in two bytes. */ desired_len = (int)*(++in_ptr); desired_len = desired_len << 8; desired_len = desired_len | (int)*(++in_ptr); no_bytes=(int)*(++in_ptr); saved_mem = buf_space - counter; needed = CEIL((desired_len-unused),8) - no_bytes; if (saved_mem < needed) { /* Have to allocate more memory */ buf_size += needed; buf_space += needed; if (realloc_memory(drv_binary,buf_size,&ptr, &complete_buf) == ASN1_ERROR) return ASN1_ERROR; } counter -= (3 + no_bytes); if((counter<0) || (ret=insert_bits_as_bits(desired_len,no_bytes,&in_ptr, &ptr,&unused)) == ASN1_ERROR) return ASN1_ERROR; buf_space -= ret; break; case 47: /* Same as case 45 apart from By1 and By2, the desired length and the length of Bin, which are in two bytes each. */ desired_len = (int)*(++in_ptr); desired_len = desired_len << 8; desired_len = desired_len | (int)*(++in_ptr); no_bytes=(int)*(++in_ptr); no_bytes = no_bytes << 8; no_bytes = no_bytes | (int)*(++in_ptr); saved_mem = buf_space - counter; needed = CEIL((desired_len-unused),8) - no_bytes; if (saved_mem < needed) { /* Have to allocate more memory */ buf_size += needed; buf_space += needed; if (realloc_memory(drv_binary,buf_size,&ptr, &complete_buf) == ASN1_ERROR) return ASN1_ERROR; } counter -= (4 + no_bytes); if((counter<0) || (ret=insert_bits_as_bits(desired_len,no_bytes,&in_ptr, &ptr,&unused)) == ASN1_ERROR) return ASN1_ERROR; buf_space -= ret; break; default: return ASN1_ERROR; } in_ptr++; } /* The returned buffer must be at least one byte and it must be octet aligned */ if ((unused == 8) && (ptr != complete_buf)) return (ptr - complete_buf); else { ptr++; /* octet align buffer */ return (ptr - complete_buf); }}int realloc_memory(ErlDrvBinary **drv_binary, int amount, unsigned char **ptr, unsigned char **complete_buf) { ErlDrvBinary *tmp_bin; int i;/* printf("realloc_momory: amount = %d\n",amount); */ if ((tmp_bin=driver_realloc_binary(*drv_binary,amount)) == NULL) { /*error handling due to memory allocation failure *//* printf("error when allocating memory\n"); */ return ASN1_ERROR; }else { i = *ptr - *complete_buf; *drv_binary=tmp_bin; *complete_buf = (*drv_binary)->orig_bytes; *ptr = *complete_buf + i; } return ASN1_OK;}int insert_most_sign_bits(int no_bits, unsigned char val, unsigned char **output_ptr, int *unused) { unsigned char *ptr = *output_ptr; if (no_bits < *unused){ *ptr = *ptr | (val >> (8 - *unused)); *unused -= no_bits; } else if (no_bits == *unused) { *ptr = *ptr | (val >> (8 - *unused)); *unused = 8; *++ptr = 0x00; } else { *ptr = *ptr | (val >> (8 - *unused)); *++ptr = 0x00; *ptr = *ptr | (val << *unused); *unused = 8 - (no_bits - *unused); } *output_ptr = ptr; return ASN1_OK;}int insert_least_sign_bits(int no_bits, unsigned char val, unsigned char **output_ptr, int *unused) { unsigned char *ptr = *output_ptr; int ret = 0; if (no_bits < *unused){ *ptr = *ptr | (val << (*unused - no_bits)); *unused -= no_bits; } else if (no_bits == *unused){ *ptr = *ptr | val; *unused = 8; *++ptr = 0x00; ret++; } else { /* first in the begun byte in the completed buffer insert so many bits that fit, then insert the rest in next byte.*/ *ptr = *ptr | (val >> (no_bits - *unused)); *++ptr = 0x00; ret++; *ptr = *ptr | (val << (8 - (no_bits - *unused))); *unused = 8 - (no_bits - *unused); } *output_ptr = ptr; return ret;}/* pad_bits adds no_bits bits in the buffer that output_ptr points at. */int pad_bits(int no_bits, unsigned char **output_ptr, int *unused) { unsigned char *ptr = *output_ptr; int ret = 0; while (no_bits > 0) { if(*unused == 1){ *unused = 8; *++ptr = 0x00; ret++; } else (*unused)--; no_bits--; } *output_ptr = ptr; return ret; }/* insert_bits_as_bits removes no_bytes bytes from the buffer that in_ptr points at and takes the desired_no leftmost bits from those removed bytes and inserts them in the buffer(output buffer) that ptr points at. The unused parameter tells how many bits that are not set in the actual byte in the output buffer. If desired_no is more bits than the input buffer has in no_bytes bytes, then zero bits is padded.*/int insert_bits_as_bits(int desired_no, int no_bytes, unsigned char **input_ptr, unsigned char **output_ptr, int *unused){ unsigned char *in_ptr = *input_ptr; unsigned char val; int no_bits, ret, ret2; if (desired_no == (no_bytes * 8)) { if(insert_octets_unaligned(no_bytes,&in_ptr,output_ptr,*unused) == ASN1_ERROR) return ASN1_ERROR; ret = no_bytes; } else if (desired_no < (no_bytes * 8)) {/* printf("insert_bits_as_bits 1\n\r"); */ if(insert_octets_unaligned(desired_no/8,&in_ptr,output_ptr,*unused) == ASN1_ERROR) return ASN1_ERROR;/* printf("insert_bits_as_bits 2\n\r"); */ val = *++in_ptr;/* printf("val = %d\n\r",(int)val); */ no_bits = desired_no % 8;/* printf("no_bits = %d\n\r",no_bits); */ insert_most_sign_bits(no_bits,val,output_ptr,unused); ret = CEIL(desired_no,8); } else { if(insert_octets_unaligned(no_bytes,&in_ptr,output_ptr,*unused) == ASN1_ERROR) return ASN1_ERROR; ret2 = pad_bits(desired_no - (no_bytes * 8),output_ptr,unused);/* printf("ret2 = %d\n\r",ret2); */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -