ucx/ucx/buffer.h

Thu, 21 Dec 2017 19:48:27 +0100

author
Mike Becker <universe@uap-core.de>
date
Thu, 21 Dec 2017 19:48:27 +0100
changeset 359
bacb54502b24
parent 335
c1bc13faadaa
child 505
481802342fdf
permissions
-rw-r--r--

davql: allow ANYWHERE keyword in SELECT statements

This may seem pointless, but users might want to be explicit about this and the grammar is more consistent.

This commit also adds some no-ops to the functions body of the SET parser, because some day the grammar might allow more clauses after the WHERE clause.

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *   1. Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *
 *   2. Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @file buffer.h
 * 
 * Advanced buffer implementation.
 * 
 * Instances of UcxBuffer can be used to read from or to write to like one
 * would do with a stream. This allows the use of ucx_stream_copy() to copy
 * contents from one buffer to another.
 * 
 * Some features for convenient use of the buffer
 * can be enabled. See the documentation of the macro constants for more
 * information.
 * 
 * @author Mike Becker
 * @author Olaf Wintermann
 */

#ifndef UCX_BUFFER_H
#define	UCX_BUFFER_H

#include "ucx.h"
#include <sys/types.h>
#include <stdio.h>

#ifdef	__cplusplus
extern "C" {
#endif

/**
 * No buffer features enabled (all flags cleared).
 */
#define UCX_BUFFER_DEFAULT      0x00

/**
 * If this flag is enabled, the buffer will automatically free its contents.
 */
#define UCX_BUFFER_AUTOFREE     0x01

/**
 * If this flag is enabled, the buffer will automatically extends its capacity.
 */
#define UCX_BUFFER_AUTOEXTEND   0x02

/** UCX Buffer. */
typedef struct {
    /** A pointer to the buffer contents. */
    char *space;
    /** Current position of the buffer. */
    size_t pos;
    /** Current capacity (i.e. maximum size) of the buffer. */
    size_t capacity;
    /** Current size of the buffer content. */
    size_t size;
    /**
     * Flag register for buffer features.
     * @see #UCX_BUFFER_DEFAULT
     * @see #UCX_BUFFER_AUTOFREE
     * @see #UCX_BUFFER_AUTOEXTEND
     */
    int flags;
} UcxBuffer;

/**
 * Creates a new buffer.
 * 
 * <b>Note:</b> you may provide <code>NULL</code> as argument for
 * <code>space</code>. Then this function will allocate the space and enforce
 * the #UCX_BUFFER_AUTOFREE flag.
 * 
 * @param space pointer to the memory area, or <code>NULL</code> to allocate
 * new memory
 * @param capacity the capacity of the buffer
 * @param flags buffer features (see UcxBuffer.flags)
 * @return the new buffer
 */
UcxBuffer *ucx_buffer_new(void *space, size_t capacity, int flags);

/**
 * Destroys a buffer.
 * 
 * If the #UCX_BUFFER_AUTOFREE feature is enabled, the contents of the buffer
 * are also freed.
 * 
 * @param buffer the buffer to destroy
 */
void ucx_buffer_free(UcxBuffer* buffer);

/**
 * Creates a new buffer and fills it with extracted content from another buffer.
 * 
 * <b>Note:</b> the #UCX_BUFFER_AUTOFREE feature is enforced for the new buffer.
 * 
 * @param src the source buffer
 * @param start the start position of extraction
 * @param length the count of bytes to extract (must not be zero)
 * @param flags feature mask for the new buffer
 * @return a new buffer containing the extraction
 */
UcxBuffer* ucx_buffer_extract(UcxBuffer *src,
        size_t start, size_t length, int flags);

/**
 * A shorthand macro for the full extraction of the buffer.
 * 
 * @param src the source buffer
 * @param flags feature mask for the new buffer
 * @return a new buffer with the extracted content
 */
#define ucx_buffer_clone(src,flags) \
    ucx_buffer_extract(src, 0, (src)->capacity, flags)

/**
 * Moves the position of the buffer.
 * 
 * The new position is relative to the <code>whence</code> argument.
 *
 * SEEK_SET marks the start of the buffer.
 * SEEK_CUR marks the current position.
 * SEEK_END marks the end of the buffer.
 * 
 * With an offset of zero, this function sets the buffer position to zero
 * (SEEK_SET), the buffer size (SEEK_END) or leaves the buffer position
 * unchanged (SEEK_CUR).
 * 
 * @param buffer
 * @param offset position offset relative to <code>whence</code>
 * @param whence one of SEEK_SET, SEEK_CUR or SEEK_END
 * @return 0 on success, non-zero if the position is invalid
 *
 */
int ucx_buffer_seek(UcxBuffer *buffer, off_t offset, int whence);

/**
 * Clears the buffer by resetting the position and deleting the data.
 * 
 * The data is deleted by a zeroing it with call to <code>memset()</code>.
 * 
 * @param buffer the buffer to be cleared
 */
#define ucx_buffer_clear(buffer) memset(buffer->space, 0, buffer->size); \
        buffer->size = 0; buffer->pos = 0;

/**
 * Tests, if the buffer position has exceeded the buffer capacity.
 * 
 * @param buffer the buffer to test
 * @return non-zero, if the current buffer position has exceeded the last
 * available byte of the buffer.
 */
int ucx_buffer_eof(UcxBuffer *buffer);


/**
 * Extends the capacity of the buffer.
 * 
 * <b>Note:</b> The buffer capacity increased by a power of two. I.e.
 * the buffer capacity is doubled, as long as it would not hold the current
 * content plus the additional required bytes.
 * 
 * <b>Attention:</b> the argument provided is the number of <i>additional</i>
 * bytes the buffer shall hold. It is <b>NOT</b> the total number of bytes the
 * buffer shall hold.
 * 
 * @param buffer the buffer to extend
 * @param additional_bytes the number of additional bytes the buffer shall
 * <i>at least</i> hold
 * @return 0 on success or a non-zero value on failure
 */
int ucx_buffer_extend(UcxBuffer *buffer, size_t additional_bytes);

/**
 * Writes data to a UcxBuffer.
 * 
 * The position of the buffer is increased by the number of bytes written.
 * 
 * @param ptr a pointer to the memory area containing the bytes to be written
 * @param size the length of one element
 * @param nitems the element count
 * @param buffer the UcxBuffer to write to
 * @return the total count of bytes written
 */
size_t ucx_buffer_write(const void *ptr, size_t size, size_t nitems,
        UcxBuffer *buffer);

/**
 * Reads data from a UcxBuffer.
 * 
 * The position of the buffer is increased by the number of bytes read.
 * 
 * @param ptr a pointer to the memory area where to store the read data
 * @param size the length of one element
 * @param nitems the element count
 * @param buffer the UcxBuffer to read from
 * @return the total number of elements read
 */
size_t ucx_buffer_read(void *ptr, size_t size, size_t nitems,
        UcxBuffer *buffer);

/**
 * Writes a character to a buffer.
 * 
 * The least significant byte of the argument is written to the buffer. If the
 * end of the buffer is reached and #UCX_BUFFER_AUTOEXTEND feature is enabled,
 * the buffer capacity is extended by ucx_buffer_extend(). If the feature is
 * disabled or buffer extension fails, <code>EOF</code> is returned.
 * 
 * On successful write the position of the buffer is increased.
 * 
 * @param buffer the buffer to write to
 * @param c the character to write as <code>int</code> value
 * @return the byte that has bean written as <code>int</code> value or
 * <code>EOF</code> when the end of the stream is reached and automatic
 * extension is not enabled or not possible
 */
int ucx_buffer_putc(UcxBuffer *buffer, int c);

/**
 * Gets a character from a buffer.
 * 
 * The current position of the buffer is increased after a successful read.
 * 
 * @param buffer the buffer to read from
 * @return the character as <code>int</code> value or <code>EOF</code>, if the
 * end of the buffer is reached
 */
int ucx_buffer_getc(UcxBuffer *buffer);

/**
 * Writes a string to a buffer.
 * 
 * @param buffer the buffer
 * @param str the string
 * @return the number of bytes written
 */
size_t ucx_buffer_puts(UcxBuffer *buffer, char *str);

#ifdef	__cplusplus
}
#endif

#endif	/* UCX_BUFFER_H */

mercurial