@@ -390,3 +390,57 @@ PGMP_PG_FUNCTION(pmpz_to_float8)
390
390
PG_RETURN_FLOAT8 ((float8 )out );
391
391
}
392
392
393
+ PGMP_PG_FUNCTION (pmpz_from_bytea )
394
+ {
395
+ bytea * data = PG_GETARG_BYTEA_PP (0 );
396
+ int data_len = VARSIZE_ANY_EXHDR (data );
397
+ char * data_body = VARDATA_ANY (data );
398
+ mpz_t result_z ;
399
+
400
+ mpz_init (result_z );
401
+
402
+ if (data_len == 0 ) {
403
+ PGMP_RETURN_MPZ (result_z );
404
+ }
405
+
406
+ if (!(data_len & 7 )) {
407
+ mpz_import (result_z , data_len / 8 , 1 , 8 , 1 , 0 , (uint64_t * )data_body );
408
+ } else if (!(data_len & 3 )) {
409
+ mpz_import (result_z , data_len / 4 , 1 , 4 , 1 , 0 , (uint32_t * )data_body );
410
+ } else if (!(data_len & 1 )) {
411
+ mpz_import (result_z , data_len / 2 , 1 , 2 , 1 , 0 , (uint16_t * )data_body );
412
+ } else {
413
+ mpz_import (result_z , data_len , 1 , 1 , 1 , 0 , data_body );
414
+ }
415
+
416
+ PGMP_RETURN_MPZ (result_z );
417
+ }
418
+
419
+ PGMP_PG_FUNCTION (pmpz_to_bytea )
420
+ {
421
+ const mpz_t z ;
422
+ bytea * result ;
423
+ char * result_body_u8 ;
424
+ int body_len ;
425
+
426
+ PGMP_GETARG_MPZ (z , 0 );
427
+
428
+ body_len = (mpz_sizeinbase (z , 16 ) + 1 ) / 2 ;
429
+
430
+ result = malloc (VARHDRSZ + body_len );
431
+ result_body_u8 = VARDATA (result );
432
+
433
+ if (!(body_len & 7 )) {
434
+ mpz_export ((uint64_t * )result_body_u8 , NULL , 1 , 8 , 1 , 0 , z );
435
+ } else if (!(body_len & 3 )) {
436
+ mpz_export ((uint32_t * )result_body_u8 , NULL , 1 , 4 , 1 , 0 , z );
437
+ } else if (!(body_len & 1 )) {
438
+ mpz_export ((uint16_t * )result_body_u8 , NULL , 1 , 2 , 1 , 0 , z );
439
+ } else {
440
+ mpz_export (result_body_u8 , NULL , 1 , 1 , 1 , 0 , z );
441
+ }
442
+
443
+ SET_VARSIZE (result , VARHDRSZ + body_len );
444
+
445
+ PG_RETURN_BYTEA_P (result );
446
+ }
0 commit comments