@@ -622,3 +622,75 @@ int intn_parse(
622
622
// let's count at the end
623
623
return out_len ;
624
624
}
625
+
626
+ static size_t cond_neg_in_place (intn_integer_sign_t sign , intn_digit_t out [])
627
+ {
628
+ if (sign == IntNNegativeInteger ) {
629
+ uint32_t carry = 1 ;
630
+ size_t i ;
631
+ int last_non_zero = -1 ;
632
+ for (i = 0 ; i < INTN_MAX_RES_LEN - 1 ; i ++ ) {
633
+ uint64_t temp = (uint64_t ) (~out [i ]) + (uint64_t ) carry ;
634
+ if ((uint32_t ) temp != 0 ) {
635
+ last_non_zero = i ;
636
+ }
637
+ out [i ] = (uint32_t ) temp ;
638
+ carry = temp >> 32 ;
639
+ }
640
+ if (carry ) {
641
+ out [i ] = carry ;
642
+ return i ;
643
+ } else {
644
+ return last_non_zero + 1 ;
645
+ }
646
+ } else {
647
+ return intn_count_digits (out , INTN_MAX_IN_LEN );
648
+ }
649
+ }
650
+
651
+ int intn_from_integer_bytes (const uint8_t in [], size_t in_size , intn_from_integer_options_t opts ,
652
+ intn_digit_t out [], intn_integer_sign_t * out_sign )
653
+ {
654
+ size_t msb_index ;
655
+ if (opts & IntnLittleEndian ) {
656
+ msb_index = in_size - 1 ;
657
+ } else {
658
+ msb_index = 0 ;
659
+ }
660
+
661
+ uint8_t filler = 0x00 ;
662
+ intn_integer_sign_t sign = IntNPositiveInteger ;
663
+ if (opts & IntnSigned ) {
664
+ if (in [msb_index ] & 0x80 ) {
665
+ filler = 0xFF ;
666
+ sign = IntNNegativeInteger ;
667
+ }
668
+ * out_sign = sign ;
669
+ }
670
+
671
+ memset (out , filler , INTN_MAX_RES_LEN * sizeof (intn_digit_t ));
672
+
673
+ size_t dest_j = in_size ;
674
+
675
+ if (UNLIKELY (dest_j / sizeof (intn_digit_t ) >= INTN_MAX_RES_LEN )) {
676
+ return -1 ;
677
+ }
678
+
679
+ if (opts & IntnLittleEndian ) {
680
+ for (int i = in_size - 1 ; i >= 0 ; i -- ) {
681
+ dest_j -- ;
682
+ size_t dest_block = dest_j / sizeof (intn_digit_t );
683
+ out [dest_block ] <<= 8 ;
684
+ out [dest_block ] |= in [i ];
685
+ }
686
+ } else {
687
+ for (size_t i = 0 ; i < in_size ; i ++ ) {
688
+ dest_j -- ;
689
+ size_t dest_block = dest_j / sizeof (intn_digit_t );
690
+ out [dest_block ] <<= 8 ;
691
+ out [dest_block ] |= in [i ];
692
+ }
693
+ }
694
+
695
+ return cond_neg_in_place (sign , out );
696
+ }
0 commit comments