17
17
#include <string.h>
19
18
#include <assert.h>
20
19
#include <unistd.h>
22
21
static int const az_magic[3] = {0xfe, 0x03, 0x01}; /* az magic header */
24
#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
25
#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
26
#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
27
#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
28
#define COMMENT 0x10 /* bit 4 set: file comment present */
29
#define RESERVED 0xE0 /* bits 5..7: reserved */
24
31
static unsigned int azwrite(azio_stream *s, void *buf, unsigned int len);
25
32
static int azrewind (azio_stream *s);
26
33
static unsigned int azio_enable_aio(azio_stream *s);
27
34
static int do_flush(azio_stream *file, int flush);
28
35
static int get_byte(azio_stream *s);
29
36
static void check_header(azio_stream *s);
30
static int write_header(azio_stream *s);
37
static void write_header(azio_stream *s);
31
38
static int destroy(azio_stream *s);
32
39
static void putLong(azio_stream *s, uLong x);
33
40
static uLong getLong(azio_stream *s);
57
63
offset= s->container.offset;
58
64
fd= s->container.fd;
59
buffer= (char *)s->container.buffer;
65
buffer= s->container.buffer;
60
66
pthread_mutex_unlock(&s->container.thresh_mutex);
62
68
if (s->container.ready == AZ_THREAD_DEAD)
82
88
pthread_mutex_unlock(&s->container.thresh_mutex);
84
90
pthread_cond_signal(&s->container.threshhold);
85
pthread_join(s->container.mainthread, NULL);
91
pthread_join(s->container.mainthread, (void *)NULL);
88
94
static size_t azio_return(azio_stream *s)
247
253
s->frm_length= 0;
248
254
s->dirty= 1; /* We create the file dirty */
249
255
s->start = AZHEADER_SIZE + AZMETA_BUFFER_SIZE;
252
257
s->pos= (size_t)my_seek(s->file, 0, MY_SEEK_END, MYF(0));
254
259
else if (s->mode == 'w')
256
unsigned char buffer[AZHEADER_SIZE + AZMETA_BUFFER_SIZE];
257
const ssize_t read_size= AZHEADER_SIZE + AZMETA_BUFFER_SIZE;
258
if(pread(s->file, buffer, read_size, 0) < read_size)
261
uchar buffer[AZHEADER_SIZE + AZMETA_BUFFER_SIZE];
262
pread(s->file, buffer, AZHEADER_SIZE + AZMETA_BUFFER_SIZE, 0);
260
263
read_header(s, buffer);
261
264
s->pos= (size_t)my_seek(s->file, 0, MY_SEEK_END, MYF(0));
303
306
int4store(ptr + AZ_COMMENT_LENGTH_POS, s->comment_length); /* COMMENT Block */
304
307
int4store(ptr + AZ_META_POS, 0); /* Meta Block */
305
308
int4store(ptr + AZ_META_LENGTH_POS, 0); /* Meta Block */
306
int8store(ptr + AZ_START_POS, (uint64_t)s->start); /* Start of Data Block Index Block */
307
int8store(ptr + AZ_ROW_POS, (uint64_t)s->rows); /* Start of Data Block Index Block */
308
int8store(ptr + AZ_FLUSH_POS, (uint64_t)s->forced_flushes); /* Start of Data Block Index Block */
309
int8store(ptr + AZ_CHECK_POS, (uint64_t)s->check_point); /* Start of Data Block Index Block */
310
int8store(ptr + AZ_AUTOINCREMENT_POS, (uint64_t)s->auto_increment); /* Start of Data Block Index Block */
309
int8store(ptr + AZ_START_POS, (unsigned long long)s->start); /* Start of Data Block Index Block */
310
int8store(ptr + AZ_ROW_POS, (unsigned long long)s->rows); /* Start of Data Block Index Block */
311
int8store(ptr + AZ_FLUSH_POS, (unsigned long long)s->forced_flushes); /* Start of Data Block Index Block */
312
int8store(ptr + AZ_CHECK_POS, (unsigned long long)s->check_point); /* Start of Data Block Index Block */
313
int8store(ptr + AZ_AUTOINCREMENT_POS, (unsigned long long)s->auto_increment); /* Start of Data Block Index Block */
311
314
int4store(ptr+ AZ_LONGEST_POS , s->longest_row); /* Longest row */
312
315
int4store(ptr+ AZ_SHORTEST_POS, s->shortest_row); /* Shorest row */
313
316
int4store(ptr+ AZ_FRM_POS,
315
318
*(ptr + AZ_DIRTY_POS)= (unsigned char)s->dirty; /* Start of Data Block Index Block */
317
320
/* Always begin at the begining, and end there as well */
318
const ssize_t write_size= AZHEADER_SIZE + AZMETA_BUFFER_SIZE;
319
if(pwrite(s->file, (unsigned char*) buffer, write_size, 0)!=write_size)
321
pwrite(s->file, (uchar*) buffer, AZHEADER_SIZE + AZMETA_BUFFER_SIZE, 0);
325
324
/* ===========================================================================
368
368
if (len) s->inbuf[0] = s->stream.next_in[0];
370
len = (uInt)pread(s->file, (unsigned char *)s->inbuf + len, AZ_BUFSIZE_READ >> len, s->pos);
370
len = (uInt)pread(s->file, (uchar *)s->inbuf + len, AZ_BUFSIZE_READ >> len, s->pos);
372
372
if (len == (uInt)-1) s->z_err = Z_ERRNO;
373
373
s->stream.avail_in += len;
402
402
s->minor_version= (unsigned int)buffer[AZ_MINOR_VERSION_POS];
403
403
s->block_size= 1024 * buffer[AZ_BLOCK_POS];
404
404
s->start= (size_t)uint8korr(buffer + AZ_START_POS);
405
s->rows= (uint64_t)uint8korr(buffer + AZ_ROW_POS);
406
s->check_point= (uint64_t)uint8korr(buffer + AZ_CHECK_POS);
407
s->forced_flushes= (uint64_t)uint8korr(buffer + AZ_FLUSH_POS);
408
s->auto_increment= (uint64_t)uint8korr(buffer + AZ_AUTOINCREMENT_POS);
405
s->rows= (unsigned long long)uint8korr(buffer + AZ_ROW_POS);
406
s->check_point= (unsigned long long)uint8korr(buffer + AZ_CHECK_POS);
407
s->forced_flushes= (unsigned long long)uint8korr(buffer + AZ_FLUSH_POS);
408
s->auto_increment= (unsigned long long)uint8korr(buffer + AZ_AUTOINCREMENT_POS);
409
409
s->longest_row= (unsigned int)uint4korr(buffer + AZ_LONGEST_POS);
410
410
s->shortest_row= (unsigned int)uint4korr(buffer + AZ_SHORTEST_POS);
411
411
s->frm_start_pos= (unsigned int)uint4korr(buffer + AZ_FRM_POS);
624
625
s->stream.next_out = s->outbuf;
625
if (pwrite(s->file, (unsigned char *)s->outbuf, AZ_BUFSIZE_WRITE, s->pos) != AZ_BUFSIZE_WRITE)
626
if (pwrite(s->file, (uchar *)s->outbuf, AZ_BUFSIZE_WRITE, s->pos) != AZ_BUFSIZE_WRITE)
627
628
s->z_err = Z_ERRNO;
666
if ((uInt)pwrite(s->file, (unsigned char *)s->outbuf, len, s->pos) != len)
667
if ((uInt)pwrite(s->file, (uchar *)s->outbuf, len, s->pos) != len)
668
669
s->z_err = Z_ERRNO;
696
697
s->dirty= AZ_STATE_SAVED; /* Mark it clean, we should be good now */
698
699
afterwrite_pos= (size_t)my_tell(s->file, MYF(0));
702
702
return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
705
705
static unsigned int azio_enable_aio(azio_stream *s)
707
pthread_cond_init(&s->container.threshhold, NULL);
708
pthread_mutex_init(&s->container.thresh_mutex, NULL);
707
VOID(pthread_cond_init(&s->container.threshhold, NULL));
708
VOID(pthread_mutex_init(&s->container.thresh_mutex, NULL));
718
pthread_mutex_destroy(&s->container.thresh_mutex);
719
pthread_cond_destroy(&s->container.threshhold);
718
VOID(pthread_mutex_destroy(&s->container.thresh_mutex));
719
VOID(pthread_cond_destroy(&s->container.threshhold));
721
721
s->method= AZ_METHOD_BLOCK;
724
int ZEXPORT azflush (azio_stream *s,int flush)
724
int ZEXPORT azflush (s, flush)
728
730
if (s->mode == 'r')
730
732
unsigned char buffer[AZHEADER_SIZE + AZMETA_BUFFER_SIZE];
731
const ssize_t read_size= AZHEADER_SIZE + AZMETA_BUFFER_SIZE;
732
if(pread(s->file, (unsigned char*) buffer, read_size, 0)!=read_size)
733
pread(s->file, (uchar*) buffer, AZHEADER_SIZE + AZMETA_BUFFER_SIZE, 0);
734
734
read_header(s, buffer); /* skip the .az header */
806
807
SEEK_END is not implemented, returns error.
807
808
In this version of the library, azseek can be extremely slow.
809
size_t azseek (azio_stream *s, size_t offset, int whence)
810
size_t azseek (s, offset, whence)
812
816
if (s == NULL || whence == SEEK_END ||
813
817
s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) {
817
821
if (s->mode == 'w')
861
864
if (offset < AZ_BUFSIZE_WRITE) size = (int)offset;
863
866
size = azread_internal(s, s->outbuf, size, &error);
864
if (error < 0) return SIZE_MAX;
867
if (error < 0) return -1L;
872
875
given compressed file. This position represents a number of bytes in the
873
876
uncompressed data stream.
875
size_t ZEXPORT aztell (azio_stream *file)
878
size_t ZEXPORT aztell (file)
877
881
return azseek(file, 0L, SEEK_CUR);
884
888
void putLong (azio_stream *s, uLong x)
887
unsigned char buffer[1];
889
893
for (n = 0; n < 4; n++)
891
895
buffer[0]= (int)(x & 0xff);
892
assert(pwrite(s->file, buffer, 1, s->pos)==1);
896
pwrite(s->file, buffer, 1, s->pos);
970
974
s->frm_length= length;
971
975
s->start+= length;
973
if (pwrite(s->file, (unsigned char*) blob, s->frm_length, s->frm_start_pos) != (ssize_t)s->frm_length)
977
pwrite(s->file, (uchar*) blob, s->frm_length, s->frm_start_pos);
977
980
s->pos= (size_t)my_seek(s->file, 0, MY_SEEK_END, MYF(0));
982
985
int azread_frm(azio_stream *s, char *blob)
984
ssize_t r= pread(s->file, (unsigned char*) blob,
985
s->frm_length, s->frm_start_pos);
986
if (r != (ssize_t)s->frm_length)
987
pread(s->file, (uchar*) blob, s->frm_length, s->frm_start_pos);
1005
1005
s->comment_length= length;
1006
1006
s->start+= length;
1008
ssize_t r= pwrite(s->file, (unsigned char*) blob,
1009
s->comment_length, s->comment_start_pos);
1010
if (r != (ssize_t)s->comment_length)
1008
pwrite(s->file, (uchar*) blob, s->comment_length, s->comment_start_pos);
1013
1010
write_header(s);
1014
1011
s->pos= (size_t)my_seek(s->file, 0, MY_SEEK_END, MYF(0));
1019
1016
int azread_comment(azio_stream *s, char *blob)
1021
ssize_t r= pread(s->file, (unsigned char*) blob,
1022
s->comment_length, s->comment_start_pos);
1023
if (r != (ssize_t)s->comment_length)
1018
pread(s->file, (uchar*) blob, s->comment_length, s->comment_start_pos);
1075
1069
#ifdef AZIO_AIO
1078
s->stream.avail_in = (uInt)pread(s->file, (unsigned char *)s->inbuf,
1072
s->stream.avail_in = (uInt)pread(s->file, (uchar *)s->inbuf,
1079
1073
AZ_BUFSIZE_READ, s->pos);
1080
1074
s->pos+= s->stream.avail_in;