Calendar-CSA

 view release on metacpan or  search on metacpan

CSA.xs  view on Meta::CPAN

#ifdef __cplusplus
extern "C" {
#endif
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#ifdef __cplusplus
}
#endif

  /*
	Copyright (c) 1997 Kenneth Albanowski. All rights reserved.
	This program is free software; you can redistribute it and/or
	modify it under the same terms as Perl itself.
  */
  
/*#define CSA_DEBUG */

#include <csa/csa.h>

#include "CsaUtils.h"

#define safe_malloc Csa_safe_malloc
#define safe_calloc Csa_safe_calloc

static int
not_here(s)
char *s;
{
    croak("%s not implemented on this architecture", s);
    return -1;
}

int max_callback = 0;

AV *callbacks, *callback_mode;

void callback_handler(
				CSA_session_handle session,
				CSA_flags reason,
				CSA_buffer call_data,
				CSA_buffer client_data,
				CSA_extension *callback_extensions)
{
	int callback = (int)client_data;
	SV ** arg = av_fetch(callbacks, callback, 0);
	AV * args = (AV*)SvRV(*arg);
	int i,j;
	dSP;
	PUSHMARK(sp);
	for(i=1;i<=av_len(args);i++)
		XPUSHs(sv_2mortal(newSVsv(*av_fetch(args, i, 0))));
	{
#ifdef CSA_DEBUG
		printf("Dealing with callback type %d, tag %d\n", reason, callback);
#endif
		if (reason & CSA_CB_CALENDAR_LOGON) {
			CSA_logon_callback_data * data = call_data;
			XPUSHs(sv_2mortal(newSVpv("CALENDAR LOGON", 0)));
			XPUSHs(sv_2mortal(newSVCSA_calendar_user(data->user)));
		}
		if (reason & CSA_CB_CALENDAR_DELETED) {
			CSA_calendar_deleted_callback_data * data = call_data;
			XPUSHs(sv_2mortal(newSVpv("CALENDAR DELETED", 0)));
			XPUSHs(sv_2mortal(newSVCSA_calendar_user(data->user)));
		}
		if (reason & CSA_CB_CALENDAR_ATTRIBUTE_UPDATED) {
			CSA_calendar_attr_update_callback_data * data = call_data;
			XPUSHs(sv_2mortal(newSVpv("CALENDAR ATTRIBUTE UPDATED", 0)));
			XPUSHs(sv_2mortal(newSVCSA_calendar_user(data->user)));
			for (j=0;j<data->number_attributes;j++)
				XPUSHs(sv_2mortal(newSVpv(data->attribute_names[j], 0)));
		}
		if (reason & CSA_CB_ENTRY_ADDED) {
			CSA_add_entry_callback_data * data = call_data;
			XPUSHs(sv_2mortal(newSVpv("ENTRY ADDED", 0)));
			XPUSHs(sv_2mortal(newSVCSA_calendar_user(data->user)));
			XPUSHs(sv_2mortal(newSVCSA_opaque_data(&data->added_entry_id)));
		}
		if (reason & CSA_CB_ENTRY_DELETED) {
			CSA_delete_entry_callback_data * data = call_data;
			XPUSHs(sv_2mortal(newSVpv("ENTRY DELETED", 0)));
			XPUSHs(sv_2mortal(newSVCSA_calendar_user(data->user)));
			XPUSHs(sv_2mortal(newSVCSA_opaque_data(&data->deleted_entry_id)));
			XPUSHs(sv_2mortal(newSVCSA_SCOPE(data->scope)));
			XPUSHs(sv_2mortal(newSVISO_date_time(data->date_and_time,0)));
		}
		if (reason & CSA_CB_ENTRY_UPDATED) {
			CSA_update_entry_callback_data * data = call_data;
			XPUSHs(sv_2mortal(newSVpv("ENTRY UPDATED", 0)));
			XPUSHs(sv_2mortal(newSVCSA_calendar_user(data->user)));
			XPUSHs(sv_2mortal(newSVCSA_opaque_data(&data->old_entry_id)));
			XPUSHs(sv_2mortal(newSVCSA_opaque_data(&data->new_entry_id)));
			XPUSHs(sv_2mortal(newSVCSA_SCOPE(data->scope)));
			XPUSHs(sv_2mortal(newSVISO_date_time(data->date_and_time,0)));
		}
	}
	PUTBACK ;
	perl_call_sv(*av_fetch(args, 0, 0), G_DISCARD);
}

typedef struct Calendar__CSA__Session_t {
	CSA_session_handle	session;
	int	shorten;
	int iso_times;
	int connected;

CSA.xs  view on Meta::CPAN

		} else
			csa_users = 0;
			
		err = csa_free_time_search(session->session, SvISO_date_time_range(range,0), SvISO_time_duration(duration,0), items-3, csa_users, &result, NULL);
		
		if (csa_users)
			free(csa_users);
		
		if (err)
			CsaCroak("free_time_search", err);
		
		if (result) {
			for(i=0;i<result->number_free_time_data;i++) {
				EXTEND(sp, 1);
				PUSHs(sv_2mortal(newSVISO_date_time(result->free_time_data[i], 0)));
			}
			csa_free(result);
		}
	}


void
delete_calendar(session)
	Calendar::CSA::Session	session
	CODE:
	{
		int err = csa_delete_calendar(session->session, NULL);
		if (err)
			CsaCroak("delete_calendar", err);
	}


int
register_callback(session, mode, callback, ...)
	Calendar::CSA::Session	session
	SV *	mode
	SV *	callback
	CODE:
	{
		int i;
		int flags=0;
		AV * args;
		if (SvROK(mode) && (SvTYPE(SvRV(mode)) == SVt_PVAV)) {
			args = (AV*)SvRV(mode);
			for (i=0;i<=av_len(args);i++)
				flags |= SvCSA_callback_mode(*av_fetch(args, i, 0));
		} else {
			flags = SvCSA_callback_mode(mode);
		}

		i = csa_register_callback(session->session, flags, callback_handler, (void*)(max_callback+1), NULL);
		if (i)
			CsaCroak("register_callback", i);
		max_callback++;
#ifdef CSA_DEBUG
		printf("Registered callback %d with action %d\n", max_callback, flags);
#endif
		args = newAV();
		for(i=2;i<items;i++)
			av_push(args, newSVsv(ST(i)));
		av_store(callbacks, max_callback, newRV((SV*)args));
		SvREFCNT_dec(args);
		av_store(callback_mode, max_callback, newSViv(flags));
		RETVAL = max_callback;
	}
	OUTPUT:
	RETVAL

void
call_callbacks(session, mode, ...)
	Calendar::CSA::Session	session
	SV *	mode
	CODE:
	{
		int i,j;
		int flags=0;
		AV * args;
		for(j=1;j<items;j++)
			if (SvROK(mode) && (SvTYPE(SvRV(mode)) == SVt_PVAV)) {
				args = (AV*)SvRV(mode);
				for (i=0;i<=av_len(args);i++)
					flags |= SvCSA_callback_mode(*av_fetch(args, i, 0));
			} else {
				flags |= SvCSA_callback_mode(mode);
			}
		i = csa_call_callbacks(session->session, flags, NULL);
		if (i)
			CsaCroak("call_callbacks", i);
	}

void
unregister_callback(session, tag)
	Calendar::CSA::Session	session
	int	tag
	CODE:
	{
		SV ** s = av_fetch(callback_mode, tag, 0);
		if (*s) {
			int flags = SvIV(*s);
			int i;
			i = csa_unregister_callback(session->session, flags, callback_handler, (void*)(tag), NULL);
			if (i)
				CsaCroak("unregister_callback", i);
			av_store(callbacks, tag, newSVsv(&sv_undef));
			av_store(callback_mode, tag, newSVsv(&sv_undef));
		}
	}

void
x_process_updates(session)
	Calendar::CSA::Session	session
	CODE:
	/*csa_x_process_updates(session->session);*/

Calendar::CSA::Entry
add_entry(session, ...)
	Calendar::CSA::Session	session
	CODE:
	{
		int i, j = 0, err;
		CSA_uint32 count;
		CSA_attribute * result;
		CSA_entry_handle new_entry;
		CSA_attribute * csa_attrs;
		Calendar__CSA__Entry entry;

		if ((items-1)%2)
			croak("attributes must be paired names and values");
		if (items>1) {
			csa_attrs = safe_calloc(sizeof(CSA_attribute)*((items-1)/2), 1);

			for(j=0,i=1;i<items;j++,i+=2) {
				csa_attrs[j].name = lengthen(SvPV(ST(i),na));
				csa_attrs[j].value = SvCSA_attribute_value(ST(i+1), 0);
			}
		} else
			csa_attrs = 0;

		/*for(i=0;i<j;i++) {
			char c;
			fprintf(stderr, "attribute %d name is %s\n", i, csa_attrs[i].name);
			fprintf(stderr, "attribute %d value is %d\n", i, csa_attrs[i].value);
			c = *(char*)csa_attrs[i].value;
		}*/

		err = csa_add_entry(session->session, j, csa_attrs, &new_entry, NULL);
		
		if (csa_attrs)
			free(csa_attrs);

		if (err)
			CsaCroak("add_entry", err);
		
		entry = safe_malloc(sizeof(struct Calendar__CSA__Entry_t));
		entry->session_sv = newRV(SvRV(ST(0)));
		entry->session = session;
		entry->entry = new_entry;
		
		RETVAL = entry;
	}
	OUTPUT:
	RETVAL

void

CSA.xs  view on Meta::CPAN

		if ((items-3)%2)
			croak("attributes must be paired names and values");
		if (items>3) {
			csa_attrs = safe_calloc(sizeof(CSA_attribute)*((items-3)/2),1);
			for(j=0,i=3;i<items;i+=2,j++) {
				csa_attrs[j].name = lengthen(SvPV(ST(i), na));
				csa_attrs[j].value = SvCSA_attribute_value(ST(i+1), 0);
			}
		} else
			csa_attrs = 0;

		err = csa_update_entry_attributes(entry->session->session, entry->entry, SvCSA_SCOPE(scope), propagate, j, csa_attrs, &new_entry, NULL);
		
		if (csa_attrs)
			free(csa_attrs);
		
		if (err)
			CsaCroak("update_entry_attributes", err);
			
		if (new_entry != 0)
			entry->entry = new_entry;
	}

void
list_entry_sequence(entry, range=&sv_undef, ...)
	Calendar::CSA::Entry	entry
	SV *	range
	PPCODE:
	{
		int i, j, err;
		int flags=0;
		CSA_uint32 count;
		CSA_attribute * result;
		CSA_entry_handle *new_entries;
		CSA_attribute csa_attr;
		Calendar__CSA__EntryList entrylist;
		
		err = csa_list_entry_sequence(entry->session->session, entry->entry, SvISO_date_time_range(range,0), &count, &new_entries, NULL);

		if (err)
			CsaCroak("list_entry_sequence", err);
		
		if (new_entries) {
			SV * result;

			entrylist = safe_malloc(sizeof(struct Calendar__CSA__EntryList_t));
			entrylist->count = count;
			entrylist->list = new_entries;
			entrylist->session_sv = newRV(SvRV(entry->session_sv));
			entrylist->session = entry->session;

			result = sv_newmortal();
			sv_setref_pv(result, 
				     "Calendar::CSA::EntryList",
				     (void *)entrylist);
			XPUSHs(result);
		}
	}

BOOT:
callbacks = newAV();
callback_mode = newAV();
{
	char buffer[54];
	_csa_range_to_iso8601(time(0),time(0)+20,buffer);
}



( run in 1.661 second using v1.01-cache-2.11-cpan-39bf76dae61 )