42 #include <ndb_global.h>
48 #include "../../../../zlib/zutil.h"
49 #include "../../../../zlib/zconf.h"
50 #include "../../../../zlib/inftrees.h"
51 #include "../../../../zlib/inflate.h"
52 #include "../../../../zlib/deflate.h"
54 #include <util/ndbzio.h>
59 #include <valgrind/memcheck.h>
61 #define VALGRIND_MAKE_MEM_DEFINED(a,b) do {} while(0);
62 #define VALGRIND_MAKE_MEM_NOACCESS(a,b) do {} while(0);
68 #define AZHEADER_SIZE 29
69 #define AZMETA_BUFFER_SIZE 512-AZHEADER_SIZE
71 #define AZ_MAGIC_POS 0
72 #define AZ_VERSION_POS 1
73 #define AZ_MINOR_VERSION_POS 2
74 #define AZ_BLOCK_POS 3
75 #define AZ_STRATEGY_POS 4
77 #define AZ_FRM_LENGTH_POS 9
78 #define AZ_META_POS 13
79 #define AZ_META_LENGTH_POS 17
80 #define AZ_START_POS 21
82 #define AZ_FLUSH_POS 37
83 #define AZ_CHECK_POS 45
84 #define AZ_AUTOINCREMENT_POS 53
85 #define AZ_LONGEST_POS 61
86 #define AZ_SHORTEST_POS 65
87 #define AZ_COMMENT_POS 69
88 #define AZ_COMMENT_LENGTH_POS 73
89 #define AZ_DIRTY_POS 77
95 #define AZ_STATE_CLEAN 0
96 #define AZ_STATE_DIRTY 1
97 #define AZ_STATE_SAVED 2
98 #define AZ_STATE_CRASHED 3
101 static int const gz_magic[2] = {0x1f, 0x8b};
102 static int const az_magic[3] = {0xfe, 0x03, 0x01};
105 #define ASCII_FLAG 0x01
106 #define HEAD_CRC 0x02
107 #define EXTRA_FIELD 0x04
108 #define ORIG_NAME 0x08
110 #define RESERVED 0xE0
112 #define AZ_MEMLEVEL 8
114 static int ndbz_open(
ndbzio_stream *s,
const char *path,
int Flags, File fd);
117 static unsigned char* get_block(
ndbzio_stream *s,
int blksz);
123 static void read_header(
ndbzio_stream *s,
unsigned char *buffer);
125 size_t ndbz_inflate_mem_size()
128 + ((1
U << MAX_WBITS)*
sizeof(
unsigned char));
131 size_t ndbz_deflate_mem_size()
134 + ((1
U << MAX_WBITS)*(2*
sizeof(Byte)))
135 + ((1
U << MAX_WBITS)*
sizeof(Pos))
136 + ((1
U << (AZ_MEMLEVEL+7))*
sizeof(Pos))
137 + ((1
U << (AZ_MEMLEVEL+6))*(
sizeof(ush)+2));
141 voidpf ndbz_alloc(voidpf opaque, uInt
items, uInt
size)
146 if((items * size) > r->mfree || r->mfree==0)
149 assert(r->mfree <= r->size);
151 retval= (r->mem + r->size) - r->mfree;
152 memset(retval, 0, items*size);
153 VALGRIND_MAKE_MEM_DEFINED(retval,items*size);
154 r->mfree -= items*
size;
158 void ndbz_free(voidpf opaque, voidpf address)
165 if(r->mfree==r->size)
166 VALGRIND_MAKE_MEM_NOACCESS(r->mem,r->size);
176 #ifndef HAVE_POSIX_MEMALIGN
177 static inline int posix_memalign(
void **memptr,
size_t alignment,
size_t size)
181 *memptr = memalign(alignment,size);
200 #define AZ_BUFSIZE_READ 32768
201 #define AZ_BUFSIZE_WRITE 16384
203 size_t ndbz_bufsize_read(
void)
205 return AZ_BUFSIZE_READ;
208 size_t ndbz_bufsize_write(
void)
210 return AZ_BUFSIZE_WRITE;
226 int ndbz_open (
ndbzio_stream *s,
const char *path,
int Flags, File fd)
229 int level = Z_DEFAULT_COMPRESSION;
230 int strategy = Z_DEFAULT_STRATEGY;
234 s->stream.zalloc = (alloc_func)ndbz_alloc;
235 s->stream.zfree = (free_func)ndbz_free;
240 err= posix_memalign((
void**)&(s->inbuf),512,AZ_BUFSIZE_READ);
242 s->inbuf= malloc(AZ_BUFSIZE_READ);
245 err= posix_memalign((
void**)&(s->outbuf),512,AZ_BUFSIZE_WRITE);
247 s->outbuf= malloc(AZ_BUFSIZE_WRITE);
252 memset(s->inbuf, 0, AZ_BUFSIZE_READ);
253 memset(s->outbuf, 0, AZ_BUFSIZE_WRITE);
254 s->stream.next_in = s->inbuf;
255 s->stream.next_out = s->outbuf;
256 s->stream.avail_in = s->stream.avail_out = 0;
262 s->crc = crc32(0L, Z_NULL, 0);
265 s->version = (
unsigned char)az_magic[1];
266 s->version = (
unsigned char)az_magic[2];
272 assert(Flags | O_APPEND);
273 assert(Flags | O_WRONLY);
275 if (Flags & O_RDWR || Flags & O_WRONLY)
280 err = deflateInit2(&(s->stream), level,
281 Z_DEFLATED, -MAX_WBITS, AZ_MEMLEVEL, strategy);
284 s->stream.next_out = s->outbuf;
291 s->stream.next_in = s->inbuf;
293 err = inflateInit2(&(s->stream), -MAX_WBITS);
306 s->stream.avail_out = AZ_BUFSIZE_WRITE;
309 s->file = fd < 0 ? my_open(path, Flags, MYF(0)) : fd;
317 if (Flags & O_CREAT || Flags & O_TRUNC)
320 s->forced_flushes= 0;
323 s->auto_increment= 0;
325 s->comment_start_pos= 0;
326 s->comment_length= 0;
330 s->start = AZHEADER_SIZE + AZMETA_BUFFER_SIZE;
333 if(my_seek(s->file, 0, MY_SEEK_END, MYF(0)) == MY_FILEPOS_ERROR)
336 else if (s->mode ==
'w')
338 if(my_pread(s->file, s->inbuf, AZHEADER_SIZE + AZMETA_BUFFER_SIZE, 0,
339 MYF(0)) < AZHEADER_SIZE + AZMETA_BUFFER_SIZE)
341 read_header(s, s->inbuf);
342 if(my_seek(s->file, 0, MY_SEEK_END, MYF(0)) == MY_FILEPOS_ERROR)
347 if(check_header(s)!=0)
357 char *buffer= (
char*)s->outbuf;
360 s->block_size= AZ_BUFSIZE_WRITE;
361 s->version = (
unsigned char)az_magic[1];
362 s->minor_version = (
unsigned char)az_magic[2];
366 memset(buffer, 0, AZHEADER_SIZE + AZMETA_BUFFER_SIZE);
367 *(ptr + AZ_MAGIC_POS)= az_magic[0];
368 *(ptr + AZ_VERSION_POS)= (
unsigned char)s->version;
369 *(ptr + AZ_MINOR_VERSION_POS)= (
unsigned char)s->minor_version;
370 *(ptr + AZ_BLOCK_POS)= (
unsigned char)(s->block_size/1024);
371 *(ptr + AZ_STRATEGY_POS)= (
unsigned char)Z_DEFAULT_STRATEGY;
373 int4store(ptr + AZ_FRM_POS, s->frm_start_pos);
374 int4store(ptr + AZ_FRM_LENGTH_POS, s->frm_length);
375 int4store(ptr + AZ_COMMENT_POS, s->comment_start_pos);
376 int4store(ptr + AZ_COMMENT_LENGTH_POS, s->comment_length);
377 int4store(ptr + AZ_META_POS, 0);
378 int4store(ptr + AZ_META_LENGTH_POS, 0);
379 int8store(ptr + AZ_START_POS, (
unsigned long long)s->start);
380 int8store(ptr + AZ_ROW_POS, (
unsigned long long)s->rows);
381 int8store(ptr + AZ_FLUSH_POS, (
unsigned long long)s->forced_flushes);
382 int8store(ptr + AZ_CHECK_POS, (
unsigned long long)s->check_point);
383 int8store(ptr + AZ_AUTOINCREMENT_POS, (
unsigned long long)s->auto_increment);
384 int4store(ptr+ AZ_LONGEST_POS , s->longest_row);
385 int4store(ptr+ AZ_SHORTEST_POS, s->shortest_row);
386 int4store(ptr+ AZ_FRM_POS,
387 AZHEADER_SIZE + AZMETA_BUFFER_SIZE);
388 *(ptr + AZ_DIRTY_POS)= (
unsigned char)s->dirty;
391 if(my_pwrite(s->file, (uchar*) buffer, AZHEADER_SIZE + AZMETA_BUFFER_SIZE, 0,
392 MYF(0)) == (size_t)-1)
403 return ndbz_open(s, path, Flags, -1);
412 if (fd < 0)
return 0;
414 return ndbz_open (s, NULL, Flags, fd);
427 if (s->z_eof)
return EOF;
429 if (s->stream.avail_in == 0)
431 s->stream.avail_in = my_read(s->file, (uchar *)s->inbuf, AZ_BUFSIZE_READ, MYF(0));
432 if(s->stream.avail_in > 0)
434 if (s->stream.avail_in == 0)
438 s->stream.next_in = s->inbuf;
450 if (s->stream.avail_in == 0)
453 s->stream.avail_in--;
454 return *(s->stream.next_in)++;
464 unsigned char *r= s->stream.next_in;
465 if (s->stream.avail_in == 0)
468 s->stream.avail_in-=blksz;
469 s->stream.next_in+=blksz;
490 if(s->stream.avail_in==0)
491 if((c= read_buffer(s)))
495 if ( s->stream.next_in[0] == gz_magic[0] && s->stream.next_in[1] == gz_magic[1])
498 s->stream.avail_in -= 2;
499 s->stream.next_in += 2;
500 s->version= (
unsigned char)2;
503 method = get_byte(s);
505 if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
506 s->z_err = Z_DATA_ERROR;
511 for (len = 0; len < 6; len++) (
void)get_byte(s);
513 if ((flags & EXTRA_FIELD) != 0) {
514 len = (uInt)get_byte(s);
515 len += ((uInt)get_byte(s))<<8;
517 while (len-- != 0 && get_byte(s) != EOF) ;
519 if ((flags & ORIG_NAME) != 0) {
520 while ((c = get_byte(s)) != 0 && c != EOF) ;
522 if ((flags & COMMENT) != 0) {
523 while ((c = get_byte(s)) != 0 && c != EOF) ;
525 if ((flags & HEAD_CRC) != 0) {
526 for (len = 0; len < 2; len++) (
void)get_byte(s);
528 s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
529 s->start = my_tell(s->file, MYF(0));
530 if(s->start == (my_off_t)-1)
532 s->start-= s->stream.avail_in;
534 else if ( s->stream.next_in[0] == az_magic[0]
535 && s->stream.next_in[1] == az_magic[1])
537 unsigned char *header_block;
538 if(s->stream.avail_in < AZHEADER_SIZE + AZMETA_BUFFER_SIZE)
540 s->z_err = Z_DATA_ERROR;
543 header_block = get_block(s,512);
546 read_header(s, header_block);
551 ndbzseek(s,0,SEEK_SET);
562 if (buffer[0] == az_magic[0] && buffer[1] == az_magic[1])
564 s->version= (
unsigned int)buffer[AZ_VERSION_POS];
565 s->minor_version= (
unsigned int)buffer[AZ_MINOR_VERSION_POS];
566 s->block_size= 1024 * buffer[AZ_BLOCK_POS];
567 s->start= (
unsigned long long)uint8korr(buffer + AZ_START_POS);
568 s->rows= (
unsigned long long)uint8korr(buffer + AZ_ROW_POS);
569 s->check_point= (
unsigned long long)uint8korr(buffer + AZ_CHECK_POS);
570 s->forced_flushes= (
unsigned long long)uint8korr(buffer + AZ_FLUSH_POS);
571 s->auto_increment= (
unsigned long long)uint8korr(buffer + AZ_AUTOINCREMENT_POS);
572 s->longest_row= (
unsigned int)uint4korr(buffer + AZ_LONGEST_POS);
573 s->shortest_row= (
unsigned int)uint4korr(buffer + AZ_SHORTEST_POS);
574 s->frm_start_pos= (
unsigned int)uint4korr(buffer + AZ_FRM_POS);
575 s->frm_length= (
unsigned int)uint4korr(buffer + AZ_FRM_LENGTH_POS);
576 s->comment_start_pos= (
unsigned int)uint4korr(buffer + AZ_COMMENT_POS);
577 s->comment_length= (
unsigned int)uint4korr(buffer + AZ_COMMENT_LENGTH_POS);
578 s->dirty= (
unsigned int)buffer[AZ_DIRTY_POS];
582 assert(buffer[0] == az_magic[0] && buffer[1] == az_magic[1]);
595 if (s->stream.state != NULL)
598 err = deflateEnd(&(s->stream));
599 else if (s->mode ==
'r')
600 err = inflateEnd(&(s->stream));
603 if (s->file > 0 && my_close(s->file, MYF(0)))
608 if (s->z_err < 0) err = s->z_err;
623 unsigned int ZEXPORT ndbzread (
ndbzio_stream *s, voidp
buf,
unsigned int len,
int *error)
625 Bytef *start = (Bytef*)buf;
631 *error= Z_STREAM_ERROR;
635 if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO)
641 if (s->z_err == Z_STREAM_END)
646 next_out = (Byte*)buf;
647 s->stream.next_out = (Bytef*)buf;
648 s->stream.avail_out = len;
650 if (s->stream.avail_out && s->back != EOF) {
651 *next_out++ = s->back;
652 s->stream.next_out++;
653 s->stream.avail_out--;
658 s->z_err = Z_STREAM_END;
664 while (s->stream.avail_out != 0) {
666 if (s->transparent) {
668 uInt
n = s->stream.avail_in;
669 if (n > s->stream.avail_out) n = s->stream.avail_out;
671 memcpy(s->stream.next_out, s->stream.next_in, n);
673 s->stream.next_out = (Bytef *)next_out;
674 s->stream.next_in +=
n;
675 s->stream.avail_out -=
n;
676 s->stream.avail_in -=
n;
678 if (s->stream.avail_out > 0)
681 bytes_read= my_read(s->file, (uchar *)next_out, s->stream.avail_out,
684 s->stream.avail_out -= bytes_read;
691 len -= s->stream.avail_out;
698 if (s->stream.avail_in == 0 && !s->z_eof) {
700 if (s->stream.avail_in == 0)
705 s->in += s->stream.avail_in;
706 s->out += s->stream.avail_out;
707 s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
708 s->in -= s->stream.avail_in;
709 s->out -= s->stream.avail_out;
711 if (s->z_err == Z_STREAM_END) {
714 s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
715 start = s->stream.next_out;
718 if (gotcrc != s->crc) {
719 s->z_err = Z_DATA_ERROR;
734 if (s->z_err != Z_OK || s->z_eof)
break;
736 s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
738 if (len == s->stream.avail_out &&
739 (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO))
745 return (len - s->stream.avail_out);
753 uInt real_len = AZ_BUFSIZE_WRITE - s->stream.avail_out;
754 uInt len = ((real_len+0x1FF)>>9)<<9;
756 memset(s->outbuf+real_len, 0, s->stream.avail_out);
758 s->check_point= my_tell(s->file, MYF(0));
760 my_write(s->file,(uchar*)s->outbuf,len,MYF(0));
762 s->dirty= AZ_STATE_CLEAN;
769 if (s->stream.avail_out == 0)
771 s->stream.next_out = s->outbuf;
772 if (my_write(s->file, (uchar *)s->outbuf, AZ_BUFSIZE_WRITE,
773 MYF(0)) != AZ_BUFSIZE_WRITE)
778 s->stream.avail_out = AZ_BUFSIZE_WRITE;
787 unsigned int ndbzwrite (
ndbzio_stream *s,
const void* buf,
unsigned int len)
790 s->stream.next_in = (Bytef*)buf;
791 s->stream.avail_in = len;
798 while (s->stream.avail_in != 0)
802 s->in += s->stream.avail_in;
803 s->out += s->stream.avail_out;
804 s->z_err = deflate(&(s->stream), Z_NO_FLUSH);
805 s->in -= s->stream.avail_in;
806 s->out -= s->stream.avail_out;
807 if (s->z_err != Z_OK)
break;
809 s->crc = crc32(s->crc, (
const Bytef *)buf, len);
811 if (len > s->longest_row)
814 if (len < s->shortest_row || !(s->shortest_row))
815 s->shortest_row= len;
817 return (
unsigned int)(len - s->stream.avail_in);
830 if (s == NULL || s->mode !=
'w')
return Z_STREAM_ERROR;
832 s->stream.avail_in = 0;
836 len = AZ_BUFSIZE_WRITE - s->stream.avail_out;
840 s->out += s->stream.avail_out;
841 s->z_err = deflate(&(s->stream), flush);
842 s->out -= s->stream.avail_out;
845 if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK;
850 done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
852 if (s->z_err != Z_OK && s->z_err != Z_STREAM_END)
break;
855 if (flush == Z_FINISH)
856 s->dirty= AZ_STATE_CLEAN;
858 s->dirty= AZ_STATE_SAVED;
860 return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
869 unsigned char buffer[AZHEADER_SIZE + AZMETA_BUFFER_SIZE];
870 if(my_pread(s->file, (uchar*) buffer, AZHEADER_SIZE + AZMETA_BUFFER_SIZE, 0,
871 MYF(0)) == (
size_t)-1)
873 read_header(s, buffer);
880 err= do_flush(s, flush);
883 if(my_sync(s->file, MYF(0)) == -1)
885 return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
894 if (s == NULL || s->mode !=
'r')
return -1;
899 s->stream.avail_in = 0;
900 s->stream.next_in = (Bytef *)s->inbuf;
901 s->crc = crc32(0L, Z_NULL, 0);
902 if (!s->transparent) (void)inflateReset(&s->stream);
905 return my_seek(s->file, (
int)s->start, MY_SEEK_SET, MYF(0)) == MY_FILEPOS_ERROR;
919 if (s == NULL || whence == SEEK_END ||
920 s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) {
926 if (whence == SEEK_SET)
933 uInt size = AZ_BUFSIZE_WRITE;
934 if (offset < AZ_BUFSIZE_WRITE) size = (uInt)offset;
936 size = ndbzwrite(s, s->inbuf, size);
937 if (size == 0)
return -1L;
946 if (whence == SEEK_CUR) {
950 if (s->transparent) {
953 s->stream.avail_in = 0;
954 s->stream.next_in = (Bytef *)s->inbuf;
955 if (my_seek(s->file, offset, MY_SEEK_SET, MYF(0)) == MY_FILEPOS_ERROR)
return -1L;
962 if (offset >= s->out) {
964 }
else if (ndbzrewind(s)) {
969 if (offset && s->back != EOF) {
973 if (s->last) s->z_err = Z_STREAM_END;
977 unsigned int size = AZ_BUFSIZE_READ;
978 if (offset < AZ_BUFSIZE_READ) size = (int)offset;
980 size = ndbzread(s, s->outbuf, size, &error);
981 if (error <= 0)
return -1L;
994 return ndbzseek(file, 0L, SEEK_CUR);
1005 for (n = 0; n < 4; n++)
1007 s->stream.avail_out--;
1008 *(s->stream.next_out) = (Bytef)(x & 0xff);
1009 s->stream.next_out++;
1021 uLong x = (uLong)get_byte(s);
1024 x += ((uLong)get_byte(s))<<8;
1025 x += ((uLong)get_byte(s))<<16;
1027 if (c == EOF) s->z_err = Z_DATA_ERROR;
1028 x += ((uLong)c)<<24;
1039 if (s == NULL)
return Z_STREAM_ERROR;
1041 if (s->file < 1)
return Z_OK;
1045 int r= do_flush(s, Z_FINISH);
1052 putLong(s, (uLong)(s->in & 0xffffffff));
1053 putLong(s, 0x4E444244);
1055 flush_write_buffer(s);
1067 if (s == NULL || size == NULL)
1070 if (my_fstat(s->file, &stat_buf, 0) != 0)
1073 *size = stat_buf.st_size;