diff -Npur cln-1.1.9/src/integer/conv/cl_I_from_BS.cc cln-1.1.9.new/src/integer/conv/cl_I_from_BS.cc --- cln-1.1.9/src/integer/conv/cl_I_from_BS.cc 1969-12-31 19:00:00.000000000 -0500 +++ cln-1.1.9.new/src/integer/conv/cl_I_from_BS.cc 2006-08-11 11:59:52.911099664 -0400 @@ -0,0 +1,68 @@ +// BS_to_I(). + +// General includes. +#include "cl_sysdep.h" + +// Specification. +#include "cl_I.h" + +// Implementation. + +#include "cl_DS.h" + +namespace cln { + +/* Assume BS is little endian and is signed. */ +const cl_I BS_to_I (const unsigned char *BS, size_t len) +{ + uintD *MSD, *LSD, *start; + uintD D; + size_t dlen; + + /* Length in digits: ceil(len/sizeof(uintD)) */ + dlen = (len+sizeof(uintD)-1)/sizeof(uintD); + start = new uintD[dlen]; +#if CL_DS_BIG_ENDIAN_P + MSD = start; + LSD = start+dlen; +#else + LSD = start; + MSD = start+dlen; +#endif + size_t i; + for (i = sizeof(uintD); i <= len; i += sizeof(uintD)) + { + /* Least significant byte is always the last argument. */ +#if intDsize == 8 + D=D1(BS[i-1]); +#elif intDsize == 16 + D=D2(BS[i-1],BS[i-2]); +#elif intDsize == 32 + D=D4(BS[i-1],BS[i-2],BS[i-3],BS[i-4]); +#elif intDsize == 64 + D=D8(BS[i-1],BS[i-2],BS[i-3],BS[i-4],BS[i-5],BS[i-6],BS[i-7],BS[i-8]); +#else +# error "Unsupported value of intDsize" intDsize +#endif + lsprefnext(LSD) = D; // Store digit and move to next least significant. + } + /* Finish the last digit. */ + if (i > len) { + D = 0; + size_t j; + for (j = i -= sizeof(uintD); i < len; i++) + D |= ((uintD) BS[i]) << (i-j)*8; + /* If sign bit is set, pad with 1s, + * as requred by 2's-complement notation. */ + if (BS[len-1]&0x80) + for ( ; i // for memcpy() +#include "cl_sysdep.h" + +// Specification. +#include "cl_I.h" + +// Implementation. + +#include "cl_DS.h" + +namespace cln { + +/* Size of bytestream necessary to store the integer X. */ +size_t I_BS_size (const cl_I& X) +{ + // Number of internal digits times the size of a digit. + if (fixnump(X)) + return FN_maxlength * sizeof (uintD); + else + return TheBignum(X)->length * sizeof (uintD); +} + +/* Copy an individual digit to a byte stream + * in little endian order with the Least Significant Byte placed at LSB. */ +static inline void D_to_BS_little_endian (uintD D, uintB *LSB) +{ +#if CL_CPU_BIG_ENDIAN_P + for (int i=0; i>=8) + *(LSB++) = (uintB) (D & 0xff); +#else + memcpy (LSB, &D, sizeof(D)); +#endif +} + +/* Copy an individual digit to a byte stream + * in big endian order with the Least Significant Byte placed at LSB. */ +static inline void D_to_BS_big_endian (uintD D, uintB *LSB) +{ +#if CL_CPU_BIG_ENDIAN_P + memcpy (LSB-sizeof(uintD)+1, &D, sizeof(D)); +#else + for (size_t i=0; i>=8) + *(LSB--) = (uintB) (D & 0xff); +#endif +} + +/* Convert the integer X to a byte stream stored at location BS in + * little endian (little_endian != 0) or big endian (little_endian == 0) + * order. The resulting integer is stored in 2's complement notation. + * Note: the space available after BS must be at least as large + * as I_BS_size(X). */ +void I_to_BS (const cl_I& X, int little_endian, unsigned char *BS) +{ + size_t len; + const uintD *MSD, *LSD; + uintB *MSB, *LSB; + + /* Get Digit Sequence representation. */ + I_to_NDS_nocopy (X, MSD=, len=, LSD=, cl_false, ); + + /* Deal with endian issues. */ +#if CL_DS_BIG_ENDIAN_P + const int nextD = -1; +#else + const int nextD = 1; +#endif + int nextB; + if (little_endian) { + LSB = BS; + MSB = BS+len-1; + nextB = sizeof (uintD); + } else { + LSB = BS+len-1; + MSB = BS; + nextB = -(int) sizeof (uintD); + } + + /* Store each digit in the correct endian order. */ + for (size_t i=0; i