@@ -416,6 +416,76 @@ PGMP_PG_FUNCTION(pmpz_from_bytea)
416
416
PGMP_RETURN_MPZ (result_z );
417
417
}
418
418
419
+ PGMP_PG_FUNCTION (pmpz_from_bytea_signed )
420
+ {
421
+ bytea * data = PG_GETARG_BYTEA_PP (0 );
422
+ int data_len = VARSIZE_ANY_EXHDR (data );
423
+ char * data_body = VARDATA_ANY (data );
424
+ char * data_buf ;
425
+ bool is_neg ;
426
+ mpz_t result_z ;
427
+
428
+ mpz_init (result_z );
429
+
430
+ if (data_len == 0 ) {
431
+ PGMP_RETURN_MPZ (result_z );
432
+ }
433
+
434
+ is_neg = data_body [0 ] & 0x80 ;
435
+
436
+ if (is_neg ) {
437
+ data_buf = palloc (data_len );
438
+
439
+ if (!(data_len & 7 )) {
440
+ size_t limbs_count = data_len / 8 ;
441
+ uint64_t * limbs_in = (uint64_t * )data_body ;
442
+ uint64_t * limbs_out = (uint64_t * )data_buf ;
443
+ for (size_t i = 0 ; i < limbs_count ; i ++ ) {
444
+ limbs_out [i ] = ~(limbs_in [i ]);
445
+ }
446
+ } else if (!(data_len & 3 )) {
447
+ size_t limbs_count = data_len / 4 ;
448
+ uint32_t * limbs_in = (uint32_t * )data_body ;
449
+ uint32_t * limbs_out = (uint32_t * )data_buf ;
450
+ for (size_t i = 0 ; i < limbs_count ; i ++ ) {
451
+ limbs_out [i ] = ~(limbs_in [i ]);
452
+ }
453
+ } else if (!(data_len & 1 )) {
454
+ size_t limbs_count = data_len / 2 ;
455
+ uint16_t * limbs_in = (uint16_t * )data_body ;
456
+ uint16_t * limbs_out = (uint16_t * )data_buf ;
457
+ for (size_t i = 0 ; i < limbs_count ; i ++ ) {
458
+ limbs_out [i ] = ~(limbs_in [i ]);
459
+ }
460
+ } else {
461
+ for (size_t i = 0 ; i < data_len ; i ++ ) {
462
+ data_buf [i ] = ~(data_body [i ]);
463
+ }
464
+ }
465
+ } else {
466
+ data_buf = data_body ;
467
+ }
468
+
469
+ if (!(data_len & 7 )) {
470
+ mpz_import (result_z , data_len / 8 , 1 , 8 , 1 , 0 , (uint64_t * )data_buf );
471
+ } else if (!(data_len & 3 )) {
472
+ mpz_import (result_z , data_len / 4 , 1 , 4 , 1 , 0 , (uint32_t * )data_buf );
473
+ } else if (!(data_len & 1 )) {
474
+ mpz_import (result_z , data_len / 2 , 1 , 2 , 1 , 0 , (uint16_t * )data_buf );
475
+ } else {
476
+ mpz_import (result_z , data_len , 1 , 1 , 1 , 0 , data_buf );
477
+ }
478
+
479
+ if (is_neg ) {
480
+ pfree (data_buf );
481
+
482
+ mpz_add_ui (result_z , result_z , 1 );
483
+ mpz_neg (result_z , result_z );
484
+ }
485
+
486
+ PGMP_RETURN_MPZ (result_z );
487
+ }
488
+
419
489
PGMP_PG_FUNCTION (pmpz_to_bytea )
420
490
{
421
491
const mpz_t z ;
0 commit comments