#include <stdlib.h>
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
#include "TreeNode.h"
Node * new(int child_count)
{
Node * n;
if ((child_count < 1) || (child_count > MAX_LEVEL))
croak("child_count out of bounds: must be between [1..%d]", MAX_LEVEL);
#if USE_MALLOC
n = malloc((size_t) NODESIZE(child_count));
if (n == NULL)
croak("unable to a allocate memory");
#else
Newc(1, n, NODESIZE(child_count), char, Node);
#endif
n->child_count = child_count;
n->key = &PL_sv_undef;
n->value = &PL_sv_undef;
return n;
}
void DESTROY(Node* n)
{
SvREFCNT_dec(n->key);
SvREFCNT_dec(n->value);
#if USE_MALLOC
free(n);
#else
Safefree(n);
#endif
}
int child_count(Node * n)
{
return n->child_count;
}
SV* get_child(Node * n, int index)
{
if ((index >= n->child_count) || (index < 0))
croak("index out of bounds: must be between [0..%d]", n->child_count-1);
return SvREFCNT_inc(n->next[index]);
}
SV* get_child_or_undef(Node * n, int index)
{
if ((index >= n->child_count) || (index < 0))
return &PL_sv_undef;
else
return SvREFCNT_inc(n->next[index]);
}
void set_child(Node* n, int index, SV* t)
{
if ((index >= n->child_count) || (index < 0))
croak("index out of bounds: must be between [0..%d]", n->child_count-1);
if (SvOK(n->next[index]))
sv_setsv(n->next[index], t);
else
n->next[index] = newSVsv(t);
}
void set_key(Node *n, SV* k)
{
if (SvOK(n->key)) {
croak("key is already set");
}
else {
n->key = newRV_inc(k);
}
}
void force_set_key(Node *n, SV* k)
{
if (SvOK(n->key)) {
warn("key is already set");
}
n->key = newRV_inc(k);
}
SV* get_key(Node *n)
{
if (SvOK(n->key)) {
return SvREFCNT_inc(SvRV(n->key));
}
else {
return &PL_sv_undef;
}
}
I32 key_cmp(Node* n, SV* k)
{
if (SvOK(n->key)) {
return sv_cmp(SvRV(n->key), k);
}
else {
return -1;
}
}
void set_value(Node *n, SV* v)
{
n->value = newRV_inc(v);
}
SV* get_value(Node *n)
{
if (SvOK(n->key)) {
return SvREFCNT_inc(SvRV(n->value));
}
else {
return &PL_sv_undef;
}
}
int _allocated(Node* n)
{
return NODESIZE(n->child_count);
}