Revision 5 (by moose, 2010/08/22 05:30:43) old changes
#include "itemtype.h"

MODULE = CSE::Proto::C::Item     PACKAGE = CSE::Proto::C::Item PREFIX = cseproto_item_

PROTOTYPES: enable

BOOT:
   {
      HV *item_stash;

      item_stash = gv_stashpv("CSE::Proto::C::Item", TRUE);
      newCONSTSUB(item_stash, "TYPE_INT8",    newSViv(CSE_ITEMTYPE_INT8));
      newCONSTSUB(item_stash, "TYPE_INT16",   newSViv(CSE_ITEMTYPE_INT16));
      newCONSTSUB(item_stash, "TYPE_INT32",   newSViv(CSE_ITEMTYPE_INT32));
      newCONSTSUB(item_stash, "TYPE_INT64",   newSViv(CSE_ITEMTYPE_INT64));
      newCONSTSUB(item_stash, "TYPE_BOOL",    newSViv(CSE_ITEMTYPE_BOOL));
      newCONSTSUB(item_stash, "TYPE_UINT8",   newSViv(CSE_ITEMTYPE_UINT8));
      newCONSTSUB(item_stash, "TYPE_UINT16",  newSViv(CSE_ITEMTYPE_UINT16));
      newCONSTSUB(item_stash, "TYPE_UINT32",  newSViv(CSE_ITEMTYPE_UINT32));
      newCONSTSUB(item_stash, "TYPE_UINT64",  newSViv(CSE_ITEMTYPE_UINT64));
      newCONSTSUB(item_stash, "TYPE_FLOAT",   newSViv(CSE_ITEMTYPE_FLOAT));
      newCONSTSUB(item_stash, "TYPE_DOUBLE",  newSViv(CSE_ITEMTYPE_DOUBLE));
      newCONSTSUB(item_stash, "TYPE_FIXED32", newSViv(CSE_ITEMTYPE_FIXED32));
      newCONSTSUB(item_stash, "TYPE_FIXED64", newSViv(CSE_ITEMTYPE_FIXED64));
      newCONSTSUB(item_stash, "TYPE_SFIXED32", newSViv(CSE_ITEMTYPE_FIXED32));
      newCONSTSUB(item_stash, "TYPE_SFIXED64", newSViv(CSE_ITEMTYPE_FIXED64));
      newCONSTSUB(item_stash, "TYPE_STRING",  newSViv(CSE_ITEMTYPE_STRING));
      newCONSTSUB(item_stash, "TYPE_MESSAGE", newSViv(CSE_ITEMTYPE_MESSAGE));
      newCONSTSUB(item_stash, "TYPE_DATA",    newSViv(CSE_ITEMTYPE_DATA));
      newCONSTSUB(item_stash, "TYPE_UUID",    newSViv(CSE_ITEMTYPE_UUID));
      newCONSTSUB(item_stash, "TYPE_IPv4",    newSViv(CSE_ITEMTYPE_IPv4));
      newCONSTSUB(item_stash, "TYPE_IPv6",    newSViv(CSE_ITEMTYPE_IPv6));
   }

SV *
cseproto_item_sviv(item)
   CSE_Proto_C_Item item
   CODE:
      if(item->wiretype == CSE_WIRETYPE_SVARINT || item->wiretype == CSE_WIRETYPE_64BIT)
         RETVAL = newSViv(item->v.int64);
      else if(item->wiretype == CSE_WIRETYPE_32BIT)
         RETVAL = newSViv(item->v.int32);
   OUTPUT:
      RETVAL

SV *
cseproto_item_svuv(item)
   CSE_Proto_C_Item item
   CODE:
      if(item->wiretype == CSE_WIRETYPE_VARINT || item->wiretype == CSE_WIRETYPE_64BIT)
         RETVAL = newSViv(item->v.uint64);
      else if(item->wiretype == CSE_WIRETYPE_32BIT)
         RETVAL = newSViv(item->v.uint32);
   OUTPUT:
      RETVAL

SV *
cseproto_item_svnv(item)
   CSE_Proto_C_Item item
   CODE:
      if(item->wiretype == CSE_WIRETYPE_64BIT)
         RETVAL = newSViv(item->v.float64);
      else if(item->wiretype == CSE_WIRETYPE_32BIT)
         RETVAL = newSViv(item->v.float32);
   OUTPUT:
      RETVAL

SV *
cseproto_item_svpv(item)
   CSE_Proto_C_Item item
   CODE:
      if(item->wiretype == CSE_WIRETYPE_LENDELIM)
         RETVAL = newSVpvn(item->v.data, item->data_len);
   OUTPUT:
      RETVAL

cseproto_wiretype_t
cseproto_item_wiretype(item)
   CSE_Proto_C_Item item
   CODE:
      RETVAL = item->wiretype;
   OUTPUT:
      RETVAL

uint32_t
cseproto_item_type(item)
   CSE_Proto_C_Item item
   CODE:
      RETVAL = (uint32_t)item->udata;
   OUTPUT:
      RETVAL

void
cseproto_item_set_type(item, type)
   CSE_Proto_C_Item item
   uint32_t type
   CODE:
      item->udata = (void *)type;

uint32_t
cseproto_item_key(item)
   CSE_Proto_C_Item item
   CODE:
      RETVAL = item->key;
   OUTPUT:
      RETVAL



CSE_Proto_C_Item
cseproto_item_next(item)
   CSE_Proto_C_Item item
   CODE:
      RETVAL = item->next;
   OUTPUT:
      RETVAL

CSE_Proto_C_Item
cseproto_item_prev(item)
   CSE_Proto_C_Item item
   CODE:
      RETVAL = item->prev;
   OUTPUT:
      RETVAL

SV *
cseproto_item_create(key, type, data)
   uint32_t key
   uint32_t type
   SV *  data
   PREINIT:
      uint32_t len;
      cseproto_wiretype_t wiretype;
      void *out;
      uint32_t uint32;
      int32_t  int32;
      uint64_t uint64;
      int64_t  int64;
      float    float32;
      double   float64;
      CSE_Proto_C_Item item;
      SV *item_sv;
   CODE:
      switch(type) {
         case CSE_ITEMTYPE_INT8:
         case CSE_ITEMTYPE_INT16:
         case CSE_ITEMTYPE_INT32:
         case CSE_ITEMTYPE_INT64:
            int64 = SvIV(data);
            wiretype = CSE_WIRETYPE_SVARINT;
            len = _varint_size(ZigZagEncode64(int64));
            out = &int64;
            break;

         case CSE_ITEMTYPE_BOOL:
         case CSE_ITEMTYPE_UINT8:
         case CSE_ITEMTYPE_UINT16:
         case CSE_ITEMTYPE_UINT32:
         case CSE_ITEMTYPE_UINT64:
            uint64 = SvUV(data);
            wiretype = CSE_WIRETYPE_VARINT;
            len = _varint_size(uint64);
            out = &uint64;
            break;

         case CSE_ITEMTYPE_FIXED32:
            int32 = SvIV(data);
            wiretype = CSE_WIRETYPE_32BIT;
            len = sizeof(int32);
            out = &int32;
            break;

         case CSE_ITEMTYPE_FLOAT:
            float32 = SvNV(data);
            wiretype = CSE_WIRETYPE_32BIT;
            len = sizeof(float32);
            out = &float32;
            break;

         case CSE_ITEMTYPE_DOUBLE:
            float64 = SvNV(data);
            wiretype = CSE_WIRETYPE_64BIT;
            len = sizeof(float64);
            out = &float64;
            break;

         case CSE_ITEMTYPE_FIXED64:
            int64 = SvIV(data);
            wiretype = CSE_WIRETYPE_64BIT;
            len = sizeof(int64);
            out = &int64;
            break;

         case CSE_ITEMTYPE_STRING:
         case CSE_ITEMTYPE_MESSAGE:
         case CSE_ITEMTYPE_DATA:
            out = SvPV(data, len);
            wiretype = CSE_WIRETYPE_LENDELIM;
            break;

         case CSE_ITEMTYPE_UUID:
         case CSE_ITEMTYPE_IPv6:
            // might want to verify len is correct
            len = 16;
            out = SvPV(data, len);
            wiretype = CSE_WIRETYPE_LENDELIM;
            break;
            
         case CSE_ITEMTYPE_IPv4:
            // might want to verify len is correct
            len = 4;
            out = SvPV(data, len);
            wiretype = CSE_WIRETYPE_LENDELIM;
            break;

      }
      item = cseproto_create_item(key, wiretype, len, out);
      item->udata = (void *)type;

      item_sv = newSV(0);
      sv_setref_pv(item_sv, "CSE::Proto::C::Item", (void*)item);
      RETVAL = item_sv;
   OUTPUT:
      RETVAL

void
cseproto_item_destroy(item)
   CSE_Proto_C_Item  item
   CODE:
      cseproto_destroy_item(item);