dickmeiss               Tue Apr  6 13:40:03 2004 EDT

  Modified files:              
    /php-src/ext/yaz    php_yaz.c 
  Log:
  Allow character set conversion for yaz_record's array method, e.g.
   yaz_record($id,$pos,"array;charset=marc8,iso-8859-1")
  
  
http://cvs.php.net/diff.php/php-src/ext/yaz/php_yaz.c?r1=1.85&r2=1.86&ty=u
Index: php-src/ext/yaz/php_yaz.c
diff -u php-src/ext/yaz/php_yaz.c:1.85 php-src/ext/yaz/php_yaz.c:1.86
--- php-src/ext/yaz/php_yaz.c:1.85      Mon Mar 15 05:01:09 2004
+++ php-src/ext/yaz/php_yaz.c   Tue Apr  6 13:40:03 2004
@@ -16,7 +16,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: php_yaz.c,v 1.85 2004/03/15 10:01:09 dickmeiss Exp $ */
+/* $Id: php_yaz.c,v 1.86 2004/04/06 17:40:03 dickmeiss Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -898,6 +898,74 @@
        }
 }
 
+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 @@
 
                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 @@
                                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 @@
        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 @@
                                                        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;
+                               }
                        }
                }
        }



-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to