\documentclass{article}
\usepackage{axiom}

\author{Gabriel Dos~Reis}

\begin{document}

\begin{abstract}
\end{abstract}

\tableofcontents
\eject

\section{The Byte domain}

<<domain BYTE Byte>>=
import NonNegativeInteger
import OutputForm
)abbrev domain BYTE Byte
++ Author: Gabriel Dos Reis
++ Date Created: April 19, 2008
++ Date Last Updated: October 5, 2008
++ Basic Operations: byte, bitand, bitor, bitxor
++ Related Constructor: NonNegativeInteger
++ Description:
++   Byte is the datatype of 8-bit sized unsigned integer values.
Byte(): Public == Private where
  Public == Join(OrderedSet, CoercibleTo NonNegativeInteger,
              HomotopicTo Character) with
    byte: NonNegativeInteger -> %
      ++ byte(x) injects the unsigned integer value `v' into
      ++ the Byte algebra.  `v' must be non-negative and less than 256.
    coerce: NonNegativeInteger -> %
      ++ coerce(x) has the same effect as byte(x).
    bitand: (%,%) -> %
      ++ bitand(x,y) returns the bitwise `and' of `x' and `y'.
    bitior: (%,%) -> %
      ++ bitor(x,y) returns the bitwise `inclusive or' of `x' and `y'.
    sample: () -> %
      ++ sample() returns a sample datum of type Byte.
  Private == add
    byte(x: NonNegativeInteger): % ==
      not (x < 256$Lisp) => 
        userError "integer value cannot be represented by a byte"
      x : %
    sample() = 0$Lisp
    hash x == SXHASH(x)$Lisp

    coerce(x: NonNegativeInteger): % == byte x
    coerce(x: %): NonNegativeInteger == x : NonNegativeInteger

    coerce(c: Character) == ord(c)::%
    coerce(x: %): Character == char(x::NonNegativeInteger)

    coerce(x: %): OutputForm ==
      x::NonNegativeInteger::OutputForm
    
    x = y == byteEqual(x,y)$Lisp
    x < y ==  byteLessThan(x,y)$Lisp

    bitand(x,y) == bitand(x,y)$Lisp
    bitior(x,y) == bitior(x,y)$Lisp
@


\section{The ByteBuffer domain}

<<domain BYTEBUF ByteBuffer>>=
import Byte
)abbrev domain BYTEBUF ByteBuffer
++ Author: Gabriel Dos Reis
++ Date Created: April 19, 2008
++ Related Constructor:
++ Description:
++   ByteBuffer provides datatype for buffers of bytes.  This domain
++   differs from PrimitiveArray Byte in that it is not as rigid
++   as  PrimitiveArray Byte.  That is, the typical use of
++   ByteBuffer is to pre-allocate a vector of Byte of some capacity
++   `n'.  The array can then store up to `n' bytes.   The actual
++   interesting bytes count (the length of the buffer) is therefore 
++   different from the capacity.  The length is no more than the 
++   capacity, but it can be set dynamically as needed.  This 
++   functionality is used for example when reading bytes from
++   input/output devices where we use buffers to transfer data in and 
++   out of the system.
++   Note: a value of type ByteBuffer is 0-based indexed, as opposed
++         Vector, but not unlike PrimitiveArray Byte.
ByteBuffer(): Public == Private where
  Public == Join(OneDimensionalArrayAggregate Byte, CoercibleTo String) with
    byteBuffer: NonNegativeInteger -> %
      ++ byteBuffer(n) creates a buffer of capacity n, and length 0.
    _#: % -> NonNegativeInteger
      ++ #buf returns the number of active elements in the buffer.
    capacity: % -> NonNegativeInteger
      ++ capacity(buf) returns the pre-allocated maximum size of `buf'.
    setLength!: (%,NonNegativeInteger) -> NonNegativeInteger
      ++ setLength!(buf,n) sets the number of active bytes in the
      ++ `buf'.  Error if `n' is more than the capacity.
  Private == add
    byteBuffer n == 
      buf := makeByteBuffer(n)$Lisp
      setLength!(buf,0)
      buf

    empty() == byteBuffer 0

    new(n,b) == makeByteBuffer(n,b)$Lisp

    qelt(buf,i) ==
      AREF(buf,i)$Lisp

    elt(buf: %,i: Integer) == 
      i >= capacity buf => error "index out of range"
      qelt(buf,i)

    qsetelt!(buf,i,b) ==
      SETF(AREF(buf,i)$Lisp,b)$Lisp

    setelt(buf: %,i: Integer, b: Byte) == 
      i >= capacity buf => error "index out of range"
      qsetelt!(buf,i,b)

    capacity buf == ARRAY_-DIMENSION(buf,0)$Lisp

    minIndex buf == 0

    maxIndex buf == capacity(buf)::Integer - 1

    # buf == LENGTH(buf)$Lisp

    x = y == 
      EQUAL(x,y)$Lisp

    setLength!(buf,n) == 
      n > capacity buf => 
        error "attempt to set length higher than capacity"
      SETF(FILL_-POINTER(buf)$Lisp,n)$Lisp

    coerce(buf: %): String == 
      s: String := MAKE_-STRING(#buf)$Lisp
      for i in 0..(#buf - 1) repeat
        qsetelt!(s,i + 1,qelt(buf,i)::Character)$String
      s

    construct l ==
      buf := byteBuffer(#l)
      for b in l for i in 0.. repeat
        buf.i := b
      buf

    concat(x: %, y:%) ==
      nx := #x
      ny := #y
      buf := byteBuffer(nx + ny)
      for i in 0..(nx - 1) repeat
        buf.i := x.i
      for i in 0..(ny - 1) repeat
        buf.(nx + i) := y.i
      buf

@


\section{The DataArray domain}

<<domain DATAARY DataArray>>=
)abbrev domain DATAARY DataArray
++ Author: Gabriel Dos Reis
++ Date Created: August 23, 2008
++ Description:
++   This domain provides for a fixed-sized homogeneous data buffer.
DataArray(N: PositiveInteger, T: SetCategory): Public == Private where
  Public == SetCategory with
    new: () -> %
      ++ new() returns a fresly allocated data buffer or length N.
    qelt: (%,NonNegativeInteger) -> T
      ++ elt(b,i) returns the ith element in buffer `b'.  Indexing
      ++ is 0-based.
    qsetelt: (%,NonNegativeInteger,T) -> T
      ++ setelt(b,i,x) sets the ith entry of data buffer `b' to `x'.
      ++ Indexing is 0-based.
  Private == add
    new() == 
      makeSimpleArray(getVMType(T)$Lisp,N)$Lisp

    qelt(b,i) == 
      getSimpleArrayEntry(b,i)$Lisp

    qsetelt(b,i,x) ==
      setSimpleArrayEntry(b,i,x)$Lisp

    x = y ==
      EQUAL(x,y)$Lisp

    coerce(b: %): OutputForm ==
      bracket([qelt(b,i)::OutputForm for i in 0..(N-1)])
@


\section{License}
<<license>>=
--Copyright (C) 2007-2008, Gabriel Dos Reis.
--All rights reserved.
--
--Redistribution and use in source and binary forms, with or without
--modification, are permitted provided that the following conditions are
--met:
--
--    - Redistributions of source code must retain the above copyright
--      notice, this list of conditions and the following disclaimer.
--
--    - 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.
--
--    - Neither the name of The Numerical Algorithms Group Ltd. nor the
--      names of its contributors may be used to endorse or promote products
--      derived from this software without specific prior written permission.
--
--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 OWNER
--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.
@


<<*>>=
<<license>>
<<domain BYTE Byte>>
<<domain BYTEBUF ByteBuffer>>
<<domain DATAARY DataArray>>

@

\end{document}