/* {{{ ps_fetch_int64 */
static
void ps_fetch_int64(MYSQL_BIND *r_param, const MYSQL_FIELD * const field,
           unsigned char **row)
{
  switch(r_param->buffer_type)
  {
/*    case MYSQL_TYPE_TINY:
      ps_fetch_from_1_to_8_bytes(r_param, field, row, 1);
      break;
    case MYSQL_TYPE_YEAR:
    case MYSQL_TYPE_SHORT:
      ps_fetch_from_1_to_8_bytes(r_param, field, row, 2);
      break;
    case MYSQL_TYPE_INT24:
    case MYSQL_TYPE_LONG:
      ps_fetch_from_1_to_8_bytes(r_param, field, row, 4);
      break; */
    case MYSQL_TYPE_LONGLONG:
      ps_fetch_from_1_to_8_bytes(r_param, field, row, 8);
    break;
    default:
    {
      longlong sval= (longlong)sint8korr(*row);
      longlong lval= field->flags & UNSIGNED_FLAG ? (ulonglong) sval : (longlong)sval;
      convert_from_long(r_param, field, lval, field->flags & UNSIGNED_FLAG);
      (*row) += 8;
    }
    break;
  }
}
/* {{{ ps_fetch_from_1_to_8_bytes */
void ps_fetch_from_1_to_8_bytes(MYSQL_BIND *r_param, const MYSQL_FIELD * const field,
                unsigned char **row, unsigned int byte_count)
{
  my_bool is_unsigned= test(field->flags & UNSIGNED_FLAG);
  r_param->buffer_length= byte_count;
  switch (byte_count) {
    case 1:
      *(uchar *)r_param->buffer= **row;
      *r_param->error= is_unsigned != r_param->is_unsigned && *(uchar *)r_param->buffer > INT_MAX8;
      break;
    case 2:
      shortstore(r_param->buffer, ((ushort) sint2korr(*row)));
      *r_param->error= is_unsigned != r_param->is_unsigned && *(ushort *)r_param->buffer > INT_MAX16;
      break;
    case 4:
    {
      longstore(r_param->buffer, ((uint32)sint4korr(*row)));
      *r_param->error= is_unsigned != r_param->is_unsigned && *(uint32 *)r_param->buffer > INT_MAX32;
    }
    break;
    case 8:
      {
        ulonglong val= (ulonglong)sint8korr(*row);
        longlongstore(r_param->buffer, val);
        *r_param->error= is_unsigned != r_param->is_unsigned && val > LONGLONG_MAX ;
      }
      break;
    default:
      r_param->buffer_length= 0;
      break;
  }
  (*row)+= byte_count;
}
Esempio n. 3
0
/* {{{ ps_fetch_from_1_to_8_bytes */
void ps_fetch_from_1_to_8_bytes(zval *zv, const MYSQLND_FIELD * const field,
								unsigned int pack_len, zend_uchar **row, zend_bool as_unicode,
								unsigned int byte_count TSRMLS_DC)
{
	char tmp[22];
	size_t tmp_len = 0;
	zend_bool is_bit = field->type == MYSQL_TYPE_BIT;
	DBG_ENTER("ps_fetch_from_1_to_8_bytes");
	DBG_INF_FMT("zv=%p byte_count=%d", zv, byte_count);
	if (field->flags & UNSIGNED_FLAG) {
		uint64_t uval = 0;

		switch (byte_count) {
			case 8:uval = is_bit? (uint64_t) bit_uint8korr(*row):(uint64_t) uint8korr(*row);break;
			case 7:uval = bit_uint7korr(*row);break;
			case 6:uval = bit_uint6korr(*row);break;
			case 5:uval = bit_uint5korr(*row);break;
			case 4:uval = is_bit? (uint64_t) bit_uint4korr(*row):(uint64_t) uint4korr(*row);break;
			case 3:uval = is_bit? (uint64_t) bit_uint3korr(*row):(uint64_t) uint3korr(*row);break;
			case 2:uval = is_bit? (uint64_t) bit_uint2korr(*row):(uint64_t) uint2korr(*row);break;
			case 1:uval = (uint64_t) uint1korr(*row);break;
		}

#if SIZEOF_LONG==4
		if (uval > INT_MAX) {
			DBG_INF("stringify");
			tmp_len = sprintf((char *)&tmp, MYSQLND_LLU_SPEC, uval);
		} else 
#endif /* #if SIZEOF_LONG==4 */
		{
			if (byte_count < 8 || uval <= L64(9223372036854775807)) {
				ZVAL_LONG(zv, uval);
			} else {
				DBG_INF("stringify");
				tmp_len = sprintf((char *)&tmp, MYSQLND_LLU_SPEC, uval);
			}
		}
	} else {
		/* SIGNED */
		int64_t lval = 0;
		switch (byte_count) {
			case 8:lval = (int64_t) sint8korr(*row);break;
			/*
			  7, 6 and 5 are not possible.
			  BIT is only unsigned, thus only uint5|6|7 macroses exist
			*/
			case 4:lval = (int64_t) sint4korr(*row);break;
			case 3:lval = (int64_t) sint3korr(*row);break;
			case 2:lval = (int64_t) sint2korr(*row);break;
			case 1:lval = (int64_t) *(int8_t*)*row;break;
		}

#if SIZEOF_LONG==4
	    if ((L64(2147483647) < (int64_t) lval) || (L64(-2147483648) > (int64_t) lval)) {
			DBG_INF("stringify");
			tmp_len = sprintf((char *)&tmp, MYSQLND_LL_SPEC, lval);
		} else 
#endif /* SIZEOF */
		{
			ZVAL_LONG(zv, lval);
		}
	}

	if (tmp_len) {
#if PHP_MAJOR_VERSION >= 6
		if (as_unicode) {
			DBG_INF("stringify");
			ZVAL_UTF8_STRINGL(zv, tmp, tmp_len, ZSTR_DUPLICATE);
		} else
#endif
		{
			DBG_INF("stringify");
			ZVAL_STRINGL(zv, tmp, tmp_len, 1);
		}			
	}
	(*row)+= byte_count;
	DBG_VOID_RETURN;
}
Esempio n. 4
0
/**************************************************

   read data in binary type 

**************************************************/ 
int mysac_decode_binary_row(char *buf, int packet_len,
                            MYSAC_RES *res, MYSAC_ROWS *row) {
	int j;
	int i;
	char nul;
	unsigned long len;
	int tmp_len;
	char *wh;
	char _null_ptr[16];
	char *null_ptr;
	unsigned char bit;

	wh = buf;
	null_ptr = _null_ptr;
	bit = 4; /* first 2 bits are reserved */

	/* first bit is unused */
	i = 1;

	/* skip null bits */
	tmp_len = ( (res->nb_cols + 9) / 8 );
	if (i + tmp_len > packet_len)
		return -1;

	memcpy(_null_ptr, &buf[i], tmp_len);
	i += tmp_len;

	for (j = 0; j < res->nb_cols; j++) {

		/*
		   We should set both row_ptr and is_null to be able to see
		   nulls in mysql_stmt_fetch_column. This is because is_null may point
		   to user data which can be overwritten between mysql_stmt_fetch and
		   mysql_stmt_fetch_column, and in this case nullness of column will be
		   lost. See mysql_stmt_fetch_column for details.
		 */
		if ( (*null_ptr & bit) != 0 ) {
			/* do nothing */
		}

		else {
			switch (res->cols[j].type) {
	
			/* read null */
			case MYSQL_TYPE_NULL:
				row->data[j].blob = NULL;
	
			/* read blob */
			case MYSQL_TYPE_TINY_BLOB:
			case MYSQL_TYPE_MEDIUM_BLOB:
			case MYSQL_TYPE_LONG_BLOB:
			case MYSQL_TYPE_BLOB:
			/* decimal ? maybe for very big num ... crypto key ? */
			case MYSQL_TYPE_DECIMAL:
			case MYSQL_TYPE_NEWDECIMAL:
			/* .... */
			case MYSQL_TYPE_BIT:
			/* read text */
			case MYSQL_TYPE_STRING:
			case MYSQL_TYPE_VAR_STRING:
			case MYSQL_TYPE_VARCHAR:
			/* read date */
			case MYSQL_TYPE_NEWDATE:
				tmp_len = my_lcb(&buf[i], &len, &nul, packet_len-i);
				if (tmp_len == -1)
					return -1;
				i += tmp_len;
				if (i + len > (unsigned int)packet_len)
					return -1;
				if (nul == 1)
					row->data[j].blob = NULL;
				else {
					memmove(wh, &buf[i], len);
					row->data[j].blob = wh;
					row->data[j].blob[len] = '\0';
					i += len;
					wh += len + 1;
				}
				row->lengths[j] = len;
				break;
	
			case MYSQL_TYPE_TINY:
				if (i > packet_len - 1)
					return -1;
				row->data[j].stiny = buf[i];
				i++;
				break;
	
			case MYSQL_TYPE_SHORT:
				if (i > packet_len - 2)
					return -1;
				row->data[j].ssmall = sint2korr(&buf[i]);
				i += 2;
				break;
	
			case MYSQL_TYPE_INT24:
			case MYSQL_TYPE_LONG:
				if (i > packet_len - 4)
					return -1;
				row->data[j].sint = sint4korr(&buf[i]);
				i += 4;
				break;
	
			case MYSQL_TYPE_LONGLONG:
				if (i > packet_len - 8)
					return -1;
				row->data[j].sbigint = sint8korr(&buf[i]);
				i += 8;
				break;
	
			case MYSQL_TYPE_FLOAT:
				if (i > packet_len - 4)
					return -1;
				float4get(row->data[j].mfloat, &buf[i]);
				i += 4;
				break;
	
			case MYSQL_TYPE_DOUBLE:
				if (i > packet_len - 8)
					return -1;
				float8get(row->data[j].mdouble, &buf[i]);
				i += 8;
				break;
	
			/* libmysql/libmysql.c:3370
			 * static void read_binary_time(MYSQL_TIME *tm, uchar **pos) */
			case MYSQL_TYPE_TIME:
				tmp_len = my_lcb(&buf[i], &len, &nul, packet_len-i);
				if (tmp_len == -1)
					return -1;
				i += tmp_len;
				if (i + len > (unsigned int)packet_len)
					return -1;
				if (nul == 1)
					row->data[j].blob = NULL;
	
				if (len > 0) {
					row->data[j].tv.tv_sec = 
					              ( uint4korr(&buf[i+1]) * 86400 ) +
					              ( buf[i+5] * 3600 ) +
					              ( buf[i+6] * 60 ) +
					                buf[i+7];
					if (buf[i] != 0)
						row->data[j].tv.tv_sec = - row->data[j].tv.tv_sec;
					if (len > 8)
						row->data[j].tv.tv_usec = uint4korr(&buf[i+8]);
					else
						row->data[j].tv.tv_usec = 0;
				}
				i += len;
				break;
	
			case MYSQL_TYPE_YEAR:
				row->data[j].tm->tm_year = uint2korr(&buf[i]) - 1900;
				row->data[j].tm->tm_mday = 1;
				i += 2;
				break;
	
			/* libmysql/libmysql.c:3400
			 * static void read_binary_datetime(MYSQL_TIME *tm, uchar **pos) */
			case MYSQL_TYPE_TIMESTAMP:
			case MYSQL_TYPE_DATETIME:
				tmp_len = my_lcb(&buf[i], &len, &nul, packet_len-i);
				if (tmp_len == -1)
					return -1;
				i += tmp_len;
				if (i + len > (unsigned int)packet_len)
					return -1;
				if (nul == 1)
					row->data[j].blob = NULL;
	
				row->data[j].tm->tm_year = uint2korr(&buf[i+0]) - 1900;
				row->data[j].tm->tm_mon  = buf[i+2] - 1;
				row->data[j].tm->tm_mday = buf[i+3];
				if (len > 4) {
					row->data[j].tm->tm_hour = buf[i+4];
					row->data[j].tm->tm_min  = buf[i+5];
					row->data[j].tm->tm_sec  = buf[i+6];
				}
				if (len > 7) {
					/* les microsecondes ... */
				}
				i += len;
				break;
	
			/* libmysql/libmysql.c:3430
			 * static void read_binary_date(MYSQL_TIME *tm, uchar **pos) */
			case MYSQL_TYPE_DATE:
				tmp_len = my_lcb(&buf[i], &len, &nul, packet_len-i);
				if (tmp_len == -1)
					return -1;
				i += tmp_len;
				if (i + len > (unsigned int)packet_len)
					return -1;
				if (nul == 1)
					row->data[j].blob = NULL;
	
				row->data[j].tm->tm_year = uint2korr(&buf[i+0]) - 1900;
				row->data[j].tm->tm_mon  = buf[i+2] - 1;
				row->data[j].tm->tm_mday = buf[i+3];
				i += len;
				break;
	
			case MYSQL_TYPE_ENUM:
			case MYSQL_TYPE_SET:
			case MYSQL_TYPE_GEOMETRY:
				break;
			}
		}

		/* To next bit */
		bit <<= 1;

		/* To next byte */
		if ( (bit & 255) == 0 ) {
			bit = 1;
			null_ptr++;
		}
	}
	return wh - buf;
}