xref: /inferno-os/libmp/port/mptobe.c (revision d0e1d143ef6f03c75c008c7ec648859dd260cbab)
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
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 	}
19 	if(p == nil)
20 		return -1;
21 	if(pp != nil)
22 		*pp = p;
23 	memset(p, 0, n);
24 
25 	// special case 0
26 	if(b->top == 0){
27 		if(n < 1)
28 			return -1;
29 		else
30 			return 1;
31 	}
32 
33 	s = p;
34 	e = s+n;
35 	suppress = 1;
36 	for(i = b->top-1; i >= 0; i--){
37 		x = b->p[i];
38 		for(j = Dbits-8; j >= 0; j -= 8){
39 			c = x>>j;
40 			if(c == 0 && suppress)
41 				continue;
42 			if(p >= e)
43 				return -1;
44 			*p++ = c;
45 			suppress = 0;
46 		}
47 	}
48 
49 	// guarantee at least one byte
50 	if(s == p){
51 		if(p >= e)
52 			return -1;
53 		*p++ = 0;
54 	}
55 
56 	return p - s;
57 }
58