📄 mysqlnd_ps_codec.c
字号:
/* +----------------------------------------------------------------------+ | PHP Version 6 | +----------------------------------------------------------------------+ | Copyright (c) 2006-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Authors: Georg Richter <georg@mysql.com> | | Andrey Hristov <andrey@mysql.com> | | Ulf Wendel <uwendel@mysql.com> | +----------------------------------------------------------------------+*//* $Id: header,v 1.17 2006/01/01 13:09:48 sniper Exp $ */#include "php.h"#include "mysqlnd.h"#include "mysqlnd_wireprotocol.h"#include "mysqlnd_priv.h"#define MYSQLND_SILENTtypedef int8 my_int8;typedef uint8 my_uint8;typedef int16 my_int16;typedef uint16 my_uint16;typedef int32 my_int32;typedef uint32 my_uint32;enum mysqlnd_timestamp_type{ MYSQLND_TIMESTAMP_NONE= -2, MYSQLND_TIMESTAMP_ERROR= -1, MYSQLND_TIMESTAMP_DATE= 0, MYSQLND_TIMESTAMP_DATETIME= 1, MYSQLND_TIMESTAMP_TIME= 2};struct st_mysqlnd_time{ unsigned int year, month, day, hour, minute, second; unsigned long second_part; zend_bool neg; enum mysqlnd_timestamp_type time_type;};struct st_mysqlnd_perm_bind mysqlnd_ps_fetch_functions[MYSQL_TYPE_LAST + 1];#define MYSQLND_PS_SKIP_RESULT_W_LEN -1#define MYSQLND_PS_SKIP_RESULT_STR -2/* {{{ ps_fetch_null */staticvoid ps_fetch_null(zval *zv, const MYSQLND_FIELD * const field, uint pack_len, zend_uchar **row, zend_bool as_unicode TSRMLS_DC){ ZVAL_NULL(zv);}/* }}} *//* {{{ ps_fetch_int8 */staticvoid ps_fetch_int8(zval *zv, const MYSQLND_FIELD * const field, uint pack_len, zend_uchar **row, zend_bool as_unicode TSRMLS_DC){ if (field->flags & UNSIGNED_FLAG) { ZVAL_LONG(zv, *(my_uint8*)*row); } else { ZVAL_LONG(zv, *(my_int8*)*row); } (*row)++;}/* }}} *//* {{{ ps_fetch_int16 */staticvoid ps_fetch_int16(zval *zv, const MYSQLND_FIELD * const field, uint pack_len, zend_uchar **row, zend_bool as_unicode TSRMLS_DC){ if (field->flags & UNSIGNED_FLAG) { ZVAL_LONG(zv, (my_uint16) sint2korr(*row)); } else { ZVAL_LONG(zv, (my_int16) sint2korr(*row)); } (*row)+= 2;}/* }}} *//* {{{ ps_fetch_int32 */staticvoid ps_fetch_int32(zval *zv, const MYSQLND_FIELD * const field, uint pack_len, zend_uchar **row, zend_bool as_unicode TSRMLS_DC){ if (field->flags & UNSIGNED_FLAG) { my_uint32 uval; /* unsigned int (11) */ uval= (my_uint32) sint4korr(*row);#if SIZEOF_LONG==4 if (uval > INT_MAX) { char *tmp, *p; int j=10; tmp= emalloc(11); p= &tmp[9]; do { *p-- = (uval % 10) + 48; uval = uval / 10; } while (--j > 0); tmp[10]= '\0'; /* unsigned int > INT_MAX is 10 digits - ALWAYS */#if PHP_MAJOR_VERSION >= 6 if (!as_unicode) {#endif ZVAL_STRING(zv, tmp, 0);#if PHP_MAJOR_VERSION >= 6 } else { ZVAL_UTF8_STRINGL(zv, tmp, 10, ZSTR_AUTOFREE); }#endif /* PHP_MAJOR_VERSION >= 6 */ } else #endif /* #if SIZEOF_LONG==4 */ { ZVAL_LONG(zv, uval); } } else { ZVAL_LONG(zv, (my_int32) sint4korr(*row)); } (*row)+= 4;}/* }}} *//* {{{ ps_fetch_int64 */staticvoid ps_fetch_int64(zval *zv, const MYSQLND_FIELD * const field, uint pack_len, zend_uchar **row, zend_bool as_unicode TSRMLS_DC){ my_uint64 llval = (my_uint64) sint8korr(*row); zend_bool uns = field->flags & UNSIGNED_FLAG? TRUE:FALSE; #if SIZEOF_LONG==8 if (uns == TRUE && llval > 9223372036854775807L) {#elif SIZEOF_LONG==4 if ((uns == TRUE && llval > L64(2147483647)) || (uns == FALSE && (( L64(2147483647) < (my_int64) llval) || (L64(-2147483648) > (my_int64) llval)))) {#endif char tmp[22]; /* even though lval is declared as unsigned, the value * may be negative. Therefor we cannot use MYSQLND_LLU_SPEC and must * use MYSQLND_LL_SPEC. */ sprintf((char *)&tmp, uns == TRUE? MYSQLND_LLU_SPEC : MYSQLND_LL_SPEC, llval);#if PHP_MAJOR_VERSION >= 6 if (!as_unicode) {#endif ZVAL_STRING(zv, tmp, 1);#if PHP_MAJOR_VERSION >= 6 } else { ZVAL_UTF8_STRING(zv, tmp, ZSTR_DUPLICATE); }#endif } else { ZVAL_LONG(zv, llval); } (*row)+= 8;}/* }}} *//* {{{ ps_fetch_float */staticvoid ps_fetch_float(zval *zv, const MYSQLND_FIELD * const field, uint pack_len, zend_uchar **row, zend_bool as_unicode TSRMLS_DC){ float value; float4get(value, *row); ZVAL_DOUBLE(zv, value); (*row)+= 4;}/* }}} *//* {{{ ps_fetch_double */staticvoid ps_fetch_double(zval *zv, const MYSQLND_FIELD * const field, uint pack_len, zend_uchar **row, zend_bool as_unicode TSRMLS_DC){ double value; float8get(value, *row); ZVAL_DOUBLE(zv, value); (*row)+= 8;}/* }}} *//* {{{ ps_fetch_time */staticvoid ps_fetch_time(zval *zv, const MYSQLND_FIELD * const field, uint pack_len, zend_uchar **row, zend_bool as_unicode TSRMLS_DC){ struct st_mysqlnd_time t; unsigned int length; /* First byte encodes the length*/ char *to; if ((length = php_mysqlnd_net_field_length(row))) { zend_uchar *to= *row; t.time_type = MYSQLND_TIMESTAMP_TIME; t.neg = (zend_bool) to[0]; t.day = (unsigned long) sint4korr(to+1); t.hour = (unsigned int) to[5]; t.minute = (unsigned int) to[6]; t.second = (unsigned int) to[7]; t.second_part = (length > 8) ? (unsigned long) sint4korr(to+8) : 0; t.year = t.month= 0; if (t.day) { /* Convert days to hours at once */ t.hour += t.day*24; t.day = 0; } (*row) += length; } else { memset(&t, 0, sizeof(t)); t.time_type = MYSQLND_TIMESTAMP_TIME; } /* QQ : How to make this unicode without copying two times the buffer - Unicode equivalent of spprintf? */ length = spprintf(&to, 0, "%s%02u:%02u:%02u", (t.neg ? "-" : ""), t.hour, t.minute, t.second);#if PHP_MAJOR_VERSION >= 6 if (!as_unicode) {#endif ZVAL_STRINGL(zv, to, length, 1); efree(to);#if PHP_MAJOR_VERSION >= 6 } else { ZVAL_UTF8_STRINGL(zv, to, length, ZSTR_AUTOFREE); }#endif}/* }}} *//* {{{ ps_fetch_date */staticvoid ps_fetch_date(zval *zv, const MYSQLND_FIELD * const field, uint pack_len, zend_uchar **row, zend_bool as_unicode TSRMLS_DC){ struct st_mysqlnd_time t = {0}; unsigned int length; /* First byte encodes the length*/ char *to; if ((length = php_mysqlnd_net_field_length(row))) { zend_uchar *to= *row; t.time_type= MYSQLND_TIMESTAMP_DATE; t.neg= 0; t.second_part = t.hour = t.minute = t.second = 0; t.year = (unsigned int) sint2korr(to); t.month = (unsigned int) to[2]; t.day = (unsigned int) to[3]; (*row)+= length; } else { memset(&t, 0, sizeof(t)); t.time_type = MYSQLND_TIMESTAMP_DATE; } /* QQ : How to make this unicode without copying two times the buffer - Unicode equivalent of spprintf? */ length = spprintf(&to, 0, "%04u-%02u-%02u", t.year, t.month, t.day);#if PHP_MAJOR_VERSION >= 6 if (!as_unicode) {#endif ZVAL_STRINGL(zv, to, length, 1); efree(to);#if PHP_MAJOR_VERSION >= 6 } else { ZVAL_UTF8_STRINGL(zv, to, length, ZSTR_AUTOFREE); }#endif}/* }}} *//* {{{ ps_fetch_datetime */staticvoid ps_fetch_datetime(zval *zv, const MYSQLND_FIELD * const field, uint pack_len, zend_uchar **row, zend_bool as_unicode TSRMLS_DC){ struct st_mysqlnd_time t; unsigned int length; /* First byte encodes the length*/ char *to; if ((length = php_mysqlnd_net_field_length(row))) { zend_uchar *to= *row; t.time_type = MYSQLND_TIMESTAMP_DATETIME; t.neg = 0; t.year = (unsigned int) sint2korr(to); t.month = (unsigned int) to[2]; t.day = (unsigned int) to[3]; if (length > 4) { t.hour = (unsigned int) to[4]; t.minute = (unsigned int) to[5]; t.second = (unsigned int) to[6]; } else { t.hour = t.minute = t.second= 0; } t.second_part = (length > 7) ? (unsigned long) sint4korr(to+7) : 0; (*row)+= length; } else { memset(&t, 0, sizeof(t)); t.time_type = MYSQLND_TIMESTAMP_DATETIME; } /* QQ : How to make this unicode without copying two times the buffer - Unicode equivalent of spprintf? */ length = spprintf(&to, 0, "%04u-%02u-%02u %02u:%02u:%02u", t.year, t.month, t.day, t.hour, t.minute, t.second);#if PHP_MAJOR_VERSION >= 6 if (!as_unicode) {#endif ZVAL_STRINGL(zv, to, length, 1); efree(to);#if PHP_MAJOR_VERSION >= 6 } else { ZVAL_UTF8_STRINGL(zv, to, length, ZSTR_AUTOFREE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -