const char* Field_set::unpack(const char* from) { ulonglong tmp; switch(pack_length()) { case 1: tmp = ulonglong(*((unsigned char*)(from))); break; case 2: tmp = ulonglong(uint2korr(from)); break; case 3: tmp = ulonglong(uint3korr(from)); break; case 4: tmp = ulonglong(uint4korr(from)); break; case 8: tmp = uint8korr(from); break; default: tmp = uint8korr(from); break; } field_data = tmp; LOG_TRACE(log, " set: " << tmp << " // " << pack_length()); return from + pack_length(); }
/* The same as above but returns longlong */ my_ulonglong net_field_length_ll(uchar **packet) { uchar *pos= *packet; if (*pos < 251) { (*packet)++; return (my_ulonglong) *pos; } if (*pos == 251) { (*packet)++; return (my_ulonglong) NULL_LENGTH; } if (*pos == 252) { (*packet)+=3; return (my_ulonglong) uint2korr(pos+1); } if (*pos == 253) { (*packet)+=4; return (my_ulonglong) uint3korr(pos+1); } DBUG_ASSERT(*pos == 254); (*packet)+=9; /* Must be 254 when here */ return (my_ulonglong) uint8korr(pos+1); }
/* The same as above but returns longlong */ my_ulonglong net_field_length_ll(uchar **packet) { reg1 uchar *pos= *packet; if (*pos < 251) { (*packet)++; return (my_ulonglong) *pos; } if (*pos == 251) { (*packet)++; return (my_ulonglong) NULL_LENGTH; } if (*pos == 252) { (*packet)+=3; return (my_ulonglong) uint2korr(pos+1); } if (*pos == 253) { (*packet)+=4; return (my_ulonglong) uint3korr(pos+1); } (*packet)+=9; /* Must be 254 when here */ #ifdef NO_CLIENT_LONGLONG return (my_ulonglong) uint4korr(pos+1); #else return (my_ulonglong) uint8korr(pos+1); #endif }
const char* Field_longlong::unpack(const char* from) { ulonglong tmp = uint8korr(from); field_data = tmp; LOG_TRACE(log, " longlong: " << tmp << " // " << pack_length()); return from + pack_length(); }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int CIntvarLogEvent::tune(uint8_t* data, size_t size, const CFormatDescriptionLogEvent& fmt) { int rc = CLogEvent::tune(data, size, fmt); if (rc == 0) { data += fmt._common_header_len + fmt._post_header_len[INTVAR_EVENT-1]; _type = data[I_TYPE_OFFSET]; _val = uint8korr(data+I_VAL_OFFSET); } return rc; }
// numeric template<class T> T as_int() const { if (is_null() || !is_valid() || sizeof(T)>8) return (T)0; switch (_size) { case 1: return (T)*_storage; case 2: return (T)uint2korr(_storage); case 3: return (T)uint3korr(_storage); case 4: return (T)uint4korr(_storage); case 8: return (T)uint8korr(_storage); } return (T)0; }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * CRotateLogEvent * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int CRotateLogEvent::tune(uint8_t* data, size_t size, const CFormatDescriptionLogEvent& fmt) { int rc = CLogEvent::tune(data, size, fmt); if (rc == 0) { data += fmt._common_header_len; size -= fmt._common_header_len; _position = uint8korr(data); _new_log = data + 8; _len = size - 8; } return rc; }
const char* Field_datetime::unpack(const char* from) { ulonglong tmp; if (is_old_storage) { tmp = uint8korr(from); } else { // !! we ignore fractional part // 5 bytes + fractional-seconds storage, big endian // --------------------------- // 1 bit sign (1= non-negative, 0= negative) // 17 bits year*13+month (year 0-9999, month 0-12) // 5 bits day (0-31) // 5 bits hour (0-23) // 6 bits minute (0-59) // 6 bits second (0-59) // --------------------------- // 40 bits = 5 bytes ulonglong data; for (unsigned int i = 0; i < 5; ++i) *((unsigned char *)&data + 4 - i) = *(from + i); tmp = data & 63; data >>= 6; tmp += (data & 63) * 100; data >>= 6; tmp += (data & 31) * 10000; data >>= 5; tmp += (data & 31) * 1000000; data >>= 5; ulonglong year_month = data & ((1 << 17) - 1); tmp += year_month % 13 * 100000000; tmp += year_month / 13 * 10000000000; } field_data = tmp; LOG_TRACE(log, " datetime: " << tmp << " // " << pack_length()); return from + pack_length(); }
my_ulonglong safe_net_field_length_ll(uchar **packet, size_t packet_len) { uchar *pos= *packet; if (packet_len < 1) goto err; if (*pos < 251) { (*packet)++; return (my_ulonglong) *pos; } if (*pos == 251) { (*packet)++; return (my_ulonglong) NULL_LENGTH; } if (*pos == 252) { if (packet_len < 3) goto err; (*packet)+=3; return (my_ulonglong) uint2korr(pos+1); } if (*pos == 253) { if (packet_len < 4) goto err; (*packet)+=4; return (my_ulonglong) uint3korr(pos+1); } if (packet_len < 9 || *pos != 254) goto err; (*packet)+=9; return (my_ulonglong) uint8korr(pos+1); err: *packet = NULL; return 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; }
xb_rstream_result_t xb_stream_read_chunk(xb_rstream_t *stream, xb_rstream_chunk_t *chunk) { uchar tmpbuf[16]; uchar *ptr = tmpbuf; uint pathlen; size_t tlen; size_t tbytes; ulonglong ullval; ulong checksum_exp; ulong checksum;; File fd = stream->fd; xb_ad(sizeof(tmpbuf) >= CHUNK_HEADER_CONSTANT_LEN); /* This is the only place where we expect EOF, so read with my_read() rather than F_READ() */ tlen = CHUNK_HEADER_CONSTANT_LEN; while (tlen > 0) { tbytes = my_read(fd, ptr, tlen, MYF(MY_WME)); if (tbytes == 0) { break; } ptr += tbytes; tlen -= tbytes; } if (tlen == CHUNK_HEADER_CONSTANT_LEN) { return XB_STREAM_READ_EOF; } else if (tlen > 0) { msg("xb_stream_read_chunk(): unexpected end of stream at " "offset 0x%llx.\n", stream->offset); goto err; } ptr = tmpbuf; /* Chunk magic value */ if (memcmp(tmpbuf, XB_STREAM_CHUNK_MAGIC, 8)) { msg("xb_stream_read_chunk(): wrong chunk magic at offset " "0x%llx.\n", (ulonglong) stream->offset); goto err; } ptr += 8; stream->offset += 8; /* Chunk flags */ chunk->flags = *ptr++; stream->offset++; /* Chunk type, ignore unknown ones if ignorable flag is set */ chunk->type = validate_chunk_type(*ptr); if (chunk->type == XB_CHUNK_TYPE_UNKNOWN && !(chunk->flags & XB_STREAM_FLAG_IGNORABLE)) { msg("xb_stream_read_chunk(): unknown chunk type 0x%lu at " "offset 0x%llx.\n", (ulong) *ptr, (ulonglong) stream->offset); goto err; } ptr++; stream->offset++; /* Path length */ pathlen = uint4korr(ptr); if (pathlen >= FN_REFLEN) { msg("xb_stream_read_chunk(): path length (%lu) is too large at " "offset 0x%llx.\n", (ulong) pathlen, stream->offset); goto err; } chunk->pathlen = pathlen; stream->offset +=4; xb_ad((ptr + 4 - tmpbuf) == CHUNK_HEADER_CONSTANT_LEN); /* Path */ if (chunk->pathlen > 0) { F_READ((uchar *) chunk->path, pathlen); stream->offset += pathlen; } chunk->path[pathlen] = '\0'; if (chunk->type == XB_CHUNK_TYPE_EOF) { return XB_STREAM_READ_CHUNK; } /* Payload length */ F_READ(tmpbuf, 16); ullval = uint8korr(tmpbuf); if (ullval > (ulonglong) SIZE_T_MAX) { msg("xb_stream_read_chunk(): chunk length is too large at " "offset 0x%llx: 0x%llx.\n", (ulonglong) stream->offset, ullval); goto err; } chunk->length = (size_t) ullval; stream->offset += 8; /* Payload offset */ ullval = uint8korr(tmpbuf + 8); if (ullval > (ulonglong) MY_OFF_T_MAX) { msg("xb_stream_read_chunk(): chunk offset is too large at " "offset 0x%llx: 0x%llx.\n", (ulonglong) stream->offset, ullval); goto err; } chunk->offset = (my_off_t) ullval; stream->offset += 8; /* Reallocate the buffer if needed */ if (chunk->length > stream->buflen) { stream->buffer = my_realloc(stream->buffer, chunk->length, MYF(MY_WME)); if (stream->buffer == NULL) { msg("xb_stream_read_chunk(): failed to increase buffer " "to %lu bytes.\n", (ulong) chunk->length); goto err; } stream->buflen = chunk->length; } /* Checksum */ F_READ(tmpbuf, 4); checksum_exp = uint4korr(tmpbuf); /* Payload */ if (chunk->length > 0) { F_READ(stream->buffer, chunk->length); stream->offset += chunk->length; } checksum = crc32(0, stream->buffer, chunk->length); if (checksum != checksum_exp) { msg("xb_stream_read_chunk(): invalid checksum at offset " "0x%llx: expected 0x%lx, read 0x%lx.\n", (ulonglong) stream->offset, checksum_exp, checksum); goto err; } stream->offset += 4; chunk->data = stream->buffer; chunk->checksum = checksum; return XB_STREAM_READ_CHUNK; err: return XB_STREAM_READ_ERROR; }