@@ -450,6 +450,227 @@ register pointer s; /*input stream*/
450
450
}
451
451
vpop ();
452
452
return (result ); }
453
+
454
+ static int base64tobin (char c ) {
455
+ if ('A' <= c && c <= 'Z' ) return (c - 'A' );
456
+ if ('a' <= c && c <= 'z' ) return (c - 'a' + 26 );
457
+ if ('0' <= c && c <= '9' ) return (c - '0' + 52 );
458
+ if (c == '+' ) return 62 ;
459
+ if (c == '/' ) return 63 ;
460
+ if (c == '=' ) return '=' ;
461
+ error (E_USER , (pointer )"invalid base64 character" );
462
+ }
463
+ static pointer readbinaryarray (context * ctx , pointer s , pointer subchr , pointer val )
464
+ {
465
+ register pointer elm ;
466
+ numunion nu ;
467
+ int i , ch ;
468
+ unsigned long size ;
469
+ int rank ;
470
+ int dim [ARRAYRANKLIMIT ];
471
+ unsigned char * buffer ;
472
+ pointer entity ;
473
+ pointer ret = NIL ;
474
+
475
+ for (i = 0 ; i < ARRAYRANKLIMIT ; i ++ ) dim [i ] = 0 ;
476
+ ch = nextch (ctx ,s );
477
+ if (ch != '(' ) error (E_USER , (pointer )"invalid binary array form [(]" );
478
+
479
+ rank = 0 ;
480
+ size = 1 ;
481
+ elm = read1 (ctx ,s ); // read size list
482
+ while (elm != NIL ) {
483
+ if ( isint (elm -> c .cons .car ) ) {
484
+ dim [rank ] = intval (elm -> c .cons .car );
485
+ size *= dim [rank ];
486
+ rank ++ ;
487
+ }
488
+ elm = elm -> c .cons .cdr ;
489
+ }
490
+ elm = read1 (ctx ,s ); // read elemtype
491
+ ch = nextch (ctx ,s );
492
+ if (ch != '"' ) {
493
+ error (E_USER , (pointer )"invalid binary array form [\"]" );
494
+ }
495
+
496
+ if (elm == K_FLOAT || elm == K_FLOAT32 ) {
497
+ entity = makefvector (size );
498
+ #ifdef x86_64
499
+ buffer = malloc (sizeof (float ) * size );
500
+ #else
501
+ buffer = (unsigned char * ) & (entity -> c .fvec .fv [0 ]);
502
+ #endif
503
+ size *= 4 ;
504
+ } else if (elm == K_DOUBLE ) {
505
+ entity = makefvector (size );
506
+ #ifdef x86_64
507
+ buffer = (unsigned char * ) & (entity -> c .fvec .fv [0 ]);
508
+ #else
509
+ buffer = malloc (sizeof (double ) * size );
510
+ #endif
511
+ size *= 8 ;
512
+ } else if (elm == K_SHORT ) {
513
+ entity = makeivector (size );
514
+ buffer = malloc (sizeof (short ) * size );
515
+ size *= 2 ;
516
+ } else if (elm == K_INTEGER ) {
517
+ entity = makeivector (size );
518
+ #ifdef x86_64
519
+ buffer = malloc (sizeof (int ) * size );
520
+ #else
521
+ buffer = (unsigned char * ) & (entity -> c .ivec .iv [0 ]);
522
+ #endif
523
+ size *= 4 ;
524
+ } else if (elm == K_LONG ) {
525
+ entity = makeivector (size );
526
+ #ifdef x86_64
527
+ buffer = (unsigned char * ) & (entity -> c .ivec .iv [0 ]);
528
+ #else
529
+ buffer = malloc (sizeof (long long ) * size );
530
+ #endif
531
+ size *= 8 ;
532
+ } else {
533
+ error (E_USER , (pointer )"invalid binary element type" );
534
+ }
535
+ vpush (entity );
536
+ if (rank == 1 ) {
537
+ // return vector
538
+ ret = entity ;
539
+ vpop ();
540
+ vpush (ret );
541
+ } else {
542
+ // make array
543
+ ret = alloc (vecsize (speval (ARRAY )-> c .cls .vars ), ELM_FIXED ,
544
+ intval (speval (ARRAY )-> c .cls .cix ),
545
+ vecsize (speval (ARRAY )-> c .cls .vars ));
546
+ ret -> c .ary .entity = entity ;
547
+ vpop ();
548
+ vpush (ret );
549
+ ret -> c .ary .fillpointer = NIL ;
550
+ ret -> c .ary .rank = makeint (rank );
551
+ ret -> c .ary .offset = makeint (0 );
552
+ for (i = 0 ; i < ARRAYRANKLIMIT ; i ++ ) ret -> c .ary .dim [i ] = makeint (dim [i ]);
553
+ ret -> c .ary .plist = NIL ;
554
+ }
555
+
556
+ int strsize = (size * 8 + 5 )/6 ;
557
+ strsize = ((strsize + 3 )/4 )* 4 ;
558
+ // read string
559
+ char * ascstr = malloc (strsize );
560
+ i = 0 ;
561
+ while ((ch = readch (s )) != EOF ) {
562
+ ascstr [i ++ ] = ch ;
563
+ if (i >= strsize ) break ;
564
+ }
565
+ if (i != strsize ) {
566
+ free (ascstr );
567
+ vpop ();
568
+ error (E_USER , (pointer )"invalid size of string" );
569
+ }
570
+ ch = readch (s );
571
+ if (ch != '"' ) {
572
+ free (ascstr );
573
+ vpop ();
574
+ error (E_USER , (pointer )"invalid binary array form / end of [\"]" );
575
+ }
576
+
577
+ // decode base64
578
+ {
579
+ int asc_cntr = 0 ;
580
+ int buf_cntr = 0 ;
581
+ int mode = 0 ;
582
+ int current_bin ;
583
+ while (asc_cntr < strsize ) {
584
+ int base64char = base64tobin (ascstr [asc_cntr ++ ]);
585
+ if (base64char != 77 ) {
586
+ switch (mode ) {
587
+ case 0 :
588
+ current_bin = (base64char << 2 );
589
+ break ;
590
+ case 1 :
591
+ current_bin |= (base64char >> 4 );
592
+ buffer [buf_cntr ++ ] = current_bin ;
593
+ current_bin = (base64char & 0x0f ) << 4 ;
594
+ break ;
595
+ case 2 :
596
+ current_bin |= (base64char >> 2 );
597
+ buffer [buf_cntr ++ ] = current_bin ;
598
+ current_bin = (base64char & 0x03 ) << 6 ;
599
+ break ;
600
+ case 3 :
601
+ current_bin |= base64char ;
602
+ buffer [buf_cntr ++ ] = current_bin ;
603
+ break ;
604
+ }
605
+ mode = (mode + 1 ) % 4 ;
606
+ }
607
+ }
608
+ if (mode > 0 ) buffer [buf_cntr ++ ] = current_bin ;
609
+ }
610
+ free (ascstr );
611
+
612
+
613
+ if (elm == K_FLOAT || elm == K_FLOAT32 ) {
614
+ #ifdef x86_64
615
+ float * src = (float * )buffer ;
616
+ eusfloat_t * dst = (eusfloat_t * )& (entity -> c .fvec .fv [0 ]);
617
+ for (i = 0 ; i < size /4 ; i ++ ) {
618
+ * dst ++ = * src ++ ;
619
+ }
620
+ free (buffer );
621
+ #else
622
+ // do nothing
623
+ #endif
624
+ } else if (elm == K_DOUBLE ) {
625
+ #ifdef x86_64
626
+ // do nothing
627
+ #else
628
+ double * src = (double * )buffer ;
629
+ eusfloat_t * dst = (eusfloat_t * )& (entity -> c .fvec .fv [0 ]);
630
+ for (i = 0 ; i < size /8 ; i ++ ) {
631
+ * dst ++ = * src ++ ;
632
+ }
633
+ free (buffer );
634
+ #endif
635
+ } else if (elm == K_SHORT ) {
636
+ short * src = (short * )buffer ;
637
+ eusinteger_t * dst = (eusinteger_t * )& (entity -> c .ivec .iv [0 ]);
638
+ for (i = 0 ; i < size /2 ; i ++ ) {
639
+ * dst ++ = * src ++ ;
640
+ }
641
+ free (buffer );
642
+ } else if (elm == K_INTEGER ) {
643
+ #ifdef x86_64
644
+ int * src = (int * )buffer ;
645
+ eusinteger_t * dst = (eusinteger_t * )& (entity -> c .ivec .iv [0 ]);
646
+ for (i = 0 ; i < size /4 ; i ++ ) {
647
+ * dst ++ = * src ++ ;
648
+ }
649
+ free (buffer );
650
+ #else
651
+ // do nothing
652
+ #endif
653
+ } else if (elm == K_LONG ) {
654
+ #ifdef x86_64
655
+ // do nothing
656
+ #else
657
+ long long * src = (long long * )buffer ;
658
+ eusinteger_t * dst = (eusinteger_t * )& (entity -> c .ivec .iv [0 ]);
659
+ for (i = 0 ; i < size /8 ; i ++ ) {
660
+ * dst ++ = * src ++ ;
661
+ }
662
+ free (buffer );
663
+ #endif
664
+ }
665
+ //
666
+ ch = nextch (ctx ,s );
667
+ while (ch != ')' && ch != EOF ) {
668
+ ch = nextch (ctx ,s );
669
+ }
670
+
671
+ return vpop ();
672
+ }
673
+
453
674
454
675
/****************************************************************/
455
676
/* read dispatch macro expression
@@ -1058,6 +1279,7 @@ register context *ctx;
1058
1279
sharpmacro ['I' ]= makeint ((eusinteger_t )readivector );
1059
1280
sharpmacro ['J' ]= makeint ((eusinteger_t )readobject );
1060
1281
sharpmacro ['V' ]= makeint ((eusinteger_t )readobject );
1282
+ sharpmacro ['G' ]= makeint ((eusinteger_t )readbinaryarray );
1061
1283
1062
1284
/* make default readtable */
1063
1285
rdtable = (pointer )makereadtable (ctx );
0 commit comments