~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/blob.cc

  • Committer: Stewart Smith
  • Date: 2009-12-09 01:28:00 UTC
  • mto: This revision was merged to the branch mainline in revision 1915.
  • Revision ID: stewart@flamingspork.com-20091209012800-c4qe0plmlf5z4xpk
remove last bits of packlength from Field_blob, leaving only support for 4 byte length for blobs (not 1, not 2 and certainly not 3).

Show diffs side-by-side

added added

removed removed

Lines of Context:
40
40
/****************************************************************************
41
41
** blob type
42
42
** A blob is saved as a length and a pointer. The length is stored in the
43
 
** packlength slot and may be from 1-4.
 
43
** packlength slot and is sizeof(uint32_t) (4 bytes)
44
44
****************************************************************************/
45
45
 
46
46
Field_blob::Field_blob(unsigned char *ptr_arg,
50
50
                       TableShare *share,
51
51
                       const CHARSET_INFO * const cs)
52
52
  :Field_str(ptr_arg,
53
 
             blob_pack_length_to_max_length(4),
 
53
             blob_pack_length_to_max_length(sizeof(uint32_t)),
54
54
             null_ptr_arg,
55
55
             null_bit_arg,
56
56
             field_name_arg,
57
 
             cs),
58
 
   packlength(4)
 
57
             cs)
59
58
{
60
59
  flags|= BLOB_FLAG;
61
60
  share->blob_fields++;
63
62
}
64
63
 
65
64
void Field_blob::store_length(unsigned char *i_ptr,
66
 
                              uint32_t i_packlength,
67
65
                              uint32_t i_number,
68
66
                              bool low_byte_first)
69
67
{
70
68
#ifndef WORDS_BIGENDIAN
71
69
  (void)low_byte_first;
72
70
#endif
73
 
  switch (i_packlength) {
74
 
  case 1:
75
 
    i_ptr[0]= (unsigned char) i_number;
76
 
    break;
77
 
  case 2:
78
 
#ifdef WORDS_BIGENDIAN
79
 
    if (low_byte_first)
80
 
    {
81
 
      int2store(i_ptr,(unsigned short) i_number);
82
 
    }
83
 
    else
84
 
#endif
85
 
      shortstore(i_ptr,(unsigned short) i_number);
86
 
    break;
87
 
  case 3:
88
 
    int3store(i_ptr,i_number);
89
 
    break;
90
 
  case 4:
91
 
#ifdef WORDS_BIGENDIAN
92
 
    if (low_byte_first)
93
 
    {
94
 
      int4store(i_ptr,i_number);
95
 
    }
96
 
    else
97
 
#endif
98
 
      longstore(i_ptr,i_number);
 
71
 
 
72
#ifdef WORDS_BIGENDIAN
 
73
  if (low_byte_first)
 
74
  {
 
75
    int4store(i_ptr,i_number);
99
76
  }
 
77
  else
 
78
#endif
 
79
    longstore(i_ptr,i_number);
100
80
}
101
81
 
102
82
 
103
 
void Field_blob::store_length(unsigned char *i_ptr, uint32_t i_packlength,
104
 
                  uint32_t i_number)
 
83
void Field_blob::store_length(unsigned char *i_ptr, uint32_t i_number)
105
84
{
106
 
  store_length(i_ptr, i_packlength, i_number, table->s->db_low_byte_first);
 
85
  store_length(i_ptr, i_number, table->s->db_low_byte_first);
107
86
}
108
87
 
109
88
 
110
89
uint32_t Field_blob::get_length(const unsigned char *pos,
111
 
                                uint32_t packlength_arg,
112
90
                                bool low_byte_first)
113
91
{
114
92
#ifndef WORDS_BIGENDIAN
115
93
  (void)low_byte_first;
116
94
#endif
117
 
  switch (packlength_arg) {
118
 
  case 1:
119
 
    return (uint32_t) pos[0];
120
 
  case 2:
121
 
    {
122
 
      uint16_t tmp;
123
 
#ifdef WORDS_BIGENDIAN
124
 
      if (low_byte_first)
125
 
        tmp=sint2korr(pos);
126
 
      else
127
 
#endif
128
 
        shortget(tmp,pos);
129
 
      return (uint32_t) tmp;
130
 
    }
131
 
  case 3:
132
 
    return (uint32_t) uint3korr(pos);
133
 
  case 4:
134
 
    {
135
 
      uint32_t tmp;
136
 
#ifdef WORDS_BIGENDIAN
137
 
      if (low_byte_first)
138
 
        tmp=uint4korr(pos);
139
 
      else
140
 
#endif
141
 
        longget(tmp,pos);
142
 
      return (uint32_t) tmp;
143
 
    }
144
 
  }
145
 
  return 0;                                     // Impossible
 
95
  uint32_t tmp;
 
96
#ifdef WORDS_BIGENDIAN
 
97
  if (low_byte_first)
 
98
    tmp=uint4korr(pos);
 
99
  else
 
100
#endif
 
101
    longget(tmp,pos);
 
102
  return (uint32_t) tmp;
146
103
}
147
104
 
148
105
 
149
106
uint32_t Field_blob::get_packed_size(const unsigned char *ptr_arg,
150
107
                                bool low_byte_first)
151
108
{
152
 
  return packlength + get_length(ptr_arg, packlength, low_byte_first);
 
109
  return sizeof(uint32_t) + get_length(ptr_arg, low_byte_first);
153
110
}
154
111
 
155
112
 
156
113
uint32_t Field_blob::get_length(uint32_t row_offset)
157
114
{
158
 
  return get_length(ptr+row_offset, this->packlength,
159
 
                    table->s->db_low_byte_first);
 
115
  return get_length(ptr+row_offset, table->s->db_low_byte_first);
160
116
}
161
117
 
162
118
 
163
119
uint32_t Field_blob::get_length(const unsigned char *ptr_arg)
164
120
{
165
 
  return get_length(ptr_arg, this->packlength, table->s->db_low_byte_first);
 
121
  return get_length(ptr_arg, table->s->db_low_byte_first);
166
122
}
167
123
 
168
124
 
169
125
/**
170
126
  Put a blob length field into a record buffer.
171
127
 
172
 
  Depending on the maximum length of a blob, its length field is
173
 
  put into 1 to 4 bytes. This is a property of the blob object,
174
 
  described by 'packlength'.
 
128
  Blob length is always stored in sizeof(uint32_t) (4 bytes)
175
129
 
176
130
  @param pos                 Pointer into the record buffer.
177
131
  @param length              The length value to put.
179
133
 
180
134
void Field_blob::put_length(unsigned char *pos, uint32_t length)
181
135
{
182
 
  switch (packlength) {
183
 
  case 1:
184
 
    *pos= (char) length;
185
 
    break;
186
 
  case 2:
187
 
    int2store(pos, length);
188
 
    break;
189
 
  case 3:
190
 
    int3store(pos, length);
191
 
    break;
192
 
  case 4:
193
136
    int4store(pos, length);
194
 
    break;
195
 
  }
196
137
}
197
138
 
198
139
 
219
160
    if (!String::needs_conversion(length, cs, field_charset, &dummy_offset))
220
161
    {
221
162
      Field_blob::store_length(length);
222
 
      memmove(ptr+packlength, &from, sizeof(char*));
 
163
      memmove(ptr+sizeof(uint32_t), &from, sizeof(char*));
223
164
      return 0;
224
165
    }
225
166
    if (tmpstr.copy(from, length, cs))
246
187
 
247
188
  Field_blob::store_length(copy_length);
248
189
  tmp= value.ptr();
249
 
  memmove(ptr+packlength, &tmp, sizeof(char*));
 
190
  memmove(ptr+sizeof(uint32_t), &tmp, sizeof(char*));
250
191
 
251
192
  if (check_string_copy_error(this, well_formed_error_pos,
252
193
                              cannot_convert_error_pos, from + length, cs))
288
229
 
289
230
  ASSERT_COLUMN_MARKED_FOR_READ;
290
231
 
291
 
  memcpy(&blob,ptr+packlength,sizeof(char*));
 
232
  memcpy(&blob,ptr+sizeof(uint32_t),sizeof(char*));
292
233
  if (!blob)
293
234
    return 0.0;
294
235
  length= get_length(ptr);
304
245
 
305
246
  ASSERT_COLUMN_MARKED_FOR_READ;
306
247
 
307
 
  memcpy(&blob,ptr+packlength,sizeof(char*));
 
248
  memcpy(&blob,ptr+sizeof(uint32_t),sizeof(char*));
308
249
  if (!blob)
309
250
    return 0;
310
251
  uint32_t length=get_length(ptr);
318
259
 
319
260
  ASSERT_COLUMN_MARKED_FOR_READ;
320
261
 
321
 
  memcpy(&blob,ptr+packlength,sizeof(char*));
 
262
  memcpy(&blob,ptr+sizeof(uint32_t),sizeof(char*));
322
263
  if (!blob)
323
264
    val_ptr->set("",0,charset());       // A bit safer than ->length(0)
324
265
  else
334
275
 
335
276
  ASSERT_COLUMN_MARKED_FOR_READ;
336
277
 
337
 
  memcpy(&blob, ptr+packlength, sizeof(const unsigned char*));
 
278
  memcpy(&blob, ptr+sizeof(uint32_t), sizeof(const unsigned char*));
338
279
  if (!blob)
339
280
  {
340
281
    blob= "";
362
303
                        uint32_t max_length)
363
304
{
364
305
  unsigned char *blob1,*blob2;
365
 
  memcpy(&blob1,a_ptr+packlength,sizeof(char*));
366
 
  memcpy(&blob2,b_ptr+packlength,sizeof(char*));
 
306
  memcpy(&blob1,a_ptr+sizeof(uint32_t),sizeof(char*));
 
307
  memcpy(&blob2,b_ptr+sizeof(uint32_t),sizeof(char*));
367
308
  uint32_t a_len= get_length(a_ptr), b_len= get_length(b_ptr);
368
309
  set_if_smaller(a_len, max_length);
369
310
  set_if_smaller(b_len, max_length);
377
318
  char *a,*b;
378
319
  uint32_t diff;
379
320
  uint32_t a_length,b_length;
380
 
  memcpy(&a,a_ptr+packlength,sizeof(char*));
381
 
  memcpy(&b,b_ptr+packlength,sizeof(char*));
 
321
  memcpy(&a,a_ptr+sizeof(uint32_t),sizeof(char*));
 
322
  memcpy(&b,b_ptr+sizeof(uint32_t),sizeof(char*));
382
323
 
383
324
  a_length= get_length(a_ptr);
384
325
 
460
401
{
461
402
  unsigned char *blob1;
462
403
  uint32_t blob_length=get_length(ptr);
463
 
  memcpy(&blob1,ptr+packlength,sizeof(char*));
 
404
  memcpy(&blob1,ptr+sizeof(uint32_t),sizeof(char*));
464
405
  const CHARSET_INFO * const cs= charset();
465
406
  uint32_t local_char_length= max_key_length / cs->mbmaxlen;
466
407
  local_char_length= my_charpos(cs, blob1, blob1+blob_length,
480
421
uint32_t Field_blob::sort_length() const
481
422
{
482
423
  return (uint32_t) (current_session->variables.max_sort_length +
483
 
                   (field_charset == &my_charset_bin ? 0 : packlength));
 
424
                     (field_charset == &my_charset_bin ? 0 : sizeof(uint32_t)));
484
425
}
485
426
 
486
427
void Field_blob::sort_string(unsigned char *to,uint32_t length)
499
440
      /*
500
441
        Store length of blob last in blob to shorter blobs before longer blobs
501
442
      */
502
 
      length-= packlength;
 
443
      length-= sizeof(uint32_t); // size of stored blob length
503
444
      pos= to+length;
504
445
 
505
 
      switch (packlength) {
506
 
      case 1:
507
 
        *pos= (char) blob_length;
508
 
        break;
509
 
      case 2:
510
 
        mi_int2store(pos, blob_length);
511
 
        break;
512
 
      case 3:
513
 
        mi_int3store(pos, blob_length);
514
 
        break;
515
 
      case 4:
516
 
        mi_int4store(pos, blob_length);
517
 
        break;
518
 
      }
 
446
      mi_int4store(pos, blob_length);
519
447
    }
520
 
    memcpy(&blob,ptr+packlength,sizeof(char*));
 
448
    memcpy(&blob,ptr+sizeof(uint32_t),sizeof(char*));
521
449
 
522
450
    blob_length=my_strnxfrm(field_charset,
523
451
                            to, length, blob, blob_length);
527
455
 
528
456
uint32_t Field_blob::pack_length() const
529
457
{
530
 
  return (uint32_t) (packlength+table->s->blob_ptr_size);
 
458
  return (uint32_t) (sizeof(uint32_t)+table->s->blob_ptr_size);
531
459
}
532
460
 
533
461
void Field_blob::sql_type(String &res) const
550
478
    length given is smaller than the actual length of the blob, we
551
479
    just store the initial bytes of the blob.
552
480
  */
553
 
  store_length(to, packlength, min(length, max_length), low_byte_first);
 
481
  store_length(to, min(length, max_length), low_byte_first);
554
482
 
555
483
  /*
556
484
    Store the actual blob data, which will occupy 'length' bytes.
558
486
  if (length > 0)
559
487
  {
560
488
    get_ptr((unsigned char**) &from);
561
 
    memcpy(to+packlength, from,length);
 
489
    memcpy(to+sizeof(uint32_t), from,length);
562
490
  }
563
491
 
564
492
  ptr= save;                                    // Restore org row pointer
565
 
  return(to+packlength+length);
 
493
  return(to+sizeof(uint32_t)+length);
566
494
}
567
495
 
568
496
/**
584
512
*/
585
513
const unsigned char *Field_blob::unpack(unsigned char *,
586
514
                                        const unsigned char *from,
587
 
                                        uint32_t param_data,
 
515
                                        uint32_t,
588
516
                                        bool low_byte_first)
589
517
{
590
 
  uint32_t const master_packlength=
591
 
    param_data > 0 ? param_data & 0xFF : packlength;
592
 
  uint32_t const length= get_length(from, master_packlength, low_byte_first);
 
518
  uint32_t const length= get_length(from, low_byte_first);
593
519
  table->setWriteSet(field_index);
594
 
  store(reinterpret_cast<const char*>(from) + master_packlength,
 
520
  store(reinterpret_cast<const char*>(from) + sizeof(uint32_t),
595
521
        length, field_charset);
596
 
  return(from + master_packlength + length);
 
522
  return(from + sizeof(uint32_t) + length);
597
523
}
598
524
 
599
525
/** Create a packed key that will be used for storage from a MySQL row. */
631
557
 
632
558
uint32_t Field_blob::max_display_length()
633
559
{
634
 
  switch (packlength)
635
 
  {
636
 
  case 1:
637
 
    return 255 * field_charset->mbmaxlen;
638
 
  case 2:
639
 
    return 65535 * field_charset->mbmaxlen;
640
 
  case 3:
641
 
    return 16777215 * field_charset->mbmaxlen;
642
 
  case 4:
643
560
    return (uint32_t) 4294967295U;
644
 
  default:
645
 
    assert(0); // we should never go here
646
 
    return 0;
647
 
  }
648
561
}