# (c) 2021 Ashok P. Nadkarni
# See LICENSE for license terms.

namespace eval ${NS}::memory {
    proc allocate {sizespec {tag {}}} {
        # Allocates memory of the specified size
        #  sizespec - requested size of memory block. This may be specified
        #   either as an integer value or a type specification.
        #  tag - Tag for the returned pointer.
        #
        # The returned memory must be eventually freed by calling [memory free].
        #
        # See also: "memory new" "memory free"
        #
        # Returns a safe pointer to the allocated memory.
    }
    proc free {pointer} {
        # Frees the memory referenced by the passed pointer
        #  pointer - safe pointer to memory to free
        # The memory must have been allocated using [memory allocate],
        # [memory frombinary], [memory fromstring] or one of the methods of
        # a [Struct] object. Null pointers are silently ignored.
        #
        # See also: "memory allocate"
    }
    proc frombinary {bin_value {tag {}}} {
        # Allocates memory and copied the passed Tcl binary string into it.
        #  bin_value - a Tcl binary value
        #  tag - Tag for the returned pointer.
        # The returned memory must be eventually freed by calling [memory free].
        #
        # See also: "memory tobinary" "memory tobinary!"
        #
        # Returns a safe pointer to the allocated memory.
    }
    proc fromstring {value {encoding {}}} {
        # Allocates memory and stores a Tcl string in it in the specified encoding.
        #  value - Tcl string value
        #  encoding - the encoding to use for conversion. If unspecified or
        #    the empty string, the system encoding is used.
        #
        # The returned memory must be eventually freed by calling [memory free].
        #
        # See also: "memory tostring" "memory tostring!"
        #
        # Returns a safe pointer to the allocated memory.
    }
    proc get {pointer typespec {index 0}} {
        # Converts a native value in memory into a Tcl script level value
        #  pointer - base address of memory location. The pointer must be a
        #   safe pointer but the tag is immaterial.
        #  typespec - type specification to use for conversion
        #  index - the index in memory from which value is to be retrieved.
        #   Care must be taken this is within bounds of the allocated space.
        #
        # The command converts the data at a memory location into a Tcl script
        # object as per the type specification $typespec. The memory address of
        # the data is given by $pointer if $index is unspecified or `0`.
        # Otherwise $index is treated as an index into an array based at
        # $pointer whose elements are of the type defined by $typespec and
        # memory address used is that of the slot given by $index.
        # For example, if $typespec is `int` and $index is 2,
        # the memory address from which the value is read is at byte offset 8
        # assuming ints occupy 4 bytes. If $typespec is `int[3]`, then the size
        # of the type specification is 12, and an index of 2 will correspond to
        # a byte offset of 24, not 8. Be aware of these semantics when reading
        # arrays using non-0 indices.
        #
        # See also: "memory get!" "memory set"
    }
    proc get! {pointer typespec {index 0}} {
        # Converts a value as per a type specification and stores it in memory
        # in native form
        #  pointer - base address of memory location. The pointer is not checked
        #   for validity.
        #  typespec - type specification to use for conversion
        #  index - the index in memory from which value is to be retrieved.
        #   Care must be taken this is within bounds of the allocated space.
        #
        # This command is identical to the [memory get] command except that it does
        # not require $pointer to be a safe pointer. See the documentation of
        # that command for details.
        #
        # See also: "memory get" "memory set"
    }
    proc new {typespec initializer {tag {}}} {
        # Allocates memory for a type and initializes it.
        #  typespec - a type declaration
        #  initializer - the type-specific value to use to initialize allocated memory.
        #  tag - The optional tag for the returned pointer.
        #
        # The $typespec argument may be any type specificiation. If an
        # array is specified of a larger size than the number of elements
        # in $initializer, the remaining elements are zeroed out.
        #
        # The returned memory must be eventually freed by calling [memory free].
        # See also: "memory allocate" "memory free"
        #
        # Returns a safe pointer to the allocated memory.
    }

    proc set {pointer typespec value {index 0}} {
        # Converts a value as per a type specification and stores it in memory
        # in native form
        #  pointer - base address of memory location. The pointer must be a
        #   safe pointer but the tag is immaterial.
        #  typespec - type specification
        #  value - the script level value to be stored
        #  index - the index in memory at which the value is to be stored. Care must
        #   be taken this is within bounds of the allocated space.
        #
        # The command converts $value into the native form corresponding to
        # the type specification $typespec. If $index is unspecified or `0`, the
        # native value is stored at the memory address given by $pointer.
        # Otherwise $index is the treated as an index into an array whose elements
        # are of the type defined by $typespec and the value is stored in the slot
        # given by $index. For example, if $typespec is `int` and $index is 2,
        # the memory address at which the value is written is at byte offset 8
        # assuming ints occupy 4 bytes. If $typespec is `int[3]`, then the size
        # of the type specification is 12, and an index of 2 will correspond to
        # a byte offset of 24, not 8. Be aware of these semantics when writing
        # arrays to non-0 indices to avoid memory corruption.
        #
        # See also: "memory get" "memory set!"
    }
    proc set! {pointer typespec value {index 0}} {
        # Converts a value as per a type specification and stores it in memory
        # in native form
        #  pointer - base address of memory location. The pointer is not checked
        #   for validity.
        #  typespec - type specification
        #  value - the script level value to be stored
        #  index - the index in memory at which the value is to be stored. Care must
        #   be taken this is within bounds of the allocated space.
        #
        # This command is identical to the [memory set] command except that it does
        # not require $pointer to be a safe pointer. See the documentation of that
        # command for details.
        #
        # See also: "memory get" "memory set"
    }

    proc tobinary {pointer size {offset 0}} {
        # Returns the content of a memory block as a Tcl binary string.
        #  pointer - safe pointer to memory
        #  size - number of bytes to copy from the memory block
        #  offset - offset from $pointer of area to value. May be negative
        #    for unsafe pointers.
        # See also: "memory tobinary!" "memory frombinary"
        #
    }
    proc tobinary! {pointer size {offset 0}} {
        # Returns the content of a memory block as a Tcl binary string.
        #  pointer - pointer to memory.
        #  size - number of bytes to copy from the memory block
        #  offset - offset from $pointer of area to value. May be negative
        #    for unsafe pointers.
        #
        # Unlike the [memory tobinary] method, this does not check the validity
        # of $pointer and should be used with care.
        #
        # See also: "memory tobinary" "memory frombinary"
    }
    proc tostring {pointer {encoding {}} {offset 0}} {
        # Returns the content of a memory block as a Tcl string.
        #  pointer - safe pointer to memory
        #  encoding - the encoding to use for conversion. If unspecified or
        #    the empty string, the system encoding is used.
        #  offset - offset from $pointer of area to value. May be negative
        #    for unsafe pointers.
        #
        # See also: "memory tostring!" "memory fromstring"
    }
    proc tostring! {pointer {encoding {}} {offset 0}} {
        # Returns the content of a memory block as a Tcl string.
        #  pointer - pointer to memory
        #  encoding - the encoding to use for conversion. If unspecified or
        #    the empty string, the system encoding is used.
        #  offset - offset from $pointer of area to value. May be negative
        #    for unsafe pointers.
        #
        # Unlike the [memory tostring] method, this does not check the validity
        # of $pointer and should be used with care.
        #
        # See also: "memory tostring!" "memory fromstring"
    }
    proc fill {pointer bytevalue count {offset 0}} {
        # Fills memory with a specified value
        #  pointer - safe pointer to memory
        #  bytevalue - a value in the range `0`-`255`
        #  count - number of bytes to be fill
        #  offset - offset from $pointer of area to fill. May be negative
        #    for unsafe pointers.
    }
    namespace export *
    namespace ensemble create
}
