/********************************************************************** * $Id$ * * Project: MapServer * Purpose: PHP/MapScript extension for MapServer : Utility functions * Header - macros * Author: Daniel Morissette, DM Solutions Group (dmorissette@dmsolutions.ca) * ********************************************************************** * Copyright (c) 2000, 2001, Daniel Morissette, DM Solutions Group Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies of this Software or works derived from this Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. **********************************************************************/ #ifndef PHP_MAPSCRIPT_UTIL_H #define PHP_MAPSCRIPT_UTIL_H #include "php.h" #include "php_globals.h" #include "php_mapscript.h" #if ZEND_MODULE_API_NO < 20010901 #define TSRMLS_D void #define TSRMLS_DC #define TSRMLS_C #define TSRMLS_CC #endif /* Add pseudo refcount macros for PHP version < 5.3 */ #ifndef Z_REFCOUNT_PP #define Z_REFCOUNT_PP(ppz) Z_REFCOUNT_P(*(ppz)) #define Z_SET_REFCOUNT_PP(ppz, rc) Z_SET_REFCOUNT_P(*(ppz), rc) #define Z_ADDREF_PP(ppz) Z_ADDREF_P(*(ppz)) #define Z_DELREF_PP(ppz) Z_DELREF_P(*(ppz)) #define Z_ISREF_PP(ppz) Z_ISREF_P(*(ppz)) #define Z_SET_ISREF_PP(ppz) Z_SET_ISREF_P(*(ppz)) #define Z_UNSET_ISREF_PP(ppz) Z_UNSET_ISREF_P(*(ppz)) #define Z_SET_ISREF_TO_PP(ppz, isref) Z_SET_ISREF_TO_P(*(ppz), isref) #define Z_REFCOUNT_P(pz) zval_refcount_p(pz) #define Z_SET_REFCOUNT_P(pz, rc) zval_set_refcount_p(pz, rc) #define Z_ADDREF_P(pz) zval_addref_p(pz) #define Z_DELREF_P(pz) zval_delref_p(pz) #define Z_ISREF_P(pz) zval_isref_p(pz) #define Z_SET_ISREF_P(pz) zval_set_isref_p(pz) #define Z_UNSET_ISREF_P(pz) zval_unset_isref_p(pz) #define Z_SET_ISREF_TO_P(pz, isref) zval_set_isref_to_p(pz, isref) #define Z_REFCOUNT(z) Z_REFCOUNT_P(&(z)) #define Z_SET_REFCOUNT(z, rc) Z_SET_REFCOUNT_P(&(z), rc) #define Z_ADDREF(z) Z_ADDREF_P(&(z)) #define Z_DELREF(z) Z_DELREF_P(&(z)) #define Z_ISREF(z) Z_ISREF_P(&(z)) #define Z_SET_ISREF(z) Z_SET_ISREF_P(&(z)) #define Z_UNSET_ISREF(z) Z_UNSET_ISREF_P(&(z)) #define Z_SET_ISREF_TO(z, isref) Z_SET_ISREF_TO_P(&(z), isref) #if defined(__GNUC__) #define zend_always_inline inline __attribute__((always_inline)) #elif defined(_MSC_VER) #define zend_always_inline __forceinline #else #define zend_always_inline inline #endif static zend_always_inline zend_uint zval_refcount_p(zval* pz) { return pz->refcount; } static zend_always_inline zend_uint zval_set_refcount_p(zval* pz, zend_uint rc) { return pz->refcount = rc; } static zend_always_inline zend_uint zval_addref_p(zval* pz) { return ++pz->refcount; } static zend_always_inline zend_uint zval_delref_p(zval* pz) { return --pz->refcount; } static zend_always_inline zend_bool zval_isref_p(zval* pz) { return pz->is_ref; } static zend_always_inline zend_bool zval_set_isref_p(zval* pz) { return pz->is_ref = 1; } static zend_always_inline zend_bool zval_unset_isref_p(zval* pz) { return pz->is_ref = 0; } static zend_always_inline zend_bool zval_set_isref_to_p(zval* pz, zend_bool isref) { return pz->is_ref = isref; } #endif /* PHP >=5.3 replaced ZVAL_DELREF by Z_DELREF_P */ #if ZEND_MODULE_API_NO >= 20090626 #define ZVAL_DELREF Z_DELREF_P #define ZVAL_ADDREF Z_ADDREF_P #endif #define MAPSCRIPT_REGISTER_CLASS(name, functions, class_entry, constructor) \ INIT_CLASS_ENTRY(ce, name, functions); \ class_entry = zend_register_internal_class(&ce TSRMLS_CC); \ class_entry->create_object = constructor; #define MAPSCRIPT_ALLOC_OBJECT(zobj, object_type) \ zobj = ecalloc(1, sizeof(object_type)); #define MAPSCRIPT_FREE_OBJECT(zobj) \ zend_hash_destroy(zobj->std.properties); \ FREE_HASHTABLE(zobj->std.properties); #define MAPSCRIPT_ADDREF(zobj) if (zobj) Z_ADDREF_P(zobj) #define MAPSCRIPT_DELREF(zobj) \ if (zobj) \ { \ if (Z_REFCOUNT_P(zobj) == 1) { \ zval_ptr_dtor(&zobj); \ } \ else { \ Z_DELREF_P(zobj); \ } \ zobj = NULL; \ } #define MAPSCRIPT_INIT_PARENT(parent) \ parent.val = NULL; \ parent.child_ptr = NULL; #define MAPSCRIPT_FREE_PARENT(parent) \ if (parent.child_ptr) \ *parent.child_ptr = NULL; \ MAPSCRIPT_DELREF(parent.val); #define MAPSCRIPT_MAKE_PARENT(zobj, ptr) \ parent.val = zobj; \ parent.child_ptr = ptr; #define MAPSCRIPT_CALL_METHOD_1(zobj, function_name, retval, arg1) \ zend_call_method_with_1_params(&zobj, Z_OBJCE_P(zobj), NULL, function_name, &retval, arg1); #define MAPSCRIPT_CALL_METHOD_2(zobj, function_name, retval, arg1, arg2) \ zend_call_method_with_2_params(&zobj, Z_OBJCE_P(zobj), NULL, function_name, &retval, arg1, arg2); #define STRING_EQUAL(string1, string2) \ strcmp(string1, string2) == 0 /* helpers for getters */ #define IF_GET_STRING(property_name, value) \ if (strcmp(property, property_name)==0) \ { \ RETVAL_STRING( (value ? value:"") , 1); \ } \ #define IF_GET_LONG(property_name, value) \ if (strcmp(property, property_name)==0) \ { \ RETVAL_LONG(value); \ } \ #define IF_GET_DOUBLE(property_name, value) \ if (strcmp(property, property_name)==0) \ { \ RETVAL_DOUBLE(value); \ } \ #define IF_GET_OBJECT(property_name, mapscript_ce, php_object_storage, internal_object) \ if (strcmp(property, property_name)==0) \ { \ if (!php_object_storage) { \ mapscript_fetch_object(mapscript_ce, zobj, NULL, (void*)internal_object, \ &php_object_storage TSRMLS_CC); \ } \ RETURN_ZVAL(php_object_storage, 1, 0); \ } #define CHECK_OBJECT(mapscript_ce, php_object_storage, internal_object) \ if (!php_object_storage) { \ mapscript_fetch_object(mapscript_ce, zobj, NULL, (void*)internal_object, \ &php_object_storage TSRMLS_CC); \ } /* helpers for setters */ #define IF_SET_STRING(property_name, internal, value) \ if (strcmp(property, property_name)==0) \ { \ convert_to_string(value); \ if (internal) free(internal); \ if (Z_STRVAL_P(value)) \ internal = strdup(Z_STRVAL_P(value)); \ } #define IF_SET_LONG(property_name, internal, value) \ if (strcmp(property, property_name)==0) \ { \ convert_to_long(value); \ internal = Z_LVAL_P(value); \ } #define IF_SET_DOUBLE(property_name, internal, value) \ if (strcmp(property, property_name)==0) \ { \ convert_to_double(value); \ internal = Z_DVAL_P(value); \ } #define IF_SET_BYTE(property_name, internal, value) \ if (strcmp(property, property_name)==0) \ { \ convert_to_long(value); \ internal = (unsigned char)Z_LVAL_P(value); \ } #define IF_SET_COLOR(property_name, internal, value) \ if (strcmp(property, property_name)==0) \ { \ convert_to_long(value); \ /* validate the color value */ \ if (Z_LVAL_P(value) < 0 || Z_LVAL_P(value) > 255) { \ mapscript_throw_exception("Invalid color value. It must be between 0 and 255." TSRMLS_CC); \ return; \ } \ internal = Z_LVAL_P(value); \ } zend_object_value mapscript_object_new(zend_object *zobj, zend_class_entry *ce, void (*zend_objects_free_object) TSRMLS_DC); int mapscript_extract_associative_array(HashTable *php, char **array); #endif /* PHP_MAPSCRIPT_UTIL_H */