------------------------------------------------------------------------------
--                             adacurl.multi                                --
--                             Specification                                --
--                    Copyright (C) 2003 Andreas Almroth                    --
--                                                                          --
-- AdacURL is free  software; you  can  redistribute it  and/or modify it   --
-- under terms of the  GNU General Public License as published by the Free  --
-- Software Foundation; either version 2,  or (at your option) any later    --
-- version.  AdacURL is distributed in the  hope that it will be useful,    --
-- but  WITH  OUT  ANY  WARRANTY;  without  even the  implied  warranty  of --
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General --
-- Public License for more details.  You should have received a copy of the --
-- GNU General Public License distributed with AdacURL;  see file COPYING. --
-- If not,  write  to  the Free  Software  Foundation, 59 Temple Place -    --
-- Suite 330, Boston, MA 02111-1307, USA.                                   --
--                                                                          --
-- As a special exception,  if other files  instantiate  generics from this --
-- unit, or you link  this unit with other files  to produce an executable, --
-- this  unit  does not  by itself cause  the resulting  executable  to  be --
-- covered  by the  GNU  General  Public  License.  This exception does not --
-- however invalidate  any other reasons why  the executable file  might be --
-- covered by the  GNU Public License.                                      --
--                                                                          --
------------------------------------------------------------------------------
-- $Author: Andreas Almroth $
-- $Date: 03-07-29 17:15 $
-- $Workfile: adacurl-multi.ads $
-- $Revision: 1 $
-- $State: Unstable $
--
-- HISTORY:
--
-- Revision 1: Initial release
--

with System;
with Adacurl; use Adacurl;

package Adacurl.Multi is
   subtype CURLM is System.Address;
   type CURLM_P is access all CURLM;

   type CURLMcode is (CURLM_CALL_MULTI_PERFORM,
                      CURLM_OK,
                      CURLM_BAD_HANDLE,
                      CURLM_BAD_EASY_HANDLE,
                      CURLM_OUT_OF_MEMORY,
                      CURLM_INTERNAL_ERROR,
                      CURLM_LAST);
   for CURLMcode use (CURLM_CALL_MULTI_PERFORM => -1,
                      CURLM_OK => 0,
                      CURLM_BAD_HANDLE => 1,
                      CURLM_BAD_EASY_HANDLE => 2,
                      CURLM_OUT_OF_MEMORY => 3,
                      CURLM_INTERNAL_ERROR => 4,
                      CURLM_LAST => 5);
   pragma Convention(C,CURLMcode);

   type CURL_MSG is (CURLMSG_NONE,
                    CURLMSG_DONE,
                    CURLMSG_LAST);
   pragma Convention(C,CURL_MSG);

   type Data_Union_Range is new Positive range 1..2;
   type Data_Union (Which : Data_Union_Range := 1) is record
      case Which is
         when 1 =>
            Whatever : System.Address;
         when 2 =>
            Result : CURLcode;
      end case;
   end record;
   pragma Unchecked_Union(Data_Union);

   type CURLMsg is record
      Msg         : CURL_MSG;
      Easy_Handle : CURL_P;
      Data        : Data_Union;
   end record;
   pragma Convention(C,Curlmsg);
   type CURLMsg_P is access all CURLMsg;
   pragma Convention(C,Curlmsg_P);

   function Curl_Multi_Init return CURLM_P;


   function Curl_Multi_Add_Handle(Multi_Handle : CURLM_P;
                                  Curl_Handle  : CURLM_P) return CURLMcode;

   function Curl_Multi_Remove_Handle(Multi_Handle : CURLM_P;
                                     Curl_Handle  : CURLM_P)
                                    return CURLMcode;

   -- Use POSIX style fd_set
   ALIGNMENT : constant :=
     Natural'Min (Standard'Maximum_Alignment,8);
   type Fd_Set is array (1 .. 32) of int;
   for Fd_Set'Alignment use ALIGNMENT;
   for Fd_Set'Size use 1024;
   pragma Convention (C,Fd_Set);

   type Fd_Set_P is access all Fd_Set;
   pragma Convention (C, Fd_Set_P);

   function Curl_Multi_Fdset(Multi_Handle : CURLM_P;
                             Read_Fd_Set  : Fd_Set;
                             Write_Fd_Set : Fd_Set;
                             Exc_Fd_Se    : Fd_Set;
                             Max_Fd       : access Int) return CURLMcode;

   function curl_multi_perform(Multi_Handle : CURLM_P;
                               Running_Handles : access Int)
                              return CURLMcode;

   function curl_multi_cleanup(Multi_Handle : CURLM_P) return CURLMcode;

   function Curl_Multi_Info_Read(Multi_Handle  : CURLM_P;
                                 Msgs_In_Queue : access Int)
                                return CURLMsg_P;
private
      pragma Import(C,Curl_Multi_Init,"curl_multi_Init");
      pragma Import(C,Curl_Multi_Add_Handle,"curl_multi_add_handle");
      pragma Import(C,Curl_Multi_Cleanup,"curl_multi_cleanup");
      pragma Import(C,Curl_Multi_Fdset,"curl_multi_fdset");
      pragma Import(C,Curl_Multi_Info_Read,"curl_multi_info_read");
      pragma Import(C,Curl_Multi_Perform,"curl_multi_perform");
      pragma Import(C,Curl_Multi_Remove_Handle,"curl_multi_remove_handle");
end Adacurl.Multi;