#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
#include "ngx-queue.h"
typedef struct p5_ngx_queue_s p5_ngx_queue_t;
typedef p5_ngx_queue_t* NgxQueue;
struct p5_ngx_queue_s {
ngx_queue_t queue;
SV* data;
};
/* from List::Util */
#if PERL_VERSION < 13 || (PERL_VERSION == 13 && PERL_SUBVERSION < 9)
# define PERL_HAS_BAD_MULTICALL_REFCOUNT
#endif
MODULE = NgxQueue PACKAGE = NgxQueue
PROTOTYPES: DISABLE
NgxQueue
new(char* class_name, SV* data = NULL)
CODE:
{
PERL_UNUSED_VAR(class_name);
Newx(RETVAL, 1, p5_ngx_queue_t);
ngx_queue_init(&RETVAL->queue);
if (data) {
RETVAL->data = newRV_inc(data);
}
else {
RETVAL->data = NULL;
}
}
OUTPUT:
RETVAL
void
DESTROY(NgxQueue self)
CODE:
{
int cnt;
if (self->data) {
cnt = SvREFCNT(self->data);
SvREFCNT_dec(self->data);
if (cnt <= 1) {
self->data = NULL;
Safefree(self);
}
}
}
void
data(NgxQueue self)
CODE:
{
if (self->data) {
ST(0) = SvRV(self->data);
XSRETURN(1);
}
else {
XSRETURN(0);
}
}
int
empty(NgxQueue h)
CODE:
{
RETVAL = ngx_queue_empty(&h->queue);
}
OUTPUT:
RETVAL
void
insert_head(NgxQueue h, NgxQueue x)
ALIAS:
insert_after = 1
CODE:
{
PERL_UNUSED_VAR(ix);
ngx_queue_insert_head(&h->queue, &x->queue);
PERL_UNUSED_VAR(SvREFCNT_inc(x->data));
}
void
insert_tail(NgxQueue h, NgxQueue x)
CODE:
{
ngx_queue_insert_tail(&h->queue, &x->queue);
PERL_UNUSED_VAR(SvREFCNT_inc(x->data));
}
NgxQueue
head(NgxQueue h)
CODE:
{
ngx_queue_t* q = ngx_queue_head(&h->queue);
RETVAL = ngx_queue_data(q, p5_ngx_queue_t, queue);
PERL_UNUSED_VAR(SvREFCNT_inc(RETVAL->data));
}
OUTPUT:
RETVAL
NgxQueue
last(NgxQueue h)
CODE:
{
ngx_queue_t* q = ngx_queue_last(&h->queue);
RETVAL = ngx_queue_data(q, p5_ngx_queue_t, queue);
PERL_UNUSED_VAR(SvREFCNT_inc(RETVAL->data));
}
OUTPUT:
RETVAL
NgxQueue
next(NgxQueue h)
CODE:
{
ngx_queue_t* q = ngx_queue_next(&h->queue);
RETVAL = ngx_queue_data(q, p5_ngx_queue_t, queue);
PERL_UNUSED_VAR(SvREFCNT_inc(RETVAL->data));
}
OUTPUT:
RETVAL
NgxQueue
prev(NgxQueue h)
CODE:
{
ngx_queue_t* q = ngx_queue_prev(&h->queue);
RETVAL = ngx_queue_data(q, p5_ngx_queue_t, queue);
PERL_UNUSED_VAR(SvREFCNT_inc(RETVAL->data));
}
OUTPUT:
RETVAL
void
remove(NgxQueue x)
CODE:
{
ngx_queue_remove(&x->queue);
SvREFCNT_dec(x->data);
}
void
split(NgxQueue h, NgxQueue q, NgxQueue n)
CODE:
{
ngx_queue_split(&h->queue, &q->queue, &n->queue);
}
void
add(NgxQueue self, NgxQueue n)
CODE:
{
ngx_queue_add(&self->queue, &n->queue);
}
void
foreach(NgxQueue h, SV* cb)
CODE:
{
ngx_queue_t* q;
CV* cv;
HV* stash;
GV* gv;
cv = sv_2cv(cb, &stash, &gv, 0);
if (cv == Nullcv) {
croak("Not a subroutine reference");
}
SAVESPTR(GvSV(PL_defgv));
dMULTICALL;
I32 gimme = G_SCALAR;
PUSH_MULTICALL(cv);
ngx_queue_foreach(q, &h->queue) {
NgxQueue queue = ngx_queue_data(q, p5_ngx_queue_t, queue);
sv_setref_pv(GvSV(PL_defgv), "NgxQueue", (void*)queue);
if (queue->data) {
PERL_UNUSED_VAR(SvREFCNT_inc(queue->data));
}
MULTICALL;
}
#ifdef PERL_HAS_BAD_MULTICALL_REFCOUNT
if (CvDEPTH(multicall_cv) > 1)
SvREFCNT_inc_simple_void_NN(multicall_cv);
#endif
POP_MULTICALL;
}