mptobe.c 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include "os.h"
  10. #include <mp.h>
  11. #include "dat.h"
  12. // convert an mpint into a big endian byte array (most significant byte first)
  13. // return number of bytes converted
  14. // if p == nil, allocate and result array
  15. int
  16. mptobe(mpint *b, uint8_t *p, uint n, uint8_t **pp)
  17. {
  18. int i, j, suppress;
  19. mpdigit x;
  20. uint8_t *e, *s, c;
  21. if(p == nil){
  22. n = (b->top+1)*Dbytes;
  23. p = malloc(n);
  24. setmalloctag(p, getcallerpc());
  25. }
  26. if(p == nil)
  27. return -1;
  28. if(pp != nil)
  29. *pp = p;
  30. memset(p, 0, n);
  31. // special case 0
  32. if(b->top == 0){
  33. if(n < 1)
  34. return -1;
  35. else
  36. return 1;
  37. }
  38. s = p;
  39. e = s+n;
  40. suppress = 1;
  41. for(i = b->top-1; i >= 0; i--){
  42. x = b->p[i];
  43. for(j = Dbits-8; j >= 0; j -= 8){
  44. c = x>>j;
  45. if(c == 0 && suppress)
  46. continue;
  47. if(p >= e)
  48. return -1;
  49. *p++ = c;
  50. suppress = 0;
  51. }
  52. }
  53. // guarantee at least one byte
  54. if(s == p){
  55. if(p >= e)
  56. return -1;
  57. *p++ = 0;
  58. }
  59. return p - s;
  60. }