#include "perl_gpgme.h" ssize_t perl_gpgme_data_read (void *handle, void *buffer, size_t size) { dSP; ssize_t got_size; int ret; STRLEN buf_len; char *buf_chr; SV *sv_buffer; sv_buffer = newSVpv ("", 0); ENTER; SAVETMPS; PUSHMARK (sp); EXTEND (sp, 3); PUSHs ((SV *)handle); PUSHs (sv_buffer); mPUSHi (size); PUTBACK; ret = call_method ("sysread", G_SCALAR); SPAGAIN; if (ret != 1) { PUTBACK; croak ("Calling sysread on io handle didn't return a single scalar."); } got_size = POPi; buf_chr = SvPV (sv_buffer, buf_len); buffer = memcpy (buffer, buf_chr, buf_len); PUTBACK; FREETMPS; LEAVE; return got_size; } ssize_t perl_gpgme_data_write (void *handle, const void *buffer, size_t size) { dSP; ssize_t got_size; int ret; ENTER; SAVETMPS; PUSHMARK (sp); EXTEND (sp, 3); PUSHs ((SV *)handle); mPUSHp ((char *)buffer, size); mPUSHi (size); PUTBACK; ret = call_method ("syswrite", G_SCALAR); SPAGAIN; if (ret != 1) { PUTBACK; croak ("Calling syswrite on io handle didn't return a single scalar."); } got_size = POPi; PUTBACK; FREETMPS; LEAVE; return got_size; } off_t perl_gpgme_data_seek (void *handle, off_t offset, int whence) { dSP; off_t seeked; int ret; ENTER; SAVETMPS; PUSHMARK (sp); EXTEND (sp, 3); PUSHs ((SV *)handle); mPUSHi (offset); mPUSHi (whence); PUTBACK; ret = call_method ("sysseek", G_SCALAR); SPAGAIN; if (ret != 1) { PUTBACK; croak ("Calling sysseek on io handle didn't return a single scalar."); } seeked = POPi; PUTBACK; FREETMPS; LEAVE; return seeked; } void perl_gpgme_data_release (void *handle) { SvREFCNT_inc ((SV *)handle); } gpgme_data_t perl_gpgme_data_new (SV *sv) { gpgme_data_t data; gpgme_error_t err; static struct gpgme_data_cbs cbs; static gpgme_data_cbs_t cbs_ptr = NULL; if (!cbs_ptr) { memset (&cbs, 0, sizeof (cbs)); cbs.read = perl_gpgme_data_read; cbs.write = perl_gpgme_data_write; cbs.seek = perl_gpgme_data_seek; cbs.release = perl_gpgme_data_release; cbs_ptr = &cbs; } SvREFCNT_inc (sv); err = gpgme_data_new_from_cbs (&data, cbs_ptr, sv); perl_gpgme_assert_error (err); return data; } SV * perl_gpgme_data_io_handle_from_scalar (SV *scalar) { dSP; SV *sv; int ret; ENTER; SAVETMPS; PUSHMARK (sp); EXTEND (sp, 2); mPUSHp ("Crypt::GpgME::Data", 18); PUSHs (newRV_inc (scalar)); PUTBACK; ret = call_method ("new", G_SCALAR); SPAGAIN; if (ret != 1) { PUTBACK; croak ("Failed to create Crypt::GpgME::Data instance."); } sv = POPs; SvREFCNT_inc (sv); /* why? */ PUTBACK; FREETMPS; LEAVE; return sv; } SV * perl_gpgme_data_to_sv (gpgme_data_t data) { dSP; SV *sv, *buffer; char *buf; int ret; size_t len; gpgme_data_seek (data, 0, SEEK_SET); buf = gpgme_data_release_and_get_mem (data, &len); if (!buf) { buffer = newSV (0); } else { buffer = newSVpv (buf, len); } gpgme_free (buf); ENTER; SAVETMPS; PUSHMARK (sp); EXTEND (sp, 2); mPUSHp ("Crypt::GpgME::Data", 18); PUSHs (newRV_inc (buffer)); PUTBACK; ret = call_method ("new", G_SCALAR); SPAGAIN; if (ret != 1) { PUTBACK; croak ("Failed to create Crypt::GpgME::Data instance."); } sv = POPs; SvREFCNT_inc (sv); /* why? */ PUTBACK; FREETMPS; LEAVE; return sv; } gpgme_data_t perl_gpgme_data_from_io_handle (SV *handle) { return perl_gpgme_data_new (handle); }