#lang scribble/doc
@(require
  scribble/manual
  (for-label "../apr.ss"))

@title[#:tag "apr" #:style '(toc)]{Apache Portable Runtime Support}

@local-table-of-contents[]

@defmodule[(planet "apr.ss" ("murphy" "svn.plt" 1 0))]{

  This module provides some utilities to work with native data
  structures used by the Apache Portable Runtime. Most of the
  definitions in this module are only of interest to someone hacking
  on the source of this binding.

}

@defform[(unsafe-apr!)]{

  Some bindings in this module are deemed unsafe and have to be
  imported using the this declaration before they can be used.

}

@section[#:tag "apr-errors"]{Error Handling}

@defstruct[(exn:fail:apr exn:fail)
           ([status exact-integer?])
           #:transparent]{

  Exception type raised by failing APR procedures. The @scheme[status]
  fields contains the error code returned from APR.

}

@defproc[(check-error [source any/c] [status exact-integer?])
         any]{

  Checks whether the given APR @scheme[status] code represents
  success. If it doesn't, the procedure decodes the status into an
  error message, prepends the @scheme[source] information to it and
  raises a new exception of type @scheme[exn:fail:apr].
  
  This procedure is unsafe, since passing arbitrary error codes may
  result in unspecified behaviour.

}

@section{Memory Pools}

@defthing[_pooled-pointer ctype?]{

  C pointer type that records the pool in which it is allocated as
  a tag.

}

@defproc[(pooled-pointer? [obj any/c])
        any]{

  Checks whether the given @scheme[obj] is a pooled C pointer.

}
            
@defproc[(pointer-pool [obj any/c])
         (or/c pool? #f)]{

  Retrieves the pool in which @scheme[obj] was allocated. Returns
  a memory pool object or @scheme[#f] if @scheme[obj] is not a pooled
  C pointer.

}

@deftogether[(
@defthing[_pool ctype?]
@defthing[_pool/null ctype?]
)]{

  C pointer type of a memory pool.

}

@defproc[(pool? [obj any/c])
         any]{

  Checks whether the given @scheme[obj] is a memory pool.

}

@defparam[current-pool pool (or/c pool? #f)]{

  Holds the memory pool to use for any native calls in the current
  dynamic scope that require one.

}

@defproc[(make-pool [parent (or/c pool? #f) (current-pool)])
         pool?]{

  Creates a new memory pool that is a child of @scheme[parent]. When
  the parent pool is destroyed so are all its children.
  
  The pool is automatically destroyed by a finalizer when no more
  references from Scheme code to the pool itself, to its subpools
  or to any objects allocated in the pool or its subpools exist.

}

@defform[(wrapper-with-pool lambda-list (proc-expr arg-exprs ...))]{

  Evaluates to an anonymous procedure that takes arguments as
  specified by @scheme[lambda-list] and executes
  @scheme[(proc-expr arg-exprs ...)] with a parameterization that
  includes a newly created child pool of the @scheme[(current-pool)].
  
  The @scheme[proc-expr] is evaluated only once, not for each
  invocation of the resulting procedure.
  
  This macro is mainly intended for the quick implementation of
  wrappers around C library calls.

}

@defproc[(bytes-copy/pool [bytes bytes?])
         pooled-pointer?]{

  Allocates a copy of @scheme[bytes] in the @scheme[(current-pool)]
  and returns an untyped pooled pointer to the data.

}

@section{Arrays}

@deftogether[(
@defthing[_array-header ctype?]
@defthing[_array-header-pointer ctype?]
@defthing[_array-header-pointer/null ctype?]
)]{

  C structure type holding an APR array header.

}

@defproc[(array-header? [obj any/c])
         any]{

  Checks whether the given @scheme[obj] is a pointer to an APR array
  header.

}

@defproc[(make-array-header [pool pool?]
                            [element-size exact-integer?]
                            [element-count exact-integer?]
                            [allocation-count exact-integer?]
                            [elements cpointer?])
         array-header?]{

  Creates an APR array header from the given fields.
  
  This procedure is unsafe.

}

@deftogether[(
@defproc[(array-header-pool [header array-header?])
         pool?]
@defproc[(array-header-element-size [header array-header?])
         exact-integer?]
@defproc[(array-header-element-count [header array-header?])
         exact-integer?]
@defproc[(array-header-allocation-count [header array-header?])
         exact-integer?]
@defproc[(array-header-elements [header array-header?])
         exact-integer?]
)]{

  Accessors for the fields of an APR array header.
  
  The @scheme[array-header-pool] procedure is unsafe.

}

@defproc[(array-header->cvector [header array-header?] [type ctype?])
         list?]{

  Converts the native data pointed to by the given @scheme[header]
  into an FFI vector object with the given element @scheme[type].
  
  If the element size in the array header doesn't match the size of
  the given foreign type, a type error is raised.
  
  This procedure is unsafe.

}

@section{Hashtables}

@deftogether[(
@defthing[_apr-hash ctype?]
@defthing[_apr-hash/null ctype?]
)]{

  C pointer type representing an APR hash table.

}

@defproc[(apr-hash? [obj any/c])
         any]{

  Checks whether the given @scheme[obj] is an APR hash table.

}

@defproc[(apr-hash->keys [hash apr-hash?])
         list?]{

  Extracts a list of all keys from the APR hash table @scheme[hash].
  The keys are returned as binary strings.

}

@section{Time}

@defproc[(apr-time->time-utc [time exact-integer?])
         time?]{

  Converts an APR microsecond count into a SRFI-19 time structure.

}

@defproc[(time-utc->apr-time [time time?])
         exact-integer?]{

  Converts a SRFI-19 time structure into an APR microsecond count.

}
