19 static int const gz_magic[2] = {0x1f, 0x8b};
20 static int const az_magic[3] = {0xfe, 0x03, 0x01};
23 #define ASCII_FLAG 0x01
25 #define EXTRA_FIELD 0x04
26 #define ORIG_NAME 0x08
30 int az_open(
azio_stream *s,
const char *path,
int Flags, File fd);
36 void putLong(File
file, uLong x);
38 void read_header(
azio_stream *s,
unsigned char *buffer);
40 #ifdef HAVE_PSI_INTERFACE
41 extern PSI_file_key arch_key_file_data;
53 int az_open (
azio_stream *s,
const char *path,
int Flags, File fd)
56 int level = Z_DEFAULT_COMPRESSION;
57 int strategy = Z_DEFAULT_STRATEGY;
60 s->stream.next_in = s->inbuf;
61 s->stream.next_out = s->outbuf;
62 DBUG_ASSERT(s->z_err == Z_OK);
64 s->crc = crc32(0L, Z_NULL, 0);
67 s->version = (
unsigned char)az_magic[1];
68 s->minor_version= (
unsigned char) az_magic[2];
69 DBUG_ASSERT(s->dirty == AZ_STATE_CLEAN);
75 DBUG_ASSERT(Flags | O_APPEND);
76 DBUG_ASSERT(Flags | O_WRONLY);
83 err = deflateInit2(&(s->stream), level,
84 Z_DEFLATED, -MAX_WBITS, 8, strategy);
87 s->stream.next_out = s->outbuf;
94 s->stream.next_in = s->inbuf;
96 err = inflateInit2(&(s->stream), -MAX_WBITS);
109 s->stream.avail_out = AZ_BUFSIZE_WRITE;
112 s->file = fd < 0 ?
mysql_file_open(arch_key_file_data, path, Flags, MYF(0)) : fd;
113 DBUG_EXECUTE_IF(
"simulate_archive_open_failure",
117 my_close(s->file, MYF(0));
129 if (Flags & O_CREAT || Flags & O_TRUNC)
132 s->start = AZHEADER_SIZE + AZMETA_BUFFER_SIZE;
134 my_seek(s->file, 0, MY_SEEK_END, MYF(0));
136 else if (s->mode ==
'w')
138 uchar buffer[AZHEADER_SIZE + AZMETA_BUFFER_SIZE];
139 my_pread(s->file, buffer, AZHEADER_SIZE + AZMETA_BUFFER_SIZE, 0,
141 read_header(s, buffer);
142 my_seek(s->file, 0, MY_SEEK_END, MYF(0));
155 char buffer[AZHEADER_SIZE + AZMETA_BUFFER_SIZE];
161 s->block_size= AZ_BUFSIZE_WRITE;
162 s->version = (
unsigned char)az_magic[1];
163 s->minor_version = (
unsigned char)az_magic[2];
167 memset(buffer, 0, AZHEADER_SIZE + AZMETA_BUFFER_SIZE);
168 *(ptr + AZ_MAGIC_POS)= az_magic[0];
169 *(ptr + AZ_VERSION_POS)= (
unsigned char)s->version;
170 *(ptr + AZ_MINOR_VERSION_POS)= (
unsigned char)s->minor_version;
171 *(ptr + AZ_BLOCK_POS)= (
unsigned char)(s->block_size/1024);
172 *(ptr + AZ_STRATEGY_POS)= (
unsigned char)Z_DEFAULT_STRATEGY;
174 int4store(ptr + AZ_FRM_POS, s->frm_start_pos);
175 int4store(ptr + AZ_FRM_LENGTH_POS, s->frm_length);
176 int4store(ptr + AZ_COMMENT_POS, s->comment_start_pos);
177 int4store(ptr + AZ_COMMENT_LENGTH_POS, s->comment_length);
178 int4store(ptr + AZ_META_POS, 0);
179 int4store(ptr + AZ_META_LENGTH_POS, 0);
180 int8store(ptr + AZ_START_POS, (
unsigned long long)s->start);
181 int8store(ptr + AZ_ROW_POS, (
unsigned long long)s->rows);
182 int8store(ptr + AZ_FLUSH_POS, (
unsigned long long)s->forced_flushes);
183 int8store(ptr + AZ_CHECK_POS, (
unsigned long long)s->check_point);
184 int8store(ptr + AZ_AUTOINCREMENT_POS, (
unsigned long long)s->auto_increment);
185 int4store(ptr+ AZ_LONGEST_POS , s->longest_row);
186 int4store(ptr+ AZ_SHORTEST_POS, s->shortest_row);
187 int4store(ptr+ AZ_FRM_POS,
188 AZHEADER_SIZE + AZMETA_BUFFER_SIZE);
189 *(ptr + AZ_DIRTY_POS)= (
unsigned char)s->dirty;
192 return my_pwrite(s->file, (uchar*) buffer, AZHEADER_SIZE + AZMETA_BUFFER_SIZE,
193 0, MYF(MY_NABP)) ? 1 : 0;
199 int azopen(
azio_stream *s,
const char *path,
int Flags)
201 return az_open(s, path, Flags, -1);
210 if (fd < 0)
return 0;
212 return az_open (s, NULL, Flags, fd);
223 if (s->z_eof)
return EOF;
224 if (s->stream.avail_in == 0)
228 AZ_BUFSIZE_READ, MYF(0));
229 if (s->stream.avail_in == 0)
234 else if (s->stream.avail_in == (uInt) -1)
240 s->stream.next_in = s->inbuf;
242 s->stream.avail_in--;
243 return *(s->stream.next_in)++;
265 len = s->stream.avail_in;
267 if (len) s->inbuf[0] = s->stream.next_in[0];
270 AZ_BUFSIZE_READ >> len, MYF(0));
271 if (len == (uInt)-1) s->z_err = Z_ERRNO;
272 s->stream.avail_in += len;
273 s->stream.next_in = s->inbuf;
274 if (s->stream.avail_in < 2) {
275 s->transparent = s->stream.avail_in;
281 if ( s->stream.next_in[0] == gz_magic[0] && s->stream.next_in[1] == gz_magic[1])
283 read_header(s, s->stream.next_in);
284 s->stream.avail_in -= 2;
285 s->stream.next_in += 2;
288 method = get_byte(s);
290 if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
291 s->z_err = Z_DATA_ERROR;
296 for (len = 0; len < 6; len++) (
void)get_byte(s);
298 if ((flags & EXTRA_FIELD) != 0) {
299 len = (uInt)get_byte(s);
300 len += ((uInt)get_byte(s))<<8;
302 while (len-- != 0 && get_byte(s) != EOF) ;
304 if ((flags & ORIG_NAME) != 0) {
305 while ((c = get_byte(s)) != 0 && c != EOF) ;
307 if ((flags & COMMENT) != 0) {
308 while ((c = get_byte(s)) != 0 && c != EOF) ;
310 if ((flags & HEAD_CRC) != 0) {
311 for (len = 0; len < 2; len++) (
void)get_byte(s);
313 s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
315 s->start= my_tell(s->file, MYF(0)) - s->stream.avail_in;
317 else if ( s->stream.next_in[0] == az_magic[0] && s->stream.next_in[1] == az_magic[1])
319 unsigned char buffer[AZHEADER_SIZE + AZMETA_BUFFER_SIZE];
321 for (len = 0; len < (AZHEADER_SIZE + AZMETA_BUFFER_SIZE); len++)
322 buffer[len]= get_byte(s);
323 s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
324 read_header(s, buffer);
325 for (; len < s->start; len++)
336 void read_header(
azio_stream *s,
unsigned char *buffer)
338 if (buffer[0] == az_magic[0] && buffer[1] == az_magic[1])
340 s->version= (
unsigned int)buffer[AZ_VERSION_POS];
341 s->minor_version= (
unsigned int)buffer[AZ_MINOR_VERSION_POS];
342 s->block_size= 1024 * buffer[AZ_BLOCK_POS];
343 s->start= (
unsigned long long)uint8korr(buffer + AZ_START_POS);
344 s->rows= (
unsigned long long)uint8korr(buffer + AZ_ROW_POS);
345 s->check_point= (
unsigned long long)uint8korr(buffer + AZ_CHECK_POS);
346 s->forced_flushes= (
unsigned long long)uint8korr(buffer + AZ_FLUSH_POS);
347 s->auto_increment= (
unsigned long long)uint8korr(buffer + AZ_AUTOINCREMENT_POS);
348 s->longest_row= (
unsigned int)uint4korr(buffer + AZ_LONGEST_POS);
349 s->shortest_row= (
unsigned int)uint4korr(buffer + AZ_SHORTEST_POS);
350 s->frm_start_pos= (
unsigned int)uint4korr(buffer + AZ_FRM_POS);
351 s->frm_length= (
unsigned int)uint4korr(buffer + AZ_FRM_LENGTH_POS);
352 s->comment_start_pos= (
unsigned int)uint4korr(buffer + AZ_COMMENT_POS);
353 s->comment_length= (
unsigned int)uint4korr(buffer + AZ_COMMENT_LENGTH_POS);
354 s->dirty= (
unsigned int)buffer[AZ_DIRTY_POS];
356 else if (buffer[0] == gz_magic[0] && buffer[1] == gz_magic[1])
362 s->auto_increment= 0;
369 s->dirty= AZ_STATE_DIRTY;
370 s->z_err= Z_VERSION_ERROR;
383 if (s->stream.state != NULL)
386 err = deflateEnd(&(s->stream));
387 else if (s->mode ==
'r')
388 err = inflateEnd(&(s->stream));
391 if (s->file > 0 && my_close(s->file, MYF(0)))
396 if (s->z_err < 0) err = s->z_err;
405 unsigned int ZEXPORT azread (
azio_stream *s, voidp
buf,
size_t len,
int *error)
407 Bytef *start = (Bytef*)buf;
413 *error= Z_STREAM_ERROR;
417 if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO)
423 if (s->z_err == Z_STREAM_END)
428 next_out = (Byte*)buf;
429 s->stream.next_out = (Bytef*)buf;
430 s->stream.avail_out = len;
432 if (s->stream.avail_out && s->back != EOF) {
433 *next_out++ = s->back;
434 s->stream.next_out++;
435 s->stream.avail_out--;
440 s->z_err = Z_STREAM_END;
447 while (s->stream.avail_out != 0) {
449 if (s->transparent) {
451 uInt
n = s->stream.avail_in;
452 if (n > s->stream.avail_out) n = s->stream.avail_out;
454 memcpy(s->stream.next_out, s->stream.next_in, n);
456 s->stream.next_out = (Bytef *)next_out;
457 s->stream.next_in +=
n;
458 s->stream.avail_out -=
n;
459 s->stream.avail_in -=
n;
461 if (s->stream.avail_out > 0)
463 s->stream.avail_out -=
465 s->stream.avail_out, MYF(0));
467 len -= s->stream.avail_out;
470 if (len == 0) s->z_eof = 1;
475 if (s->stream.avail_in == 0 && !s->z_eof) {
479 AZ_BUFSIZE_READ, MYF(0));
480 if (s->stream.avail_in == 0)
484 s->stream.next_in = (Bytef *)s->inbuf;
486 s->in += s->stream.avail_in;
487 s->out += s->stream.avail_out;
488 s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
489 s->in -= s->stream.avail_in;
490 s->out -= s->stream.avail_out;
492 if (s->z_err == Z_STREAM_END) {
494 s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
495 start = s->stream.next_out;
497 if (getLong(s) != s->crc) {
498 s->z_err = Z_DATA_ERROR;
506 if (s->z_err == Z_OK)
508 inflateReset(&(s->stream));
509 s->crc = crc32(0L, Z_NULL, 0);
513 if (s->z_err != Z_OK || s->z_eof)
break;
515 s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
517 if (len == s->stream.avail_out &&
518 (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO))
525 return (len - s->stream.avail_out);
533 unsigned int azwrite (
azio_stream *s,
const voidp buf,
unsigned int len)
535 s->stream.next_in = (Bytef*)buf;
536 s->stream.avail_in = len;
540 while (s->stream.avail_in != 0)
542 if (s->stream.avail_out == 0)
545 s->stream.next_out = s->outbuf;
547 MYF(0)) != AZ_BUFSIZE_WRITE)
552 s->stream.avail_out = AZ_BUFSIZE_WRITE;
554 s->in += s->stream.avail_in;
555 s->out += s->stream.avail_out;
556 s->z_err = deflate(&(s->stream), Z_NO_FLUSH);
557 s->in -= s->stream.avail_in;
558 s->out -= s->stream.avail_out;
559 if (s->z_err != Z_OK)
break;
561 s->crc = crc32(s->crc, (
const Bytef *)buf, len);
563 if (len > s->longest_row)
566 if (len < s->shortest_row || !(s->shortest_row))
567 s->shortest_row= len;
569 return (
unsigned int)(len - s->stream.avail_in);
581 my_off_t afterwrite_pos;
583 if (s == NULL || s->mode !=
'w')
return Z_STREAM_ERROR;
585 s->stream.avail_in = 0;
589 len = AZ_BUFSIZE_WRITE - s->stream.avail_out;
593 s->check_point= my_tell(s->file, MYF(0));
594 if ((uInt)
mysql_file_write(s->file, (uchar *)s->outbuf, len, MYF(0)) != len)
599 s->stream.next_out = s->outbuf;
600 s->stream.avail_out = AZ_BUFSIZE_WRITE;
603 s->out += s->stream.avail_out;
604 s->z_err = deflate(&(s->stream), flush);
605 s->out -= s->stream.avail_out;
608 if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK;
613 done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
615 if (s->z_err != Z_OK && s->z_err != Z_STREAM_END)
break;
618 if (flush == Z_FINISH)
619 s->dirty= AZ_STATE_CLEAN;
621 s->dirty= AZ_STATE_SAVED;
623 afterwrite_pos= my_tell(s->file, MYF(0));
625 my_seek(s->file, afterwrite_pos, SEEK_SET, MYF(0));
627 return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
630 int ZEXPORT azflush (s, flush)
638 unsigned char buffer[AZHEADER_SIZE + AZMETA_BUFFER_SIZE];
639 my_pread(s->file, (uchar*) buffer, AZHEADER_SIZE + AZMETA_BUFFER_SIZE, 0,
641 read_header(s, buffer);
648 err= do_flush(s, flush);
651 my_sync(s->file, MYF(0));
652 return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
662 if (s == NULL || s->mode !=
'r')
return -1;
667 s->stream.avail_in = 0;
668 s->stream.next_in = (Bytef *)s->inbuf;
669 s->crc = crc32(0L, Z_NULL, 0);
670 if (!s->transparent) (void)inflateReset(&s->stream);
673 return my_seek(s->file, (
int)s->start, MY_SEEK_SET, MYF(0)) == MY_FILEPOS_ERROR;
684 my_off_t azseek (s,
offset, whence)
690 if (s == NULL || whence == SEEK_END ||
691 s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) {
697 if (whence == SEEK_SET)
704 uInt
size = AZ_BUFSIZE_READ;
705 if (offset < AZ_BUFSIZE_READ) size = (uInt)offset;
707 size = azwrite(s, s->inbuf, size);
708 if (size == 0)
return -1L;
717 if (whence == SEEK_CUR) {
721 if (s->transparent) {
724 s->stream.avail_in = 0;
725 s->stream.next_in = (Bytef *)s->inbuf;
726 if (my_seek(s->file, offset, MY_SEEK_SET, MYF(0)) == MY_FILEPOS_ERROR)
return -1L;
733 if (offset >= s->out) {
735 }
else if (azrewind(s)) {
740 if (offset && s->back != EOF) {
744 if (s->last) s->z_err = Z_STREAM_END;
748 unsigned int size = AZ_BUFSIZE_WRITE;
749 if (offset < AZ_BUFSIZE_WRITE) size = (int)offset;
751 size = azread(s, s->outbuf, size, &error);
752 if (error < 0)
return -1L;
763 my_off_t ZEXPORT aztell (
file)
766 return azseek(file, 0L, SEEK_CUR);
773 void putLong (File
file, uLong x)
778 for (n = 0; n < 4; n++)
780 buffer[0]= (int)(x & 0xff);
792 uLong x = (uLong)get_byte(s);
795 x += ((uLong)get_byte(s))<<8;
796 x += ((uLong)get_byte(s))<<16;
798 if (c == EOF) s->z_err = Z_DATA_ERROR;
810 if (s == NULL)
return Z_STREAM_ERROR;
812 if (s->file < 1)
return Z_OK;
816 if (do_flush(s, Z_FINISH) != Z_OK)
819 putLong(s->file, s->crc);
820 putLong(s->file, (uLong)(s->in & 0xffffffff));
821 s->dirty= AZ_STATE_CLEAN;
822 s->check_point= my_tell(s->file, MYF(0));
833 int azwrite_frm(
azio_stream *s,
char *blob,
unsigned int length)
841 s->frm_start_pos= (uint) s->start;
842 s->frm_length= length;
845 if (my_pwrite(s->file, (uchar*) blob, s->frm_length,
846 s->frm_start_pos, MYF(MY_NABP)) ||
848 (my_seek(s->file, 0, MY_SEEK_END, MYF(0)) == MY_FILEPOS_ERROR))
856 return my_pread(s->file, (uchar*) blob, s->frm_length,
857 s->frm_start_pos, MYF(MY_NABP)) ? 1 : 0;
864 int azwrite_comment(
azio_stream *s,
char *blob,
unsigned int length)
872 s->comment_start_pos= (uint) s->start;
873 s->comment_length= length;
876 my_pwrite(s->file, (uchar*) blob, s->comment_length, s->comment_start_pos,
880 my_seek(s->file, 0, MY_SEEK_END, MYF(0));
887 my_pread(s->file, (uchar*) blob, s->comment_length, s->comment_start_pos,