├── .gitignore ├── tests ├── m001.phpt ├── m003.phpt ├── m009.phpt ├── m006.phpt ├── m007.phpt ├── m005.phpt ├── m004.phpt ├── m002.phpt ├── m001.cpp ├── m008.phpt ├── m007.cpp ├── m002.cpp ├── m003.cpp ├── m004.cpp ├── m008.cpp ├── m009.cpp ├── m005.cpp └── m006.cpp ├── boost └── php │ ├── function.hpp │ ├── module_def.hpp │ ├── resource_handle.hpp │ ├── detail │ ├── tsrm_macros.hpp │ ├── object_retriever.hpp │ ├── module_hooks.hpp │ ├── value_helpers.hpp │ ├── stream_support.hpp │ ├── function_template.hpp │ ├── caller.hpp │ ├── arg_info_factory.hpp │ ├── function_container.hpp │ ├── functional.hpp │ ├── signature.hpp │ ├── native_fun_proxy.hpp │ └── module_macros.hpp │ ├── utils.hpp │ ├── string.hpp │ ├── exceptions.hpp │ ├── error.hpp │ ├── object.hpp │ ├── module.hpp │ ├── converter.hpp │ ├── hashtable.hpp │ ├── klass.hpp │ └── value.hpp └── Makefile /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.so 3 | -------------------------------------------------------------------------------- /tests/m001.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | m001: extension loading 3 | --SKIPIF-- 4 | --INI-- 5 | extension=m001.so 6 | --FILE-- 7 | 10 | --EXPECT-- 11 | bool(true) 12 | -------------------------------------------------------------------------------- /tests/m003.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | m003: string manipulations 3 | --SKIPIF-- 4 | --INI-- 5 | extension=m003.so 6 | --FILE-- 7 | 10 | --EXPECT-- 11 | string(9) "ABCDEF..." 12 | -------------------------------------------------------------------------------- /tests/m009.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | m009: Implementing SPL classes 3 | --SKIPIF-- 4 | --INI-- 5 | extension=m009.so 6 | --FILE-- 7 | 12 | --EXPECT-- 13 | int(0) 14 | int(1) 15 | int(2) 16 | int(3) 17 | int(4) 18 | -------------------------------------------------------------------------------- /tests/m006.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | m006: extension using php's native functions 3 | --SKIPIF-- 4 | --INI-- 5 | extension=m006.so 6 | --FILE-- 7 | 10 | --EXPECT-- 11 | string(51) " 14 | " 15 | -------------------------------------------------------------------------------- /tests/m007.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | m007: extension-wide variables 3 | --SKIPIF-- 4 | --INI-- 5 | extension=m007.so 6 | --FILE-- 7 | 12 | --EXPECT-- 13 | int(0) 14 | int(1) 15 | int(3) 16 | int(6) 17 | int(10) 18 | int(15) 19 | int(21) 20 | int(28) 21 | int(36) 22 | int(45) 23 | -------------------------------------------------------------------------------- /tests/m005.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | m005: array manipulations 3 | --SKIPIF-- 4 | --INI-- 5 | extension=m005.so 6 | --FILE-- 7 | "4", 5)); 9 | var_dump(array_explode(':', array(1, 2, 3, "A" => "4", 5))); 10 | ?> 11 | --EXPECT-- 12 | 0 13 | 1 14 | 2 15 | A 16 | 3 17 | 1 18 | 2 19 | 3 20 | 4 21 | 5 22 | string(9) "1:2:3:4:5" 23 | -------------------------------------------------------------------------------- /tests/m004.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | m004: reading an array 3 | --SKIPIF-- 4 | --INI-- 5 | extension=m004.so 6 | --FILE-- 7 | 13 | --EXPECT-- 14 | string(37) "The content of array element #0 is 1." 15 | string(37) "The content of array element #1 is 2." 16 | string(37) "The content of array element #2 is 3." 17 | -------------------------------------------------------------------------------- /tests/m002.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | m002: simple functions definition 3 | --SKIPIF-- 4 | --INI-- 5 | extension=m002.so 6 | --FILE-- 7 | 12 | --EXPECT-- 13 | int(2) 14 | int(-2) 15 | int(3) 16 | int(-1) 17 | int(4) 18 | int(0) 19 | int(5) 20 | int(1) 21 | int(6) 22 | int(2) 23 | int(7) 24 | int(3) 25 | int(8) 26 | int(4) 27 | int(9) 28 | int(5) 29 | int(10) 30 | int(6) 31 | int(11) 32 | int(7) 33 | -------------------------------------------------------------------------------- /tests/m001.cpp: -------------------------------------------------------------------------------- 1 | #include "boost/php/module.hpp" 2 | 3 | using namespace boost; 4 | 5 | class m001_module 6 | : public php::module { 7 | public: 8 | class handler 9 | : public php::module::handler { 10 | public: 11 | handler(m001_module* mod) 12 | :php::module::handler(mod) {} 13 | }; 14 | public: 15 | m001_module(zend_module_entry* entry) 16 | : php::module(entry) { 17 | } 18 | }; 19 | 20 | #define BOOST_PHP_MODULE_NAME m001 21 | #define BOOST_PHP_MODULE_CAPITALIZED_NAME M001 22 | #define BOOST_PHP_MODULE_VERSION "0.1" 23 | #define BOOST_PHP_MODULE_CLASS_NAME m001_module 24 | 25 | #include "boost/php/module_def.hpp" 26 | -------------------------------------------------------------------------------- /tests/m008.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | m008: C++/PHP classes 3 | --SKIPIF-- 4 | --INI-- 5 | extension=m008.so 6 | --FILE-- 7 | accumulate($i); 12 | test::foo($test1); 13 | var_dump($test2 == $test2->self()); 14 | var_dump($test2->self()->self()->accumulate(10-$i)); 15 | echo "--\n"; 16 | } 17 | ?> 18 | --EXPECT-- 19 | 1 20 | bool(true) 21 | int(12) 22 | -- 23 | 2 24 | bool(true) 25 | int(21) 26 | -- 27 | 4 28 | bool(true) 29 | int(29) 30 | -- 31 | 7 32 | bool(true) 33 | int(36) 34 | -- 35 | 11 36 | bool(true) 37 | int(42) 38 | -- 39 | 16 40 | bool(true) 41 | int(47) 42 | -- 43 | 22 44 | bool(true) 45 | int(51) 46 | -- 47 | 29 48 | bool(true) 49 | int(54) 50 | -- 51 | 37 52 | bool(true) 53 | int(56) 54 | -- 55 | 46 56 | bool(true) 57 | int(57) 58 | -- 59 | -------------------------------------------------------------------------------- /tests/m007.cpp: -------------------------------------------------------------------------------- 1 | #include "boost/php/module.hpp" 2 | #include "boost/php/function.hpp" 3 | 4 | using namespace boost; 5 | 6 | class m007_module 7 | : public php::module, 8 | public php::function_container { 9 | public: 10 | class handler 11 | : public php::module::handler { 12 | public: 13 | handler(m007_module* mod) 14 | :php::module::handler(mod), acc_(0) {} 15 | 16 | int accumulate(int a) { 17 | acc_ += a; 18 | return acc_; 19 | } 20 | 21 | protected: 22 | int acc_; 23 | }; 24 | public: 25 | m007_module(zend_module_entry* entry) 26 | : php::module(entry) { 27 | entry->functions = 28 | defun("accumulate", &handler::accumulate); 29 | } 30 | }; 31 | 32 | #define BOOST_PHP_MODULE_NAME m007 33 | #define BOOST_PHP_MODULE_CAPITALIZED_NAME M007 34 | #define BOOST_PHP_MODULE_VERSION "0.1" 35 | #define BOOST_PHP_MODULE_CLASS_NAME m007_module 36 | 37 | #include "boost/php/module_def.hpp" 38 | -------------------------------------------------------------------------------- /tests/m002.cpp: -------------------------------------------------------------------------------- 1 | #include "boost/php/module.hpp" 2 | #include "boost/php/function.hpp" 3 | 4 | using namespace boost; 5 | 6 | class m002_module 7 | : public php::module, 8 | public php::function_container { 9 | public: 10 | class handler 11 | : public php::module::handler { 12 | public: 13 | handler(m002_module* mod) 14 | :php::module::handler(mod) {} 15 | 16 | int add(int a, int b) { 17 | return a + b; 18 | } 19 | 20 | int sub(int a, int b) { 21 | return a - b; 22 | } 23 | }; 24 | public: 25 | m002_module(zend_module_entry* entry) 26 | : php::module(entry) { 27 | entry->functions = 28 | defun("add", &handler::add). 29 | defun("sub", &handler::sub); 30 | } 31 | }; 32 | 33 | #define BOOST_PHP_MODULE_NAME m002 34 | #define BOOST_PHP_MODULE_CAPITALIZED_NAME M002 35 | #define BOOST_PHP_MODULE_VERSION "0.1" 36 | #define BOOST_PHP_MODULE_CLASS_NAME m002_module 37 | 38 | #include "boost/php/module_def.hpp" 39 | -------------------------------------------------------------------------------- /tests/m003.cpp: -------------------------------------------------------------------------------- 1 | #include "boost/php/module.hpp" 2 | #include "boost/php/function.hpp" 3 | 4 | using namespace boost; 5 | 6 | class m003_module 7 | : public php::module, 8 | public php::function_container { 9 | public: 10 | class handler 11 | : public php::module::handler { 12 | public: 13 | handler(m003_module* mod) 14 | :php::module::handler(mod) {} 15 | 16 | php::value_ptr concat_and_uppercase( 17 | std::string a, std::string b) { 18 | php::function strtoupper("strtoupper"); 19 | return strtoupper(a + b); 20 | } 21 | }; 22 | public: 23 | m003_module(zend_module_entry* entry) 24 | : php::module(entry) { 25 | entry->functions = 26 | defun("concat_and_uppercase", &handler::concat_and_uppercase); 27 | } 28 | }; 29 | 30 | #define BOOST_PHP_MODULE_NAME m003 31 | #define BOOST_PHP_MODULE_CAPITALIZED_NAME M003 32 | #define BOOST_PHP_MODULE_VERSION "0.1" 33 | #define BOOST_PHP_MODULE_CLASS_NAME m003_module 34 | 35 | #include "boost/php/module_def.hpp" 36 | -------------------------------------------------------------------------------- /tests/m004.cpp: -------------------------------------------------------------------------------- 1 | #include "boost/php/module.hpp" 2 | #include "boost/php/function.hpp" 3 | 4 | using namespace boost; 5 | 6 | class m004_module 7 | : public php::module, 8 | public php::function_container { 9 | public: 10 | class handler 11 | : public php::module::handler { 12 | public: 13 | handler(m004_module* mod) 14 | :php::module::handler(mod) {} 15 | 16 | ::std::string array_func(const php::array& a, int idx) { 17 | return ::std::string("The content of array element #") 18 | + static_cast< ::std::string>(php::value(idx)) + " is " 19 | + static_cast< ::std::string>(*a[idx]) + "."; 20 | } 21 | }; 22 | 23 | public: 24 | m004_module(zend_module_entry* entry) 25 | : php::module(entry) { 26 | entry->functions = 27 | defun("array_func", &handler::array_func); 28 | } 29 | }; 30 | 31 | #define BOOST_PHP_MODULE_NAME m004 32 | #define BOOST_PHP_MODULE_CAPITALIZED_NAME M004 33 | #define BOOST_PHP_MODULE_VERSION "0.1" 34 | #define BOOST_PHP_MODULE_CLASS_NAME m004_module 35 | 36 | #include "boost/php/module_def.hpp" 37 | -------------------------------------------------------------------------------- /boost/php/function.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2008 (C) Moriyoshi Koizumi. All rights reserved. 3 | // 4 | // This software is distributed under the Boost Software License, Version 1.0. 5 | // 6 | // Permission is hereby granted, free of charge, to any person or organization 7 | // obtaining a copy of the software and accompanying documentation covered by 8 | // this license (the "Software") to use, reproduce, display, distribute, 9 | // execute, and transmit the Software, and to prepare derivative works of the 10 | // Software, and to permit third-parties to whom the Software is furnished to 11 | // do so, all subject to the following: 12 | // 13 | // The copyright notices in the Software and this entire statement, including 14 | // the above license grant, this restriction and the following disclaimer, 15 | // must be included in all copies of the Software, in whole or in part, and 16 | // all derivative works of the Software, unless such copies or derivative 17 | // works are solely in the form of machine-executable object code generated by 18 | // a source language processor. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 23 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 24 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 25 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | // DEALINGS IN THE SOFTWARE. 27 | 28 | #ifndef BOOST_PHP_FUNCTION_HPP 29 | #define BOOST_PHP_FUNCTION_HPP 30 | 31 | #include 32 | #include 33 | #include 34 | 35 | #endif /* BOOST_PHP_FUNCTION_HPP */ 36 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | #!/bin/make 2 | 3 | # The prefix of your PHP installation. Leave it blank for auto-detection. 4 | PHP_ROOT= 5 | 6 | # System config 7 | CXX=g++ 8 | LD=g++ 9 | CPPFLAGS= 10 | CXXFLAGS= 11 | LDFLAGS= 12 | 13 | # Check if we system-wide php-config is available, or should we stay compatible 14 | # with initial makefile 15 | PHP_CONFIG=$(shell $(if $(PHP_ROOT),PATH="$(PHP_ROOT)/bin:$$PATH",) which 2>/dev/null php-config) 16 | PHP_BINARY=$(shell $(if $(PHP_ROOT),PATH="$(PHP_ROOT)/bin:$$PATH",) which 2>/dev/null php) 17 | PHP_TEST=$(shell find $(shell $(PHP_CONFIG) --prefix) -name run-tests.php) 18 | ifeq ($(PHP_CONFIG),) 19 | $(error Could not find PHP, make sure you have php-config in PATH!) 20 | endif 21 | 22 | # Find out some stuff 23 | PHP_INCLUDES=$(shell $(PHP_CONFIG) --includes) 24 | PHP_LDFLAGS=$(shell $(PHP_CONFIG) --ldflags) 25 | 26 | # Initialize variables 27 | CPPFLAGS+=-I. $(PHP_INCLUDES) 28 | CXXFLAGS+=-g -pipe -Wall 29 | 30 | # PIC should be ignored if the arch doesn't need it. 31 | CXXFLAGS+=-fPIC -DPIC 32 | 33 | # This one is also to stay compatible with initial makefile 34 | ifneq ($(wildcard $(HOME)/Sources/boost_1_35_0),) 35 | CPPFLAGS+=-I$(HOME)/Sources/boost_1_35_0 36 | endif 37 | 38 | # Darwin's way of building shared libs 39 | LDFLAGS+=$(if $(shell uname | grep "Darwin"), -bundle -undefined dynamic_lookup, -shared) 40 | 41 | all: $(patsubst %.cpp, %.so, $(wildcard tests/*.cpp)) 42 | 43 | tests/m%.o: tests/m%.cpp 44 | $(CXX) -DCOMPILE_DL_M$* $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $< 45 | 46 | tests/m%.so: tests/m%.o 47 | $(LD) $(CXXFLAGS) $(LDFLAGS) -o $@ $^ 48 | 49 | # invoke PHP for each target (may not work if your php installation is too "deep") 50 | test: $(TARGETS) 51 | TEST_PHP_EXECUTABLE="$(PHP_BINARY)" $(PHP_BINARY) $(PHP_TEST) -n -d extension_dir=`pwd`/tests tests 52 | 53 | clean: 54 | rm -f tests/*.o 55 | rm -f tests/*.so 56 | 57 | .PHONY: clean all test 58 | .SUFFIXES: .o .cpp .so 59 | 60 | -------------------------------------------------------------------------------- /tests/m008.cpp: -------------------------------------------------------------------------------- 1 | #include "boost/php/module.hpp" 2 | #include "boost/php/function.hpp" 3 | #include "boost/php/klass.hpp" 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace boost; 9 | 10 | class test { 11 | public: 12 | test(int initial): acc_(initial) { 13 | } 14 | 15 | int accumulate(int a) { 16 | acc_ += a; 17 | return acc_; 18 | } 19 | 20 | test& self() { 21 | return *this; 22 | } 23 | 24 | static void foo(test const& t) { 25 | std::cout << t.acc_ << std::endl; 26 | } 27 | 28 | static boost::shared_ptr create(int initial) { 29 | return boost::shared_ptr(new test(initial)); 30 | } 31 | 32 | /* 33 | static test* create(int initial) { 34 | return new test(initial); 35 | } 36 | */ 37 | protected: 38 | int acc_; 39 | }; 40 | 41 | class m008_module 42 | : public php::module, 43 | public php::function_container { 44 | public: 45 | class handler 46 | : public php::module::handler { 47 | public: 48 | handler(m008_module* mod) 49 | : php::module::handler(mod) {} 50 | 51 | void __initialize(TSRMLS_D) { 52 | php::def_class("test", boost::mpl::vector1() TSRMLS_CC) 53 | .defun("accumulate", &test::accumulate) 54 | .defun("foo", &test::foo) 55 | .defun("self", &test::self) 56 | .defun("create", &test::create) 57 | .fixup(); 58 | } 59 | }; 60 | public: 61 | m008_module(zend_module_entry* entry) 62 | : php::module(entry) { 63 | } 64 | }; 65 | 66 | #define BOOST_PHP_MODULE_NAME m008 67 | #define BOOST_PHP_MODULE_CAPITALIZED_NAME M008 68 | #define BOOST_PHP_MODULE_VERSION "0.1" 69 | #define BOOST_PHP_MODULE_CLASS_NAME m008_module 70 | 71 | #include "boost/php/module_def.hpp" 72 | -------------------------------------------------------------------------------- /tests/m009.cpp: -------------------------------------------------------------------------------- 1 | #include "boost/php/module.hpp" 2 | #include "boost/php/function.hpp" 3 | #include "boost/php/klass.hpp" 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace boost; 10 | 11 | class RangeIterator { 12 | public: 13 | RangeIterator(int start, int end): cnt_(start), till_(end) {} 14 | 15 | int current() const { 16 | return cnt_; 17 | } 18 | 19 | int key() const { 20 | return cnt_; 21 | } 22 | 23 | void rewind() { 24 | cnt_ = 0; 25 | } 26 | 27 | bool valid() const { 28 | return cnt_ < till_; 29 | } 30 | 31 | void next() { 32 | ++cnt_; 33 | } 34 | 35 | private: 36 | int cnt_; 37 | const int till_; 38 | }; 39 | 40 | class m009_module 41 | : public php::module, 42 | public php::function_container { 43 | public: 44 | class handler 45 | : public php::module::handler { 46 | public: 47 | handler(m009_module* mod) 48 | : php::module::handler(mod) {} 49 | 50 | void __initialize(TSRMLS_D) { 51 | php::def_class("RangeIterator", boost::mpl::vector2() TSRMLS_CC) 52 | .implements(::zend_ce_iterator) 53 | .defun("rewind", &RangeIterator::rewind) 54 | .defun("key", &RangeIterator::key) 55 | .defun("current", &RangeIterator::current) 56 | .defun("next", &RangeIterator::next) 57 | .defun("valid", &RangeIterator::valid) 58 | .fixup(); 59 | } 60 | }; 61 | public: 62 | m009_module(zend_module_entry* entry) 63 | : php::module(entry) { 64 | } 65 | }; 66 | 67 | #define BOOST_PHP_MODULE_NAME m009 68 | #define BOOST_PHP_MODULE_CAPITALIZED_NAME M008 69 | #define BOOST_PHP_MODULE_VERSION "0.1" 70 | #define BOOST_PHP_MODULE_CLASS_NAME m009_module 71 | 72 | #include "boost/php/module_def.hpp" 73 | -------------------------------------------------------------------------------- /tests/m005.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "boost/php/module.hpp" 4 | #include "boost/php/function.hpp" 5 | 6 | using namespace boost; 7 | 8 | class m005_module 9 | : public php::module, 10 | public php::function_container { 11 | public: 12 | class handler 13 | : public php::module::handler { 14 | public: 15 | handler(m005_module* mod) 16 | :php::module::handler(mod) {} 17 | 18 | struct print { 19 | void operator()(php::array::const_reference r) { 20 | std::cout << r.second << std::endl; 21 | } 22 | }; 23 | 24 | ::std::string array_explode(::std::string sep, 25 | const php::array& a) { 26 | ::std::string retval; 27 | php::array::const_iterator i(a.begin()), e(a.end()); 28 | if (i != e) { 29 | for (;;) { 30 | retval += (std::string)*(*i).second; 31 | if (++i == e) 32 | break; 33 | retval += sep; 34 | } 35 | } 36 | return retval; 37 | } 38 | 39 | void array_iter(const php::array& a) { 40 | for (php::array::const_iterator i(a.begin()), e(a.end()); 41 | i != e; ++i) { 42 | std::cout << (::std::string)(*i).first << std::endl; 43 | } 44 | std::for_each(a.begin(), a.end(), print()); 45 | } 46 | }; 47 | 48 | public: 49 | m005_module(zend_module_entry* entry) 50 | : php::module(entry) { 51 | entry->functions = 52 | defun("array_explode", &handler::array_explode). 53 | defun("array_iter", &handler::array_iter); 54 | } 55 | }; 56 | 57 | #define BOOST_PHP_MODULE_NAME m005 58 | #define BOOST_PHP_MODULE_CAPITALIZED_NAME M005 59 | #define BOOST_PHP_MODULE_VERSION "0.1" 60 | #define BOOST_PHP_MODULE_CLASS_NAME m005_module 61 | 62 | #include "boost/php/module_def.hpp" 63 | -------------------------------------------------------------------------------- /boost/php/module_def.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2008 (C) Moriyoshi Koizumi. All rights reserved. 3 | // 4 | // This software is distributed under the Boost Software License, Version 1.0. 5 | // 6 | // Permission is hereby granted, free of charge, to any person or organization 7 | // obtaining a copy of the software and accompanying documentation covered by 8 | // this license (the "Software") to use, reproduce, display, distribute, 9 | // execute, and transmit the Software, and to prepare derivative works of the 10 | // Software, and to permit third-parties to whom the Software is furnished to 11 | // do so, all subject to the following: 12 | // 13 | // The copyright notices in the Software and this entire statement, including 14 | // the above license grant, this restriction and the following disclaimer, 15 | // must be included in all copies of the Software, in whole or in part, and 16 | // all derivative works of the Software, unless such copies or derivative 17 | // works are solely in the form of machine-executable object code generated by 18 | // a source language processor. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 23 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 24 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 25 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | // DEALINGS IN THE SOFTWARE. 27 | 28 | #include 29 | 30 | BOOST_PHP_MODULE( 31 | BOOST_PHP_MODULE_NAME, 32 | BOOST_PHP_MODULE_VERSION, 33 | BOOST_PHP_MODULE_CLASS_NAME 34 | ) 35 | 36 | #define __BOOST_PHP_MODULE_DEF_TMP1 \ 37 | BOOST_PP_EXPAND(BOOST_PP_CAT(COMPILE_DL_, BOOST_PHP_MODULE_CAPITALIZED_NAME)) 38 | #if defined(/**/__BOOST_PHP_MODULE_DEF_TMP1) 39 | #define __BOOST_PHP_MODULE_DEF_TMP2(x) \ 40 | ZEND_GET_MODULE(x) 41 | __BOOST_PHP_MODULE_DEF_TMP2(BOOST_PHP_MODULE_NAME) 42 | #endif 43 | 44 | #undef BOOST_PHP_MODULE_NAME 45 | #undef BOOST_PHP_MODULE_VERSION 46 | #undef BOOST_PHP_MODULE_CLASS_NAME 47 | -------------------------------------------------------------------------------- /boost/php/resource_handle.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2008 (C) Moriyoshi Koizumi. All rights reserved. 3 | // 4 | // This software is distributed under the Boost Software License, Version 1.0. 5 | // 6 | // Permission is hereby granted, free of charge, to any person or organization 7 | // obtaining a copy of the software and accompanying documentation covered by 8 | // this license (the "Software") to use, reproduce, display, distribute, 9 | // execute, and transmit the Software, and to prepare derivative works of the 10 | // Software, and to permit third-parties to whom the Software is furnished to 11 | // do so, all subject to the following: 12 | // 13 | // The copyright notices in the Software and this entire statement, including 14 | // the above license grant, this restriction and the following disclaimer, 15 | // must be included in all copies of the Software, in whole or in part, and 16 | // all derivative works of the Software, unless such copies or derivative 17 | // works are solely in the form of machine-executable object code generated by 18 | // a source language processor. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 23 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 24 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 25 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | // DEALINGS IN THE SOFTWARE. 27 | 28 | #ifndef BOOST_RESOURCE_HANDLE_HPP 29 | #define BOOST_RESOURCE_HANDLE_HPP 30 | 31 | namespace boost { namespace php { 32 | 33 | class resource_handle { 34 | public: 35 | resource_handle(): value_() {} 36 | 37 | explicit resource_handle(long value): value_(value) {} 38 | 39 | const resource_handle& operator=(long rhs) { 40 | value_ = rhs; 41 | return *this; 42 | } 43 | 44 | const resource_handle& operator=(const resource_handle& rhs) { 45 | value_ = rhs.value_; 46 | return *this; 47 | } 48 | 49 | operator long() const { 50 | return value_; 51 | } 52 | 53 | private: 54 | long value_; 55 | }; 56 | 57 | } } // namespace boost::php 58 | 59 | #endif /* BOOST_PHP_RESOURCE_HANDLE_HPP */ 60 | -------------------------------------------------------------------------------- /boost/php/detail/tsrm_macros.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2008 (C) Moriyoshi Koizumi. All rights reserved. 3 | // 4 | // This software is distributed under the Boost Software License, Version 1.0. 5 | // 6 | // Permission is hereby granted, free of charge, to any person or organization 7 | // obtaining a copy of the software and accompanying documentation covered by 8 | // this license (the "Software") to use, reproduce, display, distribute, 9 | // execute, and transmit the Software, and to prepare derivative works of the 10 | // Software, and to permit third-parties to whom the Software is furnished to 11 | // do so, all subject to the following: 12 | // 13 | // The copyright notices in the Software and this entire statement, including 14 | // the above license grant, this restriction and the following disclaimer, 15 | // must be included in all copies of the Software, in whole or in part, and 16 | // all derivative works of the Software, unless such copies or derivative 17 | // works are solely in the form of machine-executable object code generated by 18 | // a source language processor. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 23 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 24 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 25 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | // DEALINGS IN THE SOFTWARE. 27 | 28 | #ifndef BOOST_PHP_TSRM_MACROS_HPP 29 | #define BOOST_PHP_TSRM_MACROS_HPP 30 | 31 | #ifdef ZTS 32 | 33 | #define BOOST_PHP_TSRM_MEMBER void*** tsrm_ls 34 | #define BOOST_PHP_TSRM_HANDLE reinterpret_cast(ts_resource_ex(0, 0)) 35 | #define BOOST_PHP_TSRM_DIRECT_C BOOST_PHP_TSRM_HANDLE 36 | #define BOOST_PHP_TSRM_DIRECT_CC , BOOST_PHP_TSRM_HANDLE 37 | #define BOOST_PHP_TSRM_FETCH_IN_CTOR \ 38 | tsrm_ls(BOOST_PHP_TSRM_HANDLE) 39 | #define BOOST_PHP_TSRM_FETCH_IN_CTOR_C \ 40 | , BOOST_PHP_TSRM_FETCH_IN_CTOR 41 | #else /* ZTS */ 42 | 43 | #define BOOST_PHP_TSRM_MEMBER 44 | #define BOOST_PHP_TSRM_HANDLE 45 | #define BOOST_PHP_TSRM_DIRECT_C 46 | #define BOOST_PHP_TSRM_DIRECT_CC 47 | #define BOOST_PHP_TSRM_FETCH_IN_CTOR 48 | #define BOOST_PHP_TSRM_FETCH_IN_CTOR_C 49 | 50 | #endif /* ZTS */ 51 | 52 | #endif /* BOOST_PHP_TSRM_MACROS_HPP */ 53 | -------------------------------------------------------------------------------- /boost/php/detail/object_retriever.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2008 (C) Moriyoshi Koizumi. All rights reserved. 3 | // 4 | // This software is distributed under the Boost Software License, Version 1.0. 5 | // 6 | // Permission is hereby granted, free of charge, to any person or organization 7 | // obtaining a copy of the software and accompanying documentation covered by 8 | // this license (the "Software") to use, reproduce, display, distribute, 9 | // execute, and transmit the Software, and to prepare derivative works of the 10 | // Software, and to permit third-parties to whom the Software is furnished to 11 | // do so, all subject to the following: 12 | // 13 | // The copyright notices in the Software and this entire statement, including 14 | // the above license grant, this restriction and the following disclaimer, 15 | // must be included in all copies of the Software, in whole or in part, and 16 | // all derivative works of the Software, unless such copies or derivative 17 | // works are solely in the form of machine-executable object code generated by 18 | // a source language processor. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 23 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 24 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 25 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | // DEALINGS IN THE SOFTWARE. 27 | 28 | #ifndef BOOST_PHP_DETAIL_OBJECT_RETRIEVER_HPP 29 | #define BOOST_PHP_DETAIL_OBJECT_RETRIEVER_HPP 30 | 31 | #include 32 | #include 33 | 34 | namespace boost { namespace php { 35 | 36 | // must be specialized somewhere 37 | template 38 | class object_retriever { 39 | public: 40 | Tobj_* operator()(INTERNAL_FUNCTION_PARAMETERS) const; 41 | }; 42 | 43 | template<> 44 | class object_retriever { 45 | public: 46 | void* operator()(INTERNAL_FUNCTION_PARAMETERS) const { return 0; } 47 | }; 48 | 49 | namespace detail { 50 | template 51 | const object_retriever& 52 | get_object_retriever(const Tsig_& sig) { 53 | static object_retriever oretr; 54 | return oretr; 55 | } 56 | } // namespace detail 57 | 58 | } } // namespace boost::php 59 | 60 | #endif /* BOOST_PHP_DETAIL_OBJECT_RETRIEVER_HPP */ 61 | -------------------------------------------------------------------------------- /tests/m006.cpp: -------------------------------------------------------------------------------- 1 | #include "boost/php/module.hpp" 2 | #include "boost/php/function.hpp" 3 | 4 | using namespace boost; 5 | 6 | class m006_module 7 | : public php::module, 8 | public php::function_container { 9 | public: 10 | class handler 11 | : public php::module::handler { 12 | public: 13 | handler(m006_module* mod) 14 | :php::module::handler(mod) {} 15 | 16 | php::value_ptr 17 | my_file_get_contents(::std::string filename) { 18 | php::function fopen("fopen"), 19 | fread("fread"), 20 | filesize("filesize"), 21 | fclose("fclose"); 22 | php::value_ptr $fp, $retval; 23 | 24 | BOOST_PHP_BEGIN_CAPTURE_ERROR 25 | $fp = fopen(filename, "rb"); 26 | if (*$fp == false) { 27 | throw php::runtime_error( 28 | std::string("Failure in system function: \"") 29 | + BOOST_PHP_LAST_ERROR.message() + "\"", 30 | BOOST_PHP_LAST_ERROR.filename().c_str(), 31 | BOOST_PHP_LAST_ERROR.line_number()); 32 | } 33 | BOOST_PHP_END_CAPTURE_ERROR 34 | 35 | try { 36 | BOOST_PHP_BEGIN_CAPTURE_ERROR 37 | $retval = fread($fp, filesize(filename)); 38 | if (*$retval == false) { 39 | throw php::runtime_error( 40 | std::string("Failure in system function: \"") 41 | + BOOST_PHP_LAST_ERROR.message() + "\"", 42 | BOOST_PHP_LAST_ERROR.filename().c_str(), 43 | BOOST_PHP_LAST_ERROR.line_number()); 44 | } 45 | BOOST_PHP_END_CAPTURE_ERROR 46 | } catch (const ::std::exception&) { 47 | fclose($fp); 48 | throw; 49 | } 50 | 51 | fclose($fp); 52 | 53 | return $retval; 54 | } 55 | }; 56 | 57 | public: 58 | m006_module(zend_module_entry* entry) 59 | : php::module(entry) { 60 | entry->functions = 61 | defun("my_file_get_contents", &handler::my_file_get_contents); 62 | } 63 | }; 64 | 65 | #define BOOST_PHP_MODULE_NAME m006 66 | #define BOOST_PHP_MODULE_CAPITALIZED_NAME M006 67 | #define BOOST_PHP_MODULE_VERSION "0.1" 68 | #define BOOST_PHP_MODULE_CLASS_NAME m006_module 69 | 70 | #include "boost/php/module_def.hpp" 71 | -------------------------------------------------------------------------------- /boost/php/detail/module_hooks.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2008 (C) Moriyoshi Koizumi. All rights reserved. 3 | // 4 | // This software is distributed under the Boost Software License, Version 1.0. 5 | // 6 | // Permission is hereby granted, free of charge, to any person or organization 7 | // obtaining a copy of the software and accompanying documentation covered by 8 | // this license (the "Software") to use, reproduce, display, distribute, 9 | // execute, and transmit the Software, and to prepare derivative works of the 10 | // Software, and to permit third-parties to whom the Software is furnished to 11 | // do so, all subject to the following: 12 | // 13 | // The copyright notices in the Software and this entire statement, including 14 | // the above license grant, this restriction and the following disclaimer, 15 | // must be included in all copies of the Software, in whole or in part, and 16 | // all derivative works of the Software, unless such copies or derivative 17 | // works are solely in the form of machine-executable object code generated by 18 | // a source language processor. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 23 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 24 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 25 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | // DEALINGS IN THE SOFTWARE. 27 | 28 | #ifndef BOOST_PHP_MODULE_HOOKS_HPP 29 | #define BOOST_PHP_MODULE_HOOKS_HPP 30 | 31 | #include 32 | 33 | namespace boost { namespace php { namespace detail { 34 | 35 | template 36 | struct hook_list 37 | { 38 | typedef T_ element_type; 39 | element_type* first; 40 | element_type* last; 41 | 42 | hook_list(): first(0), last(0) {} 43 | 44 | void append(element_type* item) { 45 | if (!first) { 46 | first = item; 47 | } 48 | if (!last) { 49 | last->next = item; 50 | } 51 | last = item; 52 | } 53 | }; 54 | 55 | // must not have any non-trivial constructors 56 | template 57 | struct module_hooks 58 | { 59 | struct initializer { 60 | virtual ~initializer() {} 61 | virtual void operator()(typename Tmod_::handler& mod TSRMLS_DC) = 0; 62 | initializer* next; 63 | }; 64 | 65 | struct finalizer { 66 | virtual ~finalizer() {} 67 | virtual void operator()(typename Tmod_::handler& mod TSRMLS_DC) = 0; 68 | finalizer* next; 69 | }; 70 | 71 | typedef hook_list initializers_type; 72 | typedef hook_list finalizers_type; 73 | 74 | initializers_type initializers; 75 | finalizers_type finalizers; 76 | static module_hooks singleton; 77 | }; 78 | 79 | } } } // namespace boost::php::detail::module_hook 80 | 81 | #endif /* BOOST_PHP_MODULE_HOOKS_HPP */ 82 | -------------------------------------------------------------------------------- /boost/php/detail/value_helpers.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2008 (C) Moriyoshi Koizumi. All rights reserved. 3 | // 4 | // This software is distributed under the Boost Software License, Version 1.0. 5 | // 6 | // Permission is hereby granted, free of charge, to any person or organization 7 | // obtaining a copy of the software and accompanying documentation covered by 8 | // this license (the "Software") to use, reproduce, display, distribute, 9 | // execute, and transmit the Software, and to prepare derivative works of the 10 | // Software, and to permit third-parties to whom the Software is furnished to 11 | // do so, all subject to the following: 12 | // 13 | // The copyright notices in the Software and this entire statement, including 14 | // the above license grant, this restriction and the following disclaimer, 15 | // must be included in all copies of the Software, in whole or in part, and 16 | // all derivative works of the Software, unless such copies or derivative 17 | // works are solely in the form of machine-executable object code generated by 18 | // a source language processor. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 23 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 24 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 25 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | // DEALINGS IN THE SOFTWARE. 27 | 28 | #ifndef BOOST_PHP_DETAIL_VALUE_HELPERS_HPP 29 | #define BOOST_PHP_DETAIL_VALUE_HELPERS_HPP 30 | 31 | #include 32 | #include 33 | 34 | namespace boost { namespace php { namespace detail { 35 | 36 | template 37 | struct _value_dtor_fun { 38 | static void impl(Tval_* p) {} 39 | }; 40 | 41 | template 42 | struct _value_dtor_fun { 43 | static void impl(Tval_* p) { 44 | p->~Tval_(); 45 | } 46 | }; 47 | 48 | template 49 | struct value_dtor_fun 50 | : public _value_dtor_fun::type > { 51 | }; 52 | 53 | template<> 54 | struct value_dtor_fun< ::zval> { 55 | static void impl(::zval* p) { 56 | zval_dtor_wrapper(p); 57 | } 58 | }; 59 | 60 | template<> 61 | struct value_dtor_fun< ::zval*> { 62 | static void impl(::zval** p) { 63 | zval_ptr_dtor_wrapper(p); 64 | } 65 | }; 66 | 67 | template 68 | struct _value_copy_ctor_fun { 69 | static void impl(Tval_* p, const Tval_& that) { 70 | } 71 | }; 72 | 73 | template 74 | struct _value_copy_ctor_fun { 75 | static void impl(Tval_* p, const Tval_& that) { 76 | new(p) Tval_(that); 77 | } 78 | }; 79 | 80 | template 81 | struct value_copy_ctor_fun 82 | : public _value_copy_ctor_fun::type > { 83 | }; 84 | 85 | template<> 86 | struct value_copy_ctor_fun< ::zval> { 87 | static void impl(::zval* p, const ::zval& that) { 88 | zval_copy_ctor(p); 89 | } 90 | }; 91 | 92 | } } } // namespace boost::php::detail 93 | 94 | #endif /* BOOST_PHP_DETAIL_VALUE_HELPERS_HPP */ 95 | -------------------------------------------------------------------------------- /boost/php/detail/stream_support.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2008 (C) Moriyoshi Koizumi. All rights reserved. 3 | // 4 | // This software is distributed under the Boost Software License, Version 1.0. 5 | // 6 | // Permission is hereby granted, free of charge, to any person or organization 7 | // obtaining a copy of the software and accompanying documentation covered by 8 | // this license (the "Software") to use, reproduce, display, distribute, 9 | // execute, and transmit the Software, and to prepare derivative works of the 10 | // Software, and to permit third-parties to whom the Software is furnished to 11 | // do so, all subject to the following: 12 | // 13 | // The copyright notices in the Software and this entire statement, including 14 | // the above license grant, this restriction and the following disclaimer, 15 | // must be included in all copies of the Software, in whole or in part, and 16 | // all derivative works of the Software, unless such copies or derivative 17 | // works are solely in the form of machine-executable object code generated by 18 | // a source language processor. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 23 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 24 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 25 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | // DEALINGS IN THE SOFTWARE. 27 | 28 | #ifndef BOOST_PHP_DETAIL_STREAM_SUPPORT_HPP 29 | #define BOOST_PHP_DETAIL_STREAM_SUPPORT_HPP 30 | 31 | #include 32 | #include 33 | #include 34 | 35 | # if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, < 1300 && __SGI_STL_PORT) 36 | using ::std::basic_ostream; 37 | template basic_ostream& 38 | operator<<(::basic_ostream& os, const ::boost::php::string::& p) 39 | # else 40 | template ::std::basic_ostream& 41 | operator<<(::std::basic_ostream& os, const ::boost::php::string& p) 42 | # endif 43 | { 44 | BOOST_ASSERT(p.data()); 45 | os.write(p.data(), p.size()); 46 | return os; 47 | } 48 | 49 | # if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, < 1300 && __SGI_STL_PORT) 50 | using ::std::basic_ostream; 51 | template basic_ostream& 52 | operator<<(::basic_ostream& os, const ::zval& p) 53 | # else 54 | template ::std::basic_ostream& 55 | operator<<(::std::basic_ostream& os, const ::zval& p) 56 | # endif 57 | { 58 | if (p.type == ::boost::php::value::_STRING) { 59 | os << static_cast( 60 | reinterpret_cast(p)); 61 | } else { 62 | os << static_cast( 63 | ::boost::php::value( 64 | reinterpret_cast(p), 65 | ::boost::php::value::_STRING)); 66 | } 67 | return os; 68 | } 69 | 70 | # if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, < 1300 && __SGI_STL_PORT) 71 | using ::std::basic_ostream; 72 | template basic_ostream& 73 | operator<<(::basic_ostream& os, const ::boost::php::value_ptr& p) 74 | # else 75 | template ::std::basic_ostream& 76 | operator<<(::std::basic_ostream& os, const ::boost::php::value_ptr& p) 77 | # endif 78 | { 79 | os << (*p); 80 | return os; 81 | } 82 | 83 | #endif /* BOOST_PHP_DETAIL_STREAM_SUPPORT_HPP */ 84 | -------------------------------------------------------------------------------- /boost/php/utils.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2008 (C) Moriyoshi Koizumi. All rights reserved. 3 | // 4 | // This software is distributed under the Boost Software License, Version 1.0. 5 | // 6 | // Permission is hereby granted, free of charge, to any person or organization 7 | // obtaining a copy of the software and accompanying documentation covered by 8 | // this license (the "Software") to use, reproduce, display, distribute, 9 | // execute, and transmit the Software, and to prepare derivative works of the 10 | // Software, and to permit third-parties to whom the Software is furnished to 11 | // do so, all subject to the following: 12 | // 13 | // The copyright notices in the Software and this entire statement, including 14 | // the above license grant, this restriction and the following disclaimer, 15 | // must be included in all copies of the Software, in whole or in part, and 16 | // all derivative works of the Software, unless such copies or derivative 17 | // works are solely in the form of machine-executable object code generated by 18 | // a source language processor. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 23 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 24 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 25 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | // DEALINGS IN THE SOFTWARE. 27 | 28 | #ifndef BOOST_PHP_UTILS_HPP 29 | #define BOOST_PHP_UTILS_HPP 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | namespace boost { namespace php { namespace utils { 38 | 39 | static const char* current_filename(); 40 | static ::uint current_line_number(); 41 | static std::string 42 | callable_name_to_string(const ::boost::php::value& callable_zv TSRMLS_DC); 43 | static void 44 | print_error(int type, const char* filename, ::uint lineno, const char* msg); 45 | static void 46 | print_errorf(int type, const char* filename, ::uint lineno, const char* format, 47 | ...); 48 | 49 | } } } // namespace boost::php::utils 50 | 51 | #include 52 | #include "boost/php/exceptions.hpp" 53 | 54 | namespace boost { namespace php { namespace utils { 55 | 56 | static const char* current_filename() 57 | { 58 | TSRMLS_FETCH(); 59 | const char* retval(::zend_get_compiled_filename(TSRMLS_C)); 60 | return retval ? retval: "Unknown"; 61 | } 62 | 63 | static ::uint current_line_number() 64 | { 65 | TSRMLS_FETCH(); 66 | // WTF? 67 | return static_cast< ::uint>(::zend_get_compiled_lineno(TSRMLS_C)); 68 | } 69 | 70 | static std::string 71 | callable_name_to_string(const ::boost::php::value& callable_zv TSRMLS_DC) 72 | { 73 | char* callable_name = 0; 74 | int callable_name_len = 0; 75 | 76 | #if ZEND_MODULE_API_NO < 20071006 77 | if (!zend_is_callable_ex(&const_cast< ::boost::php::value&>(callable_zv), 78 | IS_CALLABLE_CHECK_SYNTAX_ONLY, &callable_name, 79 | &callable_name_len, NULL, NULL, NULL TSRMLS_CC)) { 80 | throw illegal_argument("specified object is not callable"); 81 | } 82 | #else 83 | char *_msg; 84 | if (!zend_is_callable_ex(&const_cast< ::boost::php::value&>(callable_zv), 85 | NULL, IS_CALLABLE_CHECK_SYNTAX_ONLY, &callable_name, 86 | &callable_name_len, NULL, &_msg TSRMLS_CC)) { 87 | std::string msg(_msg); 88 | throw illegal_argument(_msg); 89 | } 90 | #endif /* ZEND_MODULE_API_NO < 20071006 */ 91 | 92 | std::string retval(callable_name, 93 | static_cast< ::std::size_t>(callable_name_len)); 94 | efree(callable_name); 95 | return retval; 96 | } 97 | 98 | static void 99 | print_error(int type, const char* filename, ::uint lineno, const char* msg) 100 | { 101 | print_errorf(type, filename, lineno, "%s", msg); 102 | } 103 | 104 | static void 105 | print_errorf(int type, const char* filename, ::uint lineno, const char* format, 106 | ...) 107 | { 108 | va_list ap; 109 | va_start(ap, format); 110 | zend_error_cb(type, filename, lineno, format, ap); 111 | va_end(ap); 112 | } 113 | 114 | } } } // namespace boost::php::utils 115 | 116 | #endif /* BOOST_PHP_UTILS_HPP */ 117 | -------------------------------------------------------------------------------- /boost/php/string.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2008 (C) Moriyoshi Koizumi. All rights reserved. 3 | // 4 | // This software is distributed under the Boost Software License, Version 1.0. 5 | // 6 | // Permission is hereby granted, free of charge, to any person or organization 7 | // obtaining a copy of the software and accompanying documentation covered by 8 | // this license (the "Software") to use, reproduce, display, distribute, 9 | // execute, and transmit the Software, and to prepare derivative works of the 10 | // Software, and to permit third-parties to whom the Software is furnished to 11 | // do so, all subject to the following: 12 | // 13 | // The copyright notices in the Software and this entire statement, including 14 | // the above license grant, this restriction and the following disclaimer, 15 | // must be included in all copies of the Software, in whole or in part, and 16 | // all derivative works of the Software, unless such copies or derivative 17 | // works are solely in the form of machine-executable object code generated by 18 | // a source language processor. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 23 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 24 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 25 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | // DEALINGS IN THE SOFTWARE. 27 | 28 | #ifndef BOOST_PHP_STRING_HPP 29 | #define BOOST_PHP_STRING_HPP 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | namespace boost { namespace php { 38 | 39 | 40 | class string { 41 | public: 42 | string() { 43 | data_.str.val = 0; 44 | data_.str.len = 0; 45 | } 46 | 47 | string(char* val, ::std::size_t len = static_cast< ::std::size_t>(-1)) { 48 | if (len == static_cast< ::std::size_t>(-1)) { 49 | len = ::strlen(val); 50 | } 51 | BOOST_ASSERT(len <= static_cast< ::std::size_t >(::std::numeric_limits::max())); 52 | data_.str.val = val; 53 | data_.str.len = static_cast(len); 54 | } 55 | 56 | string(const char* val, ::std::size_t len = static_cast< ::std::size_t>(-1)) { 57 | if (len == static_cast< ::std::size_t>(-1)) { 58 | len = ::strlen(val); 59 | } 60 | BOOST_ASSERT(len <= static_cast< ::std::size_t >(::std::numeric_limits::max())); 61 | data_.str.val = ::estrndup(val, len); 62 | data_.str.len = static_cast(len); 63 | } 64 | 65 | string(::zvalue_value& data) 66 | : data_(data) { 67 | } 68 | 69 | string(const ::zvalue_value& data) { 70 | data_.str.val = ::estrndup(data.str.val, data.str.len); 71 | data_.str.len = data.str.len; 72 | } 73 | 74 | string(string& that) { 75 | data_ = that.data_; 76 | } 77 | 78 | string(const string& that) { 79 | data_.str.val = ::estrndup(that.data_.str.val, that.data_.str.len); 80 | data_.str.len = that.data_.str.len; 81 | } 82 | 83 | ::std::size_t size() const { 84 | BOOST_ASSERT(data_.str.len >= 0); 85 | return static_cast(data_.str.len); 86 | } 87 | 88 | char* data() { 89 | return data_.str.val; 90 | } 91 | 92 | const char* data() const { 93 | return data_.str.val; 94 | } 95 | 96 | void release() { 97 | if (data_.str.val) { 98 | ::efree(data_.str.val); 99 | data_.str.val = 0; 100 | data_.str.len = 0; 101 | } 102 | } 103 | 104 | const string& operator=(const string& rhs) { 105 | string tmp(rhs); 106 | swap(*this); 107 | tmp.release(); 108 | return *this; 109 | } 110 | 111 | void swap(string& that) { 112 | zvalue_value tmp = data_; 113 | data_ = that.data_; 114 | that.data_ = tmp; 115 | } 116 | 117 | operator char*() const { 118 | return data_.str.val; 119 | } 120 | 121 | operator const ::std::string() const { 122 | return ::std::string(data_.str.val, data_.str.len); 123 | } 124 | 125 | operator zvalue_value() const { 126 | return data_; 127 | } 128 | private: 129 | ::zvalue_value data_; 130 | }; 131 | 132 | } } // namespace boost::php 133 | 134 | #endif /* BOOST_PHP_STRING_HPP */ 135 | -------------------------------------------------------------------------------- /boost/php/exceptions.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2008 (C) Moriyoshi Koizumi. All rights reserved. 3 | // 4 | // This software is distributed under the Boost Software License, Version 1.0. 5 | // 6 | // Permission is hereby granted, free of charge, to any person or organization 7 | // obtaining a copy of the software and accompanying documentation covered by 8 | // this license (the "Software") to use, reproduce, display, distribute, 9 | // execute, and transmit the Software, and to prepare derivative works of the 10 | // Software, and to permit third-parties to whom the Software is furnished to 11 | // do so, all subject to the following: 12 | // 13 | // The copyright notices in the Software and this entire statement, including 14 | // the above license grant, this restriction and the following disclaimer, 15 | // must be included in all copies of the Software, in whole or in part, and 16 | // all derivative works of the Software, unless such copies or derivative 17 | // works are solely in the form of machine-executable object code generated by 18 | // a source language processor. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 23 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 24 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 25 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | // DEALINGS IN THE SOFTWARE. 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #ifndef BOOST_PHP_RUNTIME_ERROR_DEFINED 34 | #define BOOST_PHP_RUNTIME_ERROR_DEFINED 35 | 36 | namespace boost { namespace php { 37 | class runtime_error: public ::std::runtime_error { 38 | public: 39 | runtime_error(const error_info& err); 40 | 41 | runtime_error(const ::std::string msg, 42 | const char* filename = 0, const ::uint lineno = 0); 43 | 44 | virtual ~runtime_error() throw() {} 45 | 46 | const ::std::string& filename() const { 47 | return filename_; 48 | } 49 | 50 | const ::uint line_number() const { 51 | return line_number_; 52 | } 53 | 54 | protected: 55 | const ::std::string filename_; 56 | const ::uint line_number_; 57 | }; 58 | 59 | } } // namespace boost::php 60 | 61 | #endif /* BOOST_PHP_RUNTIME_ERROR_DEFINED */ 62 | 63 | #ifndef BOOST_PHP_MISC_ERRORS_DEFINED 64 | #define BOOST_PHP_MISC_ERRORS_DEFINED 65 | 66 | namespace boost { namespace php { 67 | 68 | class arithmetic_error: public runtime_error { 69 | public: 70 | arithmetic_error(const error_info& err) 71 | : runtime_error(err) {} 72 | 73 | arithmetic_error(const ::std::string msg, 74 | const char* filename = 0, const ::uint lineno = 0) 75 | : runtime_error(msg, filename, lineno) {} 76 | 77 | virtual ~arithmetic_error() throw() {} 78 | }; 79 | 80 | class type_error: public runtime_error { 81 | public: 82 | type_error(const error_info& err) 83 | : runtime_error(err) {} 84 | 85 | type_error(const ::std::string msg, 86 | const char* filename = 0, const ::uint lineno = 0) 87 | : runtime_error(msg, filename, lineno) {} 88 | 89 | virtual ~type_error() throw() {} 90 | }; 91 | 92 | class not_found: public runtime_error { 93 | public: 94 | not_found(const error_info& err) 95 | : runtime_error(err) {} 96 | 97 | not_found(const ::std::string msg, 98 | const char* filename = 0, const ::uint lineno = 0) 99 | : runtime_error(msg, filename, lineno) {} 100 | 101 | virtual ~not_found() throw() {} 102 | }; 103 | 104 | class illegal_argument: public runtime_error { 105 | public: 106 | illegal_argument(const error_info& err) 107 | : runtime_error(err) {} 108 | 109 | illegal_argument(const ::std::string msg, 110 | const char* filename = 0, const ::uint lineno = 0) 111 | : runtime_error(msg, filename, lineno) {} 112 | 113 | virtual ~illegal_argument() throw() {} 114 | }; 115 | 116 | } } // namespace boost::php 117 | 118 | #endif /* BOOST_PHP_MISC_ERRORS_DEFINED */ 119 | 120 | #include 121 | 122 | #ifndef BOOST_PHP_RUNTIME_ERROR_MEMBERS_DEFINED 123 | #define BOOST_PHP_RUNTIME_ERROR_MEMBERS_DEFINED 124 | 125 | namespace boost { namespace php { 126 | 127 | inline runtime_error::runtime_error(const error_info& err) 128 | : ::std::runtime_error(err.message()), 129 | filename_(err.filename()), line_number_(err.line_number()) {} 130 | 131 | inline runtime_error::runtime_error(const ::std::string msg, 132 | const char* filename, const ::uint lineno) 133 | : ::std::runtime_error(msg), 134 | filename_(filename ? filename: utils::current_filename()), 135 | line_number_(filename ? lineno: 136 | ::boost::php::utils::current_line_number()) {} 137 | 138 | } } // namespace boost::php 139 | 140 | #endif /* BOOST_PHP_RUNTIME_ERROR_MEMBERS_DEFINED */ 141 | -------------------------------------------------------------------------------- /boost/php/detail/function_template.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2008 (C) Moriyoshi Koizumi. All rights reserved. 3 | // 4 | // This software is distributed under the Boost Software License, Version 1.0. 5 | // 6 | // Permission is hereby granted, free of charge, to any person or organization 7 | // obtaining a copy of the software and accompanying documentation covered by 8 | // this license (the "Software") to use, reproduce, display, distribute, 9 | // execute, and transmit the Software, and to prepare derivative works of the 10 | // Software, and to permit third-parties to whom the Software is furnished to 11 | // do so, all subject to the following: 12 | // 13 | // The copyright notices in the Software and this entire statement, including 14 | // the above license grant, this restriction and the following disclaimer, 15 | // must be included in all copies of the Software, in whole or in part, and 16 | // all derivative works of the Software, unless such copies or derivative 17 | // works are solely in the form of machine-executable object code generated by 18 | // a source language processor. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 23 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 24 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 25 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | // DEALINGS IN THE SOFTWARE. 27 | 28 | #ifndef BOOST_PHP_FUNCTION_TEMPLATE_HPP 29 | #define BOOST_PHP_FUNCTION_TEMPLATE_HPP 30 | 31 | #include 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | #include 41 | #include 42 | #include 43 | 44 | namespace boost { namespace php { 45 | 46 | class function { 47 | public: 48 | function(const ::zval& name, value_ptr object) 49 | : name_(name), object_(object), symtable_(0), fun_table_(0) 50 | BOOST_PHP_TSRM_FETCH_IN_CTOR_C {} 51 | 52 | function(const value& name, value_ptr object) 53 | : name_(name), object_(object), symtable_(0), fun_table_(0) 54 | BOOST_PHP_TSRM_FETCH_IN_CTOR_C {} 55 | 56 | function(const ::zval& name, hashtable* symtable = 0, 57 | hashtable< ::zend_function>* fun_table = 0) 58 | : name_(name), object_(), symtable_(symtable), fun_table_(fun_table) 59 | BOOST_PHP_TSRM_FETCH_IN_CTOR_C {} 60 | 61 | function(const value& name, hashtable* symtable = 0, 62 | hashtable< ::zend_function>* fun_table = 0) 63 | : name_(name), object_(), symtable_(symtable), fun_table_(fun_table) 64 | BOOST_PHP_TSRM_FETCH_IN_CTOR_C {} 65 | 66 | #define __BOOST_PHP_FUNCTOR_PARAM_ASSIGN_TPL(__z__, __idx__, __var__) \ 67 | value_ptr BOOST_PP_CAT(_arg, __idx__)( \ 68 | to_value_ptr(BOOST_PP_CAT(arg, __idx__) TSRMLS_CC)); \ 69 | __var__[__idx__] = &BOOST_PP_CAT(_arg, __idx__); 70 | 71 | #define __BOOST_PHP_FUNCTOR_BODY_TPL(__z__, __arity__, __dummy__) \ 72 | { \ 73 | static const ::std::size_t arity = __arity__; \ 74 | value_ptr* params[arity]; \ 75 | ::zval* retval( 0 ); \ 76 | if (object_->is_null() && !fun_table_) { \ 77 | const_cast(this)->fun_table_ = \ 78 | reinterpret_cast< hashtable< ::zend_function>*>( \ 79 | CG(function_table)); \ 80 | } \ 81 | BOOST_PP_REPEAT(__arity__, __BOOST_PHP_FUNCTOR_PARAM_ASSIGN_TPL, params) \ 82 | if (FAILURE == call_user_function_ex(fun_table_, \ 83 | object_->is_null() ? NULL: \ 84 | const_cast< ::zval**>( \ 85 | reinterpret_cast< ::zval* const*>(&*object_)), \ 86 | const_cast(&name_), &retval, arity, \ 87 | reinterpret_cast< ::zval***>(params), 0, \ 88 | symtable_ TSRMLS_CC)) { \ 89 | throw runtime_error( \ 90 | ::std::string("Unable to call ") \ 91 | + utils::callable_name_to_string(name_ TSRMLS_CC) \ 92 | + "()"); \ 93 | } \ 94 | return value_ptr(retval, false); \ 95 | } 96 | 97 | #define __BOOST_PHP_FUNCTOR_TPL(__z__, __arity__, __dummy__) \ 98 | template< \ 99 | BOOST_PP_ENUM_PARAMS_Z(__z__, __arity__, typename Targ) \ 100 | > \ 101 | value_ptr operator()( \ 102 | BOOST_PP_ENUM_BINARY_PARAMS_Z(__z__, __arity__, Targ, arg)) const \ 103 | __BOOST_PHP_FUNCTOR_BODY_TPL(__z__, __arity__, __dummy__) 104 | 105 | BOOST_PP_REPEAT_FROM_TO(1, BOOST_PP_LIMIT_MAG, __BOOST_PHP_FUNCTOR_TPL,) 106 | 107 | value_ptr operator()() const 108 | __BOOST_PHP_FUNCTOR_BODY_TPL(2, 0, ) 109 | 110 | #undef __BOOST_PHP_FUNCTOR_TPL 111 | 112 | private: 113 | value name_; 114 | value_ptr object_; 115 | hashtable* symtable_; 116 | hashtable< ::zend_function>* fun_table_; 117 | BOOST_PHP_TSRM_MEMBER; 118 | }; 119 | 120 | } } // namespace boost::php 121 | 122 | 123 | #endif /* BOOST_PHP_FUNCTION_TEMPLATE_HPP */ 124 | -------------------------------------------------------------------------------- /boost/php/error.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2008 (C) Moriyoshi Koizumi. All rights reserved. 3 | // 4 | // This software is distributed under the Boost Software License, Version 1.0. 5 | // 6 | // Permission is hereby granted, free of charge, to any person or organization 7 | // obtaining a copy of the software and accompanying documentation covered by 8 | // this license (the "Software") to use, reproduce, display, distribute, 9 | // execute, and transmit the Software, and to prepare derivative works of the 10 | // Software, and to permit third-parties to whom the Software is furnished to 11 | // do so, all subject to the following: 12 | // 13 | // The copyright notices in the Software and this entire statement, including 14 | // the above license grant, this restriction and the following disclaimer, 15 | // must be included in all copies of the Software, in whole or in part, and 16 | // all derivative works of the Software, unless such copies or derivative 17 | // works are solely in the form of machine-executable object code generated by 18 | // a source language processor. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 23 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 24 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 25 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | // DEALINGS IN THE SOFTWARE. 27 | 28 | #ifndef BOOST_PHP_ERROR_HPP 29 | #define BOOST_PHP_ERROR_HPP 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include
36 | 37 | namespace boost { namespace php { 38 | class error_info { 39 | public: 40 | error_info(): type_(-1), filename_(), line_number_(0), message_() {} 41 | 42 | error_info(int type, const char* filename, const ::uint lineno, 43 | const ::std::string& message) 44 | : type_(type), filename_(filename), line_number_(lineno), 45 | message_(message) {} 46 | 47 | error_info(int type, const char* filename, const ::uint lineno, 48 | const char* format, va_list ap) 49 | : type_(type), filename_(filename), line_number_(lineno), 50 | message_(format_message(format, ap)) {} 51 | 52 | int type() const { 53 | return type_; 54 | } 55 | 56 | bool valid() const { 57 | return type_ >= 0; 58 | } 59 | 60 | const ::std::string& filename() const { 61 | return filename_; 62 | } 63 | 64 | const ::uint line_number() const { 65 | return line_number_; 66 | } 67 | 68 | const ::std::string& message() const { 69 | return message_; 70 | } 71 | 72 | error_info& operator=(const error_info& rhs) { 73 | type_ = rhs.type_; 74 | filename_ = rhs.filename_; 75 | line_number_ = rhs.line_number_; 76 | message_ = rhs.message_; 77 | return *this; 78 | } 79 | 80 | private: 81 | static const ::std::string format_message(const char* format, va_list ap) { 82 | ::std::string retval; 83 | ::std::string::size_type s; 84 | BOOST_STATIC_ASSERT(sizeof(s) >= sizeof(int)); 85 | char* buf; 86 | retval.append(buf, static_cast< ::std::string::size_type>( 87 | vspprintf(&buf, 0, format, ap))); 88 | efree(buf); 89 | return retval; 90 | } 91 | 92 | protected: 93 | int type_; 94 | ::std::string filename_; 95 | ::uint line_number_; 96 | ::std::string message_; 97 | }; 98 | 99 | namespace detail { 100 | class error_captor; 101 | static error_captor* current_error_captor; 102 | 103 | class error_captor { 104 | private: 105 | typedef void (*handler_type)(int, const char*, const ::uint, 106 | const char*, va_list); 107 | public: 108 | error_captor() 109 | : prev_(current_error_captor), old_handler_(::zend_error_cb) { 110 | 111 | current_error_captor = this; 112 | ::zend_error_cb = &error_captor::capture_handler; 113 | } 114 | 115 | ~error_captor() { 116 | ::zend_error_cb = old_handler_; 117 | current_error_captor = prev_; 118 | } 119 | 120 | const error_info& captured() { 121 | return captured_; 122 | } 123 | 124 | static void capture_handler(int type, const char* filename, 125 | const ::uint lineno, const char* format, va_list ap) 126 | { 127 | current_error_captor->captured_ = error_info( 128 | type, filename, lineno, format, ap); 129 | } 130 | 131 | private: 132 | error_captor* prev_; 133 | ::boost::php::error_info captured_; 134 | handler_type old_handler_; 135 | }; 136 | } // namespace detail 137 | 138 | } } // namespace boost::php 139 | 140 | #define BOOST_PHP_BEGIN_CAPTURE_ERROR \ 141 | { \ 142 | ::boost::php::detail::error_captor __mozo_php_error_cap; 143 | 144 | #define BOOST_PHP_END_CAPTURE_ERROR \ 145 | } 146 | 147 | #define BOOST_PHP_LAST_ERROR __mozo_php_error_cap.captured() 148 | 149 | #undef slprintf 150 | #undef vslprintf 151 | #undef snprintf 152 | #undef vsnprintf 153 | #undef sprintf 154 | 155 | #endif /* BOOST_PHP_ERROR_HPP */ 156 | -------------------------------------------------------------------------------- /boost/php/detail/caller.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2008 (C) Moriyoshi Koizumi. All rights reserved. 3 | // 4 | // This software is distributed under the Boost Software License, Version 1.0. 5 | // 6 | // Permission is hereby granted, free of charge, to any person or organization 7 | // obtaining a copy of the software and accompanying documentation covered by 8 | // this license (the "Software") to use, reproduce, display, distribute, 9 | // execute, and transmit the Software, and to prepare derivative works of the 10 | // Software, and to permit third-parties to whom the Software is furnished to 11 | // do so, all subject to the following: 12 | // 13 | // The copyright notices in the Software and this entire statement, including 14 | // the above license grant, this restriction and the following disclaimer, 15 | // must be included in all copies of the Software, in whole or in part, and 16 | // all derivative works of the Software, unless such copies or derivative 17 | // works are solely in the form of machine-executable object code generated by 18 | // a source language processor. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 23 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 24 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 25 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | // DEALINGS IN THE SOFTWARE. 27 | 28 | #ifndef BOOST_PHP_DETAIL_CALLER_HPP 29 | #define BOOST_PHP_DETAIL_CALLER_HPP 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | #include 41 | 42 | #include 43 | 44 | namespace boost { namespace php { 45 | 46 | class caller_base { 47 | public: 48 | virtual ~caller_base() {} 49 | 50 | virtual void operator()(INTERNAL_FUNCTION_PARAMETERS) { 51 | } 52 | }; 53 | 54 | template< typename Tsig_, typename Tretval_ = typename Tsig_::return_value_type, ::std::size_t Narity_ = Tsig_::arity_value::value > 55 | class caller: public caller_base { 56 | public: 57 | caller(typename Tsig_::function_type) {} 58 | }; 59 | 60 | #define __BOOST_PHP_CALLER_CONV_TPL(__z__, __idx__, __var__) \ 61 | BOOST_PP_COMMA_IF(__idx__) \ 62 | to_native< typename ::boost::mpl::at >::type >(to_value_ptr(*params[__idx__])) 63 | 64 | #define __BOOST_PHP_CALLER_INVOCATION_TPL(__z__, __arity__, __var__) \ 65 | fun_(BOOST_PP_REPEAT_##__z__(__arity__, __BOOST_PHP_CALLER_CONV_TPL, _)) \ 66 | 67 | #define __BOOST_PHP_CALLER_VOID_INVOCATION_TPL(__z__, __arity__, __var__) \ 68 | __BOOST_PHP_CALLER_INVOCATION_TPL(__z__, __arity__, __var__); 69 | 70 | #define __BOOST_PHP_CALLER_NONVOID_INVOCATION_TPL(__z__, __arity__, __var__) \ 71 | new(return_value) value(__BOOST_PHP_CALLER_INVOCATION_TPL(__z__, __arity__, __var__)); 72 | 73 | #define __BOOST_PHP_CALLER_BODY_TPL(__z__, __arity__, __var__, __invoke__) \ 74 | public: \ 75 | caller(typename Tsig_::function_type fun): fun_(fun) {} \ 76 | virtual ~caller() {} \ 77 | virtual void operator()(INTERNAL_FUNCTION_PARAMETERS) { \ 78 | ::std::size_t arity = Tsig_::arity_value::value; \ 79 | ::zend_uint num_params = *((zend_uint*)EG(argument_stack).top_element - 2); \ 80 | if (num_params < arity) { \ 81 | zend_error(E_WARNING, "too few arguments (expected %d, got %d)", arity, num_params); \ 82 | return; \ 83 | } \ 84 | if (num_params > arity) { \ 85 | zend_error(E_WARNING, "too many arguments (expected %d, got %d)", arity, num_params); \ 86 | return; \ 87 | } \ 88 | zval** params = reinterpret_cast( \ 89 | EG(argument_stack).top_element - 2 - num_params ); \ 90 | __invoke__(__z__, __arity__, __var__) \ 91 | } \ 92 | public: \ 93 | typename Tsig_::function_type fun_; \ 94 | 95 | #define __BOOST_PHP_CALLER_TPL(__z__, __arity__, __var__) \ 96 | template \ 97 | class caller: public caller_base { \ 98 | __BOOST_PHP_CALLER_BODY_TPL(__z__, __arity__, __var__, \ 99 | __BOOST_PHP_CALLER_NONVOID_INVOCATION_TPL) \ 100 | }; \ 101 | template \ 102 | class caller: public caller_base { \ 103 | __BOOST_PHP_CALLER_BODY_TPL(__z__, __arity__, __var__, \ 104 | __BOOST_PHP_CALLER_VOID_INVOCATION_TPL) \ 105 | }; 106 | 107 | BOOST_PP_REPEAT_FROM_TO(0, BOOST_MPL_LIMIT_VECTOR_SIZE, __BOOST_PHP_CALLER_TPL, _); 108 | 109 | #undef __BOOST_PHP_CALLER_CONV_TPL 110 | #undef __BOOST_PHP_CALLER_BODY_TPL 111 | #undef __BOOST_PHP_CALLER_TPL 112 | #undef __BOOST_PHP_CALLER_INVOCATION_TPL 113 | #undef __BOOST_PHP_CALLER_NONVOID_INVOCATION_TPL 114 | #undef __BOOST_PHP_CALLER_VOID_INVOCATION_TPL 115 | 116 | template 117 | inline caller_base* create_caller(const Tsig_& sig) 118 | { 119 | return new caller(sig.impl); 120 | } 121 | 122 | } } // namespace boost::php 123 | 124 | #endif /* BOOST_PHP_DETAIL_CALLER_HPP */ 125 | -------------------------------------------------------------------------------- /boost/php/detail/arg_info_factory.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2008 (C) Moriyoshi Koizumi. All rights reserved. 3 | // 4 | // This software is distributed under the Boost Software License, Version 1.0. 5 | // 6 | // Permission is hereby granted, free of charge, to any person or organization 7 | // obtaining a copy of the software and accompanying documentation covered by 8 | // this license (the "Software") to use, reproduce, display, distribute, 9 | // execute, and transmit the Software, and to prepare derivative works of the 10 | // Software, and to permit third-parties to whom the Software is furnished to 11 | // do so, all subject to the following: 12 | // 13 | // The copyright notices in the Software and this entire statement, including 14 | // the above license grant, this restriction and the following disclaimer, 15 | // must be included in all copies of the Software, in whole or in part, and 16 | // all derivative works of the Software, unless such copies or derivative 17 | // works are solely in the form of machine-executable object code generated by 18 | // a source language processor. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 23 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 24 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 25 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | // DEALINGS IN THE SOFTWARE. 27 | 28 | #ifndef BOOST_PHP_DETAIL_ARG_INFO_FACTORY_HPP 29 | #define BOOST_PHP_DETAIL_ARG_INFO_FACTORY_HPP 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #include 43 | 44 | #include 45 | 46 | namespace boost { namespace php { namespace detail { 47 | 48 | template 49 | struct mpl_should_pass_by_ref { 50 | static const bool value = false; 51 | }; 52 | 53 | template 54 | struct mpl_get_class_name_for_type { 55 | static const char* value; 56 | }; 57 | 58 | template 59 | const char* mpl_get_class_name_for_type::value = 0; 60 | 61 | template 62 | struct concrete_arg_info_entry: public ::zend_arg_info { 63 | concrete_arg_info_entry() { 64 | name = 0; 65 | name_len = 0; 66 | typedef mpl_get_class_name_for_type mpl_class_name; 67 | class_name = 0; 68 | class_name_len = 0; 69 | #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 7) 70 | type_hint = 0; 71 | allow_null = 1; 72 | pass_by_reference = mpl_should_pass_by_ref::value; 73 | is_variadic = 0; 74 | #elif (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 4) 75 | type_hint = 0; 76 | pass_by_reference = mpl_should_pass_by_ref::value; 77 | allow_null = 1; 78 | #else 79 | array_type_hint = 0; 80 | allow_null = 1; 81 | pass_by_reference = mpl_should_pass_by_ref::value; 82 | return_reference = 0; 83 | required_num_args = 0; 84 | #endif 85 | } 86 | }; 87 | 88 | template 89 | struct concrete_arg_info_header: public ::zend_arg_info { 90 | concrete_arg_info_header() { 91 | name = 0; 92 | name_len = 0; 93 | class_name = 0; 94 | class_name_len = 0; 95 | #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 7) 96 | type_hint = 0; 97 | allow_null = 0; 98 | pass_by_reference = mpl_should_pass_by_ref< 99 | typename Tsig_::return_value_type >::value; 100 | is_variadic = 0; 101 | #elif (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 4) 102 | type_hint = 0; 103 | pass_by_reference = mpl_should_pass_by_ref< 104 | typename Tsig_::return_value_type >::value; 105 | allow_null = 0; 106 | #else 107 | array_type_hint = 0; 108 | allow_null = 0; 109 | pass_by_reference = 0; 110 | return_reference = mpl_should_pass_by_ref< 111 | typename Tsig_::return_value_type >::value; 112 | required_num_args = 0; 113 | #endif 114 | } 115 | }; 116 | 117 | template< ::std::size_t Narity_> 118 | struct concrete_arg_info_enclosure { 119 | template< typename Tsig_> 120 | struct arg_info {}; 121 | }; 122 | 123 | #define __BOOST_PHP_CONCRETE_ARG_INFO_ENTRY_TEMPLATE(__z__, __idx__, __var__) \ 124 | concrete_arg_info_entry<\ 125 | typename ::boost::mpl::at >::type >\ 127 | BOOST_PP_CAT(a, __idx__); 128 | 129 | #define __BOOST_PHP_CONCRETE_ARG_INFO_TEMPLATE(__z__, __arity__, __var__) \ 130 | template<> \ 131 | template \ 132 | struct concrete_arg_info_enclosure<__arity__>::arg_info { \ 133 | concrete_arg_info_header header; \ 134 | BOOST_PP_REPEAT(__arity__, \ 135 | __BOOST_PHP_CONCRETE_ARG_INFO_ENTRY_TEMPLATE, _) \ 136 | }; 137 | 138 | BOOST_PP_REPEAT_FROM_TO(0, BOOST_MPL_LIMIT_VECTOR_SIZE, __BOOST_PHP_CONCRETE_ARG_INFO_TEMPLATE, _); 139 | 140 | #undef __BOOST_PHP_CONCRETE_ARG_INFO_TEMPLATE 141 | #undef __BOOST_PHP_CONCRETE_ARG_INFO_ENTRY_TEMPLATE 142 | 143 | template 144 | zend_arg_info* create_arg_info(const Tsig_&) 145 | { 146 | return reinterpret_cast( 147 | new typename concrete_arg_info_enclosure::template arg_info()); 148 | } 149 | 150 | } } } // namespace boost::php::detail 151 | 152 | #endif /* BOOST_PHP_DETAIL_ARG_INFO_FACTORY_HPP */ 153 | -------------------------------------------------------------------------------- /boost/php/object.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2008 (C) Moriyoshi Koizumi. All rights reserved. 3 | // 4 | // This software is distributed under the Boost Software License, Version 1.0. 5 | // 6 | // Permission is hereby granted, free of charge, to any person or organization 7 | // obtaining a copy of the software and accompanying documentation covered by 8 | // this license (the "Software") to use, reproduce, display, distribute, 9 | // execute, and transmit the Software, and to prepare derivative works of the 10 | // Software, and to permit third-parties to whom the Software is furnished to 11 | // do so, all subject to the following: 12 | // 13 | // The copyright notices in the Software and this entire statement, including 14 | // the above license grant, this restriction and the following disclaimer, 15 | // must be included in all copies of the Software, in whole or in part, and 16 | // all derivative works of the Software, unless such copies or derivative 17 | // works are solely in the form of machine-executable object code generated by 18 | // a source language processor. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 23 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 24 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 25 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | // DEALINGS IN THE SOFTWARE. 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #ifndef BOOST_PHP_OBJECT_DEFINED 34 | #define BOOST_PHP_OBJECT_DEFINED 35 | namespace boost { namespace php { 36 | 37 | class object: public ::zend_object { 38 | public: 39 | #ifdef ZTS 40 | object(::zend_class_entry const& TSRMLS_DC); 41 | #endif 42 | object(::zend_class_entry const&); 43 | object(object const&); 44 | ~object(); 45 | 46 | static void* operator new(std::size_t sz) { 47 | return emalloc(sz); 48 | } 49 | 50 | static void operator delete(void* p) { 51 | efree(p); 52 | } 53 | }; 54 | } } 55 | #endif /* BOOST_PHP_OBJECT_DEFINED */ 56 | 57 | #ifndef BOOST_PHP_OBJECT_MEMBER_DEFINED 58 | #define BOOST_PHP_OBJECT_MEMBER_DEFINED 59 | namespace boost { namespace php { 60 | #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION == 1 && PHP_RELEASE_VERSION > 2) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION > 5) 61 | #ifdef ZTS 62 | inline object::object(::zend_class_entry const& _ce TSRMLS_DC) 63 | { 64 | ::zend_object_std_init(this, const_cast< ::zend_class_entry*>(&_ce) TSRMLS_CC); 65 | } 66 | #endif 67 | 68 | inline object::object(::zend_class_entry const& _ce) 69 | { 70 | TSRMLS_FETCH(); 71 | ::zend_object_std_init(this, const_cast< ::zend_class_entry*>(&_ce) TSRMLS_CC); 72 | } 73 | 74 | inline object::object(object const& that) 75 | { 76 | TSRMLS_FETCH(); 77 | ::zend_object_std_init(this, const_cast< ::zend_class_entry*>(that.ce) TSRMLS_CC); 78 | // it is ok to pass 0 as zend_object_value and zend_object_handle 79 | // since __clone() is never called. 80 | ::zend_object_value dummy = { 0, NULL }; 81 | ::zend_objects_clone_members(this, dummy, const_cast(&that), 82 | 0 TSRMLS_CC); 83 | } 84 | 85 | inline object::~object() 86 | { 87 | TSRMLS_FETCH(); 88 | ::zend_object_std_dtor(this TSRMLS_CC); 89 | } 90 | #else 91 | inline object::object(::zend_class_entry const& _ce) 92 | { 93 | ALLOC_HASHTABLE(properties); 94 | ::zend_hash_init(properties, 0, NULL, ZVAL_PTR_DTOR, 0); 95 | ce = const_cast< ::zend_class_entry*>(&_ce); 96 | guards = NULL; 97 | } 98 | 99 | inline object::object(object const& that) 100 | { 101 | TSRMLS_FETCH(); 102 | ALLOC_HASHTABLE(properties); 103 | ::zend_hash_init(properties, 0, NULL, ZVAL_PTR_DTOR, 0); 104 | ce = const_cast< ::zend_class_entry*>(that.ce); 105 | guards = NULL; 106 | // it is ok to pass 0 as zend_object_value and zend_object_handle 107 | // since __clone() is never called. 108 | ::zend_object_value dummy = { 0, NULL }; 109 | ::zend_objects_clone_members(*this, &dummy, const_cast< ::zend_object*>(&that), 110 | 0 TSRMLS_CC); 111 | } 112 | 113 | inline object::~object() 114 | { 115 | if (guards) { 116 | ::zend_hash_destroy(guards); 117 | FREE_HASHTABLE(guards); 118 | } 119 | 120 | if (properties) { 121 | ::zend_hash_destroy(properties); 122 | FREE_HASHTABLE(properties); 123 | } 124 | } 125 | #endif /* (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION == 1 && PHP_RELEASE_VERSION > 2) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION > 5) */ 126 | } } // namespace boost::php 127 | #endif /* BOOST_PHP_OBJECT_MEMBER_DEFINED */ 128 | 129 | #ifndef BOOST_PHP_SENSIBLE_OBJECT_DEFINED 130 | #define BOOST_PHP_SENSIBLE_OBJECT_DEFINED 131 | namespace boost { namespace php { 132 | class sensible_object; 133 | } } // namespace boost::php 134 | 135 | void intrusive_ptr_add_ref(::boost::php::sensible_object*); 136 | void intrusive_ptr_del_ref(::boost::php::sensible_object*); 137 | 138 | namespace boost { namespace php { 139 | 140 | class sensible_object: public object 141 | { 142 | friend void ::intrusive_ptr_add_ref(sensible_object*); 143 | friend void ::intrusive_ptr_del_ref(sensible_object*); 144 | public: 145 | #ifdef ZTS 146 | sensible_object(::zend_class_entry const& ce TSRMLS_DC) 147 | : object(ce TSRMLS_CC) {} 148 | #endif 149 | sensible_object(::zend_class_entry const& ce): object(ce) {} 150 | 151 | protected: 152 | #ifdef ZTS 153 | void add_ref(TSRMLS_D) { 154 | ::zend_objects_store_add_ref_by_handle(handle TSRMLS_CC); 155 | } 156 | 157 | void del_ref(TSRMLS_D) { 158 | ::zend_objects_store_del_ref_by_handle(handle TSRMLS_CC); 159 | } 160 | #endif 161 | void add_ref() { 162 | TSRMLS_FETCH(); 163 | ::zend_objects_store_add_ref_by_handle(handle TSRMLS_CC); 164 | } 165 | 166 | void release() { 167 | TSRMLS_FETCH(); 168 | ::zend_objects_store_del_ref_by_handle(handle TSRMLS_CC); 169 | } 170 | 171 | public: 172 | mutable ::zend_object_handle handle; 173 | }; 174 | 175 | } } 176 | 177 | inline void intrusive_ptr_add_ref(::boost::php::sensible_object* p) 178 | { 179 | p->add_ref(); 180 | } 181 | 182 | inline void intrusive_ptr_del_ref(::boost::php::sensible_object* p) 183 | { 184 | p->release(); 185 | } 186 | #endif /* BOOST_PHP_SENSIBLE_OBJECT_DEFINED */ 187 | -------------------------------------------------------------------------------- /boost/php/detail/function_container.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2008 (C) Moriyoshi Koizumi. All rights reserved. 3 | // 4 | // This software is distributed under the Boost Software License, Version 1.0. 5 | // 6 | // Permission is hereby granted, free of charge, to any person or organization 7 | // obtaining a copy of the software and accompanying documentation covered by 8 | // this license (the "Software") to use, reproduce, display, distribute, 9 | // execute, and transmit the Software, and to prepare derivative works of the 10 | // Software, and to permit third-parties to whom the Software is furnished to 11 | // do so, all subject to the following: 12 | // 13 | // The copyright notices in the Software and this entire statement, including 14 | // the above license grant, this restriction and the following disclaimer, 15 | // must be included in all copies of the Software, in whole or in part, and 16 | // all derivative works of the Software, unless such copies or derivative 17 | // works are solely in the form of machine-executable object code generated by 18 | // a source language processor. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 23 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 24 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 25 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | // DEALINGS IN THE SOFTWARE. 27 | 28 | #ifndef BOOST_PHP_DETAIL_FUNCTION_CONTAINER_HPP 29 | #define BOOST_PHP_DETAIL_FUNCTION_CONTAINER_HPP 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #include 37 | 38 | #include 39 | #include 40 | 41 | namespace boost { namespace php { 42 | 43 | struct function_entry: public ::zend_function_entry { 44 | function_entry() { 45 | fname = 0; 46 | handler = 0; 47 | arg_info = 0; 48 | num_args = 0; 49 | flags = 0; 50 | } 51 | 52 | function_entry( 53 | const char* _name, 54 | void (*_handler)(INTERNAL_FUNCTION_PARAMETERS), 55 | ::zend_arg_info* _arg_info_list, 56 | ::zend_uint _num_args, 57 | ::zend_uint _flags) { 58 | fname = const_cast(_name); 59 | handler = _handler; 60 | arg_info = _arg_info_list; 61 | num_args = _num_args; 62 | flags = _flags; 63 | } 64 | 65 | bool is_sentinel() const { 66 | return !fname; 67 | } 68 | }; 69 | 70 | template 71 | class function_container { 72 | public: 73 | typedef ::std::map< ::zend_arg_info*, detail::native_fun_proxy_base*> handler_map_type; 74 | typedef ::std::vector entry_array_type; 75 | 76 | public: 77 | function_container() { 78 | } 79 | 80 | ~function_container() { 81 | for (entry_array_type::iterator i(functions_.begin()); 82 | i != functions_.end(); ++i) { 83 | delete[] i->fname; 84 | } 85 | if (handlers_) { 86 | for (handler_map_type::iterator i(handlers_->begin()); 87 | i != handlers_->end(); ++i) { 88 | delete i->first; 89 | delete i->second; 90 | } 91 | delete handlers_; 92 | handlers_ = 0; 93 | } 94 | } 95 | 96 | template 97 | function_entry& define_function( 98 | ::std::string const& name, Tsig_ const& sig) { 99 | if (!handlers_) { 100 | handlers_ = new handler_map_type(); 101 | handlers_->insert(typename handler_map_type::value_type(0, 0)); 102 | } 103 | ::zend_arg_info* info = detail::create_arg_info(sig); 104 | 105 | ::std::pair r( 106 | handlers_->insert(typename handler_map_type::value_type( 107 | info, 108 | detail::create_native_fun_proxy(sig))) 109 | ); 110 | if (!functions_.empty() && functions_.back().is_sentinel()) 111 | functions_.pop_back(); 112 | functions_.push_back(function_entry( 113 | dup_str(name), 114 | &function_container::__fcall_handler, 115 | info, sig.arity(), sig.is_static() ? ZEND_ACC_STATIC: 0)); 116 | return functions_.back(); 117 | } 118 | 119 | template 120 | function_entry& define_function( 121 | ::std::string const& name, Tfunc_ f, bool) { 122 | return static_cast(this)->define_function(name, detail::get_signature(f)); 123 | } 124 | 125 | template 126 | T_& defun(::std::string const& name, Tfunc_ f) { 127 | define_function(name, f, true); 128 | return *static_cast(this); 129 | } 130 | 131 | operator ::zend_function_entry*() { 132 | append_sentinel(); 133 | return static_cast(&functions_[0]); 134 | }; 135 | 136 | operator ::zend_function_entry const*() const { 137 | append_sentinel(); 138 | return static_cast(&functions_[0]); 139 | }; 140 | 141 | typename entry_array_type::size_type size() const { 142 | return !functions_.empty() && functions_.back().is_sentinel() ? 143 | functions_.size() - 1: functions_.size(); 144 | } 145 | protected: 146 | void append_sentinel() { 147 | if (functions_.empty() || 148 | !functions_.back().is_sentinel()) { 149 | functions_.push_back(function_entry()); 150 | } 151 | } 152 | 153 | private: 154 | static char* dup_str(const ::std::string& val) { 155 | char* retval = new char[val.size() + 1]; 156 | ::std::memcpy(retval, val.data(), val.size()); 157 | retval[val.size()] = 0; 158 | return retval; 159 | } 160 | 161 | static void __fcall_handler(INTERNAL_FUNCTION_PARAMETERS) { 162 | (*(*handlers_)[ 163 | EG(current_execute_data)->function_state.function->common.arg_info - 1])( 164 | INTERNAL_FUNCTION_PARAM_PASSTHRU); 165 | } 166 | 167 | protected: 168 | static handler_map_type* handlers_; 169 | mutable entry_array_type functions_; 170 | }; 171 | 172 | template 173 | typename function_container::handler_map_type* 174 | function_container::handlers_; 175 | 176 | } } // namespace boost::php 177 | 178 | #endif /* BOOST_PHP_DETAIL_FUNCTION_CONTAINER_HPP */ 179 | -------------------------------------------------------------------------------- /boost/php/detail/functional.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2008 (C) Moriyoshi Koizumi. All rights reserved. 3 | // 4 | // This software is distributed under the Boost Software License, Version 1.0. 5 | // 6 | // Permission is hereby granted, free of charge, to any person or organization 7 | // obtaining a copy of the software and accompanying documentation covered by 8 | // this license (the "Software") to use, reproduce, display, distribute, 9 | // execute, and transmit the Software, and to prepare derivative works of the 10 | // Software, and to permit third-parties to whom the Software is furnished to 11 | // do so, all subject to the following: 12 | // 13 | // The copyright notices in the Software and this entire statement, including 14 | // the above license grant, this restriction and the following disclaimer, 15 | // must be included in all copies of the Software, in whole or in part, and 16 | // all derivative works of the Software, unless such copies or derivative 17 | // works are solely in the form of machine-executable object code generated by 18 | // a source language processor. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 23 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 24 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 25 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | // DEALINGS IN THE SOFTWARE. 27 | 28 | // heavily inspired by get_signature() of Boost.Python, which is the 29 | // really excellent work. 30 | 31 | #ifndef BOOST_PHP_DETAIL_FUNCTIONAL_HPP 32 | #define BOOST_PHP_DETAIL_FUNCTIONAL_HPP 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | 47 | namespace boost { namespace php { namespace detail { 48 | 49 | struct constructor_mark {}; 50 | 51 | #define __BOOST_PHP_MPL_VECTOR_N(__arity__) \ 52 | BOOST_PP_CAT(::boost::mpl::vector, __arity__) 53 | 54 | #define __BOOST_PHP_FUNCTIONAL_VECTOR_TPL(__z__, __arity__, __var__) \ 55 | __BOOST_PHP_MPL_VECTOR_N(__arity__)< BOOST_PP_ENUM_PARAMS_Z(__z__, __arity__, __var__) > 56 | 57 | #define __BOOST_PHP_FUNCTIONAL_FUN_TYPE_M(__z__, __arity__, __arg_and_name__) \ 58 | Tretval_(Tobj_::*BOOST_PP_TUPLE_ELEM(2, 1, __arg_and_name__))( \ 59 | BOOST_PP_ENUM_PARAMS_Z(__z__, __arity__, \ 60 | BOOST_PP_TUPLE_ELEM(2, 0, __arg_and_name__))) 61 | 62 | #define __BOOST_PHP_FUNCTIONAL_FUN_TYPE_F(__z__, __arity__, __arg_and_name__) \ 63 | Tretval_(*BOOST_PP_TUPLE_ELEM(2, 1, __arg_and_name__))( \ 64 | BOOST_PP_ENUM_PARAMS_Z(__z__, __arity__, \ 65 | BOOST_PP_TUPLE_ELEM(2, 0, __arg_and_name__))) 66 | 67 | #define __BOOST_PHP_FUNCTIONAL_TPL_M(__z__, __arity__, __var__) \ 68 | template \ 70 | struct unbound_function { \ 72 | typedef Tretval_ result_type; \ 73 | typedef Tobj_ object_type; \ 74 | typedef __BOOST_PHP_FUNCTIONAL_VECTOR_TPL(__z__, __arity__, Targ) \ 75 | arguments; \ 76 | typedef __BOOST_PHP_FUNCTIONAL_FUN_TYPE_M(__z__, __arity__, (Targ, impl_ptr_type)); \ 77 | unbound_function(impl_ptr_type _impl): impl(_impl) {} \ 78 | Tretval_ operator()(Tobj_* obj BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(__z__, __arity__, Targ, arg)) { \ 79 | return (obj->*impl)(BOOST_PP_ENUM_PARAMS_Z(__z__, __arity__, arg)); \ 80 | } \ 81 | impl_ptr_type impl; \ 82 | }; 83 | 84 | #define __BOOST_PHP_FUNCTIONAL_TPL_C(__z__, __arity__, __var__) \ 85 | template \ 87 | struct unbound_function { \ 89 | typedef void result_type; \ 90 | typedef Tobj_ object_type; \ 91 | typedef __BOOST_PHP_FUNCTIONAL_VECTOR_TPL(__z__, __arity__, Targ) \ 92 | arguments; \ 93 | unbound_function() {} \ 94 | void operator()(void* obj BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(__z__, __arity__, Targ, arg)) { \ 95 | new(obj) Tobj_(BOOST_PP_ENUM_PARAMS_Z(__z__, __arity__, arg)); \ 96 | } \ 97 | }; 98 | 99 | #define __BOOST_PHP_FUNCTIONAL_TPL_F(__z__, __arity__, __var__) \ 100 | template \ 102 | struct unbound_function { \ 104 | typedef Tretval_ result_type; \ 105 | typedef void object_type; \ 106 | typedef __BOOST_PHP_FUNCTIONAL_VECTOR_TPL(__z__, __arity__, Targ) \ 107 | arguments; \ 108 | typedef __BOOST_PHP_FUNCTIONAL_FUN_TYPE_F(__z__, __arity__, (Targ, impl_ptr_type)); \ 109 | unbound_function(impl_ptr_type _impl): impl(_impl) {} \ 110 | Tretval_ operator()(void* BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(__z__, __arity__, Targ, arg)) { \ 111 | return impl(BOOST_PP_ENUM_PARAMS_Z(__z__, __arity__, arg)); \ 112 | } \ 113 | impl_ptr_type impl; \ 114 | }; 115 | 116 | #define __BOOST_PHP_FUNCTIONAL_TPL(__z__, __arity__, __var__) \ 117 | __BOOST_PHP_FUNCTIONAL_TPL_M(__z__, __arity__, __var__) \ 118 | __BOOST_PHP_FUNCTIONAL_TPL_C(__z__, __arity__, __var__) \ 119 | __BOOST_PHP_FUNCTIONAL_TPL_F(__z__, __arity__, __var__) 120 | 121 | template 122 | struct unbound_function {}; 123 | 124 | BOOST_PP_REPEAT_FROM_TO(0, BOOST_MPL_LIMIT_VECTOR_SIZE, __BOOST_PHP_FUNCTIONAL_TPL, _); 125 | 126 | #undef __BOOST_PHP_MPL_VECTOR_N 127 | #undef __BOOST_PHP_FUNCTIONAL_VECTOR_TPL 128 | #undef __BOOST_PHP_FUNCTIONAL_FUN_TYPE_F 129 | #undef __BOOST_PHP_FUNCTIONAL_FUN_TYPE_M 130 | #undef __BOOST_PHP_FUNCTIONAL_TPL_M 131 | #undef __BOOST_PHP_FUNCTIONAL_TPL_C 132 | #undef __BOOST_PHP_FUNCTIONAL_TPL_F 133 | #undef __BOOST_PHP_FUNCTIONAL_TPL 134 | 135 | } } } // namespace boost::php::detail 136 | 137 | #endif /* BOOST_PHP_DETAIL_FUNCTIONAL_HPP */ 138 | -------------------------------------------------------------------------------- /boost/php/module.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2008 (C) Moriyoshi Koizumi. All rights reserved. 3 | // 4 | // This software is distributed under the Boost Software License, Version 1.0. 5 | // 6 | // Permission is hereby granted, free of charge, to any person or organization 7 | // obtaining a copy of the software and accompanying documentation covered by 8 | // this license (the "Software") to use, reproduce, display, distribute, 9 | // execute, and transmit the Software, and to prepare derivative works of the 10 | // Software, and to permit third-parties to whom the Software is furnished to 11 | // do so, all subject to the following: 12 | // 13 | // The copyright notices in the Software and this entire statement, including 14 | // the above license grant, this restriction and the following disclaimer, 15 | // must be included in all copies of the Software, in whole or in part, and 16 | // all derivative works of the Software, unless such copies or derivative 17 | // works are solely in the form of machine-executable object code generated by 18 | // a source language processor. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 23 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 24 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 25 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | // DEALINGS IN THE SOFTWARE. 27 | 28 | #ifndef BOOST_PHP_MODULE_HPP 29 | #define BOOST_PHP_MODULE_HPP 30 | 31 | #include 32 | #include 33 | #include 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | #include 41 | #include 42 | 43 | namespace boost { namespace php { 44 | 45 | namespace detail { 46 | class module_dependency_base { 47 | public: 48 | module_dependency_base(const char* _name, int _type) 49 | : next_(0) { 50 | wrapped_.name = const_cast(_name); 51 | wrapped_.rel = NULL; 52 | wrapped_.version = 0; 53 | wrapped_.type = _type; 54 | } 55 | 56 | ~module_dependency_base() { 57 | if (next_) { 58 | delete next_; 59 | } 60 | } 61 | 62 | module_dependency_base& operator<(const char* version) { 63 | wrapped_.rel = const_cast("lt"); 64 | wrapped_.version = const_cast(version); 65 | return *this; 66 | } 67 | 68 | module_dependency_base& operator<=(const char* version) { 69 | wrapped_.rel = const_cast("le"); 70 | wrapped_.version = const_cast(version); 71 | return *this; 72 | } 73 | 74 | module_dependency_base& operator==(const char* version) { 75 | wrapped_.rel = const_cast("eq"); 76 | wrapped_.version = const_cast(version); 77 | return *this; 78 | } 79 | 80 | module_dependency_base& operator>=(const char* version) { 81 | wrapped_.rel = const_cast("ge"); 82 | wrapped_.version = const_cast(version); 83 | return *this; 84 | } 85 | 86 | module_dependency_base& operator>(const char* version) { 87 | wrapped_.rel = const_cast("gt"); 88 | wrapped_.version = const_cast(version); 89 | return *this; 90 | } 91 | 92 | module_dependency_base& operator &&(const module_dependency_base& rhs) { 93 | module_dependency_base* last = this; 94 | while (last->next_) { 95 | last = last->next_; 96 | } 97 | last->next_ = new module_dependency_base(rhs); 98 | return *this; 99 | } 100 | 101 | operator const ::zend_module_dep&() const { 102 | return wrapped_; 103 | } 104 | 105 | operator ::zend_module_dep&() { 106 | return wrapped_; 107 | } 108 | 109 | operator ::zend_module_dep*() { 110 | return realize(); 111 | } 112 | 113 | protected: 114 | ::std::size_t count() { 115 | ::std::size_t retval = 0; 116 | for (module_dependency_base* current = this; current; 117 | current = current->next_) { 118 | ++retval; 119 | } 120 | return retval; 121 | } 122 | 123 | ::zend_module_dep* realize() { 124 | ::std::size_t n = count(); 125 | zend_module_dep* realized = new zend_module_dep[n + 1]; 126 | module_dependency_base* current = this; 127 | for (::std::size_t i = 0; i < n; ++i, current = current->next_) { 128 | realized[i] = current->wrapped_; 129 | } 130 | realized[n].name = NULL; 131 | return realized; 132 | } 133 | 134 | private: 135 | ::zend_module_dep wrapped_; 136 | module_dependency_base* next_; 137 | ::zend_module_dep* realized_; 138 | }; 139 | 140 | template 141 | struct module_dependency 142 | : public module_dependency_base { 143 | module_dependency(const char* name) 144 | : module_dependency_base(name, _type) {} 145 | }; 146 | 147 | static void cleanup_zend_module_entry(zend_module_entry* entry) 148 | { 149 | delete[] entry->ini_entry; 150 | delete[] entry->deps; 151 | } 152 | 153 | template 154 | struct module_class_of { 155 | typedef void type; 156 | }; 157 | } // namespace detail 158 | 159 | class module { 160 | public: 161 | typedef detail::module_dependency requires; 162 | typedef detail::module_dependency conflicts; 163 | typedef detail::module_dependency recommends; 164 | 165 | class handler { 166 | public: 167 | handler(module* mod) throw() 168 | : module_(mod) {} 169 | 170 | ~handler() throw() {} 171 | 172 | void __initialize(TSRMLS_D) {} 173 | 174 | void __finalize(TSRMLS_D) {} 175 | 176 | void __activate(TSRMLS_D) {} 177 | 178 | void __deactivate(TSRMLS_D) {} 179 | 180 | void __post_deactivate(TSRMLS_D) {} 181 | 182 | void __display_info(TSRMLS_D) {} 183 | protected: 184 | module const* const module_; 185 | }; 186 | 187 | protected: 188 | zend_module_entry* entry_; 189 | 190 | public: 191 | module(zend_module_entry* entry): entry_(entry) {} 192 | 193 | ~module() { 194 | detail::cleanup_zend_module_entry(entry_); 195 | } 196 | }; 197 | 198 | } } // namespace boost::php 199 | 200 | #endif /* BOOST_PHP_MODULE_HPP */ 201 | -------------------------------------------------------------------------------- /boost/php/detail/signature.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2008 (C) Moriyoshi Koizumi. All rights reserved. 3 | // 4 | // This software is distributed under the Boost Software License, Version 1.0. 5 | // 6 | // Permission is hereby granted, free of charge, to any person or organization 7 | // obtaining a copy of the software and accompanying documentation covered by 8 | // this license (the "Software") to use, reproduce, display, distribute, 9 | // execute, and transmit the Software, and to prepare derivative works of the 10 | // Software, and to permit third-parties to whom the Software is furnished to 11 | // do so, all subject to the following: 12 | // 13 | // The copyright notices in the Software and this entire statement, including 14 | // the above license grant, this restriction and the following disclaimer, 15 | // must be included in all copies of the Software, in whole or in part, and 16 | // all derivative works of the Software, unless such copies or derivative 17 | // works are solely in the form of machine-executable object code generated by 18 | // a source language processor. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 23 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 24 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 25 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | // DEALINGS IN THE SOFTWARE. 27 | 28 | // heavily inspired by get_signature() of Boost.Python, which is the 29 | // really excellent work. 30 | 31 | #ifndef BOOST_PHP_DETAIL_SIGNATURE_HPP 32 | #define BOOST_PHP_DETAIL_SIGNATURE_HPP 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | 47 | namespace boost { namespace php { namespace detail { 48 | 49 | template 50 | struct signature { 51 | typedef typename Tfun_::arguments arguments; 52 | typedef typename Tfun_::result_type return_value_type; 53 | typedef typename Tfun_::object_type object_type; 54 | typedef Tfun_ function_type; 55 | typedef typename ::boost::mpl::size arity_value; 56 | 57 | signature(function_type _impl): impl(_impl) {} 58 | 59 | static inline ::size_t arity() { 60 | return arity_value::value; 61 | } 62 | 63 | static inline bool is_static() { 64 | return ::boost::is_same::value; 65 | } 66 | 67 | function_type impl; 68 | }; 69 | 70 | #define __BOOST_PHP_MPL_VECTOR_N(__arity__) \ 71 | BOOST_PP_CAT(::boost::mpl::vector, __arity__) 72 | 73 | #define __BOOST_PHP_SIGNATURE_VECTOR_TPL(__z__, __arity__, __var__) \ 74 | __BOOST_PHP_MPL_VECTOR_N(__arity__)< BOOST_PP_ENUM_PARAMS_Z(__z__, __arity__, __var__) > 75 | 76 | #define __BOOST_PHP_SIGNATURE_FUN_TYPE_M(__z__, __arity__, __arg_and_name__) \ 77 | Tretval_(Tobj_::*BOOST_PP_TUPLE_ELEM(2, 1, __arg_and_name__))( \ 78 | BOOST_PP_ENUM_PARAMS_Z(__z__, __arity__, \ 79 | BOOST_PP_TUPLE_ELEM(2, 0, __arg_and_name__))) 80 | 81 | #define __BOOST_PHP_SIGNATURE_FUN_TYPE_CM(__z__, __arity__, __arg_and_name__) \ 82 | Tretval_(Tobj_::*BOOST_PP_TUPLE_ELEM(2, 1, __arg_and_name__))( \ 83 | BOOST_PP_ENUM_PARAMS_Z(__z__, __arity__, \ 84 | BOOST_PP_TUPLE_ELEM(2, 0, __arg_and_name__))) const 85 | 86 | #define __BOOST_PHP_SIGNATURE_FUN_TYPE_F(__z__, __arity__, __arg_and_name__) \ 87 | Tretval_(*BOOST_PP_TUPLE_ELEM(2, 1, __arg_and_name__))( \ 88 | BOOST_PP_ENUM_PARAMS_Z(__z__, __arity__, \ 89 | BOOST_PP_TUPLE_ELEM(2, 0, __arg_and_name__))) 90 | 91 | #define __BOOST_PHP_SIGNATURE_TYPE_M(__z__, __arity__, __retval_obj_and_args__) \ 92 | signature< unbound_function< \ 93 | BOOST_PP_TUPLE_ELEM(3, 0, __retval_obj_and_args__), \ 94 | BOOST_PP_TUPLE_ELEM(3, 1, __retval_obj_and_args__), \ 95 | __BOOST_PHP_SIGNATURE_VECTOR_TPL(__z__, __arity__, \ 96 | BOOST_PP_TUPLE_ELEM(3, 2, __retval_obj_and_args__))> > 97 | 98 | #define __BOOST_PHP_SIGNATURE_TYPE_CM(__z__, __arity__, __retval_obj_and_args__) \ 99 | signature< unbound_function< \ 100 | BOOST_PP_TUPLE_ELEM(3, 0, __retval_obj_and_args__), \ 101 | const BOOST_PP_TUPLE_ELEM(3, 1, __retval_obj_and_args__), \ 102 | __BOOST_PHP_SIGNATURE_VECTOR_TPL(__z__, __arity__, \ 103 | BOOST_PP_TUPLE_ELEM(3, 2, __retval_obj_and_args__))> > 104 | 105 | #define __BOOST_PHP_SIGNATURE_TYPE_F(__z__, __arity__, __retval_and_args__) \ 106 | signature< \ 107 | unbound_function< \ 108 | BOOST_PP_TUPLE_ELEM(2, 0, __retval_and_args__ ), void, \ 109 | __BOOST_PHP_SIGNATURE_VECTOR_TPL(__z__, __arity__, \ 110 | BOOST_PP_TUPLE_ELEM(2, 1, __retval_and_args__))> > 111 | 112 | #define __BOOST_PHP_SIGNATURE_TPL_M(__z__, __arity__, __var__) \ 113 | template< \ 114 | typename Tretval_, \ 115 | typename Tobj_ \ 116 | BOOST_PP_ENUM_TRAILING_PARAMS_Z(__z__, __arity__, typename Targ) \ 117 | > \ 118 | __BOOST_PHP_SIGNATURE_TYPE_M(__z__,__arity__, (Tretval_, Tobj_, Targ)) \ 119 | get_signature(__BOOST_PHP_SIGNATURE_FUN_TYPE_M(__z__, __arity__, (Targ, fun))) \ 120 | { \ 121 | return __BOOST_PHP_SIGNATURE_TYPE_M(__z__, __arity__, (Tretval_, Tobj_, Targ))(fun); \ 122 | } 123 | 124 | #define __BOOST_PHP_SIGNATURE_TPL_CM(__z__, __arity__, __var__) \ 125 | template< \ 126 | typename Tretval_, \ 127 | typename Tobj_ \ 128 | BOOST_PP_ENUM_TRAILING_PARAMS_Z(__z__, __arity__, typename Targ) \ 129 | > \ 130 | __BOOST_PHP_SIGNATURE_TYPE_CM(__z__,__arity__, (Tretval_, Tobj_, Targ)) \ 131 | get_signature(__BOOST_PHP_SIGNATURE_FUN_TYPE_CM(__z__, __arity__, (Targ, fun))) \ 132 | { \ 133 | return __BOOST_PHP_SIGNATURE_TYPE_CM(__z__, __arity__, (Tretval_, Tobj_, Targ))(fun); \ 134 | } 135 | 136 | #define __BOOST_PHP_SIGNATURE_TPL_F(__z__, __arity__, __var__) \ 137 | template< \ 138 | typename Tretval_ \ 139 | BOOST_PP_ENUM_TRAILING_PARAMS_Z(__z__, __arity__, typename Targ) \ 140 | > \ 141 | __BOOST_PHP_SIGNATURE_TYPE_F(__z__,__arity__, (Tretval_, Targ)) \ 142 | get_signature(__BOOST_PHP_SIGNATURE_FUN_TYPE_F(__z__, __arity__, (Targ, fun))) \ 143 | { \ 144 | return __BOOST_PHP_SIGNATURE_TYPE_F(__z__, __arity__, (Tretval_, Targ))(fun); \ 145 | } 146 | 147 | #define __BOOST_PHP_SIGNATURE_TPL(__z__, __arity__, __var__) \ 148 | __BOOST_PHP_SIGNATURE_TPL_M(__z__, __arity__, __var__) \ 149 | __BOOST_PHP_SIGNATURE_TPL_CM(__z__, __arity__, __var__) \ 150 | __BOOST_PHP_SIGNATURE_TPL_F(__z__, __arity__, __var__) 151 | 152 | BOOST_PP_REPEAT_FROM_TO(0, BOOST_MPL_LIMIT_VECTOR_SIZE, __BOOST_PHP_SIGNATURE_TPL, _); 153 | 154 | #undef __BOOST_PHP_MPL_VECTOR_N 155 | #undef __BOOST_PHP_SIGNATURE_VECTOR_TPL 156 | #undef __BOOST_PHP_SIGNATURE_FUN_TYPE_M 157 | #undef __BOOST_PHP_SIGNATURE_FUN_TYPE_CM 158 | #undef __BOOST_PHP_SIGNATURE_FUN_TYPE_F 159 | #undef __BOOST_PHP_SIGNATURE_TYPE_M 160 | #undef __BOOST_PHP_SIGNATURE_TYPE_F 161 | #undef __BOOST_PHP_SIGNATURE_TPL_M 162 | #undef __BOOST_PHP_SIGNATURE_TPL_CM 163 | #undef __BOOST_PHP_SIGNATURE_TPL_F 164 | #undef __BOOST_PHP_SIGNATURE_TPL 165 | 166 | } } } // namespace boost::php::detail 167 | 168 | #endif /* BOOST_PHP_DETAIL_SIGNATURE_HPP */ 169 | -------------------------------------------------------------------------------- /boost/php/converter.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2008 (C) Moriyoshi Koizumi. All rights reserved. 3 | // 4 | // This software is distributed under the Boost Software License, Version 1.0. 5 | // 6 | // Permission is hereby granted, free of charge, to any person or organization 7 | // obtaining a copy of the software and accompanying documentation covered by 8 | // this license (the "Software") to use, reproduce, display, distribute, 9 | // execute, and transmit the Software, and to prepare derivative works of the 10 | // Software, and to permit third-parties to whom the Software is furnished to 11 | // do so, all subject to the following: 12 | // 13 | // The copyright notices in the Software and this entire statement, including 14 | // the above license grant, this restriction and the following disclaimer, 15 | // must be included in all copies of the Software, in whole or in part, and 16 | // all derivative works of the Software, unless such copies or derivative 17 | // works are solely in the form of machine-executable object code generated by 18 | // a source language processor. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 23 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 24 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 25 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | // DEALINGS IN THE SOFTWARE. 27 | 28 | #include 29 | 30 | #ifndef BOOST_PHP_VALUE_PTR_DEFINED 31 | #include 32 | #endif /* BOOST_PHP_VALUE_PTR_DEFINED */ 33 | 34 | #ifndef BOOST_PHP_TO_NATIVE_CONVERTER_DEFINED 35 | #define BOOST_PHP_TO_NATIVE_CONVERTER_DEFINED 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | 47 | namespace boost { namespace php { 48 | 49 | namespace detail { 50 | template 51 | struct is_first_class { 52 | public: 53 | typedef typename remove_pointer< 54 | typename remove_cv::type>::type 55 | >::type type; 56 | enum { 57 | value = boost::mpl::or_< 58 | boost::is_POD, 59 | boost::mpl::or_< 60 | boost::is_same, 61 | boost::mpl::or_< 62 | boost::is_same, 63 | boost::mpl::or_< 64 | boost::is_same, 65 | boost::is_same 66 | > 67 | > 68 | > 69 | >::value 70 | }; 71 | }; 72 | } 73 | 74 | template::value> 75 | struct to_native_converter; 76 | 77 | template<> 78 | struct to_native_converter { 79 | long operator()(value_ptr const& val TSRMLS_DC) const{ 80 | return static_cast(*val.as()); 81 | } 82 | }; 83 | 84 | template<> 85 | struct to_native_converter { 86 | int operator()(value_ptr const& val TSRMLS_DC) const { 87 | return static_cast(*val.as()); 88 | } 89 | }; 90 | 91 | template<> 92 | struct to_native_converter { 93 | double const& operator()(value_ptr const& val TSRMLS_DC) const { 94 | return static_cast(*val.as()); 95 | } 96 | }; 97 | 98 | template<> 99 | struct to_native_converter< string, true> { 100 | string const& operator()(value_ptr const& val TSRMLS_DC) const { 101 | return static_cast(*val.as()); 102 | } 103 | 104 | string& operator()(value_ptr& val TSRMLS_DC) const { 105 | return static_cast(*val.as()); 106 | } 107 | }; 108 | 109 | template<> 110 | struct to_native_converter< ::std::string, true> { 111 | ::std::string operator()(value_ptr const& val TSRMLS_DC) const { 112 | return static_cast(*val.as()); 113 | } 114 | }; 115 | 116 | template<> 117 | struct to_native_converter { 118 | const array& operator()(value_ptr const& val TSRMLS_DC) const { 119 | return static_cast(*val.as()); 120 | } 121 | 122 | array& operator()(value_ptr& val TSRMLS_DC) const { 123 | return static_cast(*val.as()); 124 | } 125 | }; 126 | 127 | template<> 128 | struct to_native_converter { 129 | resource_handle operator()(value_ptr const& val TSRMLS_DC) const { 130 | return *val.as(); 131 | }; 132 | }; 133 | 134 | } } // namespace boost::php 135 | #endif /* BOOST_PHP_TO_NATIVE_CONVERTER_DEFINED */ 136 | 137 | #ifndef BOOST_PHP_TO_VALUE_PTR_CONVERTER_DEFINED 138 | #define BOOST_PHP_TO_VALUE_PTR_CONVERTER_DEFINED 139 | namespace boost { namespace php { 140 | 141 | template::value> 142 | struct to_value_ptr_converter; 143 | 144 | template 145 | struct to_value_ptr_converter { 146 | value_ptr operator()(Tnative_ const& val TSRMLS_DC) const { 147 | return value_ptr(new value(val), false); 148 | } 149 | }; 150 | 151 | template<> 152 | struct to_value_ptr_converter< ::zval*> { 153 | value_ptr operator()(::zval* that TSRMLS_DC) const { 154 | return *reinterpret_cast(&that); 155 | } 156 | }; 157 | 158 | template<> 159 | struct to_value_ptr_converter< ::zval const*> { 160 | value_ptr operator()(::zval const* that TSRMLS_DC) const { 161 | return *reinterpret_cast(&that); 162 | } 163 | }; 164 | 165 | template<> 166 | struct to_value_ptr_converter { 167 | value_ptr operator()(value_ptr that TSRMLS_DC) const { 168 | return value_ptr(that); 169 | } 170 | }; 171 | 172 | template<> 173 | struct to_value_ptr_converter { 174 | value_ptr operator()(value_ptr that TSRMLS_DC) const { 175 | return value_ptr(that); 176 | } 177 | }; 178 | 179 | template<> 180 | struct to_value_ptr_converter { 181 | value_ptr operator()(value_ptr const& that TSRMLS_DC) const { 182 | return value_ptr(that); 183 | } 184 | }; 185 | 186 | } } // namespace boost::php 187 | #endif /* BOOST_PHP_TO_VALUE_PTR_CONVERTER_DEFINED */ 188 | 189 | #ifndef BOOST_PHP_VALUE_PTR_UTILS_DEFINED 190 | #define BOOST_PHP_VALUE_PTR_UTILS_DEFINED 191 | namespace boost { namespace php { 192 | 193 | template 194 | inline value_ptr to_value_ptr(Tsrc_ const& val TSRMLS_DC) 195 | { 196 | static to_value_ptr_converter converter; 197 | return converter(val TSRMLS_CC); 198 | } 199 | 200 | template 201 | inline value_ptr to_value_ptr(Tsrc_& val TSRMLS_DC, typename boost::disable_if >::type* = 0) 202 | { 203 | static to_value_ptr_converter converter; 204 | return converter(val TSRMLS_CC); 205 | } 206 | 207 | template 208 | inline T_ to_native(value_ptr const& val TSRMLS_DC) 209 | { 210 | static to_native_converter::type>::type> converter; 211 | return converter(val TSRMLS_CC); 212 | } 213 | 214 | template 215 | inline T_& to_native(value_ptr& val TSRMLS_DC) 216 | { 217 | static to_native_converter::type>::type> converter; 218 | return converter(val TSRMLS_CC); 219 | } 220 | } } // namespace boost::php 221 | 222 | #endif /* BOOST_PHP_VALUE_PTR_UTILS_DEFINED */ 223 | -------------------------------------------------------------------------------- /boost/php/detail/native_fun_proxy.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2008 (C) Moriyoshi Koizumi. All rights reserved. 3 | // 4 | // This software is distributed under the Boost Software License, Version 1.0. 5 | // 6 | // Permission is hereby granted, free of charge, to any person or organization 7 | // obtaining a copy of the software and accompanying documentation covered by 8 | // this license (the "Software") to use, reproduce, display, distribute, 9 | // execute, and transmit the Software, and to prepare derivative works of the 10 | // Software, and to permit third-parties to whom the Software is furnished to 11 | // do so, all subject to the following: 12 | // 13 | // The copyright notices in the Software and this entire statement, including 14 | // the above license grant, this restriction and the following disclaimer, 15 | // must be included in all copies of the Software, in whole or in part, and 16 | // all derivative works of the Software, unless such copies or derivative 17 | // works are solely in the form of machine-executable object code generated by 18 | // a source language processor. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 23 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 24 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 25 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | // DEALINGS IN THE SOFTWARE. 27 | 28 | #ifndef BOOST_PHP_DETAIL_NATIVE_FUN_PROXY_HPP 29 | #define BOOST_PHP_DETAIL_NATIVE_FUN_PROXY_HPP 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | #include 42 | #include 43 | 44 | #include 45 | #include 46 | 47 | namespace boost { namespace php { namespace detail { 48 | 49 | class native_fun_proxy_base { 50 | public: 51 | virtual ~native_fun_proxy_base() {} 52 | 53 | virtual void operator()(INTERNAL_FUNCTION_PARAMETERS) { 54 | } 55 | }; 56 | 57 | template 58 | class native_fun_proxy: public native_fun_proxy_base { 59 | public: 60 | native_fun_proxy(typename Tsig_::function_type, const Toretr_&) {} 61 | }; 62 | 63 | #define __BOOST_PHP_NATIVE_FUN_PROXY_CONV_TPL(__z__, __idx__, __var__) \ 64 | , to_native< typename ::boost::mpl::at >::type >(value_ptr(params[__idx__]) TSRMLS_CC) 65 | 66 | #define __BOOST_PHP_NATIVE_FUN_PROXY_INVOCATION_TPL(__z__, __arity__, __obj__) \ 67 | fun_(__obj__ BOOST_PP_REPEAT_##__z__(__arity__, __BOOST_PHP_NATIVE_FUN_PROXY_CONV_TPL, _)) \ 68 | 69 | #define __BOOST_PHP_NATIVE_FUN_PROXY_VOID_INVOCATION_TPL(__z__, __arity__, __obj__) \ 70 | __BOOST_PHP_NATIVE_FUN_PROXY_INVOCATION_TPL(__z__, __arity__, __obj__) 71 | 72 | #define __BOOST_PHP_NATIVE_FUN_PROXY_NONVOID_INVOCATION_TPL(__z__, __arity__, __obj__) \ 73 | reinterpret_cast(return_value)->swap(*to_value_ptr(__BOOST_PHP_NATIVE_FUN_PROXY_INVOCATION_TPL(__z__, __arity__, __obj__) TSRMLS_CC)); 74 | 75 | #if ZEND_MODULE_API_NO < 20071006 76 | #define __BOOST_PHP_NATIVE_FUN_PROXY_BODY_TPL(__z__, __arity__, __var__, __invoke__) \ 77 | public: \ 78 | native_fun_proxy(typename Tsig_::function_type const& fun, \ 79 | const Toretr_& oretr) \ 80 | : fun_(fun), oretr_(oretr) {} \ 81 | virtual ~native_fun_proxy() {} \ 82 | virtual void operator()(INTERNAL_FUNCTION_PARAMETERS) { \ 83 | typename Tsig_::object_type* obj = oretr_( \ 84 | INTERNAL_FUNCTION_PARAM_PASSTHRU); \ 85 | ::std::size_t arity = Tsig_::arity_value::value; \ 86 | ::zend_uintptr_t num_params = *((zend_uintptr_t*)EG(argument_stack).top_element - 2); \ 87 | if (num_params < arity) { \ 88 | zend_error(E_WARNING, "too few arguments (expected %u, got %lu)", static_cast< ::zend_uint>(arity), num_params); \ 89 | return; \ 90 | } \ 91 | if (num_params > arity) { \ 92 | zend_error(E_WARNING, "too many arguments (expected %u, got %lu)", static_cast< ::zend_uint>(arity), num_params); \ 93 | return; \ 94 | } \ 95 | zval** params = reinterpret_cast( \ 96 | EG(argument_stack).top_element - 2 - num_params ); \ 97 | try { \ 98 | __invoke__(__z__, __arity__, obj); \ 99 | } catch (const ::boost::php::runtime_error& e) { \ 100 | ::boost::php::utils::print_error(E_WARNING, \ 101 | e.filename().c_str(), e.line_number(), e.what()); \ 102 | } catch (const ::std::exception& e) { \ 103 | zend_error(E_WARNING, "%s", e.what()); \ 104 | } \ 105 | } \ 106 | public: \ 107 | typename Tsig_::function_type fun_; \ 108 | const Toretr_& oretr_; 109 | #else 110 | #define __BOOST_PHP_NATIVE_FUN_PROXY_BODY_TPL(__z__, __arity__, __var__, __invoke__) \ 111 | public: \ 112 | native_fun_proxy(typename Tsig_::function_type fun, \ 113 | const Toretr_& oretr) \ 114 | : fun_(fun), oretr_(oretr) {} \ 115 | virtual ~native_fun_proxy() {} \ 116 | virtual void operator()(INTERNAL_FUNCTION_PARAMETERS) { \ 117 | typename Tsig_::object_type* obj = oretr_( \ 118 | INTERNAL_FUNCTION_PARAM_PASSTHRU); \ 119 | ::std::size_t arity = Tsig_::arity_value::value; \ 120 | ::zend_uintptr_t num_params = *((zend_uintptr_t*)zend_vm_stack_top(TSRMLS_C) - 1); \ 121 | if (num_params < arity) { \ 122 | zend_error(E_WARNING, "too few arguments (expected %u, got %lu)", static_cast< ::zend_uint>(arity), num_params); \ 123 | return; \ 124 | } \ 125 | if (num_params > arity) { \ 126 | zend_error(E_WARNING, "too many arguments (expected %u, got %lu)", static_cast< ::zend_uint>(arity), num_params); \ 127 | return; \ 128 | } \ 129 | zval** params = reinterpret_cast( \ 130 | zend_vm_stack_top(TSRMLS_C) - 1 - num_params ); \ 131 | try { \ 132 | __invoke__(__z__, __arity__, obj); \ 133 | } catch (const ::boost::php::runtime_error& e) { \ 134 | ::boost::php::utils::print_error(E_WARNING, \ 135 | e.filename().c_str(), e.line_number(), e.what()); \ 136 | } catch (const ::std::exception& e) { \ 137 | zend_error(E_WARNING, "%s", e.what()); \ 138 | } \ 139 | } \ 140 | public: \ 141 | typename Tsig_::function_type fun_; \ 142 | const Toretr_& oretr_; 143 | #endif /* ZEND_MODULE_API_NO < 20071006 */ 144 | 145 | #define __BOOST_PHP_NATIVE_FUN_PROXY_TPL(__z__, __arity__, __var__) \ 146 | template \ 147 | class native_fun_proxy: public native_fun_proxy_base { \ 148 | __BOOST_PHP_NATIVE_FUN_PROXY_BODY_TPL(__z__, __arity__, __var__, \ 149 | __BOOST_PHP_NATIVE_FUN_PROXY_NONVOID_INVOCATION_TPL) \ 150 | }; \ 151 | template \ 152 | class native_fun_proxy: public native_fun_proxy_base { \ 153 | __BOOST_PHP_NATIVE_FUN_PROXY_BODY_TPL(__z__, __arity__, __var__, \ 154 | __BOOST_PHP_NATIVE_FUN_PROXY_VOID_INVOCATION_TPL) \ 155 | }; 156 | 157 | BOOST_PP_REPEAT_FROM_TO(0, BOOST_MPL_LIMIT_VECTOR_SIZE, __BOOST_PHP_NATIVE_FUN_PROXY_TPL, _); 158 | 159 | #undef __BOOST_PHP_NATIVE_FUN_PROXY_CONV_TPL 160 | #undef __BOOST_PHP_NATIVE_FUN_PROXY_BODY_TPL 161 | #undef __BOOST_PHP_NATIVE_FUN_PROXY_TPL 162 | #undef __BOOST_PHP_NATIVE_FUN_PROXY_INVOCATION_TPL 163 | #undef __BOOST_PHP_NATIVE_FUN_PROXY_NONVOID_INVOCATION_TPL 164 | #undef __BOOST_PHP_NATIVE_FUN_PROXY_VOID_INVOCATION_TPL 165 | 166 | template 167 | inline native_fun_proxy_base* create_native_fun_proxy(const Tsig_& sig, const Toretr_& oretr) 168 | { 169 | return new native_fun_proxy(sig.impl, oretr); 170 | } 171 | 172 | 173 | template 174 | inline native_fun_proxy_base* create_native_fun_proxy(const Tsig_& sig) 175 | { 176 | return create_native_fun_proxy(sig, get_object_retriever(sig)); 177 | } 178 | 179 | } } } // namespace boost::php::detail 180 | 181 | #endif /* BOOST_PHP_DETAIL_NATIVE_FUN_PROXY_HPP */ 182 | -------------------------------------------------------------------------------- /boost/php/detail/module_macros.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2008 (C) Moriyoshi Koizumi. All rights reserved. 3 | // 4 | // This software is distributed under the Boost Software License, Version 1.0. 5 | // 6 | // Permission is hereby granted, free of charge, to any person or organization 7 | // obtaining a copy of the software and accompanying documentation covered by 8 | // this license (the "Software") to use, reproduce, display, distribute, 9 | // execute, and transmit the Software, and to prepare derivative works of the 10 | // Software, and to permit third-parties to whom the Software is furnished to 11 | // do so, all subject to the following: 12 | // 13 | // The copyright notices in the Software and this entire statement, including 14 | // the above license grant, this restriction and the following disclaimer, 15 | // must be included in all copies of the Software, in whole or in part, and 16 | // all derivative works of the Software, unless such copies or derivative 17 | // works are solely in the form of machine-executable object code generated by 18 | // a source language processor. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 23 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 24 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 25 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | // DEALINGS IN THE SOFTWARE. 27 | 28 | #ifndef BOOST_PHP_MODULE_MACROS_HPP 29 | #define BOOST_PHP_MODULE_MACROS_HPP 30 | 31 | #include 32 | #include 33 | 34 | #if ZEND_MODULE_API_NO < 20090115 35 | #define BOOST_PHP_MODULE_BUILD_ID 36 | #else 37 | #define BOOST_PHP_MODULE_BUILD_ID , ZEND_MODULE_BUILD_ID 38 | #endif 39 | 40 | #define BOOST_PHP_ADD_MODULE_VARIATION(__mod_name__) \ 41 | namespace boost { namespace php { namespace _ { \ 42 | struct __mod_name__ {}; \ 43 | } } } 44 | 45 | #define BOOST_PHP_ASSOCIATE_MODULE_WITH_CLASS(__mod_name__, __mod_klass__) \ 46 | namespace boost { namespace php { namespace detail { \ 47 | template<> struct module_class_of< ::boost::php::_::__mod_name__> { \ 48 | typedef __mod_klass__ type; \ 49 | }; \ 50 | } } } 51 | 52 | #define BOOST_PHP_MODULE_CLASS(__mod_name__) \ 53 | ::boost::php::detail::module_class_of< ::boost::php::_::__mod_name__>::type 54 | #define BOOST_PHP_MODULE_HANDLER_CLASS(__mod_name__) \ 55 | ::boost::php::detail::module_class_of< ::boost::php::_::__mod_name__>::type::handler 56 | #define BOOST_PHP_MODULE_HANDLER(__mod_name__) \ 57 | BOOST_PP_CAT(__mod_name__, _globals) 58 | #define BOOST_PHP_MODULE_VAR(__mod_name__) \ 59 | BOOST_PP_CAT(__mod_name__, _module) 60 | #define BOOST_PHP_MODULE_ENTRY_VAR(__mod_name__) \ 61 | BOOST_PP_CAT(__mod_name__, _module_entry) 62 | #define BOOST_PHP_TSRM_ID_VAR(__mod_name__) \ 63 | BOOST_PP_CAT(BOOST_PHP_MODULE_HANDLER(__mod_name__), _id) 64 | #define BOOST_PHP_MODULE_HANDLER_CTOR(__mod_name__) \ 65 | BOOST_PP_CAT(BOOST_PHP_MODULE_HANDLER(__mod_name__), _ctor) 66 | #define BOOST_PHP_MODULE_HANDLER_DTOR(__mod_name__) \ 67 | BOOST_PP_CAT(BOOST_PHP_MODULE_HANDLER(__mod_name__), _dtor) 68 | #define BOOST_PHP_MODULE_POST_RSHUTDOWN_FUNC(__mod_name__) \ 69 | BOOST_PP_CAT(zm_post_deactivate_, __mod_name__) 70 | 71 | #define BOOST_PHP_USE_MODULE_HANDLER_CTOR_AND_DTOR(__mod_name__) \ 72 | extern "C" { \ 73 | static void BOOST_PHP_MODULE_HANDLER_CTOR(__mod_name__)(BOOST_PHP_MODULE_HANDLER_CLASS(__mod_name__)* ptr TSRMLS_DC); \ 74 | static void BOOST_PHP_MODULE_HANDLER_DTOR(__mod_name__)(BOOST_PHP_MODULE_HANDLER_CLASS(__mod_name__)* ptr TSRMLS_DC); \ 75 | } 76 | 77 | #ifdef ZTS 78 | 79 | #define BOOST_PHP_MODULE_HEADER(__mod_name__, __version__) \ 80 | { \ 81 | STANDARD_MODULE_HEADER, \ 82 | const_cast(#__mod_name__), \ 83 | 0, \ 84 | ZEND_MINIT(__mod_name__), \ 85 | ZEND_MSHUTDOWN(__mod_name__), \ 86 | ZEND_RINIT(__mod_name__), \ 87 | ZEND_RSHUTDOWN(__mod_name__), \ 88 | ZEND_MINFO(__mod_name__), \ 89 | const_cast(__version__), \ 90 | sizeof(BOOST_PHP_MODULE_HANDLER_CLASS(__mod_name__)), \ 91 | &BOOST_PHP_TSRM_ID_VAR(__mod_name__), \ 92 | NULL, \ 93 | NULL, \ 94 | &BOOST_PHP_MODULE_POST_RSHUTDOWN_FUNC(__mod_name__), \ 95 | 0, 0, NULL, 0 BOOST_PHP_MODULE_BUILD_ID \ 96 | } 97 | 98 | #define BOOST_PHP_DECLARE_MODULE_SLOT(__mod_name__) \ 99 | extern "C" { ZEND_API ts_rsrc_id BOOST_PHP_TSRM_ID_VAR(__mod_name__); } 100 | 101 | #define BOOST_PHP_USE_MODULE_SLOT_CONFIG(__mod_name__) \ 102 | extern "C" { extern ZEND_API ts_rsrc_id BOOST_PHP_TSRM_ID_VAR(__mod_name__); } 103 | 104 | #define BOOST_PHP_MODULE_SLOT(__mod_name__) \ 105 | reinterpret_cast((*reinterpret_cast(tsrm_ls))[TSRM_UNSHUFFLE_RSRC_ID(BOOST_PHP_TSRM_ID_VAR(__mod_name__))]) 106 | 107 | #define BOOST_PHP_DECLARE_MINIT_FUNCTION(__mod_name__) \ 108 | ZEND_MINIT_FUNCTION(__mod_name__) { \ 109 | ts_allocate_id(&BOOST_PHP_TSRM_ID_VAR(__mod_name__), \ 110 | sizeof(BOOST_PHP_MODULE_HANDLER_CLASS(__mod_name__)), \ 111 | (ts_allocate_ctor)&BOOST_PHP_MODULE_HANDLER_CTOR(__mod_name__),\ 112 | (ts_allocate_dtor)&BOOST_PHP_MODULE_HANDLER_DTOR(__mod_name__));\ 113 | try { \ 114 | BOOST_PHP_MODULE_INVOKE_HOOKS(__mod_name__, initializers); \ 115 | BOOST_PHP_MODULE_SLOT(__mod_name__)->__initialize(TSRMLS_C); \ 116 | } catch (const ::std::exception& e) { \ 117 | zend_error(E_WARNING, const_cast("%s"), e.what()); \ 118 | return FAILURE; \ 119 | } \ 120 | return SUCCESS; \ 121 | } 122 | 123 | #define BOOST_PHP_DECLARE_MSHUTDOWN_FUNCTION(__mod_name__) \ 124 | ZEND_MSHUTDOWN_FUNCTION(__mod_name__) { \ 125 | ts_free_id(BOOST_PHP_TSRM_ID_VAR(__mod_name__)); \ 126 | try { \ 127 | BOOST_PHP_MODULE_SLOT(__mod_name__)->__finalize(TSRMLS_C); \ 128 | BOOST_PHP_MODULE_INVOKE_HOOKS(__mod_name__, finalizers); \ 129 | } catch (const ::std::exception& e) { \ 130 | zend_error(E_WARNING, const_cast("%s"), e.what()); \ 131 | } \ 132 | return SUCCESS; \ 133 | } 134 | 135 | #else /* ZTS */ 136 | 137 | #define BOOST_PHP_MODULE_HEADER(__mod_name__, __version__) \ 138 | { \ 139 | STANDARD_MODULE_HEADER, \ 140 | const_cast(#__mod_name__), \ 141 | 0, \ 142 | ZEND_MINIT(__mod_name__), \ 143 | ZEND_MSHUTDOWN(__mod_name__), \ 144 | ZEND_RINIT(__mod_name__), \ 145 | ZEND_RSHUTDOWN(__mod_name__), \ 146 | ZEND_MINFO(__mod_name__), \ 147 | const_cast(__version__), \ 148 | sizeof(BOOST_PHP_MODULE_HANDLER_CLASS(__mod_name__)), \ 149 | &BOOST_PHP_MODULE_HANDLER(__mod_name__), \ 150 | NULL, \ 151 | NULL, \ 152 | &BOOST_PHP_MODULE_POST_RSHUTDOWN_FUNC(__mod_name__), \ 153 | 0, 0, NULL, 0 BOOST_PHP_MODULE_BUILD_ID \ 154 | } 155 | 156 | #define BOOST_PHP_DECLARE_MODULE_SLOT(__mod_name__) \ 157 | extern "C" { ZEND_API BOOST_PHP_MODULE_HANDLER_CLASS(__mod_name__) BOOST_PHP_MODULE_HANDLER(__mod_name__)( \ 158 | BOOST_PHP_MODULE_VAR(&__mod_name__)); } 159 | 160 | #define BOOST_PHP_USE_MODULE_SLOT_CONFIG(__mod_name__) \ 161 | extern "C" { extern ZEND_API BOOST_PHP_MODULE_HANDLER_CLASS(__mod_name__) BOOST_PHP_MODULE_HANDLER(__mod_name__); } 162 | 163 | #define BOOST_PHP_MODULE_SLOT(__mod_name__) \ 164 | (&BOOST_PHP_MODULE_HANDLER(__mod_name__)) 165 | 166 | #define BOOST_PHP_DECLARE_MINIT_FUNCTION(__mod_name__) \ 167 | ZEND_MINIT_FUNCTION(__mod_name__) { \ 168 | BOOST_PHP_MODULE_HANDLER_CTOR(__mod_name__)(BOOST_PHP_MODULE_SLOT(__mod_name__)); \ 169 | try { \ 170 | BOOST_PHP_MODULE_INVOKE_HOOKS(__mod_name__, initializers); \ 171 | BOOST_PHP_MODULE_SLOT(__mod_name__)->__initialize(); \ 172 | } catch (const ::std::exception& e) { \ 173 | zend_error(E_WARNING, const_cast("%s"), e.what()); \ 174 | return FAILURE; \ 175 | } \ 176 | return SUCCESS; \ 177 | } 178 | 179 | #define BOOST_PHP_DECLARE_MSHUTDOWN_FUNCTION(__mod_name__) \ 180 | ZEND_MSHUTDOWN_FUNCTION(__mod_name__) { \ 181 | try { \ 182 | BOOST_PHP_MODULE_SLOT(__mod_name__)->__finalize(); \ 183 | BOOST_PHP_MODULE_INVOKE_HOOKS(__mod_name__, finalizers); \ 184 | BOOST_PHP_MODULE_HANDLER_DTOR(__mod_name__)(BOOST_PHP_MODULE_SLOT(__mod_name__)); \ 185 | } catch (const ::std::exception& e) { \ 186 | zend_error(E_WARNING, const_cast("%s"), e.what()); \ 187 | } \ 188 | return SUCCESS; \ 189 | } 190 | 191 | #endif /* ZTS */ 192 | 193 | #define BOOST_PHP_DECLARE_RINIT_FUNCTION(__mod_name__) \ 194 | ZEND_RINIT_FUNCTION(__mod_name__) { \ 195 | try { \ 196 | BOOST_PHP_MODULE_SLOT(__mod_name__)->__activate(TSRMLS_C); \ 197 | } catch (const ::std::exception& e) { \ 198 | zend_error(E_WARNING, const_cast("%s"), e.what()); \ 199 | return FAILURE; \ 200 | } \ 201 | return SUCCESS; \ 202 | } 203 | 204 | #define BOOST_PHP_DECLARE_RSHUTDOWN_FUNCTION(__mod_name__) \ 205 | ZEND_RSHUTDOWN_FUNCTION(__mod_name__) { \ 206 | try { \ 207 | BOOST_PHP_MODULE_SLOT(__mod_name__)->__deactivate(TSRMLS_C); \ 208 | } catch (const ::std::exception& e) { \ 209 | zend_error(E_WARNING, const_cast("%s"), e.what()); \ 210 | return FAILURE; \ 211 | } \ 212 | return SUCCESS; \ 213 | } 214 | 215 | #define BOOST_PHP_DECLARE_MINFO_FUNCTION(__mod_name__) \ 216 | ZEND_MINFO_FUNCTION(__mod_name__) { \ 217 | try { \ 218 | BOOST_PHP_MODULE_SLOT(__mod_name__)->__display_info(TSRMLS_C); \ 219 | } catch (const ::std::exception& e) { \ 220 | zend_error(E_ERROR, const_cast("%s"), e.what()); \ 221 | _zend_bailout(const_cast(__FILE__), __LINE__); \ 222 | } \ 223 | } 224 | 225 | #define BOOST_PHP_DECLARE_POST_RSHUTDOWN_FUNCTION(__mod_name__) \ 226 | int BOOST_PHP_MODULE_POST_RSHUTDOWN_FUNC(__mod_name__)() { \ 227 | TSRMLS_FETCH(); \ 228 | try { \ 229 | BOOST_PHP_MODULE_SLOT(__mod_name__)->__post_deactivate(TSRMLS_C); \ 230 | } catch (const ::std::exception& e) { \ 231 | zend_error(E_WARNING, const_cast("%s"), e.what()); \ 232 | return FAILURE; \ 233 | } \ 234 | return SUCCESS; \ 235 | } 236 | 237 | #define BOOST_PHP_MODULE_INVOKE_HOOKS(__mod_name__, __kind__) \ 238 | BOOST_PHP_MODULE_EACH_HOOK( \ 239 | ::boost::php::detail::module_hooks< \ 240 | BOOST_PHP_MODULE_CLASS(__mod_name__) >::__kind__##_type, \ 241 | BOOST_PHP_MODULE_HOOKS(__mod_name__)::singleton.__kind__, \ 242 | (*_)(*BOOST_PHP_MODULE_SLOT(__mod_name__) TSRMLS_CC)) 243 | 244 | #define BOOST_PHP_MODULE_EACH_HOOK(__type__, __list__, __action__) \ 245 | for (__type__::element_type* _ = __list__.first; _; _ = _->next) { __action__; } 246 | 247 | #define BOOST_PHP_MODULE_HOOKS(__mod_name__) \ 248 | ::boost::php::detail::module_hooks< BOOST_PHP_MODULE_CLASS(__mod_name__) > 249 | 250 | #define BOOST_PHP_DECLARE_MODULE_HOOKS(__mod_name__) \ 251 | namespace boost { namespace php { namespace detail { \ 252 | template<> \ 253 | module_hooks< BOOST_PHP_MODULE_CLASS(__mod_name__) > \ 254 | module_hooks< BOOST_PHP_MODULE_CLASS(__mod_name__) >::singleton = module_hooks< BOOST_PHP_MODULE_CLASS(__mod_name__) >(); \ 255 | } } } 256 | 257 | #define BOOST_PHP_USE_MODULE_SLOT(__mod_name__, __mod_klass__) \ 258 | BOOST_PHP_ASSOCIATE_MODULE_WITH_CLASS(__mod_name__, __mod_klass__) \ 259 | BOOST_PHP_USE_MODULE_SLOT_CONFIG(__mod_name__) \ 260 | 261 | #define BOOST_PHP_USE_INIT_FUNCTIONS(__mod_name__) \ 262 | extern "C" { \ 263 | static ZEND_MINIT_FUNCTION(__mod_name__); \ 264 | static ZEND_MSHUTDOWN_FUNCTION(__mod_name__); \ 265 | static ZEND_MINFO_FUNCTION(__mod_name__); \ 266 | static ZEND_RINIT_FUNCTION(__mod_name__); \ 267 | static ZEND_RSHUTDOWN_FUNCTION(__mod_name__); \ 268 | static int BOOST_PHP_MODULE_POST_RSHUTDOWN_FUNC(__mod_name__)(); \ 269 | } 270 | 271 | #define BOOST_PHP_DECLARE_INIT_FUNCTIONS(__mod_name__, __mod_klass__) \ 272 | extern "C" { \ 273 | static void \ 274 | BOOST_PHP_MODULE_HANDLER_CTOR(__mod_name__)(BOOST_PHP_MODULE_HANDLER_CLASS(__mod_name__)* ptr TSRMLS_DC) \ 275 | { \ 276 | new(ptr) BOOST_PHP_MODULE_HANDLER_CLASS(__mod_name__)(&BOOST_PHP_MODULE_VAR(__mod_name__)); \ 277 | } \ 278 | static void \ 279 | BOOST_PHP_MODULE_HANDLER_DTOR(__mod_name__)(BOOST_PHP_MODULE_HANDLER_CLASS(__mod_name__)* ptr TSRMLS_DC) \ 280 | { \ 281 | ptr->~handler(); \ 282 | } \ 283 | BOOST_PHP_DECLARE_MINIT_FUNCTION(__mod_name__); \ 284 | BOOST_PHP_DECLARE_MSHUTDOWN_FUNCTION(__mod_name__); \ 285 | BOOST_PHP_DECLARE_MINFO_FUNCTION(__mod_name__); \ 286 | BOOST_PHP_DECLARE_RINIT_FUNCTION(__mod_name__); \ 287 | BOOST_PHP_DECLARE_RSHUTDOWN_FUNCTION(__mod_name__); \ 288 | BOOST_PHP_DECLARE_POST_RSHUTDOWN_FUNCTION(__mod_name__); \ 289 | } \ 290 | BOOST_PHP_DECLARE_MODULE_HOOKS(__mod_name__); 291 | 292 | #define BOOST_PHP_DECLARE_HANDLER_RETRIEVER(__mod_name__) \ 293 | namespace boost { namespace php { \ 294 | template<> \ 295 | BOOST_PHP_MODULE_HANDLER_CLASS(__mod_name__)* \ 296 | object_retriever:: \ 297 | operator()(INTERNAL_FUNCTION_PARAMETERS) const { \ 298 | return BOOST_PHP_MODULE_SLOT(__mod_name__); \ 299 | } \ 300 | } } 301 | 302 | #define BOOST_PHP_MODULE(__mod_name__, __version__, __mod_klass__) \ 303 | BOOST_PHP_ADD_MODULE_VARIATION(__mod_name__); \ 304 | BOOST_PHP_USE_MODULE_SLOT(__mod_name__, __mod_klass__); \ 305 | BOOST_PHP_USE_INIT_FUNCTIONS(__mod_name__); \ 306 | BOOST_PHP_USE_MODULE_HANDLER_CTOR_AND_DTOR(__mod_name__); \ 307 | extern "C" { zend_module_entry BOOST_PHP_MODULE_ENTRY_VAR(__mod_name__) = \ 308 | BOOST_PHP_MODULE_HEADER(__mod_name__, __version__); } \ 309 | static __mod_klass__ BOOST_PHP_MODULE_VAR(__mod_name__)( \ 310 | &BOOST_PHP_MODULE_ENTRY_VAR(__mod_name__)); \ 311 | BOOST_PHP_DECLARE_MODULE_SLOT(__mod_name__); \ 312 | BOOST_PHP_DECLARE_INIT_FUNCTIONS(__mod_name__, __mod_klass__); \ 313 | BOOST_PHP_DECLARE_HANDLER_RETRIEVER(__mod_name__) 314 | 315 | #endif /* BOOST_PHP_MODULE_MACROS_HPP */ 316 | -------------------------------------------------------------------------------- /boost/php/hashtable.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2008 (C) Moriyoshi Koizumi. All rights reserved. 3 | // 4 | // This software is distributed under the Boost Software License, Version 1.0. 5 | // 6 | // Permission is hereby granted, free of charge, to any person or organization 7 | // obtaining a copy of the software and accompanying documentation covered by 8 | // this license (the "Software") to use, reproduce, display, distribute, 9 | // execute, and transmit the Software, and to prepare derivative works of the 10 | // Software, and to permit third-parties to whom the Software is furnished to 11 | // do so, all subject to the following: 12 | // 13 | // The copyright notices in the Software and this entire statement, including 14 | // the above license grant, this restriction and the following disclaimer, 15 | // must be included in all copies of the Software, in whole or in part, and 16 | // all derivative works of the Software, unless such copies or derivative 17 | // works are solely in the form of machine-executable object code generated by 18 | // a source language processor. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 23 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 24 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 25 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | // DEALINGS IN THE SOFTWARE. 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | #include 38 | #include 39 | #include 40 | 41 | #ifndef BOOST_PHP_HASHTABLE_KEY_DEFINED 42 | #define BOOST_PHP_HASHTABLE_KEY_DEFINED 43 | 44 | namespace boost { namespace php { 45 | 46 | class hashtable_key: public ::zend_hash_key { 47 | public: 48 | hashtable_key(string& v); 49 | 50 | hashtable_key(ulong v) { 51 | nKeyLength = 0; 52 | h = v; 53 | } 54 | 55 | hashtable_key(const char* str, 56 | ::std::size_t str_len = static_cast< ::std::size_t>(-1)); 57 | 58 | operator ::std::string() const { 59 | if (nKeyLength == 0) { 60 | return ::boost::lexical_cast< ::std::string>(h); 61 | } else { 62 | return ::std::string(arKey, nKeyLength); 63 | } 64 | } 65 | }; 66 | 67 | } } // namespace boost::php 68 | 69 | #endif /* BOOST_PHP_HASHTABLE_KEY_DEFINED */ 70 | 71 | #ifndef BOOST_PHP_SYMTABLE_KEY_DEFINED 72 | #define BOOST_PHP_SYMTABLE_KEY_DEFINED 73 | 74 | namespace boost { namespace php { 75 | 76 | class symtable_key: public ::zend_hash_key { 77 | public: 78 | symtable_key(ulong v) { 79 | nKeyLength = 0; 80 | h = v; 81 | } 82 | 83 | symtable_key(string& v) { 84 | init(v, v.size()); 85 | } 86 | 87 | symtable_key(const char* str, 88 | ::std::size_t str_len = static_cast< ::std::size_t>(-1)) { 89 | if (str_len == static_cast< ::std::size_t>(-1)) { 90 | str_len = ::strlen(str); 91 | } 92 | init(str, str_len); 93 | } 94 | 95 | operator ::std::string() const { 96 | if (nKeyLength == 0) { 97 | return ::boost::lexical_cast< ::std::string>(h); 98 | } else { 99 | return ::std::string(arKey, nKeyLength - 1); 100 | } 101 | } 102 | private: 103 | void assign_index(::uint _h) { 104 | arKey = 0; 105 | nKeyLength = 0; 106 | h = _h; 107 | } 108 | 109 | void init(const char* str, ::uint str_len); 110 | }; 111 | 112 | } } //namespace boost::php 113 | 114 | #endif /* BOOST_PHP_SYMTABLE_KEY_DEFINED */ 115 | 116 | #ifndef BOOST_PHP_HASHTABLE_DEFINED 117 | #define BOOST_PHP_HASHTABLE_DEFINED 118 | 119 | namespace boost { namespace php { 120 | 121 | template 122 | class hashtable: public ::HashTable { 123 | public: 124 | typedef Tkey_ key_type; 125 | typedef Telem_ mapped_type; 126 | typedef Telem_ data_type; 127 | typedef ::std::pair value_type; 128 | typedef ::uint size_type; 129 | typedef int difference_type; 130 | typedef ::dtor_func_t destructor_type; 131 | 132 | template 133 | struct pair { 134 | typedef Tfirst_ first_type; 135 | typedef Tsecond_ second_type; 136 | 137 | pair(typename ::boost::call_traits::param_type f, 138 | typename ::boost::call_traits::param_type s) 139 | : first(f), second(s) {} 140 | 141 | pair& operator=(const pair& that) { 142 | pair(that).swap(*this); 143 | return *this; 144 | } 145 | 146 | void swap(pair& that) throw() { 147 | ::std::swap(first, that.first); 148 | ::std::swap(second, that.second); 149 | } 150 | 151 | Tfirst_ first; 152 | Tsecond_ second; 153 | }; 154 | 155 | typedef pair reference; 156 | typedef pair const_reference; 157 | 158 | template class iterator_base { 159 | public: 160 | typedef typename Tcntnr_::difference_type difference_type; 161 | typedef typename std::bidirectional_iterator_tag iterator_category; 162 | 163 | public: 164 | iterator_base(Tcntnr_* cntnr, const ::HashPosition& pos, 165 | bool past_last = false) 166 | : cntnr_(cntnr), pos_(pos), past_last_(past_last) {} 167 | 168 | bool operator==(const Titer_& rhs) const { 169 | return past_last_ == rhs.past_last_ && pos_ == rhs.pos_; 170 | } 171 | 172 | bool operator!=(const Titer_& rhs) const { 173 | return past_last_ != rhs.past_last_ || pos_ != rhs.pos_; 174 | } 175 | 176 | Titer_& operator++() { 177 | ::HashPosition next(pos_); 178 | ::zend_hash_move_forward_ex( 179 | const_cast(cntnr_), &next); 180 | if (!next) { 181 | past_last_ = true; 182 | } else { 183 | pos_ = next; 184 | } 185 | return *static_cast(this); 186 | } 187 | 188 | Titer_ operator++(int) { 189 | Titer_ retval(*static_cast(this)); 190 | ::HashPosition next(pos_); 191 | ::zend_hash_move_forward_ex( 192 | const_cast(cntnr_), &next); 193 | if (!next) { 194 | past_last_ = true; 195 | } else { 196 | pos_ = next; 197 | } 198 | return retval; 199 | } 200 | 201 | Titer_& operator--() { 202 | if (past_last_) { 203 | past_last_ = false; 204 | } else { 205 | ::zend_hash_move_backwards_ex( 206 | const_cast(cntnr_), 207 | &pos_); 208 | } 209 | return *static_cast(this); 210 | } 211 | 212 | Titer_ operator--(int) { 213 | Titer_ retval(*static_cast(this)); 214 | if (past_last_) { 215 | past_last_ = false; 216 | } else { 217 | ::zend_hash_move_backwards_ex( 218 | const_cast(cntnr_), 219 | &pos_); 220 | } 221 | return retval; 222 | } 223 | 224 | typename value_type::first_type key() const { 225 | typename value_type::first_type key(0ul); 226 | ::zend_hash_get_current_key_ex( 227 | const_cast(cntnr_), 228 | const_cast(&key.arKey), 229 | const_cast< ::zend_uint*>(&key.nKeyLength), 230 | const_cast< ulong*>(&key.h), 0, 231 | const_cast< ::HashPosition*>( 232 | &static_cast(pos_))); 233 | return key; 234 | } 235 | 236 | public: 237 | Tcntnr_* cntnr_; 238 | ::HashPosition pos_; 239 | bool past_last_; 240 | }; 241 | 242 | class iterator: public iterator_base { 243 | public: 244 | typedef typename hashtable::value_type value_type; 245 | typedef typename hashtable::reference reference; 246 | typedef iterator pointer; 247 | 248 | private: 249 | typedef iterator_base base_type; 250 | 251 | public: 252 | iterator(hashtable* cntnr, const ::HashPosition& pos, 253 | bool past_last = false) 254 | : base_type(cntnr, pos, past_last) {} 255 | 256 | typename value_type::second_type& data() const { 257 | typename value_type::second_type* data; 258 | ::zend_hash_get_current_data_ex( 259 | const_cast(base_type::cntnr_), 260 | reinterpret_cast(&data), 261 | const_cast< ::HashPosition*>( 262 | &static_cast( 263 | base_type::pos_))); 264 | return *data; 265 | } 266 | 267 | reference operator*() const { 268 | return reference(base_type::key(), data()); 269 | } 270 | }; 271 | 272 | class const_iterator: public iterator_base { 273 | public: 274 | typedef typename hashtable::value_type value_type; 275 | typedef typename hashtable::const_reference reference; 276 | typedef const_iterator pointer; 277 | typedef iterator_base base_type; 278 | 279 | public: 280 | const_iterator(const hashtable* cntnr, const ::HashPosition& pos, 281 | bool past_last = false) 282 | : base_type(cntnr, pos, past_last) {} 283 | 284 | typename value_type::second_type const& data() const { 285 | typename value_type::second_type* data; 286 | ::zend_hash_get_current_data_ex( 287 | const_cast(base_type::cntnr_), 288 | reinterpret_cast(&data), 289 | const_cast< ::HashPosition*>( 290 | &static_cast< const ::HashPosition&>(base_type::pos_))); 291 | return *data; 292 | } 293 | 294 | reference operator*() const { 295 | return reference(base_type::key(), data()); 296 | } 297 | }; 298 | 299 | typedef iterator pointer; 300 | typedef const_iterator const_pointer; 301 | 302 | protected: 303 | typedef Bucket bucket_type; 304 | 305 | public: 306 | hashtable(size_type initial_size = 0, 307 | destructor_type dtor = 308 | reinterpret_cast( 309 | &detail::value_dtor_fun::impl), 310 | bool persistent = false, 311 | bool apply_protection = true) { 312 | ::zend_hash_init_ex(this, initial_size, NULL, dtor, persistent, 313 | apply_protection); 314 | } 315 | 316 | ~hashtable() { 317 | ::zend_hash_destroy(this); 318 | } 319 | 320 | size_type size() const { 321 | return nNumOfElements; 322 | } 323 | 324 | void clear() { 325 | ::zend_hash_clean(this); 326 | } 327 | 328 | void rehash() { 329 | ::zend_hash_rehash(this); 330 | } 331 | 332 | mapped_type* insert(const value_type& v) { 333 | mapped_type* retval; 334 | if (FAILURE == zend_hash_quick_add(this, v.first.arKey, 335 | v.first.nKeyLength, v.first.h, 336 | const_cast(&v.second), 337 | sizeof(mapped_type), reinterpret_cast(&retval))) { 338 | return 0; 339 | } 340 | detail::value_copy_ctor_fun::impl(retval, v.second); 341 | return retval; 342 | } 343 | 344 | mapped_type* update(const value_type& v) { 345 | mapped_type* retval; 346 | if (FAILURE == zend_hash_quick_update(this, v.first.arKey, 347 | v.first.nKeyLength, v.first.h, 348 | const_cast(&v.second), 349 | sizeof(mapped_type), reinterpret_cast(&retval))) { 350 | return 0; 351 | } 352 | detail::value_copy_ctor_fun::impl(retval, v.second); 353 | return retval; 354 | } 355 | 356 | mapped_type& push_back(const mapped_type& v); 357 | 358 | iterator begin() { 359 | ::HashPosition pos; 360 | ::zend_hash_internal_pointer_reset_ex(this, &pos); 361 | return iterator(this, pos); 362 | } 363 | 364 | iterator end() { 365 | ::HashPosition pos; 366 | ::zend_hash_internal_pointer_end_ex(this, &pos); 367 | return iterator(this, pos, true); 368 | } 369 | 370 | const_iterator begin() const { 371 | ::HashPosition pos; 372 | ::zend_hash_internal_pointer_reset_ex( 373 | const_cast(this), &pos); 374 | return const_iterator(this, pos); 375 | } 376 | 377 | const_iterator end() const { 378 | ::HashPosition pos; 379 | ::zend_hash_internal_pointer_end_ex( 380 | const_cast(this), &pos); 381 | return const_iterator(this, pos, true); 382 | } 383 | 384 | mapped_type& operator[](const key_type& k); 385 | 386 | const mapped_type& operator[](const key_type& k) const; 387 | 388 | bool erase(const key_type& k) const { 389 | return SUCCESS == zend_hash_del_key_or_index( 390 | const_cast(this), k.arKey, k.nKeyLength, k.h, 391 | k.nKeyLength == 0 ? HASH_DEL_INDEX: HASH_DEL_KEY); 392 | } 393 | 394 | bool contains(const key_type& k) const { 395 | return zend_hash_quick_exists( 396 | const_cast(this), k.arKey, k.nKeyLength, k.h); 397 | } 398 | }; 399 | 400 | } } // namespace boost::php 401 | 402 | #endif /* BOOST_PHP_HASHTABLE_DEFINED */ 403 | 404 | #include 405 | 406 | #ifndef BOOST_PHP_HASHTABLE_KEY_MEMBERS_DEFINED 407 | #define BOOST_PHP_HASHTABLE_KEY_MEMBERS_DEFINED 408 | 409 | namespace boost { namespace php { 410 | 411 | inline hashtable_key::hashtable_key(string& v) 412 | { 413 | if (v.size() == 0) { 414 | throw std::out_of_range("key length must be greater than 0"); 415 | } 416 | arKey = v; 417 | nKeyLength = v.size(); 418 | h = 0; 419 | } 420 | 421 | inline hashtable_key::hashtable_key(const char* str, ::std::size_t str_len) 422 | { 423 | if (str_len == static_cast< ::std::size_t>(-1)) { 424 | str_len = ::strlen(str); 425 | } 426 | if (str_len == 0) { 427 | throw std::out_of_range("key length must be greater than 0"); 428 | } 429 | arKey = const_cast(str); 430 | nKeyLength = str_len; 431 | h = 0; 432 | } 433 | 434 | } } // namespace boost::php 435 | 436 | #endif /* BOOST_PHP_HASHTABLE_KEY_MEMBERS_DEFINED */ 437 | 438 | #ifndef BOOST_PHP_SYMTABLE_KEY_MEMBERS_DEFINED 439 | #define BOOST_PHP_SYMTABLE_KEY_MEMBERS_DEFINED 440 | 441 | namespace boost { namespace php { 442 | 443 | inline void symtable_key::init(const char* str, ::uint str_len) 444 | { 445 | if (str_len == 0) { 446 | throw std::out_of_range("key length must be greater than 0"); 447 | } 448 | arKey = const_cast(str); 449 | nKeyLength = str_len; 450 | h = 0; 451 | #if ZEND_MODULE_API_NO < 20071006 452 | HANDLE_NUMERIC(const_cast(str), str_len, assign_index(h)); 453 | #else 454 | ZEND_HANDLE_NUMERIC(const_cast(str), str_len, assign_index(h)); 455 | #endif 456 | } 457 | 458 | } } // namespace boost::php 459 | 460 | #endif /* BOOST_PHP_SYMTABLE_KEY_MEMBERS_DEFINED */ 461 | 462 | #ifndef BOOST_PHP_HASHTABLE_MEMBERS_DEFINED 463 | #define BOOST_PHP_HASHTABLE_MEMBERS_DEFINED 464 | 465 | namespace boost { namespace php { 466 | 467 | template 468 | inline typename hashtable::mapped_type& 469 | hashtable::push_back(const mapped_type& v) 470 | { 471 | mapped_type* retval; 472 | if (FAILURE == zend_hash_index_insert(this, 0, &v, 473 | sizeof(mapped_type), reinterpret_cast(&retval))) { 474 | throw runtime_error("failed to add a new entry"); 475 | } 476 | detail::value_copy_ctor_fun::impl(*retval, v); 477 | return *retval; 478 | } 479 | 480 | template 481 | inline typename hashtable::mapped_type& 482 | hashtable::operator[](const key_type& k) 483 | { 484 | mapped_type* retval; 485 | if (SUCCESS == zend_hash_quick_find( 486 | this, k.arKey, k.nKeyLength, k.h, 487 | reinterpret_cast(&retval))) { 488 | return *retval; 489 | } 490 | retval = insert(value_type(k, mapped_type())); 491 | if (retval) { 492 | return *retval; 493 | } 494 | throw runtime_error( 495 | ::std::string("failed to add a new entry [") 496 | + static_cast< ::std::string>(k) + "]"); 497 | } 498 | 499 | template 500 | inline typename hashtable::mapped_type const& 501 | hashtable::operator[](const key_type& k) const 502 | { 503 | mapped_type* retval; 504 | if (SUCCESS == zend_hash_quick_find( 505 | const_cast(this), k.arKey, k.nKeyLength, k.h, 506 | reinterpret_cast(&retval))) { 507 | return *retval; 508 | } 509 | throw runtime_error( 510 | ::std::string("failed to find a corresponding key [") 511 | + static_cast< ::std::string>(k) + "]"); 512 | } 513 | 514 | } } // namespace boost::php 515 | 516 | #endif /* BOOST_PHP_HASHTABLE_KEY_MEMBERS_DEFINED */ 517 | -------------------------------------------------------------------------------- /boost/php/klass.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2008 (C) Moriyoshi Koizumi. All rights reserved. 3 | // 4 | // This software is distributed under the Boost Software License, Version 1.0. 5 | // 6 | // Permission is hereby granted, free of charge, to any person or organization 7 | // obtaining a copy of the software and accompanying documentation covered by 8 | // this license (the "Software") to use, reproduce, display, distribute, 9 | // execute, and transmit the Software, and to prepare derivative works of the 10 | // Software, and to permit third-parties to whom the Software is furnished to 11 | // do so, all subject to the following: 12 | // 13 | // The copyright notices in the Software and this entire statement, including 14 | // the above license grant, this restriction and the following disclaimer, 15 | // must be included in all copies of the Software, in whole or in part, and 16 | // all derivative works of the Software, unless such copies or derivative 17 | // works are solely in the form of machine-executable object code generated by 18 | // a source language processor. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 23 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 24 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 25 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | // DEALINGS IN THE SOFTWARE. 27 | 28 | #ifndef BOOST_PHP_KLASS_DEFINED 29 | #define BOOST_PHP_KLASS_DEFINED 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | 46 | namespace boost { namespace php { 47 | 48 | template 49 | class klass; 50 | 51 | template 52 | struct klass_registry 53 | { 54 | static klass* value; 55 | }; 56 | 57 | template 58 | klass* klass_registry::value(0); 59 | 60 | struct klass_base { 61 | protected: 62 | template 63 | class zo_wrapper_base: public sensible_object { 64 | public: 65 | typedef T_ object_type; 66 | typedef boost::shared_ptr shared_pointer; 67 | 68 | zo_wrapper_base(zend_class_entry const& ce TSRMLS_DC) 69 | : sensible_object(ce TSRMLS_CC), 70 | type(INSTANCE), ptr(reinterpret_cast(instance)), 71 | destroy_handler(&instance_destructor) {} 72 | 73 | zo_wrapper_base(zend_class_entry const& ce, object_type* _ptr, 74 | void(*_destroy_handler)(object_type* TSRMLS_DC) = noop_destructor 75 | TSRMLS_DC) 76 | : sensible_object(ce TSRMLS_CC), type(WEAKREF), ptr(_ptr), 77 | destroy_handler(_destroy_handler) {} 78 | 79 | zo_wrapper_base(zend_class_entry const& ce, 80 | shared_pointer const& _ptr TSRMLS_DC) 81 | : sensible_object(ce TSRMLS_CC), type(REF), 82 | ptr((new (ref) shared_pointer(_ptr))->get()) {} 83 | 84 | private: 85 | static void instance_destructor(object_type* ptr TSRMLS_DC) 86 | { 87 | ptr->~object_type(); 88 | } 89 | 90 | static void noop_destructor(object_type* ptr TSRMLS_DC) 91 | { 92 | } 93 | 94 | public: 95 | enum { WEAKREF, INSTANCE, REF } type:2; 96 | 97 | object_type* ptr; 98 | void (*destroy_handler)(object_type* TSRMLS_DC); 99 | 100 | union { 101 | unsigned char instance[sizeof(object_type)]; 102 | unsigned char ref[sizeof(shared_pointer)]; 103 | }; 104 | }; 105 | 106 | template 107 | struct zo_wrapper_tpl: public zo_wrapper_base { 108 | typedef T_ object_type; 109 | typedef zo_wrapper_base base_type; 110 | typedef typename base_type::shared_pointer shared_pointer; 111 | 112 | zo_wrapper_tpl(zend_class_entry const& ce TSRMLS_DC) 113 | : base_type(ce TSRMLS_CC) {} 114 | 115 | zo_wrapper_tpl(zo_wrapper_tpl const& that TSRMLS_DC) 116 | : base_type(*that.ce TSRMLS_CC) { 117 | this->type = that.type; 118 | this->destroy_handler = that.destroy_handler; 119 | switch (that.type) { 120 | case base_type::WEAKREF: 121 | this->ptr = that.ptr; 122 | break; 123 | case base_type::INSTANCE: 124 | this->ptr = new (this->instance) object_type( 125 | *reinterpret_cast(that.instance)); 126 | break; 127 | case base_type::REF: 128 | this->ptr = (new (this->ref) shared_pointer( 129 | *reinterpret_cast(that.ref)))->get(); 130 | break; 131 | } 132 | } 133 | 134 | zo_wrapper_tpl(zend_class_entry const& ce, object_type* ptr, 135 | void(*destroy_handler)(object_type* TSRMLS_DC) = 0 TSRMLS_DC) 136 | : base_type(ce, ptr, destroy_handler TSRMLS_CC) {} 137 | 138 | zo_wrapper_tpl(zend_class_entry const& ce, 139 | shared_pointer ptr TSRMLS_DC) 140 | : base_type(ce, ptr TSRMLS_CC) {} 141 | }; 142 | }; 143 | 144 | template 145 | struct klass_base::zo_wrapper_tpl { 146 | typedef T_ object_type; 147 | typedef zo_wrapper_base base_type; 148 | typedef typename base_type::shared_pointer shared_pointer; 149 | 150 | zo_wrapper_tpl(zend_class_entry const& ce TSRMLS_DC) 151 | : base_type(ce TSRMLS_CC) {} 152 | 153 | zo_wrapper_tpl(zo_wrapper_tpl const& that TSRMLS_DC) 154 | : base_type(*that.ce TSRMLS_CC) { 155 | this->type = that.type; 156 | this->destroy_handler = that.destroy_handler; 157 | switch (that.type) { 158 | case base_type::WEAKREF: 159 | this->ptr = that.ptr; 160 | break; 161 | case base_type::INSTANCE: 162 | throw ::std::runtime_error( 163 | "underlying object is not copy-constructible"); 164 | break; 165 | case base_type::REF: 166 | this->ptr = (new (this->ref) shared_pointer( 167 | *reinterpret_cast(that.ref)))->get(); 168 | break; 169 | } 170 | } 171 | 172 | zo_wrapper_tpl(zend_class_entry const& ce, object_type* ptr, 173 | void(*destroy_handler)(object_type* TSRMLS_DC) = 0 TSRMLS_DC) 174 | : zo_wrapper_base(ce, ptr, destroy_handler TSRMLS_CC) {} 175 | 176 | zo_wrapper_tpl(zend_class_entry const& ce, 177 | shared_pointer ptr TSRMLS_DC) 178 | : base_type(ce, ptr TSRMLS_CC) {} 179 | }; 180 | 181 | template 182 | class klass: public ::zend_class_entry, public function_container >, public klass_base { 183 | friend class object_retriever; 184 | friend class to_native_converter; 185 | friend struct to_value_ptr_converter; 186 | friend struct to_value_ptr_converter; 187 | public: 188 | typedef T_ object_type; 189 | typedef zo_wrapper_tpl zo_wrapper; 190 | friend struct to_value_ptr_converter; 191 | 192 | private: 193 | typedef boost::unordered_map instance_handle_map; 194 | 195 | public: 196 | klass(char const* _name) { 197 | TSRMLS_FETCH(); 198 | type = ZEND_INTERNAL_CLASS; 199 | zend_initialize_class_data(this, true TSRMLS_CC); 200 | ce_flags = 0; 201 | name_length = strlen(_name); 202 | name = static_cast(::std::malloc(name_length + 1)); 203 | if (!name) 204 | throw ::std::bad_alloc(); 205 | ::std::memcpy(const_cast(name), _name, name_length + 1); 206 | create_object = reinterpret_cast< 207 | ::zend_object_value(*)(::zend_class_entry* TSRMLS_DC)>(&__factory); 208 | } 209 | 210 | template 211 | function_entry& define_function( 212 | ::std::string const& name, Tsig_ const& sig) { 213 | function_entry& retval = 214 | function_container::define_function(name, sig); 215 | retval.flags |= ZEND_ACC_PUBLIC; 216 | builtin_functions_() = *this; 217 | return retval; 218 | } 219 | 220 | template 221 | klass& ctor(Targs_) { 222 | typedef detail::unbound_function 223 | ctor_type; 224 | define_function(ZEND_CONSTRUCTOR_FUNC_NAME, 225 | detail::signature(ctor_type())); 226 | constructor = &( 227 | *(--reinterpret_cast&>( 228 | function_table).end())).second; 229 | return *this; 230 | } 231 | 232 | klass& implements(::zend_class_entry* iface) { 233 | interfaces = reinterpret_cast< ::zend_class_entry **>( 234 | ::std::realloc(interfaces, 235 | sizeof(::zend_class_entry*) * (num_interfaces + 1))); 236 | interfaces[num_interfaces++] = iface; 237 | return *this; 238 | } 239 | 240 | void fixup() { 241 | TSRMLS_FETCH(); 242 | BOOST_PHP_BEGIN_CAPTURE_ERROR 243 | if (FAILURE == ::zend_register_functions( 244 | this, *this, 245 | &function_table, MODULE_PERSISTENT TSRMLS_CC)) { 246 | throw runtime_error(BOOST_PHP_LAST_ERROR); 247 | } 248 | if (interfaces) { 249 | int _num_interfaces = num_interfaces; 250 | ::zend_class_entry** _interfaces = interfaces; 251 | interfaces = 0; 252 | num_interfaces = 0; 253 | for (int i = 0; i < _num_interfaces; ++i) { 254 | zend_do_implement_interface(this, _interfaces[i]); 255 | } 256 | ::std::free(_interfaces); 257 | } 258 | BOOST_PHP_END_CAPTURE_ERROR 259 | } 260 | 261 | zend_function_entry const*& builtin_functions_() { 262 | #if PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 4 263 | return info.internal.builtin_functions; 264 | #else 265 | return builtin_functions; 266 | #endif 267 | } 268 | 269 | zend_module_entry*& module_() { 270 | #if PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 4 271 | return info.internal.module; 272 | #else 273 | return module; 274 | #endif 275 | } 276 | 277 | static void* operator new(std::size_t sz) { 278 | void* retval = ::std::malloc(sz); 279 | if (!retval) 280 | throw ::std::bad_alloc(); 281 | return retval; 282 | } 283 | 284 | static void operator delete(void* ptr) { 285 | ::std::free(ptr); 286 | } 287 | 288 | private: 289 | static ::zend_object_value __factory(klass* self TSRMLS_DC) { 290 | zend_object_value retval; 291 | 292 | zo_wrapper* obj = new zo_wrapper(*self TSRMLS_CC); 293 | obj->handle = retval.handle = ::zend_objects_store_put(obj, 294 | reinterpret_cast< ::zend_objects_store_dtor_t>(&__dtor_wrapper), 295 | reinterpret_cast< ::zend_objects_free_object_storage_t>( 296 | &__delete_wrapper), 297 | reinterpret_cast< ::zend_objects_store_clone_t>( 298 | &__cctor_wrapper) 299 | TSRMLS_CC); 300 | retval.handlers = ::zend_get_std_object_handlers(); 301 | return retval; 302 | } 303 | 304 | static void __deleter(object_type* ptr TSRMLS_DC) 305 | { 306 | delete ptr; 307 | } 308 | 309 | static ::zend_object_value __weakref_factory(klass* self, object_type* ptr, void(*destroy_handler)(object_type* TSRMLS_DC) = 0 TSRMLS_DC) { 310 | zend_object_value retval; 311 | 312 | typename instance_handle_map::const_iterator i(weakref_handle_map_.find(ptr)); 313 | if (weakref_handle_map_.end() != i) { 314 | retval.handle = (*i).second; 315 | zend_objects_store_add_ref_by_handle(retval.handle TSRMLS_CC); 316 | } else { 317 | zo_wrapper* obj = new zo_wrapper(*self, ptr, destroy_handler TSRMLS_CC); 318 | retval.handle = obj->handle = ::zend_objects_store_put(obj, 319 | reinterpret_cast< ::zend_objects_store_dtor_t>( 320 | &__dtor_wrapper), 321 | reinterpret_cast< ::zend_objects_free_object_storage_t>( 322 | &__delete_wrapper), 323 | reinterpret_cast< ::zend_objects_store_clone_t>( 324 | &__cctor_wrapper) 325 | TSRMLS_CC); 326 | weakref_handle_map_.insert(std::make_pair(ptr, retval.handle)); 327 | } 328 | retval.handlers = ::zend_get_std_object_handlers(); 329 | return retval; 330 | } 331 | 332 | static ::zend_object_value __ref_factory(klass* self, typename zo_wrapper::shared_pointer ptr TSRMLS_DC) { 333 | zend_object_value retval; 334 | 335 | typename instance_handle_map::const_iterator i(ref_handle_map_.find(ptr.get())); 336 | if (ref_handle_map_.end() != i) { 337 | retval.handle = (*i).second; 338 | zend_objects_store_add_ref_by_handle(retval.handle TSRMLS_CC); 339 | } else { 340 | zo_wrapper* obj = new zo_wrapper(*self, ptr TSRMLS_CC); 341 | retval.handle = obj->handle = ::zend_objects_store_put(obj, 342 | reinterpret_cast< ::zend_objects_store_dtor_t>( 343 | &__dtor_wrapper), 344 | reinterpret_cast< ::zend_objects_free_object_storage_t>( 345 | &__delete_wrapper), 346 | reinterpret_cast< ::zend_objects_store_clone_t>( 347 | &__cctor_wrapper) 348 | TSRMLS_CC); 349 | ref_handle_map_.insert(std::make_pair(ptr.get(), retval.handle)); 350 | } 351 | retval.handlers = ::zend_get_std_object_handlers(); 352 | return retval; 353 | } 354 | 355 | 356 | static void __dtor_wrapper(zo_wrapper* obj TSRMLS_DC) { 357 | if (obj->type == zo_wrapper::REF) { 358 | ref_handle_map_.erase(obj->ptr); 359 | typedef typename zo_wrapper::shared_pointer shared_pointer; 360 | reinterpret_cast(obj->ref)->~shared_pointer(); 361 | } else { 362 | if (obj->type == zo_wrapper::WEAKREF) 363 | weakref_handle_map_.erase(obj->ptr); 364 | if (obj->destroy_handler) 365 | obj->destroy_handler(obj->ptr TSRMLS_CC); 366 | } 367 | } 368 | 369 | static void __delete_wrapper(zo_wrapper* obj TSRMLS_DC) { 370 | delete obj; 371 | } 372 | 373 | static void __cctor_wrapper(zo_wrapper* obj, zo_wrapper** cloned_obj TSRMLS_DC) { 374 | *cloned_obj = new zo_wrapper(*obj TSRMLS_CC); 375 | } 376 | 377 | static instance_handle_map weakref_handle_map_; 378 | static instance_handle_map ref_handle_map_; 379 | }; 380 | 381 | template 382 | typename klass::instance_handle_map 383 | klass::weakref_handle_map_; 384 | 385 | template 386 | typename klass::instance_handle_map 387 | klass::ref_handle_map_; 388 | 389 | template 390 | T_* object_retriever::operator()(INTERNAL_FUNCTION_PARAMETERS) const 391 | { 392 | typedef typename klass::zo_wrapper wrapper_type; 393 | wrapper_type* w = reinterpret_cast( 394 | ::zend_objects_get_address(this_ptr TSRMLS_CC)); 395 | return w->ptr; 396 | } 397 | 398 | template 399 | static klass& def_class(char const* name, Tctor_args_ args TSRMLS_DC) 400 | { 401 | klass* retval = new klass(name); 402 | boost::scoped_array lowercased_name(new char[retval->name_length + 1]); 403 | retval->module_() = EG(current_module); 404 | retval->ctor(args); 405 | ::zend_str_tolower_copy(lowercased_name.get(), retval->name, retval->name_length); 406 | ::zend_hash_update(CG(class_table), lowercased_name.get(), retval->name_length + 1, 407 | &retval, sizeof(zend_class_entry*), NULL); 408 | klass_registry::value = retval; 409 | return *retval; 410 | } 411 | 412 | template 413 | static klass& def_class(char const* name TSRMLS_DC) 414 | { 415 | return def_class >(name, ::boost::mpl::vector0<>() TSRMLS_CC); 416 | } 417 | 418 | } } // namespace boost::php 419 | 420 | template 421 | void intrusive_ptr_add_ref(::boost::php::klass* ptr) 422 | { 423 | ++ptr->refcount; 424 | } 425 | 426 | template 427 | void intrusive_ptr_release(::boost::php::klass* ptr) 428 | { 429 | ::destroy_zend_class(&ptr); 430 | } 431 | #endif /* BOOST_PHP_KLASS_DEFINED */ 432 | 433 | #ifndef BOOST_PHP_KLASS_STD_CONVERTER_DEFINED 434 | #define BOOST_PHP_KLASS_STD_CONVERTER_DEFINED 435 | #include 436 | 437 | namespace boost { namespace php { 438 | 439 | template 440 | struct to_native_converter { 441 | T_ const& operator()(value_ptr const& val TSRMLS_DC) const { 442 | return (*this)(const_cast(val)); 443 | } 444 | 445 | T_& operator()(value_ptr& val TSRMLS_DC) const { 446 | return *reinterpret_cast::zo_wrapper*>( 447 | zend_objects_get_address( 448 | const_cast< ::zval*>( 449 | static_cast< ::zval const*>( 450 | val.as())) 451 | TSRMLS_CC))->ptr; 452 | } 453 | }; 454 | 455 | template 456 | struct to_value_ptr_converter { 457 | value_ptr operator()(T_* val TSRMLS_DC) const { 458 | return value_ptr(new value(klass::__weakref_factory(klass_registry::value, val, klass::__deleter)), false); 459 | } 460 | }; 461 | 462 | template 463 | struct to_value_ptr_converter { 464 | value_ptr operator()(T_ const* val TSRMLS_DC) const { 465 | return to_value_ptr_converter()(const_cast(val) TSRMLS_CC); 466 | } 467 | }; 468 | 469 | template 470 | struct to_value_ptr_converter { 471 | value_ptr operator()(T_& val TSRMLS_DC) const { 472 | return value_ptr(new value(klass::__weakref_factory(klass_registry::value, &val)), false); 473 | } 474 | }; 475 | 476 | template 477 | struct to_value_ptr_converter { 478 | value_ptr operator()(T_ const& val TSRMLS_DC) const { 479 | return to_value_ptr_converter()(const_cast(val) TSRMLS_CC); 480 | } 481 | }; 482 | 483 | template 484 | struct to_value_ptr_converter, false> { 485 | value_ptr operator()(boost::shared_ptr const& val TSRMLS_DC) const { 486 | return value_ptr(new value(klass::__ref_factory(klass_registry::value, val)), false); 487 | } 488 | }; 489 | 490 | } } // namespace boost::php 491 | #endif /* BOOST_PHP_KLASS_STD_CONVERTER_DEFINED */ 492 | -------------------------------------------------------------------------------- /boost/php/value.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2008 (C) Moriyoshi Koizumi. All rights reserved. 3 | // 4 | // This software is distributed under the Boost Software License, Version 1.0. 5 | // 6 | // Permission is hereby granted, free of charge, to any person or organization 7 | // obtaining a copy of the software and accompanying documentation covered by 8 | // this license (the "Software") to use, reproduce, display, distribute, 9 | // execute, and transmit the Software, and to prepare derivative works of the 10 | // Software, and to permit third-parties to whom the Software is furnished to 11 | // do so, all subject to the following: 12 | // 13 | // The copyright notices in the Software and this entire statement, including 14 | // the above license grant, this restriction and the following disclaimer, 15 | // must be included in all copies of the Software, in whole or in part, and 16 | // all derivative works of the Software, unless such copies or derivative 17 | // works are solely in the form of machine-executable object code generated by 18 | // a source language processor. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 23 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 24 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 25 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | // DEALINGS IN THE SOFTWARE. 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | #include 33 | #include 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #ifndef BOOST_PHP_VALUE_DEFINED 43 | #define BOOST_PHP_VALUE_DEFINED 44 | 45 | #if ZEND_MODULE_API_NO < 20071006 46 | #define BOOST_PHP_ZVAL_ASSERT_REFCOUNT(p) \ 47 | BOOST_ASSERT((p)->refcount >= 1) 48 | #define BOOST_PHP_ZVAL_ADDREF(p) ZVAL_ADDREF(p) 49 | #else 50 | #define BOOST_PHP_ZVAL_ASSERT_REFCOUNT(p) \ 51 | BOOST_ASSERT(Z_REFCOUNT_P(p) >= 1) 52 | #define BOOST_PHP_ZVAL_ADDREF(p) Z_ADDREF_P(p) 53 | #endif /* ZEND_MODULE_API_NO < 20071006 */ 54 | 55 | namespace boost { namespace php { 56 | 57 | class value_ptr; 58 | class symtable_key; 59 | template class hashtable; 60 | typedef hashtable array; 61 | 62 | class value: public ::zval { 63 | public: 64 | enum typecode { 65 | _NULL = IS_NULL, 66 | _LONG = IS_LONG, 67 | _DOUBLE = IS_DOUBLE, 68 | _BOOL = IS_BOOL, 69 | _ARRAY = IS_ARRAY, 70 | _OBJECT = IS_OBJECT, 71 | _STRING = IS_STRING, 72 | _RESOURCE = IS_RESOURCE 73 | }; 74 | public: 75 | value(): zval(::zval_used_for_init) {} 76 | 77 | value(const ::zval& that): ::zval(that) { 78 | zval_copy_ctor(static_cast(this)); 79 | initialize(); 80 | } 81 | 82 | value(const value& that): ::zval(that) { 83 | zval_copy_ctor(static_cast(this)); 84 | initialize(); 85 | } 86 | 87 | value(const ::zval* that): ::zval(*that) { 88 | zval_copy_ctor(static_cast(this)); 89 | initialize(); 90 | } 91 | 92 | value(const value* that): ::zval(*that) { 93 | zval_copy_ctor(static_cast(this)); 94 | initialize(); 95 | } 96 | 97 | value(::zval const& that, enum typecode desired_type); 98 | 99 | value(value_ptr const& that); 100 | 101 | value(bool v) { 102 | ::zval::type = IS_BOOL; 103 | ::zval::value.lval = ZEND_NORMALIZE_BOOL(v); 104 | initialize(); 105 | } 106 | 107 | value(int v); 108 | 109 | value(long v) { 110 | ::zval::type = IS_LONG; 111 | ::zval::value.lval = v; 112 | initialize(); 113 | } 114 | 115 | value(double v) { 116 | ::zval::type = IS_DOUBLE; 117 | ::zval::value.dval = v; 118 | initialize(); 119 | } 120 | 121 | value(char const* v) { 122 | ::zval::type = IS_STRING; 123 | ::zval::value.str.len = ::strlen(v); 124 | ::zval::value.str.val = ::estrndup(v, ::zval::value.str.len); 125 | initialize(); 126 | } 127 | 128 | value(string const& v) { 129 | ::zval::type = IS_STRING; 130 | ::zval::value.str.val = ::estrndup(v, v.size()); 131 | ::zval::value.str.len = v.size(); 132 | initialize(); 133 | } 134 | 135 | value(::std::string const& v) { 136 | ::zval::type = IS_STRING; 137 | ::zval::value.str.len = v.size(); 138 | ::zval::value.str.val = ::estrndup(v.data(), v.size()); 139 | initialize(); 140 | } 141 | 142 | value(resource_handle const& v) { 143 | ::zval::type = IS_RESOURCE; 144 | ::zval::value.lval = v; 145 | initialize(); 146 | } 147 | 148 | value(zend_object_value const& v) { 149 | ::zval::type = IS_OBJECT; 150 | ::zval::value.obj = v; 151 | initialize(); 152 | } 153 | 154 | value(array const& v); 155 | 156 | value(array* v); 157 | 158 | ~value() { 159 | zval_dtor(static_cast(this)); 160 | } 161 | 162 | void swap(::zval& that) throw() { 163 | zval tmp; 164 | tmp = that; 165 | that = *static_cast< ::zval*>(this); 166 | *static_cast< ::zval*>(this) = tmp; 167 | } 168 | 169 | const enum typecode typecode() const { 170 | return static_cast(::zval::type); 171 | } 172 | 173 | const bool is_null() const { 174 | return ::zval::type == IS_NULL; 175 | } 176 | 177 | const value concat(zval const& rhs TSRMLS_DC) const; 178 | const value is_equal(zval const& rhs TSRMLS_DC) const; 179 | const value is_not_equal(::zval const& rhs TSRMLS_DC) const; 180 | value& increment(); 181 | value& decrement(); 182 | const value add(::zval const& rhs TSRMLS_DC) const; 183 | const value sub(::zval const& rhs TSRMLS_DC) const; 184 | const value mul(::zval const& rhs TSRMLS_DC) const; 185 | const value div(::zval const& rhs TSRMLS_DC) const; 186 | const value mod(::zval const& rhs TSRMLS_DC) const; 187 | const value bitwise_or(::zval const& rhs TSRMLS_DC) const; 188 | const value bitwise_and(::zval const& rhs TSRMLS_DC) const; 189 | const value bitwise_xor(::zval const& rhs TSRMLS_DC) const; 190 | const value shift_left(::zval const& rhs TSRMLS_DC) const; 191 | const value shift_right(::zval const& rhs TSRMLS_DC) const; 192 | const value is_smaller(::zval const& rhs TSRMLS_DC) const; 193 | const value is_greater_or_equal(::zval const& rhs TSRMLS_DC) const; 194 | const value is_smaller_or_equal(::zval const& rhs TSRMLS_DC) const; 195 | const value is_greater(::zval const& rhs TSRMLS_DC) const; 196 | const value is_identical(::zval const& rhs TSRMLS_DC) const; 197 | const value is_not_identical(::zval const& rhs TSRMLS_DC) const; 198 | #ifdef ZTS 199 | const value boolean_or(::zval const& rhs TSRMLS_DC = 0) const; 200 | const value boolean_and(::zval const& rhs TSRMLS_DC = 0) const; 201 | #else 202 | const value boolean_or(::zval const& rhs) const; 203 | const value boolean_and(::zval const& rhs) const; 204 | #endif 205 | const value boolean_not(TSRMLS_D) const; 206 | const value bitwise_not(TSRMLS_D) const; 207 | 208 | #ifdef ZTS 209 | const value concat(::zval const& rhs) const { 210 | return concat(rhs BOOST_PHP_TSRM_DIRECT_CC); 211 | } 212 | 213 | const value is_equal(::zval const& rhs) const { 214 | return is_equal(rhs BOOST_PHP_TSRM_DIRECT_CC); 215 | } 216 | 217 | const value is_not_equal(::zval const& rhs) const { 218 | return is_not_equal(rhs BOOST_PHP_TSRM_DIRECT_CC); 219 | } 220 | 221 | const value add(::zval const& rhs) const { 222 | return add(rhs BOOST_PHP_TSRM_DIRECT_CC); 223 | } 224 | 225 | const value mul(::zval const& rhs) const { 226 | return mul(rhs BOOST_PHP_TSRM_DIRECT_CC); 227 | } 228 | 229 | const value sub(::zval const& rhs) const { 230 | return sub(rhs BOOST_PHP_TSRM_DIRECT_CC); 231 | } 232 | 233 | const value div(::zval const& rhs) const { 234 | return div(rhs BOOST_PHP_TSRM_DIRECT_CC); 235 | } 236 | 237 | const value mod(::zval const& rhs) const { 238 | return mod(rhs BOOST_PHP_TSRM_DIRECT_CC); 239 | } 240 | 241 | const value bitwise_or(::zval const& rhs) const { 242 | return bitwise_or(rhs BOOST_PHP_TSRM_DIRECT_CC); 243 | } 244 | 245 | const value bitwise_and(::zval const& rhs) const { 246 | return bitwise_and(rhs BOOST_PHP_TSRM_DIRECT_CC); 247 | } 248 | 249 | const value bitwise_xor(::zval const& rhs) const { 250 | return bitwise_xor(rhs BOOST_PHP_TSRM_DIRECT_CC); 251 | } 252 | 253 | const value shift_right(::zval const& rhs) const { 254 | return shift_right(rhs BOOST_PHP_TSRM_DIRECT_CC); 255 | } 256 | 257 | const value shift_left(::zval const& rhs) const { 258 | return shift_left(rhs BOOST_PHP_TSRM_DIRECT_CC); 259 | } 260 | 261 | const value is_smaller(::zval const& rhs) const { 262 | return is_smaller(rhs BOOST_PHP_TSRM_DIRECT_CC); 263 | } 264 | 265 | const value is_greater_or_equal(::zval const& rhs) const { 266 | return is_greater_or_equal(rhs BOOST_PHP_TSRM_DIRECT_CC); 267 | } 268 | 269 | const value is_smaller_or_equal(::zval const& rhs) const { 270 | return is_smaller_or_equal(rhs BOOST_PHP_TSRM_DIRECT_CC); 271 | } 272 | 273 | const value is_greater(::zval const& rhs) const { 274 | return is_greater(rhs BOOST_PHP_TSRM_DIRECT_CC); 275 | } 276 | 277 | const value is_identical(::zval const& rhs) const { 278 | return is_identical(rhs BOOST_PHP_TSRM_DIRECT_CC); 279 | } 280 | 281 | const value is_not_identical(::zval const& rhs) const { 282 | return is_not_identical(rhs BOOST_PHP_TSRM_DIRECT_CC); 283 | } 284 | 285 | const value boolean_not() const { 286 | return boolean_not(BOOST_PHP_TSRM_DIRECT_C); 287 | } 288 | 289 | const value bitwise_not() const { 290 | return bitwise_not(BOOST_PHP_TSRM_DIRECT_C); 291 | } 292 | #endif /* ZTS */ 293 | 294 | value& operator++() { 295 | return increment(); 296 | } 297 | 298 | const value operator++(int) { 299 | value retval(*this); 300 | increment(); 301 | return retval; 302 | } 303 | 304 | value& operator--() { 305 | decrement(); 306 | return *this; 307 | } 308 | 309 | const value operator--(int) { 310 | value retval(*this); 311 | decrement(); 312 | return retval; 313 | } 314 | 315 | const value operator+(::zval const& rhs) const { 316 | return add(rhs); 317 | } 318 | 319 | const value operator-(::zval const& rhs) const { 320 | return sub(rhs); 321 | } 322 | 323 | const value operator*(::zval const& rhs) const { 324 | return mul(rhs); 325 | } 326 | 327 | const value operator/(::zval const& rhs) const { 328 | return div(rhs); 329 | } 330 | 331 | const value operator%(::zval const& rhs) const { 332 | return mod(rhs); 333 | } 334 | 335 | const value operator|(::zval const& rhs) const { 336 | return bitwise_or(rhs); 337 | } 338 | 339 | const value operator&(::zval const& rhs) const { 340 | return bitwise_and(rhs); 341 | } 342 | 343 | const value operator^(::zval const& rhs) const { 344 | return bitwise_xor(rhs); 345 | } 346 | 347 | const value operator<<(::zval const& rhs) const { 348 | return shift_left(rhs); 349 | } 350 | 351 | const value operator>>(::zval const& rhs) const { 352 | return shift_right(rhs); 353 | } 354 | 355 | const value operator<(::zval const& rhs) const { 356 | return is_smaller(rhs); 357 | } 358 | 359 | const value operator>=(::zval const& rhs) const { 360 | return is_greater_or_equal(rhs); 361 | } 362 | 363 | const value operator<=(::zval const& rhs) const { 364 | return is_smaller_or_equal(rhs); 365 | } 366 | 367 | const value operator>(::zval const& rhs) const { 368 | return is_greater(rhs); 369 | } 370 | 371 | const value operator==(::zval const& rhs) const { 372 | return is_identical(rhs); 373 | } 374 | 375 | const bool operator==(const bool& rhs) const { 376 | return type == _BOOL && !!::zval::value.lval == rhs; 377 | } 378 | 379 | const value operator!=(::zval const& rhs) const { 380 | return is_not_identical(rhs); 381 | } 382 | 383 | const bool operator!=(const bool& rhs) const { 384 | return type == _BOOL && !!::zval::value.lval != rhs; 385 | } 386 | 387 | const value operator||(::zval const& rhs) const { 388 | return boolean_or(rhs); 389 | } 390 | 391 | const value operator&&(::zval const& rhs) const { 392 | return boolean_and(rhs); 393 | } 394 | 395 | const value operator!() const { 396 | return boolean_not(); 397 | } 398 | 399 | const value operator~() const { 400 | return bitwise_not(); 401 | } 402 | 403 | operator string&(); 404 | 405 | operator const string&() const; 406 | 407 | operator array&(); 408 | 409 | operator const array&() const; 410 | 411 | operator ::std::string() const; 412 | 413 | operator resource_handle() const; 414 | 415 | operator long&(); 416 | 417 | operator long() const; 418 | 419 | operator double&(); 420 | 421 | operator double const&() const; 422 | 423 | operator ::zend_object_value const&() const; 424 | 425 | static const char* get_type_string(int t) { 426 | return get_type_string(static_cast(t)); 427 | } 428 | 429 | static const char* get_type_string(enum typecode t) { 430 | switch (t) { 431 | case _NULL: 432 | return "null"; 433 | case _LONG: 434 | return "integer"; 435 | case _DOUBLE: 436 | return "double"; 437 | case _BOOL: 438 | return "boolean"; 439 | case _ARRAY: 440 | return "array"; 441 | case _OBJECT: 442 | return "object"; 443 | case _STRING: 444 | return "string"; 445 | case _RESOURCE: 446 | return "resource"; 447 | } 448 | return "unknown"; 449 | } 450 | 451 | static void* operator new(::std::size_t sz) { 452 | zval* retval; 453 | ALLOC_ZVAL(retval); 454 | return operator new(sz, retval); 455 | } 456 | 457 | static void* operator new(::std::size_t sz, void *retval) { 458 | BOOST_ASSERT(sz == sizeof(zval)); 459 | return retval; 460 | } 461 | 462 | static void operator delete(void* p) { 463 | FREE_ZVAL(reinterpret_cast(p)); 464 | } 465 | 466 | private: 467 | void initialize() { 468 | INIT_PZVAL(this); 469 | } 470 | }; 471 | 472 | #endif /* BOOST_PHP_VALUE_DEFINED */ 473 | 474 | #ifndef BOOST_PHP_VALUE_PTR_DEFINED 475 | #define BOOST_PHP_VALUE_PTR_DEFINED 476 | class value_ptr { 477 | public: 478 | value_ptr(): p_(0) 479 | { 480 | TSRMLS_FETCH(); 481 | p_ = reinterpret_cast(&EG(uninitialized_zval)); 482 | BOOST_PHP_ZVAL_ADDREF(p_); 483 | } 484 | 485 | value_ptr(::zval* p): p_(static_cast(p)) { 486 | BOOST_PHP_ZVAL_ADDREF(p_); 487 | } 488 | 489 | value_ptr(::zval* p, bool add_ref): p_(static_cast(p)) { 490 | if (add_ref) { 491 | BOOST_PHP_ZVAL_ADDREF(p_); 492 | } 493 | } 494 | 495 | value_ptr(::zval*const* that): p_(static_cast(*that)) { 496 | BOOST_PHP_ZVAL_ASSERT_REFCOUNT(p_); 497 | BOOST_PHP_ZVAL_ADDREF(p_); 498 | } 499 | 500 | value_ptr(value_ptr const& that): p_(that.p_) { 501 | BOOST_PHP_ZVAL_ASSERT_REFCOUNT(p_); 502 | BOOST_PHP_ZVAL_ADDREF(p_); 503 | } 504 | 505 | ~value_ptr() { 506 | BOOST_PHP_ZVAL_ASSERT_REFCOUNT(p_); 507 | zval_ptr_dtor(reinterpret_cast(&p_)); 508 | } 509 | 510 | value_ptr& operator=(value_ptr const& rhs) { 511 | value_ptr(rhs).swap(*this); 512 | return *this; 513 | } 514 | 515 | void swap(value_ptr& that) { 516 | value* tmp( p_ ); 517 | p_ = that.p_, that.p_ = tmp; 518 | } 519 | 520 | value* get() const { 521 | return p_; 522 | } 523 | 524 | value& operator*() { 525 | SEPARATE_ZVAL_IF_NOT_REF(reinterpret_cast(&p_)); 526 | return *p_; 527 | } 528 | 529 | const value& operator*() const { 530 | return *p_; 531 | } 532 | 533 | value* operator->() { 534 | SEPARATE_ZVAL_IF_NOT_REF(reinterpret_cast(&p_)); 535 | return p_; 536 | } 537 | 538 | const value* operator->() const { 539 | return p_; 540 | } 541 | 542 | operator const value*() const { 543 | return p_; 544 | } 545 | 546 | operator bool() const { 547 | return p_; 548 | } 549 | 550 | bool operator!() const { 551 | return !p_; 552 | } 553 | 554 | template value_ptr const as() const; 555 | 556 | template value_ptr as(); 557 | protected: 558 | value* p_; 559 | }; 560 | 561 | } } // namespace boost::php 562 | 563 | #endif /* BOOST_PHP_VALUE_PTR_DEFINED */ 564 | 565 | #include 566 | #include 567 | 568 | #ifndef BOOST_PHP_VALUE_MEMBERS_DEFINED 569 | #define BOOST_PHP_VALUE_MEMBERS_DEFINED 570 | 571 | namespace boost { namespace php { 572 | 573 | typedef hashtable array; 574 | 575 | inline value::value(value_ptr const& that): ::zval(*that) { 576 | zval_copy_ctor(static_cast(this)); 577 | initialize(); 578 | } 579 | 580 | inline value::value(array const& that) { 581 | type = _ARRAY; 582 | ::zval::value.ht = const_cast(&that); 583 | zval_copy_ctor(this); 584 | initialize(); 585 | } 586 | 587 | inline value::value(array* that) { 588 | type = _ARRAY; 589 | ::zval::value.ht = that; 590 | initialize(); 591 | } 592 | 593 | inline value::value(::zval const& that, enum typecode desired_type): ::zval(that) { 594 | zval_copy_ctor(static_cast(this)); 595 | if (that.type != desired_type) { 596 | convert_to_explicit_type(this, desired_type); 597 | if (type != desired_type) { 598 | zval_dtor(this); 599 | throw type_error( 600 | ::std::string("could not convert ") 601 | + ::std::string(get_type_string( 602 | static_cast(that.type))) 603 | + " to " 604 | + ::std::string(get_type_string(desired_type))); 605 | } 606 | } 607 | initialize(); 608 | } 609 | 610 | inline value::value(int v) { 611 | if (v < ::std::numeric_limits::min() 612 | || v > ::std::numeric_limits::max()) { 613 | throw std::overflow_error( 614 | ::std::string("cannot cast ") 615 | + ::boost::lexical_cast< ::std::string>(v) + "to long"); 616 | } 617 | ::zval::type = IS_LONG; 618 | ::zval::value.lval = v; 619 | initialize(); 620 | } 621 | 622 | inline const value value::concat(::zval const& rhs TSRMLS_DC) const { 623 | value retval; 624 | BOOST_PHP_BEGIN_CAPTURE_ERROR 625 | if (FAILURE == concat_function(&retval, 626 | reinterpret_cast(const_cast(this)), 627 | const_cast(&rhs) TSRMLS_CC)) { 628 | throw arithmetic_error(BOOST_PHP_LAST_ERROR); 629 | } 630 | BOOST_PHP_END_CAPTURE_ERROR 631 | return retval; 632 | } 633 | 634 | inline const value value::is_equal(::zval const& rhs TSRMLS_DC) const { 635 | value retval; 636 | BOOST_PHP_BEGIN_CAPTURE_ERROR 637 | if (FAILURE == is_equal_function(&retval, 638 | reinterpret_cast(const_cast(this)), 639 | const_cast(&rhs) TSRMLS_CC)) { 640 | throw arithmetic_error(BOOST_PHP_LAST_ERROR); 641 | } 642 | BOOST_PHP_END_CAPTURE_ERROR 643 | return retval; 644 | } 645 | 646 | inline const value value::is_not_equal(::zval const& rhs TSRMLS_DC) const { 647 | value retval; 648 | BOOST_PHP_BEGIN_CAPTURE_ERROR 649 | if (FAILURE == is_not_equal_function(&retval, 650 | reinterpret_cast(const_cast(this)), 651 | const_cast(&rhs) TSRMLS_CC)) { 652 | throw arithmetic_error(BOOST_PHP_LAST_ERROR); 653 | } 654 | BOOST_PHP_END_CAPTURE_ERROR 655 | return retval; 656 | } 657 | 658 | inline value& value::increment() { 659 | BOOST_PHP_BEGIN_CAPTURE_ERROR 660 | if (FAILURE == increment_function(this)) { 661 | throw arithmetic_error(BOOST_PHP_LAST_ERROR); 662 | } 663 | BOOST_PHP_END_CAPTURE_ERROR 664 | return *this; 665 | } 666 | 667 | inline value& value::decrement() { 668 | BOOST_PHP_BEGIN_CAPTURE_ERROR 669 | if (FAILURE == decrement_function(this)) { 670 | throw arithmetic_error(BOOST_PHP_LAST_ERROR); 671 | } 672 | BOOST_PHP_END_CAPTURE_ERROR 673 | return *this; 674 | } 675 | 676 | inline const value value::add(::zval const& rhs TSRMLS_DC) const { 677 | value retval; 678 | BOOST_PHP_BEGIN_CAPTURE_ERROR 679 | if (FAILURE == add_function(&retval, 680 | reinterpret_cast(const_cast(this)), 681 | const_cast(&rhs) TSRMLS_CC)) { 682 | throw arithmetic_error(BOOST_PHP_LAST_ERROR); 683 | } 684 | BOOST_PHP_END_CAPTURE_ERROR 685 | return retval; 686 | } 687 | 688 | inline const value value::sub(::zval const& rhs TSRMLS_DC) const { 689 | value retval; 690 | BOOST_PHP_BEGIN_CAPTURE_ERROR 691 | if (FAILURE == sub_function(&retval, 692 | reinterpret_cast(const_cast(this)), 693 | const_cast(&rhs) TSRMLS_CC)) { 694 | throw arithmetic_error(BOOST_PHP_LAST_ERROR); 695 | } 696 | BOOST_PHP_END_CAPTURE_ERROR 697 | return retval; 698 | } 699 | 700 | inline const value value::mul(::zval const& rhs TSRMLS_DC) const { 701 | value retval; 702 | BOOST_PHP_BEGIN_CAPTURE_ERROR 703 | if (FAILURE == mul_function(&retval, 704 | reinterpret_cast(const_cast(this)), 705 | const_cast(&rhs) TSRMLS_CC)) { 706 | throw arithmetic_error(BOOST_PHP_LAST_ERROR); 707 | } 708 | BOOST_PHP_END_CAPTURE_ERROR 709 | return retval; 710 | } 711 | 712 | inline const value value::div(::zval const& rhs TSRMLS_DC) const { 713 | value retval; 714 | BOOST_PHP_BEGIN_CAPTURE_ERROR 715 | if (FAILURE == div_function(&retval, 716 | reinterpret_cast(const_cast(this)), 717 | const_cast(&rhs) TSRMLS_CC)) { 718 | throw arithmetic_error(BOOST_PHP_LAST_ERROR); 719 | } 720 | BOOST_PHP_END_CAPTURE_ERROR 721 | return retval; 722 | } 723 | 724 | inline const value value::mod(::zval const& rhs TSRMLS_DC) const { 725 | value retval; 726 | BOOST_PHP_BEGIN_CAPTURE_ERROR 727 | if (FAILURE == mod_function(&retval, 728 | reinterpret_cast(const_cast(this)), 729 | const_cast(&rhs) TSRMLS_CC)) { 730 | throw arithmetic_error(BOOST_PHP_LAST_ERROR); 731 | } 732 | BOOST_PHP_END_CAPTURE_ERROR 733 | return retval; 734 | } 735 | 736 | inline const value value::bitwise_or(::zval const& rhs TSRMLS_DC) const { 737 | value retval; 738 | BOOST_PHP_BEGIN_CAPTURE_ERROR 739 | if (FAILURE == bitwise_or_function(&retval, 740 | reinterpret_cast(const_cast(this)), 741 | const_cast(&rhs) TSRMLS_CC)) { 742 | throw arithmetic_error(BOOST_PHP_LAST_ERROR); 743 | } 744 | BOOST_PHP_END_CAPTURE_ERROR 745 | return retval; 746 | } 747 | 748 | inline const value value::bitwise_and(::zval const& rhs TSRMLS_DC) const { 749 | value retval; 750 | BOOST_PHP_BEGIN_CAPTURE_ERROR 751 | if (FAILURE == bitwise_and_function(&retval, 752 | reinterpret_cast(const_cast(this)), 753 | const_cast(&rhs) TSRMLS_CC)) { 754 | throw arithmetic_error(BOOST_PHP_LAST_ERROR); 755 | } 756 | BOOST_PHP_END_CAPTURE_ERROR 757 | return retval; 758 | } 759 | 760 | inline const value value::bitwise_xor(::zval const& rhs TSRMLS_DC) const { 761 | value retval; 762 | BOOST_PHP_BEGIN_CAPTURE_ERROR 763 | if (FAILURE == bitwise_xor_function(&retval, 764 | reinterpret_cast(const_cast(this)), 765 | const_cast(&rhs) TSRMLS_CC)) { 766 | throw arithmetic_error(BOOST_PHP_LAST_ERROR); 767 | } 768 | BOOST_PHP_END_CAPTURE_ERROR 769 | return retval; 770 | } 771 | 772 | inline const value value::shift_left(::zval const& rhs TSRMLS_DC) const { 773 | value retval; 774 | BOOST_PHP_BEGIN_CAPTURE_ERROR 775 | if (FAILURE == shift_left_function(&retval, 776 | reinterpret_cast(const_cast(this)), 777 | const_cast(&rhs) TSRMLS_CC)) { 778 | throw arithmetic_error(BOOST_PHP_LAST_ERROR); 779 | } 780 | BOOST_PHP_END_CAPTURE_ERROR 781 | return retval; 782 | } 783 | 784 | inline const value value::shift_right(::zval const& rhs TSRMLS_DC) const { 785 | value retval; 786 | BOOST_PHP_BEGIN_CAPTURE_ERROR 787 | if (FAILURE == shift_right_function(&retval, 788 | reinterpret_cast(const_cast(this)), 789 | const_cast(&rhs) TSRMLS_CC)) { 790 | throw arithmetic_error(BOOST_PHP_LAST_ERROR); 791 | } 792 | BOOST_PHP_END_CAPTURE_ERROR 793 | return retval; 794 | } 795 | 796 | inline const value value::is_smaller(::zval const& rhs TSRMLS_DC) const { 797 | value retval; 798 | BOOST_PHP_BEGIN_CAPTURE_ERROR 799 | if (FAILURE == is_smaller_function(&retval, 800 | reinterpret_cast(const_cast(this)), 801 | const_cast(&rhs) TSRMLS_CC)) { 802 | throw arithmetic_error(BOOST_PHP_LAST_ERROR); 803 | } 804 | BOOST_PHP_END_CAPTURE_ERROR 805 | return retval; 806 | } 807 | 808 | inline const value value::is_greater_or_equal(::zval const& rhs TSRMLS_DC) const { 809 | return is_smaller(rhs TSRMLS_CC).boolean_not(TSRMLS_C); 810 | } 811 | 812 | inline const value value::is_smaller_or_equal(::zval const& rhs TSRMLS_DC) const { 813 | value retval; 814 | BOOST_PHP_BEGIN_CAPTURE_ERROR 815 | if (FAILURE == is_smaller_or_equal_function(&retval, 816 | reinterpret_cast(const_cast(this)), 817 | const_cast(&rhs) TSRMLS_CC)) { 818 | throw arithmetic_error(BOOST_PHP_LAST_ERROR); 819 | } 820 | BOOST_PHP_END_CAPTURE_ERROR 821 | return retval; 822 | } 823 | 824 | inline const value value::is_greater(::zval const& rhs TSRMLS_DC) const { 825 | return is_smaller_or_equal(rhs TSRMLS_CC).boolean_not(TSRMLS_C); 826 | } 827 | 828 | inline const value value::is_identical(::zval const& rhs TSRMLS_DC) const { 829 | value retval; 830 | BOOST_PHP_BEGIN_CAPTURE_ERROR 831 | if (FAILURE == is_identical_function(&retval, 832 | reinterpret_cast(const_cast(this)), 833 | const_cast(&rhs) TSRMLS_CC)) { 834 | throw arithmetic_error(BOOST_PHP_LAST_ERROR); 835 | } 836 | BOOST_PHP_END_CAPTURE_ERROR 837 | return retval; 838 | } 839 | 840 | inline const value value::is_not_identical(::zval const& rhs TSRMLS_DC) const { 841 | value retval; 842 | BOOST_PHP_BEGIN_CAPTURE_ERROR 843 | if (FAILURE == is_not_identical_function(&retval, 844 | reinterpret_cast(const_cast(this)), 845 | const_cast(&rhs) TSRMLS_CC)) { 846 | throw arithmetic_error(BOOST_PHP_LAST_ERROR); 847 | } 848 | BOOST_PHP_END_CAPTURE_ERROR 849 | return retval; 850 | } 851 | 852 | inline const value value::boolean_or(::zval const& rhs TSRMLS_DC) const { 853 | return value(static_cast(zval_is_true( 854 | reinterpret_cast(const_cast(this))) || 855 | zval_is_true(const_cast(&rhs)))); 856 | } 857 | 858 | inline const value value::boolean_and(::zval const& rhs TSRMLS_DC) const { 859 | return value(static_cast(zval_is_true( 860 | reinterpret_cast(const_cast(this))) && 861 | zval_is_true(const_cast(&rhs)))); 862 | } 863 | 864 | inline const value value::boolean_not(TSRMLS_D) const { 865 | value retval; 866 | BOOST_PHP_BEGIN_CAPTURE_ERROR 867 | if (FAILURE == boolean_not_function(&retval, 868 | reinterpret_cast(const_cast(this)) 869 | TSRMLS_CC)) { 870 | throw arithmetic_error(BOOST_PHP_LAST_ERROR); 871 | } 872 | BOOST_PHP_END_CAPTURE_ERROR 873 | return retval; 874 | } 875 | 876 | inline const value value::bitwise_not(TSRMLS_D) const { 877 | value retval; 878 | BOOST_PHP_BEGIN_CAPTURE_ERROR 879 | if (FAILURE == bitwise_not_function(&retval, 880 | reinterpret_cast(const_cast(this)) 881 | TSRMLS_CC)) { 882 | throw arithmetic_error(BOOST_PHP_LAST_ERROR); 883 | } 884 | BOOST_PHP_END_CAPTURE_ERROR 885 | return retval; 886 | } 887 | 888 | inline value::operator string&() { 889 | if (::zval::type != _STRING) { 890 | throw type_error( 891 | ::std::string(get_type_string(::zval::type)) 892 | + " value cannot be cast to boost::php::string"); 893 | } 894 | return *reinterpret_cast(&::zval::value.str); 895 | } 896 | 897 | inline value::operator string const&() const { 898 | if (::zval::type != _STRING) { 899 | throw type_error( 900 | ::std::string(get_type_string(::zval::type)) 901 | + " value cannot be cast to boost::php::string"); 902 | } 903 | return *reinterpret_cast(&::zval::value.str); 904 | } 905 | 906 | inline value::operator ::std::string() const 907 | { 908 | if (::zval::type == _STRING) { 909 | return ::std::string(::zval::value.str.val, ::zval::value.str.len); 910 | } 911 | value tmp(*this, _STRING); 912 | return tmp; 913 | } 914 | 915 | inline value::operator array&() 916 | { 917 | if (::zval::type != _ARRAY) { 918 | throw type_error( 919 | ::std::string(get_type_string(::zval::type)) 920 | + " value cannot be cast to hashtable"); 921 | } 922 | return *reinterpret_cast(::zval::value.ht); 923 | } 924 | 925 | inline value::operator array const&() const 926 | { 927 | if (::zval::type != _ARRAY) { 928 | throw type_error( 929 | ::std::string(get_type_string(::zval::type)) 930 | + " value cannot be cast to hashtable"); 931 | } 932 | return *reinterpret_cast(::zval::value.ht); 933 | } 934 | 935 | inline value::operator resource_handle() const 936 | { 937 | if (::zval::type != _RESOURCE) { 938 | throw type_error( 939 | ::std::string(get_type_string(::zval::type)) 940 | + " value cannot be cast to resource"); 941 | } 942 | return resource_handle(::zval::value.lval); 943 | } 944 | 945 | inline value::operator long&() { 946 | if (::zval::type != _LONG) { 947 | throw type_error( 948 | ::std::string(get_type_string(::zval::type)) 949 | + " value cannot be cast to long"); 950 | } 951 | return ::zval::value.lval; 952 | } 953 | 954 | inline value::operator long() const { 955 | if (::zval::type != _LONG) { 956 | throw type_error( 957 | ::std::string(get_type_string(::zval::type)) 958 | + " value cannot be cast to long"); 959 | } 960 | return ::zval::value.lval; 961 | } 962 | 963 | inline value::operator double&() { 964 | if (::zval::type != _DOUBLE) { 965 | throw type_error( 966 | ::std::string(get_type_string(::zval::type)) 967 | + " value cannot be cast to double"); 968 | } 969 | return ::zval::value.dval; 970 | } 971 | 972 | inline value::operator double const&() const { 973 | if (::zval::type != _DOUBLE) { 974 | throw type_error( 975 | ::std::string(get_type_string(::zval::type)) 976 | + " value cannot be cast to double"); 977 | } 978 | return ::zval::value.dval; 979 | } 980 | 981 | inline value::operator ::zend_object_value const&() const 982 | { 983 | if (::zval::type != _OBJECT) { 984 | throw type_error( 985 | ::std::string(get_type_string(::zval::type)) 986 | + " value cannot be cast to object"); 987 | } 988 | return ::zval::value.obj; 989 | } 990 | 991 | } } // namespace boost::php 992 | 993 | #endif /* BOOST_PHP_VALUE_MEMBERS_DEFINED */ 994 | 995 | #ifndef BOOST_PHP_VALUE_PTR_MEMBER_DEFINED 996 | #define BOOST_PHP_VALUE_PTR_MEMBER_DEFINED 997 | 998 | namespace boost { namespace php { 999 | 1000 | template 1001 | inline value_ptr const value_ptr::as() const 1002 | { 1003 | if (static_cast(p_->type) == TYPE_) { 1004 | return *this; 1005 | } 1006 | return value_ptr(new value(*p_, TYPE_), false); 1007 | } 1008 | 1009 | template 1010 | inline value_ptr value_ptr::as() 1011 | { 1012 | if (static_cast(p_->type) != TYPE_) { 1013 | throw type_error(::std::string("write access to ") 1014 | + value::get_type_string(p_->type) 1015 | + " as " + value::get_type_string(TYPE_) 1016 | + " requested"); 1017 | } 1018 | return *this; 1019 | } 1020 | 1021 | } } // namespace boost::php 1022 | 1023 | #endif /* BOOST_PHP_VALUE_PTR_MEMBER_DEFINED */ 1024 | 1025 | #include 1026 | #include 1027 | --------------------------------------------------------------------------------