Pantek Library
Hosting Provided By
CybrHost
High Speed Hosting

[patch 1/8] WL4081: Copy azio for NDB

From: <stewart(at)mysql.com>
Date: Thu Oct 11 2007 - 04:45:42 EDT


Only copy the files directly from ARCHIVE engine.

Index: ndb-work/storage/ndb/include/util/azlib.h


  • /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ ndb-work/storage/ndb/include/util/azlib.h 2007-09-24 17:26:58.388401288 +0200 @@ -0,0 +1,342 @@ +/*
    + This libary has been modified for use by the MySQL Archive Engine.
    + -Brian Aker
    +*/ + +/* zlib.h -- interface of the 'zlib' general purpose compression library
    + version 1.2.3, July 18th, 2005
    +
    + Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
    +
    + This software is provided 'as-is', without any express or implied
    + warranty. In no event will the authors be held liable for any damages
    + arising from the use of this software.
    +
    + Permission is granted to anyone to use this software for any purpose,
    + including commercial applications, and to alter it and redistribute it
    + freely, subject to the following restrictions:
    +
    + 1. The origin of this software must not be misrepresented; you must not
    + claim that you wrote the original software. If you use this software
    + in a product, an acknowledgment in the product documentation would be
    + appreciated but is not required.
    + 2. Altered source versions must be plainly marked as such, and must not be
    + misrepresented as being the original software.
    + 3. This notice may not be removed or altered from any source distribution.
    +
    + Jean-loup Gailly Mark Adler
    + jloup@gzip.org madler@alumni.caltech.edu
    + +
    + The data format used by the zlib library is described by RFCs (Request for
    + Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
    + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
    +*/ + +#include <zlib.h> + +#include "../../mysys/mysys_priv.h" +#include <my_dir.h> + +#ifdef __cplusplus +extern "C" { +#endif +/* Start of MySQL Specific Information */ + +/*
    + ulonglong + ulonglong + ulonglong + ulonglong + uchar
    +*/ +#define AZMETA_BUFFER_SIZE sizeof(unsigned long long) \
    + + sizeof(unsigned long long) + sizeof(unsigned long long) + sizeof(unsigned long long) \
    + + sizeof(unsigned int) + sizeof(unsigned int) \
    + + sizeof(unsigned int) + sizeof(unsigned int) \
    + + sizeof(unsigned char)
    + +#define AZHEADER_SIZE 29 + +#define AZ_MAGIC_POS 0 +#define AZ_VERSION_POS 1 +#define AZ_MINOR_VERSION_POS 2 +#define AZ_BLOCK_POS 3 +#define AZ_STRATEGY_POS 4 +#define AZ_FRM_POS 5 +#define AZ_FRM_LENGTH_POS 9 +#define AZ_META_POS 13 +#define AZ_META_LENGTH_POS 17 +#define AZ_START_POS 21 +#define AZ_ROW_POS 29 +#define AZ_FLUSH_POS 37 +#define AZ_CHECK_POS 45 +#define AZ_AUTOINCREMENT_POS 53 +#define AZ_LONGEST_POS 61 +#define AZ_SHORTEST_POS 65 +#define AZ_COMMENT_POS 69 +#define AZ_COMMENT_LENGTH_POS 73 +#define AZ_DIRTY_POS 77 + + +/*
    + Flags for state
    +*/ +#define AZ_STATE_CLEAN 0 +#define AZ_STATE_DIRTY 1 +#define AZ_STATE_SAVED 2 +#define AZ_STATE_CRASHED 3 + +/*
    + The 'zlib' compression library provides in-memory compression and
    + decompression functions, including integrity checks of the uncompressed
    + data. This version of the library supports only one compression method
    + (deflation) but other algorithms will be added later and will have the same
    + stream interface.
    +
    + Compression can be done in a single step if the buffers are large
    + enough (for example if an input file is mmap'ed), or can be done by
    + repeated calls of the compression function. In the latter case, the
    + application must provide more input and/or consume the output
    + (providing more output space) before each call.
    +
    + The compressed data format used by default by the in-memory functions is
    + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
    + around a deflate stream, which is itself documented in RFC 1951.
    +
    + The library also supports reading and writing files in gzip (.gz) format
    + with an interface similar to that of stdio using the functions that start
    + with "gz". The gzip format is different from the zlib format. gzip is a
    + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
    +
    + This library can optionally read and write gzip streams in memory as well.
    +
    + The zlib format was designed to be compact and fast for use in memory
    + and on communications channels. The gzip format was designed for single-
    + file compression on file systems, has a larger header than zlib to maintain
    + directory information, and uses a different, slower check method than zlib.
    +
    + The library does not install any signal handler. The decoder checks
    + the consistency of the compressed data, so the library should never
    + crash even in case of corrupted input.
    +*/ + + +/*
    + The application must update next_in and avail_in when avail_in has
    + dropped to zero. It must update next_out and avail_out when avail_out
    + has dropped to zero. The application must initialize zalloc, zfree and
    + opaque before calling the init function. All other fields are set by the
    + compression library and must not be updated by the application.
    +
    + The opaque value provided by the application will be passed as the first
    + parameter for calls of zalloc and zfree. This can be useful for custom
    + memory management. The compression library attaches no meaning to the
    + opaque value.
    +
    + zalloc must return Z_NULL if there is not enough memory for the object.
    + If zlib is used in a multi-threaded application, zalloc and zfree must be
    + thread safe.
    +
    + On 16-bit systems, the functions zalloc and zfree must be able to allocate
    + exactly 65536 bytes, but will not be required to allocate more than this
    + if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
    + pointers returned by zalloc for objects of exactly 65536 bytes *must*
    + have their offset normalized to zero. The default allocation function
    + provided by this library ensures this (see zutil.c). To reduce memory
    + requirements and avoid any allocation of 64K objects, at the expense of
    + compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
    +
    + The fields total_in and total_out can be used for statistics or
    + progress reports. After compression, total_in holds the total size of
    + the uncompressed data and may be saved for use in the decompressor
    + (particularly if the decompressor wants to decompress everything in
    + a single step).
    +*/ +
    + /* constants */
    + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative + * values are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_FIXED 4 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_TEXT 1 +#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN 2 +/* Possible values of the data_type field (though see inflate()) */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ +#define AZ_BUFSIZE_READ 32768 +#define AZ_BUFSIZE_WRITE 16384 + + +typedef struct azio_stream {
    + z_stream stream;
    + int z_err; /* error code for last stream operation */
    + int z_eof; /* set if end of input file */
    + File file; /* .gz file */
    + Byte inbuf[AZ_BUFSIZE_READ]; /* input buffer */
    + Byte outbuf[AZ_BUFSIZE_WRITE]; /* output buffer */
    + uLong crc; /* crc32 of uncompressed data */
    + char *msg; /* error message */
    + int transparent; /* 1 if input file is not a .gz file */
    + char mode; /* 'w' or 'r' */
    + my_off_t start; /* start of compressed data in file (header skipped) */
    + my_off_t in; /* bytes into deflate or inflate */
    + my_off_t out; /* bytes out of deflate or inflate */
    + int back; /* one character push-back */
    + int last; /* true if push-back is last character */
    + unsigned char version; /* Version */
    + unsigned char minor_version; /* Version */
    + unsigned int block_size; /* Block Size */
    + unsigned long long check_point; /* Last position we checked */
    + unsigned long long forced_flushes; /* Forced Flushes */
    + unsigned long long rows; /* rows */
    + unsigned long long auto_increment; /* auto increment field */
    + unsigned int longest_row; /* Longest row */
    + unsigned int shortest_row; /* Shortest row */
    + unsigned char dirty; /* State of file */
    + unsigned int frm_start_pos; /* Position for start of FRM */
    + unsigned int frm_length; /* Position for start of FRM */
    + unsigned int comment_start_pos; /* Position for start of comment */
    + unsigned int comment_length; /* Position for start of comment */
    +} azio_stream; +
    + /* basic functions */
    + +extern int azopen(azio_stream *s, const char *path, int Flags); +/*
    + Opens a gzip (.gz) file for reading or writing. The mode parameter
    + is as in fopen ("rb" or "wb") but can also include a compression level
    + ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
    + Huffman only compression as in "wb1h", or 'R' for run-length encoding
    + as in "wb1R". (See the description of deflateInit2 for more information
    + about the strategy parameter.)
    +
    + azopen can be used to read a file which is not in gzip format; in this
    + case gzread will directly read from the file without decompression.
    +
    + azopen returns NULL if the file could not be opened or if there was
    + insufficient memory to allocate the (de)compression state; errno
    + can be checked to distinguish the two cases (if errno is zero, the
    + zlib error is Z_MEM_ERROR). */
    + +int azdopen(azio_stream *s,File fd, int Flags); +/*
    + azdopen() associates a azio_stream with the file descriptor fd. File
    + descriptors are obtained from calls like open, dup, creat, pipe or
    + fileno (in the file has been previously opened with fopen).
    + The mode parameter is as in azopen.
    + The next call of gzclose on the returned azio_stream will also close the
    + file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
    + descriptor fd. If you want to keep fd open, use azdopen(dup(fd), mode).
    + azdopen returns NULL if there was insufficient memory to allocate
    + the (de)compression state.
    +*/ + + +extern unsigned int azread ( azio_stream *s, voidp buf, unsigned int len, int *error); +/*
    + Reads the given number of uncompressed bytes from the compressed file.
    + If the input file was not in gzip format, gzread copies the given number
    + of bytes into the buffer.
    + gzread returns the number of uncompressed bytes actually read (0 for
    + end of file, -1 for error). */
    + +extern unsigned int azwrite (azio_stream *s, voidpc buf, unsigned int len); +/*
    + Writes the given number of uncompressed bytes into the compressed file.
    + azwrite returns the number of uncompressed bytes actually written
    + (0 in case of error).
    +*/ + + +extern int azflush(azio_stream *file, int flush); +/*
    + Flushes all pending output into the compressed file. The parameter
    + flush is as in the deflate() function. The return value is the zlib
    + error number (see function gzerror below). gzflush returns Z_OK if
    + the flush parameter is Z_FINISH and all output could be flushed.
    + gzflush should be called only when strictly necessary because it can
    + degrade compression.
    +*/ + +extern my_off_t azseek (azio_stream *file,
    + my_off_t offset, int whence);
    +/*
    + Sets the starting position for the next gzread or gzwrite on the
    + given compressed file. The offset represents a number of bytes in the
    + uncompressed data stream. The whence parameter is defined as in lseek(2);
    + the value SEEK_END is not supported.
    + If the file is opened for reading, this function is emulated but can be
    + extremely slow. If the file is opened for writing, only forward seeks are
    + supported; gzseek then compresses a sequence of zeroes up to the new
    + starting position.
    +
    + gzseek returns the resulting offset location as measured in bytes from
    + the beginning of the uncompressed stream, or -1 in case of error, in
    + particular if the file is opened for writing and the new starting position
    + would be before the current position.
    +*/ + +extern int azrewind(azio_stream *file); +/*
    + Rewinds the given file. This function is supported only for reading.
    +
    + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
    +*/ + +extern my_off_t aztell(azio_stream *file); +/*
    + Returns the starting position for the next gzread or gzwrite on the
    + given compressed file. This position represents a number of bytes in the
    + uncompressed data stream.
    +
    + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
    +*/ + +extern int azclose(azio_stream *file); +/*
    + Flushes all pending output if necessary, closes the compressed file
    + and deallocates all the (de)compression state. The return value is the zlib
    + error number (see function gzerror below).
    +*/ + +extern int azwrite_frm (azio_stream *s, char *blob, unsigned int length); +extern int azread_frm (azio_stream *s, char *blob); +extern int azwrite_comment (azio_stream *s, char *blob, unsigned int length); +extern int azread_comment (azio_stream *s, char *blob); + +#ifdef __cplusplus +} +#endif Index: ndb-work/storage/ndb/src/common/util/azio.c
  • /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ ndb-work/storage/ndb/src/common/util/azio.c 2007-09-24 17:26:58.392401484 +0200 @@ -0,0 +1,871 @@ +/*
    + azio is a modified version of gzio. It makes use of mysys and removes mallocs.
    + -Brian Aker
    +*/ + +/* gzio.c -- IO on .gz files + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + * + */ + +/* @(#) $Id$ */ + +#include "azlib.h" + +#include <stdio.h> +#include <string.h> + +static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */ +static int const az_magic[3] = {0xfe, 0x03, 0x01}; /* az magic header */ + +/* gzip flag uchar */ +#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ +#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */ +#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ +#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ +#define COMMENT 0x10 /* bit 4 set: file comment present */ +#define RESERVED 0xE0 /* bits 5..7: reserved */ + +int az_open(azio_stream *s, const char *path, int Flags, File fd); +int do_flush(azio_stream *file, int flush); +int get_byte(azio_stream *s); +void check_header(azio_stream *s); +void write_header(azio_stream *s); +int destroy(azio_stream *s); +void putLong(File file, uLong x); +uLong getLong(azio_stream *s); +void read_header(azio_stream *s, unsigned char *buffer); + +/* ===========================================================================
    + Opens a gzip (.gz) file for reading or writing. The mode parameter
    + is as in fopen ("rb" or "wb"). The file is given either by file descriptor
    + or path name (if fd == -1).
    + az_open returns NULL if the file could not be opened or if there was
    + insufficient memory to allocate the (de)compression state; errno
    + can be checked to distinguish the two cases (if errno is zero, the
    + zlib error is Z_MEM_ERROR).
    +*/ +int az_open (azio_stream *s, const char *path, int Flags, File fd) +{
    + int err;
    + int level = Z_DEFAULT_COMPRESSION; /* compression level */
    + int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */
    +
    + s->stream.zalloc = (alloc_func)0;
    + s->stream.zfree = (free_func)0;
    + s->stream.opaque = (voidpf)0;
    + memset(s->inbuf, 0, AZ_BUFSIZE_READ);
    + memset(s->outbuf, 0, AZ_BUFSIZE_WRITE);
    + s->stream.next_in = s->inbuf;
    + s->stream.next_out = s->outbuf;
    + s->stream.avail_in = s->stream.avail_out = 0;
    + s->z_err = Z_OK;
    + s->z_eof = 0;
    + s->in = 0;
    + s->out = 0;
    + s->back = EOF;
    + s->crc = crc32(0L, Z_NULL, 0);
    + s->transparent = 0;
    + s->mode = 'r';
    + s->version = (unsigned char)az_magic[1]; /* this needs to be a define to version */
    + s->version = (unsigned char)az_magic[2]; /* minor version */
    +
    + /*
    + We do our own version of append by nature.
    + We must always have write access to take card of the header.
    + */
    + DBUG_ASSERT(Flags | O_APPEND);
    + DBUG_ASSERT(Flags | O_WRONLY);
    +
    + if (Flags & O_RDWR)
    + s->mode = 'w';
    +
    + if (s->mode == 'w')
    + {
    + err = deflateInit2(&(s->stream), level,
    + Z_DEFLATED, -MAX_WBITS, 8, strategy);
    + /* windowBits is passed < 0 to suppress zlib header */
    +
    + s->stream.next_out = s->outbuf;
    + if (err != Z_OK)
    + {
    + destroy(s);
    + return Z_NULL;
    + }
    + } else {
    + s->stream.next_in = s->inbuf;
    +
    + err = inflateInit2(&(s->stream), -MAX_WBITS);
    + /* windowBits is passed < 0 to tell that there is no zlib header.
    + * Note that in this case inflate *requires* an extra "dummy" byte
    + * after the compressed stream in order to complete decompression and
    + * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are
    + * present after the compressed stream.
    + */
    + if (err != Z_OK)
    + {
    + destroy(s);
    + return Z_NULL;
    + }
    + }
    + s->stream.avail_out = AZ_BUFSIZE_WRITE;
    +
    + errno = 0;
    + s->file = fd < 0 ? my_open(path, Flags, MYF(0)) : fd;
    +
    + if (s->file < 0 )
    + {
    + destroy(s);
    + return Z_NULL;
    + }
    +
    + if (Flags & O_CREAT || Flags & O_TRUNC)
    + {
    + s->rows= 0;
    + s->forced_flushes= 0;
    + s->shortest_row= 0;
    + s->longest_row= 0;
    + s->auto_increment= 0;
    + s->check_point= 0;
    + s->comment_start_pos= 0;
    + s->comment_length= 0;
    + s->frm_start_pos= 0;
    + s->frm_length= 0;
    + s->dirty= 1; /* We create the file dirty */
    + s->start = AZHEADER_SIZE + AZMETA_BUFFER_SIZE;
    + write_header(s);
    + my_seek(s->file, 0, MY_SEEK_END, MYF(0));
    + }
    + else if (s->mode == 'w')
    + {
    + uchar buffer[AZHEADER_SIZE + AZMETA_BUFFER_SIZE];
    + my_pread(s->file, buffer, AZHEADER_SIZE + AZMETA_BUFFER_SIZE, 0,
    + MYF(0));
    + read_header(s, buffer); /* skip the .az header */
    + my_seek(s->file, 0, MY_SEEK_END, MYF(0));
    + }
    + else
    + {
    + check_header(s); /* skip the .az header */
    + }
    +
    + return 1;
    +} + + +void write_header(azio_stream *s) +{
    + char buffer[AZHEADER_SIZE + AZMETA_BUFFER_SIZE];
    + char *ptr= buffer;
    +
    + s->block_size= AZ_BUFSIZE_WRITE;
    + s->version = (unsigned char)az_magic[1];
    + s->minor_version = (unsigned char)az_magic[2];
    + +
    + /* Write a very simple .az header: */
    + memset(buffer, 0, AZHEADER_SIZE + AZMETA_BUFFER_SIZE);
    + *(ptr + AZ_MAGIC_POS)= az_magic[0];
    + *(ptr + AZ_VERSION_POS)= (unsigned char)s->version;
    + *(ptr + AZ_MINOR_VERSION_POS)= (unsigned char)s->minor_version;
    + *(ptr + AZ_BLOCK_POS)= (unsigned char)(s->block_size/1024); /* Reserved for block size */
    + *(ptr + AZ_STRATEGY_POS)= (unsigned char)Z_DEFAULT_STRATEGY; /* Compression Type */
    +
    + int4store(ptr + AZ_FRM_POS, s->frm_start_pos); /* FRM Block */
    + int4store(ptr + AZ_FRM_LENGTH_POS, s->frm_length); /* FRM Block */
    + int4store(ptr + AZ_COMMENT_POS, s->comment_start_pos); /* COMMENT Block */
    + int4store(ptr + AZ_COMMENT_LENGTH_POS, s->comment_length); /* COMMENT Block */
    + int4store(ptr + AZ_META_POS, 0); /* Meta Block */
    + int4store(ptr + AZ_META_LENGTH_POS, 0); /* Meta Block */
    + int8store(ptr + AZ_START_POS, (unsigned long long)s->start); /* Start of Data Block Index Block */
    + int8store(ptr + AZ_ROW_POS, (unsigned long long)s->rows); /* Start of Data Block Index Block */
    + int8store(ptr + AZ_FLUSH_POS, (unsigned long long)s->forced_flushes); /* Start of Data Block Index Block */
    + int8store(ptr + AZ_CHECK_POS, (unsigned long long)s->check_point); /* Start of Data Block Index Block */
    + int8store(ptr + AZ_AUTOINCREMENT_POS, (unsigned long long)s->auto_increment); /* Start of Data Block Index Block */
    + int4store(ptr+ AZ_LONGEST_POS , s->longest_row); /* Longest row */
    + int4store(ptr+ AZ_SHORTEST_POS, s->shortest_row); /* Shorest row */
    + int4store(ptr+ AZ_FRM_POS,
    + AZHEADER_SIZE + AZMETA_BUFFER_SIZE); /* FRM position */
    + *(ptr + AZ_DIRTY_POS)= (unsigned char)s->dirty; /* Start of Data Block Index Block */
    +
    + /* Always begin at the begining, and end there as well */
    + my_pwrite(s->file, (uchar*) buffer, AZHEADER_SIZE + AZMETA_BUFFER_SIZE, 0,
    + MYF(0));
    +} + +/* ===========================================================================
    + Opens a gzip (.gz) file for reading or writing.
    +*/ +int azopen(azio_stream *s, const char *path, int Flags) +{
    + return az_open(s, path, Flags, -1);
    +} + +/* ===========================================================================
    + Associate a gzFile with the file descriptor fd. fd is not dup'ed here
    + to mimic the behavio(u)r of fdopen.
    +*/ +int azdopen(azio_stream *s, File fd, int Flags) +{
    + if (fd < 0) return 0;
    +
    + return az_open (s, NULL, Flags, fd);
    +} + +/* ===========================================================================
    + Read a byte from a azio_stream; update next_in and avail_in. Return EOF
    + for end of file.
    + IN assertion: the stream s has been sucessfully opened for reading.
    +*/ +int get_byte(s)
    + azio_stream *s;
    +{
    + if (s->z_eof) return EOF;
    + if (s->stream.avail_in == 0)
    + {
    + errno = 0;
    + s->stream.avail_in = my_read(s->file, (uchar *)s->inbuf, AZ_BUFSIZE_READ, MYF(0));
    + if (s->stream.avail_in == 0)
    + {
    + s->z_eof = 1;
    + /* if (ferror(s->file)) s->z_err = Z_ERRNO; */
    + return EOF;
    + }
    + s->stream.next_in = s->inbuf;
    + }
    + s->stream.avail_in--;
    + return *(s->stream.next_in)++;
    +} + +/* ===========================================================================
    + Check the gzip header of a azio_stream opened for reading. Set the stream
    + mode to transparent if the gzip magic header is not present; set s->err
    + to Z_DATA_ERROR if the magic header is present but the rest of the header
    + is incorrect.
    + IN assertion: the stream s has already been created sucessfully;
    + s->stream.avail_in is zero for the first time, but may be non-zero
    + for concatenated .gz files.
    +*/ +void check_header(azio_stream *s) +{
    + int method; /* method uchar */
    + int flags; /* flags uchar */
    + uInt len;
    + int c;
    +
    + /* Assure two bytes in the buffer so we can peek ahead -- handle case
    + where first byte of header is at the end of the buffer after the last
    + gzip segment */
    + len = s->stream.avail_in;
    + if (len < 2) {
    + if (len) s->inbuf[0] = s->stream.next_in[0];
    + errno = 0;
    + len = (uInt)my_read(s->file, (uchar *)s->inbuf + len, AZ_BUFSIZE_READ >> len, MYF(0));
    + if (len == 0) s->z_err = Z_ERRNO;
    + s->stream.avail_in += len;
    + s->stream.next_in = s->inbuf;
    + if (s->stream.avail_in < 2) {
    + s->transparent = s->stream.avail_in;
    + return;
    + }
    + }
    +
    + /* Peek ahead to check the gzip magic header */
    + if ( s->stream.next_in[0] == gz_magic[0] && s->stream.next_in[1] == gz_magic[1])
    + {
    + s->stream.avail_in -= 2;
    + s->stream.next_in += 2;
    + s->version= (unsigned char)2;
    +
    + /* Check the rest of the gzip header */
    + method = get_byte(s);
    + flags = get_byte(s);
    + if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
    + s->z_err = Z_DATA_ERROR;
    + return;
    + }
    +
    + /* Discard time, xflags and OS code: */
    + for (len = 0; len < 6; len++) (void)get_byte(s);
    +
    + if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
    + len = (uInt)get_byte(s);
    + len += ((uInt)get_byte(s))<<8;
    + /* len is garbage if EOF but the loop below will quit anyway */
    + while (len-- != 0 && get_byte(s) != EOF) ;
    + }
    + if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
    + while ((c = get_byte(s)) != 0 && c != EOF) ;
    + }
    + if ((flags & COMMENT) != 0) { /* skip the .gz file comment */
    + while ((c = get_byte(s)) != 0 && c != EOF) ;
    + }
    + if ((flags & HEAD_CRC) != 0) { /* skip the header crc */
    + for (len = 0; len < 2; len++) (void)get_byte(s);
    + }
    + s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
    + s->start = my_tell(s->file, MYF(0)) - s->stream.avail_in;
    + }
    + else if ( s->stream.next_in[0] == az_magic[0] && s->stream.next_in[1] == az_magic[1])
    + {
    + unsigned char buffer[AZHEADER_SIZE + AZMETA_BUFFER_SIZE];
    +
    + for (len = 0; len < (AZHEADER_SIZE + AZMETA_BUFFER_SIZE); len++)
    + buffer[len]= get_byte(s);
    + s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
    + read_header(s, buffer);
    + for (; len < s->start; len++)
    + get_byte(s);
    + }
    + else
    + {
    + s->z_err = Z_OK;
    +
    + return;
    + }
    +} + +void read_header(azio_stream *s, unsigned char *buffer) +{
    + if (buffer[0] == az_magic[0] && buffer[1] == az_magic[1])
    + {
    + s->version= (unsigned int)buffer[AZ_VERSION_POS];
    + s->minor_version= (unsigned int)buffer[AZ_MINOR_VERSION_POS];
    + s->block_size= 1024 * buffer[AZ_BLOCK_POS];
    + s->start= (unsigned long long)uint8korr(buffer + AZ_START_POS);
    + s->rows= (unsigned long long)uint8korr(buffer + AZ_ROW_POS);
    + s->check_point= (unsigned long long)uint8korr(buffer + AZ_CHECK_POS);
    + s->forced_flushes= (unsigned long long)uint8korr(buffer + AZ_FLUSH_POS);
    + s->auto_increment= (unsigned long long)uint8korr(buffer + AZ_AUTOINCREMENT_POS);
    + s->longest_row= (unsigned int)uint4korr(buffer + AZ_LONGEST_POS);
    + s->shortest_row= (unsigned int)uint4korr(buffer + AZ_SHORTEST_POS);
    + s->frm_start_pos= (unsigned int)uint4korr(buffer + AZ_FRM_POS);
    + s->frm_length= (unsigned int)uint4korr(buffer + AZ_FRM_LENGTH_POS);
    + s->comment_start_pos= (unsigned int)uint4korr(buffer + AZ_COMMENT_POS);
    + s->comment_length= (unsigned int)uint4korr(buffer + AZ_COMMENT_LENGTH_POS);
    + s->dirty= (unsigned int)buffer[AZ_DIRTY_POS];
    + }
    + else
    + {
    + DBUG_ASSERT(buffer[0] == az_magic[0] && buffer[1] == az_magic[1]);
    + return;
    + }
    +} + +/* =========================================================================== + * Cleanup then free the given azio_stream. Return a zlib error code. + Try freeing in the reverse order of allocations. + */ +int destroy (s)
    + azio_stream *s;
    +{
    + int err = Z_OK;
    +
    + if (s->stream.state != NULL)
    + {
    + if (s->mode == 'w')
    + err = deflateEnd(&(s->stream));
    + else if (s->mode == 'r')
    + err = inflateEnd(&(s->stream));
    + }
    +
    + if (s->file > 0 && my_close(s->file, MYF(0)))
    + err = Z_ERRNO;
    +
    + s->file= -1;
    +
    + if (s->z_err < 0) err = s->z_err;
    +
    + return err;
    +} + +/* ===========================================================================
    + Reads the given number of uncompressed bytes from the compressed file.
    + azread returns the number of bytes actually read (0 for end of file).
    +*/ +unsigned int ZEXPORT azread ( azio_stream *s, voidp buf, unsigned int len, int *error) +{
    + Bytef *start = (Bytef*)buf; /* starting point for crc computation */
    + Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */
    + *error= 0;
    +
    + if (s->mode != 'r')
    + {
    + *error= Z_STREAM_ERROR;
    + return 0;
    + }
    +
    + if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO)
    + {
    + *error= s->z_err;
    + return 0;
    + }
    +
    + if (s->z_err == Z_STREAM_END) /* EOF */
    + {
    + return 0;
    + }
    +
    + next_out = (Byte*)buf;
    + s->stream.next_out = (Bytef*)buf;
    + s->stream.avail_out = len;
    +
    + if (s->stream.avail_out && s->back != EOF) {
    + *next_out++ = s->back;
    + s->stream.next_out++;
    + s->stream.avail_out--;
    + s->back = EOF;
    + s->out++;
    + start++;
    + if (s->last) {
    + s->z_err = Z_STREAM_END;
    + {
    + return 1;
    + }
    + }
    + }
    +
    + while (s->stream.avail_out != 0) {
    +
    + if (s->transparent) {
    + /* Copy first the lookahead bytes: */
    + uInt n = s->stream.avail_in;
    + if (n > s->stream.avail_out) n = s->stream.avail_out;
    + if (n > 0) {
    + memcpy(s->stream.next_out, s->stream.next_in, n);
    + next_out += n;
    + s->stream.next_out = (Bytef *)next_out;
    + s->stream.next_in += n;
    + s->stream.avail_out -= n;
    + s->stream.avail_in -= n;
    + }
    + if (s->stream.avail_out > 0)
    + {
    + s->stream.avail_out -=
    + (uInt)my_read(s->file, (uchar *)next_out, s->stream.avail_out, MYF(0));
    + }
    + len -= s->stream.avail_out;
    + s->in += len;
    + s->out += len;
    + if (len == 0) s->z_eof = 1;
    + {
    + return len;
    + }
    + }
    + if (s->stream.avail_in == 0 && !s->z_eof) {
    +
    + errno = 0;
    + s->stream.avail_in = (uInt)my_read(s->file, (uchar *)s->inbuf, AZ_BUFSIZE_READ, MYF(0));
    + if (s->stream.avail_in == 0)
    + {
    + s->z_eof = 1;
    + }
    + s->stream.next_in = (Bytef *)s->inbuf;
    + }
    + s->in += s->stream.avail_in;
    + s->out += s->stream.avail_out;
    + s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
    + s->in -= s->stream.avail_in;
    + s->out -= s->stream.avail_out;
    +
    + if (s->z_err == Z_STREAM_END) {
    + /* Check CRC and original size */
    + s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
    + start = s->stream.next_out;
    +
    + if (getLong(s) != s->crc) {
    + s->z_err = Z_DATA_ERROR;
    + } else {
    + (void)getLong(s);
    + /* The uncompressed length returned by above getlong() may be
    + * different from s->out in case of concatenated .gz files.
    + * Check for such files:
    + */
    + check_header(s);
    + if (s->z_err == Z_OK)
    + {
    + inflateReset(&(s->stream));
    + s->crc = crc32(0L, Z_NULL, 0);
    + }
    + }
    + }
    + if (s->z_err != Z_OK || s->z_eof) break;
    + }
    + s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
    +
    + if (len == s->stream.avail_out &&
    + (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO))
    + {
    + *error= s->z_err;
    +
    + return 0;
    + }
    +
    + return (len - s->stream.avail_out);
    +} + + +/* ===========================================================================
    + Writes the given number of uncompressed bytes into the compressed file.
    + azwrite returns the number of bytes actually written (0 in case of error).
    +*/ +unsigned int azwrite (azio_stream *s, voidpc buf, unsigned int len) +{
    + s->stream.next_in = (Bytef*)buf;
    + s->stream.avail_in = len;
    +
    + s->rows++;
    +
    + while (s->stream.avail_in != 0)
    + {
    + if (s->stream.avail_out == 0)
    + {
    +
    + s->stream.next_out = s->outbuf;
    + if (my_write(s->file, (uchar *)s->outbuf, AZ_BUFSIZE_WRITE,
    + MYF(0)) != AZ_BUFSIZE_WRITE)
    + {
    + s->z_err = Z_ERRNO;
    + break;
    + }
    + s->stream.avail_out = AZ_BUFSIZE_WRITE;
    + }
    + s->in += s->stream.avail_in;
    + s->out += s->stream.avail_out;
    + s->z_err = deflate(&(s->stream), Z_NO_FLUSH);
    + s->in -= s->stream.avail_in;
    + s->out -= s->stream.avail_out;
    + if (s->z_err != Z_OK) break;
    + }
    + s->crc = crc32(s->crc, (const Bytef *)buf, len);
    +
    + if (len > s->longest_row)
    + s->longest_row= len;
    +
    + if (len < s->shortest_row || !(s->shortest_row))
    + s->shortest_row= len;
    +
    + return (unsigned int)(len - s->stream.avail_in);
    +} + + +/* ===========================================================================
    + Flushes all pending output into the compressed file. The parameter
    + flush is as in the deflate() function.
    +*/ +int do_flush (azio_stream *s, int flush) +{
    + uInt len;
    + int done = 0;
    + my_off_t afterwrite_pos;
    +
    + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
    +
    + s->stream.avail_in = 0; /* should be zero already anyway */
    +
    + for (;;)
    + {
    + len = AZ_BUFSIZE_WRITE - s->stream.avail_out;
    +
    + if (len != 0)
    + {
    + s->check_point= my_tell(s->file, MYF(0));
    + if ((uInt)my_write(s->file, (uchar *)s->outbuf, len, MYF(0)) != len)
    + {
    + s->z_err = Z_ERRNO;
    + return Z_ERRNO;
    + }
    + s->stream.next_out = s->outbuf;
    + s->stream.avail_out = AZ_BUFSIZE_WRITE;
    + }
    + if (done) break;
    + s->out += s->stream.avail_out;
    + s->z_err = deflate(&(s->stream), flush);
    + s->out -= s->stream.avail_out;
    +
    + /* Ignore the second of two consecutive flushes: */
    + if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK;
    +
    + /* deflate has finished flushing only when it hasn't used up
    + * all the available space in the output buffer:
    + */
    + done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
    +
    + if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break;
    + }
    +
    + if (flush == Z_FINISH)
    + s->dirty= AZ_STATE_CLEAN; /* Mark it clean, we should be good now */
    + else
    + s->dirty= AZ_STATE_SAVED; /* Mark it clean, we should be good now */
    +
    + afterwrite_pos= my_tell(s->file, MYF(0));
    + write_header(s);
    + my_seek(s->file, afterwrite_pos, SEEK_SET, MYF(0));
    +
    + return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
    +} + +int ZEXPORT azflush (s, flush)
    + azio_stream *s;
    + int flush;
    +{
    + int err;
    +
    + if (s->mode == 'r')
    + {
    + unsigned char buffer[AZHEADER_SIZE + AZMETA_BUFFER_SIZE];
    + my_pread(s->file, (uchar*) buffer, AZHEADER_SIZE + AZMETA_BUFFER_SIZE, 0,
    + MYF(0));
    + read_header(s, buffer); /* skip the .az header */
    +
    + return Z_OK;
    + }
    + else
    + {
    + s->forced_flushes++;
    + err= do_flush(s, flush);
    +
    + if (err) return err;
    + my_sync(s->file, MYF(0));
    + return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
    + }
    +} + +/* ===========================================================================
    + Rewinds input file.
    +*/ +int azrewind (s)
    + azio_stream *s;
    +{
    + if (s == NULL || s->mode != 'r') return -1;
    +
    + s->z_err = Z_OK;
    + s->z_eof = 0;
    + s->back = EOF;
    + s->stream.avail_in = 0;
    + s->stream.next_in = (Bytef *)s->inbuf;
    + s->crc = crc32(0L, Z_NULL, 0);
    + if (!s->transparent) (void)inflateReset(&s->stream);
    + s->in = 0;
    + s->out = 0;
    + return my_seek(s->file, (int)s->start, MY_SEEK_SET, MYF(0)) == MY_FILEPOS_ERROR;
    +} + +/* ===========================================================================
    + Sets the starting position for the next azread or azwrite on the given
    + compressed file. The offset represents a number of bytes in the
    + azseek returns the resulting offset location as measured in bytes from
    + the beginning of the uncompressed stream, or -1 in case of error.
    + SEEK_END is not implemented, returns error.
    + In this version of the library, azseek can be extremely slow.
    +*/ +my_off_t azseek (s, offset, whence)
    + azio_stream *s;
    + my_off_t offset;
    + int whence;
    +{ +
    + if (s == NULL || whence == SEEK_END ||
    + s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) {
    + return -1L;
    + }
    +
    + if (s->mode == 'w')
    + {
    + if (whence == SEEK_SET)
    + offset -= s->in;
    +
    + /* At this point, offset is the number of zero bytes to write. */
    + /* There was a zmemzero here if inbuf was null -Brian */
    + while (offset > 0)
    + {
    + uInt size = AZ_BUFSIZE_WRITE;
    + if (offset < AZ_BUFSIZE_WRITE) size = (uInt)offset;
    +
    + size = azwrite(s, s->inbuf, size);
    + if (size == 0) return -1L;
    +
    + offset -= size;
    + }
    + return s->in;
    + }
    + /* Rest of function is for reading only */
    +
    + /* compute absolute position */
    + if (whence == SEEK_CUR) {
    + offset += s->out;
    + }
    +
    + if (s->transparent) {
    + /* map to my_seek */
    + s->back = EOF;
    + s->stream.avail_in = 0;
    + s->stream.next_in = (Bytef *)s->inbuf;
    + if (my_seek(s->file, offset, MY_SEEK_SET, MYF(0)) == MY_FILEPOS_ERROR) return -1L;
    +
    + s->in = s->out = offset;
    + return offset;
    + }
    +
    + /* For a negative seek, rewind and use positive seek */
    + if (offset >= s->out) {
    + offset -= s->out;
    + } else if (azrewind(s)) {
    + return -1L;
    + }
    + /* offset is now the number of bytes to skip. */
    +
    + if (offset && s->back != EOF) {
    + s->back = EOF;
    + s->out++;
    + offset--;
    + if (s->last) s->z_err = Z_STREAM_END;
    + }
    + while (offset > 0) {
    + int error;
    + unsigned int size = AZ_BUFSIZE_READ;
    + if (offset < AZ_BUFSIZE_READ) size = (int)offset;
    +
    + size = azread(s, s->outbuf, size, &error);
    + if (error <= 0) return -1L;
    + offset -= size;
    + }
    + return s->out;
    +} + +/* ===========================================================================
    + Returns the starting position for the next azread or azwrite on the
    + given compressed file. This position represents a number of bytes in the
    + uncompressed data stream.
    +*/ +my_off_t ZEXPORT aztell (file)
    + azio_stream *file;
    +{
    + return azseek(file, 0L, SEEK_CUR);
    +} + + +/* ===========================================================================
    + Outputs a long in LSB order to the given file
    +*/ +void putLong (File file, uLong x) +{
    + int n;
    + uchar buffer[1];
    +
    + for (n = 0; n < 4; n++)
    + {
    + buffer[0]= (int)(x & 0xff);
    + my_write(file, buffer, 1, MYF(0));
    + x >>= 8;
    + }
    +} + +/* ===========================================================================
    + Reads a long in LSB order from the given azio_stream. Sets z_err in case
    + of error.
    +*/ +uLong getLong (azio_stream *s) +{
    + uLong x = (uLong)get_byte(s);
    + int c;
    +
    + x += ((uLong)get_byte(s))<<8;
    + x += ((uLong)get_byte(s))<<16;
    + c = get_byte(s);
    + if (c == EOF) s->z_err = Z_DATA_ERROR;
    + x += ((uLong)c)<<24;
    + return x;
    +} + +/* ===========================================================================
    + Flushes all pending output if necessary, closes the compressed file
    + and deallocates all the (de)compression state.
    +*/ +int azclose (azio_stream *s) +{ +
    + if (s == NULL) return Z_STREAM_ERROR;
    +
    + if (s->file < 1) return Z_OK;
    +
    + if (s->mode == 'w')
    + {
    + if (do_flush(s, Z_FINISH) != Z_OK)
    + return destroy(s);
    +
    + putLong(s->file, s->crc);
    + putLong(s->file, (uLong)(s->in & 0xffffffff));
    + s->dirty= AZ_STATE_CLEAN;
    + s->check_point= my_tell(s->file, MYF(0));
    + write_header(s);
    + }
    +
    + return destroy(s);
    +} + +/*
    + Though this was added to support MySQL's FRM file, anything can be
    + stored in this location.
    +*/ +int azwrite_frm(azio_stream *s, char *blob, unsigned int length) +{
    + if (s->mode == 'r')
    + return 1;
    +
    + if (s->rows > 0)
    + return 1;
    +
    + s->frm_start_pos= (uint) s->start;
    + s->frm_length= length;
    + s->start+= length;
    +
    + my_pwrite(s->file, (uchar*) blob, s->frm_length, s->frm_start_pos, MYF(0));
    +
    + write_header(s);
    + my_seek(s->file, 0, MY_SEEK_END, MYF(0));
    +
    + return 0;
    +} + +int azread_frm(azio_stream *s, char *blob) +{
    + my_pread(s->file, (uchar*) blob, s->frm_length, s->frm_start_pos, MYF(0));
    +
    + return 0;
    +} + + +/*
    + Simple comment field
    +*/ +int azwrite_comment(azio_stream *s, char *blob, unsigned int length) +{
    + if (s->mode == 'r')
    + return 1;
    +
    + if (s->rows > 0)
    + return 1;
    +
    + s->comment_start_pos= (uint) s->start;
    + s->comment_length= length;
    + s->start+= length;
    +
    + my_pwrite(s->file, (uchar*) blob, s->comment_length, s->comment_start_pos,
    + MYF(0));
    +
    + write_header(s);
    + my_seek(s->file, 0, MY_SEEK_END, MYF(0));
    +
    + return 0;
    +} + +int azread_comment(azio_stream *s, char *blob) +{
    + my_pread(s->file, (uchar*) blob, s->comment_length, s->comment_start_pos,
    + MYF(0));
    +
    + return 0;
    +}
--
Stewart Smith

-- 
MySQL Code Commits Mailing List
For list archives: 
http://lists.mysql.com/commits
To unsubscribe:    
http://lists.mysql.com/commits?unsub=lists@pantek.com
Received on Thu Oct 11 09:22:16 2007

This archive was generated by hypermail 2.1.8 : Thu Jul 03 2008 - 09:43:23 EDT


Contact Us  Legal Notices  Order Services Online 
Pantek Home  Privacy Policy  IT news  Site Map  Pantek Library