@@ -898,6 +898,74 @@ static void retval_array2_grs1(zval *return_value, Z_GenericRecord *p)
898
898
}
899
899
}
900
900
901
+ static int iconv_grs1 (Z_GenericRecord * p , ODR odr ,
902
+ const char * to , const char * from )
903
+ {
904
+ size_t outbuf_size = 10 ;
905
+ char * outbuf = (char * ) odr_malloc (odr , outbuf_size );
906
+
907
+ Z_GenericRecord * grs [20 ];
908
+ int eno [20 ];
909
+ int level = 0 ;
910
+ yaz_iconv_t cd ;
911
+ if (!to || to [0 ]== 0 )
912
+ to = "UTF-8" ;
913
+ if (!from || !to )
914
+ return 0 ;
915
+ cd = yaz_iconv_open (to , from );
916
+ if (!cd )
917
+ return -1 ;
918
+
919
+ eno [level ] = 0 ;
920
+ grs [level ] = p ;
921
+
922
+ while (level >= 0 ) {
923
+ Z_TaggedElement * e = 0 ;
924
+ Z_GenericRecord * p = grs [level ];
925
+
926
+ if (eno [level ] >= p -> num_elements ) {
927
+ -- level ;
928
+ if (level >= 0 )
929
+ eno [level ]++ ;
930
+ continue ;
931
+ }
932
+ e = grs [level ]-> elements [eno [level ]];
933
+ switch (e -> content -> which ) {
934
+ case Z_ElementData_string :
935
+ while (1 ) {
936
+ size_t inbytesleft = strlen (e -> content -> u .string );
937
+ const char * inp = e -> content -> u .string ;
938
+ size_t outbytesleft = outbuf_size ;
939
+ char * outp = outbuf ;
940
+ size_t r = yaz_iconv (cd , (char * * ) & inp , & inbytesleft ,
941
+ & outp , & outbytesleft );
942
+ if (r == (size_t ) (-1 )) {
943
+ int e = yaz_iconv_error (cd );
944
+ if (e != YAZ_ICONV_E2BIG || outbuf_size > 200000 )
945
+ break ;
946
+ outbuf_size = outbuf_size * 2 + 30 ;
947
+ outbuf = (char * ) odr_malloc (odr , outbuf_size );
948
+ } else {
949
+ e -> content -> u .string = odr_malloc (odr , 1 + (outp - outbuf ));
950
+ memcpy (e -> content -> u .string , outbuf , outp - outbuf );
951
+ e -> content -> u .string [outp - outbuf ] = '\0' ;
952
+ break ;
953
+ }
954
+ }
955
+ break ;
956
+ case Z_ElementData_subtree :
957
+ if (level < 20 ) {
958
+ level ++ ;
959
+ grs [level ] = e -> content -> u .subtree ;
960
+ eno [level ] = -1 ;
961
+ }
962
+ }
963
+ eno [level ]++ ;
964
+ }
965
+ yaz_iconv_close (cd );
966
+ return 0 ;
967
+ }
968
+
901
969
static void retval_array1_grs1 (zval * return_value , Z_GenericRecord * p )
902
970
{
903
971
Z_GenericRecord * grs [20 ];
@@ -918,13 +986,10 @@ static void retval_array1_grs1(zval *return_value, Z_GenericRecord *p)
918
986
919
987
if (eno [level ] >= p -> num_elements ) {
920
988
-- level ;
921
- if (level >= 0 ) {
989
+ if (level >= 0 )
922
990
eno [level ]++ ;
923
- }
924
991
continue ;
925
992
}
926
- /* eno[level]++; */
927
-
928
993
* tag = '\0' ;
929
994
for (i = 0 ; i <= level ; i ++ ) {
930
995
int tag_type = 3 ;
@@ -966,11 +1031,12 @@ static void retval_array1_grs1(zval *return_value, Z_GenericRecord *p)
966
1031
add_next_index_long (my_zval , * e -> content -> u .trueOrFalse );
967
1032
break ;
968
1033
case Z_ElementData_subtree :
969
- level ++ ;
970
- grs [level ] = e -> content -> u .subtree ;
971
- eno [level ] = -1 ;
1034
+ if (level < 20 ) {
1035
+ level ++ ;
1036
+ grs [level ] = e -> content -> u .subtree ;
1037
+ eno [level ] = -1 ;
1038
+ }
972
1039
}
973
-
974
1040
zend_hash_next_index_insert (return_value -> value .ht , (void * ) & my_zval , sizeof (zval * ), NULL );
975
1041
eno [level ]++ ;
976
1042
}
@@ -1001,54 +1067,68 @@ PHP_FUNCTION(yaz_record)
1001
1067
type = (* pval_type )-> value .str .val ;
1002
1068
1003
1069
if (p && p -> zoom_set ) {
1070
+ char type_args [4 ][60 ]; /* 0; 1=2,3 (1 is assumed charset) */
1071
+ type_args [0 ][0 ] = 0 ;
1072
+ type_args [1 ][0 ] = 0 ;
1073
+ type_args [2 ][0 ] = 0 ;
1074
+ type_args [3 ][0 ] = 0 ;
1075
+ sscanf (type , "%59[^;];%59[^=]=%59[^,],%59[^,]" , type_args [0 ],
1076
+ type_args [1 ], type_args [2 ], type_args [3 ]);
1004
1077
ZOOM_record r = ZOOM_resultset_record (p -> zoom_set , pos - 1 );
1005
- if (!strcmp (type , "string" )) {
1078
+ if (!strcmp (type_args [ 0 ] , "string" )) {
1006
1079
type = "render" ;
1007
1080
}
1008
1081
if (r ) {
1009
- if (!strcmp (type , "array" ) || !strcmp (type , "array1" )) {
1082
+ if (!strcmp (type_args [0 ], "array" ) ||
1083
+ !strcmp (type_args [0 ], "array1" )) {
1010
1084
Z_External * ext = (Z_External * ) ZOOM_record_get (r , "ext" , 0 );
1011
1085
if (ext -> which == Z_External_OPAC )
1012
1086
ext = ext -> u .opac -> bibliographicRecord ;
1013
1087
if (ext ) {
1014
1088
oident * ent = oid_getentbyoid (ext -> direct_reference );
1089
+ ODR odr = odr_createmem (ODR_DECODE );
1015
1090
1016
1091
if (ext -> which == Z_External_grs1 && ent -> value == VAL_GRS1 ) {
1092
+ if (type_args [2 ][0 ])
1093
+ iconv_grs1 (ext -> u .grs1 , odr , type_args [3 ],
1094
+ type_args [2 ]);
1017
1095
retval_array1_grs1 (return_value , ext -> u .grs1 );
1018
1096
} else if (ext -> which == Z_External_octet ) {
1019
1097
char * buf = (char * ) (ext -> u .octet_aligned -> buf );
1020
- ODR odr = odr_createmem (ODR_DECODE );
1021
1098
Z_GenericRecord * rec = 0 ;
1022
1099
1023
1100
switch (ent -> value ) {
1024
1101
case VAL_SOIF :
1025
1102
case VAL_HTML :
1026
- break ;
1027
1103
case VAL_TEXT_XML :
1028
1104
case VAL_APPLICATION_XML :
1029
- /* text2grs1(&buf, &len, t->odr_in, 0, 0); */
1030
1105
break ;
1031
1106
default :
1032
1107
rec = marc_to_grs1 (buf , odr );
1033
1108
}
1034
1109
if (rec ) {
1110
+ if (type_args [2 ][0 ])
1111
+ iconv_grs1 (rec , odr , type_args [3 ], type_args [2 ]);
1035
1112
retval_array1_grs1 (return_value , rec );
1036
1113
}
1037
- odr_destroy (odr );
1038
1114
}
1115
+ odr_destroy (odr );
1039
1116
}
1040
- } else if (!strcmp (type , "array2" )) {
1117
+ } else if (!strcmp (type_args [ 0 ] , "array2" )) {
1041
1118
Z_External * ext = (Z_External * ) ZOOM_record_get (r , "ext" , 0 );
1042
1119
if (ext -> which == Z_External_OPAC )
1043
1120
ext = ext -> u .opac -> bibliographicRecord ;
1044
1121
if (ext ) {
1045
1122
oident * ent = oid_getentbyoid (ext -> direct_reference );
1123
+ ODR odr = odr_createmem (ODR_DECODE );
1046
1124
1047
1125
if (ext -> which == Z_External_grs1 && ent -> value == VAL_GRS1 ) {
1126
+ if (type_args [2 ][0 ])
1127
+ iconv_grs1 (ext -> u .grs1 , odr , type_args [3 ],
1128
+ type_args [2 ]);
1048
1129
retval_array2_grs1 (return_value , ext -> u .grs1 );
1049
1130
} else if (ext -> which == Z_External_octet ) {
1050
1131
char * buf = (char * ) (ext -> u .octet_aligned -> buf );
1051
- ODR odr = odr_createmem (ODR_DECODE );
1052
1132
Z_GenericRecord * rec = 0 ;
1053
1133
1054
1134
switch (ent -> value ) {
@@ -1063,22 +1143,22 @@ PHP_FUNCTION(yaz_record)
1063
1143
rec = marc_to_grs1 (buf , odr );
1064
1144
}
1065
1145
if (rec ) {
1146
+ if (type_args [2 ][0 ])
1147
+ iconv_grs1 (rec , odr , type_args [3 ], type_args [2 ]);
1066
1148
retval_array2_grs1 (return_value , rec );
1067
1149
}
1068
- odr_destroy (odr );
1069
1150
}
1151
+ odr_destroy (odr );
1070
1152
}
1071
1153
} else {
1072
1154
int rlen ;
1073
1155
const char * info = ZOOM_record_get (r , type , & rlen );
1074
- #if 0
1075
- return_value -> value .str .len = 1 ;
1076
- return_value -> value .str .val = "X" ;
1077
- #else
1078
- return_value -> value .str .len = (rlen > 0 ) ? rlen : 0 ;
1079
- return_value -> value .str .val = estrndup (info , return_value -> value .str .len );
1080
- #endif
1081
- return_value -> type = IS_STRING ;
1156
+ if (info ) {
1157
+ return_value -> value .str .len = (rlen > 0 ) ? rlen : 0 ;
1158
+ return_value -> value .str .val =
1159
+ estrndup (info , return_value -> value .str .len );
1160
+ return_value -> type = IS_STRING ;
1161
+ }
1082
1162
}
1083
1163
}
1084
1164
}
0 commit comments