43
43
/****************************************************************************
45
45
** A blob is saved as a length and a pointer. The length is stored in the
46
** packlength slot and is sizeof(uint32_t) (4 bytes)
46
** packlength slot and may be from 1-4.
47
47
****************************************************************************/
49
49
Field_blob::Field_blob(unsigned char *ptr_arg,
51
51
unsigned char null_bit_arg,
52
52
const char *field_name_arg,
54
uint32_t blob_pack_length,
54
55
const CHARSET_INFO * const cs)
55
56
:Field_str(ptr_arg,
56
blob_pack_length_to_max_length(sizeof(uint32_t)),
57
blob_pack_length_to_max_length(blob_pack_length),
62
packlength(blob_pack_length)
63
65
share->blob_fields++;
67
69
void Field_blob::store_length(unsigned char *i_ptr,
70
uint32_t i_packlength,
69
72
bool low_byte_first)
71
74
#ifndef WORDS_BIGENDIAN
72
75
(void)low_byte_first;
75
#ifdef WORDS_BIGENDIAN
78
int4store(i_ptr,i_number);
77
switch (i_packlength) {
79
i_ptr[0]= (unsigned char) i_number;
82
#ifdef WORDS_BIGENDIAN
85
int2store(i_ptr,(unsigned short) i_number);
89
shortstore(i_ptr,(unsigned short) i_number);
92
int3store(i_ptr,i_number);
95
#ifdef WORDS_BIGENDIAN
98
int4store(i_ptr,i_number);
102
longstore(i_ptr,i_number);
82
longstore(i_ptr,i_number);
86
void Field_blob::store_length(unsigned char *i_ptr, uint32_t i_number)
107
void Field_blob::store_length(unsigned char *i_ptr, uint32_t i_packlength,
88
store_length(i_ptr, i_number, getTable()->getShare()->db_low_byte_first);
110
store_length(i_ptr, i_packlength, i_number, table->getShare()->db_low_byte_first);
92
114
uint32_t Field_blob::get_length(const unsigned char *pos,
115
uint32_t packlength_arg,
93
116
bool low_byte_first)
95
118
#ifndef WORDS_BIGENDIAN
96
119
(void)low_byte_first;
99
#ifdef WORDS_BIGENDIAN
105
return (uint32_t) tmp;
121
switch (packlength_arg) {
123
return (uint32_t) pos[0];
127
#ifdef WORDS_BIGENDIAN
133
return (uint32_t) tmp;
136
return (uint32_t) uint3korr(pos);
140
#ifdef WORDS_BIGENDIAN
146
return (uint32_t) tmp;
149
return 0; // Impossible
109
153
uint32_t Field_blob::get_packed_size(const unsigned char *ptr_arg,
110
154
bool low_byte_first)
112
return sizeof(uint32_t) + get_length(ptr_arg, low_byte_first);
156
return packlength + get_length(ptr_arg, packlength, low_byte_first);
116
160
uint32_t Field_blob::get_length(uint32_t row_offset)
118
return get_length(ptr+row_offset,
119
getTable()->getShare()->db_low_byte_first);
162
return get_length(ptr+row_offset, this->packlength,
163
table->getShare()->db_low_byte_first);
123
167
uint32_t Field_blob::get_length(const unsigned char *ptr_arg)
125
return get_length(ptr_arg, getTable()->getShare()->db_low_byte_first);
169
return get_length(ptr_arg, this->packlength, table->getShare()->db_low_byte_first);
130
174
Put a blob length field into a record buffer.
132
Blob length is always stored in sizeof(uint32_t) (4 bytes)
176
Depending on the maximum length of a blob, its length field is
177
put into 1 to 4 bytes. This is a property of the blob object,
178
described by 'packlength'.
134
180
@param pos Pointer into the record buffer.
135
181
@param length The length value to put.
161
220
if (from == value.ptr())
222
uint32_t dummy_offset;
164
223
if (!String::needs_conversion(length, cs, field_charset, &dummy_offset))
166
225
Field_blob::store_length(length);
167
memmove(ptr+sizeof(uint32_t), &from, sizeof(char*));
226
memmove(ptr+packlength, &from, sizeof(char*));
170
229
if (tmpstr.copy(from, length, cs))
192
251
Field_blob::store_length(copy_length);
193
252
tmp= value.ptr();
194
memmove(ptr+sizeof(uint32_t), &tmp, sizeof(char*));
253
memmove(ptr+packlength, &tmp, sizeof(char*));
196
255
if (check_string_copy_error(this, well_formed_error_pos,
197
256
cannot_convert_error_pos, from + length, cs))
264
323
ASSERT_COLUMN_MARKED_FOR_READ;
266
memcpy(&blob,ptr+sizeof(uint32_t),sizeof(char*));
325
memcpy(&blob,ptr+packlength,sizeof(char*));
268
327
val_ptr->set("",0,charset()); // A bit safer than ->length(0)
275
type::Decimal *Field_blob::val_decimal(type::Decimal *decimal_value)
334
my_decimal *Field_blob::val_decimal(my_decimal *decimal_value)
277
336
const char *blob;
280
339
ASSERT_COLUMN_MARKED_FOR_READ;
282
memcpy(&blob, ptr+sizeof(uint32_t), sizeof(const unsigned char*));
341
memcpy(&blob, ptr+packlength, sizeof(const unsigned char*));
290
348
length= get_length(ptr);
293
decimal_value->store(E_DEC_FATAL_ERROR, blob, length, charset());
350
str2my_decimal(E_DEC_FATAL_ERROR, blob, length, charset(),
295
352
return decimal_value;
309
366
uint32_t max_length)
311
368
unsigned char *blob1,*blob2;
312
memcpy(&blob1,a_ptr+sizeof(uint32_t),sizeof(char*));
313
memcpy(&blob2,b_ptr+sizeof(uint32_t),sizeof(char*));
369
memcpy(&blob1,a_ptr+packlength,sizeof(char*));
370
memcpy(&blob2,b_ptr+packlength,sizeof(char*));
314
371
uint32_t a_len= get_length(a_ptr), b_len= get_length(b_ptr);
315
372
set_if_smaller(a_len, max_length);
316
373
set_if_smaller(b_len, max_length);
326
383
uint32_t a_length,b_length;
327
memcpy(&a,a_ptr+sizeof(uint32_t),sizeof(char*));
328
memcpy(&b,b_ptr+sizeof(uint32_t),sizeof(char*));
384
memcpy(&a,a_ptr+packlength,sizeof(char*));
385
memcpy(&b,b_ptr+packlength,sizeof(char*));
330
387
a_length= get_length(a_ptr);
408
465
unsigned char *blob1;
409
466
uint32_t blob_length=get_length(ptr);
410
memcpy(&blob1,ptr+sizeof(uint32_t),sizeof(char*));
467
memcpy(&blob1,ptr+packlength,sizeof(char*));
411
468
const CHARSET_INFO * const cs= charset();
412
469
uint32_t local_char_length= max_key_length / cs->mbmaxlen;
413
470
local_char_length= my_charpos(cs, blob1, blob1+blob_length,
427
484
uint32_t Field_blob::sort_length() const
429
return (uint32_t) (getTable()->getSession()->variables.max_sort_length +
430
(field_charset == &my_charset_bin ? 0 : sizeof(uint32_t)));
486
return (uint32_t) (current_session->variables.max_sort_length +
487
(field_charset == &my_charset_bin ? 0 : packlength));
433
490
void Field_blob::sort_string(unsigned char *to,uint32_t length)
447
504
Store length of blob last in blob to shorter blobs before longer blobs
449
length-= sizeof(uint32_t); // size of stored blob length
452
mi_int4store(pos, blob_length);
509
switch (packlength) {
511
*pos= (char) blob_length;
514
mi_int2store(pos, blob_length);
517
mi_int3store(pos, blob_length);
520
mi_int4store(pos, blob_length);
454
memcpy(&blob,ptr+sizeof(uint32_t),sizeof(char*));
524
memcpy(&blob,ptr+packlength,sizeof(char*));
456
526
blob_length=my_strnxfrm(field_charset,
457
527
to, length, blob, blob_length);
484
554
length given is smaller than the actual length of the blob, we
485
555
just store the initial bytes of the blob.
487
store_length(to, min(length, max_length), low_byte_first);
557
store_length(to, packlength, min(length, max_length), low_byte_first);
490
560
Store the actual blob data, which will occupy 'length' bytes.
494
564
get_ptr((unsigned char**) &from);
495
memcpy(to+sizeof(uint32_t), from,length);
565
memcpy(to+packlength, from,length);
498
568
ptr= save; // Restore org row pointer
499
return(to+sizeof(uint32_t)+length);
569
return(to+packlength+length);
519
589
const unsigned char *Field_blob::unpack(unsigned char *,
520
590
const unsigned char *from,
522
592
bool low_byte_first)
524
uint32_t const length= get_length(from, low_byte_first);
525
getTable()->setWriteSet(position());
526
store(reinterpret_cast<const char*>(from) + sizeof(uint32_t),
594
uint32_t const master_packlength=
595
param_data > 0 ? param_data & 0xFF : packlength;
596
uint32_t const length= get_length(from, master_packlength, low_byte_first);
597
table->setWriteSet(field_index);
598
store(reinterpret_cast<const char*>(from) + master_packlength,
527
599
length, field_charset);
528
return(from + sizeof(uint32_t) + length);
600
return(from + master_packlength + length);
531
603
/** Create a packed key that will be used for storage from a MySQL row. */
564
636
uint32_t Field_blob::max_display_length()
641
return 255 * field_charset->mbmaxlen;
643
return 65535 * field_charset->mbmaxlen;
645
return 16777215 * field_charset->mbmaxlen;
566
647
return (uint32_t) 4294967295U;
649
assert(0); // we should never go here
569
654
} /* namespace drizzled */