xref: /plan9-contrib/sys/src/libmp/port/mptobe.c (revision 9027b8f78b93f49ddfe75d1dcbf015f5ad6582b6)
1 #include "os.h"
2 #include <mp.h>
3 #include "dat.h"
4 
5 // convert an mpint into a big endian byte array (most significant byte first)
6 //   return number of bytes converted
7 //   if p == nil, allocate and result array
8 int
mptobe(mpint * b,uchar * p,uint n,uchar ** pp)9 mptobe(mpint *b, uchar *p, uint n, uchar **pp)
10 {
11 	int i, j, suppress;
12 	mpdigit x;
13 	uchar *e, *s, c;
14 
15 	if(p == nil){
16 		n = (b->top+1)*Dbytes;
17 		p = malloc(n);
18 		setmalloctag(p, getcallerpc(&b));
19 	}
20 	if(p == nil)
21 		return -1;
22 	if(pp != nil)
23 		*pp = p;
24 	memset(p, 0, n);
25 
26 	// special case 0
27 	if(b->top == 0){
28 		if(n < 1)
29 			return -1;
30 		else
31 			return 1;
32 	}
33 
34 	s = p;
35 	e = s+n;
36 	suppress = 1;
37 	for(i = b->top-1; i >= 0; i--){
38 		x = b->p[i];
39 		for(j = Dbits-8; j >= 0; j -= 8){
40 			c = x>>j;
41 			if(c == 0 && suppress)
42 				continue;
43 			if(p >= e)
44 				return -1;
45 			*p++ = c;
46 			suppress = 0;
47 		}
48 	}
49 
50 	// guarantee at least one byte
51 	if(s == p){
52 		if(p >= e)
53 			return -1;
54 		*p++ = 0;
55 	}
56 
57 	return p - s;
58 }
59