/* * Copyright (c) 2001-2008, Perforce Software, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL PERFORCE SOFTWARE, INC. BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "clientapi.h" #include "undefdups.h" extern "C" { #include "php.h" } #include "php_perforce.h" #include "php_p4_map.h" zend_class_entry *p4_map_ce; static zend_object_handlers p4map_object_handlers; /* P4_Map Class Methods */ static zend_function_entry perforce_p4_map_methods[] = { PHP_ME(P4_Map, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) PHP_ME(P4_Map, join, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_ME(P4_Map, clear, NULL, ZEND_ACC_PUBLIC) PHP_ME(P4_Map, count, NULL, ZEND_ACC_PUBLIC) PHP_ME(P4_Map, is_empty, NULL, ZEND_ACC_PUBLIC) PHP_ME(P4_Map, insert, NULL, ZEND_ACC_PUBLIC) PHP_ME(P4_Map, translate, NULL, ZEND_ACC_PUBLIC) PHP_ME(P4_Map, includes, NULL, ZEND_ACC_PUBLIC) PHP_ME(P4_Map, reverse, NULL, ZEND_ACC_PUBLIC) PHP_ME(P4_Map, lhs, NULL, ZEND_ACC_PUBLIC) PHP_ME(P4_Map, rhs, NULL, ZEND_ACC_PUBLIC) PHP_ME(P4_Map, as_array, NULL, ZEND_ACC_PUBLIC) { NULL, NULL, NULL } }; /* Get the zend_class_entry for P4_Map. */ zend_class_entry *get_p4_map_ce(void) { return p4_map_ce; } /* free storage allocated for P4_Map class. */ void p4_map_object_free_storage(void *object TSRMLS_DC) { p4map_object *obj = (p4map_object *)object; delete obj->mapmaker; zend_hash_destroy(obj->std.properties); FREE_HASHTABLE(obj->std.properties); efree(obj); } /* create_object handler for P4_Map class. */ zend_object_value p4_map_create_object(zend_class_entry *type TSRMLS_DC) { zval *tmp; zend_object_value retval; p4map_object *obj = (p4map_object *)emalloc(sizeof(p4map_object)); memset(obj, 0, sizeof(p4map_object)); obj->std.ce = type; ALLOC_HASHTABLE(obj->std.properties); zend_hash_init(obj->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0); #if PHP_VERSION_ID < 50399 zend_hash_copy(obj->std.properties, &type->default_properties, (copy_ctor_func_t)zval_add_ref, (void *)&tmp, sizeof(zval *)); #else object_properties_init(&(obj->std), type); #endif retval.handle = zend_objects_store_put(obj, NULL, p4_map_object_free_storage, NULL TSRMLS_CC); retval.handlers = &p4map_object_handlers; return retval; } /* Register the P4_Map Class. */ void register_p4_map_class(INIT_FUNC_ARGS) { zend_class_entry ce; INIT_CLASS_ENTRY(ce, "P4_Map", perforce_p4_map_methods); p4_map_ce = zend_register_internal_class(&ce TSRMLS_CC); p4_map_ce->create_object = p4_map_create_object; memcpy(&p4map_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); p4map_object_handlers.clone_obj = NULL; } /* Convenience method. Get the internal class associated with the PHP class. */ P4MapMaker *get_map_maker(zval *this_ptr) { P4MapMaker *mapmaker; TSRMLS_FETCH(); p4map_object *obj = (p4map_object *)zend_object_store_get_object( this_ptr TSRMLS_CC); mapmaker = obj->mapmaker; return mapmaker; } /* {{{ proto void P4_Map::__construct() Create a new P4_Map object instance. */ PHP_METHOD(P4_Map, __construct) { zval *arg1 = NULL; zval *arg2 = NULL; P4MapMaker *mapmaker = NULL; zval *object = getThis(); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|zz", &arg1, &arg2) == FAILURE) { RETURN_NULL(); } mapmaker = new P4MapMaker; if (ZEND_NUM_ARGS() == 1 && arg1 != NULL) { if (Z_TYPE_P(arg1) == IS_ARRAY) { zval **e; HashPosition pos; HashTable *ht = Z_ARRVAL_P(arg1); for (zend_hash_internal_pointer_reset_ex(ht, &pos); zend_hash_get_current_data_ex(ht, (void **)&e, &pos) == SUCCESS; zend_hash_move_forward_ex(ht, &pos)) { if (Z_TYPE_PP(e) == IS_STRING) { mapmaker->Insert(*e); } } } else if (Z_TYPE_P(arg1) == IS_STRING) { mapmaker->Insert(arg1); } } else if (ZEND_NUM_ARGS() == 2 && arg1 != NULL && arg2 != NULL) { if (Z_TYPE_P(arg1) == IS_STRING && Z_TYPE_P(arg2) == IS_STRING) { mapmaker->Insert(arg1, arg2); } } p4map_object *obj = (p4map_object *)zend_object_store_get_object( object TSRMLS_CC); obj->mapmaker = mapmaker; } /* }}} */ /* {{{ proto string P4_Map::join(string map1, string map2) * Class method. Joins two maps to create a third. */ PHP_METHOD(P4_Map, join) { zval *map1, *map2; P4MapMaker *mapmaker = NULL; P4MapMaker *retval = NULL; if (ZEND_NUM_ARGS() != 2) { WRONG_PARAM_COUNT; } if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &map1, &map2) == FAILURE) { RETURN_NULL(); } mapmaker = new P4MapMaker; P4MapMaker *map_one = get_map_maker(map1); P4MapMaker *map_two = get_map_maker(map2); retval = mapmaker->Join(map_one, map_two); // Create a P4_Map instance zend_class_entry **ce; if (zend_hash_find(EG(class_table), "p4_map", strlen("p4_map") + 1, (void **)&ce) == FAILURE) { RETURN_NULL(); } object_init_ex(return_value, *ce); // call constructor zval func; zval *dummy; INIT_ZVAL(func); ZVAL_STRING(&func, (char *)"__construct", 1); MAKE_STD_ZVAL(dummy); call_user_function(NULL, &return_value, &func, dummy, 0, NULL TSRMLS_CC); efree(dummy); // replace P4MapMaker instance p4map_object *obj = (p4map_object *)zend_object_store_get_object(return_value TSRMLS_CC); obj->mapmaker = retval; zval_dtor(&func); } /* }}} */ /* {{{ proto void P4_Map::clear() * Empties the map. */ PHP_METHOD(P4_Map, clear) { P4MapMaker *mapmaker = get_map_maker(getThis()); if (mapmaker != NULL) { mapmaker->Clear(); } } /* }}} */ /* {{{ proto int P4_Map::count() * Returns the number of entries in the map. */ PHP_METHOD(P4_Map, count) { int count = 0; P4MapMaker *mapmaker = get_map_maker(getThis()); if (mapmaker != NULL) { count = mapmaker->Count(); } RETURN_LONG(count); } /* }}} */ /* {{{ proto bool P4_Map::is_empty() * Returns True if the map is empty. */ PHP_METHOD(P4_Map, is_empty) { int count = 0; P4MapMaker *mapmaker = get_map_maker(getThis()); if (mapmaker != NULL) { count = mapmaker->Count(); if (count > 0) { RETURN_TRUE; } } RETURN_FALSE; } /* }}} */ /* {{{ proto void P4_Map::insert(string entry) * Adds new entries to the map. */ PHP_METHOD(P4_Map, insert) { zval *l, *r; P4MapMaker *mapmaker = get_map_maker(getThis()); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|z", &l, &r) == FAILURE) { RETURN_NULL(); } if (mapmaker != NULL) { if (ZEND_NUM_ARGS() == 1) { mapmaker->Insert(l); } else if (ZEND_NUM_ARGS() == 2) { mapmaker->Insert(l, r); } else { WRONG_PARAM_COUNT; } } } /* }}} */ /* {{{ proto string P4_Map::translate(string str, bool forward) * Translates a string through the map. */ PHP_METHOD(P4_Map, translate) { zend_bool fwd = 1; zval *str; P4MapMaker *mapmaker = get_map_maker(getThis()); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &str, &fwd) == FAILURE) { RETURN_NULL(); } if (Z_TYPE_P(str) != IS_STRING) { RETURN_NULL(); } zval *tmp = mapmaker->Translate(str, fwd); if (Z_TYPE_P(tmp) == IS_STRING) { RETVAL_STRING(Z_STRVAL_P(tmp), 1); } else { RETVAL_NULL(); } zval_dtor(tmp); efree(tmp); } /* }}} */ /* {{{ proto bool P4_Map::includes(string str) * Returns True if the supplied string is visible through the map. */ PHP_METHOD(P4_Map, includes) { char *path; int path_len; zval *zpath, *result; P4MapMaker *mapmaker; zend_bool retval; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &path, &path_len) == FAILURE) { RETURN_NULL(); } MAKE_STD_ZVAL(zpath); ZVAL_STRING(zpath, path, 1); mapmaker = get_map_maker(getThis()); result = mapmaker->Translate(zpath, 1); zval_dtor(zpath); efree(zpath); if (Z_TYPE_P(result) == IS_NULL) { RETVAL_FALSE; } else { RETVAL_TRUE; } zval_dtor(result); efree(result); } /* }}} */ /* {{{ proto object P4_Map::reverse() * Returns a new map with reversed mappings. */ PHP_METHOD(P4_Map, reverse) { zend_class_entry **ce; P4MapMaker *mapmaker; P4MapMaker *mapmaker_cp; // first make a copy of this instance's mapmaker mapmaker = get_map_maker(getThis()); mapmaker_cp = new P4MapMaker(*mapmaker); // then reverse the copy mapmaker_cp->Reverse(); // now, create new P4_Map instance if (zend_hash_find(EG(class_table), "p4_map", strlen("p4_map") + 1, (void **)&ce) == FAILURE) { RETURN_NULL(); } object_init_ex(return_value, *ce); // call constructor on new P4_Map instance zval func; zval *dummy; INIT_ZVAL(func); ZVAL_STRING(&func, (char *)"__construct", 1); MAKE_STD_ZVAL(dummy); call_user_function(NULL, &return_value, &func, dummy, 0, NULL TSRMLS_CC); efree(dummy); // create and assign new mapmaker p4map_object *obj = (p4map_object *)zend_object_store_get_object( return_value TSRMLS_CC); obj->mapmaker = mapmaker_cp; zval_dtor(&func); } /* }}} */ /* {{{ proto array P4_Map::lhs() * Returns the left-hand-side of the map. */ PHP_METHOD(P4_Map, lhs) { P4MapMaker *mapmaker = get_map_maker(getThis()); mapmaker->Lhs(return_value); } /* }}} */ /* {{{ proto array P4_Map::rhs() * Returns the right-hand-side of the map. */ PHP_METHOD(P4_Map, rhs) { P4MapMaker *mapmaker = get_map_maker(getThis()); mapmaker->Rhs(return_value); } /* }}} */ /* {{{ proto array P4_Map::as_array() * Returns the map as an array. */ PHP_METHOD(P4_Map, as_array) { P4MapMaker *mapmaker = get_map_maker(getThis()); mapmaker->ToA(return_value); } /* }}} */
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#2 | 24779 | Robert Cowham | P4PHP 2016.2.1490102 | ||
#1 | 16506 | perforce_software | Move P4PHP to main branch. | ||
//guest/perforce_software/p4php/php_p4_map.cc | |||||
#1 | 8467 | Jan Van Uytven |
Initial commit of P4PHP from //depot/main/p4-php |