]> pd.if.org Git - zpackage/blob - tomsfastmath/src/bin/fp_read_unsigned_bin.c
commit files needed for zpm-fetchurl
[zpackage] / tomsfastmath / src / bin / fp_read_unsigned_bin.c
1 /* TomsFastMath, a fast ISO C bignum library.
2  * 
3  * This project is meant to fill in where LibTomMath
4  * falls short.  That is speed ;-)
5  *
6  * This project is public domain and free for all purposes.
7  * 
8  * Tom St Denis, tomstdenis@gmail.com
9  */
10 #include <tfm_private.h>
11
12 void fp_read_unsigned_bin(fp_int *a, const unsigned char *b, int c)
13 {
14   /* zero the int */
15   fp_zero (a);
16
17   /* If we know the endianness of this architecture, and we're using
18      32-bit fp_digits, we can optimize this */
19 #if (defined(ENDIAN_LITTLE) || defined(ENDIAN_BIG)) && !defined(FP_64BIT)
20   /* But not for both simultaneously */
21 #if defined(ENDIAN_LITTLE) && defined(ENDIAN_BIG)
22 #error Both ENDIAN_LITTLE and ENDIAN_BIG defined.
23 #endif
24   {
25      unsigned char *pd = (unsigned char *)a->dp;
26
27      if ((unsigned)c > (FP_SIZE * sizeof(fp_digit))) {
28         int excess = c - (FP_SIZE * sizeof(fp_digit));
29         c -= excess;
30         b += excess;
31      }
32      a->used = (c + sizeof(fp_digit) - 1)/sizeof(fp_digit);
33      /* read the bytes in */
34 #ifdef ENDIAN_BIG
35      {
36        /* Use Duff's device to unroll the loop. */
37        int idx = (c - 1) & ~3;
38        switch (c % 4) {
39        case 0:  do { pd[idx+0] = *b++;
40        case 3:       pd[idx+1] = *b++;
41        case 2:       pd[idx+2] = *b++;
42        case 1:       pd[idx+3] = *b++;
43                      idx -= 4;
44                         } while ((c -= 4) > 0);
45        }
46      }
47 #else
48      for (c -= 1; c >= 0; c -= 1) {
49        pd[c] = *b++;
50      }
51 #endif
52   }
53 #else
54   /* read the bytes in */
55   for (; c > 0; c--) {
56      fp_mul_2d (a, 8, a);
57      a->dp[0] |= *b++;
58      a->used += 1;
59   }
60 #endif
61   fp_clamp (a);
62 }
63
64 /* $Source$ */
65 /* $Revision$ */
66 /* $Date$ */