MQSeries

 view release on metacpan or  search on metacpan

MQSeries-Message-PCF/PCF.xs  view on Meta::CPAN

#       define PL_stdingv       stdingv
#       define PL_hints         hints
#       define PL_curcop        curcop
#       define PL_curstash      curstash
#       define PL_copline       copline
#endif

#if (PERL_PATCHLEVEL < 5)
#  ifdef WIN32
#       define dTHR extern int Perl___notused
#  else
#       define dTHR extern int errno
#  endif
#endif

#ifndef boolSV
#       define boolSV(b) ((b) ? &PL_sv_yes : &PL_sv_no)
#endif

#ifndef __MVS__
#include "cmqc.h"
#include "cmqcfc.h"
#else
#include "../inc/cmqc.h"
#include "../inc/cmqcfc.h"
#endif /* ! __MVS__ */

/*#define DEBUGME*/

#ifdef DEBUGME
#define TRACEME(x)      do { PerlIO_stdoutf x; PerlIO_stdoutf("\n"); } while (0)
#else
#define TRACEME(x)
#endif

/*
 * PRIdLEAST64 and SCNdLEAST64 are a late additions to C99, but we may
 * have the non-least versions.
 */
#if !defined(PRIdLEAST64)
#if !defined(PRId64)
#define PRIdLEAST64 "lld"
#else /* defined(PRId64) */
#define PRIdLEAST64 PRId64
#endif /* defined(PRId64) */
#endif /* defined(PRIdLEAST64) */
#if !defined(SCNdLEAST64)
#if !defined(SCNd64)
#define SCNdLEAST64 "lld"
#else /* defined(SCNd64) */
#define SCNdLEAST64 SCNd64
#endif /* defined(SCNd64) */
#endif /* defined(SCNdLEAST64) */

MODULE = MQSeries::Message::PCF         PACKAGE = MQSeries::Message::PCF

void
MQDecodePCF(pBuffer)
     PMQCHAR pBuffer;

     PPCODE:
     {
         PMQCHAR   pTemp = pBuffer;
         PMQCHAR   pSListTemp;
         MQCFST   *pStringParam;
#ifdef MQCFT_STRING_FILTER
         MQCFSF   *pStringFilter;
#endif
#ifdef MQCFT_BYTE_STRING
         MQCFBS   *pByteStringParam;
#endif
         MQCFIN   *pIntegerParam;
         MQCFSL   *pStringParamList;
         MQCFIL   *pIntegerParamList;
#ifdef MQCFT_INTEGER_FILTER
         MQCFIF   *pIntegerFilter;
#endif
#ifdef MQCFT_INTEGER64
         MQCFIN64 *pInteger64Param;
#endif /* MQCFT_INTEGER64 */
#ifdef MQCFT_INTEGER64_LIST
         /* yes, the type name looks like a filter, but...whatever */
         MQCFIL64 *pInteger64ParamList;
#endif /* MQCFT_INTEGER64_LIST */
#ifdef MQCFT_GROUP
         MQCFGR *pGroupParam;
#endif /* MQCFT_GROUP */

         HV       *HeaderHV, *DataHV;
         AV       *DataAV, *ListAV;
         int       count, listcount, errors = 0, tmpStringLength;
         AV       *DataAVA; /* a "stack" for handling MQCFT_GROUP records */
         int       parametercount;
         int       abscount; /* like "count", but ignores groups */

         MQCFH     Header = *(MQCFH *)pTemp;
         pTemp += Header.StrucLength;

         /* Create hash with header fields */
         HeaderHV = newHV();

         hv_store(HeaderHV,"Type",4,(newSViv(Header.Type)),0);
         hv_store(HeaderHV,"Version",7,(newSViv(Header.Version)),0);
         hv_store(HeaderHV,"Command",7,(newSViv(Header.Command)),0);
         hv_store(HeaderHV,"MsgSeqNumber",12,(newSViv(Header.MsgSeqNumber)),0);
         hv_store(HeaderHV,"Control",7,(newSViv(Header.Control)),0);
         hv_store(HeaderHV,"CompCode",8,(newSViv(Header.CompCode)),0);
         hv_store(HeaderHV,"Reason",6,(newSViv(Header.Reason)),0);
         hv_store(HeaderHV,"ParameterCount",14,(newSViv(Header.ParameterCount)),0);

         XPUSHs(sv_2mortal(newRV_noinc((SV*)HeaderHV)));

         /* Create array with data */
         DataAV = newAV();
         DataAVA = newAV();

         /*
          * Step 0 of group handling: the limit on the number of loops
          * through the for is not dependent any longer on the header.
          */
         parametercount = (int)Header.ParameterCount;

MQSeries-Message-PCF/PCF.xs  view on Meta::CPAN

                  * we peel off will go into the group's array, not
                  * the top-level one.
                  */
                 av_push(DataAVA, newRV((SV*)DataAV));
                 av_push(DataAVA, newSViv(count));
                 av_push(DataAVA, newSViv(parametercount));
                 DataAV = GroupAV;
                 count = -1; /* -1 because of post-increment in loop header */
                 /* leave abscount alone so that it indicates the full count */
                 parametercount = pGroupParam->ParameterCount;
#endif /* MQCFT_GROUP */
             } else {
                 /* Unknown type - assume basic structure is the same */
                 warn("Unknown PCF parameter %d is of type %d, structure length %d, parameter %d\n", abscount, pStringParam->Type, pStringParam->StrucLength, pStringParam->Parameter);
                 errors++;
                 pTemp += pIntegerParamList->StrucLength;
             }

             /*
              * Step 4 of group handling: if we're about to fall out
              * of the for loop and we have things in the DataAVA
              * array, pop out the previous parametercount, count, and
              * DataAV in reverse order.  Now we won't fall out of the
              * loop.  Do this "while" we're about to fall out (not
              * if, actually) so that if the current group ends at the
              * end of the group above, we don't fall out by accident.
              */
             while (count + 1 == parametercount && av_len(DataAVA) > -1) {
                 SV *sp;
                 sp = av_pop(DataAVA);
                 parametercount = SvIV(sp);
                 SvREFCNT_dec(sp);
                 sp = av_pop(DataAVA);
                 count = SvIV(sp);
                 SvREFCNT_dec(sp);
                 sp = av_pop(DataAVA);
                 DataAV = (AV*)SvRV(sp);
                 SvREFCNT_dec(sp);
             }

         } /* End foreach: PCF parameter */

         SvREFCNT_dec((SV*)DataAVA);

         if (errors) {
             warn("MQDecodePCF: %d unrecognized parameters in data list.\n",
                  errors);
             SvREFCNT_dec((SV*)DataAV);
             XSRETURN_EMPTY;
         }

         XPUSHs(sv_2mortal(newRV_noinc((SV *)DataAV)));
     }


void
MQEncodePCF(Header,ParameterList)
        MQCFH   Header;
        AV*     ParameterList = (AV*)SvRV(ST(1));

        PPCODE:
        {

          IV Type;
          SV *Result, *ParameterResult, **svp;
          AV *ValuesAV, *StringsAV;
#ifdef MQCFT_GROUP
          AV *GroupAVA;
#endif /* MQCFT_GROUP */
          HV *ParameterHV;

          MQCFST *pStringParam;
#ifdef MQCFT_BYTE_STRING
          MQCFBS *pByteStringParam;
#endif
          MQCFSL *pStringParamList;
          MQCFIL *pIntegerParamList;

          MQLONG Parameter, Value, CodedCharSetId, StrucLength;

          STRLEN StringLength, MaxStringLength;

          int index, subindex, typecount;
          char *String, *pString;

          ParameterResult = newSVpv("",0);
#define PCF_DISCARD_RESULT() SvREFCNT_dec(ParameterResult)
#ifdef MQCFT_GROUP
          GroupAVA = newAV();
#define PCF_DISCARD_GROUP() SvREFCNT_dec((SV*)GroupAVA)
#else
#define PCF_DISCARD_GROUP() do { /* nothing to do here */ } while (0)
#endif /* MQCFT_GROUP */

          Header.ParameterCount = av_len(ParameterList) + 1;

          for ( index = 0 ; index <= av_len(ParameterList) ; index++ ) {
              /*
               * Get the next element in the array, and verify that it is
               * a HASH reference.
               */
              svp = av_fetch(ParameterList,index,0);
              if ( !SvROK(*svp) || ( SvROK(*svp) && SvTYPE(SvRV(*svp)) != SVt_PVHV ) ) {
                  warn("MQEncodePCF: ParameterList entry '%d' is not a HASH reference.\n",index);
                  PCF_DISCARD_RESULT();
                  PCF_DISCARD_GROUP();
                  XSRETURN_UNDEF;
              }

              ParameterHV = (HV*)SvRV(*svp);

              /*
               * Look for the following keys: String, Value, Strings,
               * Values.  Only one of these is allowed to exist, and its
               * existence determines the type of data structure (MQCF*)
               * we are encoding.
               */
              typecount = 0;

              if (hv_exists(ParameterHV,"Value",5)) {
                  typecount++;



( run in 0.527 second using v1.01-cache-2.11-cpan-5511b514fd6 )