26
26
#include <drizzled/field/blob.h>
29
blob_pack_length_to_max_length(uint arg)
29
blob_pack_length_to_max_length(uint32_t arg)
31
return (1LL << min(arg, 4U) * 8) - 1LL;
31
return (INT64_C(1) << cmin(arg, 4U) * 8) - INT64_C(1);
38
38
** packlength slot and may be from 1-4.
39
39
****************************************************************************/
41
Field_blob::Field_blob(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
41
Field_blob::Field_blob(unsigned char *ptr_arg, unsigned char *null_ptr_arg, unsigned char null_bit_arg,
42
42
enum utype unireg_check_arg, const char *field_name_arg,
43
TABLE_SHARE *share, uint blob_pack_length,
43
TABLE_SHARE *share, uint32_t blob_pack_length,
44
44
const CHARSET_INFO * const cs)
45
45
:Field_longstr(ptr_arg, blob_pack_length_to_max_length(blob_pack_length),
46
46
null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg,
56
void Field_blob::store_length(uchar *i_ptr,
56
void Field_blob::store_length(unsigned char *i_ptr,
57
uint32_t i_packlength,
59
59
bool low_byte_first __attribute__((unused)))
61
61
switch (i_packlength) {
63
i_ptr[0]= (uchar) i_number;
63
i_ptr[0]= (unsigned char) i_number;
66
66
#ifdef WORDS_BIGENDIAN
91
uint32_t Field_blob::get_length(const uchar *pos,
91
uint32_t Field_blob::get_length(const unsigned char *pos,
92
uint32_t packlength_arg,
93
93
bool low_byte_first __attribute__((unused)))
95
95
switch (packlength_arg) {
157
int Field_blob::store(const char *from,uint length, const CHARSET_INFO * const cs)
157
int Field_blob::store(const char *from,uint32_t length, const CHARSET_INFO * const cs)
159
uint copy_length, new_length;
159
uint32_t copy_length, new_length;
160
160
const char *well_formed_error_pos;
161
161
const char *cannot_convert_error_pos;
162
162
const char *from_end_pos, *tmp;
306
int Field_blob::cmp(const uchar *a,uint32_t a_length, const uchar *b,
306
int Field_blob::cmp(const unsigned char *a,uint32_t a_length, const unsigned char *b,
307
307
uint32_t b_length)
309
309
return field_charset->coll->strnncollsp(field_charset,
315
int Field_blob::cmp_max(const uchar *a_ptr, const uchar *b_ptr,
315
int Field_blob::cmp_max(const unsigned char *a_ptr, const unsigned char *b_ptr,
318
unsigned char *blob1,*blob2;
319
319
memcpy(&blob1,a_ptr+packlength,sizeof(char*));
320
320
memcpy(&blob2,b_ptr+packlength,sizeof(char*));
321
uint a_len= get_length(a_ptr), b_len= get_length(b_ptr);
321
uint32_t a_len= get_length(a_ptr), b_len= get_length(b_ptr);
322
322
set_if_smaller(a_len, max_length);
323
323
set_if_smaller(b_len, max_length);
324
324
return Field_blob::cmp(blob1,a_len,blob2,b_len);
328
int Field_blob::cmp_binary(const uchar *a_ptr, const uchar *b_ptr,
328
int Field_blob::cmp_binary(const unsigned char *a_ptr, const unsigned char *b_ptr,
329
329
uint32_t max_length)
333
333
uint32_t a_length,b_length;
334
334
memcpy(&a,a_ptr+packlength,sizeof(char*));
335
335
memcpy(&b,b_ptr+packlength,sizeof(char*));
339
339
b_length=get_length(b_ptr);
340
340
if (b_length > max_length)
341
341
b_length=max_length;
342
diff=memcmp(a,b,min(a_length,b_length));
342
diff=memcmp(a,b,cmin(a_length,b_length));
343
343
return diff ? diff : (int) (a_length - b_length);
347
347
/* The following is used only when comparing a key */
349
uint Field_blob::get_key_image(uchar *buff,
349
uint32_t Field_blob::get_key_image(unsigned char *buff,
351
351
imagetype type_arg __attribute__((unused)))
353
353
uint32_t blob_length= get_length(ptr);
357
uint local_char_length= length / field_charset->mbmaxlen;
357
uint32_t local_char_length= length / field_charset->mbmaxlen;
358
358
local_char_length= my_charpos(field_charset, blob, blob + blob_length,
359
359
local_char_length);
360
360
set_if_smaller(blob_length, local_char_length);
377
void Field_blob::set_key_image(const uchar *buff,uint length)
377
void Field_blob::set_key_image(const unsigned char *buff,uint32_t length)
379
379
length= uint2korr(buff);
380
380
(void) Field_blob::store((const char*) buff+HA_KEY_BLOB_LENGTH, length,
385
int Field_blob::key_cmp(const uchar *key_ptr, uint max_key_length)
385
int Field_blob::key_cmp(const unsigned char *key_ptr, uint32_t max_key_length)
388
uint blob_length=get_length(ptr);
387
unsigned char *blob1;
388
uint32_t blob_length=get_length(ptr);
389
389
memcpy(&blob1,ptr+packlength,sizeof(char*));
390
390
const CHARSET_INFO * const cs= charset();
391
uint local_char_length= max_key_length / cs->mbmaxlen;
391
uint32_t local_char_length= max_key_length / cs->mbmaxlen;
392
392
local_char_length= my_charpos(cs, blob1, blob1+blob_length,
393
393
local_char_length);
394
394
set_if_smaller(blob_length, local_char_length);
397
397
uint2korr(key_ptr));
400
int Field_blob::key_cmp(const uchar *a,const uchar *b)
400
int Field_blob::key_cmp(const unsigned char *a,const unsigned char *b)
402
402
return Field_blob::cmp(a+HA_KEY_BLOB_LENGTH, uint2korr(a),
403
403
b+HA_KEY_BLOB_LENGTH, uint2korr(b));
415
415
@returns number of bytes written to metadata_ptr
417
int Field_blob::do_save_field_metadata(uchar *metadata_ptr)
417
int Field_blob::do_save_field_metadata(unsigned char *metadata_ptr)
419
419
*metadata_ptr= pack_length_no_ptr();
431
void Field_blob::sort_string(uchar *to,uint length)
431
void Field_blob::sort_string(unsigned char *to,uint32_t length)
434
uint blob_length=get_length();
434
uint32_t blob_length=get_length();
436
436
if (!blob_length)
437
437
memset(to, 0, length);
479
479
res.set_ascii(STRING_WITH_LEN("text"));
482
uchar *Field_blob::pack(uchar *to, const uchar *from,
483
uint max_length, bool low_byte_first)
482
unsigned char *Field_blob::pack(unsigned char *to, const unsigned char *from,
483
uint32_t max_length, bool low_byte_first)
485
unsigned char *save= ptr;
486
ptr= (unsigned char*) from;
487
487
uint32_t length=get_length(); // Length of from string
491
491
length given is smaller than the actual length of the blob, we
492
492
just store the initial bytes of the blob.
494
store_length(to, packlength, min(length, max_length), low_byte_first);
494
store_length(to, packlength, cmin(length, max_length), low_byte_first);
497
497
Store the actual blob data, which will occupy 'length' bytes.
501
get_ptr((uchar**) &from);
501
get_ptr((unsigned char**) &from);
502
502
memcpy(to+packlength, from,length);
504
504
ptr=save; // Restore org row pointer
524
524
@return New pointer into memory based on from + length of the data
526
const uchar *Field_blob::unpack(uchar *to __attribute__((unused)),
526
const unsigned char *Field_blob::unpack(unsigned char *to __attribute__((unused)),
527
const unsigned char *from,
529
529
bool low_byte_first)
531
uint const master_packlength=
531
uint32_t const master_packlength=
532
532
param_data > 0 ? param_data & 0xFF : packlength;
533
533
uint32_t const length= get_length(from, master_packlength, low_byte_first);
534
534
bitmap_set_bit(table->write_set, field_index);
540
540
/* Keys for blobs are like keys on varchars */
542
int Field_blob::pack_cmp(const uchar *a, const uchar *b, uint key_length_arg,
542
int Field_blob::pack_cmp(const unsigned char *a, const unsigned char *b, uint32_t key_length_arg,
543
543
bool insert_or_update)
545
uint a_length, b_length;
545
uint32_t a_length, b_length;
546
546
if (key_length_arg > 255)
548
548
a_length=uint2korr(a); a+=2;
563
int Field_blob::pack_cmp(const uchar *b, uint key_length_arg,
563
int Field_blob::pack_cmp(const unsigned char *b, uint32_t key_length_arg,
564
564
bool insert_or_update)
567
uint a_length, b_length;
567
uint32_t a_length, b_length;
568
568
memcpy(&a,ptr+packlength,sizeof(char*));
570
570
return key_length_arg > 0 ? -1 : 0;
585
585
/** Create a packed key that will be used for storage from a MySQL row. */
588
Field_blob::pack_key(uchar *to, const uchar *from, uint max_length,
588
Field_blob::pack_key(unsigned char *to, const unsigned char *from, uint32_t max_length,
589
589
bool low_byte_first __attribute__((unused)))
591
unsigned char *save= ptr;
592
ptr= (unsigned char*) from;
593
593
uint32_t length=get_length(); // Length of from string
594
uint local_char_length= ((field_charset->mbmaxlen > 1) ?
594
uint32_t local_char_length= ((field_charset->mbmaxlen > 1) ?
595
595
max_length/field_charset->mbmaxlen : max_length);
597
get_ptr((uchar**) &from);
597
get_ptr((unsigned char**) &from);
598
598
if (length > local_char_length)
599
599
local_char_length= my_charpos(field_charset, from, from+length,
600
600
local_char_length);
601
601
set_if_smaller(length, local_char_length);
602
*to++= (uchar) length;
602
*to++= (unsigned char) length;
603
603
if (max_length > 255) // 2 byte length
604
*to++= (uchar) (length >> 8);
604
*to++= (unsigned char) (length >> 8);
605
605
memcpy(to, from, length);
606
606
ptr=save; // Restore org row pointer
607
607
return to+length;
629
629
Pointer into 'from' past the last byte copied from packed key.
633
Field_blob::unpack_key(uchar *to, const uchar *from, uint max_length,
632
const unsigned char *
633
Field_blob::unpack_key(unsigned char *to, const unsigned char *from, uint32_t max_length,
634
634
bool low_byte_first __attribute__((unused)))
636
636
/* get length of the blob key */
655
655
/** Create a packed key that will be used for storage from a MySQL key. */
658
Field_blob::pack_key_from_key_image(uchar *to, const uchar *from, uint max_length,
658
Field_blob::pack_key_from_key_image(unsigned char *to, const unsigned char *from, uint32_t max_length,
659
659
bool low_byte_first __attribute__((unused)))
661
uint length=uint2korr(from);
661
uint32_t length=uint2korr(from);
662
662
if (length > max_length)
663
663
length=max_length;
664
664
*to++= (char) (length & 255);
681
uint Field_blob::max_packed_col_length(uint max_length)
681
uint32_t Field_blob::max_packed_col_length(uint32_t max_length)
683
683
return (max_length > 255 ? 2 : 1)+max_length;
687
uint Field_blob::is_equal(Create_field *new_field)
687
uint32_t Field_blob::is_equal(Create_field *new_field)
689
689
if (compare_str_field_flags(new_field, flags))