summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Dickmeiss <dickmeiss@php.net>2004-04-06 17:40:05 +0000
committerAdam Dickmeiss <dickmeiss@php.net>2004-04-06 17:40:05 +0000
commit1afef889e2169d67e62b154072d2335355d3c72a (patch)
tree51e034a816ba8d9e3524ca981ce328c45517e60b
parent4ee4d27cb4f2cfa67f5a754427fbdb8694f3aefa (diff)
downloadphp-git-1afef889e2169d67e62b154072d2335355d3c72a.tar.gz
Allow character set conversion for yaz_record's array method, e.g.
yaz_record($id,$pos,"array;charset=marc8,iso-8859-1")
-rw-r--r--ext/yaz/php_yaz.c130
1 files changed, 105 insertions, 25 deletions
diff --git a/ext/yaz/php_yaz.c b/ext/yaz/php_yaz.c
index 45db659290..7364eb4332 100644
--- a/ext/yaz/php_yaz.c
+++ b/ext/yaz/php_yaz.c
@@ -898,6 +898,74 @@ static void retval_array2_grs1(zval *return_value, Z_GenericRecord *p)
}
}
+static int iconv_grs1(Z_GenericRecord *p, ODR odr,
+ const char *to, const char *from)
+{
+ size_t outbuf_size = 10;
+ char *outbuf = (char*) odr_malloc(odr, outbuf_size);
+
+ Z_GenericRecord *grs[20];
+ int eno[20];
+ int level = 0;
+ yaz_iconv_t cd;
+ if (!to || to[0]==0)
+ to = "UTF-8";
+ if (!from || !to)
+ return 0;
+ cd = yaz_iconv_open(to, from);
+ if (!cd)
+ return -1;
+
+ eno[level] = 0;
+ grs[level] = p;
+
+ while(level >= 0) {
+ Z_TaggedElement *e = 0;
+ Z_GenericRecord *p = grs[level];
+
+ if (eno[level] >= p->num_elements) {
+ --level;
+ if (level >= 0)
+ eno[level]++;
+ continue;
+ }
+ e = grs[level]->elements[eno[level]];
+ switch (e->content->which) {
+ case Z_ElementData_string:
+ while(1) {
+ size_t inbytesleft = strlen(e->content->u.string);
+ const char *inp = e->content->u.string;
+ size_t outbytesleft = outbuf_size;
+ char *outp = outbuf;
+ size_t r = yaz_iconv(cd, (char**) &inp, &inbytesleft,
+ &outp, &outbytesleft);
+ if (r == (size_t) (-1)) {
+ int e = yaz_iconv_error(cd);
+ if (e != YAZ_ICONV_E2BIG || outbuf_size > 200000)
+ break;
+ outbuf_size = outbuf_size * 2 + 30;
+ outbuf = (char*) odr_malloc(odr, outbuf_size);
+ } else {
+ e->content->u.string = odr_malloc(odr, 1+(outp-outbuf));
+ memcpy(e->content->u.string, outbuf, outp-outbuf);
+ e->content->u.string[outp-outbuf] = '\0';
+ break;
+ }
+ }
+ break;
+ case Z_ElementData_subtree:
+ if (level < 20) {
+ level++;
+ grs[level] = e->content->u.subtree;
+ eno[level] = -1;
+ }
+ }
+ eno[level]++;
+ }
+ yaz_iconv_close(cd);
+ return 0;
+}
+
static void retval_array1_grs1(zval *return_value, Z_GenericRecord *p)
{
Z_GenericRecord *grs[20];
@@ -918,13 +986,10 @@ static void retval_array1_grs1(zval *return_value, Z_GenericRecord *p)
if (eno[level] >= p->num_elements) {
--level;
- if (level >= 0) {
+ if (level >= 0)
eno[level]++;
- }
continue;
}
- /* eno[level]++; */
-
*tag = '\0';
for (i = 0; i <= level; i++) {
int tag_type = 3;
@@ -966,11 +1031,12 @@ static void retval_array1_grs1(zval *return_value, Z_GenericRecord *p)
add_next_index_long(my_zval, *e->content->u.trueOrFalse);
break;
case Z_ElementData_subtree:
- level++;
- grs[level] = e->content->u.subtree;
- eno[level] = -1;
+ if (level < 20) {
+ level++;
+ grs[level] = e->content->u.subtree;
+ eno[level] = -1;
+ }
}
-
zend_hash_next_index_insert(return_value->value.ht, (void *) &my_zval, sizeof(zval *), NULL);
eno[level]++;
}
@@ -1001,54 +1067,68 @@ PHP_FUNCTION(yaz_record)
type = (*pval_type)->value.str.val;
if (p && p->zoom_set) {
+ char type_args[4][60]; /* 0; 1=2,3 (1 is assumed charset) */
+ type_args[0][0] = 0;
+ type_args[1][0] = 0;
+ type_args[2][0] = 0;
+ type_args[3][0] = 0;
+ sscanf(type, "%59[^;];%59[^=]=%59[^,],%59[^,]", type_args[0],
+ type_args[1], type_args[2], type_args[3]);
ZOOM_record r = ZOOM_resultset_record(p->zoom_set, pos-1);
- if (!strcmp(type, "string")) {
+ if (!strcmp(type_args[0], "string")) {
type = "render";
}
if (r) {
- if (!strcmp(type, "array") || !strcmp(type, "array1")) {
+ if (!strcmp(type_args[0], "array") ||
+ !strcmp(type_args[0], "array1")) {
Z_External *ext = (Z_External *) ZOOM_record_get(r, "ext", 0);
if (ext->which == Z_External_OPAC)
ext = ext->u.opac->bibliographicRecord;
if (ext) {
oident *ent = oid_getentbyoid(ext->direct_reference);
+ ODR odr = odr_createmem(ODR_DECODE);
if (ext->which == Z_External_grs1 && ent->value == VAL_GRS1) {
+ if (type_args[2][0])
+ iconv_grs1(ext->u.grs1, odr, type_args[3],
+ type_args[2]);
retval_array1_grs1(return_value, ext->u.grs1);
} else if (ext->which == Z_External_octet) {
char *buf = (char *) (ext->u.octet_aligned->buf);
- ODR odr = odr_createmem(ODR_DECODE);
Z_GenericRecord *rec = 0;
switch (ent->value) {
case VAL_SOIF:
case VAL_HTML:
- break;
case VAL_TEXT_XML:
case VAL_APPLICATION_XML:
- /* text2grs1(&buf, &len, t->odr_in, 0, 0); */
break;
default:
rec = marc_to_grs1(buf, odr);
}
if (rec) {
+ if (type_args[2][0])
+ iconv_grs1(rec, odr, type_args[3], type_args[2]);
retval_array1_grs1(return_value, rec);
}
- odr_destroy(odr);
}
+ odr_destroy(odr);
}
- } else if (!strcmp(type, "array2")) {
+ } else if (!strcmp(type_args[0], "array2")) {
Z_External *ext = (Z_External *) ZOOM_record_get(r, "ext", 0);
if (ext->which == Z_External_OPAC)
ext = ext->u.opac->bibliographicRecord;
if (ext) {
oident *ent = oid_getentbyoid(ext->direct_reference);
+ ODR odr = odr_createmem(ODR_DECODE);
if (ext->which == Z_External_grs1 && ent->value == VAL_GRS1) {
+ if (type_args[2][0])
+ iconv_grs1(ext->u.grs1, odr, type_args[3],
+ type_args[2]);
retval_array2_grs1(return_value, ext->u.grs1);
} else if (ext->which == Z_External_octet) {
char *buf = (char *) (ext->u.octet_aligned->buf);
- ODR odr = odr_createmem(ODR_DECODE);
Z_GenericRecord *rec = 0;
switch (ent->value) {
@@ -1063,22 +1143,22 @@ PHP_FUNCTION(yaz_record)
rec = marc_to_grs1(buf, odr);
}
if (rec) {
+ if (type_args[2][0])
+ iconv_grs1(rec, odr, type_args[3], type_args[2]);
retval_array2_grs1(return_value, rec);
}
- odr_destroy(odr);
}
+ odr_destroy(odr);
}
} else {
int rlen;
const char *info = ZOOM_record_get(r, type, &rlen);
-#if 0
- return_value->value.str.len = 1;
- return_value->value.str.val = "X";
-#else
- return_value->value.str.len = (rlen > 0) ? rlen : 0;
- return_value->value.str.val = estrndup(info, return_value->value.str.len);
-#endif
- return_value->type = IS_STRING;
+ if (info) {
+ return_value->value.str.len = (rlen > 0) ? rlen : 0;
+ return_value->value.str.val =
+ estrndup(info, return_value->value.str.len);
+ return_value->type = IS_STRING;
+ }
}
}
}