~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/blob.cc

  • Committer: Brian Aker
  • Date: 2008-08-10 16:57:26 UTC
  • Revision ID: brian@tangent.org-20080810165726-mc1660l11a5vkv69
libdrizzle has ulong removed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* - mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
 
1
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
4
4
 *  Copyright (C) 2008 MySQL
25
25
#include <drizzled/server_includes.h>
26
26
#include <drizzled/field/blob.h>
27
27
 
28
 
uint32_t
29
 
blob_pack_length_to_max_length(uint32_t arg)
30
 
{
31
 
  return (INT64_C(1) << cmin(arg, 4U) * 8) - INT64_C(1);
32
 
}
33
 
 
 
28
#define BLOB_PACK_LENGTH_TO_MAX_LENGH(arg) \
 
29
((uint32_t) ((1LL << min(arg, 4) * 8) - 1LL))
34
30
 
35
31
/****************************************************************************
36
32
** blob type
38
34
** packlength slot and may be from 1-4.
39
35
****************************************************************************/
40
36
 
41
 
Field_blob::Field_blob(unsigned char *ptr_arg, unsigned char *null_ptr_arg, unsigned char null_bit_arg,
 
37
Field_blob::Field_blob(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
42
38
                       enum utype unireg_check_arg, const char *field_name_arg,
43
 
                       TABLE_SHARE *share, uint32_t blob_pack_length,
 
39
                       TABLE_SHARE *share, uint blob_pack_length,
44
40
                       const CHARSET_INFO * const cs)
45
 
  :Field_longstr(ptr_arg, blob_pack_length_to_max_length(blob_pack_length),
 
41
  :Field_longstr(ptr_arg, BLOB_PACK_LENGTH_TO_MAX_LENGH(blob_pack_length),
46
42
                 null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg,
47
43
                 cs),
48
44
   packlength(blob_pack_length)
53
49
}
54
50
 
55
51
 
56
 
void Field_blob::store_length(unsigned char *i_ptr,
57
 
                              uint32_t i_packlength,
 
52
void Field_blob::store_length(uchar *i_ptr,
 
53
                              uint i_packlength,
58
54
                              uint32_t i_number,
59
55
                              bool low_byte_first __attribute__((unused)))
60
56
{
61
57
  switch (i_packlength) {
62
58
  case 1:
63
 
    i_ptr[0]= (unsigned char) i_number;
 
59
    i_ptr[0]= (uchar) i_number;
64
60
    break;
65
61
  case 2:
66
62
#ifdef WORDS_BIGENDIAN
88
84
}
89
85
 
90
86
 
91
 
uint32_t Field_blob::get_length(const unsigned char *pos,
92
 
                              uint32_t packlength_arg,
 
87
uint32_t Field_blob::get_length(const uchar *pos,
 
88
                              uint packlength_arg,
93
89
                              bool low_byte_first __attribute__((unused)))
94
90
{
95
91
  switch (packlength_arg) {
135
131
  @param length              The length value to put.
136
132
*/
137
133
 
138
 
void Field_blob::put_length(unsigned char *pos, uint32_t length)
 
134
void Field_blob::put_length(uchar *pos, uint32_t length)
139
135
{
140
136
  switch (packlength) {
141
137
  case 1:
154
150
}
155
151
 
156
152
 
157
 
int Field_blob::store(const char *from,uint32_t length, const CHARSET_INFO * const cs)
 
153
int Field_blob::store(const char *from,uint length, const CHARSET_INFO * const cs)
158
154
{
159
 
  uint32_t copy_length, new_length;
 
155
  uint copy_length, new_length;
160
156
  const char *well_formed_error_pos;
161
157
  const char *cannot_convert_error_pos;
162
158
  const char *from_end_pos, *tmp;
183
179
    from= tmpstr.ptr();
184
180
  }
185
181
 
186
 
  new_length= cmin(max_data_length(), field_charset->mbmaxlen * length);
 
182
  new_length= min(max_data_length(), field_charset->mbmaxlen * length);
187
183
  if (value.alloc(new_length))
188
184
    goto oom_error;
189
185
 
288
284
{
289
285
  const char *blob;
290
286
  size_t length;
291
 
  memcpy(&blob, ptr+packlength, sizeof(const unsigned char*));
 
287
  memcpy(&blob, ptr+packlength, sizeof(const uchar*));
292
288
  if (!blob)
293
289
  {
294
290
    blob= "";
303
299
}
304
300
 
305
301
 
306
 
int Field_blob::cmp(const unsigned char *a,uint32_t a_length, const unsigned char *b,
 
302
int Field_blob::cmp(const uchar *a,uint32_t a_length, const uchar *b,
307
303
                    uint32_t b_length)
308
304
{
309
305
  return field_charset->coll->strnncollsp(field_charset, 
312
308
}
313
309
 
314
310
 
315
 
int Field_blob::cmp_max(const unsigned char *a_ptr, const unsigned char *b_ptr,
316
 
                        uint32_t max_length)
 
311
int Field_blob::cmp_max(const uchar *a_ptr, const uchar *b_ptr,
 
312
                        uint max_length)
317
313
{
318
 
  unsigned char *blob1,*blob2;
 
314
  uchar *blob1,*blob2;
319
315
  memcpy(&blob1,a_ptr+packlength,sizeof(char*));
320
316
  memcpy(&blob2,b_ptr+packlength,sizeof(char*));
321
 
  uint32_t a_len= get_length(a_ptr), b_len= get_length(b_ptr);
 
317
  uint a_len= get_length(a_ptr), b_len= get_length(b_ptr);
322
318
  set_if_smaller(a_len, max_length);
323
319
  set_if_smaller(b_len, max_length);
324
320
  return Field_blob::cmp(blob1,a_len,blob2,b_len);
325
321
}
326
322
 
327
323
 
328
 
int Field_blob::cmp_binary(const unsigned char *a_ptr, const unsigned char *b_ptr,
 
324
int Field_blob::cmp_binary(const uchar *a_ptr, const uchar *b_ptr,
329
325
                           uint32_t max_length)
330
326
{
331
327
  char *a,*b;
332
 
  uint32_t diff;
 
328
  uint diff;
333
329
  uint32_t a_length,b_length;
334
330
  memcpy(&a,a_ptr+packlength,sizeof(char*));
335
331
  memcpy(&b,b_ptr+packlength,sizeof(char*));
339
335
  b_length=get_length(b_ptr);
340
336
  if (b_length > max_length)
341
337
    b_length=max_length;
342
 
  diff=memcmp(a,b,cmin(a_length,b_length));
 
338
  diff=memcmp(a,b,min(a_length,b_length));
343
339
  return diff ? diff : (int) (a_length - b_length);
344
340
}
345
341
 
346
342
 
347
343
/* The following is used only when comparing a key */
348
344
 
349
 
uint32_t Field_blob::get_key_image(unsigned char *buff,
350
 
                               uint32_t length,
 
345
uint Field_blob::get_key_image(uchar *buff,
 
346
                               uint length,
351
347
                               imagetype type_arg __attribute__((unused)))
352
348
{
353
349
  uint32_t blob_length= get_length(ptr);
354
 
  unsigned char *blob;
 
350
  uchar *blob;
355
351
 
356
352
  get_ptr(&blob);
357
 
  uint32_t local_char_length= length / field_charset->mbmaxlen;
 
353
  uint local_char_length= length / field_charset->mbmaxlen;
358
354
  local_char_length= my_charpos(field_charset, blob, blob + blob_length,
359
355
                          local_char_length);
360
356
  set_if_smaller(blob_length, local_char_length);
374
370
}
375
371
 
376
372
 
377
 
void Field_blob::set_key_image(const unsigned char *buff,uint32_t length)
 
373
void Field_blob::set_key_image(const uchar *buff,uint length)
378
374
{
379
375
  length= uint2korr(buff);
380
376
  (void) Field_blob::store((const char*) buff+HA_KEY_BLOB_LENGTH, length,
382
378
}
383
379
 
384
380
 
385
 
int Field_blob::key_cmp(const unsigned char *key_ptr, uint32_t max_key_length)
 
381
int Field_blob::key_cmp(const uchar *key_ptr, uint max_key_length)
386
382
{
387
 
  unsigned char *blob1;
388
 
  uint32_t blob_length=get_length(ptr);
 
383
  uchar *blob1;
 
384
  uint blob_length=get_length(ptr);
389
385
  memcpy(&blob1,ptr+packlength,sizeof(char*));
390
386
  const CHARSET_INFO * const cs= charset();
391
 
  uint32_t local_char_length= max_key_length / cs->mbmaxlen;
 
387
  uint local_char_length= max_key_length / cs->mbmaxlen;
392
388
  local_char_length= my_charpos(cs, blob1, blob1+blob_length,
393
389
                                local_char_length);
394
390
  set_if_smaller(blob_length, local_char_length);
397
393
                         uint2korr(key_ptr));
398
394
}
399
395
 
400
 
int Field_blob::key_cmp(const unsigned char *a,const unsigned char *b)
 
396
int Field_blob::key_cmp(const uchar *a,const uchar *b)
401
397
{
402
398
  return Field_blob::cmp(a+HA_KEY_BLOB_LENGTH, uint2korr(a),
403
399
                         b+HA_KEY_BLOB_LENGTH, uint2korr(b));
414
410
 
415
411
   @returns number of bytes written to metadata_ptr
416
412
*/
417
 
int Field_blob::do_save_field_metadata(unsigned char *metadata_ptr)
 
413
int Field_blob::do_save_field_metadata(uchar *metadata_ptr)
418
414
{
419
415
  *metadata_ptr= pack_length_no_ptr();
420
416
  return 1;
428
424
}
429
425
 
430
426
 
431
 
void Field_blob::sort_string(unsigned char *to,uint32_t length)
 
427
void Field_blob::sort_string(uchar *to,uint length)
432
428
{
433
 
  unsigned char *blob;
434
 
  uint32_t blob_length=get_length();
 
429
  uchar *blob;
 
430
  uint blob_length=get_length();
435
431
 
436
432
  if (!blob_length)
437
433
    memset(to, 0, length);
439
435
  {
440
436
    if (field_charset == &my_charset_bin)
441
437
    {
442
 
      unsigned char *pos;
 
438
      uchar *pos;
443
439
 
444
440
      /*
445
441
        Store length of blob last in blob to shorter blobs before longer blobs
479
475
    res.set_ascii(STRING_WITH_LEN("text"));
480
476
}
481
477
 
482
 
unsigned char *Field_blob::pack(unsigned char *to, const unsigned char *from,
483
 
                        uint32_t max_length, bool low_byte_first)
 
478
uchar *Field_blob::pack(uchar *to, const uchar *from,
 
479
                        uint max_length, bool low_byte_first)
484
480
{
485
 
  unsigned char *save= ptr;
486
 
  ptr= (unsigned char*) from;
 
481
  uchar *save= ptr;
 
482
  ptr= (uchar*) from;
487
483
  uint32_t length=get_length();                 // Length of from string
488
484
 
489
485
  /*
491
487
    length given is smaller than the actual length of the blob, we
492
488
    just store the initial bytes of the blob.
493
489
  */
494
 
  store_length(to, packlength, cmin(length, max_length), low_byte_first);
 
490
  store_length(to, packlength, min(length, max_length), low_byte_first);
495
491
 
496
492
  /*
497
493
    Store the actual blob data, which will occupy 'length' bytes.
498
494
   */
499
495
  if (length > 0)
500
496
  {
501
 
    get_ptr((unsigned char**) &from);
 
497
    get_ptr((uchar**) &from);
502
498
    memcpy(to+packlength, from,length);
503
499
  }
504
500
  ptr=save;                                     // Restore org row pointer
523
519
 
524
520
   @return  New pointer into memory based on from + length of the data
525
521
*/
526
 
const unsigned char *Field_blob::unpack(unsigned char *to __attribute__((unused)),
527
 
                                const unsigned char *from,
528
 
                                uint32_t param_data,
 
522
const uchar *Field_blob::unpack(uchar *to __attribute__((unused)),
 
523
                                const uchar *from,
 
524
                                uint param_data,
529
525
                                bool low_byte_first)
530
526
{
531
 
  uint32_t const master_packlength=
 
527
  uint const master_packlength=
532
528
    param_data > 0 ? param_data & 0xFF : packlength;
533
529
  uint32_t const length= get_length(from, master_packlength, low_byte_first);
534
530
  bitmap_set_bit(table->write_set, field_index);
539
535
 
540
536
/* Keys for blobs are like keys on varchars */
541
537
 
542
 
int Field_blob::pack_cmp(const unsigned char *a, const unsigned char *b, uint32_t key_length_arg,
 
538
int Field_blob::pack_cmp(const uchar *a, const uchar *b, uint key_length_arg,
543
539
                         bool insert_or_update)
544
540
{
545
 
  uint32_t a_length, b_length;
 
541
  uint a_length, b_length;
546
542
  if (key_length_arg > 255)
547
543
  {
548
544
    a_length=uint2korr(a); a+=2;
560
556
}
561
557
 
562
558
 
563
 
int Field_blob::pack_cmp(const unsigned char *b, uint32_t key_length_arg,
 
559
int Field_blob::pack_cmp(const uchar *b, uint key_length_arg,
564
560
                         bool insert_or_update)
565
561
{
566
 
  unsigned char *a;
567
 
  uint32_t a_length, b_length;
 
562
  uchar *a;
 
563
  uint a_length, b_length;
568
564
  memcpy(&a,ptr+packlength,sizeof(char*));
569
565
  if (!a)
570
566
    return key_length_arg > 0 ? -1 : 0;
584
580
 
585
581
/** Create a packed key that will be used for storage from a MySQL row. */
586
582
 
587
 
unsigned char *
588
 
Field_blob::pack_key(unsigned char *to, const unsigned char *from, uint32_t max_length,
 
583
uchar *
 
584
Field_blob::pack_key(uchar *to, const uchar *from, uint max_length,
589
585
                     bool low_byte_first __attribute__((unused)))
590
586
{
591
 
  unsigned char *save= ptr;
592
 
  ptr= (unsigned char*) from;
 
587
  uchar *save= ptr;
 
588
  ptr= (uchar*) from;
593
589
  uint32_t length=get_length();        // Length of from string
594
 
  uint32_t local_char_length= ((field_charset->mbmaxlen > 1) ?
 
590
  uint local_char_length= ((field_charset->mbmaxlen > 1) ?
595
591
                           max_length/field_charset->mbmaxlen : max_length);
596
592
  if (length)
597
 
    get_ptr((unsigned char**) &from);
 
593
    get_ptr((uchar**) &from);
598
594
  if (length > local_char_length)
599
595
    local_char_length= my_charpos(field_charset, from, from+length,
600
596
                                  local_char_length);
601
597
  set_if_smaller(length, local_char_length);
602
 
  *to++= (unsigned char) length;
 
598
  *to++= (uchar) length;
603
599
  if (max_length > 255)                         // 2 byte length
604
 
    *to++= (unsigned char) (length >> 8);
 
600
    *to++= (uchar) (length >> 8);
605
601
  memcpy(to, from, length);
606
602
  ptr=save;                                     // Restore org row pointer
607
603
  return to+length;
629
625
    Pointer into 'from' past the last byte copied from packed key.
630
626
*/
631
627
 
632
 
const unsigned char *
633
 
Field_blob::unpack_key(unsigned char *to, const unsigned char *from, uint32_t max_length,
 
628
const uchar *
 
629
Field_blob::unpack_key(uchar *to, const uchar *from, uint max_length,
634
630
                       bool low_byte_first __attribute__((unused)))
635
631
{
636
632
  /* get length of the blob key */
654
650
 
655
651
/** Create a packed key that will be used for storage from a MySQL key. */
656
652
 
657
 
unsigned char *
658
 
Field_blob::pack_key_from_key_image(unsigned char *to, const unsigned char *from, uint32_t max_length,
 
653
uchar *
 
654
Field_blob::pack_key_from_key_image(uchar *to, const uchar *from, uint max_length,
659
655
                                    bool low_byte_first __attribute__((unused)))
660
656
{
661
 
  uint32_t length=uint2korr(from);
 
657
  uint length=uint2korr(from);
662
658
  if (length > max_length)
663
659
    length=max_length;
664
660
  *to++= (char) (length & 255);
670
666
}
671
667
 
672
668
 
673
 
uint32_t Field_blob::packed_col_length(const unsigned char *data_ptr, uint32_t length)
 
669
uint Field_blob::packed_col_length(const uchar *data_ptr, uint length)
674
670
{
675
671
  if (length > 255)
676
672
    return uint2korr(data_ptr)+2;
678
674
}
679
675
 
680
676
 
681
 
uint32_t Field_blob::max_packed_col_length(uint32_t max_length)
 
677
uint Field_blob::max_packed_col_length(uint max_length)
682
678
{
683
679
  return (max_length > 255 ? 2 : 1)+max_length;
684
680
}
685
681
 
686
682
 
687
 
uint32_t Field_blob::is_equal(Create_field *new_field)
 
683
uint Field_blob::is_equal(Create_field *new_field)
688
684
{
689
685
  if (compare_str_field_flags(new_field, flags))
690
686
    return 0;