summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/sqlite/php_sqlite.h2
-rw-r--r--ext/sqlite/sqlite.c65
-rwxr-xr-xext/sqlite/tests/sqlite_017.phpt33
3 files changed, 98 insertions, 2 deletions
diff --git a/ext/sqlite/php_sqlite.h b/ext/sqlite/php_sqlite.h
index 37538ba30f..3f937e4656 100644
--- a/ext/sqlite/php_sqlite.h
+++ b/ext/sqlite/php_sqlite.h
@@ -78,6 +78,8 @@ PHP_FUNCTION(sqlite_error_string);
PHP_FUNCTION(sqlite_create_aggregate);
PHP_FUNCTION(sqlite_create_function);
+PHP_FUNCTION(sqlite_udf_decode_binary);
+PHP_FUNCTION(sqlite_udf_encode_binary);
ZEND_BEGIN_MODULE_GLOBALS(sqlite)
long assoc_case;
diff --git a/ext/sqlite/sqlite.c b/ext/sqlite/sqlite.c
index 49cdceb73c..416fab2a94 100644
--- a/ext/sqlite/sqlite.c
+++ b/ext/sqlite/sqlite.c
@@ -142,6 +142,8 @@ function_entry sqlite_functions[] = {
PHP_FE(sqlite_unbuffered_query, NULL)
PHP_FE(sqlite_create_aggregate, NULL)
PHP_FE(sqlite_create_function, NULL)
+ PHP_FE(sqlite_udf_encode_binary, NULL)
+ PHP_FE(sqlite_udf_decode_binary, NULL)
{NULL, NULL, NULL}
};
@@ -1371,8 +1373,8 @@ PHP_FUNCTION(sqlite_current)
}
/* }}} */
-/* {{{ proto array sqlite_column(resource result, mixed index_or_name [, bool decode_binary])
- Fetches a column from the current row from a result set */
+/* {{{ proto mixed sqlite_column(resource result, mixed index_or_name [, bool decode_binary])
+ Fetches a column from the current row of a result set */
PHP_FUNCTION(sqlite_column)
{
zval *zres;
@@ -1808,6 +1810,65 @@ PHP_FUNCTION(sqlite_create_function)
}
/* }}} */
+/* {{{ proto string sqlite_udf_encode_binary(string data)
+ Apply binary encoding (if required) to a string to return from an UDF */
+PHP_FUNCTION(sqlite_udf_encode_binary)
+{
+ char *data = NULL;
+ long datalen;
+
+ if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!", &data, &datalen)) {
+ return;
+ }
+
+ if (data == NULL) {
+ RETURN_NULL();
+ }
+ if (datalen && (data[0] == '\x01' || memchr(data, '\0', datalen) != NULL)) {
+ /* binary string */
+ int enclen;
+ char *ret;
+
+ ret = emalloc( 1 + ((256 * datalen + 1262) / 253) );
+ ret[0] = '\x01';
+ enclen = sqlite_encode_binary((const unsigned char*)data, datalen, ret+1);
+ RETVAL_STRINGL(ret, enclen+1, 0);
+ } else {
+ RETVAL_STRINGL(data, datalen, 1);
+ }
+}
+/* }}} */
+
+/* {{{ proto string sqlite_udf_decode_binary(string data)
+ Decode binary encoding on a string parameter passed to an UDF */
+PHP_FUNCTION(sqlite_udf_decode_binary)
+{
+ char *data = NULL;
+ long datalen;
+
+ if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!", &data, &datalen)) {
+ return;
+ }
+
+ if (data == NULL) {
+ RETURN_NULL();
+ }
+ if (datalen && data[0] == '\x01') {
+ /* encoded string */
+ int enclen;
+ char *ret;
+
+ ret = emalloc(datalen);
+ enclen = sqlite_decode_binary((const unsigned char*)data+1, ret);
+ ret[enclen] = '\0';
+ RETVAL_STRINGL(ret, enclen, 0);
+ } else {
+ RETVAL_STRINGL(data, datalen, 1);
+ }
+}
+/* }}} */
+
+
/*
* Local variables:
* tab-width: 4
diff --git a/ext/sqlite/tests/sqlite_017.phpt b/ext/sqlite/tests/sqlite_017.phpt
new file mode 100755
index 0000000000..9058622f99
--- /dev/null
+++ b/ext/sqlite/tests/sqlite_017.phpt
@@ -0,0 +1,33 @@
+--TEST--
+sqlite: UDF binary handling functions
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded("sqlite")) print "skip"; ?>
+--FILE--
+<?php
+
+$data = array(
+ "hello there",
+ "this has a \x00 char in the middle",
+ "\x01 this has an 0x01 at the start",
+ "this has \x01 in the middle"
+ );
+
+foreach ($data as $item) {
+ $coded = sqlite_udf_encode_binary($item);
+ echo bin2hex($coded) . "\n";
+ $decoded = sqlite_udf_decode_binary($coded);
+ if ($item != $decoded) {
+ echo "FAIL! $item decoded is $decoded\n";
+ }
+}
+
+echo "OK!\n";
+
+?>
+--EXPECT--
+68656c6c6f207468657265
+0101736768721f6760721f601fff1f626760711f686d1f7367641f6c6863636b64
+0102ff1e726667711e665f711e5f6c1e2e762e2f1e5f721e7266631e71725f7072
+7468697320686173200120696e20746865206d6964646c65
+OK!