Browse Source

Allow character set conversion for yaz_record's array method, e.g.

yaz_record($id,$pos,"array;charset=marc8,iso-8859-1")
PEAR_1_4DEV
Adam Dickmeiss 23 years ago
parent
commit
1afef889e2
  1. 130
      ext/yaz/php_yaz.c

130
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;
}
}
}
}

Loading…
Cancel
Save