📄 php_yaz.c
字号:
/* +----------------------------------------------------------------------+ | PHP Version 4 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Adam Dickmeiss <adam@indexdata.dk> | +----------------------------------------------------------------------+ *//* $Id: php_yaz.c,v 1.57.2.5.6.2 2007/01/01 09:46:49 sebastian Exp $ */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include "php.h"#include "php_ini.h"#if HAVE_YAZ#include "ext/standard/info.h"#include "php_yaz.h"#include <yaz/yaz-version.h>#ifndef YAZ_VERSIONL#error YAZ version 1.9 or later must be used.#endif#if YAZ_VERSIONL < 0x010900#error YAZ version 1.9 or later must be used.#endif#ifdef PHP_WIN32#include <process.h>#endif#include <yaz/proto.h>#include <yaz/marcdisp.h>#include <yaz/yaz-util.h>#include <yaz/yaz-ccl.h>#include <yaz/zoom.h>#define MAX_ASSOC 100typedef struct Yaz_AssociationInfo *Yaz_Association;struct Yaz_AssociationInfo { CCL_parser ccl_parser; ZOOM_connection zoom_conn; ZOOM_resultset zoom_set; ZOOM_scanset zoom_scan; ZOOM_package zoom_package; char *sort_criteria; int persistent; int in_use; int order;};static Yaz_Association yaz_association_mk (){ Yaz_Association p = xmalloc (sizeof(*p)); p->zoom_conn = ZOOM_connection_create (0); p->zoom_set = 0; p->zoom_scan = 0; p->zoom_package = 0; ZOOM_connection_option_set(p->zoom_conn, "implementationName", "PHP"); ZOOM_connection_option_set(p->zoom_conn, "async", "1"); p->sort_criteria = 0; p->in_use = 0; p->order = 0; p->persistent = 0; p->ccl_parser = ccl_parser_create(); p->ccl_parser->bibset = 0; return p;}static void yaz_association_destroy (Yaz_Association p){ if (!p) return ; ZOOM_resultset_destroy (p->zoom_set); ZOOM_scanset_destroy (p->zoom_scan); ZOOM_package_destroy (p->zoom_package); ZOOM_connection_destroy (p->zoom_conn); xfree (p->sort_criteria); ccl_qual_rm(&p->ccl_parser->bibset); ccl_parser_destroy(p->ccl_parser);}#ifdef ZTSstatic MUTEX_T yaz_mutex;#endifZEND_DECLARE_MODULE_GLOBALS(yaz);static Yaz_Association *shared_associations;static int order_associations;static int le_link;static unsigned char third_argument_force_ref[] = { 3, BYREF_NONE, BYREF_NONE, BYREF_FORCE };static unsigned char second_argument_force_ref[] = { 2, BYREF_NONE, BYREF_FORCE };function_entry yaz_functions [] = { PHP_FE(yaz_connect, NULL) PHP_FE(yaz_close, NULL) PHP_FE(yaz_search, NULL) PHP_FE(yaz_wait, second_argument_force_ref) PHP_FE(yaz_errno, NULL) PHP_FE(yaz_error, NULL) PHP_FE(yaz_addinfo, NULL) PHP_FE(yaz_hits, NULL) PHP_FE(yaz_record, NULL) PHP_FE(yaz_syntax, NULL) PHP_FE(yaz_element, NULL) PHP_FE(yaz_range, NULL) PHP_FE(yaz_itemorder, NULL) PHP_FE(yaz_es_result, NULL) PHP_FE(yaz_scan, NULL) PHP_FE(yaz_scan_result, second_argument_force_ref) PHP_FE(yaz_present, NULL) PHP_FE(yaz_ccl_conf, NULL) PHP_FE(yaz_ccl_parse, third_argument_force_ref) PHP_FE(yaz_database, NULL) PHP_FE(yaz_sort, NULL) PHP_FE(yaz_schema, NULL) {NULL, NULL, NULL}};static void get_assoc (INTERNAL_FUNCTION_PARAMETERS, pval **id, Yaz_Association *assocp){ Yaz_Association *as = 0; *assocp = 0;#ifdef ZTS tsrm_mutex_lock (yaz_mutex);#endif ZEND_FETCH_RESOURCE(as, Yaz_Association *, id, -1, "YAZ link", le_link); if (as && *as && (*as)->order == YAZSG(assoc_seq) && (*as)->in_use) { *assocp = *as; } else {#ifdef ZTS tsrm_mutex_unlock (yaz_mutex);#endif php_error(E_WARNING, "Invalid YAZ handle"); }}static void release_assoc (Yaz_Association assoc){#ifdef ZTS if (assoc) tsrm_mutex_unlock(yaz_mutex);#endif}static const char *array_lookup_string(HashTable *ht, const char *idx){ pval **pvalue; if (ht && zend_hash_find(ht, (char*) idx, strlen(idx)+1, (void**) &pvalue) == SUCCESS) { SEPARATE_ZVAL(pvalue); convert_to_string(*pvalue); return (*pvalue)->value.str.val; } return 0;}static long *array_lookup_long(HashTable *ht, const char *idx){ pval **pvalue; if (ht && zend_hash_find(ht, (char*) idx, strlen(idx)+1, (void**) &pvalue) == SUCCESS) { SEPARATE_ZVAL(pvalue); convert_to_long(*pvalue); return &(*pvalue)->value.lval; } return 0;}static long *array_lookup_bool(HashTable *ht, const char *idx){ pval **pvalue; if (ht && zend_hash_find(ht, (char*) idx, strlen(idx)+1, (void**) &pvalue) == SUCCESS) { SEPARATE_ZVAL(pvalue); convert_to_boolean(*pvalue); return &(*pvalue)->value.lval; } return 0;}#if iliaa_0 /* compile warning fix */static int send_present (Yaz_Association t);static int send_sort_present (Yaz_Association t);static int send_sort (Yaz_Association t);#endifconst char *option_get (Yaz_Association as, const char *name){ if (!as) return 0; return ZOOM_connection_option_get (as->zoom_conn, name);}int option_get_int (Yaz_Association as, const char *name, int def){ const char *v; v = ZOOM_connection_option_get (as->zoom_conn, name); if (!v) return def; return atoi(v);}void option_set (Yaz_Association as, const char *name, const char *value){ if (as && value) ZOOM_connection_option_set (as->zoom_conn, name, value);}void option_set_int (Yaz_Association as, const char *name, int v){ if (as) { char s[30]; sprintf (s, "%d", v); ZOOM_connection_option_set (as->zoom_conn, name, s); }}static int strcmp_null(const char *s1, const char *s2){ if (s1 == 0 && s2 == 0) return 0; if (s1 == 0 || s2 == 0) return -1; return strcmp(s1, s2);}/* {{{ proto int yaz_connect(string zurl [ array options]) Create target with given zurl. Returns positive id if successful. */PHP_FUNCTION(yaz_connect){ int i; char *cp; char *zurl_str; const char *user_str = 0, *group_str = 0, *pass_str = 0; const char *cookie_str = 0, *proxy_str = 0; const char *charset_str = 0; const char *client_IP = 0; const char *otherInfo[3]; int persistent = 1; int piggyback = 1; pval **zurl, **user = 0; Yaz_Association as; otherInfo[0] = otherInfo[1] = otherInfo[2] = 0; if (ZEND_NUM_ARGS() == 1) { if (zend_get_parameters_ex (1, &zurl) == FAILURE) WRONG_PARAM_COUNT; } else if (ZEND_NUM_ARGS() == 2) { if (zend_get_parameters_ex (2, &zurl, &user) == FAILURE) WRONG_PARAM_COUNT; if (Z_TYPE_PP(user) == IS_ARRAY) { long *persistent_val; long *piggyback_val; HashTable *ht = Z_ARRVAL_PP(user); user_str = array_lookup_string(ht, "user"); group_str = array_lookup_string(ht, "group"); pass_str = array_lookup_string(ht, "password"); cookie_str = array_lookup_string(ht, "cookie"); proxy_str = array_lookup_string(ht, "proxy"); charset_str = array_lookup_string(ht, "charset"); persistent_val = array_lookup_bool(ht, "persistent"); if (persistent_val) persistent = *persistent_val; piggyback_val = array_lookup_bool(ht, "piggyback"); if (piggyback_val) piggyback = *piggyback_val; otherInfo[0] = array_lookup_string(ht, "otherInfo0"); otherInfo[1] = array_lookup_string(ht, "otherInfo1"); otherInfo[2] = array_lookup_string(ht, "otherInfo2"); } else { convert_to_string_ex (user); user_str = (*user)->value.str.val; } } else { WRONG_PARAM_COUNT; } convert_to_string_ex (zurl); zurl_str = (*zurl)->value.str.val; for (cp = zurl_str; *cp && strchr("\t\n ", *cp); cp++) ; if (!*cp) RETURN_LONG(0); /* see if we have it already ... */#ifdef ZTS tsrm_mutex_lock (yaz_mutex);#endif for (i = 0; i<YAZSG(max_links); i++) { as = shared_associations[i]; if (persistent && as && !as->in_use && !strcmp_null(option_get(as, "host"), zurl_str) && !strcmp_null(option_get(as, "proxy"), proxy_str) && !strcmp_null(option_get(as, "user"), user_str) && !strcmp_null(option_get(as, "group"), group_str) && !strcmp_null(option_get(as, "pass"), pass_str) && !strcmp_null(option_get(as, "cookie"), cookie_str) && !strcmp_null(option_get(as, "charset"), charset_str)) { option_set (as, "clientIP", client_IP); option_set (as, "otherInfo0", otherInfo[0]); option_set (as, "otherInfo1", otherInfo[1]); option_set (as, "otherInfo2", otherInfo[2]); option_set (as, "piggyback", piggyback ? "1" : "0"); ZOOM_connection_connect (as->zoom_conn, zurl_str, 0); break; } } if (i == YAZSG(max_links)) { /* we didn't have it (or already in use) */ int i0 = -1; int min_order = 2000000000; /* find completely free slot or the oldest one */ for (i = 0; i<YAZSG(max_links) && shared_associations[i]; i++) { as = shared_associations[i]; if (persistent && !as->in_use && as->order < min_order) { min_order = as->order; i0 = i; } } if (i == YAZSG(max_links)) { i = i0; if (i == -1) {#ifdef ZTS tsrm_mutex_unlock (yaz_mutex);#endif RETURN_LONG(0); /* no free slot */ } else /* "best" free slot */ yaz_association_destroy(shared_associations[i]); } shared_associations[i] = as = yaz_association_mk (); option_set (as, "user", user_str); option_set (as, "group", group_str); option_set (as, "pass", pass_str); option_set (as, "cookie", cookie_str); option_set (as, "clientIP", client_IP); option_set (as, "otherInfo0", otherInfo[0]); option_set (as, "otherInfo1", otherInfo[1]); option_set (as, "otherInfo2", otherInfo[2]); option_set (as, "proxy", proxy_str); option_set (as, "piggyback", piggyback ? "1" : "0"); option_set (as, "charset", charset_str); ZOOM_connection_connect (as->zoom_conn, zurl_str, 0); } as->in_use = 1; as->persistent = persistent; as->order = YAZSG(assoc_seq);#ifdef ZTS tsrm_mutex_unlock (yaz_mutex);#endif ZEND_REGISTER_RESOURCE(return_value, &shared_associations[i], le_link);}/* }}} *//* {{{ proto int yaz_close(int id) Destory and close target */PHP_FUNCTION(yaz_close){ Yaz_Association p; pval **id; if (ZEND_NUM_ARGS() != 1) WRONG_PARAM_COUNT; if (zend_get_parameters_ex (1, &id) == FAILURE) RETURN_FALSE; get_assoc (INTERNAL_FUNCTION_PARAM_PASSTHRU, id, &p); if (!p) RETURN_FALSE; release_assoc (p); zend_list_delete ((*id)->value.lval); RETURN_TRUE;}/* }}} *//* {{{ proto int yaz_search(int id, string type, string query) Specify query of type for search - returns true if successful */PHP_FUNCTION(yaz_search){ char *query_str, *type_str; pval **id, **type, **query; Yaz_Association p; if (ZEND_NUM_ARGS() == 3) { if (zend_get_parameters_ex(3, &id, &type, &query) == FAILURE) { WRONG_PARAM_COUNT; } } else { WRONG_PARAM_COUNT; } get_assoc (INTERNAL_FUNCTION_PARAM_PASSTHRU, id, &p); if (!p) { RETURN_FALSE; } convert_to_string_ex (type); type_str = (*type)->value.str.val; convert_to_string_ex (query); query_str = (*query)->value.str.val; ZOOM_resultset_destroy (p->zoom_set); p->zoom_set = 0; if (!strcmp (type_str, "rpn")) { ZOOM_query q = ZOOM_query_create (); ZOOM_query_prefix (q, query_str); if (p->sort_criteria) ZOOM_query_sortby (q, p->sort_criteria); p->zoom_set = ZOOM_connection_search (p->zoom_conn, q); ZOOM_query_destroy (q); RETVAL_TRUE; } else { RETVAL_FALSE; } release_assoc (p);}/* }}} *//* {{{ proto int yaz_present(int id) Retrieve records */PHP_FUNCTION(yaz_present){ pval **id; Yaz_Association p; if (ZEND_NUM_ARGS() != 1) WRONG_PARAM_COUNT; if (zend_get_parameters_ex(1, &id) == FAILURE) { WRONG_PARAM_COUNT; } get_assoc (INTERNAL_FUNCTION_PARAM_PASSTHRU, id, &p); if (!p) { RETURN_FALSE; } if (p->zoom_set) { size_t start = option_get_int (p, "start", 0); size_t count = option_get_int (p, "count", 0); if (count > 0) ZOOM_resultset_records (p->zoom_set, 0 /* recs */, start, count); } release_assoc (p); RETURN_TRUE;}/* }}} *//* {{{ proto int yaz_wait([array options]) Process events. */PHP_FUNCTION(yaz_wait){ int no = 0; ZOOM_connection conn_ar[MAX_ASSOC]; int i, timeout = 15; if (ZEND_NUM_ARGS() == 1) { long *val = 0; pval **pval_options = 0; HashTable *options_ht = 0; if (zend_get_parameters_ex(1, &pval_options) == FAILURE) { WRONG_PARAM_COUNT; } if (Z_TYPE_PP(pval_options) != IS_ARRAY) { php_error(E_WARNING, "yaz_wait: Expected array parameter");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -