1 /* perlio.c - Imager's interface to PerlIO
4 #define IMAGER_NO_CONTEXT
12 perlio_reader(void *handle, void *buf, size_t count);
14 perlio_writer(void *handle, const void *buf, size_t count);
16 perlio_seeker(void *handle, off_t offset, int whence);
18 perlio_closer(void *handle);
20 perlio_destroy(void *handle);
21 /* my_strerror is defined since perl 5.21.x */
23 static const char *my_strerror(pTHX_ int err);
26 #define tTHX PerlInterpreter *
37 #define dIMCTXperlio(state) dIMCTXctx(state->aIMCTX)
40 =item im_io_new_perlio(PerlIO *)
42 Create a new perl I/O object that reads/writes/seeks on a PerlIO
45 The close() handle flushes output but does not close the handle.
51 im_io_new_perlio(pTHX_ PerlIO *handle) {
52 im_perlio *state = mymalloc(sizeof(im_perlio));
55 state->handle = handle;
59 state->aIMCTX = aIMCTX;
61 return io_new_cb(state, perlio_reader, perlio_writer,
62 perlio_seeker, perlio_closer, perlio_destroy);
66 perlio_reader(void *ctx, void *buf, size_t count) {
67 im_perlio *state = ctx;
68 dTHXa(state->my_perl);
71 ssize_t result = PerlIO_read(state->handle, buf, count);
72 if (result == 0 && PerlIO_error(state->handle)) {
73 im_push_errorf(aIMCTX, errno, "read() failure (%s)", my_strerror(aTHX_ errno));
81 perlio_writer(void *ctx, const void *buf, size_t count) {
82 im_perlio *state = ctx;
83 dTHXa(state->my_perl);
87 result = PerlIO_write(state->handle, buf, count);
90 im_push_errorf(aIMCTX, errno, "write() failure (%s)", my_strerror(aTHX_ errno));
97 perlio_seeker(void *ctx, off_t offset, int whence) {
98 im_perlio *state = ctx;
99 dTHXa(state->my_perl);
102 if (whence != SEEK_CUR || offset != 0) {
103 if (PerlIO_seek(state->handle, offset, whence) < 0) {
104 im_push_errorf(aIMCTX, errno, "seek() failure (%s)", my_strerror(aTHX_ errno));
109 return PerlIO_tell(state->handle);
113 perlio_closer(void *ctx) {
114 im_perlio *state = ctx;
115 dTHXa(state->my_perl);
118 if (PerlIO_flush(state->handle) < 0) {
119 im_push_errorf(aIMCTX, errno, "flush() failure (%s)", my_strerror(aTHX_ errno));
126 perlio_destroy(void *ctx) {
131 const char *my_strerror(pTHX_ int err) {
132 const char *result = strerror(err);
135 result = "Unknown error";