Calendar-CSA
view release on metacpan or search on metacpan
#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;
} 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
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 )