From: Michael Wallner Date: Tue, 19 Jan 2016 12:59:09 +0000 (+0100) Subject: Merge branch 'v1.0.x' X-Git-Tag: v2.0.0~5 X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-pq;a=commitdiff_plain;h=9e4e6b948aa03c04e66e808efa6a3522b92449d8;hp=0d8fc412a6fdd65f6bc89ae77b132ca119e00c6c Merge branch 'v1.0.x' --- diff --git a/.travis.yml b/.travis.yml index 130a777..e1f08d7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,34 +12,26 @@ env: global: - PQ_DSN="postgres://postgres@localhost/test" matrix: - - PHP=5.4 enable_debug=no enable_maintainer_zts=no enable_json=no enable_hash=yes - - PHP=5.5 enable_debug=no enable_maintainer_zts=no enable_json=no enable_hash=yes - - PHP=5.6 enable_debug=no enable_maintainer_zts=no enable_json=no enable_hash=yes - - PHP=5.4 enable_debug=yes enable_maintainer_zts=no enable_json=no enable_hash=yes - - PHP=5.5 enable_debug=yes enable_maintainer_zts=no enable_json=no enable_hash=yes - - PHP=5.6 enable_debug=yes enable_maintainer_zts=no enable_json=no enable_hash=yes - - PHP=5.4 enable_debug=no enable_maintainer_zts=yes enable_json=no enable_hash=yes - - PHP=5.5 enable_debug=no enable_maintainer_zts=yes enable_json=no enable_hash=yes - - PHP=5.6 enable_debug=no enable_maintainer_zts=yes enable_json=no enable_hash=yes - - PHP=5.4 enable_debug=yes enable_maintainer_zts=yes enable_json=no enable_hash=yes - - PHP=5.5 enable_debug=yes enable_maintainer_zts=yes enable_json=no enable_hash=yes - - PHP=5.6 enable_debug=yes enable_maintainer_zts=yes enable_json=no enable_hash=yes - - PHP=5.4 enable_debug=no enable_maintainer_zts=no enable_json=yes enable_hash=yes - - PHP=5.5 enable_debug=no enable_maintainer_zts=no enable_json=yes enable_hash=yes - - PHP=5.6 enable_debug=no enable_maintainer_zts=no enable_json=yes enable_hash=yes - - PHP=5.4 enable_debug=yes enable_maintainer_zts=no enable_json=yes enable_hash=yes - - PHP=5.5 enable_debug=yes enable_maintainer_zts=no enable_json=yes enable_hash=yes - - PHP=5.6 enable_debug=yes enable_maintainer_zts=no enable_json=yes enable_hash=yes - - PHP=5.4 enable_debug=no enable_maintainer_zts=yes enable_json=yes enable_hash=yes - - PHP=5.5 enable_debug=no enable_maintainer_zts=yes enable_json=yes enable_hash=yes - - PHP=5.6 enable_debug=no enable_maintainer_zts=yes enable_json=yes enable_hash=yes - - PHP=5.4 enable_debug=yes enable_maintainer_zts=yes enable_json=yes enable_hash=yes - - PHP=5.5 enable_debug=yes enable_maintainer_zts=yes enable_json=yes enable_hash=yes - - PHP=5.6 enable_debug=yes enable_maintainer_zts=yes enable_json=yes enable_hash=yes + - PHP=7.0 enable_debug=no enable_maintainer_zts=no enable_json=no enable_hash=yes enable_phar=yes enable_posix=yes + - PHP=master enable_debug=no enable_maintainer_zts=no enable_json=no enable_hash=yes enable_phar=yes enable_posix=yes + - PHP=7.0 enable_debug=yes enable_maintainer_zts=no enable_json=no enable_hash=yes enable_phar=yes enable_posix=yes + - PHP=master enable_debug=yes enable_maintainer_zts=no enable_json=no enable_hash=yes enable_phar=yes enable_posix=yes + - PHP=7.0 enable_debug=no enable_maintainer_zts=yes enable_json=no enable_hash=yes enable_phar=yes enable_posix=yes + - PHP=master enable_debug=no enable_maintainer_zts=yes enable_json=no enable_hash=yes enable_phar=yes enable_posix=yes + - PHP=7.0 enable_debug=yes enable_maintainer_zts=yes enable_json=no enable_hash=yes enable_phar=yes enable_posix=yes + - PHP=master enable_debug=yes enable_maintainer_zts=yes enable_json=no enable_hash=yes enable_phar=yes enable_posix=yes + - PHP=7.0 enable_debug=no enable_maintainer_zts=no enable_json=yes enable_hash=yes enable_phar=yes enable_posix=yes + - PHP=master enable_debug=no enable_maintainer_zts=no enable_json=yes enable_hash=yes enable_phar=yes enable_posix=yes + - PHP=7.0 enable_debug=yes enable_maintainer_zts=no enable_json=yes enable_hash=yes enable_phar=yes enable_posix=yes + - PHP=master enable_debug=yes enable_maintainer_zts=no enable_json=yes enable_hash=yes enable_phar=yes enable_posix=yes + - PHP=7.0 enable_debug=no enable_maintainer_zts=yes enable_json=yes enable_hash=yes enable_phar=yes enable_posix=yes + - PHP=master enable_debug=no enable_maintainer_zts=yes enable_json=yes enable_hash=yes enable_phar=yes enable_posix=yes + - PHP=7.0 enable_debug=yes enable_maintainer_zts=yes enable_json=yes enable_hash=yes enable_phar=yes enable_posix=yes + - PHP=master enable_debug=yes enable_maintainer_zts=yes enable_json=yes enable_hash=yes enable_phar=yes enable_posix=yes before_script: - make -f travis/pecl/Makefile php - - make -f travis/pecl/Makefile pecl PECL=raphf:raphf:1.1.2 + - make -f travis/pecl/Makefile pharext/raphf-master - make -f travis/pecl/Makefile ext PECL=pq - psql -U postgres -c "CREATE DATABASE test" diff --git a/README.md b/README.md index 38da65b..4c4a52c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # pecl/pq -[![Build Status](https://travis-ci.org/m6w6/ext-pq.svg?branch=v1.0.x)](https://travis-ci.org/m6w6/ext-pq) +[![Build Status](https://travis-ci.org/m6w6/ext-pq.svg?branch=master)](https://travis-ci.org/m6w6/ext-pq) ## About: diff --git a/gen_travis_yml.php b/gen_travis_yml.php index a96a338..2d28a22 100755 --- a/gen_travis_yml.php +++ b/gen_travis_yml.php @@ -17,11 +17,13 @@ env: $gen = include "./travis/pecl/gen-matrix.php"; $env = $gen([ - "PHP" => ["5.4", "5.5", "5.6"], + "PHP" => ["7.0", "master"], "enable_debug", "enable_maintainer_zts", "enable_json", "enable_hash" => ["yes"], + "enable_phar" => ["yes"], + "enable_posix" => ["yes"] ]); foreach ($env as $e) { printf(" - %s\n", $e); @@ -31,7 +33,7 @@ foreach ($env as $e) { before_script: - make -f travis/pecl/Makefile php - - make -f travis/pecl/Makefile pecl PECL=raphf:raphf:1.1.2 + - make -f travis/pecl/Makefile pecl PECL=raphf:raphf:2.0.0 - make -f travis/pecl/Makefile ext PECL=pq - psql -U postgres -c "CREATE DATABASE test" diff --git a/package.xml b/package.xml index 0b5fb18..abf67ed 100644 --- a/package.xml +++ b/package.xml @@ -35,18 +35,19 @@ daverandom@php.net yes - 2016-01-19 + 2015-12-04 - 1.0.1dev - 1.0.0 + 2.0.0dev + 2.0.0 - stable + beta stable BSD-2-Clause @@ -153,9 +154,7 @@ - 5.4.0 - 7.0.0 - 7.0.0 + 7.0.0 1.4.0 @@ -163,7 +162,7 @@ raphf pecl.php.net - 1.1.0 + 2.0.0dev raphf diff --git a/php_pq.h b/php_pq.h index 8fd0a11..cfdb095 100644 --- a/php_pq.h +++ b/php_pq.h @@ -14,7 +14,7 @@ #ifndef PHP_PQ_H #define PHP_PQ_H -#define PHP_PQ_VERSION "1.0.0dev" +#define PHP_PQ_VERSION "2.0.0dev" #ifdef PHP_WIN32 # define PHP_PQ_API __declspec(dllexport) @@ -28,14 +28,20 @@ extern int pq_module_number; extern zend_module_entry pq_module_entry; #define phpext_pq_ptr &pq_module_entry +ZEND_BEGIN_MODULE_GLOBALS(php_pq) + struct { + /* for ext-raphf */ + zend_string *name; + } connection; +ZEND_END_MODULE_GLOBALS(php_pq) + +ZEND_EXTERN_MODULE_GLOBALS(php_pq); #ifdef ZTS -# include "TSRM.h" -# define TSRMLS_DF(d) TSRMLS_D = (d)->ts -# define TSRMLS_CF(d) (d)->ts = TSRMLS_C +# include "TSRM/TSRM.h" +# define PHP_PQ_G ((zend_php_pq_globals *) (*((void ***) tsrm_get_ls_cache()))[TSRM_UNSHUFFLE_RSRC_ID(php_pq_globals_id)]) #else -# define TSRMLS_DF(d) -# define TSRMLS_CF(d) +# define PHP_PQ_G (&php_pq_globals) #endif #endif /* PHP_PQ_H */ diff --git a/raphf-1.1.2.ext.phar b/raphf-1.1.2.ext.phar deleted file mode 100755 index 0c5596c..0000000 --- a/raphf-1.1.2.ext.phar +++ /dev/null @@ -1,6405 +0,0 @@ -#!/usr/bin/env php -getUser(); - if (!is_dir($temp) && !mkdir($temp, 0700, true)) { - throw new Exception; - } - $this->name = $temp ."/". uniqid($prefix) . $suffix; - } - - private function getUser() { - if (extension_loaded("posix") && function_exists("posix_getpwuid")) { - return posix_getpwuid(posix_getuid())["name"]; - } - return trim(`whoami 2>/dev/null`) - ?: trim(`id -nu 2>/dev/null`) - ?: getenv("USER") - ?: get_current_user(); - } - - /** - * @return string - */ - public function __toString() { - return (string) $this->name; - } -} - - - -namespace pharext; - -/** - * Create a new temporary file - */ -class Tempfile extends \SplFileInfo -{ - /** - * @var resource - */ - private $handle; - - /** - * @param string $prefix uniqid() prefix - * @param string $suffix e.g. file extension - * @throws \pharext\Exception - */ - public function __construct($prefix, $suffix = ".tmp") { - $tries = 0; - $omask = umask(077); - do { - $path = new Tempname($prefix, $suffix); - $this->handle = fopen($path, "x"); - } while (!is_resource($this->handle) && $tries++ < 10); - umask($omask); - - if (!is_resource($this->handle)) { - throw new Exception("Could not create temporary file"); - } - - parent::__construct($path); - } - - /** - * Unlink the file - */ - public function __destruct() { - if (is_file($this->getPathname())) { - @unlink($this->getPathname()); - } - } - - /** - * Close the stream - */ - public function closeStream() { - fclose($this->handle); - } - - /** - * Retrieve the stream resource - * @return resource - */ - public function getStream() { - return $this->handle; - } -} - - - -namespace pharext; - -/** - * Create a temporary directory - */ -class Tempdir extends \SplFileInfo -{ - /** - * @param string $prefix prefix to uniqid() - * @throws \pharext\Exception - */ - public function __construct($prefix) { - $temp = new Tempname($prefix); - if (!is_dir($temp) && !mkdir($temp, 0700, true)) { - throw new Exception("Could not create tempdir: ".error_get_last()["message"]); - } - parent::__construct($temp); - } -} - - - -namespace pharext; - -use ArrayAccess; -use IteratorAggregate; -use RecursiveDirectoryIterator; -use SplFileInfo; - -use pharext\Exception; - -class Archive implements ArrayAccess, IteratorAggregate -{ - const HALT_COMPILER = "\137\137\150\141\154\164\137\143\157\155\160\151\154\145\162\50\51\73"; - const SIGNED = 0x10000; - const SIG_MD5 = 0x0001; - const SIG_SHA1 = 0x0002; - const SIG_SHA256 = 0x0003; - const SIG_SHA512 = 0x0004; - const SIG_OPENSSL= 0x0010; - - private static $siglen = [ - self::SIG_MD5 => 16, - self::SIG_SHA1 => 20, - self::SIG_SHA256 => 32, - self::SIG_SHA512 => 64, - self::SIG_OPENSSL=> 0 - ]; - - private static $sigalg = [ - self::SIG_MD5 => "md5", - self::SIG_SHA1 => "sha1", - self::SIG_SHA256 => "sha256", - self::SIG_SHA512 => "sha512", - self::SIG_OPENSSL=> "openssl" - ]; - - private static $sigtyp = [ - self::SIG_MD5 => "MD5", - self::SIG_SHA1 => "SHA-1", - self::SIG_SHA256 => "SHA-256", - self::SIG_SHA512 => "SHA-512", - self::SIG_OPENSSL=> "OpenSSL", - ]; - - const PERM_FILE_MASK = 0x01ff; - const COMP_FILE_MASK = 0xf000; - const COMP_GZ_FILE = 0x1000; - const COMP_BZ2_FILE = 0x2000; - - const COMP_PHAR_MASK= 0xf000; - const COMP_PHAR_GZ = 0x1000; - const COMP_PHAR_BZ2 = 0x2000; - - private $file; - private $fd; - private $stub; - private $manifest; - private $signature; - private $extracted; - - function __construct($file = null) { - if (strlen($file)) { - $this->open($file); - } - } - - function open($file) { - if (!$this->fd = @fopen($file, "r")) { - throw new Exception; - } - $this->file = $file; - $this->stub = $this->readStub(); - $this->manifest = $this->readManifest(); - $this->signature = $this->readSignature(); - } - - function getIterator() { - return new RecursiveDirectoryIterator($this->extract()); - } - - function extract() { - return $this->extracted ?: $this->extractTo(new Tempdir("archive")); - } - - function extractTo($dir) { - if ((string) $this->extracted == (string) $dir) { - return $this->extracted; - } - foreach ($this->manifest["entries"] as $file => $entry) { - fseek($this->fd, $this->manifest["offset"]+$entry["offset"]); - $path = "$dir/$file"; - $copy = stream_copy_to_stream($this->fd, $this->outFd($path, $entry["flags"]), $entry["csize"]); - if ($entry["osize"] != $copy) { - throw new Exception("Copied '$copy' of '$file', expected '{$entry["osize"]}' from '{$entry["csize"]}"); - } - - $crc = hexdec(hash_file("crc32b", $path)); - if ($crc !== $entry["crc32"]) { - throw new Exception("CRC mismatch of '$file': '$crc' != '{$entry["crc32"]}"); - } - - chmod($path, $entry["flags"] & self::PERM_FILE_MASK); - touch($path, $entry["stamp"]); - } - return $this->extracted = $dir; - } - - function offsetExists($o) { - return isset($this->entries[$o]); - } - - function offsetGet($o) { - $this->extract(); - return new SplFileInfo($this->extracted."/$o"); - } - - function offsetSet($o, $v) { - throw new Exception("Archive is read-only"); - } - - function offsetUnset($o) { - throw new Exception("Archive is read-only"); - } - - function getSignature() { - /* compatible with Phar::getSignature() */ - return [ - "hash_type" => self::$sigtyp[$this->signature["flags"]], - "hash" => strtoupper(bin2hex($this->signature["hash"])), - ]; - } - - function getPath() { - /* compatible with Phar::getPath() */ - return new SplFileInfo($this->file); - } - - function getMetadata($key = null) { - if (isset($key)) { - return $this->manifest["meta"][$key]; - } - return $this->manifest["meta"]; - } - - private function outFd($path, $flags) { - $dirn = dirname($path); - if (!is_dir($dirn) && !@mkdir($dirn, 0777, true)) { - throw new Exception; - } - if (!$fd = @fopen($path, "w")) { - throw new Exception; - } - switch ($flags & self::COMP_FILE_MASK) { - case self::COMP_GZ_FILE: - if (!@stream_filter_append($fd, "zlib.inflate")) { - throw new Exception; - } - break; - case self::COMP_BZ2_FILE: - if (!@stream_filter_append($fd, "bz2.decompress")) { - throw new Exception; - } - break; - } - - } - private function readVerified($fd, $len) { - if ($len != strlen($data = fread($fd, $len))) { - throw new Exception("Unexpected EOF"); - } - return $data; - } - - private function readFormat($format, $fd, $len) { - if (false === ($data = @unpack($format, $this->readVerified($fd, $len)))) { - throw new Exception; - } - return $data; - } - - private function readSingleFormat($format, $fd, $len) { - return current($this->readFormat($format, $fd, $len)); - } - - private function readStringBinary($fd) { - if (($length = $this->readSingleFormat("V", $fd, 4))) { - return $this->readVerified($this->fd, $length); - } - return null; - } - - private function readSerializedBinary($fd) { - if (($length = $this->readSingleFormat("V", $fd, 4))) { - if (false === ($data = unserialize($this->readVerified($fd, $length)))) { - throw new Exception; - } - return $data; - } - return null; - } - - private function readStub() { - $stub = ""; - while (!feof($this->fd)) { - $line = fgets($this->fd); - $stub .= $line; - if (false !== stripos($line, self::HALT_COMPILER)) { - /* check for '?>' on a separate line */ - if ('?>' === $this->readVerified($this->fd, 2)) { - $stub .= '?>' . fgets($this->fd); - } else { - fseek($this->fd, -2, SEEK_CUR); - } - break; - } - } - return $stub; - } - - private function readManifest() { - $current = ftell($this->fd); - $header = $this->readFormat("Vlen/Vnum/napi/Vflags", $this->fd, 14); - $alias = $this->readStringBinary($this->fd); - $meta = $this->readSerializedBinary($this->fd); - $entries = []; - for ($i = 0; $i < $header["num"]; ++$i) { - $this->readEntry($entries); - } - $offset = ftell($this->fd); - if (($length = $offset - $current - 4) != $header["len"]) { - throw new Exception("Manifest length read was '$length', expected '{$header["len"]}'"); - } - return $header + compact("alias", "meta", "entries", "offset"); - } - - private function readEntry(array &$entries) { - if (!count($entries)) { - $offset = 0; - } else { - $last = end($entries); - $offset = $last["offset"] + $last["csize"]; - } - $file = $this->readStringBinary($this->fd); - if (!strlen($file)) { - throw new Exception("Empty file name encountered at offset '$offset'"); - } - $header = $this->readFormat("Vosize/Vstamp/Vcsize/Vcrc32/Vflags", $this->fd, 20); - $meta = $this->readSerializedBinary($this->fd); - $entries[$file] = $header + compact("meta", "offset"); - } - - private function readSignature() { - fseek($this->fd, -8, SEEK_END); - $sig = $this->readFormat("Vflags/Z4magic", $this->fd, 8); - $end = ftell($this->fd); - - if ($sig["magic"] !== "GBMB") { - throw new Exception("Invalid signature magic value '{$sig["magic"]}"); - } - - switch ($sig["flags"]) { - case self::SIG_OPENSSL: - fseek($this->fd, -12, SEEK_END); - if (($hash = $this->readSingleFormat("V", $this->fd, 4))) { - $offset = 4 + $hash; - fseek($this->fd, -$offset, SEEK_CUR); - $hash = $this->readVerified($this->fd, $hash); - fseek($this->fd, 0, SEEK_SET); - $valid = openssl_verify($this->readVerified($this->fd, $end - $offset - 8), - $hash, @file_get_contents($this->file.".pubkey")) === 1; - } - break; - - case self::SIG_MD5: - case self::SIG_SHA1: - case self::SIG_SHA256: - case self::SIG_SHA512: - $offset = 8 + self::$siglen[$sig["flags"]]; - fseek($this->fd, -$offset, SEEK_END); - $hash = $this->readVerified($this->fd, self::$siglen[$sig["flags"]]); - $algo = hash_init(self::$sigalg[$sig["flags"]]); - fseek($this->fd, 0, SEEK_SET); - hash_update_stream($algo, $this->fd, $end - $offset); - $valid = hash_final($algo, true) === $hash; - break; - - default: - throw new Exception("Invalid signature type '{$sig["flags"]}"); - } - - return $sig + compact("hash", "valid"); - } -} - - -namespace pharext; - -if (extension_loaded("Phar")) { - \Phar::interceptFileFuncs(); - \Phar::mapPhar(); - $phardir = "phar://".__FILE__; -} else { - $archive = new Archive(__FILE__); - $phardir = $archive->extract(); -} - -set_include_path("$phardir:". get_include_path()); - -$installer = new Installer(); -$installer->run($argc, $argv); - -__HALT_COMPILER(); ?> -@(a:7:{s:7:"version";s:5:"4.1.1";s:6:"header";s:49:"pharext v4.1.1 (c) Michael Wallner ";s:4:"date";s:10:"2016-01-19";s:4:"name";s:5:"raphf";s:7:"release";s:5:"1.1.2";s:7:"license";s:1345:"Copyright (c) 2013, Michael Wallner . -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -";s:4:"type";s:9:"extension";}pharext/Archive.php5ïV4-ÔI¶pharext/Cli/Args/Help.phpÉ 5ïVÉ gX'¶pharext/Cli/Args.php5ïV?nö¶pharext/Cli/Command.phpk 5ïVk d„aê¶pharext/Command.php5ïVÔm`Ͷpharext/Exception.phpc5ïVcU†Ï{¶pharext/ExecCmd.php5ïV¹l”ʶpharext/Installer.php&5ïV&ød&À¶pharext/License.php“5ïV“îòE¶pharext/Metadata.php•5ïV•¿Úž¶pharext/Openssl/PrivateKey.phpÁ5ïVÁ&æP¶pharext/Packager.phpÌ!5ïVÌ!0<¶pharext/SourceDir/Basic.phpz5ïVz÷+Ôâ¶pharext/SourceDir/Git.phpZ5ïVZÉÎ\¶pharext/SourceDir/Pecl.phpø5ïVøãùжpharext/SourceDir.php½5ïV½3·#¶pharext/Task/Activate.phpÜ 5ïVÜ I“¶pharext/Task/Askpass.phpU5ïVU‡*¶ pharext/Task/BundleGenerator.php}5ïV} ï`Y¶pharext/Task/Cleanup.php5ïVÉI€B¶pharext/Task/Configure.phpT5ïVT}Ëì¶pharext/Task/Extract.phpp5ïVp[¨Û̶pharext/Task/GitClone.phpm5ïVmóyµ@¶pharext/Task/Make.phpª5ïVªœç6 ¶pharext/Task/PaxFixup.php¬5ïV¬y⯶pharext/Task/PeclFixup.phpœ5ïVœeùtš¶pharext/Task/PharBuild.phpâ5ïVâζ0ɶpharext/Task/PharCompress.phpc5ïVc½³Ï¶pharext/Task/PharRename.phpä5ïVäŠ[Þ˶pharext/Task/PharSign.php¨5ïV¨Ûº¦i¶pharext/Task/PharStub.phpæ5ïVæY|­›¶pharext/Task/Phpize.php5ïVù 2Ѷpharext/Task/StreamFetch.php5ïVˆîs\¶pharext/Task.phpw5ïVw ÄIǶpharext/Tempdir.phpµ5ïVµë–,¶pharext/Tempfile.php5ïV®ô¶pharext/Tempname.phpt5ïVtžn<¶pharext/Updater.php5ïVžÏv¶pharext_installer.phpÝ5ïVÝŒÞq¶pharext_packager.phpb5ïVbîVÓ϶pharext_updater.phph5ïVh Êúj¶pharext_package.php25ïV2vSTÒ¶ package.xmlX 5ïVX F}i(¶src/php_raphf_api.hX55ïVX53Ìä·¶src/php_raphf_api.cH5ïVH™Çꀶscripts/gen_travis_yml.phpî5ïVîø!_¶tests/http001.phpt5ïV *®¶tests/http002.phptL5ïVL€ÔïS¶tests/http003.phpt^5ïV^ˆp¶tests/http004.phpt[5ïV[Y諶AUTHORS5ïV\ÄH­¶BUGS*5ïV*<î¶CONTRIBUTING.mdŽ5ïVŽ¶Nq¶CREDITS5ïVCµ]²¶LICENSEA5ïVA¾¬Jþ¶ README.md5ïVab{ÿ¶THANKSd5ïVdÌD"å¶TODO5ïVy_÷E¶DoxyfileÓ,5ïVÓ,Mc¾Ü¶ config.m45ïVoêd”¶ -config0.m4å5ïVåÇ×Îb¶ -config.w32ò5ïVòL÷fO¶ Makefile.frag¾5ïV¾ݯõ¯¶ php_raphf.h5ïV´j¶ 16, - self::SIG_SHA1 => 20, - self::SIG_SHA256 => 32, - self::SIG_SHA512 => 64, - self::SIG_OPENSSL=> 0 - ]; - - private static $sigalg = [ - self::SIG_MD5 => "md5", - self::SIG_SHA1 => "sha1", - self::SIG_SHA256 => "sha256", - self::SIG_SHA512 => "sha512", - self::SIG_OPENSSL=> "openssl" - ]; - - private static $sigtyp = [ - self::SIG_MD5 => "MD5", - self::SIG_SHA1 => "SHA-1", - self::SIG_SHA256 => "SHA-256", - self::SIG_SHA512 => "SHA-512", - self::SIG_OPENSSL=> "OpenSSL", - ]; - - const PERM_FILE_MASK = 0x01ff; - const COMP_FILE_MASK = 0xf000; - const COMP_GZ_FILE = 0x1000; - const COMP_BZ2_FILE = 0x2000; - - const COMP_PHAR_MASK= 0xf000; - const COMP_PHAR_GZ = 0x1000; - const COMP_PHAR_BZ2 = 0x2000; - - private $file; - private $fd; - private $stub; - private $manifest; - private $signature; - private $extracted; - - function __construct($file = null) { - if (strlen($file)) { - $this->open($file); - } - } - - function open($file) { - if (!$this->fd = @fopen($file, "r")) { - throw new Exception; - } - $this->file = $file; - $this->stub = $this->readStub(); - $this->manifest = $this->readManifest(); - $this->signature = $this->readSignature(); - } - - function getIterator() { - return new RecursiveDirectoryIterator($this->extract()); - } - - function extract() { - return $this->extracted ?: $this->extractTo(new Tempdir("archive")); - } - - function extractTo($dir) { - if ((string) $this->extracted == (string) $dir) { - return $this->extracted; - } - foreach ($this->manifest["entries"] as $file => $entry) { - fseek($this->fd, $this->manifest["offset"]+$entry["offset"]); - $path = "$dir/$file"; - $copy = stream_copy_to_stream($this->fd, $this->outFd($path, $entry["flags"]), $entry["csize"]); - if ($entry["osize"] != $copy) { - throw new Exception("Copied '$copy' of '$file', expected '{$entry["osize"]}' from '{$entry["csize"]}"); - } - - $crc = hexdec(hash_file("crc32b", $path)); - if ($crc !== $entry["crc32"]) { - throw new Exception("CRC mismatch of '$file': '$crc' != '{$entry["crc32"]}"); - } - - chmod($path, $entry["flags"] & self::PERM_FILE_MASK); - touch($path, $entry["stamp"]); - } - return $this->extracted = $dir; - } - - function offsetExists($o) { - return isset($this->entries[$o]); - } - - function offsetGet($o) { - $this->extract(); - return new SplFileInfo($this->extracted."/$o"); - } - - function offsetSet($o, $v) { - throw new Exception("Archive is read-only"); - } - - function offsetUnset($o) { - throw new Exception("Archive is read-only"); - } - - function getSignature() { - /* compatible with Phar::getSignature() */ - return [ - "hash_type" => self::$sigtyp[$this->signature["flags"]], - "hash" => strtoupper(bin2hex($this->signature["hash"])), - ]; - } - - function getPath() { - /* compatible with Phar::getPath() */ - return new SplFileInfo($this->file); - } - - function getMetadata($key = null) { - if (isset($key)) { - return $this->manifest["meta"][$key]; - } - return $this->manifest["meta"]; - } - - private function outFd($path, $flags) { - $dirn = dirname($path); - if (!is_dir($dirn) && !@mkdir($dirn, 0777, true)) { - throw new Exception; - } - if (!$fd = @fopen($path, "w")) { - throw new Exception; - } - switch ($flags & self::COMP_FILE_MASK) { - case self::COMP_GZ_FILE: - if (!@stream_filter_append($fd, "zlib.inflate")) { - throw new Exception; - } - break; - case self::COMP_BZ2_FILE: - if (!@stream_filter_append($fd, "bz2.decompress")) { - throw new Exception; - } - break; - } - - } - private function readVerified($fd, $len) { - if ($len != strlen($data = fread($fd, $len))) { - throw new Exception("Unexpected EOF"); - } - return $data; - } - - private function readFormat($format, $fd, $len) { - if (false === ($data = @unpack($format, $this->readVerified($fd, $len)))) { - throw new Exception; - } - return $data; - } - - private function readSingleFormat($format, $fd, $len) { - return current($this->readFormat($format, $fd, $len)); - } - - private function readStringBinary($fd) { - if (($length = $this->readSingleFormat("V", $fd, 4))) { - return $this->readVerified($this->fd, $length); - } - return null; - } - - private function readSerializedBinary($fd) { - if (($length = $this->readSingleFormat("V", $fd, 4))) { - if (false === ($data = unserialize($this->readVerified($fd, $length)))) { - throw new Exception; - } - return $data; - } - return null; - } - - private function readStub() { - $stub = ""; - while (!feof($this->fd)) { - $line = fgets($this->fd); - $stub .= $line; - if (false !== stripos($line, self::HALT_COMPILER)) { - /* check for '?>' on a separate line */ - if ('?>' === $this->readVerified($this->fd, 2)) { - $stub .= '?>' . fgets($this->fd); - } else { - fseek($this->fd, -2, SEEK_CUR); - } - break; - } - } - return $stub; - } - - private function readManifest() { - $current = ftell($this->fd); - $header = $this->readFormat("Vlen/Vnum/napi/Vflags", $this->fd, 14); - $alias = $this->readStringBinary($this->fd); - $meta = $this->readSerializedBinary($this->fd); - $entries = []; - for ($i = 0; $i < $header["num"]; ++$i) { - $this->readEntry($entries); - } - $offset = ftell($this->fd); - if (($length = $offset - $current - 4) != $header["len"]) { - throw new Exception("Manifest length read was '$length', expected '{$header["len"]}'"); - } - return $header + compact("alias", "meta", "entries", "offset"); - } - - private function readEntry(array &$entries) { - if (!count($entries)) { - $offset = 0; - } else { - $last = end($entries); - $offset = $last["offset"] + $last["csize"]; - } - $file = $this->readStringBinary($this->fd); - if (!strlen($file)) { - throw new Exception("Empty file name encountered at offset '$offset'"); - } - $header = $this->readFormat("Vosize/Vstamp/Vcsize/Vcrc32/Vflags", $this->fd, 20); - $meta = $this->readSerializedBinary($this->fd); - $entries[$file] = $header + compact("meta", "offset"); - } - - private function readSignature() { - fseek($this->fd, -8, SEEK_END); - $sig = $this->readFormat("Vflags/Z4magic", $this->fd, 8); - $end = ftell($this->fd); - - if ($sig["magic"] !== "GBMB") { - throw new Exception("Invalid signature magic value '{$sig["magic"]}"); - } - - switch ($sig["flags"]) { - case self::SIG_OPENSSL: - fseek($this->fd, -12, SEEK_END); - if (($hash = $this->readSingleFormat("V", $this->fd, 4))) { - $offset = 4 + $hash; - fseek($this->fd, -$offset, SEEK_CUR); - $hash = $this->readVerified($this->fd, $hash); - fseek($this->fd, 0, SEEK_SET); - $valid = openssl_verify($this->readVerified($this->fd, $end - $offset - 8), - $hash, @file_get_contents($this->file.".pubkey")) === 1; - } - break; - - case self::SIG_MD5: - case self::SIG_SHA1: - case self::SIG_SHA256: - case self::SIG_SHA512: - $offset = 8 + self::$siglen[$sig["flags"]]; - fseek($this->fd, -$offset, SEEK_END); - $hash = $this->readVerified($this->fd, self::$siglen[$sig["flags"]]); - $algo = hash_init(self::$sigalg[$sig["flags"]]); - fseek($this->fd, 0, SEEK_SET); - hash_update_stream($algo, $this->fd, $end - $offset); - $valid = hash_final($algo, true) === $hash; - break; - - default: - throw new Exception("Invalid signature type '{$sig["flags"]}"); - } - - return $sig + compact("hash", "valid"); - } -} -prog = $prog; - $this->args = $args; - } - - function __toString() { - $usage = "Usage:\n\n \$ "; - $usage .= $this->prog; - - list($flags, $required, $optional, $positional) = $this->listSpec(); - if ($flags) { - $usage .= $this->dumpFlags($flags); - } - if ($required) { - $usage .= $this->dumpRequired($required); - } - if ($optional) { - $usage .= $this->dumpOptional($optional); - } - if ($positional) { - $usage .= $this->dumpPositional($positional); - } - - $help = $this->dumpHelp($positional); - - return $usage . "\n\n" . $help . "\n"; - } - - function listSpec() { - $flags = []; - $required = []; - $optional = []; - $positional = []; - foreach ($this->args->getSpec() as $spec) { - if (is_numeric($spec[0])) { - $positional[] = $spec; - } elseif ($spec[3] & Args::REQUIRED) { - $required[] = $spec; - } elseif ($spec[3] & (Args::OPTARG|Args::REQARG)) { - $optional[] = $spec; - } else { - $flags[] = $spec; - } - } - - return [$flags, $required, $optional, $positional] - + compact("flags", "required", "optional", "positional"); - } - - function dumpFlags(array $flags) { - return sprintf(" [-%s]", implode("", array_column($flags, 0))); - } - - function dumpRequired(array $required) { - $dump = ""; - foreach ($required as $req) { - $dump .= sprintf(" -%s <%s>", $req[0], $req[1]); - } - return $dump; - } - - function dumpOptional(array $optional) { - $req = array_filter($optional, function($a) { - return $a[3] & Args::REQARG; - }); - $opt = array_filter($optional, function($a) { - return $a[3] & Args::OPTARG; - }); - - $dump = ""; - if ($req) { - $dump .= sprintf(" [-%s ]", implode("|-", array_column($req, 0))); - } - if ($opt) { - $dump .= sprintf(" [-%s []]", implode("|-", array_column($opt, 0))); - } - return $dump; - } - - function dumpPositional(array $positional) { - $dump = " [--]"; - foreach ($positional as $pos) { - if ($pos[3] & Args::REQUIRED) { - $dump .= sprintf(" <%s>", $pos[1]); - } else { - $dump .= sprintf(" [<%s>]", $pos[1]); - } - if ($pos[3] & Args::MULTI) { - $dump .= sprintf(" [<%s>]...", $pos[1]); - } - } - return $dump; - } - - function calcMaxLen() { - $spc = $this->args->getSpec(); - $max = max(array_map("strlen", array_column($spc, 1))); - $max += $max % 8 + 2; - return $max; - } - - function dumpHelp() { - $max = $this->calcMaxLen(); - $dump = ""; - foreach ($this->args->getSpec() as $spec) { - $dump .= " "; - if (is_numeric($spec[0])) { - $dump .= sprintf("-- %s ", $spec[1]); - } elseif (isset($spec[0])) { - $dump .= sprintf("-%s|", $spec[0]); - } - if (!is_numeric($spec[0])) { - $dump .= sprintf("--%s ", $spec[1]); - } - if ($spec[3] & Args::REQARG) { - $dump .= " "; - } elseif ($spec[3] & Args::OPTARG) { - $dump .= "[]"; - } else { - $dump .= " "; - } - - $dump .= str_repeat(" ", $max-strlen($spec[1])+3*!isset($spec[0])); - $dump .= $spec[2]; - - if ($spec[3] & Args::REQUIRED) { - $dump .= " (REQUIRED)"; - } - if ($spec[3] & Args::MULTI) { - $dump .= " (MULTIPLE)"; - } - if (isset($spec[4])) { - $dump .= sprintf(" [%s]", $spec[4]); - } - $dump .= "\n"; - } - return $dump; - } -} -compile($spec); - } - - } - - /** - * Compile the original spec - * @param array|Traversable $spec - * @return pharext\Cli\Args self - */ - public function compile($spec) { - foreach ($spec as $arg) { - if (isset($arg[0]) && is_numeric($arg[0])) { - $arg[3] &= ~0xf00; - $this->spec["--".$arg[0]] = $arg; - } elseif (isset($arg[0])) { - $this->spec["-".$arg[0]] = $arg; - $this->spec["--".$arg[1]] = $arg; - } else { - $this->spec["--".$arg[1]] = $arg; - } - $this->orig[] = $arg; - } - return $this; - } - - /** - * Get original spec - * @return array - */ - public function getSpec() { - return $this->orig; - } - - /** - * Get compiled spec - * @return array - */ - public function getCompiledSpec() { - return $this->spec; - } - - /** - * Parse command line arguments according to the compiled spec. - * - * The Generator yields any parsing errors. - * Parsing will stop when all arguments are processed or the first option - * flagged Cli\Args::HALT was encountered. - * - * @param int $argc - * @param array $argv - * @return Generator - */ - public function parse($argc, array $argv) { - for ($f = false, $p = 0, $i = 0; $i < $argc; ++$i) { - $o = $argv[$i]; - - if ($o{0} === "-" && strlen($o) > 2 && $o{1} !== "-") { - // multiple short opts, e.g. -vps - $argc += strlen($o) - 2; - array_splice($argv, $i, 1, array_map(function($s) { - return "-$s"; - }, str_split(substr($o, 1)))); - $o = $argv[$i]; - } elseif ($o{0} === "-" && strlen($o) > 2 && $o{1} === "-" && 0 < ($eq = strpos($o, "="))) { - // long opt with argument, e.g. --foo=bar - $argc++; - array_splice($argv, $i, 1, [ - substr($o, 0, $eq++), - substr($o, $eq) - ]); - $o = $argv[$i]; - } elseif ($o === "--") { - // only positional args following - $f = true; - continue; - } - - if ($f || !isset($this->spec[$o])) { - if ($o{0} !== "-" && isset($this->spec["--$p"])) { - $this[$p] = $o; - if (!$this->optIsMulti($p)) { - ++$p; - } - } else { - yield sprintf("Unknown option %s", $o); - } - } elseif (!$this->optAcceptsArg($o)) { - $this[$o] = true; - } elseif ($i+1 < $argc && !isset($this->spec[$argv[$i+1]])) { - $this[$o] = $argv[++$i]; - } elseif ($this->optRequiresArg($o)) { - yield sprintf("Option --%s requires an argument", $this->optLongName($o)); - } else { - // OPTARG - $this[$o] = $this->optDefaultArg($o); - } - - if ($this->optHalts($o)) { - return; - } - } - } - - /** - * Validate that all required options were given. - * - * The Generator yields any validation errors. - * - * @return Generator - */ - public function validate() { - $required = array_filter($this->orig, function($spec) { - return $spec[3] & self::REQUIRED; - }); - foreach ($required as $req) { - if ($req[3] & self::MULTI) { - if (is_array($this[$req[0]])) { - continue; - } - } elseif (strlen($this[$req[0]])) { - continue; - } - if (is_numeric($req[0])) { - yield sprintf("Argument <%s> is required", $req[1]); - } else { - yield sprintf("Option --%s is required", $req[1]); - } - } - } - - - public function toArray() { - $args = []; - foreach ($this->spec as $spec) { - $opt = $this->opt($spec[1]); - $args[$opt] = $this[$opt]; - } - return $args; - } - - /** - * Retreive the default argument of an option - * @param string $o - * @return mixed - */ - private function optDefaultArg($o) { - $o = $this->opt($o); - if (isset($this->spec[$o][4])) { - return $this->spec[$o][4]; - } - return null; - } - - /** - * Retrieve the help message of an option - * @param string $o - * @return string - */ - private function optHelp($o) { - $o = $this->opt($o); - if (isset($this->spec[$o][2])) { - return $this->spec[$o][2]; - } - return ""; - } - - /** - * Retrieve option's flags - * @param string $o - * @return int - */ - private function optFlags($o) { - $o = $this->opt($o); - if (isset($this->spec[$o])) { - return $this->spec[$o][3]; - } - return null; - } - - /** - * Check whether an option is flagged for halting argument processing - * @param string $o - * @return boolean - */ - private function optHalts($o) { - return $this->optFlags($o) & self::HALT; - } - - /** - * Check whether an option needs an argument - * @param string $o - * @return boolean - */ - private function optRequiresArg($o) { - return $this->optFlags($o) & self::REQARG; - } - - /** - * Check wether an option accepts any argument - * @param string $o - * @return boolean - */ - private function optAcceptsArg($o) { - return $this->optFlags($o) & 0xf00; - } - - /** - * Check whether an option can be used more than once - * @param string $o - * @return boolean - */ - private function optIsMulti($o) { - return $this->optFlags($o) & self::MULTI; - } - - /** - * Retreive the long name of an option - * @param string $o - * @return string - */ - private function optLongName($o) { - $o = $this->opt($o); - return is_numeric($this->spec[$o][0]) ? $this->spec[$o][0] : $this->spec[$o][1]; - } - - /** - * Retreive the short name of an option - * @param string $o - * @return string - */ - private function optShortName($o) { - $o = $this->opt($o); - return is_numeric($this->spec[$o][0]) ? null : $this->spec[$o][0]; - } - - /** - * Retreive the canonical name (--long-name) of an option - * @param string $o - * @return string - */ - private function opt($o) { - if (is_numeric($o)) { - return "--$o"; - } - if ($o{0} !== '-') { - if (strlen($o) > 1) { - $o = "-$o"; - } - $o = "-$o"; - } - return $o; - } - - /**@+ - * Implements ArrayAccess and virtual properties - */ - function offsetExists($o) { - $o = $this->opt($o); - return isset($this->args[$o]); - } - function __isset($o) { - return $this->offsetExists($o); - } - function offsetGet($o) { - $o = $this->opt($o); - if (isset($this->args[$o])) { - return $this->args[$o]; - } - return $this->optDefaultArg($o); - } - function __get($o) { - return $this->offsetGet($o); - } - function offsetSet($o, $v) { - $osn = $this->optShortName($o); - $oln = $this->optLongName($o); - if ($this->optIsMulti($o)) { - if (isset($osn)) { - $this->args["-$osn"][] = $v; - } - $this->args["--$oln"][] = $v; - } else { - if (isset($osn)) { - $this->args["-$osn"] = $v; - } - $this->args["--$oln"] = $v; - } - } - function __set($o, $v) { - $this->offsetSet($o, $v); - } - function offsetUnset($o) { - unset($this->args["-".$this->optShortName($o)]); - unset($this->args["--".$this->optLongName($o)]); - } - function __unset($o) { - $this->offsetUnset($o); - } - /**@-*/ -} -args; - } - - /** - * Retrieve metadata of the currently running phar - * @param string $key - * @return mixed - */ - public function metadata($key = null) { - if (extension_loaded("Phar")) { - $running = new Phar(Phar::running(false)); - } else { - $running = new Archive(PHAREXT_PHAR); - } - - if ($key === "signature") { - $sig = $running->getSignature(); - return sprintf("%s signature of %s\n%s", - $sig["hash_type"], - $this->metadata("name"), - chunk_split($sig["hash"], 64, "\n")); - } - - $metadata = $running->getMetadata(); - if (isset($key)) { - return $metadata[$key]; - } - return $metadata; - } - - /** - * Output pharext vX.Y.Z header - */ - public function header() { - if (!headers_sent()) { - /* only display header, if we didn't generate any output yet */ - printf("%s\n\n", $this->metadata("header")); - } - } - - /** - * @inheritdoc - * @see \pharext\Command::debug() - */ - public function debug($fmt) { - if ($this->args->verbose) { - vprintf($fmt, array_slice(func_get_args(), 1)); - } - } - - /** - * @inheritdoc - * @see \pharext\Command::info() - */ - public function info($fmt) { - if (!$this->args->quiet) { - vprintf($fmt, array_slice(func_get_args(), 1)); - } - } - - /** - * @inheritdoc - * @see \pharext\Command::warn() - */ - public function warn($fmt) { - if (!$this->args->quiet) { - if (!isset($fmt)) { - $fmt = "%s\n"; - $arg = error_get_last()["message"]; - } else { - $arg = array_slice(func_get_args(), 1); - } - vfprintf(STDERR, "Warning: $fmt", $arg); - } - } - - /** - * @inheritdoc - * @see \pharext\Command::error() - */ - public function error($fmt) { - if (!isset($fmt)) { - $fmt = "%s\n"; - $arg = error_get_last()["message"]; - } else { - $arg = array_slice(func_get_args(), 1); - } - vfprintf(STDERR, "ERROR: $fmt", $arg); - } - - /** - * Output command line help message - * @param string $prog - */ - public function help($prog) { - print new Args\Help($prog, $this->args); - } - - /** - * Verbosity - * @return boolean - */ - public function verbosity() { - if ($this->args->verbose) { - return true; - } elseif ($this->args->quiet) { - return false; - } else { - return null; - } - } -} -command = $command; - $this->verbose = $verbose; - } - - /** - * (Re-)set sudo command - * @param string $sudo - */ - public function setSu($sudo = false) { - $this->sudo = $sudo; - } - - /** - * Execute a program with escalated privileges handling interactive password prompt - * @param string $command - * @param bool $verbose - * @return int exit status - */ - private function suExec($command, $verbose = null) { - if (!($proc = proc_open($command, [STDIN,["pipe","w"],["pipe","w"]], $pipes))) { - $this->status = -1; - throw new Exception("Failed to run {$command}"); - } - - $stdout = $pipes[1]; - $passwd = 0; - $checks = 10; - - while (!feof($stdout)) { - $R = [$stdout]; $W = []; $E = []; - if (!stream_select($R, $W, $E, null)) { - continue; - } - $data = fread($stdout, 0x1000); - /* only check a few times */ - if ($passwd < $checks) { - $passwd++; - if (stristr($data, "password")) { - $passwd = $checks + 1; - printf("\n%s", $data); - continue; - } - } elseif ($passwd > $checks) { - /* new line after pw entry */ - printf("\n"); - $passwd = $checks; - } - - if ($verbose === null) { - print $this->progress($data, 0); - } else { - if ($verbose) { - printf("%s", $data); - } - $this->output .= $data; - } - } - if ($verbose === null) { - $this->progress("", PHP_OUTPUT_HANDLER_FINAL); - } - return $this->status = proc_close($proc); - } - - /** - * Output handler that displays some progress while soaking output - * @param string $string - * @param int $flags - * @return string - */ - private function progress($string, $flags) { - static $counter = 0; - static $symbols = ["\\","|","/","-"]; - - $this->output .= $string; - - if (false !== strpos($string, "\n")) { - ++$counter; - } - - return $flags & PHP_OUTPUT_HANDLER_FINAL - ? " \r" - : sprintf(" %s\r", $symbols[$counter % 4]); - } - - /** - * Run the command - * @param array $args - * @return \pharext\ExecCmd self - * @throws \pharext\Exception - */ - public function run(array $args = null) { - $exec = escapeshellcmd($this->command); - if ($args) { - $exec .= " ". implode(" ", array_map("escapeshellarg", (array) $args)); - } - - if ($this->sudo) { - $this->suExec(sprintf($this->sudo." 2>&1", $exec), $this->verbose); - } elseif ($this->verbose) { - ob_start(function($s) { - $this->output .= $s; - return $s; - }, 1); - passthru($exec, $this->status); - ob_end_flush(); - } elseif ($this->verbose !== false /* !quiet */) { - ob_start([$this, "progress"], 1); - passthru($exec . " 2>&1", $this->status); - ob_end_flush(); - } else { - exec($exec ." 2>&1", $output, $this->status); - $this->output = implode("\n", $output); - } - - if ($this->status) { - throw new Exception("Command {$exec} failed ({$this->status})"); - } - - return $this; - } - - /** - * Retrieve exit code of cmd run - * @return int - */ - public function getStatus() { - return $this->status; - } - - /** - * Retrieve output of cmd run - * @return string - */ - public function getOutput() { - return $this->output; - } -} -args = new Cli\Args([ - ["h", "help", "Display help", - Cli\Args::OPTIONAL|Cli\Args::SINGLE|Cli\Args::NOARG|Cli\Args::HALT], - ["v", "verbose", "More output", - Cli\Args::OPTIONAL|Cli\Args::SINGLE|Cli\Args::NOARG], - ["q", "quiet", "Less output", - Cli\Args::OPTIONAL|Cli\Args::SINGLE|Cli\Args::NOARG], - ["p", "prefix", "PHP installation prefix if phpize is not in \$PATH, e.g. /opt/php7", - Cli\Args::OPTIONAL|Cli\Args::SINGLE|Cli\Args::REQARG], - ["n", "common-name", "PHP common program name, e.g. php5 or zts-php", - Cli\Args::OPTIONAL|Cli\Args::SINGLE|Cli\Args::REQARG, - "php"], - ["c", "configure", "Additional extension configure flags, e.g. -c --with-flag", - Cli\Args::OPTIONAL|Cli\Args::MULTI|Cli\Args::REQARG], - ["s", "sudo", "Installation might need increased privileges", - Cli\Args::OPTIONAL|Cli\Args::SINGLE|Cli\Args::OPTARG, - "sudo -S %s"], - ["i", "ini", "Activate in this php.ini instead of loaded default php.ini", - Cli\Args::OPTIONAL|Cli\Args::SINGLE|Cli\Args::REQARG], - [null, "signature", "Show package signature", - Cli\Args::OPTIONAL|Cli\Args::SINGLE|Cli\Args::NOARG|Cli\Args::HALT], - [null, "license", "Show package license", - Cli\Args::OPTIONAL|Cli\Args::SINGLE|Cli\Args::NOARG|Cli\Args::HALT], - [null, "name", "Show package name", - Cli\Args::OPTIONAL|Cli\Args::SINGLE|Cli\Args::NOARG|Cli\Args::HALT], - [null, "date", "Show package release date", - Cli\Args::OPTIONAL|Cli\Args::SINGLE|Cli\Args::NOARG|Cli\Args::HALT], - [null, "release", "Show package release version", - Cli\Args::OPTIONAL|Cli\Args::SINGLE|Cli\Args::NOARG|Cli\Args::HALT], - [null, "version", "Show pharext version", - Cli\Args::OPTIONAL|Cli\Args::SINGLE|Cli\Args::NOARG|Cli\Args::HALT], - ]); - } - - /** - * Perform cleaniup - */ - function __destruct() { - foreach ($this->cleanup as $cleanup) { - $cleanup->run(); - } - } - - private function extract($phar) { - $temp = (new Task\Extract($phar))->run($this->verbosity()); - $this->cleanup[] = new Task\Cleanup($temp); - return $temp; - } - - private function hooks(SplObjectStorage $phars) { - $hook = []; - foreach ($phars as $phar) { - if (isset($phar["pharext_package.php"])) { - $sdir = include $phar["pharext_package.php"]; - if ($sdir instanceof SourceDir) { - $this->args->compile($sdir->getArgs()); - $hook[] = $sdir; - } - } - } - return $hook; - } - - private function load() { - $list = new SplObjectStorage(); - $phar = extension_loaded("Phar") - ? new Phar(Phar::running(false)) - : new Archive(PHAREXT_PHAR); - $temp = $this->extract($phar); - - foreach ($phar as $entry) { - $dep_file = $entry->getBaseName(); - if (fnmatch("*.ext.phar*", $dep_file)) { - $dep_phar = extension_loaded("Phar") - ? new Phar("$temp/$dep_file") - : new Archive("$temp/$dep_file"); - $list[$dep_phar] = $this->extract($dep_phar); - } - } - - /* the actual ext.phar at last */ - $list[$phar] = $temp; - return $list; - } - - /** - * @inheritdoc - * @see \pharext\Command::run() - */ - public function run($argc, array $argv) { - try { - /* load the phar(s) */ - $list = $this->load(); - /* installer hooks */ - $hook = $this->hooks($list); - } catch (\Exception $e) { - $this->error("%s\n", $e->getMessage()); - exit(self::EEXTRACT); - } - - /* standard arg stuff */ - $errs = []; - $prog = array_shift($argv); - foreach ($this->args->parse(--$argc, $argv) as $error) { - $errs[] = $error; - } - - if ($this->args["help"]) { - $this->header(); - $this->help($prog); - exit; - } - try { - foreach (["signature", "name", "date", "license", "release", "version"] as $opt) { - if ($this->args[$opt]) { - printf("%s\n", $this->metadata($opt)); - exit; - } - } - } catch (\Exception $e) { - $this->error("%s\n", $e->getMessage()); - exit(self::EARGS); - } - - foreach ($this->args->validate() as $error) { - $errs[] = $error; - } - - if ($errs) { - if (!$this->args["quiet"]) { - $this->header(); - } - foreach ($errs as $err) { - $this->error("%s\n", $err); - } - if (!$this->args["quiet"]) { - $this->help($prog); - } - exit(self::EARGS); - } - - try { - /* post process hooks */ - foreach ($hook as $sdir) { - $sdir->setArgs($this->args); - } - } catch (\Exception $e) { - $this->error("%s\n", $e->getMessage()); - exit(self::EARGS); - } - - /* install packages */ - try { - foreach ($list as $phar) { - $this->info("Installing %s ...\n", basename($phar->getPath())); - $this->install($list[$phar]); - $this->activate($list[$phar]); - $this->info("Successfully installed %s!\n", basename($phar->getPath())); - } - } catch (\Exception $e) { - $this->error("%s\n", $e->getMessage()); - exit(self::EINSTALL); - } - } - - /** - * Phpize + trinity - */ - private function install($temp) { - // phpize - $phpize = new Task\Phpize($temp, $this->args->prefix, $this->args->{"common-name"}); - $phpize->run($this->verbosity()); - - // configure - $configure = new Task\Configure($temp, $this->args->configure, $this->args->prefix, $this->args->{"common-name"}); - $configure->run($this->verbosity()); - - // make - $make = new Task\Make($temp); - $make->run($this->verbosity()); - - // install - $sudo = isset($this->args->sudo) ? $this->args->sudo : null; - $install = new Task\Make($temp, ["install"], $sudo); - $install->run($this->verbosity()); - } - - private function activate($temp) { - if ($this->args->ini) { - $files = [$this->args->ini]; - } else { - $files = array_filter(array_map("trim", explode(",", php_ini_scanned_files()))); - $files[] = php_ini_loaded_file(); - } - - $sudo = isset($this->args->sudo) ? $this->args->sudo : null; - $type = $this->metadata("type") ?: "extension"; - - $activate = new Task\Activate($temp, $files, $type, $this->args->prefix, $this->args{"common-name"}, $sudo); - if (!$activate->run($this->verbosity())) { - $this->info("Extension already activated ...\n"); - } - } -} -mergeLicensePattern($name, strtolower($name)); - } - $exts = []; - foreach (["t{,e}xt", "rst", "asc{,i,ii}", "m{,ark}d{,own}", "htm{,l}"] as $ext) { - $exts[] = $this->mergeLicensePattern(strtoupper($ext), $ext); - } - - $pattern = "{". implode(",", $names) ."}{,.{". implode(",", $exts) ."}}"; - - if (($glob = glob("$dir/$pattern", GLOB_BRACE))) { - return current($glob); - } - } - - private function mergeLicensePattern($upper, $lower) { - $pattern = ""; - $length = strlen($upper); - for ($i = 0; $i < $length; ++$i) { - if ($lower{$i} === $upper{$i}) { - $pattern .= $upper{$i}; - } else { - $pattern .= "[" . $upper{$i} . $lower{$i} . "]"; - } - } - return $pattern; - } - - public function readLicense($file) { - $text = file_get_contents($file); - switch (strtolower(pathinfo($file, PATHINFO_EXTENSION))) { - case "htm": - case "html": - $text = strip_tags($text); - break; - } - return $text; - } -} -", self::version()); - } - - static function date() { - return gmdate("Y-m-d"); - } - - static function all() { - return [ - "version" => self::version(), - "header" => self::header(), - "date" => self::date(), - ]; - } -} -key); - $this->pub = openssl_pkey_get_details($key)["key"]; - } - - /** - * Sign the PHAR - * @param \Phar $package - */ - function sign(\Phar $package) { - $package->setSignatureAlgorithm(\Phar::OPENSSL, $this->key); - } - - /** - * Export the public key to a file - * @param string $file - * @throws \pharext\Exception - */ - function exportPublicKey($file) { - if (!file_put_contents("$file.tmp", $this->pub) || !rename("$file.tmp", $file)) { - throw new Exception; - } - } -} -args = new Cli\Args([ - ["h", "help", "Display this help", - Cli\Args::OPTIONAL|Cli\Args::SINGLE|Cli\Args::NOARG|Cli\Args::HALT], - ["v", "verbose", "More output", - Cli\Args::OPTIONAL|Cli\Args::SINGLE|Cli\Args::NOARG], - ["q", "quiet", "Less output", - Cli\Args::OPTIONAL|Cli\Args::SINGLE|Cli\Args::NOARG], - ["n", "name", "Extension name", - Cli\Args::REQUIRED|Cli\Args::SINGLE|Cli\Args::REQARG], - ["r", "release", "Extension release version", - Cli\Args::REQUIRED|Cli\Args::SINGLE|Cli\Args::REQARG], - ["s", "source", "Extension source directory", - Cli\Args::REQUIRED|Cli\Args::SINGLE|Cli\Args::REQARG], - ["g", "git", "Use `git ls-tree` to determine file list", - Cli\Args::OPTIONAL|Cli\Args::SINGLE|Cli\Args::NOARG], - ["b", "branch", "Checkout this tag/branch", - Cli\Args::OPTIONAL|Cli\Args::SINGLE|Cli\Args::REQARG], - ["p", "pecl", "Use PECL package.xml to determine file list, name and release", - Cli\Args::OPTIONAL|Cli\Args::SINGLE|Cli\Args::NOARG], - ["d", "dest", "Destination directory", - Cli\Args::OPTIONAL|Cli\Args::SINGLE|Cli\Args::REQARG, - "."], - ["z", "gzip", "Create additional PHAR compressed with gzip", - Cli\Args::OPTIONAL|Cli\Args::SINGLE|Cli\Args::NOARG], - ["Z", "bzip", "Create additional PHAR compressed with bzip", - Cli\Args::OPTIONAL|Cli\Args::SINGLE|Cli\Args::NOARG], - ["S", "sign", "Sign the PHAR with a private key", - Cli\Args::OPTIONAL|Cli\Args::SINGLE|Cli\Args::REQARG], - ["E", "zend", "Mark as Zend Extension", - Cli\Args::OPTIONAL|Cli\Args::SINGLE|Cli\Args::NOARG], - [null, "signature", "Show pharext signature", - Cli\Args::OPTIONAL|Cli\Args::SINGLE|Cli\Args::NOARG|Cli\Args::HALT], - [null, "license", "Show pharext license", - Cli\Args::OPTIONAL|Cli\Args::SINGLE|Cli\Args::NOARG|Cli\Args::HALT], - [null, "version", "Show pharext version", - Cli\Args::OPTIONAL|Cli\Args::SINGLE|Cli\Args::NOARG|Cli\Args::HALT], - ]); - } - - /** - * Perform cleaniup - */ - function __destruct() { - foreach ($this->cleanup as $cleanup) { - $cleanup->run(); - } - } - - /** - * @inheritdoc - * @see \pharext\Command::run() - */ - public function run($argc, array $argv) { - $errs = []; - $prog = array_shift($argv); - foreach ($this->args->parse(--$argc, $argv) as $error) { - $errs[] = $error; - } - - if ($this->args["help"]) { - $this->header(); - $this->help($prog); - exit; - } - try { - foreach (["signature", "license", "version"] as $opt) { - if ($this->args[$opt]) { - printf("%s\n", $this->metadata($opt)); - exit; - } - } - } catch (\Exception $e) { - $this->error("%s\n", $e->getMessage()); - exit(self::EARGS); - } - - try { - /* source needs to be evaluated before Cli\Args validation, - * so e.g. name and version can be overriden and Cli\Args - * does not complain about missing arguments - */ - $this->loadSource(); - } catch (\Exception $e) { - $errs[] = $e->getMessage(); - } - - foreach ($this->args->validate() as $error) { - $errs[] = $error; - } - - if ($errs) { - if (!$this->args["quiet"]) { - $this->header(); - } - foreach ($errs as $err) { - $this->error("%s\n", $err); - } - printf("\n"); - if (!$this->args["quiet"]) { - $this->help($prog); - } - exit(self::EARGS); - } - - $this->createPackage(); - } - - /** - * Download remote source - * @param string $source - * @return string local source - */ - private function download($source) { - if ($this->args->git) { - $task = new Task\GitClone($source, $this->args->branch); - } else { - /* print newline only once */ - $done = false; - $task = new Task\StreamFetch($source, function($bytes_pct) use(&$done) { - if (!$done) { - $this->info(" %3d%% [%s>%s] \r", - floor($bytes_pct*100), - str_repeat("=", round(50*$bytes_pct)), - str_repeat(" ", round(50*(1-$bytes_pct))) - ); - if ($bytes_pct == 1) { - $done = true; - $this->info("\n"); - } - } - }); - } - $local = $task->run($this->verbosity()); - - $this->cleanup[] = new Task\Cleanup($local); - return $local; - } - - /** - * Extract local archive - * @param stirng $source - * @return string extracted directory - */ - private function extract($source) { - try { - $task = new Task\Extract($source); - $dest = $task->run($this->verbosity()); - } catch (\Exception $e) { - if (false === strpos($e->getMessage(), "checksum mismatch")) { - throw $e; - } - $dest = (new Task\PaxFixup($source))->run($this->verbosity()); - } - - $this->cleanup[] = new Task\Cleanup($dest); - return $dest; - } - - /** - * Localize a possibly remote source - * @param string $source - * @return string local source directory - */ - private function localize($source) { - if (!stream_is_local($source) || ($this->args->git && isset($this->args->branch))) { - $source = $this->download($source); - $this->cleanup[] = new Task\Cleanup($source); - } - $source = realpath($source); - if (!is_dir($source)) { - $source = $this->extract($source); - $this->cleanup[] = new Task\Cleanup($source); - - if (!$this->args->git) { - $source = (new Task\PeclFixup($source))->run($this->verbosity()); - } - } - return $source; - } - - /** - * Load the source dir - * @throws \pharext\Exception - */ - private function loadSource(){ - if ($this->args["source"]) { - $source = $this->localize($this->args["source"]); - - if ($this->args["pecl"]) { - $this->source = new SourceDir\Pecl($source); - } elseif ($this->args["git"]) { - $this->source = new SourceDir\Git($source); - } elseif (is_file("$source/pharext_package.php")) { - $this->source = include "$source/pharext_package.php"; - } else { - $this->source = new SourceDir\Basic($source); - } - - if (!$this->source instanceof SourceDir) { - throw new Exception("Unknown source dir $source"); - } - - foreach ($this->source->getPackageInfo() as $key => $val) { - $this->args->$key = $val; - } - } - } - - /** - * Creates the extension phar - */ - private function createPackage() { - try { - $meta = array_merge(Metadata::all(), [ - "name" => $this->args->name, - "release" => $this->args->release, - "license" => $this->source->getLicense(), - "type" => $this->args->zend ? "zend_extension" : "extension", - ]); - $file = (new Task\PharBuild($this->source, __DIR__."/../pharext_installer.php", $meta))->run($this->verbosity()); - } catch (\Exception $e) { - $this->error("%s\n", $e->getMessage()); - exit(self::EBUILD); - } - - try { - if ($this->args->sign) { - $this->info("Using private key to sign phar ...\n"); - $pass = (new Task\Askpass)->run($this->verbosity()); - $sign = new Task\PharSign($file, $this->args->sign, $pass); - $pkey = $sign->run($this->verbosity()); - } - - } catch (\Exception $e) { - $this->error("%s\n", $e->getMessage()); - exit(self::ESIGN); - } - - if ($this->args->gzip) { - try { - $gzip = (new Task\PharCompress($file, Phar::GZ))->run(); - $move = new Task\PharRename($gzip, $this->args->dest, $this->args->name ."-". $this->args->release); - $name = $move->run($this->verbosity()); - - $this->info("Created gzipped phar %s\n", $name); - - if ($this->args->sign) { - $sign = new Task\PharSign($name, $this->args->sign, $pass); - $sign->run($this->verbosity())->exportPublicKey($name.".pubkey"); - } - - } catch (\Exception $e) { - $this->warn("%s\n", $e->getMessage()); - } - } - - if ($this->args->bzip) { - try { - $bzip = (new Task\PharCompress($file, Phar::BZ2))->run(); - $move = new Task\PharRename($bzip, $this->args->dest, $this->args->name ."-". $this->args->release); - $name = $move->run($this->verbosity()); - - $this->info("Created bzipped phar %s\n", $name); - - if ($this->args->sign) { - $sign = new Task\PharSign($name, $this->args->sign, $pass); - $sign->run($this->verbosity())->exportPublicKey($name.".pubkey"); - } - - } catch (\Exception $e) { - $this->warn("%s\n", $e->getMessage()); - } - } - - try { - $move = new Task\PharRename($file, $this->args->dest, $this->args->name ."-". $this->args->release); - $name = $move->run($this->verbosity()); - - $this->info("Created executable phar %s\n", $name); - - if (isset($pkey)) { - $pkey->exportPublicKey($name.".pubkey"); - } - - } catch (\Exception $e) { - $this->error("%s\n", $e->getMessage()); - exit(self::EBUILD); - } - } -} -path = $path; - } - - public function getBaseDir() { - return $this->path; - } - - public function getPackageInfo() { - return []; - } - - public function getLicense() { - if (($file = $this->findLicense($this->getBaseDir()))) { - return $this->readLicense($file); - } - return "UNKNOWN"; - } - - public function getArgs() { - return []; - } - - public function setArgs(Args $args) { - } - - public function filter($current, $key, $iterator) { - $sub = $current->getSubPath(); - if ($sub === ".git" || $sub === ".hg" || $sub === ".svn") { - return false; - } - return true; - } - - public function getIterator() { - $rdi = new RecursiveDirectoryIterator($this->path, - FilesystemIterator::CURRENT_AS_SELF | // needed for 5.5 - FilesystemIterator::KEY_AS_PATHNAME | - FilesystemIterator::SKIP_DOTS); - $rci = new RecursiveCallbackFilterIterator($rdi, [$this, "filter"]); - $rii = new RecursiveIteratorIterator($rci); - foreach ($rii as $path => $child) { - if (!$child->isDir()) { - yield realpath($path); - } - } - } -} -path = $path; - } - - /** - * @inheritdoc - * @see \pharext\SourceDir::getBaseDir() - */ - public function getBaseDir() { - return $this->path; - } - - /** - * @inheritdoc - * @return array - */ - public function getPackageInfo() { - return []; - } - - /** - * @inheritdoc - * @return string - */ - public function getLicense() { - if (($file = $this->findLicense($this->getBaseDir()))) { - return $this->readLicense($file); - } - return "UNKNOWN"; - } - - /** - * @inheritdoc - * @return array - */ - public function getArgs() { - return []; - } - - /** - * @inheritdoc - */ - public function setArgs(Args $args) { - } - - /** - * Generate a list of files by `git ls-files` - * @return Generator - */ - private function generateFiles() { - $pwd = getcwd(); - chdir($this->path); - if (($pipe = popen("git ls-tree -r --name-only HEAD", "r"))) { - $path = realpath($this->path); - while (!feof($pipe)) { - if (strlen($file = trim(fgets($pipe)))) { - /* there may be symlinks, so no realpath here */ - yield "$path/$file"; - } - } - pclose($pipe); - } - chdir($pwd); - } - - /** - * Implements IteratorAggregate - * @see IteratorAggregate::getIterator() - */ - public function getIterator() { - return $this->generateFiles(); - } -} -file = "$path/package2.xml"); - } elseif (is_file("$path/package.xml")) { - $sxe = simplexml_load_file($this->file = "$path/package.xml"); - } else { - throw new Exception("Missing package.xml in $path"); - } - - $sxe->registerXPathNamespace("pecl", $sxe->getDocNamespaces()[""]); - - $this->sxe = $sxe; - $this->path = realpath($path); - } - - /** - * @inheritdoc - * @see \pharext\SourceDir::getBaseDir() - */ - public function getBaseDir() { - return $this->path; - } - - /** - * Retrieve gathered package info - * @return Generator - */ - public function getPackageInfo() { - if (($name = $this->sxe->xpath("/pecl:package/pecl:name"))) { - yield "name" => (string) $name[0]; - } - if (($release = $this->sxe->xpath("/pecl:package/pecl:version/pecl:release"))) { - yield "release" => (string) $release[0]; - } - if ($this->sxe->xpath("/pecl:package/pecl:zendextsrcrelease")) { - yield "zend" => true; - } - } - - /** - * @inheritdoc - * @return string - */ - public function getLicense() { - if (($license = $this->sxe->xpath("/pecl:package/pecl:license"))) { - if (($file = $this->findLicense($this->getBaseDir(), $license[0]["filesource"]))) { - return $this->readLicense($file); - } - } - if (($file = $this->findLicense($this->getBaseDir()))) { - return $this->readLicense($file); - } - if ($license) { - return $license[0] ." ". $license[0]["uri"]; - } - return "UNKNOWN"; - } - - /** - * @inheritdoc - * @see \pharext\SourceDir::getArgs() - */ - public function getArgs() { - $configure = $this->sxe->xpath("/pecl:package/pecl:extsrcrelease/pecl:configureoption"); - foreach ($configure as $cfg) { - yield [null, $cfg["name"], ucfirst($cfg["prompt"]), Args::OPTARG, - strlen($cfg["default"]) ? $cfg["default"] : null]; - } - $configure = $this->sxe->xpath("/pecl:package/pecl:zendextsrcrelease/pecl:configureoption"); - foreach ($configure as $cfg) { - yield [null, $cfg["name"], ucfirst($cfg["prompt"]), Args::OPTARG, - strlen($cfg["default"]) ? $cfg["default"] : null]; - } - } - - /** - * @inheritdoc - * @see \pharext\SourceDir::setArgs() - */ - public function setArgs(Args $args) { - $configure = $this->sxe->xpath("/pecl:package/pecl:extsrcrelease/pecl:configureoption"); - foreach ($configure as $cfg) { - if (isset($args[$cfg["name"]])) { - $args->configure = "--{$cfg["name"]}={$args[$cfg["name"]]}"; - } - } - $configure = $this->sxe->xpath("/pecl:package/pecl:zendextsrcrelease/pecl:configureoption"); - foreach ($configure as $cfg) { - if (isset($args[$cfg["name"]])) { - $args->configure = "--{$cfg["name"]}={$args[$cfg["name"]]}"; - } - } - } - - /** - * Compute the path of a file by parent dir nodes - * @param \SimpleXMLElement $ele - * @return string - */ - private function dirOf($ele) { - $path = ""; - while (($ele = current($ele->xpath(".."))) && $ele->getName() == "dir") { - $path = trim($ele["name"], "/") ."/". $path ; - } - return trim($path, "/"); - } - - /** - * Generate a list of files from the package.xml - * @return Generator - */ - private function generateFiles() { - /* hook */ - $temp = tmpfile(); - fprintf($temp, " $temp; - - /* deps */ - $dependencies = $this->sxe->xpath("/pecl:package/pecl:dependencies/pecl:required/pecl:package"); - foreach ($dependencies as $key => $dep) { - if (($glob = glob("{$this->path}/{$dep->name}-*.ext.phar*"))) { - usort($glob, function($a, $b) { - return version_compare( - substr($a, strpos(".ext.phar", $a)), - substr($b, strpos(".ext.phar", $b)) - ); - }); - yield end($glob); - } - } - - /* files */ - yield realpath($this->file); - foreach ($this->sxe->xpath("//pecl:file") as $file) { - yield realpath($this->path ."/". $this->dirOf($file) ."/". $file["name"]); - } - } - - /** - * Implements IteratorAggregate - * @see IteratorAggregate::getIterator() - */ - public function getIterator() { - return $this->generateFiles(); - } -} -cwd = $cwd; - $this->type = $type; - $this->sudo = $sudo; - if (!$this->inis = $inis) { - throw new Exception("No PHP INIs given"); - } - $cmd = $common_name . "-config"; - if (isset($prefix)) { - $cmd = $prefix . "/bin/" . $cmd; - } - $this->php_config = $cmd; - } - - /** - * @param bool $verbose - * @return boolean false, if extension was already activated - */ - public function run($verbose = false) { - if ($verbose !== false) { - printf("Running INI activation ...\n"); - } - $extension = basename(current(glob("{$this->cwd}/modules/*.so"))); - - if ($this->type === "zend_extension") { - $pattern = preg_quote((new ExecCmd($this->php_config))->run(["--extension-dir"])->getOutput() . "/$extension", "/"); - } else { - $pattern = preg_quote($extension, "/"); - } - - foreach ($this->inis as $file) { - if ($verbose) { - printf("Checking %s ...\n", $file); - } - if (!file_exists($file)) { - throw new Exception(sprintf("INI file '%s' does not exist", $file)); - } - $temp = new Tempfile("phpini"); - foreach (file($file) as $line) { - if (preg_match("/^\s*{$this->type}\s*=\s*[\"']?{$pattern}[\"']?\s*(;.*)?\$/", $line)) { - return false; - } - fwrite($temp->getStream(), $line); - } - } - - /* not found; append to last processed file, which is the main by default */ - if ($verbose) { - printf("Activating in %s ...\n", $file); - } - fprintf($temp->getStream(), $this->type . "=%s\n", $extension); - $temp->closeStream(); - - $path = $temp->getPathname(); - $stat = stat($file); - - // owner transfer - $ugid = sprintf("%d:%d", $stat["uid"], $stat["gid"]); - $cmd = new ExecCmd("chown", $verbose); - if (isset($this->sudo)) { - $cmd->setSu($this->sudo); - } - $cmd->run([$ugid, $path]); - - // permission transfer - $perm = decoct($stat["mode"] & 0777); - $cmd = new ExecCmd("chmod", $verbose); - if (isset($this->sudo)) { - $cmd->setSu($this->sudo); - } - $cmd->run([$perm, $path]); - - // rename - $cmd = new ExecCmd("mv", $verbose); - if (isset($this->sudo)) { - $cmd->setSu($this->sudo); - } - $cmd->run([$path, $file]); - - if ($verbose) { - printf("Replaced %s ...\n", $file); - } - - return true; - } -} -prompt = $prompt; - } - - /** - * @param bool $verbose - * @return string - */ - public function run($verbose = false) { - system("stty -echo"); - printf("%s ", $this->prompt); - $pass = fgets(STDIN, 1024); - printf("\n"); - system("stty echo"); - if (substr($pass, -1) == "\n") { - $pass = substr($pass, 0, -1); - } - return $pass; - } -} -rewind(); $rii->valid(); $rii->next()) { - if (!$rii->isDot()) { - yield $rii->getSubPathname() => $rii->key(); - } - } - } -} -rm = $rm; - } - - /** - * @param bool $verbose - */ - public function run($verbose = false) { - if ($verbose) { - printf("Cleaning up %s ...\n", $this->rm); - } - if ($this->rm instanceof Tempfile) { - unset($this->rm); - } elseif (is_dir($this->rm)) { - $rdi = new RecursiveDirectoryIterator($this->rm, - FilesystemIterator::CURRENT_AS_SELF | // needed for 5.5 - FilesystemIterator::KEY_AS_PATHNAME | - FilesystemIterator::SKIP_DOTS); - $rii = new RecursiveIteratorIterator($rdi, - RecursiveIteratorIterator::CHILD_FIRST); - foreach ($rii as $path => $child) { - if ($child->isDir()) { - @rmdir($path); - } else { - @unlink($path); - } - } - @rmdir($this->rm); - } elseif (file_exists($this->rm)) { - @unlink($this->rm); - } - } -} -cwd = $cwd; - $cmd = $common_name . "-config"; - if (isset($prefix)) { - $cmd = $prefix . "/bin/" . $cmd; - } - $this->args = ["--with-php-config=$cmd"]; - if ($args) { - $this->args = array_merge($this->args, $args); - } - } - - public function run($verbose = false) { - if ($verbose !== false) { - printf("Running ./configure ...\n"); - } - $pwd = getcwd(); - if (!chdir($this->cwd)) { - throw new Exception; - } - try { - $cmd = new ExecCmd("./configure", $verbose); - $cmd->run($this->args); - } finally { - chdir($pwd); - } - } -} -source = $source; - } else { - $this->source = new PharData($source); - } - } - - /** - * @param bool $verbose - * @return \pharext\Tempdir - */ - public function run($verbose = false) { - if ($verbose) { - printf("Extracting %s ...\n", basename($this->source->getPath())); - } - if ($this->source instanceof Archive) { - return $this->source->extract(); - } - $dest = new Tempdir("extract"); - $this->source->extractTo($dest); - return $dest; - } -} -source = $source; - $this->branch = $branch; - } - - /** - * @param bool $verbose - * @return \pharext\Tempdir - */ - public function run($verbose = false) { - if ($verbose !== false) { - printf("Fetching %s ...\n", $this->source); - } - $local = new Tempdir("gitclone"); - $cmd = new ExecCmd("git", $verbose); - if (strlen($this->branch)) { - $cmd->run(["clone", "--depth", 1, "--branch", $this->branch, $this->source, $local]); - } else { - $cmd->run(["clone", $this->source, $local]); - } - return $local; - } -} -cwd = $cwd; - $this->sudo = $sudo; - $this->args = $args; - } - - /** - * - * @param bool $verbose - * @throws \pharext\Exception - */ - public function run($verbose = false) { - if ($verbose !== false) { - printf("Running make"); - if ($this->args) { - foreach ($this->args as $arg) { - printf(" %s", $arg); - } - } - printf(" ...\n"); - } - $pwd = getcwd(); - if (!chdir($this->cwd)) { - throw new Exception; - } - try { - $cmd = new ExecCmd("make", $verbose); - if (isset($this->sudo)) { - $cmd->setSu($this->sudo); - } - $args = $this->args; - if (!$verbose) { - $args = array_merge((array) $args, ["-s"]); - } - $cmd->run($args); - } finally { - chdir($pwd); - } - } -} -source = $source; - } - - private function openArchive($source) { - $hdr = file_get_contents($source, false, null, 0, 3); - if ($hdr === "\x1f\x8b\x08") { - $fd = fopen("compress.zlib://$source", "r"); - } elseif ($hdr === "BZh") { - $fd = fopen("compress.bzip2://$source", "r"); - } else { - $fd = fopen($source, "r"); - } - if (!is_resource($fd)) { - throw new Exception; - } - return $fd; - } - - public function run($verbose = false) { - if ($verbose !== false) { - printf("Fixing up a tarball with global pax header ...\n"); - } - $temp = new Tempfile("paxfix"); - stream_copy_to_stream($this->openArchive($this->source), - $temp->getStream(), -1, 1024); - $temp->closeStream(); - return (new Extract((string) $temp))->run($verbose); - } -}source = $source; - } - - /** - * @param bool $verbose - * @return string sanitized source location - * @throws \pahrext\Exception - */ - public function run($verbose = false) { - if ($verbose !== false) { - printf("Sanitizing PECL dir ...\n"); - } - $dirs = glob("{$this->source}/*", GLOB_ONLYDIR); - $files = array_diff(glob("{$this->source}/*"), $dirs); - $check = array_reduce($files, function($r, $v) { - return $v && fnmatch("package*.xml", basename($v)); - }, true); - - if (count($dirs) !== 1 || !$check) { - throw new Exception("Does not look like an extracted PECL dir: {$this->source}"); - } - - $dest = current($dirs); - - foreach ($files as $file) { - if ($verbose) { - printf("Moving %s into %s ...\n", basename($file), basename($dest)); - } - if (!rename($file, "$dest/" . basename($file))) { - throw new Exception; - } - } - - return $dest; - } -} -source = $source; - $this->stub = $stub; - $this->meta = $meta; - $this->readonly = $readonly; - } - - /** - * @param bool $verbose - * @return \pharext\Tempname - * @throws \pharext\Exception - */ - public function run($verbose = false) { - /* Phar::compress() and ::convert*() use strtok("."), ugh! - * so, be sure to not use any other dots in the filename - * except for .phar - */ - $temp = new Tempname("", "-pharext.phar"); - - $phar = new Phar($temp); - $phar->startBuffering(); - - if ($this->meta) { - $phar->setMetadata($this->meta); - } - if ($this->stub) { - (new PharStub($phar, $this->stub))->run($verbose); - } - - $phar->buildFromIterator((new Task\BundleGenerator)->run()); - - if ($this->source) { - if ($verbose) { - $bdir = $this->source->getBaseDir(); - $blen = strlen($bdir); - foreach ($this->source as $index => $file) { - if (is_resource($file)) { - printf("Packaging %s ...\n", $index); - $phar[$index] = $file; - } else { - printf("Packaging %s ...\n", $index = trim(substr($file, $blen), "/")); - $phar->addFile($file, $index); - } - } - } else { - $phar->buildFromIterator($this->source, $this->source->getBaseDir()); - } - } - - $phar->stopBuffering(); - - if (!chmod($temp, fileperms($temp) | 0111)) { - throw new Exception; - } - - return $temp; - } -}file = $file; - $this->package = new Phar($file); - $this->encoding = $encoding; - - switch ($encoding) { - case Phar::GZ: - $this->extension = ".gz"; - break; - case Phar::BZ2: - $this->extension = ".bz2"; - break; - } - } - - /** - * @param bool $verbose - * @return string - */ - public function run($verbose = false) { - if ($verbose) { - printf("Compressing %s ...\n", basename($this->package->getPath())); - } - /* stop shebang */ - $stub = $this->package->getStub(); - $phar = $this->package->compress($this->encoding); - $phar->setStub(substr($stub, strpos($stub, "\n")+1)); - return $this->file . $this->extension; - } -} -phar = $phar; - $this->dest = $dest; - $this->name = $name; - } - - /** - * @param bool $verbose - * @return string path to renamed phar - * @throws \pharext\Exception - */ - public function run($verbose = false) { - $extension = substr(strstr($this->phar, "-pharext.phar"), 8); - $name = sprintf("%s/%s.ext%s", $this->dest, $this->name, $extension); - - if ($verbose) { - printf("Renaming %s to %s ...\n", basename($this->phar), basename($name)); - } - - if (!rename($this->phar, $name)) { - throw new Exception; - } - - return $name; - } -} -phar = $phar; - } else { - $this->phar = new Phar($phar); - } - $this->pkey = new Openssl\PrivateKey($pkey, $pass); - } - - /** - * @param bool $verbose - * @return \pharext\Openssl\PrivateKey - */ - public function run($verbose = false) { - if ($verbose) { - printf("Signing %s ...\n", basename($this->phar->getPath())); - } - $this->pkey->sign($this->phar); - return $this->pkey; - } -} -phar = $phar; - if (!file_exists($this->stub = $stub)) { - throw new Exception("File '$stub' does not exist"); - } - } - - /** - * @param bool $verbose - */ - function run($verbose = false) { - if ($verbose) { - printf("Using stub '%s'...\n", basename($this->stub)); - } - $stub = preg_replace_callback('/^#include <([^>]+)>/m', function($includes) { - return file_get_contents($includes[1], true, null, 5); - }, file_get_contents($this->stub)); - if ($this->phar->isCompressed() && substr($stub, 0, 2) === "#!") { - $stub = substr($stub, strpos($stub, "\n")+1); - } - $this->phar->setStub($stub); - } -} -cwd = $cwd; - $cmd = $common_name . "ize"; - if (isset($prefix)) { - $cmd = $prefix . "/bin/" . $cmd; - } - $this->phpize = $cmd; - } - - /** - * @param bool $verbose - * @throws \pharext\Exception - */ - public function run($verbose = false) { - if ($verbose !== false) { - printf("Running %s ...\n", $this->phpize); - } - $pwd = getcwd(); - if (!chdir($this->cwd)) { - throw new Exception; - } - try { - $cmd = new ExecCmd($this->phpize, $verbose); - $cmd->run(); - } finally { - chdir($pwd); - } - } -} -source = $source; - $this->progress = $progress; - } - - private function createStreamContext() { - $progress = $this->progress; - - /* avoid bytes_max bug of older PHP versions */ - $maxbytes = 0; - return stream_context_create([],["notification" => function($notification, $severity, $message, $code, $bytes_cur, $bytes_max) use($progress, &$maxbytes) { - if ($bytes_max > $maxbytes) { - $maxbytes = $bytes_max; - } - switch ($notification) { - case STREAM_NOTIFY_CONNECT: - $progress(0); - break; - case STREAM_NOTIFY_PROGRESS: - $progress($maxbytes > 0 ? $bytes_cur/$maxbytes : .5); - break; - case STREAM_NOTIFY_COMPLETED: - /* this is sometimes not generated, why? */ - $progress(1); - break; - } - }]); - } - - /** - * @param bool $verbose - * @return \pharext\Task\Tempfile - * @throws \pharext\Exception - */ - public function run($verbose = false) { - if ($verbose !== false) { - printf("Fetching %s ...\n", $this->source); - } - $context = $this->createStreamContext(); - - if (!$remote = fopen($this->source, "r", false, $context)) { - throw new Exception; - } - - $local = new Tempfile("remote"); - if (!stream_copy_to_stream($remote, $local->getStream())) { - throw new Exception; - } - $local->closeStream(); - - /* STREAM_NOTIFY_COMPLETED is not generated, see above */ - call_user_func($this->progress, 1); - - return $local; - } -} -handle = fopen($path, "x"); - } while (!is_resource($this->handle) && $tries++ < 10); - umask($omask); - - if (!is_resource($this->handle)) { - throw new Exception("Could not create temporary file"); - } - - parent::__construct($path); - } - - /** - * Unlink the file - */ - public function __destruct() { - if (is_file($this->getPathname())) { - @unlink($this->getPathname()); - } - } - - /** - * Close the stream - */ - public function closeStream() { - fclose($this->handle); - } - - /** - * Retrieve the stream resource - * @return resource - */ - public function getStream() { - return $this->handle; - } -} -getUser(); - if (!is_dir($temp) && !mkdir($temp, 0700, true)) { - throw new Exception; - } - $this->name = $temp ."/". uniqid($prefix) . $suffix; - } - - private function getUser() { - if (extension_loaded("posix") && function_exists("posix_getpwuid")) { - return posix_getpwuid(posix_getuid())["name"]; - } - return trim(`whoami 2>/dev/null`) - ?: trim(`id -nu 2>/dev/null`) - ?: getenv("USER") - ?: get_current_user(); - } - - /** - * @return string - */ - public function __toString() { - return (string) $this->name; - } -} -args = new Cli\Args([ - ["h", "help", "Display this help", - Cli\Args::OPTIONAL|Cli\Args::SINGLE|Cli\Args::NOARG|Cli\Args::HALT], - ["v", "verbose", "More output", - Cli\Args::OPTIONAL|Cli\Args::SINGLE|Cli\Args::NOARG], - ["q", "quiet", "Less output", - Cli\Args::OPTIONAL|Cli\Args::SINGLE|Cli\Args::NOARG], - [null, "signature", "Show pharext signature", - Cli\Args::OPTIONAL|Cli\Args::SINGLE|Cli\Args::NOARG|Cli\Args::HALT], - [null, "license", "Show pharext license", - Cli\Args::OPTIONAL|Cli\Args::SINGLE|Cli\Args::NOARG|Cli\Args::HALT], - [null, "version", "Show pharext version", - Cli\Args::OPTIONAL|Cli\Args::SINGLE|Cli\Args::NOARG|Cli\Args::HALT], - [0, "path", "Path to .ext.phar to update", - Cli\Args::REQUIRED|Cli\Args::MULTI], - ]); - } - - /** - * @inheritdoc - * @see \pharext\Command::run() - */ - public function run($argc, array $argv) { - $errs = []; - $prog = array_shift($argv); - foreach ($this->args->parse(--$argc, $argv) as $error) { - $errs[] = $error; - } - - if ($this->args["help"]) { - $this->header(); - $this->help($prog); - exit; - } - - try { - foreach (["signature", "license", "version"] as $opt) { - if ($this->args[$opt]) { - printf("%s\n", $this->metadata($opt)); - exit; - } - } - } catch (\Exception $e) { - $this->error("%s\n", $e->getMessage()); - exit(self::EARGS); - } - - - foreach ($this->args->validate() as $error) { - $errs[] = $error; - } - - if ($errs) { - if (!$this->args["quiet"]) { - $this->header(); - } - foreach ($errs as $err) { - $this->error("%s\n", $err); - } - printf("\n"); - if (!$this->args["quiet"]) { - $this->help($prog); - } - exit(self::EARGS); - } - - foreach ($this->args[0] as $file) { - $info = new SplFileInfo($file); - - while ($info->isLink()) { - $info = new SplFileInfo($info->getLinkTarget()); - } - - if ($info->isFile()) { - if (!$this->updatePackage($info)) { - $this->warn("Cannot upgrade pre-v3 packages\n"); - } - } else { - $this->error("File '%s' does not exist\n", $file); - exit(self::EARGS); - } - } - } - - /** - * Replace the pharext core in an .ext.phar package - * @param string $temp path to temp phar - * @return boolean FALSE if the package is too old (pre-v3) to upgrade - */ - private function replacePharext($temp) { - $phar = new Phar($temp, Phar::CURRENT_AS_SELF); - $phar->startBuffering(); - - if (!$meta = $phar->getMetadata()) { - // don't upgrade pre-v3 packages - return false; - } - - // replace current pharext files - $core = (new Task\BundleGenerator)->run($this->verbosity()); - $phar->buildFromIterator($core); - $stub = __DIR__."/../pharext_installer.php"; - (new Task\PharStub($phar, $stub))->run($this->verbosity()); - - // check dependencies - foreach ($phar as $info) { - if (fnmatch("*.ext.phar*", $info->getBasename())) { - $this->updatePackage($info, $phar); - } - } - - $phar->stopBuffering(); - - $phar->setMetadata([ - "version" => Metadata::version(), - "header" => Metadata::header(), - ] + $meta); - - $this->info("Updated pharext version from '%s' to '%s'\n", - isset($meta["version"]) ? $meta["version"] : "(unknown)", - $phar->getMetadata()["version"]); - - return true; - } - - /** - * Update an .ext.phar package to the current pharext version - * @param SplFileInfo $file - * @param Phar $phar the parent phar containing $file as dependency - * @return boolean FALSE if the package is too old (pre-v3) to upgrade - * @throws Exception - */ - private function updatePackage(SplFileInfo $file, Phar $phar = null) { - $this->info("Updating pharext core in '%s'...\n", basename($file)); - - $temp = new Tempname("update", substr(strstr($file, ".ext.phar"), 4)); - - if (!copy($file->getPathname(), $temp)) { - throw new Exception; - } - if (!chmod($temp, $file->getPerms())) { - throw new Exception; - } - - if (!$this->replacePharext($temp)) { - return false; - } - - if ($phar) { - $phar->addFile($temp, $file); - } elseif (!rename($temp, $file->getPathname())) { - throw new Exception; - } - - return true; - } -} -#!/usr/bin/env php - -#include -#include -#include -#include - -namespace pharext; - -if (extension_loaded("Phar")) { - \Phar::interceptFileFuncs(); - \Phar::mapPhar(); - $phardir = "phar://".__FILE__; -} else { - $archive = new Archive(__FILE__); - $phardir = $archive->extract(); -} - -set_include_path("$phardir:". get_include_path()); - -$installer = new Installer(); -$installer->run($argc, $argv); - -__HALT_COMPILER(); -#!/usr/bin/php -dphar.readonly=0 -run($argc, $argv); - -__HALT_COMPILER(); -#!/usr/bin/php -dphar.readonly=0 -run($argc, $argv); - -__HALT_COMPILER(); - - - raphf - pecl.php.net - Resource and persistent handles factory - A reusable split-off of pecl_http's persistent handle and resource factory API. - - Michael Wallner - mike - mike@php.net - yes - - 2016-01-19 - - - 1.1.2 - 1.0.0 - - - stable - stable - - BSD, revised - -* Fixed release stability to stable - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5.3.0 - 7.0.0 - 7.0.0 - - - 1.4.0 - - - - raphf - - -/* - +--------------------------------------------------------------------+ - | PECL :: raphf | - +--------------------------------------------------------------------+ - | Redistribution and use in source and binary forms, with or without | - | modification, are permitted provided that the conditions mentioned | - | in the accompanying LICENSE file are met. | - +--------------------------------------------------------------------+ - | Copyright (c) 2013, Michael Wallner | - +--------------------------------------------------------------------+ -*/ - -#ifndef PHP_RAPHF_API_H -#define PHP_RAPHF_API_H - -/** - * A resource constructor. - * - * @param opaque is the \a data from php_persistent_handle_provide() - * @param init_arg is the \a init_arg from php_resource_factory_init() - * @return the created (persistent) handle - */ -typedef void *(*php_resource_factory_handle_ctor_t)(void *opaque, - void *init_arg TSRMLS_DC); - -/** - * The copy constructor of a resource. - * - * @param opaque the factory's data - * @param handle the (persistent) handle to copy - */ -typedef void *(*php_resource_factory_handle_copy_t)(void *opaque, - void *handle TSRMLS_DC); - -/** - * The destructor of a resource. - * - * @param opaque the factory's data - * @param handle the handle to destroy - */ -typedef void (*php_resource_factory_handle_dtor_t)(void *opaque, - void *handle TSRMLS_DC); - -/** - * The resource ops consisting of a ctor, a copy ctor and a dtor. - * - * Define this ops and register them with php_persistent_handle_provide() - * in MINIT. - */ -typedef struct php_resource_factory_ops { - /** The resource constructor */ - php_resource_factory_handle_ctor_t ctor; - /** The resource's copy constructor */ - php_resource_factory_handle_copy_t copy; - /** The resource's destructor */ - php_resource_factory_handle_dtor_t dtor; -} php_resource_factory_ops_t; - -/** - * The resource factory. - */ -typedef struct php_resource_factory { - /** The resource ops */ - php_resource_factory_ops_t fops; - /** Opaque user data */ - void *data; - /** User data destructor */ - void (*dtor)(void *data); - /** How often this factory is referenced */ - unsigned refcount; -} php_resource_factory_t; - -/** - * Initialize a resource factory. - * - * If you register a \a dtor for a resource factory used with a persistent - * handle provider, be sure to call php_persistent_handle_cleanup() for your - * registered provider in MSHUTDOWN, else the dtor will point to no longer - * available memory if the extension has already been unloaded. - * - * @param f the factory to initialize; if NULL allocated on the heap - * @param fops the resource ops to assign to the factory - * @param data opaque user data; may be NULL - * @param dtor a destructor for the data; may be NULL - * @return \a f or an allocated resource factory - */ -PHP_RAPHF_API php_resource_factory_t *php_resource_factory_init( - php_resource_factory_t *f, php_resource_factory_ops_t *fops, void *data, - void (*dtor)(void *data)); - -/** - * Increase the refcount of the resource factory. - * - * @param rf the resource factory - * @return the new refcount - */ -PHP_RAPHF_API unsigned php_resource_factory_addref(php_resource_factory_t *rf); - -/** - * Destroy the resource factory. - * - * If the factory's refcount reaches 0, the \a dtor for \a data is called. - * - * @param f the resource factory - */ -PHP_RAPHF_API void php_resource_factory_dtor(php_resource_factory_t *f); - -/** - * Destroy and free the resource factory. - * - * Calls php_resource_factory_dtor() and frees \æ f if the factory's refcount - * reached 0. - * - * @param f the resource factory - */ -PHP_RAPHF_API void php_resource_factory_free(php_resource_factory_t **f); - -/** - * Construct a resource by the resource factory \a f - * - * @param f the resource factory - * @param init_arg for the resource constructor - * @return the new resource - */ -PHP_RAPHF_API void *php_resource_factory_handle_ctor(php_resource_factory_t *f, - void *init_arg TSRMLS_DC); - -/** - * Create a copy of the resource \a handle - * - * @param f the resource factory - * @param handle the resource to copy - * @return the copy - */ -PHP_RAPHF_API void *php_resource_factory_handle_copy(php_resource_factory_t *f, - void *handle TSRMLS_DC); - -/** - * Destroy (and free) the resource - * - * @param f the resource factory - * @param handle the resource to destroy - */ -PHP_RAPHF_API void php_resource_factory_handle_dtor(php_resource_factory_t *f, - void *handle TSRMLS_DC); - -/** - * Persistent handles storage - */ -typedef struct php_persistent_handle_list { - /** Storage of free resources */ - HashTable free; - /** Count of acquired resources */ - ulong used; -} php_persistent_handle_list_t; - -/** - * Definition of a persistent handle provider. - * Holds a resource factory an a persistent handle list. - */ -typedef struct php_persistent_handle_provider { - /** - * The list of free handles. - * Hash of "ident" => array(handles) entries. Persistent handles are - * acquired out of this list. - */ - php_persistent_handle_list_t list; - - /** - * The resource factory. - * New handles are created by this factory. - */ - php_resource_factory_t rf; -} php_persistent_handle_provider_t; - -typedef struct php_persistent_handle_factory php_persistent_handle_factory_t; - -/** - * Wakeup the persistent handle on re-acquisition. - */ -typedef void (*php_persistent_handle_wakeup_t)( - php_persistent_handle_factory_t *f, void **handle TSRMLS_DC); -/** - * Retire the persistent handle on release. - */ -typedef void (*php_persistent_handle_retire_t)( - php_persistent_handle_factory_t *f, void **handle TSRMLS_DC); - -/** - * Definition of a persistent handle factory. - * - * php_persistent_handle_concede() will return a pointer to a - * php_persistent_handle_factory if a provider for the \a name_str has - * been registered with php_persistent_handle_provide(). - */ -struct php_persistent_handle_factory { - /** The persistent handle provider */ - php_persistent_handle_provider_t *provider; - /** The persistent handle wakeup routine; may be NULL */ - php_persistent_handle_wakeup_t wakeup; - /** The persistent handle retire routine; may be NULL */ - php_persistent_handle_retire_t retire; - - /** The ident for which this factory manages resources */ - struct { - /** ident string */ - char *str; - /** ident length */ - size_t len; - } ident; - - /** Whether it has to be free'd on php_persistent_handle_abandon() */ - unsigned free_on_abandon:1; -}; - -/** - * Register a persistent handle provider in MINIT. - * - * Registers a factory provider for \a name_str with \a fops resource factory - * ops. Call this in your MINIT. - * - * A php_resource_factory will be created with \a fops, \a data and \a dtor - * and will be stored together with a php_persistent_handle_list in the global - * raphf hash. - * - * A php_persistent_handle_factory can then be retrieved by - * php_persistent_handle_concede() at runtime. - * - * @param name_str the provider name, e.g. "http\Client\Curl" - * @param name_len the provider name length, e.g. strlen("http\Client\Curl") - * @param fops the resource factory ops - * @param data opaque user data - * @param dtor \a data destructor - * @return SUCCESS/FAILURE - */ -PHP_RAPHF_API int /* SUCCESS|FAILURE */ php_persistent_handle_provide( - const char *name_str, size_t name_len, php_resource_factory_ops_t *fops, - void *data, void (*dtor)(void *) TSRMLS_DC); - -/** - * Retrieve a persistent handle factory at runtime. - * - * If a persistent handle provider has been registered for \a name_str, a new - * php_persistent_handle_factory creating resources in the \a ident_str - * namespace will be constructed. - * - * The wakeup routine \a wakeup and the retire routine \a retire will be - * assigned to the new php_persistent_handle_factory. - * - * @param a pointer to a factory; allocated on the heap if NULL - * @param name_str the provider name, e.g. "http\Client\Curl" - * @param name_len the provider name length, e.g. strlen("http\Client\Curl") - * @param ident_str the subsidiary namespace, e.g. "php.net:80" - * @param ident_len the subsidiary namespace lenght, e.g. strlen("php.net:80") - * @param wakeup any persistent handle wakeup routine - * @param retire any persistent handle retire routine - * @return \a a or an allocated persistent handle factory - */ -PHP_RAPHF_API php_persistent_handle_factory_t *php_persistent_handle_concede( - php_persistent_handle_factory_t *a, const char *name_str, - size_t name_len, const char *ident_str, size_t ident_len, - php_persistent_handle_wakeup_t wakeup, - php_persistent_handle_retire_t retire TSRMLS_DC); - -/** - * Abandon the persistent handle factory. - * - * Destroy a php_persistent_handle_factory created by - * php_persistent_handle_concede(). If the memory for the factory was allocated, - * it will automatically be free'd. - * - * @param a the persistent handle factory to destroy - */ -PHP_RAPHF_API void php_persistent_handle_abandon( - php_persistent_handle_factory_t *a); - -/** - * Acquire a persistent handle. - * - * That is, either re-use a resource from the free list or create a new handle. - * - * If a handle is acquired from the free list, the - * php_persistent_handle_factory::wakeup callback will be executed for that - * handle. - * - * @param a the persistent handle factory - * @param init_arg the \a init_arg for php_resource_factory_handle_ctor() - * @return the acquired resource - */ -PHP_RAPHF_API void *php_persistent_handle_acquire( - php_persistent_handle_factory_t *a, void *init_arg TSRMLS_DC); - -/** - * Release a persistent handle. - * - * That is, either put it back into the free list for later re-use or clean it - * up with php_resource_factory_handle_dtor(). - * - * If a handle is put back into the free list, the - * php_persistent_handle_factory::retire callback will be executed for that - * handle. - * - * @param a the persistent handle factory - * @param handle the handle to release - */ -PHP_RAPHF_API void php_persistent_handle_release( - php_persistent_handle_factory_t *a, void *handle TSRMLS_DC); - -/** - * Copy a persistent handle. - * - * Let the underlying resource factory copy the \a handle. - * - * @param a the persistent handle factory - * @param handle the resource to accrete - */ -PHP_RAPHF_API void *php_persistent_handle_accrete( - php_persistent_handle_factory_t *a, void *handle TSRMLS_DC); - -/** - * Retrieve persistent handle resource factory ops. - * - * These ops can be used to mask a persistent handle factory as - * resource factory itself, so you can transparently use the - * resource factory API, both for persistent and non-persistent - * ressources. - * - * Example: - * \code{.c} - * php_resource_factory_t *create_my_rf(const char *persistent_id_str, - * size_t persistent_id_len TSRMLS_DC) - * { - * php_resource_factory_t *rf; - * - * if (persistent_id_str) { - * php_persistent_handle_factory_t *pf; - * php_resource_factory_ops_t *ops; - * - * ops = php_persistent_handle_get_resource_factory_ops(); - * - * pf = php_persistent_handle_concede(NULL, "my", 2, - * persistent_id_str, persistent_id_len, NULL, NULL TSRMLS_CC); - * - * rf = php_persistent_handle_resource_factory_init(NULL, pf); - * } else { - * rf = php_resource_factory_init(NULL, &myops, NULL, NULL); - * } - * return rf; - * } - * \endcode - */ -PHP_RAPHF_API php_resource_factory_ops_t * -php_persistent_handle_get_resource_factory_ops(void); - -/** - * Create a resource factory for persistent handles. - * - * This will create a resource factory with persistent handle ops, which wraps - * the provided reource factory \a pf. - * - * @param a the persistent handle resource factory to initialize - * @param pf the resource factory to wrap - */ -PHP_RAPHF_API php_resource_factory_t * -php_persistent_handle_resource_factory_init(php_resource_factory_t *a, - php_persistent_handle_factory_t *pf); - -/** - * Check whether a resource factory is a persistent handle resource factory. - * - * @param a the resource factory to check - */ -PHP_RAPHF_API zend_bool php_resource_factory_is_persistent( - php_resource_factory_t *a); - -/** - * Clean persistent handles up. - * - * Destroy persistent handles of provider \a name_str and in subsidiary - * namespace \a ident_str. - * - * If \a name_str is NULL, all persistent handles of all providers with a - * matching \a ident_str will be cleaned up. - * - * If \a ident_str is NULL all persistent handles of the provider will be - * cleaned up. - * - * Ergo, if both, \a name_str and \a ident_str are NULL, then all - * persistent handles will be cleaned up. - * - * You must call this in MSHUTDOWN, if your resource factory ops hold a - * registered php_resource_factory::dtor, else the dtor will point to - * memory not any more available if the extension has already been unloaded. - * - * @param name_str the provider name; may be NULL - * @param name_len the provider name length - * @param ident_str the subsidiary namespace name; may be NULL - * @param ident_len the subsidiary namespace name length - */ -PHP_RAPHF_API void php_persistent_handle_cleanup(const char *name_str, - size_t name_len, const char *ident_str, size_t ident_len TSRMLS_DC); - -/** - * Retrieve statistics about the current process/thread's persistent handles. - * - * @return a HashTable like: - * \code - * [ - * "name" => [ - * "ident" => [ - * "used" => 1, - * "free" => 0, - * ] - * ] - * ] - * \endcode - */ -PHP_RAPHF_API HashTable *php_persistent_handle_statall(HashTable *ht TSRMLS_DC); - -#endif /* PHP_RAPHF_API_H */ - - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - * vim600: noet sw=4 ts=4 fdm=marker - * vim<600: noet sw=4 ts=4 - */ -/* - +--------------------------------------------------------------------+ - | PECL :: raphf | - +--------------------------------------------------------------------+ - | Redistribution and use in source and binary forms, with or without | - | modification, are permitted provided that the conditions mentioned | - | in the accompanying LICENSE file are met. | - +--------------------------------------------------------------------+ - | Copyright (c) 2013, Michael Wallner | - +--------------------------------------------------------------------+ -*/ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "php.h" -#include "php_ini.h" -#include "ext/standard/info.h" -#include "php_raphf.h" - -struct php_persistent_handle_globals { - ulong limit; - HashTable hash; -}; - -ZEND_BEGIN_MODULE_GLOBALS(raphf) - struct php_persistent_handle_globals persistent_handle; -ZEND_END_MODULE_GLOBALS(raphf) - -#ifdef ZTS -# define PHP_RAPHF_G ((zend_raphf_globals *) \ - (*((void ***) tsrm_ls))[TSRM_UNSHUFFLE_RSRC_ID(raphf_globals_id)]) -#else -# define PHP_RAPHF_G (&raphf_globals) -#endif - -ZEND_DECLARE_MODULE_GLOBALS(raphf) - -#if PHP_VERSION_ID < 50500 -#undef SUCCESS -#undef FAILURE -typedef enum { - SUCCESS = 0, - FAILURE = -1 -} ZEND_RESULT_CODE; -#endif - -#ifndef PHP_RAPHF_DEBUG_PHANDLES -# define PHP_RAPHF_DEBUG_PHANDLES 0 -#endif -#if PHP_RAPHF_DEBUG_PHANDLES -# undef inline -# define inline -#endif - -php_resource_factory_t *php_resource_factory_init(php_resource_factory_t *f, - php_resource_factory_ops_t *fops, void *data, void (*dtor)(void *data)) -{ - if (!f) { - f = emalloc(sizeof(*f)); - } - memset(f, 0, sizeof(*f)); - - memcpy(&f->fops, fops, sizeof(*fops)); - - f->data = data; - f->dtor = dtor; - - f->refcount = 1; - - return f; -} - -unsigned php_resource_factory_addref(php_resource_factory_t *rf) -{ - return ++rf->refcount; -} - -void php_resource_factory_dtor(php_resource_factory_t *f) -{ - --f->refcount; - - if (!f->refcount) { - if (f->dtor) { - f->dtor(f->data); - } - } -} - -void php_resource_factory_free(php_resource_factory_t **f) -{ - if (*f) { - php_resource_factory_dtor(*f); - if (!(*f)->refcount) { - efree(*f); - *f = NULL; - } - } -} - -void *php_resource_factory_handle_ctor(php_resource_factory_t *f, - void *init_arg TSRMLS_DC) -{ - if (f->fops.ctor) { - return f->fops.ctor(f->data, init_arg TSRMLS_CC); - } - return NULL; -} - -void *php_resource_factory_handle_copy(php_resource_factory_t *f, - void *handle TSRMLS_DC) -{ - if (f->fops.copy) { - return f->fops.copy(f->data, handle TSRMLS_CC); - } - return NULL; -} - -void php_resource_factory_handle_dtor(php_resource_factory_t *f, - void *handle TSRMLS_DC) -{ - if (f->fops.dtor) { - f->fops.dtor(f->data, handle TSRMLS_CC); - } -} - -php_resource_factory_t *php_persistent_handle_resource_factory_init( - php_resource_factory_t *a, php_persistent_handle_factory_t *pf) -{ - return php_resource_factory_init(a, - php_persistent_handle_get_resource_factory_ops(), pf, - (void(*)(void*)) php_persistent_handle_abandon); -} - -zend_bool php_resource_factory_is_persistent(php_resource_factory_t *a) -{ - return a->dtor == (void(*)(void *)) php_persistent_handle_abandon; -} - - -static inline php_persistent_handle_list_t *php_persistent_handle_list_init( - php_persistent_handle_list_t *list) -{ - int free_list; - - if ((free_list = !list)) { - list = pemalloc(sizeof(php_persistent_handle_list_t), 1); - } - - list->used = 0; - - if (SUCCESS != zend_hash_init(&list->free, 0, NULL, NULL, 1)) { - if (free_list) { - pefree(list, 1); - } - list = NULL; - } - - return list; -} - -static int php_persistent_handle_apply_stat(void *p TSRMLS_DC, int argc, - va_list argv, zend_hash_key *key) -{ - php_persistent_handle_list_t **list = p; - zval *zsubentry, *zentry = va_arg(argv, zval *); - - MAKE_STD_ZVAL(zsubentry); - array_init(zsubentry); - add_assoc_long_ex(zsubentry, ZEND_STRS("used"), (*list)->used); - add_assoc_long_ex(zsubentry, ZEND_STRS("free"), - zend_hash_num_elements(&(*list)->free)); - add_assoc_zval_ex(zentry, key->arKey, key->nKeyLength, zsubentry); - - return ZEND_HASH_APPLY_KEEP; -} - -static int php_persistent_handle_apply_statall(void *p TSRMLS_DC, int argc, - va_list argv, zend_hash_key *key) -{ - php_persistent_handle_provider_t *provider = p; - HashTable *ht = va_arg(argv, HashTable *); - zval *zentry; - - MAKE_STD_ZVAL(zentry); - array_init(zentry); - - zend_hash_apply_with_arguments(&provider->list.free TSRMLS_CC, - php_persistent_handle_apply_stat, 1, zentry); - zend_symtable_update(ht, key->arKey, key->nKeyLength, &zentry, - sizeof(zval *), NULL); - - return ZEND_HASH_APPLY_KEEP; -} - -static int php_persistent_handle_apply_cleanup_ex(void *pp, void *arg TSRMLS_DC) -{ - php_resource_factory_t *rf = arg; - void **handle = pp; - -#if PHP_RAPHF_DEBUG_PHANDLES - fprintf(stderr, "DESTROY: %p\n", *handle); -#endif - php_resource_factory_handle_dtor(rf, *handle TSRMLS_CC); - return ZEND_HASH_APPLY_REMOVE; -} - -static int php_persistent_handle_apply_cleanup(void *pp, void *arg TSRMLS_DC) -{ - php_resource_factory_t *rf = arg; - php_persistent_handle_list_t **listp = pp; - - zend_hash_apply_with_argument(&(*listp)->free, - php_persistent_handle_apply_cleanup_ex, rf TSRMLS_CC); - if ((*listp)->used) { - return ZEND_HASH_APPLY_KEEP; - } - zend_hash_destroy(&(*listp)->free); -#if PHP_RAPHF_DEBUG_PHANDLES - fprintf(stderr, "LSTFREE: %p\n", *listp); -#endif - pefree(*listp, 1); - *listp = NULL; - return ZEND_HASH_APPLY_REMOVE; -} - -static inline void php_persistent_handle_list_dtor( - php_persistent_handle_list_t *list, - php_persistent_handle_provider_t *provider TSRMLS_DC) -{ -#if PHP_RAPHF_DEBUG_PHANDLES - fprintf(stderr, "LSTDTOR: %p\n", list); -#endif - zend_hash_apply_with_argument(&list->free, - php_persistent_handle_apply_cleanup_ex, &provider->rf TSRMLS_CC); - zend_hash_destroy(&list->free); -} - -static inline void php_persistent_handle_list_free( - php_persistent_handle_list_t **list, - php_persistent_handle_provider_t *provider TSRMLS_DC) -{ - php_persistent_handle_list_dtor(*list, provider TSRMLS_CC); -#if PHP_RAPHF_DEBUG_PHANDLES - fprintf(stderr, "LSTFREE: %p\n", *list); -#endif - pefree(*list, 1); - *list = NULL; -} - -static int php_persistent_handle_list_apply_dtor(void *listp, - void *provider TSRMLS_DC) -{ - php_persistent_handle_list_free(listp, provider TSRMLS_CC); - return ZEND_HASH_APPLY_REMOVE; -} - -static inline php_persistent_handle_list_t *php_persistent_handle_list_find( - php_persistent_handle_provider_t *provider, const char *ident_str, - size_t ident_len TSRMLS_DC) -{ - php_persistent_handle_list_t **list, *new_list; - ZEND_RESULT_CODE rv = zend_symtable_find(&provider->list.free, ident_str, - ident_len + 1, (void *) &list); - - if (SUCCESS == rv) { -#if PHP_RAPHF_DEBUG_PHANDLES - fprintf(stderr, "LSTFIND: %p\n", *list); -#endif - return *list; - } - - if ((new_list = php_persistent_handle_list_init(NULL))) { - rv = zend_symtable_update(&provider->list.free, ident_str, ident_len+1, - (void *) &new_list, sizeof(php_persistent_handle_list_t *), - (void *) &list); - if (SUCCESS == rv) { -#if PHP_RAPHF_DEBUG_PHANDLES - fprintf(stderr, "LSTFIND: %p (new)\n", *list); -#endif - return *list; - } - php_persistent_handle_list_free(&new_list, provider TSRMLS_CC); - } - - return NULL; -} - -static int php_persistent_handle_apply_cleanup_all(void *p TSRMLS_DC, int argc, - va_list argv, zend_hash_key *key) -{ - php_persistent_handle_provider_t *provider = p; - const char *ident_str = va_arg(argv, const char *); - size_t ident_len = va_arg(argv, size_t); - php_persistent_handle_list_t *list; - - if (ident_str && ident_len) { - if ((list = php_persistent_handle_list_find(provider, ident_str, - ident_len TSRMLS_CC))) { - zend_hash_apply_with_argument(&list->free, - php_persistent_handle_apply_cleanup_ex, - &provider->rf TSRMLS_CC); - } - } else { - zend_hash_apply_with_argument(&provider->list.free, - php_persistent_handle_apply_cleanup, &provider->rf TSRMLS_CC); - } - - return ZEND_HASH_APPLY_KEEP; -} - -static void php_persistent_handle_hash_dtor(void *p) -{ - php_persistent_handle_provider_t *provider; - TSRMLS_FETCH(); - - provider = (php_persistent_handle_provider_t *) p; - zend_hash_apply_with_argument(&provider->list.free, - php_persistent_handle_list_apply_dtor, provider TSRMLS_CC); - zend_hash_destroy(&provider->list.free); - php_resource_factory_dtor(&provider->rf); -} - -PHP_RAPHF_API ZEND_RESULT_CODE php_persistent_handle_provide(const char *name_str, - size_t name_len, php_resource_factory_ops_t *fops, void *data, - void (*dtor)(void *) TSRMLS_DC) -{ - ZEND_RESULT_CODE status = FAILURE; - php_persistent_handle_provider_t provider; - - if (php_persistent_handle_list_init(&provider.list)) { - if (php_resource_factory_init(&provider.rf, fops, data, dtor)) { -#if PHP_RAPHF_DEBUG_PHANDLES - fprintf(stderr, "PROVIDE: %p %s\n", PHP_RAPHF_G, name_str); -#endif - - status = zend_symtable_update(&PHP_RAPHF_G->persistent_handle.hash, - name_str, name_len+1, (void *) &provider, - sizeof(php_persistent_handle_provider_t), NULL); - if (SUCCESS != status) { - php_resource_factory_dtor(&provider.rf); - } - } - } - - return status; -} - -php_persistent_handle_factory_t *php_persistent_handle_concede( - php_persistent_handle_factory_t *a, const char *name_str, - size_t name_len, const char *ident_str, size_t ident_len, - php_persistent_handle_wakeup_t wakeup, - php_persistent_handle_retire_t retire TSRMLS_DC) -{ - ZEND_RESULT_CODE status = FAILURE; - php_persistent_handle_factory_t *free_a = NULL; - - if (!a) { - free_a = a = emalloc(sizeof(*a)); - } - memset(a, 0, sizeof(*a)); - - status = zend_symtable_find(&PHP_RAPHF_G->persistent_handle.hash, name_str, - name_len+1, (void *) &a->provider); - - if (SUCCESS == status) { - a->ident.str = estrndup(ident_str, ident_len); - a->ident.len = ident_len; - - a->wakeup = wakeup; - a->retire = retire; - - if (free_a) { - a->free_on_abandon = 1; - } - } else { - if (free_a) { - efree(free_a); - } - a = NULL; - } - -#if PHP_RAPHF_DEBUG_PHANDLES - fprintf(stderr, "CONCEDE: %p %p (%s) (%s)\n", PHP_RAPHF_G, - a ? a->provider : NULL, name_str, ident_str); -#endif - - return a; -} - -PHP_RAPHF_API void php_persistent_handle_abandon( - php_persistent_handle_factory_t *a) -{ - zend_bool f = a->free_on_abandon; - -#if PHP_RAPHF_DEBUG_PHANDLES - fprintf(stderr, "ABANDON: %p\n", a->provider); -#endif - - STR_FREE(a->ident.str); - memset(a, 0, sizeof(*a)); - if (f) { - efree(a); - } -} - -void *php_persistent_handle_acquire( - php_persistent_handle_factory_t *a, void *init_arg TSRMLS_DC) -{ - int key; - ZEND_RESULT_CODE rv; - ulong index; - void **handle_ptr, *handle = NULL; - php_persistent_handle_list_t *list; - - list = php_persistent_handle_list_find(a->provider, a->ident.str, - a->ident.len TSRMLS_CC); - if (list) { - zend_hash_internal_pointer_end(&list->free); - key = zend_hash_get_current_key(&list->free, NULL, &index, 0); - rv = zend_hash_get_current_data(&list->free, (void *) &handle_ptr); - if (HASH_KEY_NON_EXISTANT != key && SUCCESS == rv) { - handle = *handle_ptr; - if (a->wakeup) { - a->wakeup(a, &handle TSRMLS_CC); - } - zend_hash_index_del(&list->free, index); - } else { - handle = php_resource_factory_handle_ctor(&a->provider->rf, - init_arg TSRMLS_CC); - } -#if PHP_RAPHF_DEBUG_PHANDLES - fprintf(stderr, "CREATED: %p\n", *handle); -#endif - if (handle) { - ++a->provider->list.used; - ++list->used; - } - } - - return handle; -} - -void *php_persistent_handle_accrete( - php_persistent_handle_factory_t *a, void *handle TSRMLS_DC) -{ - void *new_handle = NULL; - php_persistent_handle_list_t *list; - - new_handle = php_resource_factory_handle_copy(&a->provider->rf, - handle TSRMLS_CC); - if (handle) { - list = php_persistent_handle_list_find(a->provider, a->ident.str, - a->ident.len TSRMLS_CC); - if (list) { - ++list->used; - } - ++a->provider->list.used; - } - - return new_handle; -} - -void php_persistent_handle_release( - php_persistent_handle_factory_t *a, void *handle TSRMLS_DC) -{ - php_persistent_handle_list_t *list; - - list = php_persistent_handle_list_find(a->provider, a->ident.str, - a->ident.len TSRMLS_CC); - if (list) { - if (a->provider->list.used >= PHP_RAPHF_G->persistent_handle.limit) { -#if PHP_RAPHF_DEBUG_PHANDLES - fprintf(stderr, "DESTROY: %p\n", *handle); -#endif - php_resource_factory_handle_dtor(&a->provider->rf, - handle TSRMLS_CC); - } else { - if (a->retire) { - a->retire(a, &handle TSRMLS_CC); - } - zend_hash_next_index_insert(&list->free, (void *) &handle, - sizeof(void *), NULL); - } - - --a->provider->list.used; - --list->used; - } -} - -void php_persistent_handle_cleanup(const char *name_str, size_t name_len, - const char *ident_str, size_t ident_len TSRMLS_DC) -{ - php_persistent_handle_provider_t *provider; - php_persistent_handle_list_t *list; - ZEND_RESULT_CODE rv; - - if (name_str && name_len) { - rv = zend_symtable_find(&PHP_RAPHF_G->persistent_handle.hash, name_str, - name_len+1, (void *) &provider); - - if (SUCCESS == rv) { - if (ident_str && ident_len) { - list = php_persistent_handle_list_find(provider, ident_str, - ident_len TSRMLS_CC); - if (list) { - zend_hash_apply_with_argument(&list->free, - php_persistent_handle_apply_cleanup_ex, - &provider->rf TSRMLS_CC); - } - } else { - zend_hash_apply_with_argument(&provider->list.free, - php_persistent_handle_apply_cleanup, - &provider->rf TSRMLS_CC); - } - } - } else { - zend_hash_apply_with_arguments( - &PHP_RAPHF_G->persistent_handle.hash TSRMLS_CC, - php_persistent_handle_apply_cleanup_all, 2, ident_str, - ident_len); - } -} - -HashTable *php_persistent_handle_statall(HashTable *ht TSRMLS_DC) -{ - if (zend_hash_num_elements(&PHP_RAPHF_G->persistent_handle.hash)) { - if (!ht) { - ALLOC_HASHTABLE(ht); - zend_hash_init(ht, 0, NULL, ZVAL_PTR_DTOR, 0); - } - zend_hash_apply_with_arguments( - &PHP_RAPHF_G->persistent_handle.hash TSRMLS_CC, - php_persistent_handle_apply_statall, 1, ht); - } else if (ht) { - ht = NULL; - } - - return ht; -} - -static php_resource_factory_ops_t php_persistent_handle_resource_factory_ops = { - (php_resource_factory_handle_ctor_t) php_persistent_handle_acquire, - (php_resource_factory_handle_copy_t) php_persistent_handle_accrete, - (php_resource_factory_handle_dtor_t) php_persistent_handle_release -}; - -php_resource_factory_ops_t *php_persistent_handle_get_resource_factory_ops(void) -{ - return &php_persistent_handle_resource_factory_ops; -} - -ZEND_BEGIN_ARG_INFO_EX(ai_raphf_stat_persistent_handles, 0, 0, 0) -ZEND_END_ARG_INFO(); -static PHP_FUNCTION(raphf_stat_persistent_handles) -{ - if (SUCCESS == zend_parse_parameters_none()) { - object_init(return_value); - if (php_persistent_handle_statall(HASH_OF(return_value) TSRMLS_CC)) { - return; - } - zval_dtor(return_value); - } - RETURN_FALSE; -} - -ZEND_BEGIN_ARG_INFO_EX(ai_raphf_clean_persistent_handles, 0, 0, 0) - ZEND_ARG_INFO(0, name) - ZEND_ARG_INFO(0, ident) -ZEND_END_ARG_INFO(); -static PHP_FUNCTION(raphf_clean_persistent_handles) -{ - char *name_str = NULL, *ident_str = NULL; - int name_len = 0, ident_len = 0; - - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!s!", - &name_str, &name_len, &ident_str, &ident_len)) { - php_persistent_handle_cleanup(name_str, name_len, ident_str, - ident_len TSRMLS_CC); - } -} - -static const zend_function_entry raphf_functions[] = { - ZEND_NS_FENTRY("raphf", stat_persistent_handles, - ZEND_FN(raphf_stat_persistent_handles), - ai_raphf_stat_persistent_handles, 0) - ZEND_NS_FENTRY("raphf", clean_persistent_handles, - ZEND_FN(raphf_clean_persistent_handles), - ai_raphf_clean_persistent_handles, 0) - {0} -}; - -PHP_INI_BEGIN() - STD_PHP_INI_ENTRY("raphf.persistent_handle.limit", "-1", PHP_INI_SYSTEM, - OnUpdateLong, persistent_handle.limit, zend_raphf_globals, - raphf_globals) -PHP_INI_END() - -static HashTable *php_persistent_handles_global_hash; - -static PHP_GINIT_FUNCTION(raphf) -{ - raphf_globals->persistent_handle.limit = -1; - - zend_hash_init(&raphf_globals->persistent_handle.hash, 0, NULL, - php_persistent_handle_hash_dtor, 1); - if (php_persistent_handles_global_hash) { - zend_hash_copy(&raphf_globals->persistent_handle.hash, - php_persistent_handles_global_hash, NULL, NULL, - sizeof(php_persistent_handle_provider_t)); - } -} - -static PHP_GSHUTDOWN_FUNCTION(raphf) -{ - zend_hash_destroy(&raphf_globals->persistent_handle.hash); -} - -PHP_MINIT_FUNCTION(raphf) -{ - php_persistent_handles_global_hash = &PHP_RAPHF_G->persistent_handle.hash; - REGISTER_INI_ENTRIES(); - return SUCCESS; -} - -PHP_MSHUTDOWN_FUNCTION(raphf) -{ - UNREGISTER_INI_ENTRIES(); - php_persistent_handles_global_hash = NULL; - return SUCCESS; -} - -static int php_persistent_handle_apply_info_ex(void *p TSRMLS_DC, int argc, - va_list argv, zend_hash_key *key) -{ - php_persistent_handle_list_t **list = p; - zend_hash_key *super_key = va_arg(argv, zend_hash_key *); - char used[21], free[21]; - - slprintf(used, sizeof(used), "%u", (*list)->used); - slprintf(free, sizeof(free), "%d", zend_hash_num_elements(&(*list)->free)); - - php_info_print_table_row(4, super_key->arKey, key->arKey, used, free); - - return ZEND_HASH_APPLY_KEEP; -} - -static int php_persistent_handle_apply_info(void *p TSRMLS_DC, int argc, - va_list argv, zend_hash_key *key) -{ - php_persistent_handle_provider_t *provider = p; - - zend_hash_apply_with_arguments(&provider->list.free TSRMLS_CC, - php_persistent_handle_apply_info_ex, 1, key); - - return ZEND_HASH_APPLY_KEEP; -} - -PHP_MINFO_FUNCTION(raphf) -{ - php_info_print_table_start(); - php_info_print_table_header(2, - "Resource and persistent handle factory support", "enabled"); - php_info_print_table_row(2, "Extension version", PHP_RAPHF_VERSION); - php_info_print_table_end(); - - php_info_print_table_start(); - php_info_print_table_colspan_header(4, "Persistent handles in this " -#ifdef ZTS - "thread" -#else - "process" -#endif - ); - php_info_print_table_header(4, "Provider", "Ident", "Used", "Free"); - zend_hash_apply_with_arguments( - &PHP_RAPHF_G->persistent_handle.hash TSRMLS_CC, - php_persistent_handle_apply_info, 0); - php_info_print_table_end(); - - DISPLAY_INI_ENTRIES(); -} - -zend_module_entry raphf_module_entry = { - STANDARD_MODULE_HEADER, - "raphf", - raphf_functions, - PHP_MINIT(raphf), - PHP_MSHUTDOWN(raphf), - NULL, - NULL, - PHP_MINFO(raphf), - PHP_RAPHF_VERSION, - ZEND_MODULE_GLOBALS(raphf), - PHP_GINIT(raphf), - PHP_GSHUTDOWN(raphf), - NULL, - STANDARD_MODULE_PROPERTIES_EX -}; -/* }}} */ - -#ifdef COMPILE_DL_RAPHF -ZEND_GET_MODULE(raphf) -#endif - - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - * vim600: noet sw=4 ts=4 fdm=marker - * vim<600: noet sw=4 ts=4 - */ -#!/usr/bin/env php -# autogenerated file; do not edit -sudo: false -language: c - -addons: - apt: - packages: - - php5-cli - - php-pear - -env: - matrix: - ["5.4", "5.5", "5.6"], - "enable_debug", - "enable_maintainer_zts", -]); -foreach ($env as $e) { - printf(" - %s\n", $e); -} - -?> - -before_script: - - make -f travis/pecl/Makefile php - - make -f travis/pecl/Makefile ext PECL=raphf - -script: - - make -f travis/pecl/Makefile test ---TEST-- -pecl/http-v2 - general and stat ---SKIPIF-- - ---FILE-- -enqueue(new http\Client\Request("GET", "http://php.net")); -} while (count($c) < 3); - -$h = (array) raphf\stat_persistent_handles(); -var_dump(array_intersect_key($h, array_flip(preg_grep("/^http/", array_keys($h))))); - -unset($c); - -$h = (array) raphf\stat_persistent_handles(); -var_dump(array_intersect_key($h, array_flip(preg_grep("/^http/", array_keys($h))))); - -?> -Done ---EXPECTF-- -Test -array(2) { - ["http\Client\Curl"]=> - array(0) { - } - ["http\Client\Curl\Request"]=> - array(0) { - } -} -array(2) { - ["http\Client\Curl"]=> - array(1) { - ["php.net:80"]=> - array(2) { - ["used"]=> - int(1) - ["free"]=> - int(0) - } - } - ["http\Client\Curl\Request"]=> - array(1) { - ["php.net:80"]=> - array(2) { - ["used"]=> - int(3) - ["free"]=> - int(0) - } - } -} -array(2) { - ["http\Client\Curl"]=> - array(1) { - ["php.net:80"]=> - array(2) { - ["used"]=> - int(0) - ["free"]=> - int(1) - } - } - ["http\Client\Curl\Request"]=> - array(1) { - ["php.net:80"]=> - array(2) { - ["used"]=> - int(0) - ["free"]=> - int(3) - } - } -} -Done ---TEST-- -pecl/http-v2 - clean with name and id ---SKIPIF-- - ---FILE-- -enqueue(new http\Client\Request("GET", "http://php.net")); -} while (count($c) < 3); - -unset($c); - -$h = (array) raphf\stat_persistent_handles(); -var_dump(array_intersect_key($h, array_flip(preg_grep("/^http/", array_keys($h))))); - - -raphf\clean_persistent_handles("http\\Client\\Curl"); -raphf\clean_persistent_handles("http\\Client\\Curl\\Request", "php.net:80"); - -$h = (array) raphf\stat_persistent_handles(); -var_dump(array_intersect_key($h, array_flip(preg_grep("/^http/", array_keys($h))))); - -?> -Done ---EXPECTF-- -Test -array(2) { - ["http\Client\Curl"]=> - array(1) { - ["php.net:80"]=> - array(2) { - ["used"]=> - int(0) - ["free"]=> - int(1) - } - } - ["http\Client\Curl\Request"]=> - array(1) { - ["php.net:80"]=> - array(2) { - ["used"]=> - int(0) - ["free"]=> - int(3) - } - } -} -array(2) { - ["http\Client\Curl"]=> - array(0) { - } - ["http\Client\Curl\Request"]=> - array(1) { - ["php.net:80"]=> - array(2) { - ["used"]=> - int(0) - ["free"]=> - int(0) - } - } -} -Done ---TEST-- -pecl/http-v2 - clean with id only ---SKIPIF-- - ---FILE-- -enqueue(new http\Client\Request("GET", "http://php.net")); -} while (count($c) < 3); - -unset($c); - -$h = (array) raphf\stat_persistent_handles(); -var_dump(array_intersect_key($h, array_flip(preg_grep("/^http/", array_keys($h))))); - -raphf\clean_persistent_handles(null, "php.net:80"); - -$h = (array) raphf\stat_persistent_handles(); -var_dump(array_intersect_key($h, array_flip(preg_grep("/^http/", array_keys($h))))); - -?> -Done ---EXPECTF-- -Test -array(2) { - ["http\Client\Curl"]=> - array(1) { - ["php.net:80"]=> - array(2) { - ["used"]=> - int(0) - ["free"]=> - int(1) - } - } - ["http\Client\Curl\Request"]=> - array(1) { - ["php.net:80"]=> - array(2) { - ["used"]=> - int(0) - ["free"]=> - int(3) - } - } -} -array(2) { - ["http\Client\Curl"]=> - array(1) { - ["php.net:80"]=> - array(2) { - ["used"]=> - int(0) - ["free"]=> - int(0) - } - } - ["http\Client\Curl\Request"]=> - array(1) { - ["php.net:80"]=> - array(2) { - ["used"]=> - int(0) - ["free"]=> - int(0) - } - } -} -Done ---TEST-- -pecl/http-v2 - partial clean ---SKIPIF-- - ---FILE-- -enqueue(new http\Client\Request("GET", "http://php.net")); - $c2->enqueue(new http\Client\Request("GET", "http://php.net")); -} while (count($c) < 3); - -$h = (array) raphf\stat_persistent_handles(); -var_dump(array_intersect_key($h, array_flip(preg_grep("/^http/", array_keys($h))))); - -unset($c); - -$h = (array) raphf\stat_persistent_handles(); -var_dump(array_intersect_key($h, array_flip(preg_grep("/^http/", array_keys($h))))); - -raphf\clean_persistent_handles(); - -$h = (array) raphf\stat_persistent_handles(); -var_dump(array_intersect_key($h, array_flip(preg_grep("/^http/", array_keys($h))))); - -?> -Done ---EXPECTF-- -Test -array(2) { - ["http\Client\Curl"]=> - array(0) { - } - ["http\Client\Curl\Request"]=> - array(0) { - } -} -array(2) { - ["http\Client\Curl"]=> - array(1) { - ["php.net:80"]=> - array(2) { - ["used"]=> - int(2) - ["free"]=> - int(0) - } - } - ["http\Client\Curl\Request"]=> - array(1) { - ["php.net:80"]=> - array(2) { - ["used"]=> - int(6) - ["free"]=> - int(0) - } - } -} -array(2) { - ["http\Client\Curl"]=> - array(1) { - ["php.net:80"]=> - array(2) { - ["used"]=> - int(1) - ["free"]=> - int(1) - } - } - ["http\Client\Curl\Request"]=> - array(1) { - ["php.net:80"]=> - array(2) { - ["used"]=> - int(3) - ["free"]=> - int(3) - } - } -} -array(2) { - ["http\Client\Curl"]=> - array(1) { - ["php.net:80"]=> - array(2) { - ["used"]=> - int(1) - ["free"]=> - int(0) - } - } - ["http\Client\Curl\Request"]=> - array(1) { - ["php.net:80"]=> - array(2) { - ["used"]=> - int(3) - ["free"]=> - int(0) - } - } -} -Done -Michael Wallner -Yay, now known and unresolved issues yet! -# Contributor Code of Conduct - -As contributors and maintainers of this project, and in the interest of -fostering an open and welcoming community, we pledge to respect all people who -contribute through reporting issues, posting feature requests, updating -documentation, submitting pull requests or patches, and other activities. - -We are committed to making participation in this project a harassment-free -experience for everyone, regardless of level of experience, gender, gender -identity and expression, sexual orientation, disability, personal appearance, -body size, race, ethnicity, age, religion, or nationality. - -Examples of unacceptable behavior by participants include: - -* The use of sexualized language or imagery -* Personal attacks -* Trolling or insulting/derogatory comments -* Public or private harassment -* Publishing other's private information, such as physical or electronic - addresses, without explicit permission -* Other unethical or unprofessional conduct. - -Project maintainers have the right and responsibility to remove, edit, or reject -comments, commits, code, wiki edits, issues, and other contributions that are -not aligned to this Code of Conduct. By adopting this Code of Conduct, project -maintainers commit themselves to fairly and consistently applying these -principles to every aspect of managing this project. Project maintainers who do -not follow or enforce the Code of Conduct may be permanently removed from the -project team. - -This code of conduct applies both within project spaces and in public spaces -when an individual is representing the project or its community. - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by opening an issue or contacting one or more of the project maintainers. - -This Code of Conduct is adapted from the -[Contributor Covenant](http://contributor-covenant.org), version 1.2.0, -available at http://contributor-covenant.org/version/1/2/0/. -raphf -Michael Wallner -Copyright (c) 2013, Michael Wallner . -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# ext-raphf - -[![Build Status](https://travis-ci.org/m6w6/ext-raphf.svg?branch=v1.1.x)](https://travis-ci.org/m6w6/ext-raphf) - -The "Resource and Persistent Handle Factory" extension provides facilities to manage those in a convenient manner. - -## Documentation - -See the [online markdown reference](https://mdref.m6w6.name/raphf). - -Known issues are listed in [BUGS](./BUGS) and future ideas can be found in [TODO](./TODO). - -## Installing - -### PECL - - pecl install raphf - -### PHARext - -Watch out for [PECL replicates](https://replicator.pharext.org?raphf) -and pharext packages attached to [releases](./releases). - -### Checkout - - git clone github.com:m6w6/ext-raphf - cd ext-raphf - /path/to/phpize - ./configure --with-php-config=/path/to/php-config - make - sudo make install - -## ChangeLog - -A comprehensive list of changes can be obtained from the -[PECL website](https://pecl.php.net/package-changelog.php?package=raphf). - -## License - -ext-raphf is licensed under the 2-Clause-BSD license, which can be found in -the accompanying [LICENSE](./LICENSE) file. - -## Contributing - -All forms of contribution are welcome! Please see the bundled -[CONTRIBUTING](./CONTRIBUTING.md) note for the general principles followed. - -The list of past and current contributors is maintained in [THANKS](./THANKS). -Thanks go to the following people, who have contributed to this project: - -Anatol Belski -Remi Collet -* TTL -# Doxyfile 1.8.10 - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- -DOXYFILE_ENCODING = UTF-8 -PROJECT_NAME = "Resource and persistent handle factory API" -PROJECT_NUMBER = -PROJECT_BRIEF = "A facility to manage possibly persistent resources with a comprehensible API. Provides simliar functionality like the zend_list API, but with more flexiblity and freedom." -PROJECT_LOGO = raphf.png -OUTPUT_DIRECTORY = -CREATE_SUBDIRS = NO -ALLOW_UNICODE_NAMES = NO -OUTPUT_LANGUAGE = English -BRIEF_MEMBER_DESC = YES -REPEAT_BRIEF = YES -ABBREVIATE_BRIEF = -ALWAYS_DETAILED_SEC = NO -INLINE_INHERITED_MEMB = NO -FULL_PATH_NAMES = YES -STRIP_FROM_PATH = -STRIP_FROM_INC_PATH = -SHORT_NAMES = NO -JAVADOC_AUTOBRIEF = YES -QT_AUTOBRIEF = NO -MULTILINE_CPP_IS_BRIEF = NO -INHERIT_DOCS = YES -SEPARATE_MEMBER_PAGES = NO -TAB_SIZE = 4 -ALIASES = -TCL_SUBST = -OPTIMIZE_OUTPUT_FOR_C = YES -OPTIMIZE_OUTPUT_JAVA = NO -OPTIMIZE_FOR_FORTRAN = NO -OPTIMIZE_OUTPUT_VHDL = NO -EXTENSION_MAPPING = no_extension=md -MARKDOWN_SUPPORT = YES -AUTOLINK_SUPPORT = YES -BUILTIN_STL_SUPPORT = NO -CPP_CLI_SUPPORT = NO -SIP_SUPPORT = NO -IDL_PROPERTY_SUPPORT = YES -DISTRIBUTE_GROUP_DOC = NO -GROUP_NESTED_COMPOUNDS = NO -SUBGROUPING = YES -INLINE_GROUPED_CLASSES = NO -INLINE_SIMPLE_STRUCTS = YES -TYPEDEF_HIDES_STRUCT = NO -LOOKUP_CACHE_SIZE = 0 -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- -EXTRACT_ALL = YES -EXTRACT_PRIVATE = NO -EXTRACT_PACKAGE = NO -EXTRACT_STATIC = NO -EXTRACT_LOCAL_CLASSES = NO -EXTRACT_LOCAL_METHODS = NO -EXTRACT_ANON_NSPACES = NO -HIDE_UNDOC_MEMBERS = NO -HIDE_UNDOC_CLASSES = NO -HIDE_FRIEND_COMPOUNDS = NO -HIDE_IN_BODY_DOCS = NO -INTERNAL_DOCS = NO -CASE_SENSE_NAMES = YES -HIDE_SCOPE_NAMES = NO -HIDE_COMPOUND_REFERENCE= NO -SHOW_INCLUDE_FILES = YES -SHOW_GROUPED_MEMB_INC = NO -FORCE_LOCAL_INCLUDES = NO -INLINE_INFO = YES -SORT_MEMBER_DOCS = YES -SORT_BRIEF_DOCS = NO -SORT_MEMBERS_CTORS_1ST = NO -SORT_GROUP_NAMES = NO -SORT_BY_SCOPE_NAME = NO -STRICT_PROTO_MATCHING = NO -GENERATE_TODOLIST = YES -GENERATE_TESTLIST = YES -GENERATE_BUGLIST = YES -GENERATE_DEPRECATEDLIST= YES -ENABLED_SECTIONS = -MAX_INITIALIZER_LINES = 30 -SHOW_USED_FILES = YES -SHOW_FILES = YES -SHOW_NAMESPACES = YES -FILE_VERSION_FILTER = -LAYOUT_FILE = -CITE_BIB_FILES = -#--------------------------------------------------------------------------- -# Configuration options related to warning and progress messages -#--------------------------------------------------------------------------- -QUIET = NO -WARNINGS = YES -WARN_IF_UNDOCUMENTED = YES -WARN_IF_DOC_ERROR = YES -WARN_NO_PARAMDOC = NO -WARN_FORMAT = "$file:$line: $text" -WARN_LOGFILE = -#--------------------------------------------------------------------------- -# Configuration options related to the input files -#--------------------------------------------------------------------------- -INPUT = README.md CONTRIBUTING.md php_raphf.h src -INPUT_ENCODING = UTF-8 -FILE_PATTERNS = -RECURSIVE = NO -EXCLUDE = -EXCLUDE_SYMLINKS = NO -EXCLUDE_PATTERNS = -EXCLUDE_SYMBOLS = -EXAMPLE_PATH = -EXAMPLE_PATTERNS = -EXAMPLE_RECURSIVE = NO -IMAGE_PATH = -INPUT_FILTER = -FILTER_PATTERNS = -FILTER_SOURCE_FILES = NO -FILTER_SOURCE_PATTERNS = -USE_MDFILE_AS_MAINPAGE = README.md -#--------------------------------------------------------------------------- -# Configuration options related to source browsing -#--------------------------------------------------------------------------- -SOURCE_BROWSER = NO -INLINE_SOURCES = NO -STRIP_CODE_COMMENTS = YES -REFERENCED_BY_RELATION = YES -REFERENCES_RELATION = NO -REFERENCES_LINK_SOURCE = YES -SOURCE_TOOLTIPS = YES -USE_HTAGS = NO -VERBATIM_HEADERS = YES -#--------------------------------------------------------------------------- -# Configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- -ALPHABETICAL_INDEX = YES -COLS_IN_ALPHA_INDEX = 5 -IGNORE_PREFIX = -#--------------------------------------------------------------------------- -# Configuration options related to the HTML output -#--------------------------------------------------------------------------- -GENERATE_HTML = YES -HTML_OUTPUT = . -HTML_FILE_EXTENSION = .html -HTML_HEADER = -HTML_FOOTER = -HTML_STYLESHEET = -HTML_EXTRA_STYLESHEET = -HTML_EXTRA_FILES = BUGS CONTRIBUTING.md LICENSE THANKS TODO -HTML_COLORSTYLE_HUE = 220 -HTML_COLORSTYLE_SAT = 100 -HTML_COLORSTYLE_GAMMA = 80 -HTML_TIMESTAMP = NO -HTML_DYNAMIC_SECTIONS = NO -HTML_INDEX_NUM_ENTRIES = 100 -GENERATE_DOCSET = NO -DOCSET_FEEDNAME = "Doxygen generated docs" -DOCSET_BUNDLE_ID = org.doxygen.Project -DOCSET_PUBLISHER_ID = org.doxygen.Publisher -DOCSET_PUBLISHER_NAME = Publisher -GENERATE_HTMLHELP = NO -CHM_FILE = -HHC_LOCATION = -GENERATE_CHI = NO -CHM_INDEX_ENCODING = -BINARY_TOC = NO -TOC_EXPAND = NO -GENERATE_QHP = NO -QCH_FILE = -QHP_NAMESPACE = org.doxygen.Project -QHP_VIRTUAL_FOLDER = doc -QHP_CUST_FILTER_NAME = -QHP_CUST_FILTER_ATTRS = -QHP_SECT_FILTER_ATTRS = -QHG_LOCATION = -GENERATE_ECLIPSEHELP = NO -ECLIPSE_DOC_ID = org.doxygen.Project -DISABLE_INDEX = NO -GENERATE_TREEVIEW = YES -ENUM_VALUES_PER_LINE = 4 -TREEVIEW_WIDTH = 250 -EXT_LINKS_IN_WINDOW = NO -FORMULA_FONTSIZE = 10 -FORMULA_TRANSPARENT = YES -USE_MATHJAX = NO -MATHJAX_FORMAT = HTML-CSS -MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest -MATHJAX_EXTENSIONS = -MATHJAX_CODEFILE = -SEARCHENGINE = YES -SERVER_BASED_SEARCH = NO -EXTERNAL_SEARCH = NO -SEARCHENGINE_URL = -SEARCHDATA_FILE = searchdata.xml -EXTERNAL_SEARCH_ID = -EXTRA_SEARCH_MAPPINGS = -#--------------------------------------------------------------------------- -# Configuration options related to the LaTeX output -#--------------------------------------------------------------------------- -GENERATE_LATEX = NO -LATEX_OUTPUT = latex -LATEX_CMD_NAME = latex -MAKEINDEX_CMD_NAME = makeindex -COMPACT_LATEX = NO -PAPER_TYPE = a4 -EXTRA_PACKAGES = -LATEX_HEADER = -LATEX_FOOTER = -LATEX_EXTRA_STYLESHEET = -LATEX_EXTRA_FILES = -PDF_HYPERLINKS = YES -USE_PDFLATEX = YES -LATEX_BATCHMODE = NO -LATEX_HIDE_INDICES = NO -LATEX_SOURCE_CODE = NO -LATEX_BIB_STYLE = plain -#--------------------------------------------------------------------------- -# Configuration options related to the RTF output -#--------------------------------------------------------------------------- -GENERATE_RTF = NO -RTF_OUTPUT = rtf -COMPACT_RTF = NO -RTF_HYPERLINKS = NO -RTF_STYLESHEET_FILE = -RTF_EXTENSIONS_FILE = -RTF_SOURCE_CODE = NO -#--------------------------------------------------------------------------- -# Configuration options related to the man page output -#--------------------------------------------------------------------------- -GENERATE_MAN = NO -MAN_OUTPUT = man -MAN_EXTENSION = .3 -MAN_SUBDIR = -MAN_LINKS = NO -#--------------------------------------------------------------------------- -# Configuration options related to the XML output -#--------------------------------------------------------------------------- -GENERATE_XML = NO -XML_OUTPUT = xml -XML_PROGRAMLISTING = YES -#--------------------------------------------------------------------------- -# Configuration options related to the DOCBOOK output -#--------------------------------------------------------------------------- -GENERATE_DOCBOOK = NO -DOCBOOK_OUTPUT = docbook -DOCBOOK_PROGRAMLISTING = NO -#--------------------------------------------------------------------------- -# Configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- -GENERATE_AUTOGEN_DEF = NO -#--------------------------------------------------------------------------- -# Configuration options related to the Perl module output -#--------------------------------------------------------------------------- -GENERATE_PERLMOD = NO -PERLMOD_LATEX = NO -PERLMOD_PRETTY = YES -PERLMOD_MAKEVAR_PREFIX = -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- -ENABLE_PREPROCESSING = YES -MACRO_EXPANSION = YES -EXPAND_ONLY_PREDEF = NO -SEARCH_INCLUDES = YES -INCLUDE_PATH = -INCLUDE_FILE_PATTERNS = -PREDEFINED = DOXYGEN \ - TSRMLS_C= \ - TSRMLS_D= \ - TSRMLS_CC= \ - TSRMLS_DC= \ - PHP_RAPHF_API= -EXPAND_AS_DEFINED = -SKIP_FUNCTION_MACROS = YES -#--------------------------------------------------------------------------- -# Configuration options related to external references -#--------------------------------------------------------------------------- -TAGFILES = -GENERATE_TAGFILE = -ALLEXTERNALS = NO -EXTERNAL_GROUPS = YES -EXTERNAL_PAGES = YES -PERL_PATH = /usr/bin/perl -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- -CLASS_DIAGRAMS = YES -MSCGEN_PATH = -DIA_PATH = -HIDE_UNDOC_RELATIONS = YES -HAVE_DOT = YES -DOT_NUM_THREADS = 0 -DOT_FONTNAME = Helvetica -DOT_FONTSIZE = 10 -DOT_FONTPATH = -CLASS_GRAPH = NO -COLLABORATION_GRAPH = YES -GROUP_GRAPHS = YES -UML_LOOK = NO -UML_LIMIT_NUM_FIELDS = 10 -TEMPLATE_RELATIONS = NO -INCLUDE_GRAPH = YES -INCLUDED_BY_GRAPH = YES -CALL_GRAPH = YES -CALLER_GRAPH = YES -GRAPHICAL_HIERARCHY = YES -DIRECTORY_GRAPH = YES -DOT_IMAGE_FORMAT = png -INTERACTIVE_SVG = NO -DOT_PATH = -DOTFILE_DIRS = -MSCFILE_DIRS = -DIAFILE_DIRS = -PLANTUML_JAR_PATH = -PLANTUML_INCLUDE_PATH = -DOT_GRAPH_MAX_NODES = 50 -MAX_DOT_GRAPH_DEPTH = 0 -DOT_TRANSPARENT = NO -DOT_MULTI_TARGETS = NO -GENERATE_LEGEND = YES -DOT_CLEANUP = YES -sinclude(config0.m4) -PHP_ARG_ENABLE(raphf, whether to enable raphf support, -[ --enable-raphf Enable resource and persistent handles factory support]) - -if test "$PHP_RAPHF" != "no"; then - PHP_RAPHF_SRCDIR=PHP_EXT_SRCDIR(raphf) - PHP_RAPHF_BUILDDIR=PHP_EXT_BUILDDIR(raphf) - - PHP_ADD_INCLUDE($PHP_RAPHF_SRCDIR/src) - PHP_ADD_BUILD_DIR($PHP_RAPHF_BUILDDIR/src) - - PHP_RAPHF_HEADERS=`(cd $PHP_RAPHF_SRCDIR/src && echo *.h)` - PHP_RAPHF_SOURCES=`(cd $PHP_RAPHF_SRCDIR && echo src/*.c)` - - PHP_NEW_EXTENSION(raphf, $PHP_RAPHF_SOURCES, $ext_shared) - PHP_INSTALL_HEADERS(ext/raphf, php_raphf.h $PHP_RAPHF_HEADERS) - - PHP_SUBST(PHP_RAPHF_HEADERS) - PHP_SUBST(PHP_RAPHF_SOURCES) - - PHP_SUBST(PHP_RAPHF_SRCDIR) - PHP_SUBST(PHP_RAPHF_BUILDDIR) - - PHP_ADD_MAKEFILE_FRAGMENT -fi -ARG_ENABLE("raphf", "for raphf support", "no"); - -if (PHP_RAPHF == "yes") { - var PHP_RAPHF_HEADERS=glob("src/*.h"), PHP_RAPHF_SOURCES=glob("src/*.c"); - - EXTENSION("raphf", PHP_RAPHF_SOURCES); - PHP_INSTALL_HEADERS("ext/raphf", "php_propro.h"); - for (var i=0; i$@ <$< - -$(all_targets): raphf-build-headers -clean: raphf-clean-headers - -.PHONY: raphf-build-headers -raphf-build-headers: $(PHP_RAPHF_HEADERS) - -.PHONY: raphf-clean-headers -raphf-clean-headers: - -rm -f $(PHP_RAPHF_HEADERS) -/* - +--------------------------------------------------------------------+ - | PECL :: raphf | - +--------------------------------------------------------------------+ - | Redistribution and use in source and binary forms, with or without | - | modification, are permitted provided that the conditions mentioned | - | in the accompanying LICENSE file are met. | - +--------------------------------------------------------------------+ - | Copyright (c) 2013, Michael Wallner | - +--------------------------------------------------------------------+ -*/ - -#ifndef PHP_RAPHF_H -#define PHP_RAPHF_H - -extern zend_module_entry raphf_module_entry; -#define phpext_raphf_ptr &raphf_module_entry - -#define PHP_RAPHF_VERSION "1.1.2" - -#ifdef PHP_WIN32 -# define PHP_RAPHF_API __declspec(dllexport) -#elif defined(__GNUC__) && __GNUC__ >= 4 -# define PHP_RAPHF_API extern __attribute__ ((visibility("default"))) -#else -# define PHP_RAPHF_API extern -#endif - -#ifdef ZTS -# include "TSRM.h" -#endif - -#include "php_raphf_api.h" - -#endif /* PHP_RAPHF_H */ - - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - * vim600: noet sw=4 ts=4 fdm=marker - * vim<600: noet sw=4 ts=4 - */ -×]_ÏÏ¢Â]ºUwåŽKÈٞ’¢GBMB \ No newline at end of file diff --git a/src/php_pq_callback.c b/src/php_pq_callback.c index 63f2edc..695d592 100644 --- a/src/php_pq_callback.c +++ b/src/php_pq_callback.c @@ -29,8 +29,11 @@ void php_pq_callback_dtor(php_pq_callback_t *cb) if (cb->fci.size > 0) { zend_fcall_info_args_clear(&cb->fci, 1); zval_ptr_dtor(&cb->fci.function_name); - if (cb->fci.object_ptr) { - zval_ptr_dtor(&cb->fci.object_ptr); + if (cb->fci.object) { + zval tmp; + + ZVAL_OBJ(&tmp, cb->fci.object); + zval_ptr_dtor(&tmp); } cb->fci.size = 0; } @@ -38,34 +41,51 @@ void php_pq_callback_dtor(php_pq_callback_t *cb) void php_pq_callback_addref(php_pq_callback_t *cb) { - Z_ADDREF_P(cb->fci.function_name); - if (cb->fci.object_ptr) { - Z_ADDREF_P(cb->fci.object_ptr); + Z_TRY_ADDREF(cb->fci.function_name); + if (cb->fci.object) { + ++GC_REFCOUNT(cb->fci.object); } } -zval *php_pq_callback_to_zval(php_pq_callback_t *cb) +zval *php_pq_callback_to_zval(php_pq_callback_t *cb, zval *tmp) { - zval *zcb; - php_pq_callback_addref(cb); - if (cb->fci.object_ptr) { - MAKE_STD_ZVAL(zcb); - array_init_size(zcb, 2); - add_next_index_zval(zcb, cb->fci.object_ptr); - add_next_index_zval(zcb, cb->fci.function_name); - } else { - zcb = cb->fci.function_name; + if (cb->fci.object) { + zval zo; + + array_init_size(tmp, 2); + ZVAL_OBJ(&zo, cb->fci.object); + add_next_index_zval(tmp, &zo); + add_next_index_zval(tmp, &cb->fci.function_name); + + return tmp; + } + + return &cb->fci.function_name; +} + +zval *php_pq_callback_to_zval_no_addref(php_pq_callback_t *cb, zval *tmp) +{ + if (cb->fci.object) { + zval zo; + + array_init_size(tmp, 2); + ZVAL_OBJ(&zo, cb->fci.object); + add_next_index_zval(tmp, &zo); + add_next_index_zval(tmp, &cb->fci.function_name); + + return tmp; } - return zcb; + return &cb->fci.function_name; } -zend_bool php_pq_callback_is_locked(php_pq_callback_t *cb TSRMLS_DC) +zend_bool php_pq_callback_is_locked(php_pq_callback_t *cb) { + /* TODO: fixed in php7? if (cb->fci.size > 0 && Z_TYPE_P(cb->fci.function_name) == IS_OBJECT) { - const zend_function *closure = zend_get_closure_method_def(cb->fci.function_name TSRMLS_CC); + const zend_function *closure = zend_get_closure_method_def(cb->fci.function_name); if (closure->type == ZEND_USER_FUNCTION) { zend_execute_data *ex = EG(current_execute_data); @@ -78,6 +98,7 @@ zend_bool php_pq_callback_is_locked(php_pq_callback_t *cb TSRMLS_DC) } } } + */ return 0; } diff --git a/src/php_pq_callback.h b/src/php_pq_callback.h index 2edf6d5..da71143 100644 --- a/src/php_pq_callback.h +++ b/src/php_pq_callback.h @@ -23,9 +23,10 @@ typedef struct php_pq_callback { extern void php_pq_callback_dtor(php_pq_callback_t *cb); extern void php_pq_callback_addref(php_pq_callback_t *cb); -extern zval *php_pq_callback_to_zval(php_pq_callback_t *cb); -extern zend_bool php_pq_callback_is_locked(php_pq_callback_t *cb TSRMLS_DC); -extern void php_pq_callback_recurse(php_pq_callback_t *old, php_pq_callback_t *new TSRMLS_DC); +extern zval *php_pq_callback_to_zval(php_pq_callback_t *cb, zval *tmp); +extern zval *php_pq_callback_to_zval_no_addref(php_pq_callback_t *cb, zval *tmp); +extern zend_bool php_pq_callback_is_locked(php_pq_callback_t *cb); +extern void php_pq_callback_recurse(php_pq_callback_t *old, php_pq_callback_t *new); #endif diff --git a/src/php_pq_misc.c b/src/php_pq_misc.c index a3db8bb..10defed 100644 --- a/src/php_pq_misc.c +++ b/src/php_pq_misc.c @@ -52,33 +52,37 @@ const char *php_pq_strmode(long mode) } } -int php_pq_compare_index(const void *lptr, const void *rptr TSRMLS_DC) +int php_pq_compare_index(const void *lptr, const void *rptr) { - const Bucket *l = *(const Bucket **) lptr; - const Bucket *r = *(const Bucket **) rptr; + zend_ulong l = ((const Bucket *) lptr)->h; + zend_ulong r = ((const Bucket *) rptr)->h; - if (l->h < r->h) { + if (l < r) { return -1; } - if (l->h > r->h) { + if (l > r) { return 1; } return 0; } +void php_pq_hash_ptr_dtor(zval *p) +{ + efree(Z_PTR_P(p)); +} + zend_class_entry *php_pqdt_class_entry; ZEND_BEGIN_ARG_INFO_EX(ai_pqdt_to_string, 0, 0, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(pqdt, __toString) { - zval *rv = NULL; + zval rv, tmp; - zend_call_method_with_1_params(&getThis(), php_pqdt_class_entry, NULL, "format", &rv, - zend_read_property(php_pqdt_class_entry, getThis(), ZEND_STRL("format"), 0 TSRMLS_CC)); - if (rv) { - RETVAL_ZVAL(rv, 1, 1); - } + ZVAL_NULL(&rv); + zend_call_method_with_1_params(getThis(), php_pqdt_class_entry, NULL, "format", &rv, + zend_read_property(php_pqdt_class_entry, getThis(), ZEND_STRL("format"), 0, &tmp)); + RETVAL_ZVAL(&rv, 1, 1); } ZEND_BEGIN_ARG_INFO_EX(ai_pqdt_create_from_format, 0, 0, 2) @@ -90,16 +94,16 @@ static PHP_METHOD(pqdt, createFromFormat) { zend_error_handling zeh; char *fmt_str, *dt_str; - int fmt_len, dt_len; + size_t fmt_len, dt_len; zval *ztz = NULL; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|O", &fmt_str, &fmt_len, &dt_str, &dt_len, &ztz, php_date_get_timezone_ce()); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "ss|O", &fmt_str, &fmt_len, &dt_str, &dt_len, &ztz, php_date_get_timezone_ce()); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqdt_from_string(return_value, fmt_str, dt_str, dt_len, "Y-m-d H:i:s.uO", ztz TSRMLS_CC); + php_pqdt_from_string(return_value, fmt_str, dt_str, dt_len, "Y-m-d H:i:s.uO", ztz); } } @@ -110,54 +114,47 @@ static zend_function_entry php_pqdt_methods[] = { {0} }; -zval *php_pqdt_from_string(zval *zv, char *input_fmt, char *dt_str, size_t dt_len, char *output_fmt, zval *ztimezone TSRMLS_DC) +zval *php_pqdt_from_string(zval *zv, char *input_fmt, char *dt_str, size_t dt_len, char *output_fmt, zval *ztimezone) { php_date_obj *dobj; - if (!zv) { - MAKE_STD_ZVAL(zv); - } - - php_date_instantiate(php_pqdt_class_entry, zv TSRMLS_CC); - dobj = zend_object_store_get_object(zv TSRMLS_CC); - if (!php_date_initialize(dobj, dt_str, dt_len, input_fmt, ztimezone, 1 TSRMLS_CC)) { + php_date_instantiate(php_pqdt_class_entry, zv); + dobj = php_date_obj_from_obj(Z_OBJ_P(zv)); + if (!php_date_initialize(dobj, dt_str, dt_len, input_fmt, ztimezone, 1)) { zval_dtor(zv); ZVAL_NULL(zv); } else if (output_fmt) { - zend_update_property_string(php_pqdt_class_entry, zv, ZEND_STRL("format"), output_fmt TSRMLS_CC); + zend_update_property_string(php_pqdt_class_entry, zv, ZEND_STRL("format"), output_fmt); } return zv; } -void php_pqdt_to_string(zval *zdt, const char *format, char **str_buf, size_t *str_len TSRMLS_DC) +zend_string *php_pqdt_to_string(zval *zdt, const char *format) { zval rv; - INIT_PZVAL(&rv); ZVAL_NULL(&rv); if (Z_OBJ_HT_P(zdt)->cast_object - && SUCCESS == Z_OBJ_HT_P(zdt)->cast_object(zdt, &rv, IS_STRING TSRMLS_CC) + && SUCCESS == Z_OBJ_HT_P(zdt)->cast_object(zdt, &rv, IS_STRING) ) { - *str_len = Z_STRLEN(rv); - *str_buf = Z_STRVAL(rv); - } else if (instanceof_function(Z_OBJCE_P(zdt), php_date_get_date_ce() TSRMLS_CC)) { - zval *rv = NULL, *zfmt; - - MAKE_STD_ZVAL(zfmt); - ZVAL_STRING(zfmt, format, 1); - zend_call_method_with_1_params(&zdt, Z_OBJCE_P(zdt), NULL, "format", &rv, zfmt); + return Z_STR(rv); + } else if (instanceof_function(Z_OBJCE_P(zdt), php_date_get_date_ce())) { + zval rv, zfmt; + + ZVAL_NULL(&rv); + ZVAL_STRING(&zfmt, format); + zend_call_method_with_1_params(zdt, Z_OBJCE_P(zdt), NULL, "format", &rv, &zfmt); zval_ptr_dtor(&zfmt); - if (rv) { - if (Z_TYPE_P(rv) == IS_STRING) { - *str_len = Z_STRLEN_P(rv); - *str_buf = estrndup(Z_STRVAL_P(rv), *str_len); - } - zval_ptr_dtor(&rv); + if (Z_TYPE(rv) == IS_STRING) { + return Z_STR(rv); } + zval_ptr_dtor(&rv); } + + return NULL; } zend_class_entry *php_pqconv_class_entry; @@ -185,27 +182,27 @@ zend_function_entry php_pqconv_methods[] = { PHP_MINIT_FUNCTION(pq_misc) { - zend_class_entry **json, ce = {0}; + zend_class_entry *json, ce = {0}; INIT_NS_CLASS_ENTRY(ce, "pq", "Converter", php_pqconv_methods); - php_pqconv_class_entry = zend_register_internal_interface(&ce TSRMLS_CC); + php_pqconv_class_entry = zend_register_internal_interface(&ce); memset(&ce, 0, sizeof(ce)); INIT_NS_CLASS_ENTRY(ce ,"pq", "DateTime", php_pqdt_methods); - php_pqdt_class_entry = zend_register_internal_class_ex(&ce, php_date_get_date_ce(), "DateTime" TSRMLS_CC); + php_pqdt_class_entry = zend_register_internal_class_ex(&ce, php_date_get_date_ce()); - zend_declare_property_stringl(php_pqdt_class_entry, ZEND_STRL("format"), ZEND_STRL("Y-m-d H:i:s.uO"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_stringl(php_pqdt_class_entry, ZEND_STRL("format"), ZEND_STRL("Y-m-d H:i:s.uO"), ZEND_ACC_PUBLIC); /* stop reading this file right here! */ - if (SUCCESS == zend_hash_find(CG(class_table), ZEND_STRS("jsonserializable"), (void *) &json)) { - zend_class_implements(php_pqdt_class_entry TSRMLS_CC, 1, *json); + if ((json = zend_hash_str_find_ptr(CG(class_table), ZEND_STRL("jsonserializable")))) { + zend_class_implements(php_pqdt_class_entry, 1, json); } return SUCCESS; } typedef struct _HashTableList { - HashTable ht; + zval arr; struct _HashTableList *parent; } HashTableList; @@ -213,9 +210,6 @@ typedef struct _ArrayParserState { const char *ptr, *end; HashTableList *list; php_pqres_t *res; -#ifdef ZTS - void ***ts; -#endif Oid typ; unsigned quotes:1; unsigned escaped:1; @@ -224,7 +218,6 @@ typedef struct _ArrayParserState { static char caa(ArrayParserState *a, const char *any, unsigned advance) { const char *p = any; - TSRMLS_FETCH_FROM_CTX(a->ts); do { if (*p == *a->ptr) { @@ -233,38 +226,31 @@ static char caa(ArrayParserState *a, const char *any, unsigned advance) } } while (*++p); - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to parse array: expected one of '%s', got '%c'", any, *a->ptr); \ + php_error_docref(NULL, E_WARNING, "Failed to parse array: expected one of '%s', got '%c'", any, *a->ptr); \ return 0; } static ZEND_RESULT_CODE add_element(ArrayParserState *a, const char *start) { - zval *zelem; - size_t el_len = a->ptr - start; - char *el_str = estrndup(start, el_len); - TSRMLS_FETCH_FROM_CTX(a->ts); + zval zelem; + zend_string *zstr = zend_string_init(start, a->ptr - start, 0); if (a->quotes) { - int tmp_len = el_len; - - php_stripslashes(el_str, &tmp_len TSRMLS_CC); - el_len = tmp_len; - } else if ((a->ptr - start == 4) && !strncmp(start, "NULL", 4)) { - efree(el_str); - el_str = NULL; - el_len = 0; - } - - if (!el_str) { - MAKE_STD_ZVAL(zelem); - ZVAL_NULL(zelem); + php_stripslashes(zstr); + ZVAL_STR(&zelem, zstr); + } else if (!zend_string_equals_literal(zstr, "NULL")) { + ZVAL_STR(&zelem, zstr); } else { - zelem = php_pqres_typed_zval(a->res, el_str, el_len, a->typ TSRMLS_CC); + zend_string_release(zstr); + ZVAL_NULL(&zelem); + } - efree(el_str); + if (!ZVAL_IS_NULL(&zelem)) { + php_pqres_typed_zval(a->res, a->typ, &zelem); } - return zend_hash_next_index_insert(&a->list->ht, &zelem, sizeof(zval *), NULL); + add_next_index_zval(&a->list->arr, &zelem); + return SUCCESS; } static ZEND_RESULT_CODE parse_array(ArrayParserState *a); @@ -272,7 +258,6 @@ static ZEND_RESULT_CODE parse_array(ArrayParserState *a); static ZEND_RESULT_CODE parse_element(ArrayParserState *a, char delim) { const char *el; - TSRMLS_FETCH_FROM_CTX(a->ts); switch (*a->ptr) { case '{': @@ -301,7 +286,7 @@ static ZEND_RESULT_CODE parse_element(ArrayParserState *a, char delim) ++a->ptr; return SUCCESS; } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to parse element, unexpected quote: '%.*s'", (int) (a->ptr - el), el); + php_error_docref(NULL, E_WARNING, "Failed to parse element, unexpected quote: '%.*s'", (int) (a->ptr - el), el); return FAILURE; } break; @@ -321,14 +306,13 @@ static ZEND_RESULT_CODE parse_element(ArrayParserState *a, char delim) } } - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to parse element, reached end of input"); + php_error_docref(NULL, E_WARNING, "Failed to parse element, reached end of input"); return FAILURE; } static ZEND_RESULT_CODE parse_elements(ArrayParserState *a) { char delims[] = {'}', PHP_PQ_DELIM_OF_ARRAY(a->typ), 0}; - TSRMLS_FETCH_FROM_CTX(a->ts); while (SUCCESS == parse_element(a, delims[1])) { switch (caa(a, delims, 0)) { @@ -340,7 +324,7 @@ static ZEND_RESULT_CODE parse_elements(ArrayParserState *a) default: if (!*++a->ptr) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to parse elements, reached end of input"); + php_error_docref(NULL, E_WARNING, "Failed to parse elements, reached end of input"); return FAILURE; } break; @@ -359,17 +343,10 @@ static ZEND_RESULT_CODE parse_array(ArrayParserState *a) } list = ecalloc(1, sizeof(*list)); - ZEND_INIT_SYMTABLE(&list->ht); + array_init(&list->arr); if (a->list) { - zval *zcur; - - MAKE_STD_ZVAL(zcur); - Z_TYPE_P(zcur) = IS_ARRAY; - Z_ARRVAL_P(zcur) = &list->ht; - - zend_hash_next_index_insert(&a->list->ht, &zcur, sizeof(zval *), NULL); - + add_next_index_zval(&a->list->arr, &list->arr); list->parent = a->list; } a->list = list; @@ -382,8 +359,12 @@ static ZEND_RESULT_CODE parse_array(ArrayParserState *a) return FAILURE; } + /* step one level back up */ if (a->list->parent) { - a->list = a->list->parent; + HashTableList *l = a->list->parent; + + efree(a->list); + a->list = l; } return SUCCESS; @@ -393,7 +374,6 @@ HashTable *php_pq_parse_array(php_pqres_t *res, const char *val_str, size_t val_ { HashTable *ht = NULL; ArrayParserState a = {0}; - TSRMLS_SET_CTX(a.ts); a.typ = typ; a.ptr = val_str; @@ -404,7 +384,7 @@ HashTable *php_pq_parse_array(php_pqres_t *res, const char *val_str, size_t val_ while (a.list) { HashTableList *l = a.list->parent; - zend_hash_destroy(&a.list->ht); + zval_dtor(&a.list->arr); efree(a.list); a.list = l; } @@ -412,12 +392,16 @@ HashTable *php_pq_parse_array(php_pqres_t *res, const char *val_str, size_t val_ } if (*a.ptr) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Trailing input: '%s'", a.ptr); + php_error_docref(NULL, E_NOTICE, "Trailing input: '%s'", a.ptr); } - do { - ht = &a.list->ht; - } while ((a.list = a.list->parent)); + while (a.list) { + HashTableList *l = a.list->parent; + + ht = Z_ARRVAL(a.list->arr); + efree(a.list); + a.list = l; + } return ht; } diff --git a/src/php_pq_misc.h b/src/php_pq_misc.h index 9fc086a..b25f871 100644 --- a/src/php_pq_misc.h +++ b/src/php_pq_misc.h @@ -27,12 +27,10 @@ typedef enum { #include "php_pqres.h" -/* TSRM morony */ -#if PHP_VERSION_ID >= 50700 -# define z_is_true(z) zend_is_true(z TSRMLS_CC) -#else -# define z_is_true zend_is_true -#endif +#define z_is_true zend_is_true +#define smart_str_s(ss) (ss)->s +#define smart_str_v(ss) (ss)->s->val +#define smart_str_l(ss) (ss)->s->len /* trim LF from EOL */ extern char *php_pq_rtrim(char *e); @@ -41,18 +39,21 @@ extern char *php_pq_rtrim(char *e); extern const char *php_pq_strmode(long mode); /* compare array index */ -extern int php_pq_compare_index(const void *lptr, const void *rptr TSRMLS_DC); +extern int php_pq_compare_index(const void *lptr, const void *rptr); + +/* free zval ptr values (as hash dtor) */ +extern void php_pq_hash_ptr_dtor(zval *p); #define PHP_PQerrorMessage(c) php_pq_rtrim(PQerrorMessage((c))) #define PHP_PQresultErrorMessage(r) php_pq_rtrim(PQresultErrorMessage((r))) extern zend_class_entry *php_pqdt_class_entry; -extern zval *php_pqdt_from_string(zval *zv, char *input_fmt, char *dt_str, size_t dt_len, char *output_fmt, zval *ztimezone TSRMLS_DC); -extern void php_pqdt_to_string(zval *zdt, const char *format, char **str_buf, size_t *str_len TSRMLS_DC); +extern zval *php_pqdt_from_string(zval *zv, char *input_fmt, char *dt_str, size_t dt_len, char *output_fmt, zval *ztimezone); +extern zend_string *php_pqdt_to_string(zval *zdt, const char *format); extern zend_class_entry *php_pqconv_class_entry; -extern HashTable *php_pq_parse_array(php_pqres_t *res, const char *val_str, size_t val_len, Oid typ TSRMLS_DC); +extern HashTable *php_pq_parse_array(php_pqres_t *res, const char *val_str, size_t val_len, Oid typ); extern PHP_MINIT_FUNCTION(pq_misc); diff --git a/src/php_pq_module.c b/src/php_pq_module.c index 989b7c8..53ec94c 100644 --- a/src/php_pq_module.c +++ b/src/php_pq_module.c @@ -33,14 +33,23 @@ #include "php_pqtxn.h" #include "php_pqtypes.h" +ZEND_DECLARE_MODULE_GLOBALS(php_pq); + +static void php_pq_globals_init_once(zend_php_pq_globals *G) +{ + memset(G, 0, sizeof(*G)); +} + #define PHP_MINIT_CALL(i) do { \ - if (SUCCESS != PHP_MINIT(i)(type, module_number TSRMLS_CC)) { \ + if (SUCCESS != PHP_MINIT(i)(type, module_number)) { \ return FAILURE; \ } \ } while(0) static PHP_MINIT_FUNCTION(pq) { + ZEND_INIT_MODULE_GLOBALS(php_pq, php_pq_globals_init_once, NULL); + PHP_MINIT_CALL(pq_misc); PHP_MINIT_CALL(pqexc); @@ -56,19 +65,17 @@ static PHP_MINIT_FUNCTION(pq) PHP_MINIT_CALL(pqcopy); PHP_MINIT_CALL(pqlob); - return php_persistent_handle_provide(ZEND_STRL("pq\\Connection"), php_pqconn_get_resource_factory_ops(), NULL, NULL TSRMLS_CC); + return SUCCESS; } #define PHP_MSHUT_CALL(i) do { \ - if (SUCCESS != PHP_MSHUTDOWN(i)(type, module_number TSRMLS_CC)) { \ + if (SUCCESS != PHP_MSHUTDOWN(i)(type, module_number)) { \ return FAILURE; \ } \ } while(0) static PHP_MSHUTDOWN_FUNCTION(pq) { - php_persistent_handle_cleanup(ZEND_STRL("pq\\Connection"), NULL, 0 TSRMLS_CC); - PHP_MSHUT_CALL(pqlob); PHP_MSHUT_CALL(pqcopy); PHP_MSHUT_CALL(pqcur); diff --git a/src/php_pq_object.c b/src/php_pq_object.c index f362060..c7e04d6 100644 --- a/src/php_pq_object.c +++ b/src/php_pq_object.c @@ -18,68 +18,93 @@ #include "php_pq_object.h" -void php_pq_object_to_zval(void *o, zval **zv TSRMLS_DC) +void *php_pq_object_create(zend_class_entry *ce, void *intern, size_t obj_size, zend_object_handlers *oh, HashTable *ph) { - php_pq_object_t *obj = o; + php_pq_object_t *o = ecalloc(1, obj_size + zend_object_properties_size(ce)); - if (!*zv) { - MAKE_STD_ZVAL(*zv); - } + zend_object_std_init(&o->zo, ce); + object_properties_init(&o->zo, ce); + o->zo.handlers = oh; + o->intern = intern; + o->prophandler = ph; - zend_objects_store_add_ref_by_handle(obj->zv.handle TSRMLS_CC); + zend_hash_init(&o->gc, 0, NULL, NULL, 0); - (*zv)->type = IS_OBJECT; - (*zv)->value.obj = obj->zv; + return o; } -void php_pq_object_to_zval_no_addref(void *o, zval **zv TSRMLS_DC) +void php_pq_object_dtor(zend_object *o) +{ + php_pq_object_t *obj = PHP_PQ_OBJ(NULL, o); + + zend_hash_destroy(&obj->gc); + zend_object_std_dtor(o); +} + +void php_pq_object_to_zval(void *o, zval *zv) { php_pq_object_t *obj = o; - if (!*zv) { - MAKE_STD_ZVAL(*zv); - } + ZVAL_OBJ(zv, &obj->zo); + Z_ADDREF_P(zv); +} - /* no add ref */ +void php_pq_object_to_zval_no_addref(void *o, zval *zv) +{ + php_pq_object_t *obj = o; - (*zv)->type = IS_OBJECT; - (*zv)->value.obj = obj->zv; + ZVAL_OBJ(zv, &obj->zo); } -void php_pq_object_addref(void *o TSRMLS_DC) +void php_pq_object_addref(void *o) { php_pq_object_t *obj = o; - zend_objects_store_add_ref_by_handle(obj->zv.handle TSRMLS_CC); + ++GC_REFCOUNT(&obj->zo); } -void php_pq_object_delref(void *o TSRMLS_DC) +void php_pq_object_delref(void *o) { php_pq_object_t *obj = o; - zend_objects_store_del_ref_by_handle_ex(obj->zv.handle, obj->zv.handlers TSRMLS_CC); + zval tmp; + + /* this should gc immediately */ + ZVAL_OBJ(&tmp, &obj->zo); + zval_ptr_dtor(&tmp); } struct apply_pi_to_ht_arg { HashTable *ht; zval *object; php_pq_object_t *pq_obj; - unsigned addref:1; + unsigned gc:1; }; -static int apply_pi_to_ht(void *p, void *a TSRMLS_DC) +static int apply_pi_to_ht(zval *p, void *a) { - zend_property_info *pi = p; + zend_property_info *pi = Z_PTR_P(p); struct apply_pi_to_ht_arg *arg = a; - zval *property = zend_read_property(arg->pq_obj->zo.ce, arg->object, pi->name, pi->name_length, 0 TSRMLS_CC); - if (arg->addref) { - Z_ADDREF_P(property); + if (arg->gc) { + php_pq_object_prophandler_t *handler; + + if ((handler = zend_hash_find_ptr(arg->pq_obj->prophandler, pi->name)) && handler->gc) { + zval member, return_value; + + ZVAL_STR(&member, pi->name); + ZVAL_ARR(&return_value, arg->ht); + handler->gc(arg->object, arg->pq_obj, &return_value); + } + } else { + zval tmp_prop, *property = NULL; + + property = zend_read_property(arg->pq_obj->zo.ce, arg->object, pi->name->val, pi->name->len, 0, &tmp_prop); + zend_hash_update(arg->ht, pi->name, property); } - zend_hash_update(arg->ht, pi->name, pi->name_length + 1, (void *) &property, sizeof(zval *), NULL); return ZEND_HASH_APPLY_KEEP; } -HashTable *php_pq_object_debug_info(zval *object, int *temp TSRMLS_DC) +HashTable *php_pq_object_debug_info(zval *object, int *temp) { struct apply_pi_to_ht_arg arg = {NULL}; @@ -88,24 +113,43 @@ HashTable *php_pq_object_debug_info(zval *object, int *temp TSRMLS_DC) ZEND_INIT_SYMTABLE(arg.ht); arg.object = object; - arg.pq_obj = zend_object_store_get_object(object TSRMLS_CC); - arg.addref = 1; + arg.pq_obj = PHP_PQ_OBJ(object, NULL); + arg.gc = 0; + + zend_hash_apply_with_argument(&arg.pq_obj->zo.ce->properties_info, apply_pi_to_ht, &arg); + + return arg.ht; +} + +HashTable *php_pq_object_properties(zval *object) +{ + struct apply_pi_to_ht_arg arg = {NULL}; + + arg.ht = zend_get_std_object_handlers()->get_properties(object); + arg.object = object; + arg.pq_obj = PHP_PQ_OBJ(object, NULL); + arg.gc = 0; - zend_hash_apply_with_argument(&arg.pq_obj->zo.ce->properties_info, apply_pi_to_ht, &arg TSRMLS_CC); + zend_hash_apply_with_argument(&arg.pq_obj->zo.ce->properties_info, apply_pi_to_ht, &arg); return arg.ht; } -HashTable *php_pq_object_properties(zval *object TSRMLS_DC) +HashTable *php_pq_object_get_gc(zval *object, zval **table, int *n) { struct apply_pi_to_ht_arg arg = {NULL}; - arg.ht = zend_get_std_object_handlers()->get_properties(object TSRMLS_CC); arg.object = object; - arg.pq_obj = zend_object_store_get_object(object TSRMLS_CC); - arg.addref = 1; + arg.pq_obj = PHP_PQ_OBJ(object, NULL); + arg.ht = &arg.pq_obj->gc; + arg.gc = 1; + + zend_hash_clean(arg.ht); + zend_hash_copy(arg.ht, zend_std_get_properties(object), NULL); + zend_hash_apply_with_argument(&arg.pq_obj->zo.ce->properties_info, apply_pi_to_ht, &arg); - zend_hash_apply_with_argument(&arg.pq_obj->zo.ce->properties_info, apply_pi_to_ht, &arg TSRMLS_CC); + *table = NULL; + *n = 0; return arg.ht; } @@ -118,45 +162,61 @@ zend_class_entry *ancestor(zend_class_entry *ce) return ce; } -zval *php_pq_object_read_prop(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) +zval *php_pq_object_read_prop(zval *object, zval *member, int type, void **cache_slot, zval *tmp) { - php_pq_object_t *obj = zend_object_store_get_object(object TSRMLS_CC); + php_pq_object_t *obj = PHP_PQ_OBJ(object, NULL); php_pq_object_prophandler_t *handler; zval *return_value = NULL; + return_value = zend_get_std_object_handlers()->read_property(object, member, type, cache_slot, tmp); + if (!obj->intern) { - php_error(E_RECOVERABLE_ERROR, "%s not initialized", ancestor(obj->zo.ce)->name); - return_value = zend_get_std_object_handlers()->read_property(object, member, type, key TSRMLS_CC); - } else if ((SUCCESS != zend_hash_find(obj->prophandler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void *) &handler)) || !handler->read) { - return_value = zend_get_std_object_handlers()->read_property(object, member, type, key TSRMLS_CC); + php_error(E_RECOVERABLE_ERROR, "%s not initialized", ancestor(obj->zo.ce)->name->val); + } else if (!(handler = zend_hash_find_ptr(obj->prophandler, Z_STR_P(member))) || !handler->read) { + /* default handler */ } else if (type != BP_VAR_R) { - php_error(E_WARNING, "Cannot access %s properties by reference or array key/index", ancestor(obj->zo.ce)->name); - return_value = zend_get_std_object_handlers()->read_property(object, member, type, key TSRMLS_CC); + php_error(E_WARNING, "Cannot access %s properties by reference or array key/index", ancestor(obj->zo.ce)->name->val); } else { - ALLOC_ZVAL(return_value); - Z_SET_REFCOUNT_P(return_value, 0); - Z_UNSET_ISREF_P(return_value); + handler->read(object, obj, tmp); + zend_get_std_object_handlers()->write_property(object, member, tmp, cache_slot); + return_value = tmp; + + /* + zval dtor; + + ZVAL_COPY_VALUE(&dtor, return_value); + + ZVAL_ZVAL(return_value, tmp, 0, 0); + zval_ptr_dtor(&dtor); - handler->read(object, obj, return_value TSRMLS_CC); + */ + + if (cache_slot) { + *cache_slot = NULL; + } } return return_value; } -void php_pq_object_write_prop(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC) +void php_pq_object_write_prop(zval *object, zval *member, zval *value, void **cache_slot) { - php_pq_object_t *obj = zend_object_store_get_object(object TSRMLS_CC); + php_pq_object_t *obj = PHP_PQ_OBJ(object, NULL); php_pq_object_prophandler_t *handler; if (!obj->intern) { - php_error(E_RECOVERABLE_ERROR, "%s not initialized", ancestor(obj->zo.ce)->name); - zend_get_std_object_handlers()->write_property(object, member, value, key TSRMLS_CC); - } else if (SUCCESS == zend_hash_find(obj->prophandler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void *) &handler)) { + php_error(E_RECOVERABLE_ERROR, "%s not initialized", ancestor(obj->zo.ce)->name->val); + zend_get_std_object_handlers()->write_property(object, member, value, cache_slot); + } else if ((handler = zend_hash_find_ptr(obj->prophandler, Z_STR_P(member)))) { if (handler->write) { - handler->write(object, obj, value TSRMLS_CC); + handler->write(object, obj, value); } } else { - zend_get_std_object_handlers()->write_property(object, member, value, key TSRMLS_CC); + zend_get_std_object_handlers()->write_property(object, member, value, cache_slot); } } +void php_pq_object_prophandler_dtor(zval *zv) { + pefree(Z_PTR_P(zv), 1); +} + diff --git a/src/php_pq_object.h b/src/php_pq_object.h index d26fb7b..2c7417a 100644 --- a/src/php_pq_object.h +++ b/src/php_pq_object.h @@ -13,29 +13,44 @@ #ifndef PHP_PQ_OBJECT_H #define PHP_PQ_OBJECT_H -typedef struct php_pq_object { +#define PHP_PQ_OBJ_DECL(_intern_type) \ + _intern_type intern; \ + HashTable *prophandler; \ + HashTable gc; \ zend_object zo; - zend_object_value zv; - HashTable *prophandler; - void *intern; + +typedef struct php_pq_object { + PHP_PQ_OBJ_DECL(void *) } php_pq_object_t; -typedef void (*php_pq_object_prophandler_func_t)(zval *object, void *o, zval *return_value TSRMLS_DC); +static inline void *PHP_PQ_OBJ(zval *zv, zend_object *zo) { + if (zv) { + zo = Z_OBJ_P(zv); + } + return (void *) (((char *) zo) - zo->handlers->offset); +} + +typedef void (*php_pq_object_prophandler_func_t)(zval *object, void *o, zval *return_value); typedef struct php_pq_object_prophandler { php_pq_object_prophandler_func_t read; php_pq_object_prophandler_func_t write; + php_pq_object_prophandler_func_t gc; } php_pq_object_prophandler_t; -extern void php_pq_object_to_zval(void *o, zval **zv TSRMLS_DC); -extern void php_pq_object_to_zval_no_addref(void *o, zval **zv TSRMLS_DC); -extern void php_pq_object_addref(void *o TSRMLS_DC); -extern void php_pq_object_delref(void *o TSRMLS_DC); -extern HashTable *php_pq_object_debug_info(zval *object, int *temp TSRMLS_DC); -extern HashTable *php_pq_object_properties(zval *object TSRMLS_DC); +extern void *php_pq_object_create(zend_class_entry *ce, void *intern, size_t obj_size, zend_object_handlers *oh, HashTable *ph); +extern void php_pq_object_dtor(zend_object *obj); +extern void php_pq_object_to_zval(void *o, zval *zv); +extern void php_pq_object_to_zval_no_addref(void *o, zval *zv); +extern void php_pq_object_addref(void *o); +extern void php_pq_object_delref(void *o); +extern HashTable *php_pq_object_debug_info(zval *object, int *temp); +extern HashTable *php_pq_object_properties(zval *object); +HashTable *php_pq_object_get_gc(zval *object, zval **table, int *n); extern zend_class_entry *ancestor(zend_class_entry *ce); -extern zval *php_pq_object_read_prop(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC); -extern void php_pq_object_write_prop(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC); +extern zval *php_pq_object_read_prop(zval *object, zval *member, int type, void **cache_slot, zval *tmp); +extern void php_pq_object_write_prop(zval *object, zval *member, zval *value, void **cache_slot); +extern void php_pq_object_prophandler_dtor(zval *zv); #endif diff --git a/src/php_pq_params.c b/src/php_pq_params.c index 1ae7dd6..0f7ba50 100644 --- a/src/php_pq_params.c +++ b/src/php_pq_params.c @@ -16,11 +16,11 @@ #include #include -#include #if PHP_PQ_HAVE_PHP_JSON_H #include /* we've added the include directory to INCLUDES */ #endif +#include #include #include @@ -34,31 +34,22 @@ void php_pq_params_set_type_conv(php_pq_params_t *p, HashTable *conv) { zend_hash_clean(&p->type.conv); - zend_hash_copy(&p->type.conv, conv, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *)); + zend_hash_copy(&p->type.conv, conv, (copy_ctor_func_t) zval_add_ref); } -static int apply_to_oid(void *p, void *arg TSRMLS_DC) +static int apply_to_oid(zval *ztype, void *arg) { Oid **types = arg; - zval **ztype = p; - if (Z_TYPE_PP(ztype) != IS_LONG) { - convert_to_long_ex(ztype); - } - - **types = Z_LVAL_PP(ztype); + **types = zval_get_long(ztype); ++*types; - if (*ztype != *(zval **)p) { - zval_ptr_dtor(ztype); - } return ZEND_HASH_APPLY_KEEP; } unsigned php_pq_params_set_type_oids(php_pq_params_t *p, HashTable *oids) { p->type.count = oids ? zend_hash_num_elements(oids) : 0; - TSRMLS_DF(p); if (p->type.oids) { efree(p->type.oids); @@ -68,7 +59,7 @@ unsigned php_pq_params_set_type_oids(php_pq_params_t *p, HashTable *oids) Oid *ptr = ecalloc(p->type.count + 1, sizeof(*p->type.oids)); /* +1 for when less types than params are specified */ p->type.oids = ptr; - zend_hash_apply_with_argument(oids, apply_to_oid, &ptr TSRMLS_CC); + zend_hash_apply_with_argument(oids, apply_to_oid, &ptr); } return p->type.count; } @@ -82,9 +73,8 @@ unsigned php_pq_params_add_type_oid(php_pq_params_t *p, Oid type) } -static zval *object_param_to_string(php_pq_params_t *p, zval *zobj, Oid type TSRMLS_DC) +static zend_string *object_param_to_string(php_pq_params_t *p, zval *zobj, Oid type) { - zval *return_value = NULL; smart_str str = {0}; switch (type) { @@ -93,40 +83,25 @@ static zval *object_param_to_string(php_pq_params_t *p, zval *zobj, Oid type TSR case PHP_PQ_OID_JSONB: # endif case PHP_PQ_OID_JSON: - php_json_encode(&str, zobj, PHP_JSON_UNESCAPED_UNICODE TSRMLS_CC); + php_json_encode(&str, zobj, PHP_JSON_UNESCAPED_UNICODE); smart_str_0(&str); - break; + return str.s; #endif case PHP_PQ_OID_DATE: - php_pqdt_to_string(zobj, "Y-m-d", &str.c, &str.len TSRMLS_CC); - break; + return php_pqdt_to_string(zobj, "Y-m-d"); case PHP_PQ_OID_ABSTIME: - php_pqdt_to_string(zobj, "Y-m-d H:i:s", &str.c, &str.len TSRMLS_CC); - break; + return php_pqdt_to_string(zobj, "Y-m-d H:i:s"); case PHP_PQ_OID_TIMESTAMP: - php_pqdt_to_string(zobj, "Y-m-d H:i:s.u", &str.c, &str.len TSRMLS_CC); - break; + return php_pqdt_to_string(zobj, "Y-m-d H:i:s.u"); case PHP_PQ_OID_TIMESTAMPTZ: - php_pqdt_to_string(zobj, "Y-m-d H:i:s.uO", &str.c, &str.len TSRMLS_CC); - break; - - default: - MAKE_STD_ZVAL(return_value); - MAKE_COPY_ZVAL(&zobj, return_value); - convert_to_string(return_value); - break; - } - - if (str.c) { - MAKE_STD_ZVAL(return_value); - RETVAL_STRINGL(str.c, str.len, 0); + return php_pqdt_to_string(zobj, "Y-m-d H:i:s.uO"); } - return return_value; + return zval_get_string(zobj); } struct apply_to_param_from_array_arg { @@ -135,54 +110,54 @@ struct apply_to_param_from_array_arg { smart_str *buffer; Oid type; char delim; - zval **zconv; + zval *zconv; }; -static int apply_to_param_from_array(void *ptr, void *arg_ptr TSRMLS_DC) +static int apply_to_param_from_array(zval *zparam, void *arg_ptr) { struct apply_to_param_from_array_arg subarg, *arg = arg_ptr; - zval *ztmp, **zparam = ptr, *zcopy = *zparam; char *tmp; size_t len; - int tmp_len; + zend_string *str; if (arg->index++) { smart_str_appendc(arg->buffer, arg->delim); } if (arg->zconv) { - zval *ztype, *rv = NULL; - - MAKE_STD_ZVAL(ztype); - ZVAL_LONG(ztype, arg->type); - zend_call_method_with_2_params(arg->zconv, NULL, NULL, "converttostring", &rv, zcopy, ztype); - zval_ptr_dtor(&ztype); - - if (rv) { - convert_to_string(rv); - zcopy = rv; - } else { - return ZEND_HASH_APPLY_STOP; - } + zval ztype, rv; + ZVAL_LONG(&ztype, arg->type); + zend_call_method_with_2_params(arg->zconv, NULL, NULL, "converttostring", &rv, zparam, &ztype); + str = zval_get_string(&rv); + zval_ptr_dtor(&rv); goto append_string; } else { - switch (Z_TYPE_P(zcopy)) { + again: + switch (Z_TYPE_P(zparam)) { + case IS_REFERENCE: + ZVAL_DEREF(zparam); + goto again; + case IS_NULL: smart_str_appends(arg->buffer, "NULL"); break; - case IS_BOOL: - smart_str_appends(arg->buffer, Z_BVAL_P(zcopy) ? "t" : "f"); + case IS_TRUE: + smart_str_appends(arg->buffer, "t"); + break; + + case IS_FALSE: + smart_str_appends(arg->buffer, "f"); break; case IS_LONG: - smart_str_append_long(arg->buffer, Z_LVAL_P(zcopy)); + smart_str_append_long(arg->buffer, Z_LVAL_P(zparam)); break; case IS_DOUBLE: - len = spprintf(&tmp, 0, "%F", Z_DVAL_P(zcopy)); + len = spprintf(&tmp, 0, "%F", Z_DVAL_P(zparam)); smart_str_appendl(arg->buffer, tmp, len); efree(tmp); break; @@ -191,29 +166,24 @@ static int apply_to_param_from_array(void *ptr, void *arg_ptr TSRMLS_DC) subarg = *arg; subarg.index = 0; smart_str_appendc(arg->buffer, '{'); - zend_hash_apply_with_argument(Z_ARRVAL_P(zcopy), apply_to_param_from_array, &subarg TSRMLS_CC); + zend_hash_apply_with_argument(Z_ARRVAL_P(zparam), apply_to_param_from_array, &subarg); smart_str_appendc(arg->buffer, '}'); break; case IS_OBJECT: - if ((ztmp = object_param_to_string(arg->params, zcopy, arg->type TSRMLS_CC))) { - zcopy = ztmp; + if ((str = object_param_to_string(arg->params, zparam, arg->type))) { + goto append_string; } /* no break */ default: - SEPARATE_ZVAL(&zcopy); - convert_to_string(zcopy); + str = zval_get_string(zparam); append_string: - tmp = php_addslashes(Z_STRVAL_P(zcopy), Z_STRLEN_P(zcopy), &tmp_len, 0 TSRMLS_CC); + str = php_addslashes(str, 1); smart_str_appendc(arg->buffer, '"'); - smart_str_appendl(arg->buffer, tmp, tmp_len); + smart_str_appendl(arg->buffer, str->val, str->len); smart_str_appendc(arg->buffer, '"'); - - if (zcopy != *zparam) { - zval_ptr_dtor(&zcopy); - } - efree(tmp); + zend_string_release(str); break; } } @@ -221,9 +191,8 @@ static int apply_to_param_from_array(void *ptr, void *arg_ptr TSRMLS_DC) return ZEND_HASH_APPLY_KEEP; } -static zval *array_param_to_string(php_pq_params_t *p, zval *zarr, Oid type TSRMLS_DC) +static zend_string *array_param_to_string(php_pq_params_t *p, zval *zarr, Oid type) { - zval *zcopy, *return_value; smart_str s = {0}; struct apply_to_param_from_array_arg arg = {NULL}; @@ -233,8 +202,7 @@ static zval *array_param_to_string(php_pq_params_t *p, zval *zarr, Oid type TSRM case PHP_PQ_OID_JSONB: # endif case PHP_PQ_OID_JSON: - php_json_encode(&s, zarr, PHP_JSON_UNESCAPED_UNICODE TSRMLS_CC); - smart_str_0(&s); + php_json_encode(&s, zarr, PHP_JSON_UNESCAPED_UNICODE); break; #endif @@ -243,90 +211,79 @@ static zval *array_param_to_string(php_pq_params_t *p, zval *zarr, Oid type TSRM arg.buffer = &s; arg.type = PHP_PQ_TYPE_OF_ARRAY(type); arg.delim = PHP_PQ_DELIM_OF_ARRAY(type); - zend_hash_index_find(&p->type.conv, PHP_PQ_TYPE_OF_ARRAY(type), (void *) &arg.zconv); + arg.zconv = zend_hash_index_find(&p->type.conv, PHP_PQ_TYPE_OF_ARRAY(type)); smart_str_appendc(arg.buffer, '{'); - MAKE_STD_ZVAL(zcopy); - MAKE_COPY_ZVAL(&zarr, zcopy); - zend_hash_apply_with_argument(Z_ARRVAL_P(zcopy), apply_to_param_from_array, &arg TSRMLS_CC); - zval_ptr_dtor(&zcopy); + SEPARATE_ZVAL(zarr); + zend_hash_apply_with_argument(Z_ARRVAL_P(zarr), apply_to_param_from_array, &arg); smart_str_appendc(arg.buffer, '}'); - smart_str_0(&s); break; } - /* must not return NULL */ - MAKE_STD_ZVAL(return_value); - - if (s.c) { - RETVAL_STRINGL(s.c, s.len, 0); - } else { - RETVAL_EMPTY_STRING(); - } - - return return_value; + smart_str_0(&s); + return s.s; } -static void php_pq_params_set_param(php_pq_params_t *p, unsigned index, zval **zpp) +static void php_pq_params_set_param(php_pq_params_t *p, unsigned index, zval *zpp) { - zval **zconv = NULL; + zval *zconv = NULL; Oid type = p->type.count > index ? p->type.oids[index] : 0; - TSRMLS_DF(p); - - if (type && SUCCESS == zend_hash_index_find(&p->type.conv, type, (void *) &zconv)) { - zval *ztype, *rv = NULL; - - MAKE_STD_ZVAL(ztype); - ZVAL_LONG(ztype, type); - zend_call_method_with_2_params(zconv, NULL, NULL, "converttostring", &rv, *zpp, ztype); - zval_ptr_dtor(&ztype); - if (rv) { - convert_to_string(rv); - p->param.strings[index] = Z_STRVAL_P(rv); - zend_hash_next_index_insert(&p->param.dtor, (void *) &rv, sizeof(zval *), NULL); - } + + if (type && (zconv = zend_hash_index_find(&p->type.conv, type))) { + zval ztype, rv; + + ZVAL_NULL(&rv); + ZVAL_LONG(&ztype, type); + zend_call_method_with_2_params(zconv, NULL, NULL, "converttostring", &rv, zpp, &ztype); + convert_to_string(&rv); + p->param.strings[index] = Z_STRVAL_P(&rv); + zend_hash_next_index_insert(&p->param.dtor, &rv); } else { - zval *tmp, *zcopy = *zpp; + zval tmp; + zend_string *str = NULL; + char tmp_str[64]; + size_t tmp_len = 0; + + again: + switch (Z_TYPE_P(zpp)) { + case IS_REFERENCE: + ZVAL_DEREF(zpp); + goto again; - switch (Z_TYPE_P(zcopy)) { case IS_NULL: p->param.strings[index] = NULL; return; - case IS_BOOL: - p->param.strings[index] = Z_BVAL_P(zcopy) ? "t" : "f"; + case IS_TRUE: + p->param.strings[index] = "t"; + break; + + case IS_FALSE: + p->param.strings[index] = "f"; return; case IS_DOUBLE: - MAKE_STD_ZVAL(zcopy); - MAKE_COPY_ZVAL(zpp, zcopy); - Z_TYPE_P(zcopy) = IS_STRING; - Z_STRLEN_P(zcopy) = spprintf(&Z_STRVAL_P(zcopy), 0, "%F", Z_DVAL_PP(zpp)); + tmp_len = slprintf(tmp_str, sizeof(tmp_str), "%F", Z_DVAL_P(zpp)); + str = zend_string_init(tmp_str, tmp_len, 0); break; case IS_ARRAY: - MAKE_STD_ZVAL(zcopy); - MAKE_COPY_ZVAL(zpp, zcopy); - tmp = array_param_to_string(p, zcopy, type TSRMLS_CC); - zval_ptr_dtor(&zcopy); - zcopy = tmp; + str = array_param_to_string(p, zpp, type); break; case IS_OBJECT: - if ((tmp = object_param_to_string(p, zcopy, type TSRMLS_CC))) { - zcopy = tmp; + if ((str = object_param_to_string(p, zpp, type))) { break; } /* no break */ - default: - convert_to_string_ex(&zcopy); + str = zval_get_string(zpp); break; } - p->param.strings[index] = Z_STRVAL_P(zcopy); - - if (zcopy != *zpp) { - zend_hash_next_index_insert(&p->param.dtor, (void *) &zcopy, sizeof(zval *), NULL); + if (str) { + ZVAL_STR(&tmp, str); + p->param.strings[index] = Z_STRVAL(tmp); + zend_hash_next_index_insert(&p->param.dtor, &tmp); } } } @@ -336,11 +293,11 @@ struct apply_to_params_arg { unsigned index; }; -static int apply_to_params(void *zp, void *arg_ptr TSRMLS_DC) +static int apply_to_params(zval *zp, void *arg_ptr) { struct apply_to_params_arg *arg = arg_ptr; - SEPARATE_ZVAL_IF_NOT_REF((zval **) zp); + SEPARATE_ZVAL_IF_NOT_REF(zp); php_pq_params_set_param(arg->params, arg->index++, zp); return ZEND_HASH_APPLY_KEEP; } @@ -348,14 +305,13 @@ static int apply_to_params(void *zp, void *arg_ptr TSRMLS_DC) unsigned php_pq_params_add_param(php_pq_params_t *p, zval *param) { p->param.strings = safe_erealloc(p->param.strings, ++p->param.count, sizeof(*p->param.strings), 0); - php_pq_params_set_param(p, p->param.count-1, ¶m); + php_pq_params_set_param(p, p->param.count-1, param); return p->type.count; } unsigned php_pq_params_set_params(php_pq_params_t *p, HashTable *params) { p->param.count = params ? zend_hash_num_elements(params) : 0; - TSRMLS_DF(p); if (p->param.strings) { efree(p->param.strings); @@ -365,7 +321,7 @@ unsigned php_pq_params_set_params(php_pq_params_t *p, HashTable *params) if (p->param.count) { struct apply_to_params_arg arg = {p, 0}; p->param.strings = ecalloc(p->param.count, sizeof(*p->param.strings)); - zend_hash_apply_with_argument(params, apply_to_params, &arg TSRMLS_CC); + zend_hash_apply_with_argument(params, apply_to_params, &arg); } return p->param.count; } @@ -384,11 +340,10 @@ void php_pq_params_free(php_pq_params_t **p) } } -php_pq_params_t *php_pq_params_init(HashTable *conv, HashTable *oids, HashTable *params TSRMLS_DC) +php_pq_params_t *php_pq_params_init(HashTable *conv, HashTable *oids, HashTable *params) { php_pq_params_t *p = ecalloc(1, sizeof(*p)); - TSRMLS_CF(p); zend_hash_init(&p->type.conv, 0, NULL, ZVAL_PTR_DTOR, 0); zend_hash_init(&p->param.dtor, 0, NULL, ZVAL_PTR_DTOR, 0); diff --git a/src/php_pq_params.h b/src/php_pq_params.h index fe5d9c6..f94cd9c 100644 --- a/src/php_pq_params.h +++ b/src/php_pq_params.h @@ -24,12 +24,9 @@ typedef struct php_pq_params { unsigned count; char **strings; } param; -#ifdef ZTS - void ***ts; -#endif } php_pq_params_t; -extern php_pq_params_t *php_pq_params_init(HashTable *conv, HashTable *oids, HashTable *params TSRMLS_DC); +extern php_pq_params_t *php_pq_params_init(HashTable *conv, HashTable *oids, HashTable *params); extern void php_pq_params_free(php_pq_params_t **p); extern unsigned php_pq_params_set_params(php_pq_params_t *p, HashTable *params); extern unsigned php_pq_params_set_type_oids(php_pq_params_t *p, HashTable *oids); diff --git a/src/php_pqcancel.c b/src/php_pqcancel.c index 9711190..4d5d339 100644 --- a/src/php_pqcancel.c +++ b/src/php_pqcancel.c @@ -28,55 +28,46 @@ zend_class_entry *php_pqcancel_class_entry; static zend_object_handlers php_pqcancel_object_handlers; static HashTable php_pqcancel_object_prophandlers; -static void php_pqcancel_object_free(void *o TSRMLS_DC) +static void php_pqcancel_object_free(zend_object *o) { - php_pqcancel_object_t *obj = o; + php_pqcancel_object_t *obj = PHP_PQ_OBJ(NULL, o); #if DBG_GC - fprintf(stderr, "FREE cancel(#%d) %p (conn(#%d): %p)\n", obj->zv.handle, obj, obj->intern->conn->zv.handle, obj->intern->conn); + fprintf(stderr, "FREE cancel(#%d) %p (conn(#%d): %p)\n", obj->zo.handle, obj, obj->intern->conn->zo.handle, obj->intern->conn); #endif if (obj->intern) { PQfreeCancel(obj->intern->cancel); - php_pq_object_delref(obj->intern->conn TSRMLS_CC); + php_pq_object_delref(obj->intern->conn); efree(obj->intern); obj->intern = NULL; } - zend_object_std_dtor((zend_object *) o TSRMLS_CC); - efree(obj); + php_pq_object_dtor(o); } -zend_object_value php_pqcancel_create_object_ex(zend_class_entry *ce, php_pqcancel_t *intern, php_pqcancel_object_t **ptr TSRMLS_DC) +php_pqcancel_object_t *php_pqcancel_create_object_ex(zend_class_entry *ce, php_pqcancel_t *intern) { - php_pqcancel_object_t *o; - - o = ecalloc(1, sizeof(*o)); - zend_object_std_init((zend_object *) o, ce TSRMLS_CC); - object_properties_init((zend_object *) o, ce); - o->prophandler = &php_pqcancel_object_prophandlers; - - if (ptr) { - *ptr = o; - } - - if (intern) { - o->intern = intern; - } - - o->zv.handle = zend_objects_store_put((zend_object *) o, NULL, php_pqcancel_object_free, NULL TSRMLS_CC); - o->zv.handlers = &php_pqcancel_object_handlers; + return php_pq_object_create(ce, intern, sizeof(php_pqcancel_object_t), + &php_pqcancel_object_handlers, &php_pqcancel_object_prophandlers); +} - return o->zv; +static zend_object *php_pqcancel_create_object(zend_class_entry *class_type TSRMLS_DC) +{ + return &php_pqcancel_create_object_ex(class_type, NULL)->zo; } -static zend_object_value php_pqcancel_create_object(zend_class_entry *class_type TSRMLS_DC) +static void php_pqcancel_object_read_connection(zval *object, void *o, zval *return_value) { - return php_pqcancel_create_object_ex(class_type, NULL, NULL TSRMLS_CC); + php_pqcancel_object_t *obj = o; + + php_pq_object_to_zval(obj->intern->conn, return_value); } -static void php_pqcancel_object_read_connection(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqcancel_object_gc_connection(zval *object, void *o, zval *return_value) { php_pqcancel_object_t *obj = o; + zval zconn; - php_pq_object_to_zval(obj->intern->conn, &return_value TSRMLS_CC); + php_pq_object_to_zval_no_addref(obj->intern->conn, &zconn); + add_next_index_zval(return_value, &zconn); } ZEND_BEGIN_ARG_INFO_EX(ai_pqcancel_construct, 0, 0, 1) @@ -87,26 +78,26 @@ static PHP_METHOD(pqcancel, __construct) { zval *zconn; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &zconn, php_pqconn_class_entry); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "O", &zconn, php_pqconn_class_entry); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqconn_object_t *conn_obj = zend_object_store_get_object(zconn TSRMLS_CC); + php_pqconn_object_t *conn_obj = PHP_PQ_OBJ(zconn, NULL); if (!conn_obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized"); } else { PGcancel *cancel = PQgetCancel(conn_obj->intern->conn); if (!cancel) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to acquire cancel (%s)", PHP_PQerrorMessage(conn_obj->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to acquire cancel (%s)", PHP_PQerrorMessage(conn_obj->intern->conn)); } else { - php_pqcancel_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqcancel_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); obj->intern = ecalloc(1, sizeof(*obj->intern)); obj->intern->cancel = cancel; - php_pq_object_addref(conn_obj TSRMLS_CC); + php_pq_object_addref(conn_obj); obj->intern->conn = conn_obj; } } @@ -119,20 +110,20 @@ static PHP_METHOD(pqcancel, cancel) { zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); rv = zend_parse_parameters_none(); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqcancel_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqcancel_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Cancel not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Cancel not initialized"); } else { char err[256] = {0}; if (!PQcancel(obj->intern->cancel, err, sizeof(err))) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to request cancellation (%s)", err); + throw_exce(EX_RUNTIME, "Failed to request cancellation (%s)", err); } } } @@ -156,23 +147,26 @@ PHP_MINIT_FUNCTION(pqcancel) php_pq_object_prophandler_t ph = {0}; INIT_NS_CLASS_ENTRY(ce, "pq", "Cancel", php_pqcancel_methods); - php_pqcancel_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC); + php_pqcancel_class_entry = zend_register_internal_class_ex(&ce, NULL); php_pqcancel_class_entry->create_object = php_pqcancel_create_object; memcpy(&php_pqcancel_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + php_pqcancel_object_handlers.offset = XtOffsetOf(php_pqcancel_object_t, zo); + php_pqcancel_object_handlers.free_obj = php_pqcancel_object_free; php_pqcancel_object_handlers.read_property = php_pq_object_read_prop; php_pqcancel_object_handlers.write_property = php_pq_object_write_prop; php_pqcancel_object_handlers.clone_obj = NULL; php_pqcancel_object_handlers.get_property_ptr_ptr = NULL; - php_pqcancel_object_handlers.get_gc = NULL; + php_pqcancel_object_handlers.get_gc = php_pq_object_get_gc; php_pqcancel_object_handlers.get_properties = php_pq_object_properties; php_pqcancel_object_handlers.get_debug_info = php_pq_object_debug_info; - zend_hash_init(&php_pqcancel_object_prophandlers, 1, NULL, NULL, 1); + zend_hash_init(&php_pqcancel_object_prophandlers, 1, NULL, php_pq_object_prophandler_dtor, 1); - zend_declare_property_null(php_pqcancel_class_entry, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqcancel_class_entry, ZEND_STRL("connection"), ZEND_ACC_PUBLIC); ph.read = php_pqcancel_object_read_connection; - zend_hash_add(&php_pqcancel_object_prophandlers, "connection", sizeof("connection"), (void *) &ph, sizeof(ph), NULL); + ph.gc = php_pqcancel_object_gc_connection; + zend_hash_str_add_mem(&php_pqcancel_object_prophandlers, ZEND_STRL("connection"), (void *) &ph, sizeof(ph)); return SUCCESS; } diff --git a/src/php_pqcancel.h b/src/php_pqcancel.h index ad9fb64..fb0a69e 100644 --- a/src/php_pqcancel.h +++ b/src/php_pqcancel.h @@ -22,14 +22,11 @@ typedef struct php_pqcancel { } php_pqcancel_t; typedef struct php_pqcancel_object { - zend_object zo; - zend_object_value zv; - HashTable *prophandler; - php_pqcancel_t *intern; + PHP_PQ_OBJ_DECL(php_pqcancel_t *) } php_pqcancel_object_t; extern zend_class_entry *php_pqcancel_class_entry; -extern zend_object_value php_pqcancel_create_object_ex(zend_class_entry *ce, php_pqcancel_t *intern, php_pqcancel_object_t **ptr TSRMLS_DC); +extern php_pqcancel_object_t *php_pqcancel_create_object_ex(zend_class_entry *ce, php_pqcancel_t *intern); extern PHP_MINIT_FUNCTION(pqcancel); extern PHP_MSHUTDOWN_FUNCTION(pqcancel); diff --git a/src/php_pqconn.c b/src/php_pqconn.c index e753c7c..a7fca0e 100644 --- a/src/php_pqconn.c +++ b/src/php_pqconn.c @@ -15,9 +15,7 @@ #endif #include - -#define SMART_STR_PREALLOC 256 -#include +#include #include #include @@ -37,8 +35,14 @@ zend_class_entry *php_pqconn_class_entry; static zend_object_handlers php_pqconn_object_handlers; static HashTable php_pqconn_object_prophandlers; +static void php_pq_callback_hash_dtor(zval *p) +{ + php_pq_callback_dtor(Z_PTR_P(p)); + efree(Z_PTR_P(p)); +} + /* -static void php_pqconn_del_eventhandler(php_pqconn_object_t *obj, const char *type_str, size_t type_len, ulong id TSRMLS_DC) +static void php_pqconn_del_eventhandler(php_pqconn_object_t *obj, const char *type_str, size_t type_len, ulong id) { zval **evhs; @@ -48,34 +52,38 @@ static void php_pqconn_del_eventhandler(php_pqconn_object_t *obj, const char *ty } */ -static ulong php_pqconn_add_eventhandler(php_pqconn_object_t *obj, const char *type_str, size_t type_len, php_pq_callback_t *cb TSRMLS_DC) +static zend_long php_pqconn_add_eventhandler(php_pqconn_object_t *obj, const char *type_str, size_t type_len, php_pq_callback_t *cb) { - ulong h; - HashTable *evhs; + zend_long h; + zval *zevhs; - if (SUCCESS != zend_hash_find(&obj->intern->eventhandlers, type_str, type_len + 1, (void *) &evhs)) { - HashTable evh; + if (!(zevhs = zend_hash_str_find(&obj->intern->eventhandlers, type_str, type_len))) { + HashTable *evhs; + zval tmp; - zend_hash_init(&evh, 1, NULL, (dtor_func_t) php_pq_callback_dtor, 0); - zend_hash_add(&obj->intern->eventhandlers, type_str, type_len + 1, (void *) &evh, sizeof(evh), (void *) &evhs); + ALLOC_HASHTABLE(evhs); + zend_hash_init(evhs, 1, NULL, php_pq_callback_hash_dtor, 0); + + ZVAL_ARR(&tmp, evhs); + zevhs = zend_hash_str_add(&obj->intern->eventhandlers, type_str, type_len, &tmp); } php_pq_callback_addref(cb); - h = zend_hash_next_free_element(evhs); - zend_hash_index_update(evhs, h, (void *) cb, sizeof(*cb), NULL); + h = zend_hash_next_free_element(Z_ARRVAL_P(zevhs)); + zend_hash_index_update_mem(Z_ARRVAL_P(zevhs), h, (void *) cb, sizeof(*cb)); return h; } -static void php_pqconn_object_free(void *o TSRMLS_DC) +static void php_pqconn_object_free(zend_object *o) { - php_pqconn_object_t *obj = o; + php_pqconn_object_t *obj = PHP_PQ_OBJ(NULL, o); #if DBG_GC - fprintf(stderr, "FREE conn(#%d) %p\n", obj->zv.handle, obj); + fprintf(stderr, "FREE conn(#%d) %p\n", obj->zo.handle, obj); #endif if (obj->intern) { php_pq_callback_dtor(&obj->intern->onevent); - php_resource_factory_handle_dtor(&obj->intern->factory, obj->intern->conn TSRMLS_CC); + php_resource_factory_handle_dtor(&obj->intern->factory, obj->intern->conn); php_resource_factory_dtor(&obj->intern->factory); zend_hash_destroy(&obj->intern->listeners); zend_hash_destroy(&obj->intern->converters); @@ -83,80 +91,60 @@ static void php_pqconn_object_free(void *o TSRMLS_DC) efree(obj->intern); obj->intern = NULL; } - zend_object_std_dtor((zend_object *) o TSRMLS_CC); - efree(obj); + php_pq_object_dtor(o); } -zend_object_value php_pqconn_create_object_ex(zend_class_entry *ce, php_pqconn_t *intern, php_pqconn_object_t **ptr TSRMLS_DC) +php_pqconn_object_t *php_pqconn_create_object_ex(zend_class_entry *ce, php_pqconn_t *intern) { - php_pqconn_object_t *o; - - o = ecalloc(1, sizeof(*o)); - zend_object_std_init((zend_object *) o, ce TSRMLS_CC); - object_properties_init((zend_object *) o, ce); - o->prophandler = &php_pqconn_object_prophandlers; - - if (ptr) { - *ptr = o; - } - - if (intern) { - o->intern = intern; - } - - o->zv.handle = zend_objects_store_put((zend_object *) o, NULL, php_pqconn_object_free, NULL TSRMLS_CC); - o->zv.handlers = &php_pqconn_object_handlers; - - return o->zv; + return php_pq_object_create(ce, intern, sizeof(php_pqconn_object_t), + &php_pqconn_object_handlers, &php_pqconn_object_prophandlers); } -static zend_object_value php_pqconn_create_object(zend_class_entry *class_type TSRMLS_DC) +static zend_object *php_pqconn_create_object(zend_class_entry *class_type) { - return php_pqconn_create_object_ex(class_type, NULL, NULL TSRMLS_CC); + return &php_pqconn_create_object_ex(class_type, NULL)->zo; } -static void php_pqconn_object_read_status(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqconn_object_read_status(zval *object, void *o, zval *return_value) { php_pqconn_object_t *obj = o; RETVAL_LONG(PQstatus(obj->intern->conn)); } -static void php_pqconn_object_read_transaction_status(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqconn_object_read_transaction_status(zval *object, void *o, zval *return_value) { php_pqconn_object_t *obj = o; RETVAL_LONG(PQtransactionStatus(obj->intern->conn)); } -static void php_pqconn_object_read_error_message(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqconn_object_read_error_message(zval *object, void *o, zval *return_value) { php_pqconn_object_t *obj = o; char *error = PHP_PQerrorMessage(obj->intern->conn); if (error) { - RETVAL_STRING(error, 1); + RETVAL_STRING(error); } else { RETVAL_NULL(); } } -static int apply_notify_listener(void *p, void *arg TSRMLS_DC) +static int apply_notify_listener(zval *p, void *arg) { - php_pq_callback_t *listener = p; + php_pq_callback_t *listener = Z_PTR_P(p); PGnotify *nfy = arg; - zval *zpid, *zchannel, *zmessage; + zval zpid, zchannel, zmessage; - MAKE_STD_ZVAL(zpid); - ZVAL_LONG(zpid, nfy->be_pid); - MAKE_STD_ZVAL(zchannel); - ZVAL_STRING(zchannel, nfy->relname, 1); - MAKE_STD_ZVAL(zmessage); - ZVAL_STRING(zmessage, nfy->extra, 1); + ZVAL_LONG(&zpid, nfy->be_pid); + ZVAL_STRING(&zchannel, nfy->relname); + ZVAL_STRING(&zmessage, nfy->extra); - zend_fcall_info_argn(&listener->fci TSRMLS_CC, 3, &zchannel, &zmessage, &zpid); - zend_fcall_info_call(&listener->fci, &listener->fcc, NULL, NULL TSRMLS_CC); + zend_fcall_info_argn(&listener->fci, 3, &zchannel, &zmessage, &zpid); + zend_fcall_info_call(&listener->fci, &listener->fcc, NULL, NULL); + zend_fcall_info_args_clear(&listener->fci, 0); zval_ptr_dtor(&zchannel); zval_ptr_dtor(&zmessage); @@ -165,144 +153,130 @@ static int apply_notify_listener(void *p, void *arg TSRMLS_DC) return ZEND_HASH_APPLY_KEEP; } -static int apply_notify_listeners(void *p TSRMLS_DC, int argc, va_list argv, zend_hash_key *key) +static int apply_notify_listeners(zval *p, int argc, va_list argv, zend_hash_key *key) { - HashTable *listeners = p; + HashTable *listeners = Z_ARRVAL_P(p); PGnotify *nfy = va_arg(argv, PGnotify *); - if (0 == fnmatch(key->arKey, nfy->relname, 0)) { - zend_hash_apply_with_argument(listeners, apply_notify_listener, nfy TSRMLS_CC); + if (0 == fnmatch(key->key->val, nfy->relname, 0)) { + zend_hash_apply_with_argument(listeners, apply_notify_listener, nfy); } return ZEND_HASH_APPLY_KEEP; } -void php_pqconn_notify_listeners(php_pqconn_object_t *obj TSRMLS_DC) +void php_pqconn_notify_listeners(php_pqconn_object_t *obj) { PGnotify *nfy; while ((nfy = PQnotifies(obj->intern->conn))) { - zend_hash_apply_with_arguments(&obj->intern->listeners TSRMLS_CC, apply_notify_listeners, 1, nfy); + zend_hash_apply_with_arguments(&obj->intern->listeners, apply_notify_listeners, 1, nfy); PQfreemem(nfy); } } -static void php_pqconn_object_read_busy(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqconn_object_read_busy(zval *object, void *o, zval *return_value) { php_pqconn_object_t *obj = o; RETVAL_BOOL(PQisBusy(obj->intern->conn)); } -static void php_pqconn_object_read_encoding(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqconn_object_read_encoding(zval *object, void *o, zval *return_value) { php_pqconn_object_t *obj = o; - RETVAL_STRING(pg_encoding_to_char(PQclientEncoding(obj->intern->conn)), 1); + RETVAL_STRING(pg_encoding_to_char(PQclientEncoding(obj->intern->conn))); } -static void php_pqconn_object_write_encoding(zval *object, void *o, zval *value TSRMLS_DC) +static void php_pqconn_object_write_encoding(zval *object, void *o, zval *value) { php_pqconn_object_t *obj = o; - zval *zenc = value; - - if (Z_TYPE_P(value) != IS_STRING) { - if (Z_REFCOUNT_P(value) > 1) { - zval *tmp; - MAKE_STD_ZVAL(tmp); - ZVAL_ZVAL(tmp, zenc, 1, 0); - convert_to_string(tmp); - zenc = tmp; - } else { - convert_to_string_ex(&zenc); - } - } + zend_string *zenc = zval_get_string(value); - if (0 > PQsetClientEncoding(obj->intern->conn, Z_STRVAL_P(zenc))) { - php_error(E_NOTICE, "Unrecognized encoding '%s'", Z_STRVAL_P(zenc)); + if (0 > PQsetClientEncoding(obj->intern->conn, zenc->val)) { + php_error(E_NOTICE, "Unrecognized encoding '%s'", zenc->val); } - if (zenc != value) { - zval_ptr_dtor(&zenc); - } + zend_string_release(zenc); } -static void php_pqconn_object_read_unbuffered(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqconn_object_read_unbuffered(zval *object, void *o, zval *return_value) { php_pqconn_object_t *obj = o; RETVAL_BOOL(obj->intern->unbuffered); } -static void php_pqconn_object_write_unbuffered(zval *object, void *o, zval *value TSRMLS_DC) +static void php_pqconn_object_write_unbuffered(zval *object, void *o, zval *value) { php_pqconn_object_t *obj = o; obj->intern->unbuffered = z_is_true(value); } -static void php_pqconn_object_read_db(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqconn_object_read_db(zval *object, void *o, zval *return_value) { php_pqconn_object_t *obj = o; char *db = PQdb(obj->intern->conn); if (db) { - RETVAL_STRING(db, 1); + RETVAL_STRING(db); } else { RETVAL_EMPTY_STRING(); } } -static void php_pqconn_object_read_user(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqconn_object_read_user(zval *object, void *o, zval *return_value) { php_pqconn_object_t *obj = o; char *user = PQuser(obj->intern->conn); if (user) { - RETVAL_STRING(user, 1); + RETVAL_STRING(user); } else { RETVAL_EMPTY_STRING(); } } -static void php_pqconn_object_read_pass(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqconn_object_read_pass(zval *object, void *o, zval *return_value) { php_pqconn_object_t *obj = o; char *pass = PQpass(obj->intern->conn); if (pass) { - RETVAL_STRING(pass, 1); + RETVAL_STRING(pass); } else { RETVAL_EMPTY_STRING(); } } -static void php_pqconn_object_read_host(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqconn_object_read_host(zval *object, void *o, zval *return_value) { php_pqconn_object_t *obj = o; char *host = PQhost(obj->intern->conn); if (host) { - RETVAL_STRING(host, 1); + RETVAL_STRING(host); } else { RETVAL_EMPTY_STRING(); } } -static void php_pqconn_object_read_port(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqconn_object_read_port(zval *object, void *o, zval *return_value) { php_pqconn_object_t *obj = o; char *port = PQport(obj->intern->conn); if (port) { - RETVAL_STRING(port, 1); + RETVAL_STRING(port); } else { RETVAL_EMPTY_STRING(); } } #if HAVE_PQCONNINFO -static void php_pqconn_object_read_params(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqconn_object_read_params(zval *object, void *o, zval *return_value) { php_pqconn_object_t *obj = o; PQconninfoOption *ptr, *params = PQconninfo(obj->intern->conn); @@ -312,7 +286,7 @@ static void php_pqconn_object_read_params(zval *object, void *o, zval *return_va if (params) { for (ptr = params; ptr->keyword; ++ptr) { if (ptr->val) { - add_assoc_string(return_value, ptr->keyword, ptr->val, 1); + add_assoc_string(return_value, ptr->keyword, ptr->val); } else { add_assoc_null(return_value, ptr->keyword); } @@ -322,202 +296,217 @@ static void php_pqconn_object_read_params(zval *object, void *o, zval *return_va } #endif -static void php_pqconn_object_read_options(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqconn_object_read_options(zval *object, void *o, zval *return_value) { php_pqconn_object_t *obj = o; char *options = PQoptions(obj->intern->conn); if (options) { - RETVAL_STRING(options, 1); + RETVAL_STRING(options); } else { RETVAL_EMPTY_STRING(); } } -static int apply_read_event_handler_ex(void *p, void *arg TSRMLS_DC) +static int apply_read_callback_ex(zval *p, void *arg) { HashTable *rv = arg; - zval *zcb = php_pq_callback_to_zval(p); + zval zcb; - zend_hash_next_index_insert(rv, &zcb, sizeof(zval *), NULL); + zend_hash_next_index_insert(rv, php_pq_callback_to_zval(Z_PTR_P(p), &zcb)); return ZEND_HASH_APPLY_KEEP; } -static int apply_read_event_handlers(void *p TSRMLS_DC, int argc, va_list argv, zend_hash_key *key) +static int apply_read_callbacks(zval *p, int argc, va_list argv, zend_hash_key *key) { - HashTable *evhs = p, *rv = va_arg(argv, HashTable *); - zval *entry, **entry_ptr; + HashTable *evhs = Z_ARRVAL_P(p), *rv = va_arg(argv, HashTable *); + zval entry, *entry_ptr; - MAKE_STD_ZVAL(entry); - array_init_size(entry, zend_hash_num_elements(evhs)); + array_init_size(&entry, zend_hash_num_elements(evhs)); - if (key->nKeyLength) { - zend_hash_add(rv, key->arKey, key->nKeyLength, &entry, sizeof(zval *), (void *) &entry_ptr); + if (key->key->len) { + entry_ptr = zend_hash_add(rv, key->key, &entry); } else { - zend_hash_index_update(rv, key->h, &entry, sizeof(zval *), (void *) &entry_ptr); + entry_ptr = zend_hash_index_update(rv, key->h, &entry); } - zend_hash_apply_with_argument(evhs, apply_read_event_handler_ex, Z_ARRVAL_PP(entry_ptr) TSRMLS_CC); + zend_hash_apply_with_argument(evhs, apply_read_callback_ex, Z_ARRVAL_P(entry_ptr)); return ZEND_HASH_APPLY_KEEP; } -static void php_pqconn_object_read_event_handlers(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqconn_object_read_event_handlers(zval *object, void *o, zval *return_value) { php_pqconn_object_t *obj = o; array_init(return_value); - zend_hash_apply_with_arguments(&obj->intern->eventhandlers TSRMLS_CC, apply_read_event_handlers, 1, Z_ARRVAL_P(return_value) TSRMLS_CC); + zend_hash_apply_with_arguments(&obj->intern->eventhandlers, apply_read_callbacks, 1, Z_ARRVAL_P(return_value)); } -static void php_pqconn_object_read_def_fetch_type(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqconn_object_gc_event_handlers(zval *object, void *o, zval *return_value) { php_pqconn_object_t *obj = o; + zval *evhs; - RETVAL_LONG(obj->intern->default_fetch_type); + ZEND_HASH_FOREACH_VAL(&obj->intern->eventhandlers, evhs) + { + zval *evh; + + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(evhs), evh) + { + zval zcb; + + add_next_index_zval(return_value, php_pq_callback_to_zval_no_addref(Z_PTR_P(evh), &zcb)); + } + ZEND_HASH_FOREACH_END(); + } + ZEND_HASH_FOREACH_END(); } -static void php_pqconn_object_write_def_fetch_type(zval *object, void *o, zval *value TSRMLS_DC) + +static void php_pqconn_object_read_listeners(zval *object, void *o, zval *return_value) { php_pqconn_object_t *obj = o; - zval *zft = value; - - if (Z_TYPE_P(zft) != IS_LONG) { - if (Z_REFCOUNT_P(zft) > 1) { - zval *tmp; - MAKE_STD_ZVAL(tmp); - ZVAL_ZVAL(tmp, zft, 1, 0); - convert_to_long(tmp); - zft = tmp; - } else { - convert_to_long_ex(&zft); + + array_init(return_value); + zend_hash_apply_with_arguments(&obj->intern->listeners, apply_read_callbacks, 1, Z_ARRVAL_P(return_value)); +} + +static void php_pqconn_object_gc_listeners(zval *object, void *o, zval *return_value) +{ + php_pqconn_object_t *obj = o; + zval *listeners; + + ZEND_HASH_FOREACH_VAL(&obj->intern->listeners, listeners) + { + zval *listener; + + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(listeners), listener) + { + zval zcb; + + add_next_index_zval(return_value, php_pq_callback_to_zval_no_addref(Z_PTR_P(listener), &zcb)); } + ZEND_HASH_FOREACH_END(); } + ZEND_HASH_FOREACH_END(); +} + +static void php_pqconn_object_read_converters(zval *object, void *o, zval *return_value) +{ + php_pqconn_object_t *obj = o; + + array_init(return_value); + zend_hash_copy(Z_ARRVAL_P(return_value), &obj->intern->converters, zval_add_ref); +} - obj->intern->default_fetch_type = Z_LVAL_P(zft) & 0x3; /* two bits only */ +static void php_pqconn_object_gc_converters(zval *object, void *o, zval *return_value) +{ + php_pqconn_object_t *obj = o; + zval *converter; - if (zft != value) { - zval_ptr_dtor(&zft); + ZEND_HASH_FOREACH_VAL(&obj->intern->converters, converter) + { + add_next_index_zval(return_value, converter); } + ZEND_HASH_FOREACH_END(); } -static void php_pqconn_object_read_def_txn_isolation(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqconn_object_read_def_fetch_type(zval *object, void *o, zval *return_value) { php_pqconn_object_t *obj = o; - RETVAL_LONG(obj->intern->default_txn_isolation); + RETVAL_LONG(obj->intern->default_fetch_type); } -static void php_pqconn_object_write_def_txn_isolation(zval *object, void *o, zval *value TSRMLS_DC) +static void php_pqconn_object_write_def_fetch_type(zval *object, void *o, zval *value) { php_pqconn_object_t *obj = o; - zval *zti = value; - - if (Z_TYPE_P(zti) != IS_LONG) { - if (Z_REFCOUNT_P(zti) > 1) { - zval *tmp; - MAKE_STD_ZVAL(tmp); - ZVAL_ZVAL(tmp, zti, 1, 0); - convert_to_long(tmp); - zti = tmp; - } else { - convert_to_long_ex(&zti); - } - } - obj->intern->default_txn_isolation = Z_LVAL_P(zti) & 0x3; /* two bits only */ + obj->intern->default_fetch_type = zval_get_long(value) & 0x3; /* two bits only */ +} + +static void php_pqconn_object_read_def_txn_isolation(zval *object, void *o, zval *return_value) +{ + php_pqconn_object_t *obj = o; - if (zti != value) { - zval_ptr_dtor(&zti); - } + RETVAL_LONG(obj->intern->default_txn_isolation); +} +static void php_pqconn_object_write_def_txn_isolation(zval *object, void *o, zval *value) +{ + php_pqconn_object_t *obj = o; + + obj->intern->default_txn_isolation = zval_get_long(value) & 0x3; /* two bits only */ } -static void php_pqconn_object_read_def_txn_readonly(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqconn_object_read_def_txn_readonly(zval *object, void *o, zval *return_value) { php_pqconn_object_t *obj = o; RETVAL_BOOL(obj->intern->default_txn_readonly); } -static void php_pqconn_object_write_def_txn_readonly(zval *object, void *o, zval *value TSRMLS_DC) +static void php_pqconn_object_write_def_txn_readonly(zval *object, void *o, zval *value) { php_pqconn_object_t *obj = o; - obj->intern->default_txn_readonly = zend_is_true(value); + obj->intern->default_txn_readonly = z_is_true(value); } -static void php_pqconn_object_read_def_txn_deferrable(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqconn_object_read_def_txn_deferrable(zval *object, void *o, zval *return_value) { php_pqconn_object_t *obj = o; RETVAL_BOOL(obj->intern->default_txn_deferrable); } -static void php_pqconn_object_write_def_txn_deferrable(zval *object, void *o, zval *value TSRMLS_DC) +static void php_pqconn_object_write_def_txn_deferrable(zval *object, void *o, zval *value) { php_pqconn_object_t *obj = o; obj->intern->default_txn_deferrable = zend_is_true(value); } -static void php_pqconn_object_read_def_auto_conv(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqconn_object_read_def_auto_conv(zval *object, void *o, zval *return_value) { php_pqconn_object_t *obj = o; RETVAL_LONG(obj->intern->default_auto_convert); } -static void php_pqconn_object_write_def_auto_conv(zval*object, void *o, zval *value TSRMLS_DC) +static void php_pqconn_object_write_def_auto_conv(zval*object, void *o, zval *value) { php_pqconn_object_t *obj = o; - zval *zac = value; - - if (Z_TYPE_P(zac) != IS_LONG) { - if (Z_REFCOUNT_P(zac) > 1) { - zval *tmp; - MAKE_STD_ZVAL(tmp); - ZVAL_ZVAL(tmp, zac, 1, 0); - convert_to_long(tmp); - zac = tmp; - } else { - convert_to_long_ex(&zac); - } - } - obj->intern->default_auto_convert = Z_LVAL_P(zac) & PHP_PQRES_CONV_ALL; - - if (zac != value) { - zval_ptr_dtor(&zac); - } + obj->intern->default_auto_convert = zval_get_long(value) & PHP_PQRES_CONV_ALL; } -static ZEND_RESULT_CODE php_pqconn_update_socket(zval *this_ptr, php_pqconn_object_t *obj TSRMLS_DC) +static ZEND_RESULT_CODE php_pqconn_update_socket(zval *zobj, php_pqconn_object_t *obj) { - zval *zsocket, zmember; + zval zsocket, zmember; php_stream *stream; ZEND_RESULT_CODE retval; int socket; if (!obj) { - obj = zend_object_store_get_object(getThis() TSRMLS_CC); + obj = PHP_PQ_OBJ(zobj, NULL); } - INIT_PZVAL(&zmember); - ZVAL_STRINGL(&zmember, "socket", sizeof("socket")-1, 0); - MAKE_STD_ZVAL(zsocket); + ZVAL_STRINGL(&zmember, "socket", sizeof("socket")-1); if ((CONNECTION_BAD != PQstatus(obj->intern->conn)) && (-1 < (socket = PQsocket(obj->intern->conn))) && (stream = php_stream_fopen_from_fd(socket, "r+b", NULL))) { stream->flags |= PHP_STREAM_FLAG_NO_CLOSE; - php_stream_to_zval(stream, zsocket); + php_stream_to_zval(stream, &zsocket); retval = SUCCESS; } else { - ZVAL_NULL(zsocket); + ZVAL_NULL(&zsocket); retval = FAILURE; } - zend_get_std_object_handlers()->write_property(getThis(), &zmember, zsocket, NULL TSRMLS_CC); + zend_get_std_object_handlers()->write_property(zobj, &zmember, &zsocket, NULL); zval_ptr_dtor(&zsocket); + zval_ptr_dtor(&zmember); return retval; } -static void *php_pqconn_resource_factory_ctor(void *data, void *init_arg TSRMLS_DC) +static void *php_pqconn_resource_factory_ctor(void *data, void *init_arg) { php_pqconn_resource_factory_data_t *o = init_arg; PGconn *conn = NULL;; @@ -535,7 +524,7 @@ static void *php_pqconn_resource_factory_ctor(void *data, void *init_arg TSRMLS_ return conn; } -static void php_pqconn_resource_factory_dtor(void *opaque, void *handle TSRMLS_DC) +static void php_pqconn_resource_factory_dtor(void *opaque, void *handle) { php_pqconn_event_data_t *evdata = PQinstanceData(handle, php_pqconn_event); @@ -560,7 +549,7 @@ php_resource_factory_ops_t *php_pqconn_get_resource_factory_ops(void) return &php_pqconn_resource_factory_ops; } -static void php_pqconn_wakeup(php_persistent_handle_factory_t *f, void **handle TSRMLS_DC) +static void php_pqconn_wakeup(php_persistent_handle_factory_t *f, void **handle) { PGresult *res = PQexec(*handle, ""); PHP_PQclear(res); @@ -570,7 +559,7 @@ static void php_pqconn_wakeup(php_persistent_handle_factory_t *f, void **handle } } -static inline PGresult *unlisten(PGconn *conn, const char *channel_str, size_t channel_len TSRMLS_DC) +static inline PGresult *unlisten(PGconn *conn, const char *channel_str, size_t channel_len) { char *quoted_channel = PQescapeIdentifier(conn, channel_str, channel_len); PGresult *res = NULL; @@ -582,7 +571,7 @@ static inline PGresult *unlisten(PGconn *conn, const char *channel_str, size_t c smart_str_appends(&cmd, quoted_channel); smart_str_0(&cmd); - res = PQexec(conn, cmd.c); + res = PQexec(conn, smart_str_v(&cmd)); smart_str_free(&cmd); PQfreemem(quoted_channel); @@ -591,10 +580,10 @@ static inline PGresult *unlisten(PGconn *conn, const char *channel_str, size_t c return res; } -static int apply_unlisten(void *p TSRMLS_DC, int argc, va_list argv, zend_hash_key *key) +static int apply_unlisten(zval *p, int argc, va_list argv, zend_hash_key *key) { php_pqconn_object_t *obj = va_arg(argv, php_pqconn_object_t *); - PGresult *res = unlisten(obj->intern->conn, key->arKey, key->nKeyLength - 1 TSRMLS_CC); + PGresult *res = unlisten(obj->intern->conn, key->key->val, key->key->len); if (res) { PHP_PQclear(res); @@ -603,7 +592,7 @@ static int apply_unlisten(void *p TSRMLS_DC, int argc, va_list argv, zend_hash_k return ZEND_HASH_APPLY_REMOVE; } -static void php_pqconn_retire(php_persistent_handle_factory_t *f, void **handle TSRMLS_DC) +static void php_pqconn_retire(php_persistent_handle_factory_t *f, void **handle) { php_pqconn_event_data_t *evdata = PQinstanceData(*handle, php_pqconn_event); PGcancel *cancel; @@ -643,7 +632,7 @@ static void php_pqconn_retire(php_persistent_handle_factory_t *f, void **handle if (evdata) { /* clean up notify listeners */ - zend_hash_apply_with_arguments(&evdata->obj->intern->listeners TSRMLS_CC, apply_unlisten, 1, evdata->obj); + zend_hash_apply_with_arguments(&evdata->obj->intern->listeners, apply_unlisten, 1, evdata->obj); /* release instance data */ efree(evdata); @@ -657,34 +646,36 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(pqconn, __construct) { zend_error_handling zeh; char *dsn_str = ""; - int dsn_len = 0; - long flags = 0; + size_t dsn_len = 0; + zend_long flags = 0; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sl", &dsn_str, &dsn_len, &flags); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "|sl", &dsn_str, &dsn_len, &flags); zend_restore_error_handling(&zeh TSRMLS_CC); if (SUCCESS == rv) { - php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (obj->intern) { - throw_exce(EX_BAD_METHODCALL TSRMLS_CC, "pq\\Connection already initialized"); + throw_exce(EX_BAD_METHODCALL, "pq\\Connection already initialized"); } else { - php_pqconn_event_data_t *evdata = php_pqconn_event_data_init(obj TSRMLS_CC); + php_pqconn_event_data_t *evdata = php_pqconn_event_data_init(obj); php_pqconn_resource_factory_data_t rfdata = {dsn_str, flags}; obj->intern = ecalloc(1, sizeof(*obj->intern)); obj->intern->default_auto_convert = PHP_PQRES_CONV_ALL; - zend_hash_init(&obj->intern->listeners, 0, NULL, (dtor_func_t) zend_hash_destroy, 0); + zend_hash_init(&obj->intern->listeners, 0, NULL, ZVAL_PTR_DTOR, 0); zend_hash_init(&obj->intern->converters, 0, NULL, ZVAL_PTR_DTOR, 0); - zend_hash_init(&obj->intern->eventhandlers, 0, NULL, (dtor_func_t) zend_hash_destroy, 0); + zend_hash_init(&obj->intern->eventhandlers, 0, NULL, ZVAL_PTR_DTOR, 0); if (flags & PHP_PQCONN_PERSISTENT) { - php_persistent_handle_factory_t *phf = php_persistent_handle_concede(NULL, ZEND_STRL("pq\\Connection"), dsn_str, dsn_len, php_pqconn_wakeup, php_pqconn_retire TSRMLS_CC); + zend_string *dsn = zend_string_init(dsn_str, dsn_len, 0); + php_persistent_handle_factory_t *phf = php_persistent_handle_concede(NULL, PHP_PQ_G->connection.name, dsn, php_pqconn_wakeup, php_pqconn_retire); php_persistent_handle_resource_factory_init(&obj->intern->factory, phf); + zend_string_release(dsn); } else { php_resource_factory_init(&obj->intern->factory, &php_pqconn_resource_factory_ops, NULL, NULL); } @@ -693,13 +684,13 @@ static PHP_METHOD(pqconn, __construct) { obj->intern->poller = (int (*)(PGconn*)) PQconnectPoll; } - obj->intern->conn = php_resource_factory_handle_ctor(&obj->intern->factory, &rfdata TSRMLS_CC); + obj->intern->conn = php_resource_factory_handle_ctor(&obj->intern->factory, &rfdata); PQsetInstanceData(obj->intern->conn, php_pqconn_event, evdata); PQsetNoticeReceiver(obj->intern->conn, php_pqconn_notice_recv, evdata); - if (SUCCESS != php_pqconn_update_socket(getThis(), obj TSRMLS_CC)) { - throw_exce(EX_CONNECTION_FAILED TSRMLS_CC, "Connection failed (%s)", PHP_PQerrorMessage(obj->intern->conn)); + if (SUCCESS != php_pqconn_update_socket(getThis(), obj)) { + throw_exce(EX_CONNECTION_FAILED, "Connection failed (%s)", PHP_PQerrorMessage(obj->intern->conn)); } } } @@ -711,23 +702,23 @@ static PHP_METHOD(pqconn, reset) { zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); rv = zend_parse_parameters_none(); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized"); } else { PQreset(obj->intern->conn); if (CONNECTION_OK != PQstatus(obj->intern->conn)) { - throw_exce(EX_CONNECTION_FAILED TSRMLS_CC, "Connection reset failed: (%s)", PHP_PQerrorMessage(obj->intern->conn)); + throw_exce(EX_CONNECTION_FAILED, "Connection reset failed: (%s)", PHP_PQerrorMessage(obj->intern->conn)); } - php_pqconn_notify_listeners(obj TSRMLS_CC); + php_pqconn_notify_listeners(obj); } } } @@ -738,12 +729,12 @@ static PHP_METHOD(pqconn, resetAsync) { zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); rv = zend_parse_parameters_none(); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized"); @@ -754,7 +745,7 @@ static PHP_METHOD(pqconn, resetAsync) { obj->intern->poller = (int (*)(PGconn*)) PQresetPoll; } - php_pqconn_notify_listeners(obj TSRMLS_CC); + php_pqconn_notify_listeners(obj); } } } @@ -766,23 +757,23 @@ static PHP_METHOD(pqconn, unlisten) { zend_error_handling zeh; char *channel_str; - int channel_len; + size_t channel_len; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &channel_str, &channel_len); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "s", &channel_str, &channel_len); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized"); - } else if (SUCCESS == zend_hash_del(&obj->intern->listeners, channel_str, channel_len + 1)) { - PGresult *res = unlisten(obj->intern->conn, channel_str, channel_len TSRMLS_CC); + throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized"); + } else if (SUCCESS == zend_hash_str_del(&obj->intern->listeners, channel_str, channel_len)) { + PGresult *res = unlisten(obj->intern->conn, channel_str, channel_len); if (res) { - php_pqres_success(res TSRMLS_CC); + php_pqres_success(res); PHP_PQclear(res); } } @@ -795,23 +786,23 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(pqconn, unlistenAsync) { zend_error_handling zeh; char *channel_str; - int channel_len; + size_t channel_len; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &channel_str, &channel_len); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "s", &channel_str, &channel_len); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized"); } else { char *quoted_channel = PQescapeIdentifier(obj->intern->conn, channel_str, channel_len); if (!quoted_channel) { - throw_exce(EX_ESCAPE TSRMLS_CC, "Failed to escape channel identifier (%s)", PHP_PQerrorMessage(obj->intern->conn)); + throw_exce(EX_ESCAPE, "Failed to escape channel identifier (%s)", PHP_PQerrorMessage(obj->intern->conn)); } else { smart_str cmd = {0}; @@ -819,33 +810,39 @@ static PHP_METHOD(pqconn, unlistenAsync) { smart_str_appends(&cmd, quoted_channel); smart_str_0(&cmd); - if (!PQsendQuery(obj->intern->conn, cmd.c)) { - throw_exce(EX_IO TSRMLS_CC, "Failed to uninstall listener (%s)", PHP_PQerrorMessage(obj->intern->conn)); + if (!PQsendQuery(obj->intern->conn, smart_str_v(&cmd))) { + throw_exce(EX_IO, "Failed to uninstall listener (%s)", PHP_PQerrorMessage(obj->intern->conn)); } else { obj->intern->poller = PQconsumeInput; - zend_hash_del(&obj->intern->listeners, channel_str, channel_len + 1); + zend_hash_str_del(&obj->intern->listeners, channel_str, channel_len); } smart_str_free(&cmd); PQfreemem(quoted_channel); - php_pqconn_notify_listeners(obj TSRMLS_CC); + php_pqconn_notify_listeners(obj); } } } } -static void php_pqconn_add_listener(php_pqconn_object_t *obj, const char *channel_str, size_t channel_len, php_pq_callback_t *listener TSRMLS_DC) +static void php_pqconn_add_listener(php_pqconn_object_t *obj, const char *channel_str, size_t channel_len, php_pq_callback_t *listener) { - HashTable ht, *existing_listeners; + zval *existing; php_pq_callback_addref(listener); - if (SUCCESS == zend_hash_find(&obj->intern->listeners, channel_str, channel_len + 1, (void *) &existing_listeners)) { - zend_hash_next_index_insert(existing_listeners, (void *) listener, sizeof(*listener), NULL); + if ((existing = zend_hash_str_find(&obj->intern->listeners, channel_str, channel_len))) { + zend_hash_next_index_insert_mem(Z_ARRVAL_P(existing), (void *) listener, sizeof(*listener)); } else { - zend_hash_init(&ht, 1, NULL, (dtor_func_t) php_pq_callback_dtor, 0); - zend_hash_next_index_insert(&ht, (void *) listener, sizeof(*listener), NULL); - zend_hash_add(&obj->intern->listeners, channel_str, channel_len + 1, (void *) &ht, sizeof(HashTable), NULL); + zval tmp; + HashTable *ht; + + ALLOC_HASHTABLE(ht); + zend_hash_init(ht, 0, NULL, php_pq_callback_hash_dtor, 0); + zend_hash_next_index_insert_mem(ht, (void *) listener, sizeof(*listener)); + + ZVAL_ARR(&tmp, ht); + zend_hash_str_add(&obj->intern->listeners, channel_str, channel_len, &tmp); } } @@ -856,24 +853,24 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(pqconn, listen) { zend_error_handling zeh; char *channel_str = NULL; - int channel_len = 0; + size_t channel_len = 0; php_pq_callback_t listener = {{0}}; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sf", &channel_str, &channel_len, &listener.fci, &listener.fcc); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "sf", &channel_str, &channel_len, &listener.fci, &listener.fcc); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized"); } else { char *quoted_channel = PQescapeIdentifier(obj->intern->conn, channel_str, channel_len); if (!quoted_channel) { - throw_exce(EX_ESCAPE TSRMLS_CC, "Failed to escape channel identifier (%s)", PHP_PQerrorMessage(obj->intern->conn)); + throw_exce(EX_ESCAPE, "Failed to escape channel identifier (%s)", PHP_PQerrorMessage(obj->intern->conn)); } else { PGresult *res; smart_str cmd = {0}; @@ -882,22 +879,22 @@ static PHP_METHOD(pqconn, listen) { smart_str_appends(&cmd, quoted_channel); smart_str_0(&cmd); - res = PQexec(obj->intern->conn, cmd.c); + res = PQexec(obj->intern->conn, smart_str_v(&cmd)); smart_str_free(&cmd); PQfreemem(quoted_channel); if (!res) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to install listener (%s)", PHP_PQerrorMessage(obj->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to install listener (%s)", PHP_PQerrorMessage(obj->intern->conn)); } else { - if (SUCCESS == php_pqres_success(res TSRMLS_CC)) { + if (SUCCESS == php_pqres_success(res)) { obj->intern->poller = PQconsumeInput; - php_pqconn_add_listener(obj, channel_str, channel_len, &listener TSRMLS_CC); + php_pqconn_add_listener(obj, channel_str, channel_len, &listener); } PHP_PQclear(res); } - php_pqconn_notify_listeners(obj TSRMLS_CC); + php_pqconn_notify_listeners(obj); } } } @@ -910,16 +907,16 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(pqconn, listenAsync) { zend_error_handling zeh; char *channel_str = NULL; - int channel_len = 0; + size_t channel_len = 0; php_pq_callback_t listener = {{0}}; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sf", &channel_str, &channel_len, &listener.fci, &listener.fcc); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "sf", &channel_str, &channel_len, &listener.fci, &listener.fcc); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized"); @@ -935,16 +932,16 @@ static PHP_METHOD(pqconn, listenAsync) { smart_str_appends(&cmd, quoted_channel); smart_str_0(&cmd); - if (!PQsendQuery(obj->intern->conn, cmd.c)) { - throw_exce(EX_IO TSRMLS_CC, "Failed to install listener (%s)", PHP_PQerrorMessage(obj->intern->conn)); + if (!PQsendQuery(obj->intern->conn, smart_str_v(&cmd))) { + throw_exce(EX_IO, "Failed to install listener (%s)", PHP_PQerrorMessage(obj->intern->conn)); } else { obj->intern->poller = PQconsumeInput; - php_pqconn_add_listener(obj, channel_str, channel_len, &listener TSRMLS_CC); + php_pqconn_add_listener(obj, channel_str, channel_len, &listener); } smart_str_free(&cmd); PQfreemem(quoted_channel); - php_pqconn_notify_listeners(obj TSRMLS_CC); + php_pqconn_notify_listeners(obj); } } } @@ -957,18 +954,18 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(pqconn, notify) { zend_error_handling zeh; char *channel_str, *message_str; - int channel_len, message_len; + size_t channel_len, message_len; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &channel_str, &channel_len, &message_str, &message_len); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "ss", &channel_str, &channel_len, &message_str, &message_len); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized"); } else { PGresult *res; char *params[2] = {channel_str, message_str}; @@ -976,13 +973,13 @@ static PHP_METHOD(pqconn, notify) { res = PQexecParams(obj->intern->conn, "select pg_notify($1, $2)", 2, NULL, (const char *const*) params, NULL, NULL, 0); if (!res) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to notify listeners (%s)", PHP_PQerrorMessage(obj->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to notify listeners (%s)", PHP_PQerrorMessage(obj->intern->conn)); } else { - php_pqres_success(res TSRMLS_CC); + php_pqres_success(res); PHP_PQclear(res); } - php_pqconn_notify_listeners(obj TSRMLS_CC); + php_pqconn_notify_listeners(obj); } } } @@ -994,28 +991,28 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(pqconn, notifyAsync) { zend_error_handling zeh; char *channel_str, *message_str; - int channel_len, message_len; + size_t channel_len, message_len; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &channel_str, &channel_len, &message_str, &message_len); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "ss", &channel_str, &channel_len, &message_str, &message_len); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized"); } else { char *params[2] = {channel_str, message_str}; if (!PQsendQueryParams(obj->intern->conn, "select pg_notify($1, $2)", 2, NULL, (const char *const*) params, NULL, NULL, 0)) { - throw_exce(EX_IO TSRMLS_CC, "Failed to notify listeners (%s)", PHP_PQerrorMessage(obj->intern->conn)); + throw_exce(EX_IO, "Failed to notify listeners (%s)", PHP_PQerrorMessage(obj->intern->conn)); } else { obj->intern->poller = PQconsumeInput; } - php_pqconn_notify_listeners(obj TSRMLS_CC); + php_pqconn_notify_listeners(obj); } } } @@ -1026,24 +1023,24 @@ static PHP_METHOD(pqconn, poll) { zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); rv = zend_parse_parameters_none(); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized"); } else if (!obj->intern->poller) { - throw_exce(EX_RUNTIME TSRMLS_CC, "No asynchronous operation active"); + throw_exce(EX_RUNTIME, "No asynchronous operation active"); } else { if (obj->intern->poller == PQconsumeInput) { RETVAL_LONG(obj->intern->poller(obj->intern->conn) * PGRES_POLLING_OK); } else { RETVAL_LONG(obj->intern->poller(obj->intern->conn)); } - php_pqconn_notify_listeners(obj TSRMLS_CC); + php_pqconn_notify_listeners(obj); } } } @@ -1054,30 +1051,30 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(pqconn, exec) { zend_error_handling zeh; char *query_str; - int query_len; + size_t query_len; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &query_str, &query_len); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "s", &query_str, &query_len); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized"); } else { PGresult *res = PQexec(obj->intern->conn, query_str); if (!res) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to execute query (%s)", PHP_PQerrorMessage(obj->intern->conn)); - } else if (SUCCESS == php_pqres_success(res TSRMLS_CC)) { - php_pq_object_to_zval_no_addref(PQresultInstanceData(res, php_pqconn_event), &return_value TSRMLS_CC); + throw_exce(EX_RUNTIME, "Failed to execute query (%s)", PHP_PQerrorMessage(obj->intern->conn)); + } else if (SUCCESS == php_pqres_success(res)) { + php_pq_object_to_zval_no_addref(PQresultInstanceData(res, php_pqconn_event), return_value); } else { PHP_PQclear(res); } - php_pqconn_notify_listeners(obj TSRMLS_CC); + php_pqconn_notify_listeners(obj); } } } @@ -1088,25 +1085,25 @@ static PHP_METHOD(pqconn, getResult) { zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); rv = zend_parse_parameters_none(); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized"); } else { PGresult *res = PQgetResult(obj->intern->conn); if (!res) { RETVAL_NULL(); } else { - php_pq_object_to_zval_no_addref(PQresultInstanceData(res, php_pqconn_event), &return_value TSRMLS_CC); + php_pq_object_to_zval_no_addref(PQresultInstanceData(res, php_pqconn_event), return_value); } - php_pqconn_notify_listeners(obj TSRMLS_CC); + php_pqconn_notify_listeners(obj); } } } @@ -1119,28 +1116,28 @@ static PHP_METHOD(pqconn, execAsync) { zend_error_handling zeh; php_pq_callback_t resolver = {{0}}; char *query_str; - int query_len; + size_t query_len; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|f", &query_str, &query_len, &resolver.fci, &resolver.fcc); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "s|f", &query_str, &query_len, &resolver.fci, &resolver.fcc); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized"); } else if (!PQsendQuery(obj->intern->conn, query_str)) { - throw_exce(EX_IO TSRMLS_CC, "Failed to execute query (%s)", PHP_PQerrorMessage(obj->intern->conn)); + throw_exce(EX_IO, "Failed to execute query (%s)", PHP_PQerrorMessage(obj->intern->conn)); #if HAVE_PQSETSINGLEROWMODE } else if (obj->intern->unbuffered && !PQsetSingleRowMode(obj->intern->conn)) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj->intern->conn)); #endif } else { - php_pq_callback_recurse(&obj->intern->onevent, &resolver TSRMLS_CC); + php_pq_callback_recurse(&obj->intern->onevent, &resolver); obj->intern->poller = PQconsumeInput; - php_pqconn_notify_listeners(obj TSRMLS_CC); + php_pqconn_notify_listeners(obj); } } } @@ -1153,38 +1150,38 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(pqconn, execParams) { zend_error_handling zeh; char *query_str; - int query_len; + size_t query_len; zval *zparams; zval *ztypes = NULL; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa/|a/!", &query_str, &query_len, &zparams, &ztypes); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "sa/|a/!", &query_str, &query_len, &zparams, &ztypes); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized"); } else { PGresult *res; php_pq_params_t *params; - params = php_pq_params_init(&obj->intern->converters, ztypes ? Z_ARRVAL_P(ztypes) : NULL, Z_ARRVAL_P(zparams) TSRMLS_CC); + params = php_pq_params_init(&obj->intern->converters, ztypes ? Z_ARRVAL_P(ztypes) : NULL, Z_ARRVAL_P(zparams)); res = PQexecParams(obj->intern->conn, query_str, params->param.count, params->type.oids, (const char *const*) params->param.strings, NULL, NULL, 0); php_pq_params_free(¶ms); if (!res) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to execute query (%s)", PHP_PQerrorMessage(obj->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to execute query (%s)", PHP_PQerrorMessage(obj->intern->conn)); } else { - if (SUCCESS == php_pqres_success(res TSRMLS_CC)) { - php_pq_object_to_zval_no_addref(PQresultInstanceData(res, php_pqconn_event), &return_value TSRMLS_CC); + if (SUCCESS == php_pqres_success(res)) { + php_pq_object_to_zval_no_addref(PQresultInstanceData(res, php_pqconn_event), return_value); } else { PHP_PQclear(res); } - php_pqconn_notify_listeners(obj TSRMLS_CC); + php_pqconn_notify_listeners(obj); } } } @@ -1200,62 +1197,62 @@ static PHP_METHOD(pqconn, execParamsAsync) { zend_error_handling zeh; php_pq_callback_t resolver = {{0}}; char *query_str; - int query_len; + size_t query_len; zval *zparams; zval *ztypes = NULL; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa/|a/!f", &query_str, &query_len, &zparams, &ztypes, &resolver.fci, &resolver.fcc); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "sa/|a/!f", &query_str, &query_len, &zparams, &ztypes, &resolver.fci, &resolver.fcc); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized"); } else { int rc; php_pq_params_t *params; - params = php_pq_params_init(&obj->intern->converters, ztypes ? Z_ARRVAL_P(ztypes) : NULL, Z_ARRVAL_P(zparams) TSRMLS_CC); + params = php_pq_params_init(&obj->intern->converters, ztypes ? Z_ARRVAL_P(ztypes) : NULL, Z_ARRVAL_P(zparams)); rc = PQsendQueryParams(obj->intern->conn, query_str, params->param.count, params->type.oids, (const char *const*) params->param.strings, NULL, NULL, 0); php_pq_params_free(¶ms); if (!rc) { - throw_exce(EX_IO TSRMLS_CC, "Failed to execute query (%s)", PHP_PQerrorMessage(obj->intern->conn)); + throw_exce(EX_IO, "Failed to execute query (%s)", PHP_PQerrorMessage(obj->intern->conn)); #if HAVE_PQSETSINGLEROWMODE } else if (obj->intern->unbuffered && !PQsetSingleRowMode(obj->intern->conn)) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj->intern->conn)); #endif } else { - php_pq_callback_recurse(&obj->intern->onevent, &resolver TSRMLS_CC); + php_pq_callback_recurse(&obj->intern->onevent, &resolver); obj->intern->poller = PQconsumeInput; - php_pqconn_notify_listeners(obj TSRMLS_CC); + php_pqconn_notify_listeners(obj); } } } - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); } -ZEND_RESULT_CODE php_pqconn_prepare(zval *object, php_pqconn_object_t *obj, const char *name, const char *query, php_pq_params_t *params TSRMLS_DC) +ZEND_RESULT_CODE php_pqconn_prepare(zval *object, php_pqconn_object_t *obj, const char *name, const char *query, php_pq_params_t *params) { PGresult *res; ZEND_RESULT_CODE rv; if (!obj) { - obj = zend_object_store_get_object(object TSRMLS_CC); + obj = PHP_PQ_OBJ(object, NULL); } res = PQprepare(obj->intern->conn, name, query, params->type.count, params->type.oids); if (!res) { rv = FAILURE; - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to prepare statement (%s)", PHP_PQerrorMessage(obj->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to prepare statement (%s)", PHP_PQerrorMessage(obj->intern->conn)); } else { - rv = php_pqres_success(res TSRMLS_CC); + rv = php_pqres_success(res); PHP_PQclear(res); - php_pqconn_notify_listeners(obj TSRMLS_CC); + php_pqconn_notify_listeners(obj); } return rv; @@ -1270,28 +1267,27 @@ static PHP_METHOD(pqconn, prepare) { zend_error_handling zeh; zval *ztypes = NULL; char *name_str, *query_str; - int name_len, *query_len; + size_t name_len, *query_len; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|a/!", &name_str, &name_len, &query_str, &query_len, &ztypes); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "ss|a/!", &name_str, &name_len, &query_str, &query_len, &ztypes); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized"); } else { - php_pq_params_t *params = php_pq_params_init(&obj->intern->converters, ztypes ? Z_ARRVAL_P(ztypes) : NULL, NULL TSRMLS_CC); + php_pq_params_t *params = php_pq_params_init(&obj->intern->converters, ztypes ? Z_ARRVAL_P(ztypes) : NULL, NULL); - if (SUCCESS != php_pqconn_prepare(getThis(), obj, name_str, query_str, params TSRMLS_CC)) { + if (SUCCESS != php_pqconn_prepare(getThis(), obj, name_str, query_str, params)) { php_pq_params_free(¶ms); } else { - php_pqstm_t *stm = php_pqstm_init(obj, name_str, query_str, params TSRMLS_CC); + php_pqstm_t *stm = php_pqstm_init(obj, name_str, query_str, params); - return_value->type = IS_OBJECT; - return_value->value.obj = php_pqstm_create_object_ex(php_pqstm_class_entry, stm, NULL TSRMLS_CC); + RETVAL_OBJ(&php_pqstm_create_object_ex(php_pqstm_class_entry, stm)->zo); } } } @@ -1302,16 +1298,16 @@ ZEND_RESULT_CODE php_pqconn_prepare_async(zval *object, php_pqconn_object_t *obj ZEND_RESULT_CODE rv; if (!obj) { - obj = zend_object_store_get_object(object TSRMLS_CC); + obj = PHP_PQ_OBJ(object, NULL); } if (!PQsendPrepare(obj->intern->conn, name, query, params->type.count, params->type.oids)) { rv = FAILURE; - throw_exce(EX_IO TSRMLS_CC, "Failed to prepare statement (%s)", PHP_PQerrorMessage(obj->intern->conn)); + throw_exce(EX_IO, "Failed to prepare statement (%s)", PHP_PQerrorMessage(obj->intern->conn)); } else { rv = SUCCESS; obj->intern->poller = PQconsumeInput; - php_pqconn_notify_listeners(obj TSRMLS_CC); + php_pqconn_notify_listeners(obj); } return rv; @@ -1326,51 +1322,50 @@ static PHP_METHOD(pqconn, prepareAsync) { zend_error_handling zeh; zval *ztypes = NULL; char *name_str, *query_str; - int name_len, *query_len; + size_t name_len, *query_len; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|a/!", &name_str, &name_len, &query_str, &query_len, &ztypes); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "ss|a/!", &name_str, &name_len, &query_str, &query_len, &ztypes); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized"); } else { - php_pq_params_t *params = php_pq_params_init(&obj->intern->converters, ztypes ? Z_ARRVAL_P(ztypes) : NULL, NULL TSRMLS_CC); + php_pq_params_t *params = php_pq_params_init(&obj->intern->converters, ztypes ? Z_ARRVAL_P(ztypes) : NULL, NULL); - if (SUCCESS != php_pqconn_prepare_async(getThis(), obj, name_str, query_str, params TSRMLS_CC)) { + if (SUCCESS != php_pqconn_prepare_async(getThis(), obj, name_str, query_str, params)) { php_pq_params_free(¶ms); } else { - php_pqstm_t *stm = php_pqstm_init(obj, name_str, query_str, params TSRMLS_CC); + php_pqstm_t *stm = php_pqstm_init(obj, name_str, query_str, params); - return_value->type = IS_OBJECT; - return_value->value.obj = php_pqstm_create_object_ex(php_pqstm_class_entry, stm, NULL TSRMLS_CC); + RETVAL_OBJ(&php_pqstm_create_object_ex(php_pqstm_class_entry, stm)->zo); } } } } -ZEND_RESULT_CODE php_pqconn_declare(zval *object, php_pqconn_object_t *obj, const char *decl TSRMLS_DC) +ZEND_RESULT_CODE php_pqconn_declare(zval *object, php_pqconn_object_t *obj, const char *decl) { PGresult *res; ZEND_RESULT_CODE rv; if (!obj) { - obj = zend_object_store_get_object(object TSRMLS_CC); + obj = PHP_PQ_OBJ(object, NULL); } res = PQexec(obj->intern->conn, decl); if (!res) { rv = FAILURE; - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to declare cursor (%s)", PHP_PQerrorMessage(obj->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to declare cursor (%s)", PHP_PQerrorMessage(obj->intern->conn)); } else { - rv = php_pqres_success(res TSRMLS_CC); + rv = php_pqres_success(res); PHP_PQclear(res); - php_pqconn_notify_listeners(obj TSRMLS_CC); + php_pqconn_notify_listeners(obj); } return rv; @@ -1384,50 +1379,49 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(pqconn, declare) { zend_error_handling zeh; char *name_str, *query_str; - int name_len, query_len; - long flags; + size_t name_len, query_len; + zend_long flags; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sls", &name_str, &name_len, &flags, &query_str, &query_len); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "sls", &name_str, &name_len, &flags, &query_str, &query_len); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized"); } else { int query_offset; char *decl = php_pqcur_declare_str(name_str, name_len, flags, query_str, query_len, &query_offset); - if (SUCCESS != php_pqconn_declare(getThis(), obj, decl TSRMLS_CC)) { + if (SUCCESS != php_pqconn_declare(getThis(), obj, decl)) { efree(decl); } else { - php_pqcur_t *cur = php_pqcur_init(obj, name_str, decl, query_offset, flags TSRMLS_CC); + php_pqcur_t *cur = php_pqcur_init(obj, name_str, decl, query_offset, flags); - return_value->type = IS_OBJECT; - return_value->value.obj = php_pqcur_create_object_ex(php_pqcur_class_entry, cur, NULL TSRMLS_CC); + RETVAL_OBJ(&php_pqcur_create_object_ex(php_pqcur_class_entry, cur)->zo); } } } } -ZEND_RESULT_CODE php_pqconn_declare_async(zval *object, php_pqconn_object_t *obj, const char *decl TSRMLS_DC) +ZEND_RESULT_CODE php_pqconn_declare_async(zval *object, php_pqconn_object_t *obj, const char *decl) { ZEND_RESULT_CODE rv; if (!obj) { - obj = zend_object_store_get_object(object TSRMLS_CC); + obj = PHP_PQ_OBJ(object, NULL); } if (!PQsendQuery(obj->intern->conn, decl)) { rv = FAILURE; - throw_exce(EX_IO TSRMLS_CC, "Failed to declare cursor (%s)", PHP_PQerrorMessage(obj->intern->conn)); + throw_exce(EX_IO, "Failed to declare cursor (%s)", PHP_PQerrorMessage(obj->intern->conn)); } else { rv = SUCCESS; obj->intern->poller = PQconsumeInput; - php_pqconn_notify_listeners(obj TSRMLS_CC); + php_pqconn_notify_listeners(obj); } return rv; @@ -1441,30 +1435,29 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(pqconn, declareAsync) { zend_error_handling zeh; char *name_str, *query_str; - int name_len, query_len; - long flags; + size_t name_len, query_len; + zend_long flags; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sls", &name_str, &name_len, &flags, &query_str, &query_len); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "sls", &name_str, &name_len, &flags, &query_str, &query_len); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized"); } else { int query_offset; char *decl = php_pqcur_declare_str(name_str, name_len, flags, query_str, query_len, &query_offset); - if (SUCCESS != php_pqconn_declare_async(getThis(), obj, decl TSRMLS_CC)) { + if (SUCCESS != php_pqconn_declare_async(getThis(), obj, decl)) { efree(decl); } else { - php_pqcur_t *cur = php_pqcur_init(obj, name_str, decl, query_offset, flags TSRMLS_CC); + php_pqcur_t *cur = php_pqcur_init(obj, name_str, decl, query_offset, flags); - return_value->type = IS_OBJECT; - return_value->value.obj = php_pqcur_create_object_ex(php_pqcur_class_entry, cur, NULL TSRMLS_CC); + RETVAL_OBJ(&php_pqcur_create_object_ex(php_pqcur_class_entry, cur)->zo); } } } @@ -1475,21 +1468,21 @@ ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_quote, 0, 0, 1) ZEND_END_ARG_INFO(); static PHP_METHOD(pqconn, quote) { char *str; - int len; + size_t len; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &len)) { - php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "s", &str, &len)) { + php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized"); } else { char *quoted = PQescapeLiteral(obj->intern->conn, str, len); if (!quoted) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to quote string (%s)", PHP_PQerrorMessage(obj->intern->conn)); + php_error_docref(NULL, E_WARNING, "Failed to quote string (%s)", PHP_PQerrorMessage(obj->intern->conn)); RETVAL_FALSE; } else { - RETVAL_STRING(quoted, 1); + RETVAL_STRING(quoted); PQfreemem(quoted); } } @@ -1501,21 +1494,21 @@ ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_quote_name, 0, 0, 1) ZEND_END_ARG_INFO(); static PHP_METHOD(pqconn, quoteName) { char *str; - int len; + size_t len; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &len)) { - php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "s", &str, &len)) { + php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized"); } else { char *quoted = PQescapeIdentifier(obj->intern->conn, str, len); if (!quoted) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to quote name (%s)", PHP_PQerrorMessage(obj->intern->conn)); + php_error_docref(NULL, E_WARNING, "Failed to quote name (%s)", PHP_PQerrorMessage(obj->intern->conn)); RETVAL_FALSE; } else { - RETVAL_STRING(quoted, 1); + RETVAL_STRING(quoted); PQfreemem(quoted); } } @@ -1529,20 +1522,20 @@ static PHP_METHOD(pqconn, escapeBytea) { char *str; int len; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &len)) { - php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "s", &str, &len)) { + php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized"); } else { size_t escaped_len; char *escaped_str = (char *) PQescapeByteaConn(obj->intern->conn, (unsigned char *) str, len, &escaped_len); if (!escaped_str) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to escape bytea (%s)", PHP_PQerrorMessage(obj->intern->conn)); + php_error_docref(NULL, E_WARNING, "Failed to escape bytea (%s)", PHP_PQerrorMessage(obj->intern->conn)); RETVAL_FALSE; } else { - RETVAL_STRINGL(escaped_str, escaped_len - 1, 1); + RETVAL_STRINGL(escaped_str, escaped_len - 1); PQfreemem(escaped_str); } } @@ -1554,34 +1547,34 @@ ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_unescape_bytea, 0, 0, 1) ZEND_END_ARG_INFO(); static PHP_METHOD(pqconn, unescapeBytea) { char *str; - int len; + size_t len; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &len)) { - php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "s", &str, &len)) { + php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized"); } else { size_t unescaped_len; char *unescaped_str = (char *) PQunescapeBytea((unsigned char *)str, &unescaped_len); if (!unescaped_str) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to unescape bytea (%s)", PHP_PQerrorMessage(obj->intern->conn)); + php_error_docref(NULL, E_WARNING, "Failed to unescape bytea (%s)", PHP_PQerrorMessage(obj->intern->conn)); RETVAL_FALSE; } else { - RETVAL_STRINGL(unescaped_str, unescaped_len, 1); + RETVAL_STRINGL(unescaped_str, unescaped_len); PQfreemem(unescaped_str); } } } } -ZEND_RESULT_CODE php_pqconn_start_transaction(zval *zconn, php_pqconn_object_t *conn_obj, long isolation, zend_bool readonly, zend_bool deferrable TSRMLS_DC) +ZEND_RESULT_CODE php_pqconn_start_transaction(zval *zconn, php_pqconn_object_t *conn_obj, long isolation, zend_bool readonly, zend_bool deferrable) { ZEND_RESULT_CODE rv = FAILURE; if (!conn_obj) { - conn_obj = zend_object_store_get_object(zconn TSRMLS_CC); + conn_obj = PHP_PQ_OBJ(zconn, NULL); } if (!conn_obj->intern) { @@ -1600,14 +1593,14 @@ ZEND_RESULT_CODE php_pqconn_start_transaction(zval *zconn, php_pqconn_object_t * smart_str_appends(&cmd, " DEFERRABLE"); smart_str_0(&cmd); - res = PQexec(conn_obj->intern->conn, cmd.c); + res = PQexec(conn_obj->intern->conn, smart_str_v(&cmd)); if (!res) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to start transaction (%s)", PHP_PQerrorMessage(conn_obj->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to start transaction (%s)", PHP_PQerrorMessage(conn_obj->intern->conn)); } else { - rv = php_pqres_success(res TSRMLS_CC); + rv = php_pqres_success(res); PHP_PQclear(res); - php_pqconn_notify_listeners(conn_obj TSRMLS_CC); + php_pqconn_notify_listeners(conn_obj); } smart_str_free(&cmd); @@ -1616,16 +1609,16 @@ ZEND_RESULT_CODE php_pqconn_start_transaction(zval *zconn, php_pqconn_object_t * return rv; } -ZEND_RESULT_CODE php_pqconn_start_transaction_async(zval *zconn, php_pqconn_object_t *conn_obj, long isolation, zend_bool readonly, zend_bool deferrable TSRMLS_DC) +ZEND_RESULT_CODE php_pqconn_start_transaction_async(zval *zconn, php_pqconn_object_t *conn_obj, long isolation, zend_bool readonly, zend_bool deferrable) { ZEND_RESULT_CODE rv = FAILURE; if (!conn_obj) { - conn_obj = zend_object_store_get_object(zconn TSRMLS_CC); + conn_obj = PHP_PQ_OBJ(zconn, NULL); } if (!conn_obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized"); } else { smart_str cmd = {0}; const char *il = php_pq_isolation_level(&isolation); @@ -1639,12 +1632,12 @@ ZEND_RESULT_CODE php_pqconn_start_transaction_async(zval *zconn, php_pqconn_obje smart_str_appends(&cmd, " DEFERRABLE"); smart_str_0(&cmd); - if (!PQsendQuery(conn_obj->intern->conn, cmd.c)) { - throw_exce(EX_IO TSRMLS_CC, "Failed to start transaction (%s)", PHP_PQerrorMessage(conn_obj->intern->conn)); + if (!PQsendQuery(conn_obj->intern->conn, smart_str_v(&cmd))) { + throw_exce(EX_IO, "Failed to start transaction (%s)", PHP_PQerrorMessage(conn_obj->intern->conn)); } else { rv = SUCCESS; conn_obj->intern->poller = PQconsumeInput; - php_pqconn_notify_listeners(conn_obj TSRMLS_CC); + php_pqconn_notify_listeners(conn_obj); } smart_str_free(&cmd); @@ -1660,31 +1653,30 @@ ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_start_transaction, 0, 0, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(pqconn, startTransaction) { zend_error_handling zeh; - php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); - long isolation = obj->intern ? obj->intern->default_txn_isolation : PHP_PQTXN_READ_COMMITTED; + php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); + zend_long isolation = obj->intern ? obj->intern->default_txn_isolation : PHP_PQTXN_READ_COMMITTED; zend_bool readonly = obj->intern ? obj->intern->default_txn_readonly : 0; zend_bool deferrable = obj->intern ? obj->intern->default_txn_deferrable : 0; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|lbb", &isolation, &readonly, &deferrable); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "|lbb", &isolation, &readonly, &deferrable); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - rv = php_pqconn_start_transaction(getThis(), obj, isolation, readonly, deferrable TSRMLS_CC); + rv = php_pqconn_start_transaction(getThis(), obj, isolation, readonly, deferrable); if (SUCCESS == rv) { php_pqtxn_t *txn = ecalloc(1, sizeof(*txn)); - php_pq_object_addref(obj TSRMLS_CC); + php_pq_object_addref(obj); txn->conn = obj; txn->open = 1; txn->isolation = isolation; txn->readonly = readonly; txn->deferrable = deferrable; - return_value->type = IS_OBJECT; - return_value->value.obj = php_pqtxn_create_object_ex(php_pqtxn_class_entry, txn, NULL TSRMLS_CC); + RETVAL_OBJ(&php_pqtxn_create_object_ex(php_pqtxn_class_entry, txn)->zo); } } } @@ -1696,31 +1688,30 @@ ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_start_transaction_async, 0, 0, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(pqconn, startTransactionAsync) { zend_error_handling zeh; - php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); - long isolation = obj->intern ? obj->intern->default_txn_isolation : PHP_PQTXN_READ_COMMITTED; + php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); + zend_long isolation = obj->intern ? obj->intern->default_txn_isolation : PHP_PQTXN_READ_COMMITTED; zend_bool readonly = obj->intern ? obj->intern->default_txn_readonly : 0; zend_bool deferrable = obj->intern ? obj->intern->default_txn_deferrable : 0; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|lbb", &isolation, &readonly, &deferrable); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "|lbb", &isolation, &readonly, &deferrable); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - rv = php_pqconn_start_transaction_async(getThis(), obj, isolation, readonly, deferrable TSRMLS_CC); + rv = php_pqconn_start_transaction_async(getThis(), obj, isolation, readonly, deferrable); if (SUCCESS == rv) { php_pqtxn_t *txn = ecalloc(1, sizeof(*txn)); - php_pq_object_addref(obj TSRMLS_CC); + php_pq_object_addref(obj); txn->conn = obj; txn->open = 1; txn->isolation = isolation; txn->readonly = readonly; txn->deferrable = deferrable; - return_value->type = IS_OBJECT; - return_value->value.obj = php_pqtxn_create_object_ex(php_pqtxn_class_entry, txn, NULL TSRMLS_CC); + RETVAL_OBJ(&php_pqtxn_create_object_ex(php_pqtxn_class_entry, txn)->zo); } } } @@ -1731,11 +1722,11 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(pqconn, trace) { zval *zstream = NULL; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r!", &zstream)) { - php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "|r!", &zstream)) { + php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized"); } else { if (!zstream) { PQuntrace(obj->intern->conn); @@ -1744,7 +1735,7 @@ static PHP_METHOD(pqconn, trace) { FILE *fp; php_stream *stream = NULL; - php_stream_from_zval(stream, &zstream); + php_stream_from_zval(stream, zstream); if (SUCCESS != php_stream_cast(stream, PHP_STREAM_AS_STDIO, (void *) &fp, REPORT_ERRORS)) { RETVAL_FALSE; @@ -1763,21 +1754,20 @@ ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_off, 0, 0, 1) ZEND_END_ARG_INFO(); static PHP_METHOD(pqconn, off) { zend_error_handling zeh; - char *type_str; - int type_len; + zend_string *type; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &type_str, &type_len); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "S", &type); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized"); } else { - RETURN_BOOL(SUCCESS == zend_hash_del(&obj->intern->eventhandlers, type_str, type_len + 1)); + RETURN_BOOL(SUCCESS == zend_hash_del(&obj->intern->eventhandlers, type)); } } } @@ -1789,48 +1779,42 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(pqconn, on) { zend_error_handling zeh; char *type_str; - int type_len; + size_t type_len; php_pq_callback_t cb = {{0}}; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sf", &type_str, &type_len, &cb.fci, &cb.fcc); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "sf", &type_str, &type_len, &cb.fci, &cb.fcc); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized"); } else { - php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); - - RETVAL_LONG(php_pqconn_add_eventhandler(obj, type_str, type_len, &cb TSRMLS_CC)); + RETVAL_LONG(php_pqconn_add_eventhandler(obj, type_str, type_len, &cb)); } } } struct apply_set_converter_arg { HashTable *ht; - zval **zconv; + zval *zconv; unsigned add:1; }; -static int apply_set_converter(void *p, void *a TSRMLS_DC) +static int apply_set_converter(zval *zoid, void *a) { - zval *tmp, **zoid = p; + zend_long oid = zval_get_long(zoid); struct apply_set_converter_arg *arg = a; - tmp = *zoid; - Z_ADDREF_P(tmp); - convert_to_long_ex(&tmp); if (arg->add) { - Z_ADDREF_PP(arg->zconv); - zend_hash_index_update(arg->ht, Z_LVAL_P(tmp), arg->zconv, sizeof(zval *), NULL); + Z_ADDREF_P(arg->zconv); + zend_hash_index_update(arg->ht, oid, arg->zconv); } else { - zend_hash_index_del(arg->ht, Z_LVAL_P(tmp)); + zend_hash_index_del(arg->ht, oid); } - zval_ptr_dtor(&tmp); return ZEND_HASH_APPLY_KEEP; } @@ -1843,29 +1827,29 @@ static PHP_METHOD(pqconn, setConverter) { zend_error_handling zeh; zval *zcnv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &zcnv, php_pqconv_class_entry); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "O", &zcnv, php_pqconv_class_entry); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized"); } else { - zval *tmp, *zoids = NULL; + zval tmp, zoids; struct apply_set_converter_arg arg = {NULL}; - zend_call_method_with_0_params(&zcnv, NULL, NULL, "converttypes", &zoids); - tmp = zoids; - Z_ADDREF_P(tmp); - convert_to_array_ex(&tmp); + ZVAL_NULL(&zoids); + zend_call_method_with_0_params(zcnv, NULL, NULL, "converttypes", &zoids); + ZVAL_DUP(&tmp, &zoids); + convert_to_array(&tmp); arg.ht = &obj->intern->converters; - arg.zconv = &zcnv; + arg.zconv = zcnv; arg.add = 1; - zend_hash_apply_with_argument(Z_ARRVAL_P(tmp), apply_set_converter, &arg TSRMLS_CC); + zend_hash_apply_with_argument(Z_ARRVAL(tmp), apply_set_converter, &arg); zval_ptr_dtor(&tmp); zval_ptr_dtor(&zoids); @@ -1881,29 +1865,29 @@ static PHP_METHOD(pqconn, unsetConverter) { zend_error_handling zeh; zval *zcnv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &zcnv, php_pqconv_class_entry); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "O", &zcnv, php_pqconv_class_entry); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqconn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized"); } else { - zval *tmp, *zoids = NULL; + zval tmp, zoids; struct apply_set_converter_arg arg = {NULL}; - zend_call_method_with_0_params(&zcnv, NULL, NULL, "converttypes", &zoids); - tmp = zoids; - Z_ADDREF_P(tmp); - convert_to_array_ex(&tmp); + ZVAL_NULL(&zoids); + zend_call_method_with_0_params(zcnv, NULL, NULL, "converttypes", &zoids); + ZVAL_DUP(&tmp, &zoids); + convert_to_array(&tmp); arg.ht = &obj->intern->converters; - arg.zconv = &zcnv; + arg.zconv = zcnv; arg.add = 0; - zend_hash_apply_with_argument(Z_ARRVAL_P(tmp), apply_set_converter, &arg TSRMLS_CC); + zend_hash_apply_with_argument(Z_ARRVAL(tmp), apply_set_converter, &arg); zval_ptr_dtor(&tmp); zval_ptr_dtor(&zoids); @@ -1947,6 +1931,8 @@ static zend_function_entry php_pqconn_methods[] = { PHP_MSHUTDOWN_FUNCTION(pqconn) { + php_persistent_handle_cleanup(PHP_PQ_G->connection.name, NULL); + zend_string_release(PHP_PQ_G->connection.name); zend_hash_destroy(&php_pqconn_object_prophandlers); return SUCCESS; } @@ -1957,144 +1943,162 @@ PHP_MINIT_FUNCTION(pqconn) php_pq_object_prophandler_t ph = {0}; INIT_NS_CLASS_ENTRY(ce, "pq", "Connection", php_pqconn_methods); - php_pqconn_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC); + php_pqconn_class_entry = zend_register_internal_class_ex(&ce, NULL); php_pqconn_class_entry->create_object = php_pqconn_create_object; memcpy(&php_pqconn_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + php_pqconn_object_handlers.offset = XtOffsetOf(php_pqconn_object_t, zo); + php_pqconn_object_handlers.free_obj = php_pqconn_object_free; php_pqconn_object_handlers.read_property = php_pq_object_read_prop; php_pqconn_object_handlers.write_property = php_pq_object_write_prop; php_pqconn_object_handlers.clone_obj = NULL; php_pqconn_object_handlers.get_property_ptr_ptr = NULL; - php_pqconn_object_handlers.get_gc = NULL; + php_pqconn_object_handlers.get_gc = php_pq_object_get_gc; php_pqconn_object_handlers.get_properties = php_pq_object_properties; php_pqconn_object_handlers.get_debug_info = php_pq_object_debug_info; - zend_hash_init(&php_pqconn_object_prophandlers, 20, NULL, NULL, 1); + zend_hash_init(&php_pqconn_object_prophandlers, 22, NULL, php_pq_object_prophandler_dtor, 1); - zend_declare_property_long(php_pqconn_class_entry, ZEND_STRL("status"), CONNECTION_BAD, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(php_pqconn_class_entry, ZEND_STRL("status"), CONNECTION_BAD, ZEND_ACC_PUBLIC); ph.read = php_pqconn_object_read_status; - zend_hash_add(&php_pqconn_object_prophandlers, "status", sizeof("status"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "status", sizeof("status")-1, (void *) &ph, sizeof(ph)); - zend_declare_property_long(php_pqconn_class_entry, ZEND_STRL("transactionStatus"), PQTRANS_UNKNOWN, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(php_pqconn_class_entry, ZEND_STRL("transactionStatus"), PQTRANS_UNKNOWN, ZEND_ACC_PUBLIC); ph.read = php_pqconn_object_read_transaction_status; - zend_hash_add(&php_pqconn_object_prophandlers, "transactionStatus", sizeof("transactionStatus"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "transactionStatus", sizeof("transactionStatus")-1, (void *) &ph, sizeof(ph)); - zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("socket"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("socket"), ZEND_ACC_PUBLIC); ph.read = NULL; /* forward to std prophandler */ - zend_hash_add(&php_pqconn_object_prophandlers, "socket", sizeof("socket"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "socket", sizeof("socket")-1, (void *) &ph, sizeof(ph)); - zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("errorMessage"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("errorMessage"), ZEND_ACC_PUBLIC); ph.read = php_pqconn_object_read_error_message; - zend_hash_add(&php_pqconn_object_prophandlers, "errorMessage", sizeof("errorMessage"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "errorMessage", sizeof("errorMessage")-1, (void *) &ph, sizeof(ph)); - zend_declare_property_bool(php_pqconn_class_entry, ZEND_STRL("busy"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_bool(php_pqconn_class_entry, ZEND_STRL("busy"), 0, ZEND_ACC_PUBLIC); ph.read = php_pqconn_object_read_busy; - zend_hash_add(&php_pqconn_object_prophandlers, "busy", sizeof("busy"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "busy", sizeof("busy")-1, (void *) &ph, sizeof(ph)); - zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("encoding"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("encoding"), ZEND_ACC_PUBLIC); ph.read = php_pqconn_object_read_encoding; ph.write = php_pqconn_object_write_encoding; - zend_hash_add(&php_pqconn_object_prophandlers, "encoding", sizeof("encoding"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "encoding", sizeof("encoding")-1, (void *) &ph, sizeof(ph)); ph.write = NULL; - zend_declare_property_bool(php_pqconn_class_entry, ZEND_STRL("unbuffered"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_bool(php_pqconn_class_entry, ZEND_STRL("unbuffered"), 0, ZEND_ACC_PUBLIC); ph.read = php_pqconn_object_read_unbuffered; ph.write = php_pqconn_object_write_unbuffered; - zend_hash_add(&php_pqconn_object_prophandlers, "unbuffered", sizeof("unbuffered"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "unbuffered", sizeof("unbuffered")-1, (void *) &ph, sizeof(ph)); ph.write = NULL; - zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("db"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("db"), ZEND_ACC_PUBLIC); ph.read = php_pqconn_object_read_db; - zend_hash_add(&php_pqconn_object_prophandlers, "db", sizeof("db"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "db", sizeof("db")-1, (void *) &ph, sizeof(ph)); - zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("user"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("user"), ZEND_ACC_PUBLIC); ph.read = php_pqconn_object_read_user; - zend_hash_add(&php_pqconn_object_prophandlers, "user", sizeof("user"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "user", sizeof("user")-1, (void *) &ph, sizeof(ph)); - zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("pass"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("pass"), ZEND_ACC_PUBLIC); ph.read = php_pqconn_object_read_pass; - zend_hash_add(&php_pqconn_object_prophandlers, "pass", sizeof("pass"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "pass", sizeof("pass")-1, (void *) &ph, sizeof(ph)); - zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("host"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("host"), ZEND_ACC_PUBLIC); ph.read = php_pqconn_object_read_host; - zend_hash_add(&php_pqconn_object_prophandlers, "host", sizeof("host"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "host", sizeof("host")-1, (void *) &ph, sizeof(ph)); - zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("port"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("port"), ZEND_ACC_PUBLIC); ph.read = php_pqconn_object_read_port; - zend_hash_add(&php_pqconn_object_prophandlers, "port", sizeof("port"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "port", sizeof("port")-1, (void *) &ph, sizeof(ph)); #if HAVE_PQCONNINFO - zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("params"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("params"), ZEND_ACC_PUBLIC); ph.read = php_pqconn_object_read_params; - zend_hash_add(&php_pqconn_object_prophandlers, "params", sizeof("params"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "params", sizeof("params")-1, (void *) &ph, sizeof(ph)); #endif - zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("options"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("options"), ZEND_ACC_PUBLIC); ph.read = php_pqconn_object_read_options; - zend_hash_add(&php_pqconn_object_prophandlers, "options", sizeof("options"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "options", sizeof("options")-1, (void *) &ph, sizeof(ph)); - zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("eventHandlers"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("eventHandlers"), ZEND_ACC_PUBLIC); ph.read = php_pqconn_object_read_event_handlers; - zend_hash_add(&php_pqconn_object_prophandlers, "eventHandlers", sizeof("eventHandlers"), (void *) &ph, sizeof(ph), NULL); - - zend_declare_property_long(php_pqconn_class_entry, ZEND_STRL("defaultFetchType"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); + ph.gc = php_pqconn_object_gc_event_handlers; + zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "eventHandlers", sizeof("eventHandlers")-1, (void *) &ph, sizeof(ph)); + ph.gc = NULL; + + zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("listeners"), ZEND_ACC_PUBLIC); + ph.read = php_pqconn_object_read_listeners; + ph.gc = php_pqconn_object_gc_listeners; + zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "listeners", sizeof("listeners")-1, (void *) &ph, sizeof(ph)); + ph.gc = NULL; + + zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("converters"), ZEND_ACC_PUBLIC); + ph.read = php_pqconn_object_read_converters; + ph.gc = php_pqconn_object_gc_converters; + zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "converters", sizeof("converters")-1, (void *) &ph, sizeof(ph)); + ph.gc = NULL; + + zend_declare_property_long(php_pqconn_class_entry, ZEND_STRL("defaultFetchType"), 0, ZEND_ACC_PUBLIC); ph.read = php_pqconn_object_read_def_fetch_type; ph.write = php_pqconn_object_write_def_fetch_type; - zend_hash_add(&php_pqconn_object_prophandlers, "defaultFetchType", sizeof("defaultFetchType"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "defaultFetchType", sizeof("defaultFetchType")-1, (void *) &ph, sizeof(ph)); ph.write = NULL; - zend_declare_property_long(php_pqconn_class_entry, ZEND_STRL("defaultTransactionIsolation"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(php_pqconn_class_entry, ZEND_STRL("defaultTransactionIsolation"), 0, ZEND_ACC_PUBLIC); ph.read = php_pqconn_object_read_def_txn_isolation; ph.write = php_pqconn_object_write_def_txn_isolation; - zend_hash_add(&php_pqconn_object_prophandlers, "defaultTransactionIsolation", sizeof("defaultTransactionIsolation"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "defaultTransactionIsolation", sizeof("defaultTransactionIsolation")-1, (void *) &ph, sizeof(ph)); ph.write = NULL; - zend_declare_property_bool(php_pqconn_class_entry, ZEND_STRL("defaultTransactionReadonly"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_bool(php_pqconn_class_entry, ZEND_STRL("defaultTransactionReadonly"), 0, ZEND_ACC_PUBLIC); ph.read = php_pqconn_object_read_def_txn_readonly; ph.write = php_pqconn_object_write_def_txn_readonly; - zend_hash_add(&php_pqconn_object_prophandlers, "defaultTransactionReadonly", sizeof("defaultTransactionReadonly"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "defaultTransactionReadonly", sizeof("defaultTransactionReadonly")-1, (void *) &ph, sizeof(ph)); ph.write = NULL; zend_declare_property_bool(php_pqconn_class_entry, ZEND_STRL("defaultTransactionDeferrable"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); ph.read = php_pqconn_object_read_def_txn_deferrable; ph.write = php_pqconn_object_write_def_txn_deferrable; - zend_hash_add(&php_pqconn_object_prophandlers, "defaultTransactionDeferrable", sizeof("defaultTransactionDeferrable"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "defaultTransactionDeferrable", sizeof("defaultTransactionDeferrable")-1, (void *) &ph, sizeof(ph)); ph.write = NULL; - zend_declare_property_long(php_pqconn_class_entry, ZEND_STRL("defaultAutoConvert"), PHP_PQRES_CONV_ALL, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(php_pqconn_class_entry, ZEND_STRL("defaultAutoConvert"), PHP_PQRES_CONV_ALL, ZEND_ACC_PUBLIC); ph.read = php_pqconn_object_read_def_auto_conv; ph.write = php_pqconn_object_write_def_auto_conv; - zend_hash_add(&php_pqconn_object_prophandlers, "defaultAutoConvert", sizeof("defaultAutoConvert"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqconn_object_prophandlers, "defaultAutoConvert", sizeof("defaultAutoConvert")-1, (void *) &ph, sizeof(ph)); ph.write = NULL; - zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("OK"), CONNECTION_OK TSRMLS_CC); - zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("BAD"), CONNECTION_BAD TSRMLS_CC); - zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("STARTED"), CONNECTION_STARTED TSRMLS_CC); - zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("MADE"), CONNECTION_MADE TSRMLS_CC); - zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("AWAITING_RESPONSE"), CONNECTION_AWAITING_RESPONSE TSRMLS_CC); - zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("AUTH_OK"), CONNECTION_AUTH_OK TSRMLS_CC); - zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("SSL_STARTUP"), CONNECTION_SSL_STARTUP TSRMLS_CC); - zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("SETENV"), CONNECTION_SETENV TSRMLS_CC); - - zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("TRANS_IDLE"), PQTRANS_IDLE TSRMLS_CC); - zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("TRANS_ACTIVE"), PQTRANS_ACTIVE TSRMLS_CC); - zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("TRANS_INTRANS"), PQTRANS_INTRANS TSRMLS_CC); - zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("TRANS_INERROR"), PQTRANS_INERROR TSRMLS_CC); - zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("TRANS_UNKNOWN"), PQTRANS_UNKNOWN TSRMLS_CC); - - zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("POLLING_FAILED"), PGRES_POLLING_FAILED TSRMLS_CC); - zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("POLLING_READING"), PGRES_POLLING_READING TSRMLS_CC); - zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("POLLING_WRITING"), PGRES_POLLING_WRITING TSRMLS_CC); - zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("POLLING_OK"), PGRES_POLLING_OK TSRMLS_CC); - - zend_declare_class_constant_stringl(php_pqconn_class_entry, ZEND_STRL("EVENT_NOTICE"), ZEND_STRL("notice") TSRMLS_CC); - zend_declare_class_constant_stringl(php_pqconn_class_entry, ZEND_STRL("EVENT_RESULT"), ZEND_STRL("result") TSRMLS_CC); - zend_declare_class_constant_stringl(php_pqconn_class_entry, ZEND_STRL("EVENT_RESET"), ZEND_STRL("reset") TSRMLS_CC); - - zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("ASYNC"), 0x1 TSRMLS_CC); - zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("PERSISTENT"), 0x2 TSRMLS_CC); + zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("OK"), CONNECTION_OK); + zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("BAD"), CONNECTION_BAD); + zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("STARTED"), CONNECTION_STARTED); + zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("MADE"), CONNECTION_MADE); + zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("AWAITING_RESPONSE"), CONNECTION_AWAITING_RESPONSE); + zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("AUTH_OK"), CONNECTION_AUTH_OK); + zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("SSL_STARTUP"), CONNECTION_SSL_STARTUP); + zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("SETENV"), CONNECTION_SETENV); - return SUCCESS; + zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("TRANS_IDLE"), PQTRANS_IDLE); + zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("TRANS_ACTIVE"), PQTRANS_ACTIVE); + zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("TRANS_INTRANS"), PQTRANS_INTRANS); + zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("TRANS_INERROR"), PQTRANS_INERROR); + zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("TRANS_UNKNOWN"), PQTRANS_UNKNOWN); + + zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("POLLING_FAILED"), PGRES_POLLING_FAILED); + zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("POLLING_READING"), PGRES_POLLING_READING); + zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("POLLING_WRITING"), PGRES_POLLING_WRITING); + zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("POLLING_OK"), PGRES_POLLING_OK); + + zend_declare_class_constant_stringl(php_pqconn_class_entry, ZEND_STRL("EVENT_NOTICE"), ZEND_STRL("notice")); + zend_declare_class_constant_stringl(php_pqconn_class_entry, ZEND_STRL("EVENT_RESULT"), ZEND_STRL("result")); + zend_declare_class_constant_stringl(php_pqconn_class_entry, ZEND_STRL("EVENT_RESET"), ZEND_STRL("reset")); + + zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("ASYNC"), 0x1); + zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("PERSISTENT"), 0x2); + + PHP_PQ_G->connection.name = zend_string_init(ZEND_STRL("pq\\Connection"), 1); + + return php_persistent_handle_provide(PHP_PQ_G->connection.name, php_pqconn_get_resource_factory_ops(), NULL, NULL); } /* diff --git a/src/php_pqconn.h b/src/php_pqconn.h index 03ad9c8..65c1278 100644 --- a/src/php_pqconn.h +++ b/src/php_pqconn.h @@ -18,6 +18,7 @@ #define PHP_PQCONN_PERSISTENT 0x02 #include +#include "php_pq_object.h" #include "php_pq_callback.h" #include "php_pq_params.h" @@ -38,28 +39,25 @@ typedef struct php_pqconn { } php_pqconn_t; typedef struct php_pqconn_object { - zend_object zo; - zend_object_value zv; - HashTable *prophandler; - php_pqconn_t *intern; + PHP_PQ_OBJ_DECL(php_pqconn_t *) } php_pqconn_object_t; typedef struct php_pqconn_resource_factory_data { char *dsn; - long flags; + ulong flags; } php_pqconn_resource_factory_data_t; extern php_resource_factory_ops_t *php_pqconn_get_resource_factory_ops(void); extern zend_class_entry *php_pqconn_class_entry; -extern zend_object_value php_pqconn_create_object_ex(zend_class_entry *ce, php_pqconn_t *intern, php_pqconn_object_t **ptr TSRMLS_DC); -extern void php_pqconn_notify_listeners(php_pqconn_object_t *obj TSRMLS_DC); -extern ZEND_RESULT_CODE php_pqconn_prepare(zval *object, php_pqconn_object_t *obj, const char *name, const char *query, php_pq_params_t *params TSRMLS_DC); -extern ZEND_RESULT_CODE php_pqconn_prepare_async(zval *object, php_pqconn_object_t *obj, const char *name, const char *query, php_pq_params_t *params TSRMLS_DC); -extern ZEND_RESULT_CODE php_pqconn_start_transaction(zval *zconn, php_pqconn_object_t *conn_obj, long isolation, zend_bool readonly, zend_bool deferrable TSRMLS_DC); -extern ZEND_RESULT_CODE php_pqconn_start_transaction_async(zval *zconn, php_pqconn_object_t *conn_obj, long isolation, zend_bool readonly, zend_bool deferrable TSRMLS_DC); -extern ZEND_RESULT_CODE php_pqconn_declare(zval *object, php_pqconn_object_t *obj, const char *decl TSRMLS_DC); -extern ZEND_RESULT_CODE php_pqconn_declare_async(zval *object, php_pqconn_object_t *obj, const char *decl TSRMLS_DC); +extern php_pqconn_object_t *php_pqconn_create_object_ex(zend_class_entry *ce, php_pqconn_t *intern); +extern void php_pqconn_notify_listeners(php_pqconn_object_t *obj); +extern ZEND_RESULT_CODE php_pqconn_prepare(zval *object, php_pqconn_object_t *obj, const char *name, const char *query, php_pq_params_t *params); +extern ZEND_RESULT_CODE php_pqconn_prepare_async(zval *object, php_pqconn_object_t *obj, const char *name, const char *query, php_pq_params_t *params); +extern ZEND_RESULT_CODE php_pqconn_start_transaction(zval *zconn, php_pqconn_object_t *conn_obj, long isolation, zend_bool readonly, zend_bool deferrable); +extern ZEND_RESULT_CODE php_pqconn_start_transaction_async(zval *zconn, php_pqconn_object_t *conn_obj, long isolation, zend_bool readonly, zend_bool deferrable); +extern ZEND_RESULT_CODE php_pqconn_declare(zval *object, php_pqconn_object_t *obj, const char *decl); +extern ZEND_RESULT_CODE php_pqconn_declare_async(zval *object, php_pqconn_object_t *obj, const char *decl); extern PHP_MINIT_FUNCTION(pqconn); extern PHP_MSHUTDOWN_FUNCTION(pqconn); diff --git a/src/php_pqconn_event.c b/src/php_pqconn_event.c index f509c57..2b94dee 100644 --- a/src/php_pqconn_event.c +++ b/src/php_pqconn_event.c @@ -24,17 +24,17 @@ #include "php_pqconn_event.h" #include "php_pqres.h" -static int apply_event(void *p, void *a TSRMLS_DC) +static int apply_event(zval *p, void *a) { - php_pq_callback_t *cb = p; + php_pq_callback_t *cb = Z_PTR_P(p); zval *args = a; - zval *retval = NULL; + zval rv; - zend_fcall_info_args(&cb->fci, args TSRMLS_CC); - zend_fcall_info_call(&cb->fci, &cb->fcc, &retval, NULL TSRMLS_CC); - if (retval) { - zval_ptr_dtor(&retval); - } + ZVAL_NULL(&rv); + zend_fcall_info_args(&cb->fci, args); + zend_fcall_info_call(&cb->fci, &cb->fcc, &rv, NULL); + zend_fcall_info_args_clear(&cb->fci, 0); + zval_ptr_dtor(&rv); return ZEND_HASH_APPLY_KEEP; } @@ -44,17 +44,15 @@ static void php_pqconn_event_connreset(PGEventConnReset *event) php_pqconn_event_data_t *data = PQinstanceData(event->conn, php_pqconn_event); if (data) { - HashTable *evhs; - TSRMLS_DF(data); + zval *zevhs; - if (SUCCESS == zend_hash_find(&data->obj->intern->eventhandlers, ZEND_STRS("reset"), (void *) &evhs)) { - zval *args, *connection = NULL; + if ((zevhs = zend_hash_str_find(&data->obj->intern->eventhandlers, ZEND_STRL("reset")))) { + zval args, connection; - MAKE_STD_ZVAL(args); - array_init(args); - php_pq_object_to_zval(data->obj, &connection TSRMLS_CC); - add_next_index_zval(args, connection); - zend_hash_apply_with_argument(evhs, apply_event, args TSRMLS_CC); + array_init(&args); + php_pq_object_to_zval(data->obj, &connection); + add_next_index_zval(&args, &connection); + zend_hash_apply_with_argument(Z_ARRVAL_P(zevhs), apply_event, &args); zval_ptr_dtor(&args); } } @@ -65,33 +63,29 @@ static void php_pqconn_event_resultcreate(PGEventResultCreate *event) php_pqconn_event_data_t *data = PQinstanceData(event->conn, php_pqconn_event); if (data) { - php_pqres_object_t *obj; - HashTable *evhs; - TSRMLS_DF(data); - - php_pqres_init_instance_data(event->result, data->obj, &obj TSRMLS_CC); + php_pqres_object_t *obj = php_pqres_init_instance_data(event->result, data->obj); + zval *zevhs; /* event listener */ - if (SUCCESS == zend_hash_find(&data->obj->intern->eventhandlers, ZEND_STRS("result"), (void *) &evhs)) { - zval *args, *connection = NULL, *res = NULL; - - MAKE_STD_ZVAL(args); - array_init(args); - php_pq_object_to_zval(data->obj, &connection TSRMLS_CC); - add_next_index_zval(args, connection); - php_pq_object_to_zval(obj, &res TSRMLS_CC); - add_next_index_zval(args, res); - zend_hash_apply_with_argument(evhs, apply_event, args TSRMLS_CC); + if ((zevhs = zend_hash_str_find(&data->obj->intern->eventhandlers, ZEND_STRL("result")))) { + zval args, connection, res; + + array_init(&args); + php_pq_object_to_zval(data->obj, &connection); + add_next_index_zval(&args, &connection); + php_pq_object_to_zval(obj, &res); + add_next_index_zval(&args, &res); + zend_hash_apply_with_argument(Z_ARRVAL_P(zevhs), apply_event, &args); zval_ptr_dtor(&args); } /* async callback */ if (data->obj->intern->onevent.fci.size > 0) { - zval *res = NULL; + zval res; - php_pq_object_to_zval(obj, &res TSRMLS_CC); - zend_fcall_info_argn(&data->obj->intern->onevent.fci TSRMLS_CC, 1, &res); - zend_fcall_info_call(&data->obj->intern->onevent.fci, &data->obj->intern->onevent.fcc, NULL, NULL TSRMLS_CC); + php_pq_object_to_zval(obj, &res); + zend_fcall_info_argn(&data->obj->intern->onevent.fci, 1, &res); + zend_fcall_info_call(&data->obj->intern->onevent.fci, &data->obj->intern->onevent.fcc, NULL, NULL); zval_ptr_dtor(&res); } @@ -104,6 +98,8 @@ static void php_pqconn_event_resultdestroy(PGEventResultDestroy *event) if (obj) { obj->intern->res = NULL; + assert(GC_REFCOUNT(&obj->zo)); + php_pq_object_delref(obj); } } @@ -126,12 +122,12 @@ int php_pqconn_event(PGEventId id, void *e, void *data) return 1; } -php_pqconn_event_data_t *php_pqconn_event_data_init(php_pqconn_object_t *obj TSRMLS_DC) +php_pqconn_event_data_t *php_pqconn_event_data_init(php_pqconn_object_t *obj) { php_pqconn_event_data_t *data = emalloc(sizeof(*data)); data->obj = obj; - TSRMLS_CF(data); + data->res = NULL; return data; } @@ -141,18 +137,16 @@ void php_pqconn_notice_recv(void *p, const PGresult *res) php_pqconn_event_data_t *data = p; if (data) { - HashTable *evhs; - TSRMLS_DF(data); - - if (SUCCESS == zend_hash_find(&data->obj->intern->eventhandlers, ZEND_STRS("notice"), (void *) &evhs)) { - zval *args, *connection = NULL; - - MAKE_STD_ZVAL(args); - array_init(args); - php_pq_object_to_zval(data->obj, &connection TSRMLS_CC); - add_next_index_zval(args, connection); - add_next_index_string(args, PHP_PQresultErrorMessage(res), 1); - zend_hash_apply_with_argument(evhs, apply_event, args TSRMLS_CC); + zval *zevhs; + + if ((zevhs = zend_hash_str_find(&data->obj->intern->eventhandlers, ZEND_STRL("notice")))) { + zval args, connection; + + array_init(&args); + php_pq_object_to_zval(data->obj, &connection); + add_next_index_zval(&args, &connection); + add_next_index_string(&args, PHP_PQresultErrorMessage(res)); + zend_hash_apply_with_argument(Z_ARRVAL_P(zevhs), apply_event, &args); zval_ptr_dtor(&args); } } diff --git a/src/php_pqconn_event.h b/src/php_pqconn_event.h index df4afca..b7513a6 100644 --- a/src/php_pqconn_event.h +++ b/src/php_pqconn_event.h @@ -17,15 +17,14 @@ #include #include "php_pqconn.h" +#include "php_pqres.h" typedef struct php_pqconn_event_data { php_pqconn_object_t *obj; -#ifdef ZTS - void ***ts; -#endif + php_pqres_object_t *res; } php_pqconn_event_data_t; -extern php_pqconn_event_data_t *php_pqconn_event_data_init(php_pqconn_object_t *obj TSRMLS_DC); +extern php_pqconn_event_data_t *php_pqconn_event_data_init(php_pqconn_object_t *obj); extern void php_pqconn_notice_recv(void *p, const PGresult *res); extern void php_pqconn_notice_ignore(void *p, const PGresult *res); extern int php_pqconn_event(PGEventId id, void *e, void *data); diff --git a/src/php_pqcopy.c b/src/php_pqcopy.c index 32e20ba..2413268 100644 --- a/src/php_pqcopy.c +++ b/src/php_pqcopy.c @@ -15,7 +15,7 @@ #endif #include -#include +#include #include @@ -31,77 +31,68 @@ zend_class_entry *php_pqcopy_class_entry; static zend_object_handlers php_pqcopy_object_handlers; static HashTable php_pqcopy_object_prophandlers; -static void php_pqcopy_object_free(void *o TSRMLS_DC) +static void php_pqcopy_object_free(zend_object *o) { - php_pqcopy_object_t *obj = o; + php_pqcopy_object_t *obj = PHP_PQ_OBJ(NULL, o); #if DBG_GC - fprintf(stderr, "FREE copy(#%d) %p (conn(#%d): %p)\n", obj->zv.handle, obj, obj->intern->conn->zv.handle, obj->intern->conn); + fprintf(stderr, "FREE copy(#%d) %p (conn(#%d): %p)\n", obj->zo.handle, obj, obj->intern->conn->zo.handle, obj->intern->conn); #endif if (obj->intern) { efree(obj->intern->expression); efree(obj->intern->options); - php_pq_object_delref(obj->intern->conn TSRMLS_CC); + php_pq_object_delref(obj->intern->conn); efree(obj->intern); obj->intern = NULL; } - zend_object_std_dtor((zend_object *) o TSRMLS_CC); - efree(obj); + php_pq_object_dtor(o); } -zend_object_value php_pqcopy_create_object_ex(zend_class_entry *ce, php_pqcopy_t *intern, php_pqcopy_object_t **ptr TSRMLS_DC) +php_pqcopy_object_t *php_pqcopy_create_object_ex(zend_class_entry *ce, php_pqcopy_t *intern) { - php_pqcopy_object_t *o; - - o = ecalloc(1, sizeof(*o)); - zend_object_std_init((zend_object *) o, ce TSRMLS_CC); - object_properties_init((zend_object *) o, ce); - o->prophandler = &php_pqcopy_object_prophandlers; - - if (ptr) { - *ptr = o; - } - - if (intern) { - o->intern = intern; - } - - o->zv.handle = zend_objects_store_put((zend_object *) o, NULL, php_pqcopy_object_free, NULL TSRMLS_CC); - o->zv.handlers = &php_pqcopy_object_handlers; + return php_pq_object_create(ce, intern, sizeof(php_pqcopy_object_t), + &php_pqcopy_object_handlers, &php_pqcopy_object_prophandlers); +} - return o->zv; +static zend_object *php_pqcopy_create_object(zend_class_entry *class_type) +{ + return &php_pqcopy_create_object_ex(class_type, NULL)->zo; } -static zend_object_value php_pqcopy_create_object(zend_class_entry *class_type TSRMLS_DC) +static void php_pqcopy_object_read_connection(zval *object, void *o, zval *return_value) { - return php_pqcopy_create_object_ex(class_type, NULL, NULL TSRMLS_CC); + php_pqcopy_object_t *obj = o; + + php_pq_object_to_zval(obj->intern->conn, return_value); } -static void php_pqcopy_object_read_connection(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqcopy_object_gc_connection(zval *object, void *o, zval *return_value) { php_pqcopy_object_t *obj = o; + zval zconn; - php_pq_object_to_zval(obj->intern->conn, &return_value TSRMLS_CC); + php_pq_object_to_zval_no_addref(obj->intern->conn, &zconn); + add_next_index_zval(return_value, &zconn); } -static void php_pqcopy_object_read_direction(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqcopy_object_read_direction(zval *object, void *o, zval *return_value) { php_pqcopy_object_t *obj = o; RETVAL_LONG(obj->intern->direction); } -static void php_pqcopy_object_read_expression(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqcopy_object_read_expression(zval *object, void *o, zval *return_value) { php_pqcopy_object_t *obj = o; - RETURN_STRING(obj->intern->expression, 1); + RETURN_STRING(obj->intern->expression); } -static void php_pqcopy_object_read_options(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqcopy_object_read_options(zval *object, void *o, zval *return_value) { php_pqcopy_object_t *obj = o; - RETURN_STRING(obj->intern->options, 1); + RETURN_STRING(obj->intern->options); } ZEND_BEGIN_ARG_INFO_EX(ai_pqcopy_construct, 0, 0, 3) @@ -114,21 +105,21 @@ static PHP_METHOD(pqcopy, __construct) { zend_error_handling zeh; zval *zconn; char *expr_str, *opt_str = ""; - int expr_len, opt_len = 0; - long direction; + size_t expr_len, opt_len = 0; + zend_long direction; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Osl|s", &zconn, php_pqconn_class_entry, &expr_str, &expr_len, &direction, &opt_str, &opt_len); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "Osl|s", &zconn, php_pqconn_class_entry, &expr_str, &expr_len, &direction, &opt_str, &opt_len); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqconn_object_t *conn_obj = zend_object_store_get_object(zconn TSRMLS_CC); + php_pqconn_object_t *conn_obj = PHP_PQ_OBJ(zconn, NULL); if (!conn_obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized"); } else { - php_pqcopy_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqcopy_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); smart_str cmd = {0}; PGresult *res; @@ -143,32 +134,32 @@ static PHP_METHOD(pqcopy, __construct) { smart_str_appends(&cmd, " TO STDOUT "); break; default: - throw_exce(EX_RUNTIME TSRMLS_CC, "Invalid COPY direction, expected one of FROM_STDIN (%d) TO_STDOUT (%d), got %ld", PHP_PQCOPY_FROM_STDIN, PHP_PQCOPY_TO_STDOUT, direction); + throw_exce(EX_RUNTIME, "Invalid COPY direction, expected one of FROM_STDIN (%d) TO_STDOUT (%d), got %ld", PHP_PQCOPY_FROM_STDIN, PHP_PQCOPY_TO_STDOUT, direction); smart_str_free(&cmd); return; } smart_str_appendl(&cmd, opt_str, opt_len); smart_str_0(&cmd); - res = PQexec(conn_obj->intern->conn, cmd.c); + res = PQexec(conn_obj->intern->conn, smart_str_v(&cmd)); if (!res) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to start %s (%s)", cmd.c, PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to start %s (%s)", smart_str_v(&cmd), PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { - if (SUCCESS == php_pqres_success(res TSRMLS_CC)) { + if (SUCCESS == php_pqres_success(res)) { obj->intern = ecalloc(1, sizeof(*obj->intern)); obj->intern->direction = direction; obj->intern->expression = estrdup(expr_str); obj->intern->options = estrdup(opt_str); obj->intern->conn = conn_obj; - php_pq_object_addref(conn_obj TSRMLS_CC); + php_pq_object_addref(conn_obj); } PHP_PQclear(res); } smart_str_free(&cmd); - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->conn); } } } @@ -179,25 +170,25 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(pqcopy, put) { zend_error_handling zeh; char *data_str; - int data_len; + size_t data_len; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &data_str, &data_len); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "s", &data_str, &data_len); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqcopy_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqcopy_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\COPY not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\COPY not initialized"); } else if (obj->intern->direction != PHP_PQCOPY_FROM_STDIN) { - throw_exce(EX_BAD_METHODCALL TSRMLS_CC, "pq\\COPY was not initialized with FROM_STDIN"); + throw_exce(EX_BAD_METHODCALL, "pq\\COPY was not initialized with FROM_STDIN"); } else { if (1 != PQputCopyData(obj->intern->conn->intern->conn, data_str, data_len)) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to put COPY data (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to put COPY data (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->conn); } } } @@ -208,35 +199,35 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(pqcopy, end) { zend_error_handling zeh; char *error_str = NULL; - int error_len = 0; + size_t error_len = 0; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!", &error_str, &error_len); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "|s!", &error_str, &error_len); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqcopy_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqcopy_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\COPY not intitialized"); + throw_exce(EX_UNINITIALIZED, "pq\\COPY not intitialized"); } else if (obj->intern->direction != PHP_PQCOPY_FROM_STDIN) { - throw_exce(EX_BAD_METHODCALL TSRMLS_CC, "pq\\COPY was not intitialized with FROM_STDIN"); + throw_exce(EX_BAD_METHODCALL, "pq\\COPY was not intitialized with FROM_STDIN"); } else { if (1 != PQputCopyEnd(obj->intern->conn->intern->conn, error_str)) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to end COPY (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to end COPY (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { PGresult *res = PQgetResult(obj->intern->conn->intern->conn); if (!res) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to fetch COPY result (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to fetch COPY result (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { - php_pqres_success(res TSRMLS_CC); + php_pqres_success(res); PHP_PQclear(res); } } - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->conn); } } } @@ -249,17 +240,17 @@ static PHP_METHOD(pqcopy, get) { zval *zdata; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zdata); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqcopy_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqcopy_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\COPY not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\COPY not initialized"); } else if (obj->intern->direction != PHP_PQCOPY_TO_STDOUT) { - throw_exce(EX_RUNTIME TSRMLS_CC, "pq\\COPY was not intialized with TO_STDOUT"); + throw_exce(EX_RUNTIME, "pq\\COPY was not intialized with TO_STDOUT"); } else { PGresult *res; char *buffer = NULL; @@ -267,25 +258,26 @@ static PHP_METHOD(pqcopy, get) { switch (bytes) { case -2: - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to fetch COPY data (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to fetch COPY data (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); break; case -1: res = PQgetResult(obj->intern->conn->intern->conn); if (!res) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to fetch COPY result (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to fetch COPY result (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { - php_pqres_success(res TSRMLS_CC); + php_pqres_success(res); PHP_PQclear(res); RETVAL_FALSE; } break; default: + ZVAL_DEREF(zdata); zval_dtor(zdata); if (buffer) { - ZVAL_STRINGL(zdata, buffer, bytes, 1); + ZVAL_STRINGL(zdata, buffer, bytes); } else { ZVAL_EMPTY_STRING(zdata); } @@ -320,38 +312,42 @@ PHP_MINIT_FUNCTION(pqcopy) php_pq_object_prophandler_t ph = {0}; INIT_NS_CLASS_ENTRY(ce, "pq", "COPY", php_pqcopy_methods); - php_pqcopy_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC); + php_pqcopy_class_entry = zend_register_internal_class_ex(&ce, NULL); php_pqcopy_class_entry->create_object = php_pqcopy_create_object; memcpy(&php_pqcopy_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + php_pqcopy_object_handlers.offset = XtOffsetOf(php_pqcopy_object_t, zo); + php_pqcopy_object_handlers.free_obj = php_pqcopy_object_free; php_pqcopy_object_handlers.read_property = php_pq_object_read_prop; php_pqcopy_object_handlers.write_property = php_pq_object_write_prop; php_pqcopy_object_handlers.clone_obj = NULL; php_pqcopy_object_handlers.get_property_ptr_ptr = NULL; - php_pqcopy_object_handlers.get_gc = NULL; + php_pqcopy_object_handlers.get_gc = php_pq_object_get_gc; php_pqcopy_object_handlers.get_properties = php_pq_object_properties; php_pqcopy_object_handlers.get_debug_info = php_pq_object_debug_info; - zend_hash_init(&php_pqcopy_object_prophandlers, 4, NULL, NULL, 1); + zend_hash_init(&php_pqcopy_object_prophandlers, 4, NULL, php_pq_object_prophandler_dtor, 1); - zend_declare_property_null(php_pqcopy_class_entry, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqcopy_class_entry, ZEND_STRL("connection"), ZEND_ACC_PUBLIC); ph.read = php_pqcopy_object_read_connection; - zend_hash_add(&php_pqcopy_object_prophandlers, "connection", sizeof("connection"), (void *) &ph, sizeof(ph), NULL); + ph.gc = php_pqcopy_object_gc_connection; + zend_hash_str_add_mem(&php_pqcopy_object_prophandlers, "connection", sizeof("connection")-1, (void *) &ph, sizeof(ph)); + ph.gc = NULL; - zend_declare_property_null(php_pqcopy_class_entry, ZEND_STRL("expression"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqcopy_class_entry, ZEND_STRL("expression"), ZEND_ACC_PUBLIC); ph.read = php_pqcopy_object_read_expression; - zend_hash_add(&php_pqcopy_object_prophandlers, "expression", sizeof("expression"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqcopy_object_prophandlers, "expression", sizeof("expression")-1, (void *) &ph, sizeof(ph)); - zend_declare_property_null(php_pqcopy_class_entry, ZEND_STRL("direction"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqcopy_class_entry, ZEND_STRL("direction"), ZEND_ACC_PUBLIC); ph.read = php_pqcopy_object_read_direction; - zend_hash_add(&php_pqcopy_object_prophandlers, "direction", sizeof("direction"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqcopy_object_prophandlers, "direction", sizeof("direction")-1, (void *) &ph, sizeof(ph)); - zend_declare_property_null(php_pqcopy_class_entry, ZEND_STRL("options"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqcopy_class_entry, ZEND_STRL("options"), ZEND_ACC_PUBLIC); ph.read = php_pqcopy_object_read_options; - zend_hash_add(&php_pqcopy_object_prophandlers, "options", sizeof("options"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqcopy_object_prophandlers, "options", sizeof("options")-1, (void *) &ph, sizeof(ph)); - zend_declare_class_constant_long(php_pqcopy_class_entry, ZEND_STRL("FROM_STDIN"), PHP_PQCOPY_FROM_STDIN TSRMLS_CC); - zend_declare_class_constant_long(php_pqcopy_class_entry, ZEND_STRL("TO_STDOUT"), PHP_PQCOPY_TO_STDOUT TSRMLS_CC); + zend_declare_class_constant_long(php_pqcopy_class_entry, ZEND_STRL("FROM_STDIN"), PHP_PQCOPY_FROM_STDIN); + zend_declare_class_constant_long(php_pqcopy_class_entry, ZEND_STRL("TO_STDOUT"), PHP_PQCOPY_TO_STDOUT); return SUCCESS; } diff --git a/src/php_pqcopy.h b/src/php_pqcopy.h index 130a1f2..decc817 100644 --- a/src/php_pqcopy.h +++ b/src/php_pqcopy.h @@ -35,14 +35,11 @@ typedef struct php_pqcopy { } php_pqcopy_t; typedef struct php_pqcopy_object { - zend_object zo; - zend_object_value zv; - HashTable *prophandler; - php_pqcopy_t *intern; + PHP_PQ_OBJ_DECL(php_pqcopy_t *) } php_pqcopy_object_t; extern zend_class_entry *php_pqcopy_class_entry; -extern zend_object_value php_pqcopy_create_object_ex(zend_class_entry *ce, php_pqcopy_t *intern, php_pqcopy_object_t **ptr TSRMLS_DC); +extern php_pqcopy_object_t *php_pqcopy_create_object_ex(zend_class_entry *ce, php_pqcopy_t *intern); extern PHP_MINIT_FUNCTION(pqcopy); extern PHP_MSHUTDOWN_FUNCTION(pqcopy); diff --git a/src/php_pqcur.c b/src/php_pqcur.c index 58ffd86..7a96994 100644 --- a/src/php_pqcur.c +++ b/src/php_pqcur.c @@ -15,7 +15,7 @@ #endif #include -#include +#include #include "php_pq.h" #include "php_pq_misc.h" @@ -29,7 +29,7 @@ zend_class_entry *php_pqcur_class_entry; static zend_object_handlers php_pqcur_object_handlers; static HashTable php_pqcur_object_prophandlers; -static void cur_close(php_pqcur_object_t *obj, zend_bool async, zend_bool silent TSRMLS_DC) +static void cur_close(php_pqcur_object_t *obj, zend_bool async, zend_bool silent) { if (obj->intern->open && obj->intern->conn->intern) { PGresult *res; @@ -40,17 +40,17 @@ static void cur_close(php_pqcur_object_t *obj, zend_bool async, zend_bool silent smart_str_0(&cmd); if (async) { - if (PQsendQuery(obj->intern->conn->intern->conn, cmd.c)) { + if (PQsendQuery(obj->intern->conn->intern->conn, smart_str_v(&cmd))) { obj->intern->conn->intern->poller = PQconsumeInput; - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->conn); } else if (!silent) { - throw_exce(EX_IO TSRMLS_CC, "Failed to close cursor (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_IO, "Failed to close cursor (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } } else { - if ((res = PQexec(obj->intern->conn->intern->conn, cmd.c))) { + if ((res = PQexec(obj->intern->conn->intern->conn, smart_str_v(&cmd)))) { PHP_PQclear(res); } else if (!silent) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to close cursor (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to close cursor (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } } @@ -65,27 +65,27 @@ static void cur_open(INTERNAL_FUNCTION_PARAMETERS, zend_bool async) ZEND_RESULT_CODE rv; php_pqcur_object_t *obj; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); rv = zend_parse_parameters_none(); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); if (rv == FAILURE) { return; } - obj = zend_object_store_get_object(getThis() TSRMLS_CC); + obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Cursor not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Cursor not initialized"); return; } else if (obj->intern->open) { return; } if (async) { - rv = php_pqconn_declare_async(NULL, obj->intern->conn, obj->intern->decl TSRMLS_CC); + rv = php_pqconn_declare_async(NULL, obj->intern->conn, obj->intern->decl); } else { - rv = php_pqconn_declare(NULL, obj->intern->conn, obj->intern->decl TSRMLS_CC); + rv = php_pqconn_declare(NULL, obj->intern->conn, obj->intern->decl); } if (rv == SUCCESS) { @@ -96,20 +96,20 @@ static void cur_open(INTERNAL_FUNCTION_PARAMETERS, zend_bool async) static void cur_fetch_or_move(INTERNAL_FUNCTION_PARAMETERS, const char *action, zend_bool async) { char *spec_str = "1"; - int spec_len = 1; + size_t spec_len = 1; ZEND_RESULT_CODE rv; php_pq_callback_t resolver = {{0}}; zend_error_handling zeh; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, async ? "|sf" : "|s", &spec_str, &spec_len, &resolver.fci, &resolver.fcc); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), async ? "|sf" : "|s", &spec_str, &spec_len, &resolver.fci, &resolver.fcc); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqcur_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqcur_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Cursor not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Cursor not initialized"); } else { smart_str cmd = {0}; @@ -120,102 +120,93 @@ static void cur_fetch_or_move(INTERNAL_FUNCTION_PARAMETERS, const char *action, smart_str_0(&cmd); if (async) { - int rc = PQsendQuery(obj->intern->conn->intern->conn, cmd.c); + int rc = PQsendQuery(obj->intern->conn->intern->conn, smart_str_v(&cmd)); if (!rc) { - throw_exce(EX_IO TSRMLS_CC, "Failed to %s cursor (%s)", *action == 'f' ? "fetch from" : "move in", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_IO, "Failed to %s cursor (%s)", *action == 'f' ? "fetch from" : "move in", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); #if HAVE_PQSETSINGLEROWMODE } else if (obj->intern->conn->intern->unbuffered && !PQsetSingleRowMode(obj->intern->conn->intern->conn)) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); #endif } else { - php_pq_callback_recurse(&obj->intern->conn->intern->onevent, &resolver TSRMLS_CC); + php_pq_callback_recurse(&obj->intern->conn->intern->onevent, &resolver); obj->intern->conn->intern->poller = PQconsumeInput; } } else { - PGresult *res = PQexec(obj->intern->conn->intern->conn, cmd.c); + PGresult *res = PQexec(obj->intern->conn->intern->conn, smart_str_v(&cmd)); if (!res) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to %s cursor (%s)", *action == 'f' ? "fetch from" : "move in", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); - } else if (SUCCESS == php_pqres_success(res TSRMLS_CC)) { - php_pq_object_to_zval_no_addref(PQresultInstanceData(res, php_pqconn_event), &return_value TSRMLS_CC); + throw_exce(EX_RUNTIME, "Failed to %s cursor (%s)", *action == 'f' ? "fetch from" : "move in", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + } else if (SUCCESS == php_pqres_success(res)) { + php_pq_object_to_zval_no_addref(PQresultInstanceData(res, php_pqconn_event), return_value); } } smart_str_free(&cmd); - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->conn); } } } -static void php_pqcur_object_free(void *o TSRMLS_DC) +static void php_pqcur_object_free(zend_object *o) { - php_pqcur_object_t *obj = o; + php_pqcur_object_t *obj = PHP_PQ_OBJ(NULL, o); #if DBG_GC - fprintf(stderr, "FREE cur(#%d) %p (conn: %p)\n", obj->zv.handle, obj, obj->intern->conn); + fprintf(stderr, "FREE cur(#%d) %p (conn: %p)\n", obj->zo.handle, obj, obj->intern->conn); #endif if (obj->intern) { - cur_close(obj, 0, 1 TSRMLS_CC); - php_pq_object_delref(obj->intern->conn TSRMLS_CC); + cur_close(obj, 0, 1); + php_pq_object_delref(obj->intern->conn); efree(obj->intern->decl); efree(obj->intern->name); efree(obj->intern); obj->intern = NULL; } - zend_object_std_dtor((zend_object *) o TSRMLS_CC); - efree(obj); + php_pq_object_dtor(o); } -zend_object_value php_pqcur_create_object_ex(zend_class_entry *ce, php_pqcur_t *intern, php_pqcur_object_t **ptr TSRMLS_DC) +php_pqcur_object_t *php_pqcur_create_object_ex(zend_class_entry *ce, php_pqcur_t *intern) { - php_pqcur_object_t *o; - - o = ecalloc(1, sizeof(*o)); - zend_object_std_init((zend_object *) o, ce TSRMLS_CC); - object_properties_init((zend_object *) o, ce); - o->prophandler = &php_pqcur_object_prophandlers; - - if (ptr) { - *ptr = o; - } - - if (intern) { - o->intern = intern; - } - - o->zv.handle = zend_objects_store_put((zend_object *) o, NULL, php_pqcur_object_free, NULL TSRMLS_CC); - o->zv.handlers = &php_pqcur_object_handlers; + return php_pq_object_create(ce, intern, sizeof(php_pqcur_object_t), + &php_pqcur_object_handlers, &php_pqcur_object_prophandlers); +} - return o->zv; +static zend_object *php_pqcur_create_object(zend_class_entry *class_type) +{ + return &php_pqcur_create_object_ex(class_type, NULL)->zo; } -static zend_object_value php_pqcur_create_object(zend_class_entry *class_type TSRMLS_DC) +static void php_pqcur_object_read_name(zval *object, void *o, zval *return_value) { - return php_pqcur_create_object_ex(class_type, NULL, NULL TSRMLS_CC); + php_pqcur_object_t *obj = o; + + RETVAL_STRING(obj->intern->name); } -static void php_pqcur_object_read_name(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqcur_object_read_connection(zval *object, void *o, zval *return_value) { php_pqcur_object_t *obj = o; - RETVAL_STRING(obj->intern->name, 1); + php_pq_object_to_zval(obj->intern->conn, return_value); } -static void php_pqcur_object_read_connection(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqcur_object_gc_connection(zval *object, void *o, zval *return_value) { php_pqcur_object_t *obj = o; + zval zconn; - php_pq_object_to_zval(obj->intern->conn, &return_value TSRMLS_CC); + php_pq_object_to_zval_no_addref(obj->intern->conn, &zconn); + add_next_index_zval(return_value, &zconn); } -static void php_pqcur_object_read_query(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqcur_object_read_query(zval *object, void *o, zval *return_value) { php_pqcur_object_t *obj = o; - RETVAL_STRING(obj->intern->decl + obj->intern->query_offset, 1); + RETVAL_STRING(obj->intern->decl + obj->intern->query_offset); } -static void php_pqcur_object_read_flags(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqcur_object_read_flags(zval *object, void *o, zval *return_value) { php_pqcur_object_t *obj = o; @@ -254,11 +245,11 @@ char *php_pqcur_declare_str(const char *name_str, size_t name_len, unsigned flag return decl_str; } -php_pqcur_t *php_pqcur_init(php_pqconn_object_t *conn, const char *name, char *decl, int query_offset, long flags TSRMLS_DC) +php_pqcur_t *php_pqcur_init(php_pqconn_object_t *conn, const char *name, char *decl, int query_offset, long flags) { php_pqcur_t *cur = ecalloc(1, sizeof(*cur)); - php_pq_object_addref(conn TSRMLS_CC); + php_pq_object_addref(conn); cur->conn = conn; cur->name = estrdup(name); cur->decl = decl; @@ -279,38 +270,38 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(pqcur, __construct) { zend_error_handling zeh; char *name_str, *query_str; - int name_len, query_len; - long flags; + size_t name_len, query_len; + zend_long flags; zval *zconn; ZEND_RESULT_CODE rv; zend_bool async = 0; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Osls|b", &zconn, php_pqconn_class_entry, &name_str, &name_len, &flags, &query_str, &query_len, &async); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "Osls|b", &zconn, php_pqconn_class_entry, &name_str, &name_len, &flags, &query_str, &query_len, &async); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqcur_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); - php_pqconn_object_t *conn_obj = zend_object_store_get_object(zconn TSRMLS_CC); + php_pqcur_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); + php_pqconn_object_t *conn_obj = PHP_PQ_OBJ(zconn, NULL); if (obj->intern) { - throw_exce(EX_BAD_METHODCALL TSRMLS_CC, "pq\\Cursor already initialized"); + throw_exce(EX_BAD_METHODCALL, "pq\\Cursor already initialized"); } if (!conn_obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized"); } else { int query_offset; char *decl = php_pqcur_declare_str(name_str, name_len, flags, query_str, query_len, &query_offset); if (async) { - rv = php_pqconn_declare_async(zconn, conn_obj, decl TSRMLS_CC); + rv = php_pqconn_declare_async(zconn, conn_obj, decl); } else { - rv = php_pqconn_declare(zconn, conn_obj, decl TSRMLS_CC); + rv = php_pqconn_declare(zconn, conn_obj, decl); } if (SUCCESS != rv) { efree(decl); } else { - obj->intern = php_pqcur_init(conn_obj, name_str, decl, query_offset, flags TSRMLS_CC); + obj->intern = php_pqcur_init(conn_obj, name_str, decl, query_offset, flags); } } } @@ -337,17 +328,17 @@ static PHP_METHOD(pqcur, close) zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); rv = zend_parse_parameters_none(); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); if (rv == SUCCESS) { - php_pqcur_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqcur_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Cursor not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Cursor not initialized"); } else { - cur_close(obj, 0, 0 TSRMLS_CC); + cur_close(obj, 0, 0); } } } @@ -359,17 +350,17 @@ static PHP_METHOD(pqcur, closeAsync) zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); rv = zend_parse_parameters_none(); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); if (rv == SUCCESS) { - php_pqcur_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqcur_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Cursor not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Cursor not initialized"); } else { - cur_close(obj, 1, 0 TSRMLS_CC); + cur_close(obj, 1, 0); } } } @@ -411,7 +402,7 @@ static PHP_METHOD(pqcur, moveAsync) static zend_function_entry php_pqcur_methods[] = { PHP_ME(pqcur, __construct, ai_pqcur___construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR) PHP_ME(pqcur, open, ai_pqcur_open, ZEND_ACC_PUBLIC) - PHP_ME(pqcur, openAsync, ai_pqcur_open, ZEND_ACC_PUBLIC) + PHP_ME(pqcur, openAsync, ai_pqcur_openAsync, ZEND_ACC_PUBLIC) PHP_ME(pqcur, close, ai_pqcur_close, ZEND_ACC_PUBLIC) PHP_ME(pqcur, closeAsync, ai_pqcur_closeAsync, ZEND_ACC_PUBLIC) PHP_ME(pqcur, fetch, ai_pqcur_fetch, ZEND_ACC_PUBLIC) @@ -433,41 +424,45 @@ PHP_MINIT_FUNCTION(pqcur) php_pq_object_prophandler_t ph = {0}; INIT_NS_CLASS_ENTRY(ce, "pq", "Cursor", php_pqcur_methods); - php_pqcur_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC); + php_pqcur_class_entry = zend_register_internal_class_ex(&ce, NULL); php_pqcur_class_entry->create_object = php_pqcur_create_object; memcpy(&php_pqcur_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + php_pqcur_object_handlers.offset = XtOffsetOf(php_pqcur_object_t, zo); + php_pqcur_object_handlers.free_obj = php_pqcur_object_free; php_pqcur_object_handlers.read_property = php_pq_object_read_prop; php_pqcur_object_handlers.write_property = php_pq_object_write_prop; php_pqcur_object_handlers.clone_obj = NULL; php_pqcur_object_handlers.get_property_ptr_ptr = NULL; - php_pqcur_object_handlers.get_gc = NULL; + php_pqcur_object_handlers.get_gc = php_pq_object_get_gc; php_pqcur_object_handlers.get_properties = php_pq_object_properties; php_pqcur_object_handlers.get_debug_info = php_pq_object_debug_info; - zend_hash_init(&php_pqcur_object_prophandlers, 4, NULL, NULL, 1); + zend_hash_init(&php_pqcur_object_prophandlers, 4, NULL, php_pq_object_prophandler_dtor, 1); - zend_declare_class_constant_long(php_pqcur_class_entry, ZEND_STRL("BINARY"), PHP_PQ_DECLARE_BINARY TSRMLS_CC); - zend_declare_class_constant_long(php_pqcur_class_entry, ZEND_STRL("INSENSITIVE"), PHP_PQ_DECLARE_INSENSITIVE TSRMLS_CC); - zend_declare_class_constant_long(php_pqcur_class_entry, ZEND_STRL("WITH_HOLD"), PHP_PQ_DECLARE_WITH_HOLD TSRMLS_CC); - zend_declare_class_constant_long(php_pqcur_class_entry, ZEND_STRL("SCROLL"), PHP_PQ_DECLARE_SCROLL TSRMLS_CC); - zend_declare_class_constant_long(php_pqcur_class_entry, ZEND_STRL("NO_SCROLL"), PHP_PQ_DECLARE_NO_SCROLL TSRMLS_CC); + zend_declare_class_constant_long(php_pqcur_class_entry, ZEND_STRL("BINARY"), PHP_PQ_DECLARE_BINARY); + zend_declare_class_constant_long(php_pqcur_class_entry, ZEND_STRL("INSENSITIVE"), PHP_PQ_DECLARE_INSENSITIVE); + zend_declare_class_constant_long(php_pqcur_class_entry, ZEND_STRL("WITH_HOLD"), PHP_PQ_DECLARE_WITH_HOLD); + zend_declare_class_constant_long(php_pqcur_class_entry, ZEND_STRL("SCROLL"), PHP_PQ_DECLARE_SCROLL); + zend_declare_class_constant_long(php_pqcur_class_entry, ZEND_STRL("NO_SCROLL"), PHP_PQ_DECLARE_NO_SCROLL); - zend_declare_property_null(php_pqcur_class_entry, ZEND_STRL("name"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqcur_class_entry, ZEND_STRL("name"), ZEND_ACC_PUBLIC); ph.read = php_pqcur_object_read_name; - zend_hash_add(&php_pqcur_object_prophandlers, "name", sizeof("name"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqcur_object_prophandlers, "name", sizeof("name")-1, (void *) &ph, sizeof(ph)); - zend_declare_property_null(php_pqcur_class_entry, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqcur_class_entry, ZEND_STRL("connection"), ZEND_ACC_PUBLIC); ph.read = php_pqcur_object_read_connection; - zend_hash_add(&php_pqcur_object_prophandlers, "connection", sizeof("connection"), (void *) &ph, sizeof(ph), NULL); + ph.gc = php_pqcur_object_gc_connection; + zend_hash_str_add_mem(&php_pqcur_object_prophandlers, "connection", sizeof("connection")-1, (void *) &ph, sizeof(ph)); + ph.gc = NULL; - zend_declare_property_null(php_pqcur_class_entry, ZEND_STRL("query"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqcur_class_entry, ZEND_STRL("query"), ZEND_ACC_PUBLIC); ph.read = php_pqcur_object_read_query; - zend_hash_add(&php_pqcur_object_prophandlers, "query", sizeof("query"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqcur_object_prophandlers, "query", sizeof("query")-1, (void *) &ph, sizeof(ph)); zend_declare_property_null(php_pqcur_class_entry, ZEND_STRL("flags"), ZEND_ACC_PUBLIC TSRMLS_CC); ph.read = php_pqcur_object_read_flags; - zend_hash_add(&php_pqcur_object_prophandlers, "flags", sizeof("flags"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqcur_object_prophandlers, "flags", sizeof("flags")-1, (void *) &ph, sizeof(ph)); return SUCCESS; } diff --git a/src/php_pqcur.h b/src/php_pqcur.h index b12e0a1..ab74e8d 100644 --- a/src/php_pqcur.h +++ b/src/php_pqcur.h @@ -32,17 +32,14 @@ typedef struct php_pqcur { } php_pqcur_t; typedef struct php_pqcur_object { - zend_object zo; - zend_object_value zv; - HashTable *prophandler; - php_pqcur_t *intern; + PHP_PQ_OBJ_DECL(php_pqcur_t *) } php_pqcur_object_t; extern zend_class_entry *php_pqcur_class_entry; -extern zend_object_value php_pqcur_create_object_ex(zend_class_entry *ce, php_pqcur_t *intern, php_pqcur_object_t **ptr TSRMLS_DC); +extern php_pqcur_object_t *php_pqcur_create_object_ex(zend_class_entry *ce, php_pqcur_t *intern); extern char *php_pqcur_declare_str(const char *name_str, size_t name_len, unsigned flags, const char *query_str, size_t query_len, int *query_offset); -extern php_pqcur_t *php_pqcur_init(php_pqconn_object_t *conn, const char *name, char *decl, int query_offset, long flags TSRMLS_DC); +extern php_pqcur_t *php_pqcur_init(php_pqconn_object_t *conn, const char *name, char *decl, int query_offset, long flags); extern PHP_MINIT_FUNCTION(pqcur); extern PHP_MSHUTDOWN_FUNCTION(pqcur); diff --git a/src/php_pqexc.c b/src/php_pqexc.c index d67a3ff..1f96662 100644 --- a/src/php_pqexc.c +++ b/src/php_pqexc.c @@ -53,17 +53,17 @@ zend_class_entry *exce(php_pqexc_type_t type) } } -zval *throw_exce(php_pqexc_type_t type TSRMLS_DC, const char *fmt, ...) +zend_object *throw_exce(php_pqexc_type_t type, const char *fmt, ...) { char *msg; - zval *zexc; + zend_object *zexc; va_list argv; va_start(argv, fmt); vspprintf(&msg, 0, fmt, argv); va_end(argv); - zexc = zend_throw_exception(exce(type), msg, type TSRMLS_CC); + zexc = zend_throw_exception(exce(type), msg, type); efree(msg); return zexc; @@ -74,38 +74,39 @@ PHP_MINIT_FUNCTION(pqexc) zend_class_entry ce = {0}; INIT_NS_CLASS_ENTRY(ce, "pq", "Exception", php_pqexc_methods); - php_pqexc_interface_class_entry = zend_register_internal_interface(&ce TSRMLS_CC); - - zend_declare_class_constant_long(php_pqexc_interface_class_entry, ZEND_STRL("INVALID_ARGUMENT"), EX_INVALID_ARGUMENT TSRMLS_CC); - zend_declare_class_constant_long(php_pqexc_interface_class_entry, ZEND_STRL("RUNTIME"), EX_RUNTIME TSRMLS_CC); - zend_declare_class_constant_long(php_pqexc_interface_class_entry, ZEND_STRL("CONNECTION_FAILED"), EX_CONNECTION_FAILED TSRMLS_CC); - zend_declare_class_constant_long(php_pqexc_interface_class_entry, ZEND_STRL("IO"), EX_IO TSRMLS_CC); - zend_declare_class_constant_long(php_pqexc_interface_class_entry, ZEND_STRL("ESCAPE"), EX_ESCAPE TSRMLS_CC); - zend_declare_class_constant_long(php_pqexc_interface_class_entry, ZEND_STRL("BAD_METHODCALL"), EX_BAD_METHODCALL TSRMLS_CC); - zend_declare_class_constant_long(php_pqexc_interface_class_entry, ZEND_STRL("UNINITIALIZED"), EX_UNINITIALIZED TSRMLS_CC); - zend_declare_class_constant_long(php_pqexc_interface_class_entry, ZEND_STRL("DOMAIN"), EX_DOMAIN TSRMLS_CC); - zend_declare_class_constant_long(php_pqexc_interface_class_entry, ZEND_STRL("SQL"), EX_SQL TSRMLS_CC); + php_pqexc_interface_class_entry = zend_register_internal_interface(&ce); + zend_class_implements(php_pqexc_interface_class_entry, 1, zend_ce_throwable); + + zend_declare_class_constant_long(php_pqexc_interface_class_entry, ZEND_STRL("INVALID_ARGUMENT"), EX_INVALID_ARGUMENT); + zend_declare_class_constant_long(php_pqexc_interface_class_entry, ZEND_STRL("RUNTIME"), EX_RUNTIME); + zend_declare_class_constant_long(php_pqexc_interface_class_entry, ZEND_STRL("CONNECTION_FAILED"), EX_CONNECTION_FAILED); + zend_declare_class_constant_long(php_pqexc_interface_class_entry, ZEND_STRL("IO"), EX_IO); + zend_declare_class_constant_long(php_pqexc_interface_class_entry, ZEND_STRL("ESCAPE"), EX_ESCAPE); + zend_declare_class_constant_long(php_pqexc_interface_class_entry, ZEND_STRL("BAD_METHODCALL"), EX_BAD_METHODCALL); + zend_declare_class_constant_long(php_pqexc_interface_class_entry, ZEND_STRL("UNINITIALIZED"), EX_UNINITIALIZED); + zend_declare_class_constant_long(php_pqexc_interface_class_entry, ZEND_STRL("DOMAIN"), EX_DOMAIN); + zend_declare_class_constant_long(php_pqexc_interface_class_entry, ZEND_STRL("SQL"), EX_SQL); memset(&ce, 0, sizeof(ce)); INIT_NS_CLASS_ENTRY(ce, "pq\\Exception", "InvalidArgumentException", php_pqexc_methods); - php_pqexc_invalid_argument_class_entry = zend_register_internal_class_ex(&ce, spl_ce_InvalidArgumentException, "InvalidArgumentException" TSRMLS_CC); - zend_class_implements(php_pqexc_invalid_argument_class_entry TSRMLS_CC, 1, php_pqexc_interface_class_entry); + php_pqexc_invalid_argument_class_entry = zend_register_internal_class_ex(&ce, spl_ce_InvalidArgumentException); + zend_class_implements(php_pqexc_invalid_argument_class_entry, 1, php_pqexc_interface_class_entry); memset(&ce, 0, sizeof(ce)); INIT_NS_CLASS_ENTRY(ce, "pq\\Exception", "RuntimeException", php_pqexc_methods); - php_pqexc_runtime_class_entry = zend_register_internal_class_ex(&ce, spl_ce_RuntimeException, "RuntimeException" TSRMLS_CC); - zend_class_implements(php_pqexc_runtime_class_entry TSRMLS_CC, 1, php_pqexc_interface_class_entry); + php_pqexc_runtime_class_entry = zend_register_internal_class_ex(&ce, spl_ce_RuntimeException); + zend_class_implements(php_pqexc_runtime_class_entry, 1, php_pqexc_interface_class_entry); memset(&ce, 0, sizeof(ce)); INIT_NS_CLASS_ENTRY(ce, "pq\\Exception", "BadMethodCallException", php_pqexc_methods); - php_pqexc_bad_methodcall_class_entry = zend_register_internal_class_ex(&ce, spl_ce_BadMethodCallException, "BadMethodCallException" TSRMLS_CC); - zend_class_implements(php_pqexc_bad_methodcall_class_entry TSRMLS_CC, 1, php_pqexc_interface_class_entry); + php_pqexc_bad_methodcall_class_entry = zend_register_internal_class_ex(&ce, spl_ce_BadMethodCallException); + zend_class_implements(php_pqexc_bad_methodcall_class_entry, 1, php_pqexc_interface_class_entry); memset(&ce, 0, sizeof(ce)); INIT_NS_CLASS_ENTRY(ce, "pq\\Exception", "DomainException", php_pqexc_methods); - php_pqexc_domain_class_entry = zend_register_internal_class_ex(&ce, spl_ce_DomainException, "DomainException" TSRMLS_CC); - zend_class_implements(php_pqexc_domain_class_entry TSRMLS_CC, 1, php_pqexc_interface_class_entry); - zend_declare_property_null(php_pqexc_domain_class_entry, ZEND_STRL("sqlstate"), ZEND_ACC_PUBLIC TSRMLS_CC); + php_pqexc_domain_class_entry = zend_register_internal_class_ex(&ce, spl_ce_DomainException); + zend_class_implements(php_pqexc_domain_class_entry, 1, php_pqexc_interface_class_entry); + zend_declare_property_null(php_pqexc_domain_class_entry, ZEND_STRL("sqlstate"), ZEND_ACC_PUBLIC); return SUCCESS; } diff --git a/src/php_pqexc.h b/src/php_pqexc.h index c5847da..2666dcf 100644 --- a/src/php_pqexc.h +++ b/src/php_pqexc.h @@ -27,7 +27,7 @@ typedef enum php_pqexc_type { } php_pqexc_type_t; extern zend_class_entry *exce(php_pqexc_type_t type); -extern zval *throw_exce(php_pqexc_type_t type TSRMLS_DC, const char *fmt, ...); +extern zend_object *throw_exce(php_pqexc_type_t type, const char *fmt, ...); extern PHP_MINIT_FUNCTION(pqexc); diff --git a/src/php_pqlob.c b/src/php_pqlob.c index 1c6e7b7..01c0ec2 100644 --- a/src/php_pqlob.c +++ b/src/php_pqlob.c @@ -28,11 +28,11 @@ zend_class_entry *php_pqlob_class_entry; static zend_object_handlers php_pqlob_object_handlers; static HashTable php_pqlob_object_prophandlers; -static void php_pqlob_object_free(void *o TSRMLS_DC) +static void php_pqlob_object_free(zend_object *o) { - php_pqlob_object_t *obj = o; + php_pqlob_object_t *obj = PHP_PQ_OBJ(NULL, o); #if DBG_GC - fprintf(stderr, "FREE lob(#%d) %p (txn(#%d): %p)\n", obj->zv.handle, obj, obj->intern->txn->zv.handle, obj->intern->txn); + fprintf(stderr, "FREE lob(#%d) %p (txn(#%d): %p)\n", obj->zo.handle, obj, obj->intern->txn->zo.handle, obj->intern->txn); #endif if (obj->intern) { if (obj->intern->lofd) { @@ -40,74 +40,64 @@ static void php_pqlob_object_free(void *o TSRMLS_DC) } /* invalidate the stream */ if (obj->intern->stream) { - zend_list_delete(obj->intern->stream); - obj->intern->stream = 0; + zend_list_delete(obj->intern->stream->res); + obj->intern->stream = NULL; } - php_pq_object_delref(obj->intern->txn TSRMLS_CC); + php_pq_object_delref(obj->intern->txn); efree(obj->intern); obj->intern = NULL; } - zend_object_std_dtor((zend_object *) o TSRMLS_CC); - efree(obj); + php_pq_object_dtor(o); } -zend_object_value php_pqlob_create_object_ex(zend_class_entry *ce, php_pqlob_t *intern, php_pqlob_object_t **ptr TSRMLS_DC) +php_pqlob_object_t *php_pqlob_create_object_ex(zend_class_entry *ce, php_pqlob_t *intern) { - php_pqlob_object_t *o; - - o = ecalloc(1, sizeof(*o)); - zend_object_std_init((zend_object *) o, ce TSRMLS_CC); - object_properties_init((zend_object *) o, ce); - o->prophandler = &php_pqlob_object_prophandlers; - - if (ptr) { - *ptr = o; - } - - if (intern) { - o->intern = intern; - } - - o->zv.handle = zend_objects_store_put((zend_object *) o, NULL, php_pqlob_object_free, NULL TSRMLS_CC); - o->zv.handlers = &php_pqlob_object_handlers; + return php_pq_object_create(ce, intern, sizeof(php_pqlob_object_t), + &php_pqlob_object_handlers, &php_pqlob_object_prophandlers); +} - return o->zv; +static zend_object *php_pqlob_create_object(zend_class_entry *class_type) +{ + return &php_pqlob_create_object_ex(class_type, NULL)->zo; } -static zend_object_value php_pqlob_create_object(zend_class_entry *class_type TSRMLS_DC) +static void php_pqlob_object_read_transaction(zval *object, void *o, zval *return_value) { - return php_pqlob_create_object_ex(class_type, NULL, NULL TSRMLS_CC); + php_pqlob_object_t *obj = o; + + php_pq_object_to_zval(obj->intern->txn, return_value); } -static void php_pqlob_object_read_transaction(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqlob_object_gc_transaction(zval *object, void *o, zval *return_value) { php_pqlob_object_t *obj = o; + zval ztxn; - php_pq_object_to_zval(obj->intern->txn, &return_value TSRMLS_CC); + php_pq_object_to_zval_no_addref(obj->intern->txn, &ztxn); + add_next_index_zval(return_value, &ztxn); } -static void php_pqlob_object_read_oid(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqlob_object_read_oid(zval *object, void *o, zval *return_value) { php_pqlob_object_t *obj = o; RETVAL_LONG(obj->intern->loid); } -static void php_pqlob_object_update_stream(zval *this_ptr, php_pqlob_object_t *obj, zval **zstream TSRMLS_DC); +static void php_pqlob_object_update_stream(zval *this_ptr, php_pqlob_object_t *obj, zval *zstream); -static void php_pqlob_object_read_stream(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqlob_object_read_stream(zval *object, void *o, zval *return_value) { php_pqlob_object_t *obj = o; + zval zstream; if (!obj->intern->stream) { - zval *zstream; - - php_pqlob_object_update_stream(object, obj, &zstream TSRMLS_CC); - RETVAL_ZVAL(zstream, 1, 1); + php_pqlob_object_update_stream(object, obj, &zstream); } else { - RETVAL_RESOURCE(obj->intern->stream); - zend_list_addref(obj->intern->stream); + php_stream_to_zval(obj->intern->stream, &zstream); } + + RETVAL_ZVAL(&zstream, 1, 0); } static size_t php_pqlob_stream_write(php_stream *stream, const char *buffer, size_t length TSRMLS_DC) @@ -201,30 +191,21 @@ static php_stream_ops php_pqlob_stream_ops = { NULL, /* set_option */ }; -static void php_pqlob_object_update_stream(zval *this_ptr, php_pqlob_object_t *obj, zval **zstream_ptr TSRMLS_DC) +static void php_pqlob_object_update_stream(zval *zpqlob, php_pqlob_object_t *obj, zval *zstream) { - zval *zstream, zmember; - php_stream *stream; + zval zmember; - INIT_PZVAL(&zmember); - ZVAL_STRINGL(&zmember, "stream", sizeof("stream")-1, 0); + ZVAL_STRINGL(&zmember, "stream", sizeof("stream")-1); - MAKE_STD_ZVAL(zstream); if (!obj) { - obj = zend_object_store_get_object(getThis() TSRMLS_CC); + obj = PHP_PQ_OBJ(zpqlob, NULL); } - stream = php_stream_alloc(&php_pqlob_stream_ops, obj, NULL, "r+b"); - stream->flags |= PHP_STREAM_FLAG_NO_FCLOSE; - zend_list_addref(obj->intern->stream = stream->rsrc_id); - php_stream_to_zval(stream, zstream); - - zend_get_std_object_handlers()->write_property(getThis(), &zmember, zstream, NULL TSRMLS_CC); + obj->intern->stream = php_stream_alloc(&php_pqlob_stream_ops, obj, NULL, "r+b"); + obj->intern->stream->flags |= PHP_STREAM_FLAG_NO_FCLOSE; + php_stream_to_zval(obj->intern->stream, zstream); - if (zstream_ptr) { - *zstream_ptr = zstream; - } else { - zval_ptr_dtor(&zstream); - } + zend_get_std_object_handlers()->write_property(zpqlob, &zmember, zstream, NULL); + zval_ptr_dtor(&zmember); } ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_construct, 0, 0, 1) @@ -235,45 +216,45 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(pqlob, __construct) { zend_error_handling zeh; zval *ztxn; - long mode = INV_WRITE|INV_READ, loid = InvalidOid; + zend_long mode = INV_WRITE|INV_READ, loid = InvalidOid; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|ll", &ztxn, php_pqtxn_class_entry, &loid, &mode); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "O|ll", &ztxn, php_pqtxn_class_entry, &loid, &mode); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqlob_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); - php_pqtxn_object_t *txn_obj = zend_object_store_get_object(ztxn TSRMLS_CC); + php_pqlob_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); + php_pqtxn_object_t *txn_obj = PHP_PQ_OBJ(ztxn, NULL); if (obj->intern) { - throw_exce(EX_BAD_METHODCALL TSRMLS_CC, "pq\\LOB already initialized"); + throw_exce(EX_BAD_METHODCALL, "pq\\LOB already initialized"); } else if (!txn_obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Transaction not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized"); } else if (!txn_obj->intern->open) { - throw_exce(EX_RUNTIME TSRMLS_CC, "pq\\Transation already closed"); + throw_exce(EX_RUNTIME, "pq\\Transation already closed"); } else { if (loid == InvalidOid) { loid = lo_creat(txn_obj->intern->conn->intern->conn, mode); } if (loid == InvalidOid) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to create large object with mode '%s' (%s)", php_pq_strmode(mode), PHP_PQerrorMessage(txn_obj->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to create large object with mode '%s' (%s)", php_pq_strmode(mode), PHP_PQerrorMessage(txn_obj->intern->conn->intern->conn)); } else { int lofd = lo_open(txn_obj->intern->conn->intern->conn, loid, mode); if (lofd < 0) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to open large object with oid=%u with mode '%s' (%s)", loid, php_pq_strmode(mode), PHP_PQerrorMessage(txn_obj->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to open large object with oid=%u with mode '%s' (%s)", loid, php_pq_strmode(mode), PHP_PQerrorMessage(txn_obj->intern->conn->intern->conn)); } else { obj->intern = ecalloc(1, sizeof(*obj->intern)); obj->intern->lofd = lofd; obj->intern->loid = loid; - php_pq_object_addref(txn_obj TSRMLS_CC); + php_pq_object_addref(txn_obj); obj->intern->txn = txn_obj; } } - php_pqconn_notify_listeners(txn_obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(txn_obj->intern->conn); } } } @@ -284,28 +265,28 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(pqlob, write) { zend_error_handling zeh; char *data_str; - int data_len; + size_t data_len; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &data_str, &data_len); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "s", &data_str, &data_len); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqlob_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqlob_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\LOB not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\LOB not initialized"); } else { int written = lo_write(obj->intern->txn->intern->conn->intern->conn, obj->intern->lofd, data_str, data_len); if (written < 0) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to write to LOB with oid=%u (%s)", obj->intern->loid, PHP_PQerrorMessage(obj->intern->txn->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to write to LOB with oid=%u (%s)", obj->intern->loid, PHP_PQerrorMessage(obj->intern->txn->intern->conn->intern->conn)); } else { RETVAL_LONG(written); } - php_pqconn_notify_listeners(obj->intern->txn->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->txn->intern->conn); } } } @@ -316,36 +297,37 @@ ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_read, 0, 0, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(pqlob, read) { zend_error_handling zeh; - long length = 0x1000; + zend_long length = 0x1000; zval *zread = NULL; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|lz!", &length, &zread); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "|lz!", &length, &zread); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqlob_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqlob_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\LOB not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\LOB not initialized"); } else { - char *buffer = emalloc(length + 1); - int read = lo_read(obj->intern->txn->intern->conn->intern->conn, obj->intern->lofd, buffer, length); + zend_string *buffer = zend_string_alloc(length, 0); + int read = lo_read(obj->intern->txn->intern->conn->intern->conn, obj->intern->lofd, &buffer->val[0], length); if (read < 0) { - efree(buffer); - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to read from LOB with oid=%d (%s)", obj->intern->loid, PHP_PQerrorMessage(obj->intern->txn->intern->conn->intern->conn)); + zend_string_release(buffer); + throw_exce(EX_RUNTIME, "Failed to read from LOB with oid=%d (%s)", obj->intern->loid, PHP_PQerrorMessage(obj->intern->txn->intern->conn->intern->conn)); } else { if (zread) { + ZVAL_DEREF(zread); zval_dtor(zread); ZVAL_LONG(zread, read); } - buffer[read] = '\0'; - RETVAL_STRINGL(buffer, read, 0); + buffer->val[buffer->len = read] = '\0'; + RETVAL_STR(buffer); } - php_pqconn_notify_listeners(obj->intern->txn->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->txn->intern->conn); } } } @@ -356,28 +338,28 @@ ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_seek, 0, 0, 1) ZEND_END_ARG_INFO(); static PHP_METHOD(pqlob, seek) { zend_error_handling zeh; - long offset, whence = SEEK_SET; + zend_long offset, whence = SEEK_SET; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l", &offset, &whence); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "l|l", &offset, &whence); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqlob_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqlob_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\LOB not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\LOB not initialized"); } else { int position = lo_lseek(obj->intern->txn->intern->conn->intern->conn, obj->intern->lofd, offset, whence); if (position < 0) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to seek offset in LOB with oid=%d (%s)", obj->intern->loid, PHP_PQerrorMessage(obj->intern->txn->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to seek offset in LOB with oid=%d (%s)", obj->intern->loid, PHP_PQerrorMessage(obj->intern->txn->intern->conn->intern->conn)); } else { RETVAL_LONG(position); } - php_pqconn_notify_listeners(obj->intern->txn->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->txn->intern->conn); } } } @@ -388,25 +370,25 @@ static PHP_METHOD(pqlob, tell) { zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); rv = zend_parse_parameters_none(); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqlob_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqlob_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\LOB not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\LOB not initialized"); } else { int position = lo_tell(obj->intern->txn->intern->conn->intern->conn, obj->intern->lofd); if (position < 0) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to tell offset in LOB with oid=%d (%s)", obj->intern->loid, PHP_PQerrorMessage(obj->intern->txn->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to tell offset in LOB with oid=%d (%s)", obj->intern->loid, PHP_PQerrorMessage(obj->intern->txn->intern->conn->intern->conn)); } else { RETVAL_LONG(position); } - php_pqconn_notify_listeners(obj->intern->txn->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->txn->intern->conn); } } } @@ -416,26 +398,26 @@ ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_truncate, 0, 0, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(pqlob, truncate) { zend_error_handling zeh; - long length = 0; + zend_long length = 0; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &length); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &length); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqlob_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqlob_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\LOB not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\LOB not initialized"); } else { int rc = lo_truncate(obj->intern->txn->intern->conn->intern->conn, obj->intern->lofd, length); if (rc != 0) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to truncate LOB with oid=%d (%s)", obj->intern->loid, PHP_PQerrorMessage(obj->intern->txn->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to truncate LOB with oid=%d (%s)", obj->intern->loid, PHP_PQerrorMessage(obj->intern->txn->intern->conn->intern->conn)); } - php_pqconn_notify_listeners(obj->intern->txn->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->txn->intern->conn); } } } @@ -462,36 +444,40 @@ PHP_MINIT_FUNCTION(pqlob) php_pq_object_prophandler_t ph = {0}; INIT_NS_CLASS_ENTRY(ce, "pq", "LOB", php_pqlob_methods); - php_pqlob_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC); + php_pqlob_class_entry = zend_register_internal_class_ex(&ce, NULL); php_pqlob_class_entry->create_object = php_pqlob_create_object; memcpy(&php_pqlob_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + php_pqlob_object_handlers.offset = XtOffsetOf(php_pqlob_object_t, zo); + php_pqlob_object_handlers.free_obj = php_pqlob_object_free; php_pqlob_object_handlers.read_property = php_pq_object_read_prop; php_pqlob_object_handlers.write_property = php_pq_object_write_prop; php_pqlob_object_handlers.clone_obj = NULL; php_pqlob_object_handlers.get_property_ptr_ptr = NULL; - php_pqlob_object_handlers.get_gc = NULL; + php_pqlob_object_handlers.get_gc = php_pq_object_get_gc; php_pqlob_object_handlers.get_properties = php_pq_object_properties; php_pqlob_object_handlers.get_debug_info = php_pq_object_debug_info; - zend_hash_init(&php_pqlob_object_prophandlers, 3, NULL, NULL, 1); + zend_hash_init(&php_pqlob_object_prophandlers, 3, NULL, php_pq_object_prophandler_dtor, 1); - zend_declare_property_null(php_pqlob_class_entry, ZEND_STRL("transaction"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqlob_class_entry, ZEND_STRL("transaction"), ZEND_ACC_PUBLIC); ph.read = php_pqlob_object_read_transaction; - zend_hash_add(&php_pqlob_object_prophandlers, "transaction", sizeof("transaction"), (void *) &ph, sizeof(ph), NULL); + ph.gc = php_pqlob_object_gc_transaction; + zend_hash_str_add_mem(&php_pqlob_object_prophandlers, "transaction", sizeof("transaction")-1, (void *) &ph, sizeof(ph)); + ph.gc = NULL; - zend_declare_property_long(php_pqlob_class_entry, ZEND_STRL("oid"), InvalidOid, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(php_pqlob_class_entry, ZEND_STRL("oid"), InvalidOid, ZEND_ACC_PUBLIC); ph.read = php_pqlob_object_read_oid; - zend_hash_add(&php_pqlob_object_prophandlers, "oid", sizeof("oid"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqlob_object_prophandlers, "oid", sizeof("oid")-1, (void *) &ph, sizeof(ph)); - zend_declare_property_null(php_pqlob_class_entry, ZEND_STRL("stream"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqlob_class_entry, ZEND_STRL("stream"), ZEND_ACC_PUBLIC); ph.read = php_pqlob_object_read_stream; - zend_hash_add(&php_pqlob_object_prophandlers, "stream", sizeof("stream"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqlob_object_prophandlers, "stream", sizeof("stream")-1, (void *) &ph, sizeof(ph)); - zend_declare_class_constant_long(php_pqlob_class_entry, ZEND_STRL("INVALID_OID"), InvalidOid TSRMLS_CC); - zend_declare_class_constant_long(php_pqlob_class_entry, ZEND_STRL("R"), INV_READ TSRMLS_CC); - zend_declare_class_constant_long(php_pqlob_class_entry, ZEND_STRL("W"), INV_WRITE TSRMLS_CC); - zend_declare_class_constant_long(php_pqlob_class_entry, ZEND_STRL("RW"), INV_READ|INV_WRITE TSRMLS_CC); + zend_declare_class_constant_long(php_pqlob_class_entry, ZEND_STRL("INVALID_OID"), InvalidOid); + zend_declare_class_constant_long(php_pqlob_class_entry, ZEND_STRL("R"), INV_READ); + zend_declare_class_constant_long(php_pqlob_class_entry, ZEND_STRL("W"), INV_WRITE); + zend_declare_class_constant_long(php_pqlob_class_entry, ZEND_STRL("RW"), INV_READ|INV_WRITE); return SUCCESS; } diff --git a/src/php_pqlob.h b/src/php_pqlob.h index 98c8a94..fc7fa13 100644 --- a/src/php_pqlob.h +++ b/src/php_pqlob.h @@ -19,19 +19,16 @@ typedef struct php_pqlob { int lofd; Oid loid; - int stream; + php_stream *stream; php_pqtxn_object_t *txn; } php_pqlob_t; typedef struct php_pqlob_object { - zend_object zo; - zend_object_value zv; - HashTable *prophandler; - php_pqlob_t *intern; + PHP_PQ_OBJ_DECL(php_pqlob_t *) } php_pqlob_object_t; extern zend_class_entry *php_pqlob_class_entry; -extern zend_object_value php_pqlob_create_object_ex(zend_class_entry *ce, php_pqlob_t *intern, php_pqlob_object_t **ptr TSRMLS_DC); +extern php_pqlob_object_t *php_pqlob_create_object_ex(zend_class_entry *ce, php_pqlob_t *intern); extern PHP_MINIT_FUNCTION(pqlob); extern PHP_MSHUTDOWN_FUNCTION(pqlob); diff --git a/src/php_pqres.c b/src/php_pqres.c index 6e1fa68..f2ddf98 100644 --- a/src/php_pqres.c +++ b/src/php_pqres.c @@ -36,51 +36,55 @@ static zend_object_handlers php_pqres_object_handlers; static HashTable php_pqres_object_prophandlers; static zend_object_iterator_funcs php_pqres_iterator_funcs; -static zend_object_iterator *php_pqres_iterator_init(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC) +static zend_object_iterator *php_pqres_iterator_init(zend_class_entry *ce, zval *object, int by_ref) { php_pqres_iterator_t *iter; - zval *prop, *zfetch_type; + zval tmp, *zfetch_type; iter = ecalloc(1, sizeof(*iter)); iter->zi.funcs = &php_pqres_iterator_funcs; - iter->zi.data = zend_object_store_get_object(object TSRMLS_CC); - zend_objects_store_add_ref(object TSRMLS_CC); + ZVAL_COPY(&iter->zi.data, object); - zfetch_type = prop = zend_read_property(ce, object, ZEND_STRL("fetchType"), 0 TSRMLS_CC); - if (Z_TYPE_P(zfetch_type) != IS_LONG) { - convert_to_long_ex(&zfetch_type); - } - iter->fetch_type = Z_LVAL_P(zfetch_type); - if (zfetch_type != prop) { - zval_ptr_dtor(&zfetch_type); - } - if (Z_REFCOUNT_P(prop)) { - zval_ptr_dtor(&prop); - } else { - zval_dtor(prop); - FREE_ZVAL(prop); - } + zend_iterator_init(&iter->zi); + zfetch_type = zend_read_property(ce, object, ZEND_STRL("fetchType"), 0, &tmp); + iter->fetch_type = zval_get_long(zfetch_type); +#if DBG_GC + fprintf(stderr, "INIT iter(#%d) %p res(#%d) %p\n", iter->zi.std.handle, iter, Z_OBJ_HANDLE_P(object), PHP_PQ_OBJ(object, NULL)); +#endif return (zend_object_iterator *) iter; } -static void php_pqres_iterator_dtor(zend_object_iterator *i TSRMLS_DC) +static void php_pqres_internal_iterator_init(zval *zobj) +{ + php_pqres_object_t *obj = PHP_PQ_OBJ(zobj, NULL); + + obj->intern->iter = (php_pqres_iterator_t *) php_pqres_iterator_init(Z_OBJCE_P(zobj), zobj, 0); + /* prevent cyclic dep */ + Z_DELREF_P(zobj); + obj->intern->iter->zi.funcs->rewind((zend_object_iterator *) obj->intern->iter); + +} + +static void php_pqres_iterator_dtor(zend_object_iterator *i) { php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i; - php_pqres_object_t *obj = i->data; - if (iter->current_val) { +#if DBG_GC + fprintf(stderr, "FREE iter(#%d) %p\n", iter->zi.std.handle, iter); +#endif + if (!Z_ISUNDEF(iter->current_val)) { zval_ptr_dtor(&iter->current_val); - iter->current_val = NULL; + ZVAL_UNDEF(&iter->current_val); } - zend_objects_store_del_ref_by_handle_ex(obj->zv.handle, obj->zv.handlers TSRMLS_CC); - efree(iter); + zval_ptr_dtor(&i->data); + zend_iterator_dtor(i); } -static ZEND_RESULT_CODE php_pqres_iterator_valid(zend_object_iterator *i TSRMLS_DC) +static ZEND_RESULT_CODE php_pqres_iterator_valid(zend_object_iterator *i) { php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i; - php_pqres_object_t *obj = i->data; + php_pqres_object_t *obj = PHP_PQ_OBJ(&i->data, NULL); switch (PQresultStatus(obj->intern->res)) { case PGRES_TUPLES_OK: @@ -101,35 +105,34 @@ static ZEND_RESULT_CODE php_pqres_iterator_valid(zend_object_iterator *i TSRMLS_ #define PHP_PQRES_JSON_OPTIONS(res) \ (php_pqres_fetch_type(res) != PHP_PQRES_FETCH_OBJECT ? PHP_JSON_OBJECT_AS_ARRAY:0) -zval *php_pqres_typed_zval(php_pqres_t *res, char *val, size_t len, Oid typ TSRMLS_DC) +zval *php_pqres_typed_zval(php_pqres_t *res, Oid typ, zval *zv) { - zval *zv, **zconv; - - MAKE_STD_ZVAL(zv); + zval *zconv; + HashTable *ht; + zend_string *str; - if (SUCCESS == zend_hash_index_find(&res->converters, typ, (void *) &zconv)) { - zval *ztype, *tmp = NULL; + if ((zconv = zend_hash_index_find(&res->converters, typ))) { + zval ztype, rv; - MAKE_STD_ZVAL(ztype); - ZVAL_LONG(ztype, typ); - ZVAL_STRINGL(zv, val, len, 1); - zend_call_method_with_2_params(zconv, NULL, NULL, "convertfromstring", &tmp, zv, ztype); - zval_ptr_dtor(&ztype); + ZVAL_NULL(&rv); + ZVAL_LONG(&ztype, typ); + zend_call_method_with_2_params(zconv, NULL, NULL, "convertfromstring", &rv, zv, &ztype); - if (tmp) { - zval_ptr_dtor(&zv); - zv = tmp; - } + zval_ptr_dtor(zv); + ZVAL_ZVAL(zv, &rv, 0, 0); return zv; } + str = zval_get_string(zv); + zval_ptr_dtor(zv); + switch (typ) { case PHP_PQ_OID_BOOL: if (!(res->auto_convert & PHP_PQRES_CONV_BOOL)) { goto noconversion; } - ZVAL_BOOL(zv, *val == 't'); + ZVAL_BOOL(zv, *str->val == 't'); break; case PHP_PQ_OID_INT8: @@ -145,7 +148,7 @@ zval *php_pqres_typed_zval(php_pqres_t *res, char *val, size_t len, Oid typ TSRM long lval; double dval; - switch (is_numeric_string(val, len, &lval, &dval, 0)) { + switch (is_numeric_str_function(str, &lval, &dval)) { case IS_LONG: ZVAL_LONG(zv, lval); break; @@ -163,35 +166,35 @@ zval *php_pqres_typed_zval(php_pqres_t *res, char *val, size_t len, Oid typ TSRM if (!(res->auto_convert & PHP_PQRES_CONV_FLOAT)) { goto noconversion; } - ZVAL_DOUBLE(zv, zend_strtod(val, NULL)); + ZVAL_DOUBLE(zv, zend_strtod(str->val, NULL)); break; case PHP_PQ_OID_DATE: if (!(res->auto_convert & PHP_PQRES_CONV_DATETIME)) { goto noconversion; } - php_pqdt_from_string(zv, NULL, val, len, "Y-m-d", NULL TSRMLS_CC); + php_pqdt_from_string(zv, NULL, str->val, str->len, "Y-m-d", NULL); break; case PHP_PQ_OID_ABSTIME: if (!(res->auto_convert & PHP_PQRES_CONV_DATETIME)) { goto noconversion; } - php_pqdt_from_string(zv, NULL, val, len, "Y-m-d H:i:s", NULL TSRMLS_CC); + php_pqdt_from_string(zv, NULL, str->val, str->len, "Y-m-d H:i:s", NULL); break; case PHP_PQ_OID_TIMESTAMP: if (!(res->auto_convert & PHP_PQRES_CONV_DATETIME)) { goto noconversion; } - php_pqdt_from_string(zv, NULL, val, len, "Y-m-d H:i:s.u", NULL TSRMLS_CC); + php_pqdt_from_string(zv, NULL, str->val, str->len, "Y-m-d H:i:s.u", NULL); break; case PHP_PQ_OID_TIMESTAMPTZ: if (!(res->auto_convert & PHP_PQRES_CONV_DATETIME)) { goto noconversion; } - php_pqdt_from_string(zv, NULL, val, len, "Y-m-d H:i:s.uO", NULL TSRMLS_CC); + php_pqdt_from_string(zv, NULL, str->val, str->len, "Y-m-d H:i:s.uO", NULL); break; #if PHP_PQ_HAVE_PHP_JSON_H && defined(PHP_PQ_OID_JSON) @@ -202,7 +205,7 @@ zval *php_pqres_typed_zval(php_pqres_t *res, char *val, size_t len, Oid typ TSRM if (!(res->auto_convert & PHP_PQRES_CONV_JSON)) { goto noconversion; } - php_json_decode_ex(zv, val, len, PHP_PQRES_JSON_OPTIONS(res), 512 /* PHP_JSON_DEFAULT_DEPTH */ TSRMLS_CC); + php_json_decode_ex(zv, str->val, str->len, PHP_PQRES_JSON_OPTIONS(res), 512 /* PHP_JSON_DEFAULT_DEPTH */); break; #endif @@ -210,33 +213,35 @@ zval *php_pqres_typed_zval(php_pqres_t *res, char *val, size_t len, Oid typ TSRM if (!(res->auto_convert & PHP_PQRES_CONV_ARRAY)) { goto noconversion; } - if (PHP_PQ_TYPE_IS_ARRAY(typ) && (Z_ARRVAL_P(zv) = php_pq_parse_array(res, val, len, PHP_PQ_TYPE_OF_ARRAY(typ) TSRMLS_CC))) { - Z_TYPE_P(zv) = IS_ARRAY; + if (PHP_PQ_TYPE_IS_ARRAY(typ) && (ht = php_pq_parse_array(res, str->val, str->len, PHP_PQ_TYPE_OF_ARRAY(typ)))) { + ZVAL_ARR(zv, ht); } else { - noconversion: - ZVAL_STRINGL(zv, val, len, 1); + goto noconversion; } break; } + zend_string_release(str); + return zv; + + noconversion: + ZVAL_STR(zv, str); return zv; } -static inline zval *php_pqres_get_col(php_pqres_t *r, unsigned row, unsigned col TSRMLS_DC) +static inline zval *php_pqres_get_col(php_pqres_t *r, unsigned row, unsigned col, zval *zv) { - zval *zv; - if (PQgetisnull(r->res, row, col)) { - MAKE_STD_ZVAL(zv); ZVAL_NULL(zv); } else { - zv = php_pqres_typed_zval(r, PQgetvalue(r->res, row, col), PQgetlength(r->res, row, col), PQftype(r->res, col) TSRMLS_CC); + ZVAL_STRINGL(zv, PQgetvalue(r->res, row, col), PQgetlength(r->res, row, col)); + zv = php_pqres_typed_zval(r, PQftype(r->res, col), zv); } return zv; } -static inline void php_pqres_add_col_to_zval(php_pqres_t *r, unsigned row, unsigned col, php_pqres_fetch_t fetch_type, zval *data TSRMLS_DC) +static inline void php_pqres_add_col_to_zval(php_pqres_t *r, unsigned row, unsigned col, php_pqres_fetch_t fetch_type, zval *data) { if (PQgetisnull(r->res, row, col)) { switch (fetch_type) { @@ -253,109 +258,91 @@ static inline void php_pqres_add_col_to_zval(php_pqres_t *r, unsigned row, unsig break; } } else { - zval *zv; + zval zv; - zv = php_pqres_typed_zval(r, PQgetvalue(r->res, row, col), PQgetlength(r->res, row, col), PQftype(r->res, col) TSRMLS_CC); + ZVAL_STRINGL(&zv, PQgetvalue(r->res, row, col), PQgetlength(r->res, row, col)); + php_pqres_typed_zval(r, PQftype(r->res, col), &zv); switch (fetch_type) { case PHP_PQRES_FETCH_OBJECT: - add_property_zval(data, PQfname(r->res, col), zv); + add_property_zval(data, PQfname(r->res, col), &zv); zval_ptr_dtor(&zv); break; case PHP_PQRES_FETCH_ASSOC: - add_assoc_zval(data, PQfname(r->res, col), zv); + add_assoc_zval(data, PQfname(r->res, col), &zv); break; case PHP_PQRES_FETCH_ARRAY: - add_index_zval(data, col, zv); + add_index_zval(data, col, &zv); break; } } } -zval *php_pqres_row_to_zval(PGresult *res, unsigned row, php_pqres_fetch_t fetch_type, zval **data_ptr TSRMLS_DC) +zval *php_pqres_row_to_zval(PGresult *res, unsigned row, php_pqres_fetch_t fetch_type, zval *data) { - zval *data = NULL; - int c, cols; + int c, cols = PQnfields(res); php_pqres_object_t *res_obj = PQresultInstanceData(res, php_pqconn_event); - if (data_ptr) { - data = *data_ptr; - } - if (!data) { - MAKE_STD_ZVAL(data); + if (Z_TYPE_P(data) != IS_OBJECT && Z_TYPE_P(data) != IS_ARRAY) { if (PHP_PQRES_FETCH_OBJECT == fetch_type) { object_init(data); } else { - array_init(data); - } - if (data_ptr) { - *data_ptr = data; + array_init_size(data, cols); } } if (PQntuples(res) > row) { - for (c = 0, cols = PQnfields(res); c < cols; ++c) { - php_pqres_add_col_to_zval(res_obj->intern, row, c, fetch_type, data TSRMLS_CC); + for (c = 0; c < cols; ++c) { + php_pqres_add_col_to_zval(res_obj->intern, row, c, fetch_type, data); } } return data; } -static void php_pqres_iterator_current(zend_object_iterator *i, zval ***data_ptr TSRMLS_DC) +static zval *php_pqres_iterator_current(zend_object_iterator *i) { php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i; - php_pqres_object_t *obj = i->data; + php_pqres_object_t *obj = PHP_PQ_OBJ(&i->data, NULL); - if (!iter->current_val) { - iter->current_val = php_pqres_row_to_zval(obj->intern->res, iter->index, iter->fetch_type, NULL TSRMLS_CC); + if (Z_ISUNDEF(iter->current_val)) { + php_pqres_row_to_zval(obj->intern->res, iter->index, iter->fetch_type, &iter->current_val); } - *data_ptr = &iter->current_val; + return &iter->current_val; } -#if PHP_VERSION_ID >= 50500 -static void php_pqres_iterator_key(zend_object_iterator *i, zval *key TSRMLS_DC) +static void php_pqres_iterator_key(zend_object_iterator *i, zval *key) { php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i; ZVAL_LONG(key, iter->index); } -#else -static int php_pqres_iterator_key(zend_object_iterator *i, char **key_str, uint *key_len, ulong *key_num TSRMLS_DC) -{ - php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i; - - *key_num = (ulong) iter->index; - - return HASH_KEY_IS_LONG; -} -#endif -static void php_pqres_iterator_invalidate(zend_object_iterator *i TSRMLS_DC) +static void php_pqres_iterator_invalidate(zend_object_iterator *i) { php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i; - if (iter->current_val) { + if (!Z_ISUNDEF(iter->current_val)) { zval_ptr_dtor(&iter->current_val); - iter->current_val = NULL; + ZVAL_UNDEF(&iter->current_val); } } -static void php_pqres_iterator_next(zend_object_iterator *i TSRMLS_DC) +static void php_pqres_iterator_next(zend_object_iterator *i) { php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i; - php_pqres_iterator_invalidate(i TSRMLS_CC); + php_pqres_iterator_invalidate(i); ++iter->index; } -static void php_pqres_iterator_rewind(zend_object_iterator *i TSRMLS_DC) +static void php_pqres_iterator_rewind(zend_object_iterator *i) { php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i; - php_pqres_iterator_invalidate(i TSRMLS_CC); + php_pqres_iterator_invalidate(i); iter->index = 0; } @@ -375,9 +362,9 @@ static zend_object_iterator_funcs php_pqres_iterator_funcs = { php_pqres_iterator_invalidate }; -static int php_pqres_count_elements(zval *object, long *count TSRMLS_DC) +static ZEND_RESULT_CODE php_pqres_count_elements(zval *object, long *count) { - php_pqres_object_t *obj = zend_object_store_get_object(object TSRMLS_CC); + php_pqres_object_t *obj = PHP_PQ_OBJ(object, NULL); if (!obj->intern) { return FAILURE; @@ -389,39 +376,37 @@ static int php_pqres_count_elements(zval *object, long *count TSRMLS_DC) ZEND_RESULT_CODE php_pqres_success(PGresult *res TSRMLS_DC) { - zval *zexc; + zval zexc; switch (PQresultStatus(res)) { case PGRES_BAD_RESPONSE: case PGRES_NONFATAL_ERROR: case PGRES_FATAL_ERROR: - zexc = throw_exce(EX_SQL TSRMLS_CC, "%s", PHP_PQresultErrorMessage(res)); - zend_update_property_string(Z_OBJCE_P(zexc), zexc, ZEND_STRL("sqlstate"), PQresultErrorField(res, PG_DIAG_SQLSTATE) TSRMLS_CC); + ZVAL_OBJ(&zexc, throw_exce(EX_SQL, "%s", PHP_PQresultErrorMessage(res))); + zend_update_property_string(Z_OBJCE(zexc), &zexc, ZEND_STRL("sqlstate"), PQresultErrorField(res, PG_DIAG_SQLSTATE)); return FAILURE; default: return SUCCESS; } } -void php_pqres_init_instance_data(PGresult *res, php_pqconn_object_t *conn_obj, php_pqres_object_t **ptr TSRMLS_DC) +php_pqres_object_t *php_pqres_init_instance_data(PGresult *res, php_pqconn_object_t *conn_obj) { php_pqres_object_t *obj; php_pqres_t *r = ecalloc(1, sizeof(*r)); r->res = res; zend_hash_init(&r->bound, 0, 0, ZVAL_PTR_DTOR, 0); - zend_hash_init(&r->converters, 0, 0, ZVAL_PTR_DTOR, 0); - zend_hash_copy(&r->converters, &conn_obj->intern->converters, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *)); + zend_hash_init(&r->converters, zend_hash_num_elements(&conn_obj->intern->converters), 0, ZVAL_PTR_DTOR, 0); + zend_hash_copy(&r->converters, &conn_obj->intern->converters, (copy_ctor_func_t) zval_add_ref); r->auto_convert = conn_obj->intern->default_auto_convert; r->default_fetch_type = conn_obj->intern->default_fetch_type; - php_pqres_create_object_ex(php_pqres_class_entry, r, &obj TSRMLS_CC); + obj = php_pqres_create_object_ex(php_pqres_class_entry, r); PQresultSetInstanceData(res, php_pqconn_event, obj); - if (ptr) { - *ptr = obj; - } + return obj; } php_pqres_fetch_t php_pqres_fetch_type(php_pqres_t *res) @@ -429,12 +414,10 @@ php_pqres_fetch_t php_pqres_fetch_type(php_pqres_t *res) return res->iter ? res->iter->fetch_type : res->default_fetch_type; } -static void php_pqres_object_free(void *o TSRMLS_DC) +static void php_pqres_object_free(zend_object *o) { - php_pqres_object_t *obj = o; -#if DBG_GC - fprintf(stderr, "FREE res(#%d) %p\n", obj->zv.handle, obj); -#endif + php_pqres_object_t *obj = PHP_PQ_OBJ(NULL, o); + if (obj->intern) { if (obj->intern->res) { PQresultSetInstanceData(obj->intern->res, php_pqconn_event, NULL); @@ -443,7 +426,8 @@ static void php_pqres_object_free(void *o TSRMLS_DC) } if (obj->intern->iter) { - php_pqres_iterator_dtor((zend_object_iterator *) obj->intern->iter TSRMLS_CC); + ZVAL_NULL(&obj->intern->iter->zi.data); + php_pqres_iterator_dtor((zend_object_iterator *) obj->intern->iter); obj->intern->iter = NULL; } @@ -453,170 +437,117 @@ static void php_pqres_object_free(void *o TSRMLS_DC) efree(obj->intern); obj->intern = NULL; } - zend_object_std_dtor((zend_object *) o TSRMLS_CC); - efree(obj); + php_pq_object_dtor(o); } -zend_object_value php_pqres_create_object_ex(zend_class_entry *ce, php_pqres_t *intern, php_pqres_object_t **ptr TSRMLS_DC) +php_pqres_object_t *php_pqres_create_object_ex(zend_class_entry *ce, php_pqres_t *intern) { - php_pqres_object_t *o; - - o = ecalloc(1, sizeof(*o)); - zend_object_std_init((zend_object *) o, ce TSRMLS_CC); - object_properties_init((zend_object *) o, ce); - o->prophandler = &php_pqres_object_prophandlers; - - if (ptr) { - *ptr = o; - } - - if (intern) { - o->intern = intern; - } - - o->zv.handle = zend_objects_store_put((zend_object *) o, NULL, php_pqres_object_free, NULL TSRMLS_CC); - o->zv.handlers = &php_pqres_object_handlers; - - return o->zv; + return php_pq_object_create(ce, intern, sizeof(php_pqres_object_t), + &php_pqres_object_handlers, &php_pqres_object_prophandlers); } -static zend_object_value php_pqres_create_object(zend_class_entry *class_type TSRMLS_DC) +static zend_object *php_pqres_create_object(zend_class_entry *class_type) { - return php_pqres_create_object_ex(class_type, NULL, NULL TSRMLS_CC); + return &php_pqres_create_object_ex(class_type, NULL)->zo; } -static void php_pqres_object_read_status(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqres_object_read_status(zval *object, void *o, zval *return_value) { php_pqres_object_t *obj = o; RETVAL_LONG(PQresultStatus(obj->intern->res)); } -static void php_pqres_object_read_status_message(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqres_object_read_status_message(zval *object, void *o, zval *return_value) { php_pqres_object_t *obj = o; - RETVAL_STRING(PQresStatus(PQresultStatus(obj->intern->res))+sizeof("PGRES"), 1); + RETVAL_STRING(PQresStatus(PQresultStatus(obj->intern->res))+sizeof("PGRES")); } -static void php_pqres_object_read_error_message(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqres_object_read_error_message(zval *object, void *o, zval *return_value) { php_pqres_object_t *obj = o; char *error = PHP_PQresultErrorMessage(obj->intern->res); if (error) { - RETVAL_STRING(error, 1); + RETVAL_STRING(error); } else { RETVAL_NULL(); } } -static void php_pqres_object_read_num_rows(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqres_object_read_num_rows(zval *object, void *o, zval *return_value) { php_pqres_object_t *obj = o; RETVAL_LONG(PQntuples(obj->intern->res)); } -static void php_pqres_object_read_num_cols(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqres_object_read_num_cols(zval *object, void *o, zval *return_value) { php_pqres_object_t *obj = o; RETVAL_LONG(PQnfields(obj->intern->res)); } -static void php_pqres_object_read_affected_rows(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqres_object_read_affected_rows(zval *object, void *o, zval *return_value) { php_pqres_object_t *obj = o; RETVAL_LONG(atoi(PQcmdTuples(obj->intern->res))); } -static void php_pqres_object_read_fetch_type(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqres_object_read_fetch_type(zval *object, void *o, zval *return_value) { php_pqres_object_t *obj = o; RETVAL_LONG(php_pqres_fetch_type(obj->intern)); } -static void php_pqres_object_write_fetch_type(zval *object, void *o, zval *value TSRMLS_DC) +static void php_pqres_object_write_fetch_type(zval *object, void *o, zval *value) { php_pqres_object_t *obj = o; - zval *zfetch_type = value; - - if (Z_TYPE_P(value) != IS_LONG) { - if (Z_REFCOUNT_P(value) > 1) { - zval *tmp; - MAKE_STD_ZVAL(tmp); - ZVAL_ZVAL(tmp, zfetch_type, 1, 0); - convert_to_long(tmp); - zfetch_type = tmp; - } else { - convert_to_long_ex(&zfetch_type); - } - } if (!obj->intern->iter) { - obj->intern->iter = (php_pqres_iterator_t *) php_pqres_iterator_init(Z_OBJCE_P(object), object, 0 TSRMLS_CC); - obj->intern->iter->zi.funcs->rewind((zend_object_iterator *) obj->intern->iter TSRMLS_CC); - } - obj->intern->iter->fetch_type = Z_LVAL_P(zfetch_type); - - if (zfetch_type != value) { - zval_ptr_dtor(&zfetch_type); + php_pqres_internal_iterator_init(object); } + obj->intern->iter->fetch_type = zval_get_long(value); } -static void php_pqres_object_read_auto_conv(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqres_object_read_auto_conv(zval *object, void *o, zval *return_value) { php_pqres_object_t *obj = o; RETVAL_LONG(obj->intern->auto_convert); } -static void php_pqres_object_write_auto_conv(zval *object, void *o, zval *value TSRMLS_DC) +static void php_pqres_object_write_auto_conv(zval *object, void *o, zval *value) { php_pqres_object_t *obj = o; - zval *zauto_conv = value; - - if (Z_TYPE_P(value) != IS_LONG) { - if (Z_REFCOUNT_P(value) > 1) { - zval *tmp; - MAKE_STD_ZVAL(tmp); - ZVAL_ZVAL(tmp, zauto_conv, 1, 0); - convert_to_long(tmp); - zauto_conv = tmp; - } else { - convert_to_long_ex(&zauto_conv); - } - } - - obj->intern->auto_convert = Z_LVAL_P(zauto_conv); - if (zauto_conv != value) { - zval_ptr_dtor(&zauto_conv); - } + obj->intern->auto_convert = zval_get_long(value); } -static ZEND_RESULT_CODE php_pqres_iteration(zval *this_ptr, php_pqres_object_t *obj, php_pqres_fetch_t fetch_type, zval ***row TSRMLS_DC) +static ZEND_RESULT_CODE php_pqres_iteration(zval *zobj, php_pqres_object_t *obj, php_pqres_fetch_t fetch_type, zval *row TSRMLS_DC) { ZEND_RESULT_CODE rv; php_pqres_fetch_t orig_fetch; if (!obj) { - obj = zend_object_store_get_object(getThis() TSRMLS_CC); + obj = PHP_PQ_OBJ(zobj, NULL); } if (obj->intern->iter) { - obj->intern->iter->zi.funcs->move_forward((zend_object_iterator *) obj->intern->iter TSRMLS_CC); + obj->intern->iter->zi.funcs->move_forward((zend_object_iterator *) obj->intern->iter); } else { - obj->intern->iter = (php_pqres_iterator_t *) php_pqres_iterator_init(Z_OBJCE_P(getThis()), getThis(), 0 TSRMLS_CC); - obj->intern->iter->zi.funcs->rewind((zend_object_iterator *) obj->intern->iter TSRMLS_CC); + php_pqres_internal_iterator_init(zobj); } orig_fetch = obj->intern->iter->fetch_type; obj->intern->iter->fetch_type = fetch_type; - if (SUCCESS == (rv = obj->intern->iter->zi.funcs->valid((zend_object_iterator *) obj->intern->iter TSRMLS_CC))) { - obj->intern->iter->zi.funcs->get_current_data((zend_object_iterator *) obj->intern->iter, row TSRMLS_CC); + if (SUCCESS == (rv = obj->intern->iter->zi.funcs->valid((zend_object_iterator *) obj->intern->iter))) { + zval *tmp = obj->intern->iter->zi.funcs->get_current_data((zend_object_iterator *) obj->intern->iter); + ZVAL_COPY_VALUE(row, tmp); } obj->intern->iter->fetch_type = orig_fetch; @@ -628,7 +559,7 @@ typedef struct php_pqres_col { int num; } php_pqres_col_t; -static ZEND_RESULT_CODE column_nn(php_pqres_object_t *obj, zval *zcol, php_pqres_col_t *col TSRMLS_DC) +static ZEND_RESULT_CODE column_nn(php_pqres_object_t *obj, zval *zcol, php_pqres_col_t *col) { long index = -1; char *name = NULL; @@ -666,11 +597,11 @@ static ZEND_RESULT_CODE column_nn(php_pqres_object_t *obj, zval *zcol, php_pqres } if (!col->name) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to find column at index %ld", index); + php_error_docref(NULL, E_WARNING, "Failed to find column at index %ld", index); return FAILURE; } if (col->num == -1) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to find column with name '%s'", name); + php_error_docref(NULL, E_WARNING, "Failed to find column with name '%s'", name); return FAILURE; } return SUCCESS; @@ -685,28 +616,28 @@ static PHP_METHOD(pqres, bind) { zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z/z", &zcol, &zref); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "z/z", &zcol, &zref); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqres_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqres_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Result not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Result not initialized"); } else { php_pqres_col_t col; - if (SUCCESS != column_nn(obj, zcol, &col TSRMLS_CC)) { + if (SUCCESS != column_nn(obj, zcol, &col)) { RETVAL_FALSE; } else { - Z_ADDREF_P(zref); + Z_TRY_ADDREF_P(zref); - if (SUCCESS != zend_hash_index_update(&obj->intern->bound, col.num, (void *) &zref, sizeof(zval *), NULL)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to bind column %s@%d", col.name, col.num); + if (!zend_hash_index_update(&obj->intern->bound, col.num, zref)) { + php_error_docref(NULL, E_WARNING, "Failed to bind column %s@%d", col.name, col.num); RETVAL_FALSE; } else { - zend_hash_sort(&obj->intern->bound, zend_qsort, php_pq_compare_index, 0 TSRMLS_CC); + zend_hash_sort(&obj->intern->bound, php_pq_compare_index, 0); RETVAL_TRUE; } } @@ -714,23 +645,20 @@ static PHP_METHOD(pqres, bind) { } } -static int apply_bound(void *p TSRMLS_DC, int argc, va_list argv, zend_hash_key *key) +static int apply_bound(zval *zbound, int argc, va_list argv, zend_hash_key *key) { - zval **zvalue, **zbound = p; - zval **zrow = va_arg(argv, zval **); + zval *zvalue; + zval *zrow = va_arg(argv, zval *); ZEND_RESULT_CODE *rv = va_arg(argv, ZEND_RESULT_CODE *); - if (SUCCESS != zend_hash_index_find(Z_ARRVAL_PP(zrow), key->h, (void *) &zvalue)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to find column ad index %lu", key->h); + if (!(zvalue = zend_hash_index_find(Z_ARRVAL_P(zrow), key->h))) { + php_error_docref(NULL, E_WARNING, "Failed to find column ad index %lu", key->h); *rv = FAILURE; return ZEND_HASH_APPLY_STOP; } else { - zval_dtor(*zbound); - ZVAL_COPY_VALUE(*zbound, *zvalue); - ZVAL_NULL(*zvalue); - zval_ptr_dtor(zvalue); - Z_ADDREF_P(*zbound); - *zvalue = *zbound; + ZVAL_DEREF(zbound); + zval_dtor(zbound); + ZVAL_COPY(zbound, zvalue); *rv = SUCCESS; return ZEND_HASH_APPLY_KEEP; } @@ -742,29 +670,27 @@ static PHP_METHOD(pqres, fetchBound) { zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); rv = zend_parse_parameters_none(); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqres_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqres_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Result not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Result not initialized"); } else { - zval **row = NULL; + zval row; - if (SUCCESS == php_pqres_iteration(getThis(), obj, PHP_PQRES_FETCH_ARRAY, &row TSRMLS_CC) && row) { - zend_replace_error_handling(EH_THROW, exce(EX_RUNTIME), &zeh TSRMLS_CC); - zend_hash_apply_with_arguments(&obj->intern->bound TSRMLS_CC, apply_bound, 2, row, &rv); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_RUNTIME), &zeh); + if (SUCCESS == php_pqres_iteration(getThis(), obj, PHP_PQRES_FETCH_ARRAY, &row)) { + zend_hash_apply_with_arguments(&obj->intern->bound, apply_bound, 2, &row, &rv); - if (SUCCESS != rv) { - zval_ptr_dtor(row); - } else { - RETVAL_ZVAL(*row, 1, 0); + if (SUCCESS == rv) { + RETVAL_ZVAL(&row, 1, 0); } } + zend_restore_error_handling(&zeh); } } } @@ -774,49 +700,47 @@ ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_row, 0, 0, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(pqres, fetchRow) { zend_error_handling zeh; - php_pqres_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); - long fetch_type = -1; + php_pqres_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); + zend_long fetch_type = -1; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &fetch_type); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &fetch_type); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Result not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Result not initialized"); } else { - zval **row = NULL; + zval row; if (fetch_type == -1) { fetch_type = php_pqres_fetch_type(obj->intern); } - zend_replace_error_handling(EH_THROW, exce(EX_RUNTIME), &zeh TSRMLS_CC); - php_pqres_iteration(getThis(), obj, fetch_type, &row TSRMLS_CC); - zend_restore_error_handling(&zeh TSRMLS_CC); - - if (row) { - RETVAL_ZVAL(*row, 1, 0); + zend_replace_error_handling(EH_THROW, exce(EX_RUNTIME), &zeh); + if (SUCCESS == php_pqres_iteration(getThis(), obj, fetch_type, &row)) { + RETVAL_ZVAL(&row, 1, 0); } + zend_restore_error_handling(&zeh); } } } -static zval **column_at(zval *row, int col TSRMLS_DC) +static zval *column_at(zval *row, int col) { - zval **data = NULL; + zval *data = NULL; HashTable *ht = HASH_OF(row); int count = zend_hash_num_elements(ht); if (col >= count) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Column index %d exceeds column count %d", col, count); + php_error_docref(NULL, E_WARNING, "Column index %d exceeds column count %d", col, count); } else { zend_hash_internal_pointer_reset(ht); while (col-- > 0) { zend_hash_move_forward(ht); } - zend_hash_get_current_data(ht, (void *) &data); + data = zend_hash_get_current_data(ht); } return data; } @@ -830,38 +754,38 @@ static PHP_METHOD(pqres, fetchCol) { zval *zcol = NULL, *zref; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|z/!", &zref, &zcol); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "z|z/!", &zref, &zcol); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqres_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqres_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Result not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Result not initialized"); } else { - zval **row = NULL; + zval row; - zend_replace_error_handling(EH_THROW, exce(EX_RUNTIME), &zeh TSRMLS_CC); - php_pqres_iteration(getThis(), obj, php_pqres_fetch_type(obj->intern), &row TSRMLS_CC); - if (row) { + zend_replace_error_handling(EH_THROW, exce(EX_RUNTIME), &zeh); + if (SUCCESS == php_pqres_iteration(getThis(), obj, php_pqres_fetch_type(obj->intern), &row)) { php_pqres_col_t col; - if (SUCCESS != column_nn(obj, zcol, &col TSRMLS_CC)) { + if (SUCCESS != column_nn(obj, zcol, &col)) { RETVAL_FALSE; } else { - zval **zres = column_at(*row, col.num TSRMLS_CC); + zval *zres = column_at(&row, col.num); if (!zres) { RETVAL_FALSE; } else { + ZVAL_DEREF(zref); zval_dtor(zref); - ZVAL_ZVAL(zref, *zres, 1, 0); + ZVAL_ZVAL(zref, zres, 1, 0); RETVAL_TRUE; } } } - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); } } } @@ -874,28 +798,29 @@ static PHP_METHOD(pqres, fetchAllCols) { zval *zcol = NULL; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z!", &zcol); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "|z!", &zcol); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqres_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqres_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Result not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Result not initialized"); } else { php_pqres_col_t col; - zend_replace_error_handling(EH_THROW, exce(EX_RUNTIME), &zeh TSRMLS_CC); - if (SUCCESS == column_nn(obj, zcol, &col TSRMLS_CC)) { + zend_replace_error_handling(EH_THROW, exce(EX_RUNTIME), &zeh); + if (SUCCESS == column_nn(obj, zcol, &col)) { int r, rows = PQntuples(obj->intern->res); + zval tmp; array_init(return_value); for (r = 0; r < rows; ++r) { - add_next_index_zval(return_value, php_pqres_get_col(obj->intern, r, col.num TSRMLS_CC)); + add_next_index_zval(return_value, php_pqres_get_col(obj->intern, r, col.num, &tmp)); } } - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); } } } @@ -906,12 +831,11 @@ struct apply_to_col_arg { ZEND_RESULT_CODE status; }; -static int apply_to_col(void *p, void *a TSRMLS_DC) +static int apply_to_col(zval *c, void *a) { - zval **c = p; struct apply_to_col_arg *arg = a; - if (SUCCESS != column_nn(arg->obj, *c, arg->cols TSRMLS_CC)) { + if (SUCCESS != column_nn(arg->obj, c, arg->cols)) { arg->status = FAILURE; return ZEND_HASH_APPLY_STOP; } else { @@ -921,7 +845,7 @@ static int apply_to_col(void *p, void *a TSRMLS_DC) } } -static php_pqres_col_t *php_pqres_convert_to_cols(php_pqres_object_t *obj, HashTable *ht TSRMLS_DC) +static php_pqres_col_t *php_pqres_convert_to_cols(php_pqres_object_t *obj, HashTable *ht) { struct apply_to_col_arg arg = {NULL}; php_pqres_col_t *tmp; @@ -929,7 +853,7 @@ static php_pqres_col_t *php_pqres_convert_to_cols(php_pqres_object_t *obj, HashT arg.obj = obj; arg.cols = ecalloc(zend_hash_num_elements(ht), sizeof(*tmp)); tmp = arg.cols; - zend_hash_apply_with_argument(ht, apply_to_col, &arg TSRMLS_CC); + zend_hash_apply_with_argument(ht, apply_to_col, &arg); if (SUCCESS == arg.status) { return tmp; @@ -947,18 +871,18 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(pqres, map) { zend_error_handling zeh; zval *zkeys = 0, *zvals = 0; - long fetch_type = -1; + zend_long fetch_type = -1; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z/!z/!l", &zkeys, &zvals, &fetch_type); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "|z/!z/!l", &zkeys, &zvals, &fetch_type); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqres_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqres_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Result not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Result not initialized"); } else { int ks = 0, vs = 0; php_pqres_col_t def = {PQfname(obj->intern->res, 0), 0}, *keys = NULL, *vals = NULL; @@ -967,7 +891,7 @@ static PHP_METHOD(pqres, map) { convert_to_array(zkeys); if ((ks = zend_hash_num_elements(Z_ARRVAL_P(zkeys)))) { - keys = php_pqres_convert_to_cols(obj, Z_ARRVAL_P(zkeys) TSRMLS_CC); + keys = php_pqres_convert_to_cols(obj, Z_ARRVAL_P(zkeys)); } else { ks = 1; keys = &def; @@ -980,7 +904,7 @@ static PHP_METHOD(pqres, map) { convert_to_array(zvals); if ((vs = zend_hash_num_elements(Z_ARRVAL_P(zvals)))) { - vals = php_pqres_convert_to_cols(obj, Z_ARRVAL_P(zvals) TSRMLS_CC); + vals = php_pqres_convert_to_cols(obj, Z_ARRVAL_P(zvals)); } } @@ -990,7 +914,7 @@ static PHP_METHOD(pqres, map) { if (keys) { int rows, r; - zval **cur; + zval *cur; switch (fetch_type) { case PHP_PQRES_FETCH_ARRAY: @@ -1003,30 +927,32 @@ static PHP_METHOD(pqres, map) { } for (r = 0, rows = PQntuples(obj->intern->res); r < rows; ++r) { int k, v; + zval *ptr; - cur = &return_value; + cur = return_value; for (k = 0; k < ks; ++k) { char *key = PQgetvalue(obj->intern->res, r, keys[k].num); int len = PQgetlength(obj->intern->res, r, keys[k].num); - if (SUCCESS != zend_symtable_find(HASH_OF(*cur), key, len + 1, (void *) &cur)) { - zval *tmp; + if (!(ptr = zend_symtable_str_find(HASH_OF(cur), key, len))) { + zval tmp; - MAKE_STD_ZVAL(tmp); switch (fetch_type) { case PHP_PQRES_FETCH_ARRAY: case PHP_PQRES_FETCH_ASSOC: - array_init(tmp); + array_init(&tmp); break; case PHP_PQRES_FETCH_OBJECT: - object_init(tmp); + object_init(&tmp); break; } - if (SUCCESS != zend_symtable_update(HASH_OF(*cur), key, len + 1, (void *) &tmp, sizeof(zval *), (void *) &cur)) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to create map"); + if (!(ptr = zend_symtable_str_update(HASH_OF(cur), key, len, &tmp))) { + throw_exce(EX_RUNTIME, "Failed to create map"); goto err; } + cur = ptr; } + cur = ptr; } if (vals && vs) { for (v = 0; v < vs; ++v) { @@ -1035,18 +961,18 @@ static PHP_METHOD(pqres, map) { switch (fetch_type) { case PHP_PQRES_FETCH_ARRAY: - add_index_stringl(*cur, vals[v].num, val, len, 1); + add_index_stringl(cur, vals[v].num, val, len); break; case PHP_PQRES_FETCH_ASSOC: - add_assoc_stringl(*cur, vals[v].name, val, len, 1); + add_assoc_stringl(cur, vals[v].name, val, len); break; case PHP_PQRES_FETCH_OBJECT: - add_property_stringl(*cur, vals[v].name, val, len, 1); + add_property_stringl(cur, vals[v].name, val, len); break; } } } else { - php_pqres_row_to_zval(obj->intern->res, r, fetch_type, cur TSRMLS_CC); + php_pqres_row_to_zval(obj->intern->res, r, fetch_type, cur); } } } @@ -1067,19 +993,21 @@ ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_all, 0, 0, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(pqres, fetchAll) { zend_error_handling zeh; - long fetch_type = -1; + zend_long fetch_type = -1; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &fetch_type); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &fetch_type); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqres_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqres_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); + if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Result not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Result not initialized"); } else { int r, rows = PQntuples(obj->intern->res); + zval tmp; if (fetch_type == -1) { fetch_type = php_pqres_fetch_type(obj->intern); @@ -1087,7 +1015,8 @@ static PHP_METHOD(pqres, fetchAll) { array_init(return_value); for (r = 0; r < rows; ++r) { - add_next_index_zval(return_value, php_pqres_row_to_zval(obj->intern->res, r, fetch_type, NULL TSRMLS_CC)); + ZVAL_NULL(&tmp); + add_next_index_zval(return_value, php_pqres_row_to_zval(obj->intern->res, r, fetch_type, &tmp)); } } } @@ -1099,15 +1028,15 @@ static PHP_METHOD(pqres, count) { zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); rv = zend_parse_parameters_none(); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { long count; - if (SUCCESS != php_pqres_count_elements(getThis(), &count TSRMLS_CC)) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Result not initialized"); + if (SUCCESS != php_pqres_count_elements(getThis(), &count)) { + throw_exce(EX_UNINITIALIZED, "pq\\Result not initialized"); } else { RETVAL_LONG(count); } @@ -1120,15 +1049,15 @@ static PHP_METHOD(pqres, desc) { zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); rv = zend_parse_parameters_none(); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqres_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqres_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Result not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Result not initialized"); } else { int p, params; @@ -1165,89 +1094,90 @@ PHP_MINIT_FUNCTION(pqres) php_pq_object_prophandler_t ph = {0}; INIT_NS_CLASS_ENTRY(ce, "pq", "Result", php_pqres_methods); - php_pqres_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC); + php_pqres_class_entry = zend_register_internal_class_ex(&ce, NULL); php_pqres_class_entry->create_object = php_pqres_create_object; - php_pqres_class_entry->iterator_funcs.funcs = &php_pqres_iterator_funcs; php_pqres_class_entry->get_iterator = php_pqres_iterator_init; - zend_class_implements(php_pqres_class_entry TSRMLS_CC, 2, zend_ce_traversable, spl_ce_Countable); + zend_class_implements(php_pqres_class_entry, 2, zend_ce_traversable, spl_ce_Countable); memcpy(&php_pqres_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + php_pqres_object_handlers.offset = XtOffsetOf(php_pqres_object_t, zo); + php_pqres_object_handlers.free_obj = php_pqres_object_free; php_pqres_object_handlers.read_property = php_pq_object_read_prop; php_pqres_object_handlers.write_property = php_pq_object_write_prop; php_pqres_object_handlers.clone_obj = NULL; php_pqres_object_handlers.get_property_ptr_ptr = NULL; - php_pqres_object_handlers.get_gc = NULL; + php_pqres_object_handlers.get_gc = php_pq_object_get_gc; php_pqres_object_handlers.get_debug_info = php_pq_object_debug_info; php_pqres_object_handlers.get_properties = php_pq_object_properties; php_pqres_object_handlers.count_elements = php_pqres_count_elements; - zend_hash_init(&php_pqres_object_prophandlers, 8, NULL, NULL, 1); + zend_hash_init(&php_pqres_object_prophandlers, 8, NULL, php_pq_object_prophandler_dtor, 1); - zend_declare_property_null(php_pqres_class_entry, ZEND_STRL("status"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqres_class_entry, ZEND_STRL("status"), ZEND_ACC_PUBLIC); ph.read = php_pqres_object_read_status; - zend_hash_add(&php_pqres_object_prophandlers, "status", sizeof("status"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqres_object_prophandlers, "status", sizeof("status")-1, (void *) &ph, sizeof(ph)); - zend_declare_property_null(php_pqres_class_entry, ZEND_STRL("statusMessage"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqres_class_entry, ZEND_STRL("statusMessage"), ZEND_ACC_PUBLIC); ph.read = php_pqres_object_read_status_message; - zend_hash_add(&php_pqres_object_prophandlers, "statusMessage", sizeof("statusMessage"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqres_object_prophandlers, "statusMessage", sizeof("statusMessage")-1, (void *) &ph, sizeof(ph)); - zend_declare_property_null(php_pqres_class_entry, ZEND_STRL("errorMessage"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqres_class_entry, ZEND_STRL("errorMessage"), ZEND_ACC_PUBLIC); ph.read = php_pqres_object_read_error_message; - zend_hash_add(&php_pqres_object_prophandlers, "errorMessage", sizeof("errorMessage"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqres_object_prophandlers, "errorMessage", sizeof("errorMessage")-1, (void *) &ph, sizeof(ph)); - zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("numRows"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("numRows"), 0, ZEND_ACC_PUBLIC); ph.read = php_pqres_object_read_num_rows; - zend_hash_add(&php_pqres_object_prophandlers, "numRows", sizeof("numRows"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqres_object_prophandlers, "numRows", sizeof("numRows")-1, (void *) &ph, sizeof(ph)); - zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("numCols"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("numCols"), 0, ZEND_ACC_PUBLIC); ph.read = php_pqres_object_read_num_cols; - zend_hash_add(&php_pqres_object_prophandlers, "numCols", sizeof("numCols"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqres_object_prophandlers, "numCols", sizeof("numCols")-1, (void *) &ph, sizeof(ph)); - zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("affectedRows"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("affectedRows"), 0, ZEND_ACC_PUBLIC); ph.read = php_pqres_object_read_affected_rows; - zend_hash_add(&php_pqres_object_prophandlers, "affectedRows", sizeof("affectedRows"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqres_object_prophandlers, "affectedRows", sizeof("affectedRows")-1, (void *) &ph, sizeof(ph)); - zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("fetchType"), PHP_PQRES_FETCH_ARRAY, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("fetchType"), PHP_PQRES_FETCH_ARRAY, ZEND_ACC_PUBLIC); ph.read = php_pqres_object_read_fetch_type; ph.write = php_pqres_object_write_fetch_type; - zend_hash_add(&php_pqres_object_prophandlers, "fetchType", sizeof("fetchType"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqres_object_prophandlers, "fetchType", sizeof("fetchType")-1, (void *) &ph, sizeof(ph)); ph.write = NULL; - zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("autoConvert"), PHP_PQRES_CONV_ALL, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("autoConvert"), PHP_PQRES_CONV_ALL, ZEND_ACC_PUBLIC); ph.read = php_pqres_object_read_auto_conv; ph.write = php_pqres_object_write_auto_conv; - zend_hash_add(&php_pqres_object_prophandlers, "autoConvert", sizeof("autoConvert"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqres_object_prophandlers, "autoConvert", sizeof("autoConvert")-1, (void *) &ph, sizeof(ph)); ph.write = NULL; - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("EMPTY_QUERY"), PGRES_EMPTY_QUERY TSRMLS_CC); - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("COMMAND_OK"), PGRES_COMMAND_OK TSRMLS_CC); - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("TUPLES_OK"), PGRES_TUPLES_OK TSRMLS_CC); - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("COPY_OUT"), PGRES_COPY_OUT TSRMLS_CC); - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("COPY_IN"), PGRES_COPY_IN TSRMLS_CC); - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("BAD_RESPONSE"), PGRES_BAD_RESPONSE TSRMLS_CC); - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("NONFATAL_ERROR"), PGRES_NONFATAL_ERROR TSRMLS_CC); - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("FATAL_ERROR"), PGRES_FATAL_ERROR TSRMLS_CC); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("EMPTY_QUERY"), PGRES_EMPTY_QUERY); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("COMMAND_OK"), PGRES_COMMAND_OK); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("TUPLES_OK"), PGRES_TUPLES_OK); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("COPY_OUT"), PGRES_COPY_OUT); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("COPY_IN"), PGRES_COPY_IN); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("BAD_RESPONSE"), PGRES_BAD_RESPONSE); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("NONFATAL_ERROR"), PGRES_NONFATAL_ERROR); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("FATAL_ERROR"), PGRES_FATAL_ERROR); #ifdef HAVE_PGRES_COPY_BOTH - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("COPY_BOTH"), PGRES_COPY_BOTH TSRMLS_CC); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("COPY_BOTH"), PGRES_COPY_BOTH); #endif #ifdef HAVE_PGRES_SINGLE_TUPLE - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("SINGLE_TUPLE"), PGRES_SINGLE_TUPLE TSRMLS_CC); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("SINGLE_TUPLE"), PGRES_SINGLE_TUPLE); #endif - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("FETCH_ARRAY"), PHP_PQRES_FETCH_ARRAY TSRMLS_CC); - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("FETCH_ASSOC"), PHP_PQRES_FETCH_ASSOC TSRMLS_CC); - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("FETCH_OBJECT"), PHP_PQRES_FETCH_OBJECT TSRMLS_CC); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("FETCH_ARRAY"), PHP_PQRES_FETCH_ARRAY); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("FETCH_ASSOC"), PHP_PQRES_FETCH_ASSOC); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("FETCH_OBJECT"), PHP_PQRES_FETCH_OBJECT); - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_BOOL"), PHP_PQRES_CONV_BOOL TSRMLS_CC); - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_INT"), PHP_PQRES_CONV_INT TSRMLS_CC); - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_FLOAT"), PHP_PQRES_CONV_FLOAT TSRMLS_CC); - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_SCALAR"), PHP_PQRES_CONV_SCALAR TSRMLS_CC); - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_ARRAY"), PHP_PQRES_CONV_ARRAY TSRMLS_CC); - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_DATETIME"), PHP_PQRES_CONV_DATETIME TSRMLS_CC); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_BOOL"), PHP_PQRES_CONV_BOOL); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_INT"), PHP_PQRES_CONV_INT); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_FLOAT"), PHP_PQRES_CONV_FLOAT); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_SCALAR"), PHP_PQRES_CONV_SCALAR); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_ARRAY"), PHP_PQRES_CONV_ARRAY); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_DATETIME"), PHP_PQRES_CONV_DATETIME); #if PHP_PQ_HAVE_PHP_JSON_H - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_JSON"), PHP_PQRES_CONV_JSON TSRMLS_CC); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_JSON"), PHP_PQRES_CONV_JSON); #endif - zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_ALL"), PHP_PQRES_CONV_ALL TSRMLS_CC); + zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_ALL"), PHP_PQRES_CONV_ALL); return SUCCESS; } diff --git a/src/php_pqres.h b/src/php_pqres.h index f5f80bf..acc03cc 100644 --- a/src/php_pqres.h +++ b/src/php_pqres.h @@ -33,7 +33,7 @@ typedef enum php_pqres_fetch { typedef struct php_pqres_iterator { zend_object_iterator zi; - zval *current_val; + zval current_val; unsigned index; php_pqres_fetch_t fetch_type; } php_pqres_iterator_t; @@ -48,16 +48,13 @@ typedef struct php_pqres { } php_pqres_t; typedef struct php_pqres_object { - zend_object zo; - zend_object_value zv; - HashTable *prophandler; - php_pqres_t *intern; + PHP_PQ_OBJ_DECL(php_pqres_t *) } php_pqres_object_t; -extern ZEND_RESULT_CODE php_pqres_success(PGresult *res TSRMLS_DC); -extern void php_pqres_init_instance_data(PGresult *res, php_pqconn_object_t *obj, php_pqres_object_t **ptr TSRMLS_DC); -extern zval *php_pqres_row_to_zval(PGresult *res, unsigned row, php_pqres_fetch_t fetch_type, zval **data_ptr TSRMLS_DC); -extern zval *php_pqres_typed_zval(php_pqres_t *res, char *val, size_t len, Oid typ TSRMLS_DC); +extern ZEND_RESULT_CODE php_pqres_success(PGresult *res); +extern php_pqres_object_t *php_pqres_init_instance_data(PGresult *res, php_pqconn_object_t *obj); +extern zval *php_pqres_row_to_zval(PGresult *res, unsigned row, php_pqres_fetch_t fetch_type, zval *data); +extern zval *php_pqres_typed_zval(php_pqres_t *res, Oid typ, zval *zv); extern php_pqres_fetch_t php_pqres_fetch_type(php_pqres_t *res); #include "php_pq_object.h" @@ -65,14 +62,14 @@ extern php_pqres_fetch_t php_pqres_fetch_type(php_pqres_t *res); #define PHP_PQclear(_r) do { \ php_pqres_object_t *_o = PQresultInstanceData((_r), php_pqconn_event); \ if (_o) { \ - php_pq_object_delref(_o TSRMLS_CC); \ + php_pq_object_delref(_o); \ } else { \ PQclear(_r); \ } \ } while(0) extern zend_class_entry *php_pqres_class_entry; -extern zend_object_value php_pqres_create_object_ex(zend_class_entry *ce, php_pqres_t *intern, php_pqres_object_t **ptr TSRMLS_DC); +extern php_pqres_object_t *php_pqres_create_object_ex(zend_class_entry *ce, php_pqres_t *intern); extern PHP_MINIT_FUNCTION(pqres); extern PHP_MSHUTDOWN_FUNCTION(pqres); diff --git a/src/php_pqstm.c b/src/php_pqstm.c index 6d61a19..dff5375 100644 --- a/src/php_pqstm.c +++ b/src/php_pqstm.c @@ -15,7 +15,7 @@ #endif #include -#include +#include #include "php_pq.h" #include "php_pq_misc.h" @@ -29,7 +29,7 @@ zend_class_entry *php_pqstm_class_entry; static zend_object_handlers php_pqstm_object_handlers; static HashTable php_pqstm_object_prophandlers; -static void php_pqstm_deallocate(php_pqstm_object_t *obj, zend_bool async, zend_bool silent TSRMLS_DC) +static void php_pqstm_deallocate(php_pqstm_object_t *obj, zend_bool async, zend_bool silent) { if (obj->intern->allocated) { char *quoted_name = PQescapeIdentifier(obj->intern->conn->intern->conn, obj->intern->name, strlen(obj->intern->name)); @@ -42,19 +42,19 @@ static void php_pqstm_deallocate(php_pqstm_object_t *obj, zend_bool async, zend_ smart_str_0(&cmd); if (async) { - if (PQsendQuery(obj->intern->conn->intern->conn, cmd.c)) { + if (PQsendQuery(obj->intern->conn->intern->conn, smart_str_v(&cmd))) { obj->intern->conn->intern->poller = PQconsumeInput; - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->conn); } else if (!silent) { - throw_exce(EX_IO TSRMLS_CC, "Failed to deallocate statement (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_IO, "Failed to deallocate statement (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } } else { PGresult *res; - if ((res = PQexec(obj->intern->conn->intern->conn, cmd.c))) { + if ((res = PQexec(obj->intern->conn->intern->conn, smart_str_v(&cmd)))) { PHP_PQclear(res); } else if (!silent) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to deallocate statement (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to deallocate statement (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } } @@ -66,17 +66,17 @@ static void php_pqstm_deallocate(php_pqstm_object_t *obj, zend_bool async, zend_ } } -static void php_pqstm_object_free(void *o TSRMLS_DC) +static void php_pqstm_object_free(zend_object *o) { - php_pqstm_object_t *obj = o; + php_pqstm_object_t *obj = PHP_PQ_OBJ(NULL, o); #if DBG_GC - fprintf(stderr, "FREE stm(#%d) %p (conn(#%d): %p)\n", obj->zv.handle, obj, obj->intern->conn->zv.handle, obj->intern->conn); + fprintf(stderr, "FREE stm(#%d) %p (conn(#%d): %p)\n", obj->zo.handle, obj, obj->intern->conn->zo.handle, obj->intern->conn); #endif if (obj->intern) { if (obj->intern->conn->intern) { php_pq_callback_dtor(&obj->intern->conn->intern->onevent); - php_pqstm_deallocate(obj, 0, 1 TSRMLS_CC); - php_pq_object_delref(obj->intern->conn TSRMLS_CC); + php_pqstm_deallocate(obj, 0, 1); + php_pq_object_delref(obj->intern->conn); } efree(obj->intern->name); efree(obj->intern->query); @@ -87,60 +87,51 @@ static void php_pqstm_object_free(void *o TSRMLS_DC) efree(obj->intern); obj->intern = NULL; } - zend_object_std_dtor((zend_object *) o TSRMLS_CC); - efree(obj); + php_pq_object_dtor(o); } -zend_object_value php_pqstm_create_object_ex(zend_class_entry *ce, php_pqstm_t *intern, php_pqstm_object_t **ptr TSRMLS_DC) +php_pqstm_object_t *php_pqstm_create_object_ex(zend_class_entry *ce, php_pqstm_t *intern) { - php_pqstm_object_t *o; - - o = ecalloc(1, sizeof(*o)); - zend_object_std_init((zend_object *) o, ce TSRMLS_CC); - object_properties_init((zend_object *) o, ce); - o->prophandler = &php_pqstm_object_prophandlers; - - if (ptr) { - *ptr = o; - } - - if (intern) { - o->intern = intern; - } - - o->zv.handle = zend_objects_store_put((zend_object *) o, NULL, php_pqstm_object_free, NULL TSRMLS_CC); - o->zv.handlers = &php_pqstm_object_handlers; + return php_pq_object_create(ce, intern, sizeof(php_pqstm_object_t), + &php_pqstm_object_handlers, &php_pqstm_object_prophandlers); +} - return o->zv; +static zend_object *php_pqstm_create_object(zend_class_entry *class_type) +{ + return &php_pqstm_create_object_ex(class_type, NULL)->zo; } -static zend_object_value php_pqstm_create_object(zend_class_entry *class_type TSRMLS_DC) +static void php_pqstm_object_read_name(zval *object, void *o, zval *return_value) { - return php_pqstm_create_object_ex(class_type, NULL, NULL TSRMLS_CC); + php_pqstm_object_t *obj = o; + + RETVAL_STRING(obj->intern->name); } -static void php_pqstm_object_read_name(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqstm_object_read_connection(zval *object, void *o, zval *return_value) { php_pqstm_object_t *obj = o; - RETVAL_STRING(obj->intern->name, 1); + php_pq_object_to_zval(obj->intern->conn, return_value); } -static void php_pqstm_object_read_connection(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqstm_object_gc_connection(zval *object, void *o, zval *return_value) { php_pqstm_object_t *obj = o; + zval zconn; - php_pq_object_to_zval(obj->intern->conn, &return_value TSRMLS_CC); + php_pq_object_to_zval_no_addref(obj->intern->conn, &zconn); + add_next_index_zval(return_value, &zconn); } -static void php_pqstm_object_read_query(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqstm_object_read_query(zval *object, void *o, zval *return_value) { php_pqstm_object_t *obj = o; - RETVAL_STRING(obj->intern->query, 1); + RETVAL_STRING(obj->intern->query); } -static void php_pqstm_object_read_types(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqstm_object_read_types(zval *object, void *o, zval *return_value) { int i; php_pqstm_object_t *obj = o; @@ -151,11 +142,11 @@ static void php_pqstm_object_read_types(zval *object, void *o, zval *return_valu } } -php_pqstm_t *php_pqstm_init(php_pqconn_object_t *conn, const char *name, const char *query, php_pq_params_t *params TSRMLS_DC) +php_pqstm_t *php_pqstm_init(php_pqconn_object_t *conn, const char *name, const char *query, php_pq_params_t *params) { php_pqstm_t *stm = ecalloc(1, sizeof(*stm)); - php_pq_object_addref(conn TSRMLS_CC); + php_pq_object_addref(conn); stm->conn = conn; stm->name = estrdup(name); stm->params = params; @@ -178,33 +169,33 @@ static PHP_METHOD(pqstm, __construct) { zend_error_handling zeh; zval *zconn, *ztypes = NULL; char *name_str, *query_str; - int name_len, *query_len; + size_t name_len, *query_len; zend_bool async = 0; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Oss|a/!b", &zconn, php_pqconn_class_entry, &name_str, &name_len, &query_str, &query_len, &ztypes, &async); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "Oss|a/!b", &zconn, php_pqconn_class_entry, &name_str, &name_len, &query_str, &query_len, &ztypes, &async); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqstm_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); - php_pqconn_object_t *conn_obj = zend_object_store_get_object(zconn TSRMLS_CC); + php_pqstm_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); + php_pqconn_object_t *conn_obj = PHP_PQ_OBJ(zconn, NULL); if (obj->intern) { - throw_exce(EX_BAD_METHODCALL TSRMLS_CC, "pq\\Statement already initialized"); + throw_exce(EX_BAD_METHODCALL, "pq\\Statement already initialized"); } else if (!conn_obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized"); } else { - php_pq_params_t *params = php_pq_params_init(&conn_obj->intern->converters, ztypes ? Z_ARRVAL_P(ztypes) : NULL, NULL TSRMLS_CC); + php_pq_params_t *params = php_pq_params_init(&conn_obj->intern->converters, ztypes ? Z_ARRVAL_P(ztypes) : NULL, NULL); if (async) { - rv = php_pqconn_prepare_async(zconn, conn_obj, name_str, query_str, params TSRMLS_CC); + rv = php_pqconn_prepare_async(zconn, conn_obj, name_str, query_str, params); } else { - rv = php_pqconn_prepare(zconn, conn_obj, name_str, query_str, params TSRMLS_CC); + rv = php_pqconn_prepare(zconn, conn_obj, name_str, query_str, params); } if (SUCCESS == rv) { - obj->intern = php_pqstm_init(conn_obj, name_str, query_str, params TSRMLS_CC); + obj->intern = php_pqstm_init(conn_obj, name_str, query_str, params); } } } @@ -214,27 +205,26 @@ ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_bind, 0, 0, 2) ZEND_ARG_INFO(1, param_ref) ZEND_END_ARG_INFO(); static PHP_METHOD(pqstm, bind) { - long param_no; - zval **param_ref; + zend_long param_no; + zval *param_ref; zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lZ", ¶m_no, ¶m_ref); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "lz", ¶m_no, ¶m_ref); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqstm_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqstm_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Statement not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Statement not initialized"); } else if (!obj->intern->allocated) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Statement has been deallocated"); + throw_exce(EX_UNINITIALIZED, "pq\\Statement has been deallocated"); } else { - SEPARATE_ZVAL_TO_MAKE_IS_REF(param_ref); - Z_ADDREF_PP(param_ref); - zend_hash_index_update(&obj->intern->bound, param_no, (void *) param_ref, sizeof(zval *), NULL); - zend_hash_sort(&obj->intern->bound, zend_qsort, php_pq_compare_index, 0 TSRMLS_CC); + Z_ADDREF_P(param_ref); + zend_hash_index_update(&obj->intern->bound, param_no, param_ref); + zend_hash_sort(&obj->intern->bound, php_pq_compare_index, 0); } } } @@ -247,17 +237,17 @@ static PHP_METHOD(pqstm, exec) { zval *zparams = NULL; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a/!", &zparams); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "|a/!", &zparams); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqstm_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqstm_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Statement not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Statement not initialized"); } else if (!obj->intern->allocated) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Statement has been deallocated"); + throw_exce(EX_UNINITIALIZED, "pq\\Statement has been deallocated"); } else { PGresult *res; @@ -266,10 +256,10 @@ static PHP_METHOD(pqstm, exec) { php_pq_params_set_params(obj->intern->params, NULL); if (!res) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to execute statement (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); - } else if (SUCCESS == php_pqres_success(res TSRMLS_CC)) { - php_pq_object_to_zval_no_addref(PQresultInstanceData(res, php_pqconn_event), &return_value TSRMLS_CC); - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + throw_exce(EX_RUNTIME, "Failed to execute statement (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + } else if (SUCCESS == php_pqres_success(res)) { + php_pq_object_to_zval_no_addref(PQresultInstanceData(res, php_pqconn_event), return_value); + php_pqconn_notify_listeners(obj->intern->conn); } } } @@ -285,17 +275,17 @@ static PHP_METHOD(pqstm, execAsync) { php_pq_callback_t resolver = {{0}}; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a/!f", &zparams, &resolver.fci, &resolver.fcc); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "|a/!f", &zparams, &resolver.fci, &resolver.fcc); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqstm_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqstm_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Statement not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Statement not initialized"); } else if (!obj->intern->allocated) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Statement has been deallocated"); + throw_exce(EX_UNINITIALIZED, "pq\\Statement has been deallocated"); } else { int rc; @@ -304,17 +294,17 @@ static PHP_METHOD(pqstm, execAsync) { php_pq_params_set_params(obj->intern->params, NULL); if (!rc) { - throw_exce(EX_IO TSRMLS_CC, "Failed to execute statement (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_IO, "Failed to execute statement (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); #if HAVE_PQSETSINGLEROWMODE } else if (obj->intern->conn->intern->unbuffered && !PQsetSingleRowMode(obj->intern->conn->intern->conn)) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); #endif } else { - php_pq_callback_recurse(&obj->intern->conn->intern->onevent, &resolver TSRMLS_CC); + php_pq_callback_recurse(&obj->intern->conn->intern->onevent, &resolver); obj->intern->conn->intern->poller = PQconsumeInput; } - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->conn); } } } @@ -325,24 +315,24 @@ static PHP_METHOD(pqstm, desc) { zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); rv = zend_parse_parameters_none(); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqstm_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqstm_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Statement not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Statement not initialized"); } else if (!obj->intern->allocated) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Statement has been deallocated"); + throw_exce(EX_UNINITIALIZED, "pq\\Statement has been deallocated"); } else { PGresult *res = PQdescribePrepared(obj->intern->conn->intern->conn, obj->intern->name); if (!res) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to describe statement (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to describe statement (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { - if (SUCCESS == php_pqres_success(res TSRMLS_CC)) { + if (SUCCESS == php_pqres_success(res)) { int p, params; array_init(return_value); @@ -351,7 +341,7 @@ static PHP_METHOD(pqstm, desc) { } } PHP_PQclear(res); - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->conn); } } } @@ -365,23 +355,23 @@ static PHP_METHOD(pqstm, descAsync) { php_pq_callback_t resolver = {{0}}; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "f", &resolver.fci, &resolver.fcc); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "f", &resolver.fci, &resolver.fcc); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqstm_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqstm_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Statement not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Statement not initialized"); } else if (!obj->intern->allocated) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Statement has been deallocated"); + throw_exce(EX_UNINITIALIZED, "pq\\Statement has been deallocated"); } else if (!PQsendDescribePrepared(obj->intern->conn->intern->conn, obj->intern->name)) { - throw_exce(EX_IO TSRMLS_CC, "Failed to describe statement: %s", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_IO, "Failed to describe statement: %s", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { - php_pq_callback_recurse(&obj->intern->conn->intern->onevent, &resolver TSRMLS_CC); + php_pq_callback_recurse(&obj->intern->conn->intern->onevent, &resolver); obj->intern->conn->intern->poller = PQconsumeInput; - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->conn); } } } @@ -391,17 +381,17 @@ static zend_always_inline void php_pqstm_deallocate_handler(INTERNAL_FUNCTION_PA zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); rv = zend_parse_parameters_none(); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); if (rv == SUCCESS) { - php_pqstm_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqstm_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Statement not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Statement not initialized"); } else { - php_pqstm_deallocate(obj, async, 0 TSRMLS_CC); + php_pqstm_deallocate(obj, async, 0); } } } @@ -425,20 +415,20 @@ static zend_always_inline void php_pqstm_prepare_handler(INTERNAL_FUNCTION_PARAM zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); rv = zend_parse_parameters_none(); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); if (rv == SUCCESS) { - php_pqstm_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqstm_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Statement not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Statement not initialized"); } else if (!obj->intern->allocated) { if (async) { - rv = php_pqconn_prepare_async(NULL, obj->intern->conn, obj->intern->name, obj->intern->query, obj->intern->params TSRMLS_CC); + rv = php_pqconn_prepare_async(NULL, obj->intern->conn, obj->intern->name, obj->intern->query, obj->intern->params); } else { - rv = php_pqconn_prepare(NULL, obj->intern->conn, obj->intern->name, obj->intern->query, obj->intern->params TSRMLS_CC); + rv = php_pqconn_prepare(NULL, obj->intern->conn, obj->intern->name, obj->intern->query, obj->intern->params); } if (SUCCESS == rv) { @@ -488,35 +478,39 @@ PHP_MINIT_FUNCTION(pqstm) php_pq_object_prophandler_t ph = {0}; INIT_NS_CLASS_ENTRY(ce, "pq", "Statement", php_pqstm_methods); - php_pqstm_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC); + php_pqstm_class_entry = zend_register_internal_class_ex(&ce, NULL); php_pqstm_class_entry->create_object = php_pqstm_create_object; memcpy(&php_pqstm_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + php_pqstm_object_handlers.offset = XtOffsetOf(php_pqstm_object_t, zo); + php_pqstm_object_handlers.free_obj = php_pqstm_object_free; php_pqstm_object_handlers.read_property = php_pq_object_read_prop; php_pqstm_object_handlers.write_property = php_pq_object_write_prop; php_pqstm_object_handlers.clone_obj = NULL; php_pqstm_object_handlers.get_property_ptr_ptr = NULL; - php_pqstm_object_handlers.get_gc = NULL; + php_pqstm_object_handlers.get_gc = php_pq_object_get_gc; php_pqstm_object_handlers.get_properties = php_pq_object_properties; php_pqstm_object_handlers.get_debug_info = php_pq_object_debug_info; - zend_hash_init(&php_pqstm_object_prophandlers, 2, NULL, NULL, 1); + zend_hash_init(&php_pqstm_object_prophandlers, 4, NULL, php_pq_object_prophandler_dtor, 1); - zend_declare_property_null(php_pqstm_class_entry, ZEND_STRL("name"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqstm_class_entry, ZEND_STRL("name"), ZEND_ACC_PUBLIC); ph.read = php_pqstm_object_read_name; - zend_hash_add(&php_pqstm_object_prophandlers, "name", sizeof("name"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqstm_object_prophandlers, "name", sizeof("name")-1, (void *) &ph, sizeof(ph)); - zend_declare_property_null(php_pqstm_class_entry, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqstm_class_entry, ZEND_STRL("connection"), ZEND_ACC_PUBLIC); ph.read = php_pqstm_object_read_connection; - zend_hash_add(&php_pqstm_object_prophandlers, "connection", sizeof("connection"), (void *) &ph, sizeof(ph), NULL); + ph.gc = php_pqstm_object_gc_connection; + zend_hash_str_add_mem(&php_pqstm_object_prophandlers, "connection", sizeof("connection")-1, (void *) &ph, sizeof(ph)); + ph.gc = NULL; - zend_declare_property_null(php_pqstm_class_entry, ZEND_STRL("query"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqstm_class_entry, ZEND_STRL("query"), ZEND_ACC_PUBLIC); ph.read = php_pqstm_object_read_query; - zend_hash_add(&php_pqstm_object_prophandlers, "query", sizeof("query"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqstm_object_prophandlers, "query", sizeof("query")-1, (void *) &ph, sizeof(ph)); - zend_declare_property_null(php_pqstm_class_entry, ZEND_STRL("types"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqstm_class_entry, ZEND_STRL("types"), ZEND_ACC_PUBLIC); ph.read = php_pqstm_object_read_types; - zend_hash_add(&php_pqstm_object_prophandlers, "types", sizeof("types"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqstm_object_prophandlers, "types", sizeof("types")-1, (void *) &ph, sizeof(ph)); return SUCCESS; } diff --git a/src/php_pqstm.h b/src/php_pqstm.h index f5c59a6..79e6aa7 100644 --- a/src/php_pqstm.h +++ b/src/php_pqstm.h @@ -26,15 +26,12 @@ typedef struct php_pqstm { } php_pqstm_t; typedef struct php_pqstm_object { - zend_object zo; - zend_object_value zv; - HashTable *prophandler; - php_pqstm_t *intern; + PHP_PQ_OBJ_DECL(php_pqstm_t *) } php_pqstm_object_t; extern zend_class_entry *php_pqstm_class_entry; -extern zend_object_value php_pqstm_create_object_ex(zend_class_entry *ce, php_pqstm_t *intern, php_pqstm_object_t **ptr TSRMLS_DC); -extern php_pqstm_t *php_pqstm_init(php_pqconn_object_t *conn, const char *name, const char *query, php_pq_params_t *params TSRMLS_DC); +extern php_pqstm_object_t *php_pqstm_create_object_ex(zend_class_entry *ce, php_pqstm_t *intern); +extern php_pqstm_t *php_pqstm_init(php_pqconn_object_t *conn, const char *name, const char *query, php_pq_params_t *params); extern PHP_MINIT_FUNCTION(pqstm); extern PHP_MSHUTDOWN_FUNCTION(pqstm); diff --git a/src/php_pqtxn.c b/src/php_pqtxn.c index e0574e8..5b12545 100644 --- a/src/php_pqtxn.c +++ b/src/php_pqtxn.c @@ -15,7 +15,7 @@ #endif #include -#include +#include #include #include @@ -47,11 +47,11 @@ const char *php_pq_isolation_level(long *isolation) } } -static void php_pqtxn_object_free(void *o TSRMLS_DC) +static void php_pqtxn_object_free(zend_object *o) { - php_pqtxn_object_t *obj = o; + php_pqtxn_object_t *obj = PHP_PQ_OBJ(NULL, o); #if DBG_GC - fprintf(stderr, "FREE txn(#%d) %p (conn(#%d): %p)\n", obj->zv.handle, obj, obj->intern->conn->zv.handle, obj->intern->conn); + fprintf(stderr, "FREE txn(#%d) %p (conn(#%d): %p)\n", obj->zo.handle, obj, obj->intern->conn->zo.handle, obj->intern->conn); #endif if (obj->intern) { if (obj->intern->open && obj->intern->conn->intern) { @@ -61,90 +61,68 @@ static void php_pqtxn_object_free(void *o TSRMLS_DC) PHP_PQclear(res); } } - php_pq_object_delref(obj->intern->conn TSRMLS_CC); + php_pq_object_delref(obj->intern->conn); efree(obj->intern); obj->intern = NULL; } - zend_object_std_dtor((zend_object *) o TSRMLS_CC); - efree(obj); + php_pq_object_dtor(o); } -zend_object_value php_pqtxn_create_object_ex(zend_class_entry *ce, php_pqtxn_t *intern, php_pqtxn_object_t **ptr TSRMLS_DC) +php_pqtxn_object_t *php_pqtxn_create_object_ex(zend_class_entry *ce, php_pqtxn_t *intern) { - php_pqtxn_object_t *o; - - o = ecalloc(1, sizeof(*o)); - zend_object_std_init((zend_object *) o, ce TSRMLS_CC); - object_properties_init((zend_object *) o, ce); - o->prophandler = &php_pqtxn_object_prophandlers; - - if (ptr) { - *ptr = o; - } - - if (intern) { - o->intern = intern; - } - - o->zv.handle = zend_objects_store_put((zend_object *) o, NULL, php_pqtxn_object_free, NULL TSRMLS_CC); - o->zv.handlers = &php_pqtxn_object_handlers; + return php_pq_object_create(ce, intern, sizeof(php_pqtxn_object_t), + &php_pqtxn_object_handlers, &php_pqtxn_object_prophandlers); +} - return o->zv; +static zend_object *php_pqtxn_create_object(zend_class_entry *class_type) +{ + return &php_pqtxn_create_object_ex(class_type, NULL)->zo; } -static zend_object_value php_pqtxn_create_object(zend_class_entry *class_type TSRMLS_DC) +static void php_pqtxn_object_read_connection(zval *object, void *o, zval *return_value) { - return php_pqtxn_create_object_ex(class_type, NULL, NULL TSRMLS_CC); + php_pqtxn_object_t *obj = o; + + php_pq_object_to_zval(obj->intern->conn, return_value); } -static void php_pqtxn_object_read_connection(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqtxn_object_gc_connection(zval *object, void *o, zval *return_value) { php_pqtxn_object_t *obj = o; + zval zconn; - php_pq_object_to_zval(obj->intern->conn, &return_value TSRMLS_CC); + php_pq_object_to_zval_no_addref(obj->intern->conn, &zconn); + add_next_index_zval(return_value, &zconn); } -static void php_pqtxn_object_read_isolation(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqtxn_object_read_isolation(zval *object, void *o, zval *return_value) { php_pqtxn_object_t *obj = o; RETVAL_LONG(obj->intern->isolation); } -static void php_pqtxn_object_read_readonly(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqtxn_object_read_readonly(zval *object, void *o, zval *return_value) { php_pqtxn_object_t *obj = o; RETVAL_BOOL(obj->intern->readonly); } -static void php_pqtxn_object_read_deferrable(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqtxn_object_read_deferrable(zval *object, void *o, zval *return_value) { php_pqtxn_object_t *obj = o; RETVAL_BOOL(obj->intern->deferrable); } -static void php_pqtxn_object_write_isolation(zval *object, void *o, zval *value TSRMLS_DC) +static void php_pqtxn_object_write_isolation(zval *object, void *o, zval *value) { php_pqtxn_object_t *obj = o; php_pqtxn_isolation_t orig = obj->intern->isolation; - zval *zisolation = value; PGresult *res; - if (Z_TYPE_P(zisolation) != IS_LONG) { - if (Z_REFCOUNT_P(value) > 1) { - zval *tmp; - MAKE_STD_ZVAL(tmp); - ZVAL_ZVAL(tmp, zisolation, 1, 0); - convert_to_long(tmp); - zisolation = tmp; - } else { - convert_to_long_ex(&zisolation); - } - } - - switch ((obj->intern->isolation = Z_LVAL_P(zisolation))) { + switch ((obj->intern->isolation = zval_get_long(value))) { case PHP_PQTXN_READ_COMMITTED: res = PQexec(obj->intern->conn->intern->conn, "SET TRANSACTION ISOLATION LEVEL READ COMMITED"); break; @@ -160,17 +138,13 @@ static void php_pqtxn_object_write_isolation(zval *object, void *o, zval *value break; } - if (zisolation != value) { - zval_ptr_dtor(&zisolation); - } - if (res) { - php_pqres_success(res TSRMLS_CC); + php_pqres_success(res); PHP_PQclear(res); } } -static void php_pqtxn_object_write_readonly(zval *object, void *o, zval *value TSRMLS_DC) +static void php_pqtxn_object_write_readonly(zval *object, void *o, zval *value) { php_pqtxn_object_t *obj = o; PGresult *res; @@ -182,12 +156,12 @@ static void php_pqtxn_object_write_readonly(zval *object, void *o, zval *value T } if (res) { - php_pqres_success(res TSRMLS_CC); + php_pqres_success(res); PHP_PQclear(res); } } -static void php_pqtxn_object_write_deferrable(zval *object, void *o, zval *value TSRMLS_DC) +static void php_pqtxn_object_write_deferrable(zval *object, void *o, zval *value) { php_pqtxn_object_t *obj = o; PGresult *res; @@ -199,7 +173,7 @@ static void php_pqtxn_object_write_deferrable(zval *object, void *o, zval *value } if (res) { - php_pqres_success(res TSRMLS_CC); + php_pqres_success(res); PHP_PQclear(res); } } @@ -215,19 +189,19 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(pqtxn, __construct) { zend_error_handling zeh; zval *zconn; - long isolation = PHP_PQTXN_READ_COMMITTED; + zend_long isolation = PHP_PQTXN_READ_COMMITTED; zend_bool async = 0, readonly = 0, deferrable = 0; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|blbb", &zconn, php_pqconn_class_entry, &async, &isolation, &readonly, &deferrable); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "O|blbb", &zconn, php_pqconn_class_entry, &async, &isolation, &readonly, &deferrable); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqconn_object_t *conn_obj = zend_object_store_get_object(zconn TSRMLS_CC); + php_pqconn_object_t *conn_obj = PHP_PQ_OBJ(zconn, NULL); if (!conn_obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized"); } else { switch (ZEND_NUM_ARGS()) { @@ -244,17 +218,17 @@ static PHP_METHOD(pqtxn, __construct) { } if (async) { - rv = php_pqconn_start_transaction_async(zconn, conn_obj, isolation, readonly, deferrable TSRMLS_CC); + rv = php_pqconn_start_transaction_async(zconn, conn_obj, isolation, readonly, deferrable); } else { - rv = php_pqconn_start_transaction(zconn, conn_obj, isolation, readonly, deferrable TSRMLS_CC); + rv = php_pqconn_start_transaction(zconn, conn_obj, isolation, readonly, deferrable); } if (SUCCESS == rv) { - php_pqtxn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); obj->intern = ecalloc(1, sizeof(*obj->intern)); - php_pq_object_addref(conn_obj TSRMLS_CC); + php_pq_object_addref(conn_obj); obj->intern->conn = conn_obj; obj->intern->open = 1; obj->intern->isolation = isolation; @@ -271,17 +245,17 @@ static PHP_METHOD(pqtxn, savepoint) { zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); rv = zend_parse_parameters_none(); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqtxn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Transaction not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized"); } else if (!obj->intern->open) { - throw_exce(EX_RUNTIME TSRMLS_CC, "pq\\Transaction already closed"); + throw_exce(EX_RUNTIME, "pq\\Transaction already closed"); } else { PGresult *res; smart_str cmd = {0}; @@ -291,12 +265,12 @@ static PHP_METHOD(pqtxn, savepoint) { smart_str_appends(&cmd, "\""); smart_str_0(&cmd); - res = PQexec(obj->intern->conn->intern->conn, cmd.c); + res = PQexec(obj->intern->conn->intern->conn, smart_str_v(&cmd)); if (!res) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to create %s (%s)", cmd.c, PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to create %s (%s)", smart_str_v(&cmd), PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { - php_pqres_success(res TSRMLS_CC); + php_pqres_success(res); PHP_PQclear(res); } @@ -311,17 +285,17 @@ static PHP_METHOD(pqtxn, savepointAsync) { zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); rv = zend_parse_parameters_none(); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqtxn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Transaction not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized"); } else if (!obj->intern->open) { - throw_exce(EX_RUNTIME TSRMLS_CC, "pq\\Transaction already closed"); + throw_exce(EX_RUNTIME, "pq\\Transaction already closed"); } else { smart_str cmd = {0}; @@ -330,8 +304,8 @@ static PHP_METHOD(pqtxn, savepointAsync) { smart_str_appends(&cmd, "\""); smart_str_0(&cmd); - if (!PQsendQuery(obj->intern->conn->intern->conn, cmd.c)) { - throw_exce(EX_IO TSRMLS_CC, "Failed to create %s (%s)", cmd.c, PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + if (!PQsendQuery(obj->intern->conn->intern->conn, smart_str_v(&cmd))) { + throw_exce(EX_IO, "Failed to create %s (%s)", smart_str_v(&cmd), PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } smart_str_free(&cmd); @@ -345,22 +319,23 @@ static PHP_METHOD(pqtxn, commit) { zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); rv = zend_parse_parameters_none(); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqtxn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Transacation not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Transacation not initialized"); } else if (!obj->intern->open) { - throw_exce(EX_RUNTIME TSRMLS_CC, "pq\\Transaction already closed"); + throw_exce(EX_RUNTIME, "pq\\Transaction already closed"); } else { PGresult *res; smart_str cmd = {0}; + zend_bool just_release_sp = !!obj->intern->savepoint; - if (!obj->intern->savepoint) { + if (!just_release_sp) { res = PQexec(obj->intern->conn->intern->conn, "COMMIT"); } else { smart_str_appends(&cmd, "RELEASE SAVEPOINT \""); @@ -368,14 +343,14 @@ static PHP_METHOD(pqtxn, commit) { smart_str_appends(&cmd, "\""); smart_str_0(&cmd); - res = PQexec(obj->intern->conn->intern->conn, cmd.c); + res = PQexec(obj->intern->conn->intern->conn, smart_str_v(&cmd)); } if (!res) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to %s (%s)", cmd.c ? cmd.c : "commit transaction", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to %s (%s)", smart_str_l(&cmd) ? smart_str_v(&cmd) : "commit transaction", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { - if (SUCCESS == php_pqres_success(res TSRMLS_CC)) { - if (!cmd.c) { + if (SUCCESS == php_pqres_success(res)) { + if (!just_release_sp) { obj->intern->open = 0; } } @@ -383,7 +358,7 @@ static PHP_METHOD(pqtxn, commit) { } smart_str_free(&cmd); - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->conn); } } } @@ -394,22 +369,23 @@ static PHP_METHOD(pqtxn, commitAsync) { zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); rv = zend_parse_parameters_none(); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqtxn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Transaction not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized"); } else if (!obj->intern->open) { - throw_exce(EX_RUNTIME TSRMLS_CC, "pq\\Transaction already closed"); + throw_exce(EX_RUNTIME, "pq\\Transaction already closed"); } else { int rc; smart_str cmd = {0}; + zend_bool just_release_sp = !!obj->intern->savepoint; - if (!obj->intern->savepoint) { + if (!just_release_sp) { rc = PQsendQuery(obj->intern->conn->intern->conn, "COMMIT"); } else { smart_str_appends(&cmd, "RELEASE SAVEPOINT \""); @@ -417,17 +393,17 @@ static PHP_METHOD(pqtxn, commitAsync) { smart_str_appends(&cmd, "\""); smart_str_0(&cmd); - rc = PQsendQuery(obj->intern->conn->intern->conn, cmd.c); + rc = PQsendQuery(obj->intern->conn->intern->conn, smart_str_v(&cmd)); } if (!rc) { - throw_exce(EX_IO TSRMLS_CC, "Failed to %s (%s)", cmd.c ? cmd.c : "commmit transaction", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_IO, "Failed to %s (%s)", smart_str_l(&cmd) ? smart_str_v(&cmd) : "commmit transaction", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { - if (!cmd.c) { + if (!just_release_sp) { obj->intern->open = 0; } obj->intern->conn->intern->poller = PQconsumeInput; - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->conn); } smart_str_free(&cmd); @@ -441,22 +417,23 @@ static PHP_METHOD(pqtxn, rollback) { zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); rv = zend_parse_parameters_none(); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqtxn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Transaction not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized"); } else if (!obj->intern->open) { - throw_exce(EX_RUNTIME TSRMLS_CC, "pq\\Transaction already closed"); + throw_exce(EX_RUNTIME, "pq\\Transaction already closed"); } else { PGresult *res; smart_str cmd = {0}; + zend_bool just_release_sp = !!obj->intern->savepoint; - if (!obj->intern->savepoint) { + if (!just_release_sp) { res = PQexec(obj->intern->conn->intern->conn, "ROLLBACK"); } else { smart_str_appends(&cmd, "ROLLBACK TO SAVEPOINT \""); @@ -464,14 +441,14 @@ static PHP_METHOD(pqtxn, rollback) { smart_str_appends(&cmd, "\""); smart_str_0(&cmd); - res = PQexec(obj->intern->conn->intern->conn, cmd.c); + res = PQexec(obj->intern->conn->intern->conn, smart_str_v(&cmd)); } if (!res) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to %s (%s)", cmd.c ? cmd.c : "rollback transaction", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to %s (%s)", smart_str_l(&cmd) ? smart_str_v(&cmd) : "rollback transaction", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { - if (SUCCESS == php_pqres_success(res TSRMLS_CC)) { - if (!cmd.c) { + if (SUCCESS == php_pqres_success(res)) { + if (!just_release_sp) { obj->intern->open = 0; } } @@ -479,7 +456,7 @@ static PHP_METHOD(pqtxn, rollback) { } smart_str_free(&cmd); - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->conn); } } } @@ -490,22 +467,23 @@ static PHP_METHOD(pqtxn, rollbackAsync) { zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); rv = zend_parse_parameters_none(); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqtxn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Transaction not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized"); } else if (!obj->intern->open) { - throw_exce(EX_RUNTIME TSRMLS_CC, "pq\\Transaction already closed"); + throw_exce(EX_RUNTIME, "pq\\Transaction already closed"); } else { int rc; smart_str cmd = {0}; + zend_bool just_release_sp = !!obj->intern->savepoint; - if (!obj->intern->savepoint) { + if (!just_release_sp) { rc = PQsendQuery(obj->intern->conn->intern->conn, "ROLLBACK"); } else { smart_str_appends(&cmd, "ROLLBACK TO SAVEPOINT \""); @@ -513,20 +491,20 @@ static PHP_METHOD(pqtxn, rollbackAsync) { smart_str_appends(&cmd, "\""); smart_str_0(&cmd); - rc = PQsendQuery(obj->intern->conn->intern->conn, cmd.c); + rc = PQsendQuery(obj->intern->conn->intern->conn, smart_str_v(&cmd)); } if (!rc) { - throw_exce(EX_IO TSRMLS_CC, "Failed to %s (%s)", cmd.c ? cmd.c : "rollback transaction", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_IO, "Failed to %s (%s)", smart_str_l(&cmd) ? smart_str_v(&cmd) : "rollback transaction", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { - if (!cmd.c) { + if (!just_release_sp) { obj->intern->open = 0; } obj->intern->conn->intern->poller = PQconsumeInput; } smart_str_free(&cmd); - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->conn); } } } @@ -537,29 +515,29 @@ static PHP_METHOD(pqtxn, exportSnapshot) { zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); rv = zend_parse_parameters_none(); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqtxn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Transaction not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized"); } else { PGresult *res = PQexec(obj->intern->conn->intern->conn, "SELECT pg_export_snapshot()"); if (!res) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to export transaction snapshot (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to export transaction snapshot (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { - if (SUCCESS == php_pqres_success(res TSRMLS_CC)) { - RETVAL_STRING(PQgetvalue(res, 0, 0), 1); + if (SUCCESS == php_pqres_success(res)) { + RETVAL_STRING(PQgetvalue(res, 0, 0)); } PHP_PQclear(res); } - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->conn); } } } @@ -570,20 +548,20 @@ static PHP_METHOD(pqtxn, exportSnapshotAsync) { zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); rv = zend_parse_parameters_none(); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqtxn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Transaction not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized"); } else if (!PQsendQuery(obj->intern->conn->intern->conn, "SELECT pg_export_snapshot()")) { - throw_exce(EX_IO TSRMLS_CC, "Failed to export transaction snapshot (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_IO, "Failed to export transaction snapshot (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { obj->intern->conn->intern->poller = PQconsumeInput; - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->conn); } } } @@ -594,25 +572,25 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(pqtxn, importSnapshot) { zend_error_handling zeh; char *snapshot_str; - int snapshot_len; + size_t snapshot_len; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &snapshot_str, &snapshot_len); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "s", &snapshot_str, &snapshot_len); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqtxn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Transaction not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized"); } else if (obj->intern->isolation < PHP_PQTXN_REPEATABLE_READ) { - throw_exce(EX_RUNTIME TSRMLS_CC, "pq\\Transaction must have at least isolation level REPEATABLE READ to be able to import a snapshot"); + throw_exce(EX_RUNTIME, "pq\\Transaction must have at least isolation level REPEATABLE READ to be able to import a snapshot"); } else { char *sid = PQescapeLiteral(obj->intern->conn->intern->conn, snapshot_str, snapshot_len); if (!sid) { - throw_exce(EX_ESCAPE TSRMLS_CC, "Failed to quote snapshot identifier (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_ESCAPE, "Failed to quote snapshot identifier (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { PGresult *res; smart_str cmd = {0}; @@ -621,17 +599,17 @@ static PHP_METHOD(pqtxn, importSnapshot) { smart_str_appends(&cmd, sid); smart_str_0(&cmd); - res = PQexec(obj->intern->conn->intern->conn, cmd.c); + res = PQexec(obj->intern->conn->intern->conn, smart_str_v(&cmd)); if (!res) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to import transaction snapshot (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to import transaction snapshot (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { - php_pqres_success(res TSRMLS_CC); + php_pqres_success(res); PHP_PQclear(res); } smart_str_free(&cmd); - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->conn); } } } @@ -643,25 +621,25 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(pqtxn, importSnapshotAsync) { zend_error_handling zeh; char *snapshot_str; - int snapshot_len; + size_t snapshot_len; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &snapshot_str, &snapshot_len); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "s", &snapshot_str, &snapshot_len); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqtxn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Transaction not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized"); } else if (obj->intern->isolation < PHP_PQTXN_REPEATABLE_READ) { - throw_exce(EX_RUNTIME TSRMLS_CC, "pq\\Transaction must have at least isolation level REPEATABLE READ to be able to import a snapshot"); + throw_exce(EX_RUNTIME, "pq\\Transaction must have at least isolation level REPEATABLE READ to be able to import a snapshot"); } else { char *sid = PQescapeLiteral(obj->intern->conn->intern->conn, snapshot_str, snapshot_len); if (!sid) { - throw_exce(EX_ESCAPE TSRMLS_CC, "Failed to quote snapshot identifier (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_ESCAPE, "Failed to quote snapshot identifier (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { smart_str cmd = {0}; @@ -669,14 +647,14 @@ static PHP_METHOD(pqtxn, importSnapshotAsync) { smart_str_appends(&cmd, sid); smart_str_0(&cmd); - if (!PQsendQuery(obj->intern->conn->intern->conn, cmd.c)) { - throw_exce(EX_IO TSRMLS_CC, "Failed to %s (%s)", cmd.c, PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + if (!PQsendQuery(obj->intern->conn->intern->conn, smart_str_v(&cmd))) { + throw_exce(EX_IO, "Failed to %s (%s)", smart_str_v(&cmd), PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { obj->intern->conn->intern->poller = PQconsumeInput; } smart_str_free(&cmd); - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->conn); } } } @@ -688,36 +666,35 @@ ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_open_lob, 0, 0, 1) ZEND_END_ARG_INFO(); static PHP_METHOD(pqtxn, openLOB) { zend_error_handling zeh; - long mode = INV_WRITE|INV_READ, loid; + zend_long mode = INV_WRITE|INV_READ, loid; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l", &loid, &mode); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "l|l", &loid, &mode); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqtxn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Transaction not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized"); } else { int lofd = lo_open(obj->intern->conn->intern->conn, loid, mode); if (lofd < 0) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to open large object with oid=%u with mode '%s' (%s)", loid, php_pq_strmode(mode), PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to open large object with oid=%lu with mode '%s' (%s)", loid, php_pq_strmode(mode), PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { php_pqlob_t *lob = ecalloc(1, sizeof(*lob)); lob->lofd = lofd; lob->loid = loid; - php_pq_object_addref(obj TSRMLS_CC); + php_pq_object_addref(obj); lob->txn = obj; - return_value->type = IS_OBJECT; - return_value->value.obj = php_pqlob_create_object_ex(php_pqlob_class_entry, lob, NULL TSRMLS_CC); + RETVAL_OBJ(&php_pqlob_create_object_ex(php_pqlob_class_entry, lob)->zo); } - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->conn); } } } @@ -727,28 +704,28 @@ ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_create_lob, 0, 0, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(pqtxn, createLOB) { zend_error_handling zeh; - long mode = INV_WRITE|INV_READ; + zend_long mode = INV_WRITE|INV_READ; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &mode); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &mode); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqtxn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Transaction not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized"); } else { Oid loid = lo_creat(obj->intern->conn->intern->conn, mode); if (loid == InvalidOid) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to create large object with mode '%s' (%s)", php_pq_strmode(mode), PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to create large object with mode '%s' (%s)", php_pq_strmode(mode), PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { int lofd = lo_open(obj->intern->conn->intern->conn, loid, mode); if (lofd < 0) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to open large object with oid=%u with mode '%s': %s", loid, php_pq_strmode(mode), PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to open large object with oid=%lu with mode '%s': %s", loid, php_pq_strmode(mode), PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { php_pqlob_t *lob = ecalloc(1, sizeof(*lob)); @@ -757,12 +734,11 @@ static PHP_METHOD(pqtxn, createLOB) { php_pq_object_addref(obj TSRMLS_CC); lob->txn = obj; - return_value->type = IS_OBJECT; - return_value->value.obj = php_pqlob_create_object_ex(php_pqlob_class_entry, lob, NULL TSRMLS_CC); + RETVAL_OBJ(&php_pqlob_create_object_ex(php_pqlob_class_entry, lob)->zo); } } - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->conn); } } } @@ -772,26 +748,26 @@ ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_unlink_lob, 0, 0, 1) ZEND_END_ARG_INFO(); static PHP_METHOD(pqtxn, unlinkLOB) { zend_error_handling zeh; - long loid; + zend_long loid; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &loid); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "l", &loid); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqtxn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Transaction not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized"); } else { int rc = lo_unlink(obj->intern->conn->intern->conn, loid); if (rc != 1) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to unlink LOB (oid=%u): %s", loid, PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to unlink LOB (oid=%lu): %s", loid, PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->conn); } } } @@ -803,19 +779,19 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(pqtxn, importLOB) { zend_error_handling zeh; char *path_str; - int path_len; - long oid = InvalidOid; + size_t path_len; + zend_long oid = InvalidOid; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|l", &path_str, &path_len, &oid); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "p|l", &path_str, &path_len, &oid); + zend_restore_error_handling(&zeh); if (rv == SUCCESS) { - php_pqtxn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Transaction not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized"); } else { if (oid == InvalidOid) { oid = lo_import(obj->intern->conn->intern->conn, path_str); @@ -824,12 +800,12 @@ static PHP_METHOD(pqtxn, importLOB) { } if (oid == InvalidOid) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to import LOB from '%s' (%s)", path_str, PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to import LOB from '%s' (%s)", path_str, PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { RETVAL_LONG(oid); } - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->conn); } } } @@ -841,27 +817,27 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(pqtxn, exportLOB) { zend_error_handling zeh; char *path_str; - int path_len; - long oid; + size_t path_len; + zend_long oid; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lp", &oid, &path_str, &path_len); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "lp", &oid, &path_str, &path_len); + zend_restore_error_handling(&zeh); if (rv == SUCCESS) { - php_pqtxn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqtxn_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Transaction not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Transaction not initialized"); } else { int rc = lo_export(obj->intern->conn->intern->conn, oid, path_str); if (rc == -1) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to export LOB (oid=%u) to '%s' (%s)", oid, path_str, PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to export LOB (oid=%lu) to '%s' (%s)", oid, path_str, PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->conn); } } } @@ -898,43 +874,47 @@ PHP_MINIT_FUNCTION(pqtxn) php_pq_object_prophandler_t ph = {0}; INIT_NS_CLASS_ENTRY(ce, "pq", "Transaction", php_pqtxn_methods); - php_pqtxn_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC); + php_pqtxn_class_entry = zend_register_internal_class_ex(&ce, NULL); php_pqtxn_class_entry->create_object = php_pqtxn_create_object; memcpy(&php_pqtxn_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + php_pqtxn_object_handlers.offset = XtOffsetOf(php_pqtxn_object_t, zo); + php_pqtxn_object_handlers.free_obj = php_pqtxn_object_free; php_pqtxn_object_handlers.read_property = php_pq_object_read_prop; php_pqtxn_object_handlers.write_property = php_pq_object_write_prop; php_pqtxn_object_handlers.clone_obj = NULL; php_pqtxn_object_handlers.get_property_ptr_ptr = NULL; - php_pqtxn_object_handlers.get_gc = NULL; + php_pqtxn_object_handlers.get_gc = php_pq_object_get_gc; php_pqtxn_object_handlers.get_properties = php_pq_object_properties; php_pqtxn_object_handlers.get_debug_info = php_pq_object_debug_info; - zend_hash_init(&php_pqtxn_object_prophandlers, 4, NULL, NULL, 1); + zend_hash_init(&php_pqtxn_object_prophandlers, 4, NULL, php_pq_object_prophandler_dtor, 1); - zend_declare_property_null(php_pqtxn_class_entry, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqtxn_class_entry, ZEND_STRL("connection"), ZEND_ACC_PUBLIC); ph.read = php_pqtxn_object_read_connection; - zend_hash_add(&php_pqtxn_object_prophandlers, "connection", sizeof("connection"), (void *) &ph, sizeof(ph), NULL); + ph.gc = php_pqtxn_object_gc_connection; + zend_hash_str_add_mem(&php_pqtxn_object_prophandlers, "connection", sizeof("connection")-1, (void *) &ph, sizeof(ph)); + ph.gc = NULL; - zend_declare_property_null(php_pqtxn_class_entry, ZEND_STRL("isolation"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqtxn_class_entry, ZEND_STRL("isolation"), ZEND_ACC_PUBLIC); ph.read = php_pqtxn_object_read_isolation; ph.write = php_pqtxn_object_write_isolation; - zend_hash_add(&php_pqtxn_object_prophandlers, "isolation", sizeof("isolation"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqtxn_object_prophandlers, "isolation", sizeof("isolation")-1, (void *) &ph, sizeof(ph)); - zend_declare_property_bool(php_pqtxn_class_entry, ZEND_STRL("readonly"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_bool(php_pqtxn_class_entry, ZEND_STRL("readonly"), 0, ZEND_ACC_PUBLIC); ph.read = php_pqtxn_object_read_readonly; ph.write = php_pqtxn_object_write_readonly; - zend_hash_add(&php_pqtxn_object_prophandlers, "readonly", sizeof("readonly"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqtxn_object_prophandlers, "readonly", sizeof("readonly")-1, (void *) &ph, sizeof(ph)); - zend_declare_property_bool(php_pqtxn_class_entry, ZEND_STRL("deferrable"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_bool(php_pqtxn_class_entry, ZEND_STRL("deferrable"), 0, ZEND_ACC_PUBLIC); ph.read = php_pqtxn_object_read_deferrable; ph.write = php_pqtxn_object_write_deferrable; - zend_hash_add(&php_pqtxn_object_prophandlers, "deferrable", sizeof("deferrable"), (void *) &ph, sizeof(ph), NULL); + zend_hash_str_add_mem(&php_pqtxn_object_prophandlers, "deferrable", sizeof("deferrable")-1, (void *) &ph, sizeof(ph)); ph.write = NULL; - zend_declare_class_constant_long(php_pqtxn_class_entry, ZEND_STRL("READ_COMMITTED"), PHP_PQTXN_READ_COMMITTED TSRMLS_CC); - zend_declare_class_constant_long(php_pqtxn_class_entry, ZEND_STRL("REPEATABLE_READ"), PHP_PQTXN_REPEATABLE_READ TSRMLS_CC); - zend_declare_class_constant_long(php_pqtxn_class_entry, ZEND_STRL("SERIALIZABLE"), PHP_PQTXN_SERIALIZABLE TSRMLS_CC); + zend_declare_class_constant_long(php_pqtxn_class_entry, ZEND_STRL("READ_COMMITTED"), PHP_PQTXN_READ_COMMITTED); + zend_declare_class_constant_long(php_pqtxn_class_entry, ZEND_STRL("REPEATABLE_READ"), PHP_PQTXN_REPEATABLE_READ); + zend_declare_class_constant_long(php_pqtxn_class_entry, ZEND_STRL("SERIALIZABLE"), PHP_PQTXN_SERIALIZABLE); return SUCCESS; } diff --git a/src/php_pqtxn.h b/src/php_pqtxn.h index 0c8fd86..82e4970 100644 --- a/src/php_pqtxn.h +++ b/src/php_pqtxn.h @@ -32,16 +32,13 @@ typedef struct php_pqtxn { } php_pqtxn_t; typedef struct php_pqtxn_object { - zend_object zo; - zend_object_value zv; - HashTable *prophandler; - php_pqtxn_t *intern; + PHP_PQ_OBJ_DECL(php_pqtxn_t *) } php_pqtxn_object_t; extern const char *php_pq_isolation_level(long *isolation); extern zend_class_entry *php_pqtxn_class_entry; -extern zend_object_value php_pqtxn_create_object_ex(zend_class_entry *ce, php_pqtxn_t *intern, php_pqtxn_object_t **ptr TSRMLS_DC); +extern php_pqtxn_object_t *php_pqtxn_create_object_ex(zend_class_entry *ce, php_pqtxn_t *intern); extern PHP_MINIT_FUNCTION(pqtxn); extern PHP_MSHUTDOWN_FUNCTION(pqtxn); diff --git a/src/php_pqtypes.c b/src/php_pqtypes.c index 6cf5741..ef169d3 100644 --- a/src/php_pqtypes.c +++ b/src/php_pqtypes.c @@ -15,7 +15,7 @@ #endif #include -#include +#include #include "php_pq.h" #include "php_pq_misc.h" @@ -28,158 +28,119 @@ zend_class_entry *php_pqtypes_class_entry; static zend_object_handlers php_pqtypes_object_handlers; static HashTable php_pqtypes_object_prophandlers; -static void php_pqtypes_object_free(void *o TSRMLS_DC) +static void php_pqtypes_object_free(zend_object *o) { - php_pqtypes_object_t *obj = o; + php_pqtypes_object_t *obj = PHP_PQ_OBJ(NULL, o); #if DBG_GC - fprintf(stderr, "FREE types(#%d) %p (conn(#%d): %p)\n", obj->zv.handle, obj, obj->intern->conn->zv.handle, obj->intern->conn); + fprintf(stderr, "FREE types(#%d) %p (conn(#%d): %p)\n", obj->zo.handle, obj, obj->intern->conn->zo.handle, obj->intern->conn); #endif if (obj->intern) { zend_hash_destroy(&obj->intern->types); - php_pq_object_delref(obj->intern->conn TSRMLS_CC); + php_pq_object_delref(obj->intern->conn); efree(obj->intern); obj->intern = NULL; } - zend_object_std_dtor((zend_object *) o TSRMLS_CC); - efree(obj); + php_pq_object_dtor(o); } -zend_object_value php_pqtypes_create_object_ex(zend_class_entry *ce, php_pqtypes_t *intern, php_pqtypes_object_t **ptr TSRMLS_DC) +php_pqtypes_object_t *php_pqtypes_create_object_ex(zend_class_entry *ce, php_pqtypes_t *intern) { - php_pqtypes_object_t *o; - - o = ecalloc(1, sizeof(*o)); - zend_object_std_init((zend_object *) o, ce TSRMLS_CC); - object_properties_init((zend_object *) o, ce); - o->prophandler = &php_pqtypes_object_prophandlers; - - if (ptr) { - *ptr = o; - } - - if (intern) { - o->intern = intern; - } - - o->zv.handle = zend_objects_store_put((zend_object *) o, NULL, php_pqtypes_object_free, NULL TSRMLS_CC); - o->zv.handlers = &php_pqtypes_object_handlers; - - return o->zv; + return php_pq_object_create(ce, intern, sizeof(php_pqtypes_object_t), + &php_pqtypes_object_handlers, &php_pqtypes_object_prophandlers); } -static zend_object_value php_pqtypes_create_object(zend_class_entry *class_type TSRMLS_DC) +static zend_object *php_pqtypes_create_object(zend_class_entry *class_type) { - return php_pqtypes_create_object_ex(class_type, NULL, NULL TSRMLS_CC); + return &php_pqtypes_create_object_ex(class_type, NULL)->zo; } -static void php_pqtypes_object_read_connection(zval *object, void *o, zval *return_value TSRMLS_DC) +static void php_pqtypes_object_read_connection(zval *object, void *o, zval *return_value) { php_pqtypes_object_t *obj = o; - php_pq_object_to_zval(obj->intern->conn, &return_value TSRMLS_CC); + php_pq_object_to_zval(obj->intern->conn, return_value); +} +static void php_pqtypes_object_gc_connection(zval *object, void *o, zval *return_value) +{ + php_pqtypes_object_t *obj = o; + zval zconn; + + php_pq_object_to_zval_no_addref(obj->intern->conn, &zconn); + add_next_index_zval(return_value, &zconn); } -static int has_dimension(HashTable *ht, zval *member, char **key_str, int *key_len, ulong *index TSRMLS_DC) +static int has_dimension(HashTable *ht, zval *member, zend_string **key, zend_long *index) { - long lval = 0; - zval *tmp = member; - - switch (Z_TYPE_P(member)) { - default: - convert_to_string_ex(&tmp); - /* no break */ - case IS_STRING: - if (!is_numeric_string(Z_STRVAL_P(tmp), Z_STRLEN_P(tmp), &lval, NULL, 0)) { - int exists = zend_hash_exists(ht, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp) + 1); - - if (key_str) { - *key_str = estrndup(Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); - if (key_len) { - *key_len = Z_STRLEN_P(tmp) + 1; - } - } - if (member != tmp) { - zval_ptr_dtor(&tmp); - } + if (Z_TYPE_P(member) == IS_LONG) { + *index = Z_LVAL_P(member); + + check_index: + return zend_hash_index_exists(ht, *index); + } else { + zend_string *str = zval_get_string(member); - return exists; + if (is_numeric_str_function(str, index, NULL)) { + zend_string_release(str); + goto check_index; } - break; - case IS_LONG: - lval = Z_LVAL_P(member); - break; - } - if (member != tmp) { - zval_ptr_dtor(&tmp); - } - if (index) { - *index = lval; + if (zend_hash_exists(ht, str)) { + *key = str; + return 1; + } + + zend_string_release(str); + return 0; } - return zend_hash_index_exists(ht, lval); } -static int php_pqtypes_object_has_dimension(zval *object, zval *member, int check_empty TSRMLS_DC) +static int php_pqtypes_object_has_dimension(zval *object, zval *member, int check_empty) { - php_pqtypes_object_t *obj = zend_object_store_get_object(object TSRMLS_CC); - char *key_str = NULL; - int key_len = 0; - ulong index = 0; - - if (check_empty) { - if (has_dimension(&obj->intern->types, member, &key_str, &key_len, &index TSRMLS_CC)) { - zval **data; - - if (key_str && key_len) { - if (SUCCESS == zend_hash_find(&obj->intern->types, key_str, key_len, (void *) &data)) { - efree(key_str); - return Z_TYPE_PP(data) != IS_NULL; - } - efree(key_str); - key_str = NULL; - } else { - if (SUCCESS == zend_hash_index_find(&obj->intern->types, index, (void *) &data)) { - return Z_TYPE_PP(data) != IS_NULL; + php_pqtypes_object_t *obj = PHP_PQ_OBJ(object, NULL); + zend_string *key = NULL; + zend_long index = 0; + + if (has_dimension(&obj->intern->types, member, &key, &index)) { + if (check_empty) { + zval *data; + + if (key) { + if ((data = zend_hash_find(&obj->intern->types, key))) { + zend_string_release(key); + return Z_TYPE_P(data) != IS_NULL; } + zend_string_release(key); + } else if ((data = zend_hash_index_find(&obj->intern->types, index))) { + return Z_TYPE_P(data) != IS_NULL; } + } else { + if (key) { + zend_string_release(key); + } + return 1; } - if (key_str) { - efree(key_str); - } - } else { - return has_dimension(&obj->intern->types, member, NULL, NULL, NULL TSRMLS_CC); } return 0; } -static zval *php_pqtypes_object_read_dimension(zval *object, zval *member, int type TSRMLS_DC) +static zval *php_pqtypes_object_read_dimension(zval *object, zval *member, int type, zval *rv) { - ulong index = 0; - char *key_str = NULL; - int key_len = 0; - php_pqtypes_object_t *obj = zend_object_store_get_object(object TSRMLS_CC); - - if (has_dimension(&obj->intern->types, member, &key_str, &key_len, &index TSRMLS_CC)) { - zval **data; - - if (key_str && key_len) { - if (SUCCESS == zend_hash_find(&obj->intern->types, key_str, key_len, (void *) &data)) { - efree(key_str); - return *data; - } + php_pqtypes_object_t *obj = PHP_PQ_OBJ(object, NULL); + zend_string *key = NULL; + zend_long index = 0; + zval *data = NULL; + + if (has_dimension(&obj->intern->types, member, &key, &index)) { + if (key) { + data = zend_hash_find(&obj->intern->types, key); + zend_string_release(key); } else { - if (SUCCESS == zend_hash_index_find(&obj->intern->types, index, (void *) &data)) { - return *data; - } + data = zend_hash_index_find(&obj->intern->types, index); } } - if (key_str) { - efree(key_str); - } - - return NULL; + return data; } ZEND_BEGIN_ARG_INFO_EX(ai_pqtypes_construct, 0, 0, 1) @@ -191,32 +152,27 @@ static PHP_METHOD(pqtypes, __construct) { zval *zconn, *znsp = NULL; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|a!", &zconn, php_pqconn_class_entry, &znsp); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "O|a!", &zconn, php_pqconn_class_entry, &znsp); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqconn_object_t *conn_obj = zend_object_store_get_object(zconn TSRMLS_CC); + php_pqconn_object_t *conn_obj = PHP_PQ_OBJ(zconn, NULL); if (!conn_obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Connection not initialized"); } else { - php_pqtypes_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); - zval *retval = NULL; + php_pqtypes_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); obj->intern = ecalloc(1, sizeof(*obj->intern)); obj->intern->conn = conn_obj; - php_pq_object_addref(conn_obj TSRMLS_CC); + php_pq_object_addref(conn_obj); zend_hash_init(&obj->intern->types, 512, NULL, ZVAL_PTR_DTOR, 0); if (znsp) { - zend_call_method_with_1_params(&getThis(), Z_OBJCE_P(getThis()), NULL, "refresh", &retval, znsp); + zend_call_method_with_1_params(getThis(), Z_OBJCE_P(getThis()), NULL, "refresh", NULL, znsp); } else { - zend_call_method_with_0_params(&getThis(), Z_OBJCE_P(getThis()), NULL, "refresh", &retval); - } - - if (retval) { - zval_ptr_dtor(&retval); + zend_call_method_with_0_params(getThis(), Z_OBJCE_P(getThis()), NULL, "refresh", NULL); } } } @@ -231,18 +187,17 @@ static PHP_METHOD(pqtypes, __construct) { # define PHP_PQ_OID_TEXT 25 #endif -static int apply_nsp(void *p TSRMLS_DC, int argc, va_list argv, zend_hash_key *key) +static int apply_nsp(zval *zp, int argc, va_list argv, zend_hash_key *key) { - zval **zp = p; unsigned pcount, tcount; php_pq_params_t *params = va_arg(argv, php_pq_params_t *); smart_str *str = va_arg(argv, smart_str *); tcount = php_pq_params_add_type_oid(params, PHP_PQ_OID_TEXT); - pcount = php_pq_params_add_param(params, *zp); + pcount = php_pq_params_add_param(params, zp); if (tcount != pcount) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Param/Type count mismatch"); + php_error_docref(NULL, E_WARNING, "Param/Type count mismatch"); return ZEND_HASH_APPLY_STOP; } if (pcount > 1) { @@ -262,15 +217,15 @@ static PHP_METHOD(pqtypes, refresh) { zend_error_handling zeh; ZEND_RESULT_CODE rv; - zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC); - rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|H/!", &nsp); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh); + rv = zend_parse_parameters(ZEND_NUM_ARGS(), "|H/!", &nsp); + zend_restore_error_handling(&zeh); if (SUCCESS == rv) { - php_pqtypes_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_pqtypes_object_t *obj = PHP_PQ_OBJ(getThis(), NULL); if (!obj->intern) { - throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Types not initialized"); + throw_exce(EX_UNINITIALIZED, "pq\\Types not initialized"); } else { PGresult *res; @@ -278,39 +233,39 @@ static PHP_METHOD(pqtypes, refresh) { res = PQexec(obj->intern->conn->intern->conn, PHP_PQ_TYPES_QUERY " and nspname in ('public', 'pg_catalog')"); } else { smart_str str = {0}; - php_pq_params_t *params = php_pq_params_init(&obj->intern->conn->intern->converters, NULL, NULL TSRMLS_CC); + php_pq_params_t *params = php_pq_params_init(&obj->intern->conn->intern->converters, NULL, NULL); smart_str_appends(&str, PHP_PQ_TYPES_QUERY " and nspname in("); zend_hash_apply_with_arguments(nsp TSRMLS_CC, apply_nsp, 2, params, &str); smart_str_appendc(&str, ')'); smart_str_0(&str); - res = PQexecParams(obj->intern->conn->intern->conn, str.c, params->param.count, params->type.oids, (const char *const*) params->param.strings, NULL, NULL, 0); + res = PQexecParams(obj->intern->conn->intern->conn, smart_str_v(&str), params->param.count, params->type.oids, (const char *const*) params->param.strings, NULL, NULL, 0); smart_str_free(&str); php_pq_params_free(¶ms); } if (!res) { - throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to fetch types (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); + throw_exce(EX_RUNTIME, "Failed to fetch types (%s)", PHP_PQerrorMessage(obj->intern->conn->intern->conn)); } else { - if (SUCCESS == php_pqres_success(res TSRMLS_CC)) { + if (SUCCESS == php_pqres_success(res)) { int r, rows; for (r = 0, rows = PQntuples(res); r < rows; ++r) { - zval *row = php_pqres_row_to_zval(res, r, PHP_PQRES_FETCH_OBJECT, NULL TSRMLS_CC); - long oid = atol(PQgetvalue(res, r, 0 )); - char *name = PQgetvalue(res, r, 1); + zval tmp, *row; + ZVAL_NULL(&tmp); + row = php_pqres_row_to_zval(res, r, PHP_PQRES_FETCH_OBJECT, &tmp); Z_ADDREF_P(row); - zend_hash_index_update(&obj->intern->types, oid, (void *) &row, sizeof(zval *), NULL); - zend_hash_update(&obj->intern->types, name, strlen(name) + 1, (void *) &row, sizeof(zval *), NULL); + zend_hash_index_update(&obj->intern->types, atol(PQgetvalue(res, r, 0 )), row); + zend_hash_str_update(&obj->intern->types, PQgetvalue(res, r, 1), PQgetlength(res, r, 1), row); } } PHP_PQclear(res); - php_pqconn_notify_listeners(obj->intern->conn TSRMLS_CC); + php_pqconn_notify_listeners(obj->intern->conn); } } } @@ -334,7 +289,7 @@ PHP_MINIT_FUNCTION(pqtypes) php_pq_object_prophandler_t ph = {0}; INIT_NS_CLASS_ENTRY(ce, "pq", "Types", php_pqtypes_methods); - php_pqtypes_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC); + php_pqtypes_class_entry = zend_register_internal_class_ex(&ce, NULL); php_pqtypes_class_entry->create_object = php_pqtypes_create_object; /* @@ -342,11 +297,13 @@ PHP_MINIT_FUNCTION(pqtypes) */ memcpy(&php_pqtypes_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + php_pqtypes_object_handlers.offset = XtOffsetOf(php_pqtypes_object_t, zo); + php_pqtypes_object_handlers.free_obj = php_pqtypes_object_free; php_pqtypes_object_handlers.read_property = php_pq_object_read_prop; php_pqtypes_object_handlers.write_property = php_pq_object_write_prop; php_pqtypes_object_handlers.clone_obj = NULL; php_pqtypes_object_handlers.get_property_ptr_ptr = NULL; - php_pqtypes_object_handlers.get_gc = NULL; + php_pqtypes_object_handlers.get_gc = php_pq_object_get_gc; php_pqtypes_object_handlers.get_properties = php_pq_object_properties; php_pqtypes_object_handlers.get_debug_info = php_pq_object_debug_info; php_pqtypes_object_handlers.has_dimension = php_pqtypes_object_has_dimension; @@ -354,14 +311,16 @@ PHP_MINIT_FUNCTION(pqtypes) php_pqtypes_object_handlers.unset_dimension = NULL; php_pqtypes_object_handlers.write_dimension = NULL; - zend_hash_init(&php_pqtypes_object_prophandlers, 1, NULL, NULL, 1); + zend_hash_init(&php_pqtypes_object_prophandlers, 1, NULL, php_pq_object_prophandler_dtor, 1); - zend_declare_property_null(php_pqtypes_class_entry, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_pqtypes_class_entry, ZEND_STRL("connection"), ZEND_ACC_PUBLIC); ph.read = php_pqtypes_object_read_connection; - zend_hash_add(&php_pqtypes_object_prophandlers, "connection", sizeof("connection"), (void *) &ph, sizeof(ph), NULL); + ph.gc = php_pqtypes_object_gc_connection; + zend_hash_str_add_mem(&php_pqtypes_object_prophandlers, "connection", sizeof("connection")-1, (void *) &ph, sizeof(ph)); + ph.gc = NULL; # undef PHP_PQ_TYPE -# define PHP_PQ_TYPE(name, oid) zend_declare_class_constant_long(php_pqtypes_class_entry, ZEND_STRL(name), oid TSRMLS_CC); +# define PHP_PQ_TYPE(name, oid) zend_declare_class_constant_long(php_pqtypes_class_entry, ZEND_STRL(name), oid); # include "php_pq_type.h" return SUCCESS; diff --git a/src/php_pqtypes.h b/src/php_pqtypes.h index 8a551b1..9e9d6d6 100644 --- a/src/php_pqtypes.h +++ b/src/php_pqtypes.h @@ -22,14 +22,11 @@ typedef struct php_pqtypes { } php_pqtypes_t; typedef struct php_pqtypes_object { - zend_object zo; - zend_object_value zv; - HashTable *prophandler; - php_pqtypes_t *intern; + PHP_PQ_OBJ_DECL(php_pqtypes_t *) } php_pqtypes_object_t; extern zend_class_entry *php_pqtypes_class_entry; -extern zend_object_value php_pqtypes_create_object_ex(zend_class_entry *ce, php_pqtypes_t *intern, php_pqtypes_object_t **ptr TSRMLS_DC); +extern php_pqtypes_object_t *php_pqtypes_create_object_ex(zend_class_entry *ce, php_pqtypes_t *intern); extern PHP_MINIT_FUNCTION(pqtypes); extern PHP_MSHUTDOWN_FUNCTION(pqtypes); diff --git a/tests/async001.phpt b/tests/async001.phpt index d1aa35b..7272272 100644 --- a/tests/async001.phpt +++ b/tests/async001.phpt @@ -38,11 +38,12 @@ while (true) { break 2; } } +$s[] = $c->status; printf("\n%s\n", implode(",", $s)); ?> DONE --EXPECTREGEX-- Test (WP(RP)*)+S -(2,)*3(,\d)*,4 +2(,\d)*,0 DONE diff --git a/tests/async002.phpt b/tests/async002.phpt index 4cc19c8..bd09863 100644 --- a/tests/async002.phpt +++ b/tests/async002.phpt @@ -40,6 +40,7 @@ function complete($c) { break 2; } } + $s[] = $c->status; printf("\n%s\n", implode(",", $s)); } @@ -54,7 +55,7 @@ DONE --EXPECTREGEX-- Test (WP(RP)*)+S -(2,)*3(,\d)*,4 +2(,\d)*,0 (WP(RP)*)+S -(2,)*3(,\d)*,4 +2(,\d)*,0 DONE diff --git a/tests/async003.phpt b/tests/async003.phpt index 9872642..9eb44df 100644 --- a/tests/async003.phpt +++ b/tests/async003.phpt @@ -16,7 +16,7 @@ do { while ($c->busy) { $r = array($c->socket); $w = $e = null; - if (stream_select($r, $w, $e, null)) { + if (stream_select($r, $w, $e, 1, 1000)) { $c->poll(); } } diff --git a/tests/basic002.phpt b/tests/basic002.phpt index 2afb785..e43b27d 100644 --- a/tests/basic002.phpt +++ b/tests/basic002.phpt @@ -13,12 +13,13 @@ $s = $c->prepare("test1", "SELECT \$1",array($t["text"]->oid)); $r = $s->exec(array("fooo")); printf("%s\n", $r->errorMessage); -$r->fetchCol($val); -printf("%s\n", $val); +var_dump($r->fetchCol($val)); +var_dump($val); ?> DONE --EXPECT-- Test -fooo +bool(true) +string(4) "fooo" DONE diff --git a/tests/bound002.phpt b/tests/bound002.phpt index 3633902..cedda91 100644 --- a/tests/bound002.phpt +++ b/tests/bound002.phpt @@ -24,22 +24,22 @@ DONE Test array(3) { [0]=> - &int(2) + int(2) [1]=> - &int(4) + int(4) [2]=> - &int(6) + int(6) } int(2) int(4) int(6) array(3) { [0]=> - &int(3) + int(3) [1]=> - &int(6) + int(6) [2]=> - &int(9) + int(9) } int(3) int(6) diff --git a/tests/lob002.phpt b/tests/lob002.phpt index 3625d89..1eacfbc 100644 --- a/tests/lob002.phpt +++ b/tests/lob002.phpt @@ -35,7 +35,7 @@ int(488) bool(true) Warning: ftruncate(): Can't truncate this stream! in %s on line %d -string(123) "