/* ====================================================================
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2000-2003 The Apache Software Foundation.  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.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Apache" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
 * ITS 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

#ifndef APV_LIB_H
#define APV_LIB_H
/**
 * @file apv_lib.h
 * @brief APR-APVFS general purpose library routines
 */

#include "apr.h"
#include "apr_pools.h"
#include "apr_errno.h"
#include "apr_file_io.h"
#include "apr_file_info.h"
#include "apu.h" 

#include "apv.h"

/**
 * @defgroup APV_General General Purpose Library Routines
 * @ingroup APV
 * @{
 */

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

void dbprintf(char *format, ...);

/**
 * Structure for referencing files.
 * @defvar apv_file_t
 */
typedef struct apv_file_t         apv_file_t;

/**
 * Structure for referencing directories.
 * @defvar apv_dir_t
 */
typedef struct apv_dir_t          apv_dir_t;  

/**
 * Structure for referencing filesystem modules.
 * @defvar apv_vfs_t
 */
typedef struct apv_vfs_t          apv_vfs_t;

struct apv_vfs_t {
    /** Open the specified file. */
    apr_status_t (*file_open)       (apv_file_t **, const char *,
                                     apr_int32_t, apr_fileperms_t,
                                     apr_pool_t *);
    /** Close the specified file. */
    apr_status_t (*file_close)      (apv_file_t *);
    /** Delete the specified file.
     * If the file is open, it won't be removed until all instances are closed.
     */ 
    apr_status_t (*file_remove)     (const char *, apr_pool_t *);
    /** Rename the specified file.
     * If a file exists at the new location, then it will be overwritten.  
     * Moving files or directories across devices may not be possible.
     */     
    apr_status_t (*file_rename)     (const char *, const char *,
                                     apr_pool_t *);
    /** Copy the specified file to another file. */
    apr_status_t (*file_copy)       (const char *, const char *,
                                     apr_fileperms_t, apr_pool_t *);
    /** Append the specified file to another file. */
    apr_status_t (*file_append)     (const char *, const char *,
                                     apr_fileperms_t, apr_pool_t *);
    
    /** Test for the end of the file or stream */ 
    apr_status_t (*file_eof)        (apr_file_t *);
    /** Read data from the specified file.  */
    apr_status_t (*file_read)       (apv_file_t *, void *, apr_size_t *);
    /** Write data to the specified file. */
    apr_status_t (*file_write)      (apv_file_t *, const void *, apr_size_t *);
    /** Write data from iovec array to the specified file. */ 
    apr_status_t (*file_writev)     (apv_file_t *, const struct iovec *,
                                     apr_size_t, apr_size_t *);
    /** Read data from the specified file, ensuring that the buffer is filled
     * before returning.
     */
    apr_status_t (*file_read_full)  (apv_file_t *, void *,
                                     apr_size_t, apr_size_t *);
    /** Write data to the specified file, ensuring that all of the data is
     * written before returning.
     */
    apr_status_t (*file_write_full) (apv_file_t *, const void *,
                                     apr_size_t, apr_size_t *);
    /** Put a character into the specified file. */
    apr_status_t (*file_putc)       (char, apv_file_t *);
    /** Get a character from the specified file. */
    apr_status_t (*file_getc)       (char *, apv_file_t *);
    /** Put a character back onto a specified stream. */
    apr_status_t (*file_ungetc)     (char, apv_file_t *);
    /** Get a string from a specified file. */
    apr_status_t (*file_gets)       (char *, int, apv_file_t *);
    /** Put the string into a specified file. */
    apr_status_t (*file_puts)       (const char *, apv_file_t *);
    /** Flush the file's buffer.*/
    apr_status_t (*file_flush)      (apv_file_t *);
    /** Duplicate the specified file descriptor.
     * new file must point to a valid apv_file_t, or point to NULL
     */         
    apr_status_t (*file_dup)        (apv_file_t **, apv_file_t *,
                                     apr_pool_t *);
    /** Duplicate the specified file descriptor and close the original */
    apr_status_t (*file_dup2)       (apv_file_t *, apv_file_t *,
                                     apr_pool_t *);
    /** Move the specified file descriptor to a new pool */
    apr_status_t (*file_setaside)   (apv_file_t **, apv_file_t *,
                                     apr_pool_t *);
    /** Move the read/write file offset to a specified byte within a file. */
    apr_status_t (*file_seek)       (apv_file_t *, apr_seek_where_t,
                                     apr_off_t *);
    /** Establish a lock on the specified, open file. The lock may be advisory
     * or mandatory, at the discretion of the platform. The lock applies to
     * the file as a whole, rather than a specific range. Locks are established
     * on a per-thread/process basis; a second lock by the same thread will not
     * block.
     */
    apr_status_t (*file_lock)       (apv_file_t *, int);
    /** Remove any outstanding locks on the file. */
    apr_status_t (*file_unlock)     (apv_file_t *);
    /** Return the file name of the current file. */
    apr_status_t (*file_name_get)   (const char **, apv_file_t *);
    /** Return the data associated with the current file.
     * If the key is NULL, then the internal data is returned.
     */
    apr_status_t (*file_data_get)   (void **data, const char *, 
                                     apv_file_t *);
    /** Set the data associated with the current file. */
    apr_status_t (*file_data_set)   (apv_file_t *, void *data,
                                     const char *,
                                     apr_status_t (*cleanup)(void *));
    /** Write a string to a file using a printf format. */
    int          (*file_printf)      (apv_file_t *fptr, 
                                      const char *format, ...)
                                     __attribute__((format(printf,2,3)));
    /** Set the specified file's permission bits.
     * Platforms which do not implement this feature will return
     * APR_ENOTIMPL.
     */
    apr_status_t (*file_perms_set)  (const char *, apr_fileperms_t);
    /** Set attributes of the specified file.
     * Platforms which do not implement this feature will return
     * APR_ENOTIMPL.
     */
    apr_status_t (*file_attrs_set)  (const char *, apr_fileattrs_t,
                                     apr_fileattrs_t, apr_pool_t *);
    /** Create a new directory on the file system. */
    apr_status_t (*dir_make)        (const char *, apr_fileperms_t, 
                                     apr_pool_t *);
    /** Creates a new directory on the file system, but behaves like
     * 'mkdir -p'. Creates intermediate directories as required. No error
     * will be reported if PATH already exists.
     */
    apr_status_t (*dir_make_recursive)(const char *, apr_fileperms_t,
                                       apr_pool_t *p);
    /** Remove directory from the file system. */
    apr_status_t (*dir_remove)      (const char *, apr_pool_t *);
    /** Get the specified file's stats. */
    apr_status_t (*file_info_get)   (apr_finfo_t *, apr_int32_t,
                                     apv_file_t *);
    /** Truncate the file's length to the specified offset */
    apr_status_t (*file_trunc)      (apv_file_t *, apr_off_t);

    /** Retrieve the flags that were passed into apv_file_open()
     * when the file was opened.
     */
    apr_int32_t  (*file_flags_get)  (apv_file_t *);
    /** Get the pool used by the file. */
    apr_pool_t*  (*file_pool_get)   (const apv_file_t *);
    /** Set a file to be inherited by child processes. */
    void         (*file_inherit_set)(apv_file_t *);
    /** Unset a file from being inherited by child processes. */
    void         (*file_inherit_unset)(apv_file_t *);
    /** Open a temporary file */
    apr_status_t (*file_mktemp)     (apv_file_t **, char *,
                                     apr_int32_t, apr_pool_t *);
    /** Get the specified file's stats.  The file is specified by 
     *  filename, instead of using a pre-opened file.
     */
    apr_status_t (*stat)            (apr_finfo_t *, const char *,
                                     apr_int32_t, apr_pool_t *);
    /** Get the specified file's stats.  The file is specified by filename, 
     * instead of using a pre-opened file.  If the file is a symlink,
     * this function will get the stats for the symlink not the file the
     * symlink refers to.
     */
    apr_status_t (*lstat)           (apr_finfo_t *, const char *,
                                     apr_int32_t, apr_pool_t *);
    /** Open the specified directory. */
    apr_status_t (*apv_dir_open)    (apv_dir_t **, const char *, 
                                     apr_pool_t *);
    /** Close the specified directory. */
    apr_status_t (*dir_close)       (apv_dir_t *);
    /** Read the next entry from the specified directory.
     * All systems return . and .. as the first two files.
     */                        
    apr_status_t (*dir_read)        (apr_finfo_t *, apr_int32_t,
                                     apv_dir_t *thedir);
    /** Rewind the directory to the first entry. */
    apr_status_t (*dir_rewind)      (apv_dir_t *);
 };

#ifdef __cplusplus
}
#endif
/** @} */
#endif	/* ! APV_LIB_H */