Example #1
0
// caller should free
static int desr_read_header(const cdsl_deserializer_t* self, cdsl_serializeHeader_t* header) {
	if(self == NULL) {
		return ERR_INV_PARAM;
	}

	file_deserializer_t* desr = container_of(self, file_deserializer_t, handle);
	uint16_t sof = 0;
	if(desr->fd <= 0) {
		return ERR_INV_PARAM;
	}
	do {
		if(F_READ(desr->fd, &sof, sizeof(uint16_t)) <= 0) {
			// fail to find start of file
			desr->is_eos_reached = TRUE;
			return ERR_RD_OP_FAIL;
		}
	} while(sof != SERIALIZER_START_OF_FILE);

	struct deserializer_header desr_header;
	if(F_READ(desr->fd, &desr_header, sizeof(struct deserializer_header)) <= 0) {
		// fail to read header
		desr->is_eos_reached = TRUE;
		return ERR_RD_OP_FAIL;
	}
	desr->has_next = (desr_header.has_next == HAS_NEXT);
	MEMCPY(header, &desr_header, sizeof(cdsl_serializeHeader_t));
	return OK;
}
Example #2
0
static void* desr_get_next(const cdsl_deserializer_t* self,
                          cdsl_serializeNode_t* nodep,
                          size_t nsz,
                          const cdsl_memoryMngt_t* m_mngt) {

	if(self == NULL || m_mngt == NULL) {
		return NULL;
	}
	file_deserializer_t* desr = container_of(self, file_deserializer_t, handle);
	if(desr->fd < 0) {
		desr->is_eos_reached = TRUE;
		return NULL;
	}
	if(F_READ(desr->fd, nodep, nsz) < 0) {
		desr->is_eos_reached = TRUE;
		return NULL;
	}
	size_t node_hole_size = 0; //   if serialized data doesn't contain space which tree node struct is inserted into, \
                                    then allocate more size for that purpose

	if(!(nodep->flags & EMBEDDED_MSK)) {
		node_hole_size = nsz;
	}
	void* data = NULL;
	if(nodep->d_size > 0) {
		uint8_t ext_sz = nodep->d_offset + offsetof(cdsl_serializeNode_t, flags) - nsz;
		if(ext_sz > 0) {
			uint8_t _readout_buffer[ext_sz];
			if(F_READ(desr->fd, _readout_buffer, ext_sz) < 0) {
				desr->is_eos_reached = TRUE;
				return NULL;
			}
		}
		data = m_mngt->alloc(nodep->d_size + node_hole_size);
		if (F_READ(desr->fd, &data[node_hole_size], nodep->d_size) < 0) {
			desr->is_eos_reached = TRUE;
			goto FREE_AND_RETURN_NULL;
		}
	}
	struct deserializer_delim node_delim;
	if(F_READ(desr->fd, &node_delim, sizeof(struct deserializer_delim)) < 0) {
		desr->is_eos_reached = TRUE;
		goto FREE_AND_RETURN_NULL;
	}
	if(node_delim.ser_delim.delim != SERIALIZER_DELIM) {
		goto FREE_AND_RETURN_NULL;
	}
	if(node_delim.ser_delim.node_chs != serializer_calcNodeChecksum(nodep, data)) {
		goto FREE_AND_RETURN_NULL;
	}

	desr->has_next = (node_delim.has_next == HAS_NEXT);
	return data;

FREE_AND_RETURN_NULL:
	if(data) m_mngt->free(data);
	return NULL;
}
Example #3
0
static int desr_read_tail(const cdsl_deserializer_t* self, cdsl_serializeTail_t* tailp) {
	if(!self || !tailp) {
		return ERR_INV_PARAM;
	}
	file_deserializer_t* desr = container_of(self, file_deserializer_t, handle);
	if(desr->fd <= 0) {
		return ERR_INV_PARAM;
	}
	if(F_READ(desr->fd, tailp, sizeof(cdsl_serializeTail_t))) {
		return ERR_RD_OP_FAIL;
	}
	return OK;
}
Example #4
0
/* ===========================================================================
     Read a byte from a gz_stream; update next_in and avail_in. Return EOF
   for end of file.
   IN assertion: the stream s has been sucessfully opened for reading.
*/
static int get_byte(
    gz_stream *s)
{
    if (s->z_eof) return EOF;
    if (s->stream.avail_in == 0) {
	s->stream.avail_in = F_READ(s->inbuf, 1, Z_BUFSIZE, s->file);
	if (s->stream.avail_in == 0) {
	    s->z_eof = 1;
	    if (F_ERROR(s->file)) s->z_err = Z_ERRNO;
	    return EOF;
	}
	s->stream.next_in = s->inbuf;
    }
    s->stream.avail_in--;
    return *(s->stream.next_in)++;
}
Example #5
0
/* ===========================================================================
     Reads the given number of uncompressed bytes from the compressed file.
   lib_gzread returns the number of bytes actually read (0 for end of file).
*/
int lib_gzread (gzFile file, voidp buf, size_t len)
{
    gz_stream *s = (gz_stream*)file;
    Bytef *start = (Bytef*)buf; /* starting point for crc computation */
    Byte  *next_out; /* == stream.next_out but not forced far (for MSDOS) */

    if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR;

    if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1;
    if (s->z_err == Z_STREAM_END) return 0;  /* EOF */

    next_out = (Byte*)buf;
    s->stream.next_out = (Bytef*)buf;
    s->stream.avail_out = (uInt)len;

    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) {
		sysMemCpy(s->stream.next_out, s->stream.next_in, n);
		next_out += n;
		s->stream.next_out = 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 -= F_READ(next_out, 1, s->stream.avail_out,
					     s->file);
	    }
	    len -= s->stream.avail_out;
	    s->stream.total_in  += (uLong)len;
	    s->stream.total_out += (uLong)len;
            if (len == 0) s->z_eof = 1;
	    return (int)len;
	}
        if (s->stream.avail_in == 0 && !s->z_eof) {

            s->stream.avail_in = F_READ(s->inbuf, 1, Z_BUFSIZE, s->file);
            if (s->stream.avail_in == 0) {
                s->z_eof = 1;
		if (F_ERROR(s->file)) {
		    s->z_err = Z_ERRNO;
		    break;
		}
            }
            s->stream.next_in = s->inbuf;
        }
        s->z_err = inflate(&(s->stream), Z_NO_FLUSH);

	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->stream.total_out) in case of
		 * concatenated .gz files. Check for such files:
		 */
		check_header(s);
		if (s->z_err == Z_OK) {
		    uLong total_in = s->stream.total_in;
		    uLong total_out = s->stream.total_out;

		    inflateReset(&(s->stream));
		    s->stream.total_in = total_in;
		    s->stream.total_out = total_out;
		    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));

    return (int)(len - s->stream.avail_out);
}
Example #6
0
xb_rstream_result_t
xb_stream_read_chunk(xb_rstream_t *stream, xb_rstream_chunk_t *chunk)
{
	uchar		tmpbuf[16];
	uchar		*ptr = tmpbuf;
	uint		pathlen;
	size_t		tlen;
	size_t		tbytes;
	ulonglong	ullval;
	ulong		checksum_exp;
	ulong		checksum;;
	File		fd = stream->fd;

	xb_ad(sizeof(tmpbuf) >= CHUNK_HEADER_CONSTANT_LEN);

	/* This is the only place where we expect EOF, so read with my_read()
	rather than F_READ() */
	tlen = CHUNK_HEADER_CONSTANT_LEN;
	while (tlen > 0) {
		tbytes = my_read(fd, ptr, tlen, MYF(MY_WME));
		if (tbytes == 0) {
			break;
		}
		ptr += tbytes;
		tlen -= tbytes;
	}
	if (tlen == CHUNK_HEADER_CONSTANT_LEN) {
		return XB_STREAM_READ_EOF;
	} else if (tlen > 0) {
		msg("xb_stream_read_chunk(): unexpected end of stream at "
		    "offset 0x%llx.\n", stream->offset);
		goto err;
	}

	ptr = tmpbuf;

	/* Chunk magic value */
	if (memcmp(tmpbuf, XB_STREAM_CHUNK_MAGIC, 8)) {
		msg("xb_stream_read_chunk(): wrong chunk magic at offset "
		    "0x%llx.\n", (ulonglong) stream->offset);
		goto err;
	}
	ptr += 8;
	stream->offset += 8;

	/* Chunk flags */
	chunk->flags = *ptr++;
	stream->offset++;

	/* Chunk type, ignore unknown ones if ignorable flag is set */
	chunk->type = validate_chunk_type(*ptr);
	if (chunk->type == XB_CHUNK_TYPE_UNKNOWN &&
	    !(chunk->flags & XB_STREAM_FLAG_IGNORABLE)) {
		msg("xb_stream_read_chunk(): unknown chunk type 0x%lu at "
		    "offset 0x%llx.\n", (ulong) *ptr,
		    (ulonglong) stream->offset);
		goto err;
	}
	ptr++;
	stream->offset++;

	/* Path length */
	pathlen = uint4korr(ptr);
	if (pathlen >= FN_REFLEN) {
		msg("xb_stream_read_chunk(): path length (%lu) is too large at "
		    "offset 0x%llx.\n", (ulong) pathlen, stream->offset);
		goto err;
	}
	chunk->pathlen = pathlen;
	stream->offset +=4;

	xb_ad((ptr + 4 - tmpbuf) == CHUNK_HEADER_CONSTANT_LEN);

	/* Path */
	if (chunk->pathlen > 0) {
		F_READ((uchar *) chunk->path, pathlen);
		stream->offset += pathlen;
	}
	chunk->path[pathlen] = '\0';

	if (chunk->type == XB_CHUNK_TYPE_EOF) {
		return XB_STREAM_READ_CHUNK;
	}

	/* Payload length */
	F_READ(tmpbuf, 16);
	ullval = uint8korr(tmpbuf);
	if (ullval > (ulonglong) SIZE_T_MAX) {
		msg("xb_stream_read_chunk(): chunk length is too large at "
		    "offset 0x%llx: 0x%llx.\n", (ulonglong) stream->offset,
		    ullval);
		goto err;
	}
	chunk->length = (size_t) ullval;
	stream->offset += 8;

	/* Payload offset */
	ullval = uint8korr(tmpbuf + 8);
	if (ullval > (ulonglong) MY_OFF_T_MAX) {
		msg("xb_stream_read_chunk(): chunk offset is too large at "
		    "offset 0x%llx: 0x%llx.\n", (ulonglong) stream->offset,
		    ullval);
		goto err;
	}
	chunk->offset = (my_off_t) ullval;
	stream->offset += 8;

	/* Reallocate the buffer if needed */
	if (chunk->length > stream->buflen) {
		stream->buffer = my_realloc(stream->buffer, chunk->length,
					    MYF(MY_WME));
		if (stream->buffer == NULL) {
			msg("xb_stream_read_chunk(): failed to increase buffer "
			    "to %lu bytes.\n", (ulong) chunk->length);
			goto err;
		}
		stream->buflen = chunk->length;
	}

	/* Checksum */
	F_READ(tmpbuf, 4);
	checksum_exp = uint4korr(tmpbuf);

	/* Payload */
	if (chunk->length > 0) {
		F_READ(stream->buffer, chunk->length);
		stream->offset += chunk->length;
	}

	checksum = crc32(0, stream->buffer, chunk->length);
	if (checksum != checksum_exp) {
		msg("xb_stream_read_chunk(): invalid checksum at offset "
		    "0x%llx: expected 0x%lx, read 0x%lx.\n",
		    (ulonglong) stream->offset, checksum_exp, checksum);
		goto err;
	}
	stream->offset += 4;

	chunk->data = stream->buffer;
	chunk->checksum = checksum;

	return XB_STREAM_READ_CHUNK;

err:
	return XB_STREAM_READ_ERROR;
}