/* CSL - Common Sound Layer
 * Copyright (C) 2000-2001 Stefan Westerfeld and Tim Janik
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "artscsladapter.h"
#include "artsmcopmethods.h"
#include "cslutils.h"
#include "artsbinbuffer.h"
#include "artsmcopdispatcher.h"

#include <stdio.h>

struct _ArtsCslAdapter
{
  ArtsMcopObject object;
  
  int method_open;
  int method_set_params;
  int method_set_title;
  int method_write;
  int method_read;
  int method_activate;
  int method_wait_buffer_level;
  int method_status;
  int method_close;
  int method_sample_new;
  int method_sample_release;
  int method_sample_write;
  int method_sample_write_done;
  int method_sample_play;
  int method_sample_is_playing;
  int method_sample_stop;
  int method_sample_wait_done;
  int method_sample_cache_add;
  int method_sample_cache_find;
  int method_sample_cache_remove;
};
/* HACK! */
#define	REQUEST_RESULT(dispatcher, request_id)	(&(dispatcher)->requests[(request_id)].result)

ArtsCslAdapter *_arts_csl_adapter_from_reference (ArtsMcopDispatcher	*dispatcher,
						  ArtsMcopObjectReference *reference,
						  CslBool		 need_copy)
{
  ArtsCslAdapter *result
    = (ArtsCslAdapter *)csl_malloc0 (sizeof (ArtsCslAdapter));
  
  result->object.dispatcher = dispatcher;
  result->object.object_id = reference->object_id;
  
  if (need_copy)
    _arts_mcop_object_copy_remote(&result->object);
  _arts_mcop_object_use_remote(&result->object);
  return result;
}

int
_arts_csl_adapter_open (ArtsCslAdapter  *adapter,
			const char      *role,
			ArtsCslDirection dir)
{
  ArtsBinBuffer buffer;
  unsigned int request_id;
  int result;
  
  csl_return_val_if_fail (adapter != NULL, 0);
  csl_return_val_if_fail (role != NULL, 0);
  
  if (!adapter->method_open)
    {
      adapter->method_open = _arts_mcop_dispatcher_lookup_hex_method (adapter->object.dispatcher,
								      adapter->object.object_id, CSL_CSL_Adapter_open);
    }
  
  /* method header and return type */
  request_id = _arts_mcop_dispatcher_setup_invocation (adapter->object.dispatcher, &buffer,
						       adapter->object.object_id,
						       adapter->method_open,
						       ARTS_MCOP_RESULT_LONG);
  /* method args */
  _arts_bin_buffer_put_string (&buffer, role);
  _arts_bin_buffer_put_int (&buffer, (int)dir);
  /* do invocation, fetch args */
  if (_arts_mcop_dispatcher_invoke (adapter->object.dispatcher, &buffer, request_id))
    result = REQUEST_RESULT (adapter->object.dispatcher, request_id)->v_long;
  else
    result = 0;
  /* free request slot */
  _arts_mcop_dispatcher_free_request (adapter->object.dispatcher, request_id);
  
  return result;
}

CslBool
_arts_csl_adapter_set_params (ArtsCslAdapter      *adapter,
			      int                  streamID, 
			      ArtsCslStreamParams *params)
{
  ArtsBinBuffer buffer;
  unsigned int request_id;
  CslBool result;
  
  csl_return_val_if_fail (adapter != NULL, FALSE);
  csl_return_val_if_fail (params != NULL, FALSE);
  
  if (!adapter->method_set_params)
    {
      adapter->method_set_params = _arts_mcop_dispatcher_lookup_hex_method (adapter->object.dispatcher,
									    adapter->object.object_id, CSL_CSL_Adapter_setParams);
    }
  
  /* method header and return type */
  request_id = _arts_mcop_dispatcher_setup_invocation (adapter->object.dispatcher, &buffer,
						       adapter->object.object_id,
						       adapter->method_set_params,
						       ARTS_MCOP_RESULT_BOOLEAN);
  /* method args */
  _arts_bin_buffer_put_int (&buffer, streamID);
  _arts_csl_stream_params_marshal (&buffer, params);
  
  /* do invocation, fetch args */
  if (_arts_mcop_dispatcher_invoke (adapter->object.dispatcher, &buffer, request_id))
    result = REQUEST_RESULT (adapter->object.dispatcher, request_id)->v_boolean;
  else
    result = FALSE;
  /* free request slot */
  _arts_mcop_dispatcher_free_request (adapter->object.dispatcher, request_id);
  
  return result;
}

void
_arts_csl_adapter_set_title (ArtsCslAdapter *adapter,
			     int             streamID,
			     const char     *title)
{
  ArtsBinBuffer buffer;
  unsigned int request_id;
  
  csl_return_if_fail (adapter != NULL);
  csl_return_if_fail (title != NULL);
  
  if (!adapter->method_set_title)
    {
      adapter->method_set_title = _arts_mcop_dispatcher_lookup_hex_method (adapter->object.dispatcher,
									   adapter->object.object_id,
									   CSL_CSL_Adapter_setTitle);
    }
  
  /* method header and return type */
  request_id = _arts_mcop_dispatcher_setup_invocation (adapter->object.dispatcher,
						       &buffer,
						       adapter->object.object_id,
						       adapter->method_set_title,
						       ARTS_MCOP_RESULT_VOID);
  /* method args */
  _arts_bin_buffer_put_int (&buffer, streamID);
  _arts_bin_buffer_put_string (&buffer, title);
  
  /* do invocation, fetch args */
  _arts_mcop_dispatcher_invoke (adapter->object.dispatcher, &buffer, request_id);
  /* free request slot */
  _arts_mcop_dispatcher_free_request (adapter->object.dispatcher, request_id);
}

void
_arts_csl_adapter_write (ArtsCslAdapter *adapter,
			 int            streamID,
			 unsigned char *bytes,
			 unsigned int   n_bytes)
{
  ArtsBinBuffer buffer;
  
  csl_return_if_fail (adapter != NULL);
  csl_return_if_fail (bytes != NULL);
  
  if (!adapter->method_write)
    {
      adapter->method_write = _arts_mcop_dispatcher_lookup_hex_method (adapter->object.dispatcher,
								       adapter->object.object_id, CSL_CSL_Adapter_write);
    }
  
  /* method header and return type */
  _arts_mcop_dispatcher_setup_oneway_invocation (adapter->object.dispatcher, &buffer,
						 adapter->object.object_id,
						 adapter->method_write);
  /* method args */
  _arts_bin_buffer_put_int (&buffer, streamID);
  _arts_bin_buffer_put_bytes (&buffer, n_bytes, bytes);
  
  /* do invocation, fetch args */
  _arts_mcop_dispatcher_oneway_invoke (adapter->object.dispatcher, &buffer);
}

/* this function has a bit strange "language binding" (i.e. no IDL compiler
 * could possibly generate it like that) but since we're handwriting all that,
 * it's okay
 */
unsigned int
_arts_csl_adapter_read (ArtsCslAdapter *adapter,
		    	int             streamID,
		    	unsigned int    n_bytes,
		    	unsigned char  *bytes)
{
  ArtsBinBuffer buffer;
  unsigned int request_id;
  unsigned int result;
  
  csl_return_val_if_fail (adapter != NULL, 0);
  csl_return_val_if_fail (bytes != NULL, 0);
  
  if (!adapter->method_read)
    {
      adapter->method_read = _arts_mcop_dispatcher_lookup_hex_method (adapter->object.dispatcher,
			      					      adapter->object.object_id,
								      CSL_CSL_Adapter_read);
    }
  
  /* method header and return type */
  request_id = _arts_mcop_dispatcher_setup_invocation (adapter->object.dispatcher, &buffer,
						       adapter->object.object_id,
						       adapter->method_read,
						       ARTS_MCOP_RESULT_BYTE_SEQ);

  /* method args */
  _arts_bin_buffer_put_int (&buffer, streamID);
  _arts_bin_buffer_put_int (&buffer, n_bytes);
  
  /* do invocation, fetch args */
  if (_arts_mcop_dispatcher_invoke (adapter->object.dispatcher, &buffer, request_id))
    {
      unsigned char *read_bytes
	= REQUEST_RESULT (adapter->object.dispatcher, request_id)->v_byte_seq.bytes;
      result = REQUEST_RESULT (adapter->object.dispatcher, request_id)->v_byte_seq.n_bytes;

      memcpy (bytes, read_bytes, result);
    }
  else
    {
      result = 0;
    }

  /* free request slot */
  _arts_mcop_dispatcher_free_request (adapter->object.dispatcher, request_id);

  return result;
}

void
_arts_csl_adapter_activate (ArtsCslAdapter *adapter,
			    int             streamID)
{
  ArtsBinBuffer buffer;
  unsigned int request_id;
  
  csl_return_if_fail (adapter != NULL);
  
  if (!adapter->method_activate)
    {
      adapter->method_activate = _arts_mcop_dispatcher_lookup_hex_method (adapter->object.dispatcher,
									  adapter->object.object_id, CSL_CSL_Adapter_activate);
    }
  
  /* method header and return type */
  request_id = _arts_mcop_dispatcher_setup_invocation (adapter->object.dispatcher, &buffer,
						       adapter->object.object_id,
						       adapter->method_activate,
						       ARTS_MCOP_RESULT_VOID);
  /* method args */
  _arts_bin_buffer_put_int (&buffer, streamID);
  
  /* do invocation, fetch args */
  _arts_mcop_dispatcher_invoke (adapter->object.dispatcher, &buffer, request_id);
  
  /* free request slot -- necessary? */
  _arts_mcop_dispatcher_free_request (adapter->object.dispatcher, request_id);
}

int _arts_csl_adapter_wait_buffer_level (ArtsCslAdapter *adapter,
					 int             streamID,
					 int             bufferUsed)
{
  ArtsBinBuffer buffer;
  unsigned int request_id;
  int result;
  
  csl_return_val_if_fail (adapter != NULL, 0);
  
  if (!adapter->method_wait_buffer_level)
    {
      adapter->method_wait_buffer_level = _arts_mcop_dispatcher_lookup_hex_method (adapter->object.dispatcher,
										   adapter->object.object_id, CSL_CSL_Adapter_waitBufferLevel);
    }
  
  /* method header and return type */
  request_id = _arts_mcop_dispatcher_setup_invocation (adapter->object.dispatcher, &buffer,
						       adapter->object.object_id,
						       adapter->method_wait_buffer_level,
						       ARTS_MCOP_RESULT_LONG);
  /* method args */
  _arts_bin_buffer_put_int (&buffer, streamID);
  _arts_bin_buffer_put_int (&buffer, bufferUsed);
  
  /* do invocation, fetch args */
  if (_arts_mcop_dispatcher_invoke (adapter->object.dispatcher, &buffer, request_id))
    result = REQUEST_RESULT (adapter->object.dispatcher, request_id)->v_long;
  else
    result = 0;
  /* free request slot */
  _arts_mcop_dispatcher_free_request (adapter->object.dispatcher, request_id);
  
  return result;
}

void
_arts_csl_adapter_close (ArtsCslAdapter *adapter,
			 int             streamID)
{
  ArtsBinBuffer buffer;
  unsigned int request_id;
  
  csl_return_if_fail (adapter != NULL);
  
  if (!adapter->method_close)
    {
      adapter->method_close = _arts_mcop_dispatcher_lookup_hex_method (adapter->object.dispatcher,
								       adapter->object.object_id, CSL_CSL_Adapter_close);
    }
  
  /* method header and return type */
  request_id = _arts_mcop_dispatcher_setup_invocation (adapter->object.dispatcher, &buffer,
						       adapter->object.object_id,
						       adapter->method_close,
						       ARTS_MCOP_RESULT_VOID);
  /* method args */
  _arts_bin_buffer_put_int (&buffer, streamID);
  
  /* do invocation, fetch args */
  _arts_mcop_dispatcher_invoke (adapter->object.dispatcher, &buffer, request_id);
  
  /* free request slot -- necessary? */
  _arts_mcop_dispatcher_free_request (adapter->object.dispatcher, request_id);
}

static void *
my_stream_status_demarshal (ArtsBinBuffer *buffer)
{
  return _arts_csl_stream_status_demarshal (buffer);
}

ArtsCslStreamStatus*
_arts_csl_adapter_status (ArtsCslAdapter *adapter,
			  int             streamID)
{
  ArtsBinBuffer buffer;
  unsigned int request_id;
  ArtsCslStreamStatus *result;
  
  csl_return_val_if_fail (adapter != NULL, NULL);
  csl_return_val_if_fail (streamID != 0, NULL);
  
  if (!adapter->method_status)
    {
      adapter->method_status = _arts_mcop_dispatcher_lookup_hex_method (adapter->object.dispatcher,
									adapter->object.object_id,
									CSL_CSL_Adapter_status);
    }
  
  /* method header and return type */
  request_id = _arts_mcop_dispatcher_setup_invocation (adapter->object.dispatcher, &buffer,
						       adapter->object.object_id,
						       adapter->method_status,
						       ARTS_MCOP_RESULT_CUSTOM);
  /* method args */
  _arts_bin_buffer_put_int (&buffer, streamID);

  /* set demarshal function for custom return code */
  REQUEST_RESULT (adapter->object.dispatcher, request_id)->v_custom.demarshal
    = my_stream_status_demarshal;

  /* set free function for custom return code: we'll keep the result */
  REQUEST_RESULT (adapter->object.dispatcher, request_id)->v_custom.free = NULL;

  /* do invocation, fetch args */
  if (_arts_mcop_dispatcher_invoke (adapter->object.dispatcher, &buffer, request_id))
    result = REQUEST_RESULT (adapter->object.dispatcher, request_id)->v_custom.data;
  else
    result = NULL;

  /* free request slot */
  _arts_mcop_dispatcher_free_request (adapter->object.dispatcher, request_id);
  
  return result;
}

int
_arts_csl_adapter_sample_new (ArtsCslAdapter *adapter,
                              const char     *name,
			      const char     *role,
			      const char     *title)
{
  ArtsBinBuffer buffer;
  unsigned int request_id;
  int result;
  
  csl_return_val_if_fail (adapter != NULL, 0);
  csl_return_val_if_fail (name != NULL, 0);
  csl_return_val_if_fail (role != NULL, 0);
  csl_return_val_if_fail (title != NULL, 0);
  
  if (!adapter->method_sample_new)
    {
      adapter->method_sample_new = _arts_mcop_dispatcher_lookup_hex_method (adapter->object.dispatcher,
								            adapter->object.object_id, CSL_CSL_Adapter_sampleNew);
    }
  
  /* method header and return type */
  request_id = _arts_mcop_dispatcher_setup_invocation (adapter->object.dispatcher, &buffer,
						       adapter->object.object_id,
						       adapter->method_sample_new,
						       ARTS_MCOP_RESULT_LONG);
  /* method args */
  _arts_bin_buffer_put_string (&buffer, name);
  _arts_bin_buffer_put_string (&buffer, role);
  _arts_bin_buffer_put_string (&buffer, title);
  /* do invocation, fetch args */
  if (_arts_mcop_dispatcher_invoke (adapter->object.dispatcher, &buffer, request_id))
    result = REQUEST_RESULT (adapter->object.dispatcher, request_id)->v_long;
  else
    result = 0;
  /* free request slot */
  _arts_mcop_dispatcher_free_request (adapter->object.dispatcher, request_id);
  
  return result;
}

void
_arts_csl_adapter_sample_release (ArtsCslAdapter *adapter,
                                  int             sampleID)
{
  ArtsBinBuffer buffer;
  unsigned int request_id;
  
  csl_return_if_fail (adapter != NULL);
  
  if (!adapter->method_sample_release)
    {
      adapter->method_sample_release = _arts_mcop_dispatcher_lookup_hex_method (adapter->object.dispatcher,
									        adapter->object.object_id,
									        CSL_CSL_Adapter_sampleRelease);
    }
  
  /* method header and return type */
  request_id = _arts_mcop_dispatcher_setup_invocation (adapter->object.dispatcher, &buffer,
						       adapter->object.object_id,
						       adapter->method_sample_release,
						       ARTS_MCOP_RESULT_VOID);
  /* method args */
  _arts_bin_buffer_put_int (&buffer, sampleID);
  
  /* do invocation, fetch args */
  _arts_mcop_dispatcher_invoke (adapter->object.dispatcher, &buffer, request_id);
  
  /* free request slot -- necessary? */
  _arts_mcop_dispatcher_free_request (adapter->object.dispatcher, request_id);
}


void
_arts_csl_adapter_sample_write (ArtsCslAdapter *adapter,
			        int             sampleID,
			        unsigned char  *bytes,
				unsigned int    n_bytes)
{
  ArtsBinBuffer buffer;
  
  csl_return_if_fail (adapter != NULL);
  csl_return_if_fail (bytes != NULL);
  
  if (!adapter->method_sample_write)
    {
      adapter->method_sample_write = _arts_mcop_dispatcher_lookup_hex_method (adapter->object.dispatcher,
				        				      adapter->object.object_id,
									      CSL_CSL_Adapter_sampleWrite);
    }
  
  /* method header and return type */
  _arts_mcop_dispatcher_setup_oneway_invocation (adapter->object.dispatcher, &buffer,
						 adapter->object.object_id,
						 adapter->method_sample_write);
  /* method args */
  _arts_bin_buffer_put_int (&buffer, sampleID);
  _arts_bin_buffer_put_bytes (&buffer, n_bytes, bytes);
  
  /* do invocation, fetch args */
  _arts_mcop_dispatcher_oneway_invoke (adapter->object.dispatcher, &buffer);
}

void
_arts_csl_adapter_sample_write_done (ArtsCslAdapter *adapter,
                                     int             sampleID)
{
  ArtsBinBuffer buffer;
  unsigned int request_id;
  
  csl_return_if_fail (adapter != NULL);
  
  if (!adapter->method_sample_write_done)
    {
      adapter->method_sample_write_done = _arts_mcop_dispatcher_lookup_hex_method (adapter->object.dispatcher,
									           adapter->object.object_id,
									           CSL_CSL_Adapter_sampleWriteDone);
    }
  
  /* method header and return type */
  request_id = _arts_mcop_dispatcher_setup_invocation (adapter->object.dispatcher, &buffer,
						       adapter->object.object_id,
						       adapter->method_sample_write_done,
						       ARTS_MCOP_RESULT_VOID);
  /* method args */
  _arts_bin_buffer_put_int (&buffer, sampleID);
  
  /* do invocation, fetch args */
  _arts_mcop_dispatcher_invoke (adapter->object.dispatcher, &buffer, request_id);
  
  /* free request slot -- necessary? */
  _arts_mcop_dispatcher_free_request (adapter->object.dispatcher, request_id);
}

CslBool	
_arts_csl_adapter_sample_play (ArtsCslAdapter *adapter,
                               int             sampleID)
{
  ArtsBinBuffer buffer;
  CslBool result;
  unsigned int request_id;
  
  csl_return_val_if_fail (adapter != NULL, FALSE);
  
  if (!adapter->method_sample_play)
    {
      adapter->method_sample_play = _arts_mcop_dispatcher_lookup_hex_method (adapter->object.dispatcher,
									     adapter->object.object_id,
									     CSL_CSL_Adapter_samplePlay);
    }
  
  /* method header and return type */
  request_id = _arts_mcop_dispatcher_setup_invocation (adapter->object.dispatcher, &buffer,
						       adapter->object.object_id,
						       adapter->method_sample_play,
						       ARTS_MCOP_RESULT_VOID);
  /* method args */
  _arts_bin_buffer_put_int (&buffer, sampleID);
  
  /* do invocation, fetch args */
  if (_arts_mcop_dispatcher_invoke (adapter->object.dispatcher, &buffer, request_id))
    result = REQUEST_RESULT (adapter->object.dispatcher, request_id)->v_boolean;
  else
    result = FALSE;
  /* free request slot */
  _arts_mcop_dispatcher_free_request (adapter->object.dispatcher, request_id);
  
  return result;
}

CslBool	
_arts_csl_adapter_sample_is_playing (ArtsCslAdapter *adapter,
                                     int             sampleID)
{
  ArtsBinBuffer buffer;
  CslBool result;
  unsigned int request_id;
  
  csl_return_val_if_fail (adapter != NULL, FALSE);
  
  if (!adapter->method_sample_is_playing)
    {
      adapter->method_sample_is_playing = _arts_mcop_dispatcher_lookup_hex_method (adapter->object.dispatcher,
									           adapter->object.object_id,
									           CSL_CSL_Adapter_sampleIsPlaying);
    }
  
  /* method header and return type */
  request_id = _arts_mcop_dispatcher_setup_invocation (adapter->object.dispatcher, &buffer,
						       adapter->object.object_id,
						       adapter->method_sample_is_playing,
						       ARTS_MCOP_RESULT_VOID);
  /* method args */
  _arts_bin_buffer_put_int (&buffer, sampleID);
  
  /* do invocation, fetch args */
  if (_arts_mcop_dispatcher_invoke (adapter->object.dispatcher, &buffer, request_id))
    result = REQUEST_RESULT (adapter->object.dispatcher, request_id)->v_boolean;
  else
    result = FALSE;
  /* free request slot */
  _arts_mcop_dispatcher_free_request (adapter->object.dispatcher, request_id);
  
  return result;
}

void	
_arts_csl_adapter_sample_stop (ArtsCslAdapter *adapter,
                               int             sampleID)
{
  ArtsBinBuffer buffer;
  unsigned int request_id;
  
  csl_return_if_fail (adapter != NULL);
  
  if (!adapter->method_sample_stop)
    {
      adapter->method_sample_stop = _arts_mcop_dispatcher_lookup_hex_method (adapter->object.dispatcher,
									     adapter->object.object_id,
									     CSL_CSL_Adapter_sampleStop);
    }
  
  /* method header and return type */
  request_id = _arts_mcop_dispatcher_setup_invocation (adapter->object.dispatcher, &buffer,
						       adapter->object.object_id,
						       adapter->method_sample_stop,
						       ARTS_MCOP_RESULT_VOID);
  /* method args */
  _arts_bin_buffer_put_int (&buffer, sampleID);
  
  /* do invocation, fetch args */
  _arts_mcop_dispatcher_invoke (adapter->object.dispatcher, &buffer, request_id);
  
  /* free request slot -- necessary? */
  _arts_mcop_dispatcher_free_request (adapter->object.dispatcher, request_id);
}

void	
_arts_csl_adapter_sample_wait_done (ArtsCslAdapter *adapter,
                                    int             sampleID)
{
  ArtsBinBuffer buffer;
  unsigned int request_id;
  
  csl_return_if_fail (adapter != NULL);
  
  if (!adapter->method_sample_wait_done)
    {
      adapter->method_sample_wait_done = _arts_mcop_dispatcher_lookup_hex_method (adapter->object.dispatcher,
									          adapter->object.object_id,
									          CSL_CSL_Adapter_sampleWaitDone);
    }
  
  /* method header and return type */
  request_id = _arts_mcop_dispatcher_setup_invocation (adapter->object.dispatcher, &buffer,
						       adapter->object.object_id,
						       adapter->method_sample_wait_done,
						       ARTS_MCOP_RESULT_VOID);
  /* method args */
  _arts_bin_buffer_put_int (&buffer, sampleID);
  
  /* do invocation, fetch args */
  _arts_mcop_dispatcher_invoke (adapter->object.dispatcher, &buffer, request_id);
  
  /* free request slot -- necessary? */
  _arts_mcop_dispatcher_free_request (adapter->object.dispatcher, request_id);
}

void	
_arts_csl_adapter_sample_cache_add (ArtsCslAdapter *adapter,
                                    int             sampleID)
{
  ArtsBinBuffer buffer;
  unsigned int request_id;
  
  csl_return_if_fail (adapter != NULL);
  
  if (!adapter->method_sample_cache_add)
    {
      adapter->method_sample_cache_add = _arts_mcop_dispatcher_lookup_hex_method (adapter->object.dispatcher,
									          adapter->object.object_id,
									          CSL_CSL_Adapter_sampleCacheAdd);
    }
  
  /* method header and return type */
  request_id = _arts_mcop_dispatcher_setup_invocation (adapter->object.dispatcher, &buffer,
						       adapter->object.object_id,
						       adapter->method_sample_cache_add,
						       ARTS_MCOP_RESULT_VOID);
  /* method args */
  _arts_bin_buffer_put_int (&buffer, sampleID);
  
  /* do invocation, fetch args */
  _arts_mcop_dispatcher_invoke (adapter->object.dispatcher, &buffer, request_id);
  
  /* free request slot -- necessary? */
  _arts_mcop_dispatcher_free_request (adapter->object.dispatcher, request_id);
}

int
_arts_csl_adapter_sample_cache_find (ArtsCslAdapter *adapter,
                                     const char     *name,
				     const char     *role,
				     const char     *title)
{
  ArtsBinBuffer buffer;
  unsigned int request_id;
  int result;
  
  csl_return_val_if_fail (adapter != NULL, 0);
  csl_return_val_if_fail (name != NULL, 0);
  
  if (!adapter->method_sample_cache_find)
    {
      adapter->method_sample_cache_find = _arts_mcop_dispatcher_lookup_hex_method (adapter->object.dispatcher,
								                   adapter->object.object_id,
										   CSL_CSL_Adapter_sampleCacheFind);
    }
  
  /* method header and return type */
  request_id = _arts_mcop_dispatcher_setup_invocation (adapter->object.dispatcher, &buffer,
						       adapter->object.object_id,
						       adapter->method_sample_cache_find,
						       ARTS_MCOP_RESULT_LONG);
  /* method args */
  _arts_bin_buffer_put_string (&buffer, name);
  _arts_bin_buffer_put_string (&buffer, role);
  _arts_bin_buffer_put_string (&buffer, title);
  /* do invocation, fetch args */
  if (_arts_mcop_dispatcher_invoke (adapter->object.dispatcher, &buffer, request_id))
    result = REQUEST_RESULT (adapter->object.dispatcher, request_id)->v_long;
  else
    result = 0;
  /* free request slot */
  _arts_mcop_dispatcher_free_request (adapter->object.dispatcher, request_id);
  
  return result;
}

void
_arts_csl_adapter_sample_cache_remove (ArtsCslAdapter *adapter,
                                       int             sampleID)
{
  ArtsBinBuffer buffer;
  unsigned int request_id;
  
  csl_return_if_fail (adapter != NULL);
  
  if (!adapter->method_sample_cache_remove)
    {
      adapter->method_sample_cache_remove = _arts_mcop_dispatcher_lookup_hex_method (adapter->object.dispatcher,
									             adapter->object.object_id,
									             CSL_CSL_Adapter_sampleCacheRemove);
    }
  
  /* method header and return type */
  request_id = _arts_mcop_dispatcher_setup_invocation (adapter->object.dispatcher, &buffer,
						       adapter->object.object_id,
						       adapter->method_sample_cache_remove,
						       ARTS_MCOP_RESULT_VOID);
  /* method args */
  _arts_bin_buffer_put_int (&buffer, sampleID);
  
  /* do invocation, fetch args */
  _arts_mcop_dispatcher_invoke (adapter->object.dispatcher, &buffer, request_id);
  
  /* free request slot -- necessary? */
  _arts_mcop_dispatcher_free_request (adapter->object.dispatcher, request_id);
}

 
/* CSL::StreamParams */

ArtsCslStreamParams*
_arts_csl_stream_params_demarshal (ArtsBinBuffer *buffer)
{
  ArtsCslStreamParams *params = csl_malloc (sizeof (ArtsCslStreamParams));

  params->rate = _arts_bin_buffer_get_int (buffer);
  params->rate = _arts_bin_buffer_get_int (buffer);
  params->format = (ArtsCslStreamFormat) _arts_bin_buffer_get_int (buffer);

  if (buffer->error)
    {
      _arts_csl_stream_params_free (params);
      params = NULL;
    }
  return params;
}

void
_arts_csl_stream_params_marshal (ArtsBinBuffer       *buffer,
				 ArtsCslStreamParams *params)
{
  _arts_bin_buffer_put_int (buffer, params->rate);
  _arts_bin_buffer_put_int (buffer, params->channels);
  _arts_bin_buffer_put_int (buffer, (int)params->format);
}

void		 
_arts_csl_stream_params_free (ArtsCslStreamParams *params)
{
  csl_free (params);
}

/* CSL::StreamStatus */

ArtsCslStreamStatus*
_arts_csl_stream_status_demarshal (ArtsBinBuffer *buffer)
{
  ArtsCslStreamStatus *status = csl_malloc (sizeof (ArtsCslStreamStatus));

  status->stream_id = _arts_bin_buffer_get_int (buffer);

  status->stream_params = _arts_csl_stream_params_demarshal (buffer);
  status->stream_buffer_used = _arts_bin_buffer_get_int (buffer);
  status->stream_buffer_size = _arts_bin_buffer_get_int (buffer);

  status->arts_params = _arts_csl_stream_params_demarshal (buffer);
  status->arts_buffer_used = _arts_bin_buffer_get_int (buffer);
  status->arts_buffer_size = _arts_bin_buffer_get_int (buffer);

  if (buffer->error)
    {
      _arts_csl_stream_status_free (status);
      status = NULL;
    }
  return status;
}

void
_arts_csl_stream_status_marshal (ArtsBinBuffer       *buffer,
				 ArtsCslStreamStatus *status)
{
  _arts_bin_buffer_put_int (buffer, status->stream_id);

  _arts_csl_stream_params_marshal (buffer, status->stream_params);
  _arts_bin_buffer_put_int (buffer, status->stream_buffer_used);
  _arts_bin_buffer_put_int (buffer, status->stream_buffer_size);

  _arts_csl_stream_params_marshal (buffer, status->arts_params);
  _arts_bin_buffer_put_int (buffer, status->arts_buffer_used);
  _arts_bin_buffer_put_int (buffer, status->arts_buffer_size);
}

void
_arts_csl_stream_status_free (ArtsCslStreamStatus *status)
{
  if (status != NULL)
    {
      _arts_csl_stream_params_free (status->stream_params);
      _arts_csl_stream_params_free (status->arts_params);
    }
  csl_free (status);
}

/* vim:ts=8:sw=2:sts=2
 */
