mozzoni/src/mozzoni-client.ads

140 lines
4.7 KiB
Ada

with System;
with Interfaces.C;
with Ada.Containers.Hashed_Maps; use Ada.Containers;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with GNAT.Sockets; use GNAT.Sockets;
private with Ada.Characters.Latin_1;
package Mozzoni.Client is
Disconnect_Client : exception;
type Client_Type is tagged record
Descriptor : Integer;
Socket : Socket_Type;
Stream : Stream_Access;
Buffer : Unbounded_String;
Current_RESP_Type : RESP_Type := Mozzoni.None;
Command : Command_Array_Access := null;
Parsed_Command : Natural := 0;
-- Offset in the buffer the parser is currently finished
Offset : Natural := 1;
-- IP Address
-- Client_Port_Number
end record;
-- Determine whether the client data structure is valid
--
-- @param Client
function Is_Valid (Client : in Client_Type) return Boolean;
-- Read and parse the bytes available on the given client's socket
--
-- @param Client a valid Client_Type
procedure Read_Available (Client : in out Client_Type)
with Pre => Is_Valid (Client);
-- Write the given buffer out to the client
--
-- @param Buffer a non-zero length string
procedure Write (Client : in out Client_Type;
Buffer : in String);
-- Write the given character out to the client
--
-- @param Char any valid character
procedure Write (Client : in out Client_Type;
Char : in Character);
-- Write the given number out to the client as a literal string.
--
-- NOTE: this procedure is not going to result in writing an integer to the
-- socket, but rather a string representation of the integer which is what
-- the underlying protocol expects
--
-- @param Number a number
procedure Write (Client : in out Client_Type;
Number : in Natural);
-- Write the CRLF line ending to the socket
procedure Write_Line_Ending (Client : in out Client_Type);
-- Determine whether a Client is registered
--
-- @param Descriptor A valid Socket_Type
-- @return True when the Descriptor has already be registered.
function Has_Client (Descriptor : in Socket_Type) return Boolean;
-- Register a client structure using the given Socket as a key
--
-- @param Socket a valid Socket_Type which can be considered a unique identifier
procedure Register_Client (Socket : in Socket_Type)
with Post => Has_Client (Socket);
-- Remove a Client by its specified socket.
--
-- @param Socket A valid, and already registered Socket_Type
procedure Deregister_Client (Socket : in Socket_Type)
with Pre => Has_Client (Socket),
Post => not Has_Client (Socket);
-- Dump_Status will output some potentially useful information to the log
-- about the current state of the registered Clients
procedure Dump_Status;
-- Look up the client given an integer file descriptor
--
-- @param Descriptor a file descriptor, typically from C
-- @return Client_Type the registered client corresponding to the descriptor;
function Client_For (Descriptor : in Integer) return Client_Type
with Pre => Descriptor > 0;
-- Look up the client given a Socket_Type file descriptor
--
-- @param Descriptor a socket
-- @return Client_Type the registered client corresponding to the socket
function Client_For (Descriptor : in Socket_Type) return Client_Type;
private
use Ada.Characters.Latin_1;
function Hash_Descriptor (D : in Integer) return Hash_Type;
package Maps is new Ada.Containers.Hashed_Maps (Key_Type => Integer,
Element_Type => Client_Type,
Hash => Hash_Descriptor,
Equivalent_Keys => "=");
Read_Buffer_Size : constant := 128;
Directory : Maps.Map;
Terminator : constant String := CR & LF;
function Read_Socket (S : in Socket_Type;
Buffer : in System.Address;
Count : Interfaces.C.size_t) return Interfaces.C.size_t
with Import,
Link_Name => "read",
Convention => C;
function Write_Socket (S : in Socket_Type;
Buffer : in System.Address;
Count : Interfaces.C.size_t) return Interfaces.C.size_t
with Import,
Link_Name => "write",
Convention => C;
function Close_Socket (S : in Socket_Type) return Integer
with Import,
Link_Name => "close",
Convention => C;
-- This procedure is only intended to be invoked in tests. It will destroy
-- *ALL* state for currently registered clients;
procedure Flush_All_Clients;
end Mozzoni.Client;