#ifdef __cplusplus
extern
"C"
{
#endif
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#ifdef __cplusplus
}
#endif
static
char
rcsid[] =
"$Id: PCF.xs,v 33.2 2009/07/30 12:25:54 biersma Exp $"
;
#ifndef PERL_PATCHLEVEL
# ifndef __PATCHLEVEL_H_INCLUDED__
# include "patchlevel.h"
# endif
#endif
#ifndef PATCHLEVEL
# define PATCHLEVEL PERL_VERSION
#endif
#ifndef PERL_PATCHLEVEL
# define PERL_PATCHLEVEL PATCHLEVEL
#endif
#ifndef PERL_SUBVERSION
# define PERL_SUBVERSION SUBVERSION
#endif
#ifndef ERRSV
# define ERRSV perl_get_sv("@",FALSE)
#endif
#if (PERL_PATCHLEVEL < 4) || ((PERL_PATCHLEVEL == 4) && (PERL_SUBVERSION <= 4))
# define PL_sv_undef sv_undef
# define PL_sv_yes sv_yes
# define PL_sv_no sv_no
# define PL_na na
# 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__ */
#ifdef DEBUGME
#define TRACEME(x) do { PerlIO_stdoutf x; PerlIO_stdoutf("\n"); } while (0)
#else
#define TRACEME(x)
#endif
MODULE = MQSeries::Message::PCF PACKAGE = MQSeries::Message::PCF
void
MQDecodePCF(pBuffer)
PMQCHAR pBuffer;
PPCODE:
{
PMQCHAR pTemp = pBuffer;
PMQCHAR pSListTemp;
MQCFST *pStringParam;
#ifdef MQCFT_BYTE_STRING
MQCFBS *pByteStringParam;
#endif
MQCFIN *pIntegerParam;
MQCFSL *pStringParamList;
MQCFIL *pIntegerParamList;
MQLONG StringLength;
HV *HeaderHV, *DataHV;
AV *DataAV, *ListAV;
SV **svp;
int
count, listcount, errors = 0, tmpStringLength;
MQCFH Header = *(MQCFH *)pTemp;
pTemp += Header.StrucLength;
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)));
DataAV = newAV();
for
( count = 0 ; count < (
int
)Header.ParameterCount ; count++ ) {
pStringParam = (MQCFST *)pTemp;
#ifdef MQCFT_BYTE_STRING
pByteStringParam = (MQCFBS *)pTemp;
#endif
pIntegerParam = (MQCFIN *)pTemp;
pStringParamList = (MQCFSL *)pTemp;
pIntegerParamList = (MQCFIL *)pTemp;
if
( pStringParam->Type == MQCFT_STRING ) {
DataHV = newHV();
hv_store(DataHV,
"Type"
,4,(newSViv(pStringParam->Type)),0);
hv_store(DataHV,
"Parameter"
,9,(newSViv(pStringParam->Parameter)),0);
hv_store(DataHV,
"CodedCharSetId"
,14,(newSViv(pStringParam->CodedCharSetId)),0);
hv_store(DataHV,
"String"
,6,(newSVpvn(pStringParam->String,pStringParam->StringLength)),0);
av_push(DataAV,newRV_noinc((SV*)DataHV));
pTemp += pStringParam->StrucLength;
#ifdef MQCFT_BYTE_STRING
}
else
if
( pByteStringParam->Type == MQCFT_BYTE_STRING ) {
DataHV = newHV();
hv_store(DataHV,
"Type"
,4,(newSViv(pByteStringParam->Type)),0);
hv_store(DataHV,
"Parameter"
,9,(newSViv(pByteStringParam->Parameter)),0);
hv_store(DataHV,
"ByteString"
,10,(newSVpvn(pByteStringParam->String,pByteStringParam->StringLength)),0);
av_push(DataAV,newRV_noinc((SV*)DataHV));
pTemp += pByteStringParam->StrucLength;
#endif /*MQCFT_BYTE_STRING */
}
else
if
( pIntegerParam->Type == MQCFT_INTEGER ) {
DataHV = newHV();
hv_store(DataHV,
"Type"
,4,(newSViv(pIntegerParam->Type)),0);
hv_store(DataHV,
"Parameter"
,9,(newSViv(pIntegerParam->Parameter)),0);
hv_store(DataHV,
"Value"
,5,(newSViv(pIntegerParam->Value)),0);
av_push(DataAV,newRV_noinc((SV*)DataHV));
pTemp += pIntegerParam->StrucLength;
}
else
if
( pStringParamList->Type == MQCFT_STRING_LIST ) {
DataHV = newHV();
hv_store(DataHV,
"Type"
,4,(newSViv(pStringParamList->Type)),0);
hv_store(DataHV,
"Parameter"
,9,(newSViv(pStringParamList->Parameter)),0);
hv_store(DataHV,
"CodedCharSetId"
,14,(newSViv(pStringParamList->CodedCharSetId)),0);
ListAV = newAV();
pSListTemp = pStringParamList->Strings;
for
( listcount = 0 ; listcount < (
int
)pStringParamList->Count ; listcount++ ) {
tmpStringLength = 0;
while
(
tmpStringLength < pStringParamList->StringLength &&
pSListTemp[tmpStringLength] !=
'\0'
) {
tmpStringLength++;
}
av_push(ListAV,newSVpvn(pSListTemp,tmpStringLength));
pSListTemp += pStringParamList->StringLength;
}
hv_store(DataHV,
"Strings"
,7,(newRV_noinc((SV*)ListAV)),0);
av_push(DataAV,newRV_noinc((SV*)DataHV));
pTemp += pStringParamList->StrucLength;
}
else
if
( pIntegerParamList->Type == MQCFT_INTEGER_LIST ) {
DataHV = newHV();
hv_store(DataHV,
"Type"
,4,(newSViv(pIntegerParamList->Type)),0);
hv_store(DataHV,
"Parameter"
,9,(newSViv(pIntegerParamList->Parameter)),0);
ListAV = newAV();
for
( listcount = 0 ; listcount < (
int
)pIntegerParamList->Count ; listcount++ ) {
av_push(ListAV,newSViv(pIntegerParamList->Values[listcount]));
}
hv_store(DataHV,
"Values"
,6,(newRV_noinc((SV*)ListAV)),0);
av_push(DataAV,newRV_noinc((SV*)DataHV));
pTemp += pIntegerParamList->StrucLength;
}
else
{
warn(
"Unknown PCF parameter %d is of type %d, structure length %d, parameter %d\n"
, count, pStringParam->Type, pStringParam->StrucLength, pStringParam->Parameter);
errors++;
pTemp += pIntegerParamList->StrucLength;
}
}
if
(errors) {
warn(
"MQDecodePCF: %d unrecognized parameters in data list.\n"
,
errors);
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;
HV *ParameterHV;
MQCFST *pStringParam;
#ifdef MQCFT_BYTE_STRING
MQCFBS *pByteStringParam;
#endif
MQCFSL *pStringParamList;
MQCFIL *pIntegerParamList;
MQLONG Parameter, Value, CodedCharSetId, StrucLength;
STRLEN StringLength;
int
index, subindex, MaxStringLength, typecount;
char
*String, *pString;
ParameterResult = newSVpv(
""
,0);
Header.ParameterCount = av_len(ParameterList) + 1;
for
( index = 0 ; index <= av_len(ParameterList) ; index++ ) {
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);
XSRETURN_UNDEF;
}
ParameterHV = (HV*)SvRV(*svp);
typecount = 0;
if
(hv_exists(ParameterHV,
"Value"
,5)) {
typecount++;
Type = MQCFT_INTEGER;
}
if
(hv_exists(ParameterHV,
"String"
,6)) {
typecount++;
Type = MQCFT_STRING;
}
#ifdef MQCFT_BYTE_STRING
if
(hv_exists(ParameterHV,
"ByteString"
,10)) {
typecount++;
Type = MQCFT_BYTE_STRING;
}
#endif /* MQCFT_BYTE_STRING */
if
(hv_exists(ParameterHV,
"Values"
,6)) {
typecount++;
Type = MQCFT_INTEGER_LIST;
}
if
(hv_exists(ParameterHV,
"Strings"
,7)) {
typecount++;
Type = MQCFT_STRING_LIST;
}
#ifdef MQCFT_INTEGER_FILTER
if
(hv_exists(ParameterHV,
"ByteStringFilter"
,16)) {
typecount++;
Type = MQCFT_BYTE_STRING_FILTER;
}
if
(hv_exists(ParameterHV,
"IntegerFilter"
,13)) {
typecount++;
Type = MQCFT_INTEGER_FILTER;
}
if
(hv_exists(ParameterHV,
"StringFilter"
,12)) {
typecount++;
Type = MQCFT_STRING_FILTER;
}
#endif
if
(typecount == 0) {
warn(
"MQEncodePCF: ParameterList entry '%d' has none of the following keys:\n"
,index);
#ifdef MQCFT_BYTE_STRING
warn(
"\tString ByteString Value Strings Values\n"
);
#else
warn(
"\tString Value Strings Values\n"
);
#endif /* MQCFT_BYTE_STRING */
#ifdef MQCFT_INTEGER_FILTER
warn(
"\tIntegerFilter StringFilter ByteStringFilter\n"
);
#endif
XSRETURN_UNDEF;
}
if
(typecount > 1) {
warn(
"MQEncodePCF: ParameterList entry '%d' has more than one of the following keys:\n"
,index);
#ifdef MQCFT_BYTE_STRING
warn(
"\tString ByteString Value Strings Values\n"
);
#else
warn(
"\tString Value Strings Values\n"
);
#endif /* MQCFT_BYTE_STRING */
#ifdef MQCFT_INTEGER_FILTER
warn(
"\tIntegerFilter StringFilter ByteStringFilter\n"
);
#endif
XSRETURN_UNDEF;
}
svp = hv_fetch(ParameterHV,
"Parameter"
,9,0);
if
(svp == NULL) {
warn(
"MQEncodePCF: ParameterList entry '%d' has no 'Parameter' key.\n"
,index);
XSRETURN_UNDEF;
}
Parameter = SvIV(*svp);
if
(Type == MQCFT_STRING || Type == MQCFT_STRING_LIST) {
svp = hv_fetch(ParameterHV,
"CodedCharSetId"
,14,0);
if
(svp != NULL) {
CodedCharSetId = SvIV(*svp);
}
else
{
CodedCharSetId = MQCCSI_DEFAULT;
}
}
if
(Type == MQCFT_INTEGER) {
MQCFIN IntegerParam = {MQCFIN_DEFAULT};
svp = hv_fetch(ParameterHV,
"Value"
,5,0);
if
( svp == NULL ) {
warn(
"MQEncodePCF: ParameterList entry '%d' has no 'Value' key.\n"
,index);
XSRETURN_UNDEF;
}
Value = SvIV(*svp);
IntegerParam.Parameter = Parameter;
IntegerParam.Value = Value;
sv_catpvn(ParameterResult,(
char
*)&IntegerParam,MQCFIN_STRUC_LENGTH);
}
else
if
(Type == MQCFT_STRING) {
svp = hv_fetch(ParameterHV,
"String"
,6,0);
if
(svp == NULL) {
warn(
"MQEncodePCF: ParameterList entry '%d' has no 'String' key.\n"
,index);
XSRETURN_UNDEF;
}
if
(!SvPOK(*svp)) {
warn(
"MQEncodePCF: ParameterList entry '%d' String key is not a string.\n"
,index);
XSRETURN_UNDEF;
}
String = SvPV(*svp,StringLength);
StrucLength = MQCFST_STRUC_LENGTH_FIXED + StringLength;
if
( StrucLength % 4 )
StrucLength += 4 - (StrucLength%4);
if
((pStringParam = (MQCFST *)
malloc
(StrucLength)) == NULL) {
perror
(
"Unable to allocate memory"
);
XSRETURN_UNDEF;
}
pStringParam->Type = MQCFT_STRING;
pStringParam->Parameter = Parameter;
pStringParam->CodedCharSetId = CodedCharSetId;
pStringParam->StringLength = StringLength;
pStringParam->StrucLength = StrucLength;
memset
(pStringParam->String,
'\0'
,StrucLength - MQCFST_STRUC_LENGTH_FIXED);
strncpy
(pStringParam->String,String,StringLength);
sv_catpvn(ParameterResult, (
char
*)pStringParam, pStringParam->StrucLength);
free
(pStringParam);
#ifdef MQCFT_BYTE_STRING
}
else
if
(Type == MQCFT_BYTE_STRING) {
svp = hv_fetch(ParameterHV,
"ByteString"
, 10, 0);
if
(svp == NULL) {
warn(
"MQEncodePCF: ParameterList entry '%d' has no 'ByteString' key.\n"
, index);
XSRETURN_UNDEF;
}
if
(!SvPOK(*svp)) {
warn(
"MQEncodePCF: ParameterList entry '%d' ByteString key is not a string.\n"
,index);
XSRETURN_UNDEF;
}
String = SvPV(*svp, StringLength);
StrucLength = MQCFBS_STRUC_LENGTH_FIXED + StringLength;
if
( StrucLength % 4 )
StrucLength += 4 - (StrucLength%4);
if
((pByteStringParam = (MQCFBS *)
malloc
(StrucLength)) == NULL) {
perror
(
"Unable to allocate memory"
);
XSRETURN_UNDEF;
}
pByteStringParam->Type = MQCFT_BYTE_STRING;
pByteStringParam->Parameter = Parameter;
pByteStringParam->StringLength = StringLength;
pByteStringParam->StrucLength = StrucLength;
memset
(pByteStringParam->String,
'\0'
, StrucLength - MQCFBS_STRUC_LENGTH_FIXED);
memcpy
(pByteStringParam->String, String, StringLength);
sv_catpvn(ParameterResult, (
char
*)pByteStringParam, pByteStringParam->StrucLength);
free
(pByteStringParam);
#endif /* MQCFT_BYTE_STRING */
}
else
if
(Type == MQCFT_INTEGER_LIST) {
svp = hv_fetch(ParameterHV,
"Values"
,6,0);
if
(svp == NULL) {
warn(
"MQEncodePCF: ParameterList entry '%d' has no 'Values' key.\n"
,index);
XSRETURN_UNDEF;
}
if
(!SvROK(*svp) || ( SvROK(*svp) && SvTYPE(SvRV(*svp)) != SVt_PVAV)) {
warn(
"MQEncodePCF: ParameterList entry '%d' Values key is not an ARRAY reference.\n"
,index);
XSRETURN_UNDEF;
}
ValuesAV = (AV*)SvRV(*svp);
if
(av_len(ValuesAV) == -1) {
warn(
"MQEncodePCF: ParameterList entry '%d' Values ARRAY is empty.\n"
,index);
XSRETURN_UNDEF;
}
StrucLength = (MQLONG)(MQCFIL_STRUC_LENGTH_FIXED +
(
sizeof
(MQLONG) * (av_len(ValuesAV) + 1)));
if
((pIntegerParamList = (MQCFIL *)
malloc
(StrucLength) ) == NULL) {
perror
(
"Unable to allocate memory"
);
XSRETURN_UNDEF;
}
pIntegerParamList->Type = MQCFT_INTEGER_LIST;
pIntegerParamList->StrucLength = StrucLength;
pIntegerParamList->Parameter = Parameter;
pIntegerParamList->Count = av_len(ValuesAV) + 1;
for
(subindex = 0 ; subindex <= av_len(ValuesAV) ; subindex++) {
svp = av_fetch(ValuesAV,subindex,0);
if
(svp == NULL) {
warn(
"MQEncodePCF: Unable to retrieve ParameterList entry '%d' Values entry '%d'.\n"
, index,subindex);
free
(pIntegerParamList);
XSRETURN_UNDEF;
}
pIntegerParamList->Values[subindex] = SvIV(*svp);
}
sv_catpvn(ParameterResult, (
char
*)pIntegerParamList, StrucLength);
free
(pIntegerParamList);
}
else
if
(Type == MQCFT_STRING_LIST) {
svp = hv_fetch(ParameterHV,
"Strings"
,7,0);
if
(svp == NULL) {
warn(
"MQEncodePCF: ParameterList entry '%d' has no 'Strings' key.\n"
,index);
XSRETURN_UNDEF;
}
if
(!SvROK(*svp) || ( SvROK(*svp) && SvTYPE(SvRV(*svp)) != SVt_PVAV)) {
warn(
"MQEncodePCF: ParameterList entry '%d' Strings key is not an ARRAY reference.\n"
,index);
XSRETURN_UNDEF;
}
StringsAV = (AV*)SvRV(*svp);
if
( av_len(StringsAV) == -1 ) {
warn(
"MQEncodePCF: ParameterList entry '%d' Strings ARRAY is empty.\n"
,index);
XSRETURN_UNDEF;
}
MaxStringLength = 0;
for
(subindex = 0; subindex <= av_len(StringsAV); subindex++) {
svp = av_fetch(StringsAV,subindex,0);
if
( svp == NULL || !SvPOK(*svp) ) {
warn(
"MQEncodePCF: ParameterList entry '%d' Strings entry '%d' is not a string.\n"
, index,subindex);
XSRETURN_UNDEF;
}
String = SvPV(*svp,StringLength);
if
(StringLength > MaxStringLength)
MaxStringLength = StringLength;
}
StrucLength = MQCFSL_STRUC_LENGTH_FIXED +
(MaxStringLength * (av_len(StringsAV) + 1));
if
(StrucLength % 4)
StrucLength += 4 - (StrucLength%4);
if
((pStringParamList = (MQCFSL *)
malloc
(StrucLength)) == NULL) {
perror
(
"Unable to allocate memory"
);
XSRETURN_UNDEF;
}
pStringParamList->Type = MQCFT_STRING_LIST;
pStringParamList->StrucLength = StrucLength;
pStringParamList->Parameter = Parameter;
pStringParamList->CodedCharSetId = CodedCharSetId;
pStringParamList->Count = av_len(StringsAV) + 1;
pStringParamList->StringLength = MaxStringLength;
pString = (
char
*)pStringParamList->Strings;
memset
(pString,
'\0'
,StrucLength - MQCFSL_STRUC_LENGTH_FIXED);
for
(subindex = 0; subindex <= av_len(StringsAV); subindex++) {
svp = av_fetch(StringsAV,subindex,0);
String = SvPV(*svp,StringLength);
strncpy
(pString,String,StringLength);
pString += MaxStringLength;
}
sv_catpvn(ParameterResult, (
char
*)pStringParamList, StrucLength);
free
(pStringParamList);
#ifdef MQCFT_INTEGER_FILTER
}
else
if
(Type == MQCFT_BYTE_STRING_FILTER) {
MQCFBF *pByteStringFilter;
svp = hv_fetch(ParameterHV,
"ByteStringFilter"
,16,0);
if
(svp == NULL) {
warn(
"MQEncodePCF: ParameterList entry '%d' has no 'ByteStringFilter' key.\n"
,index);
XSRETURN_UNDEF;
}
if
(!SvROK(*svp) || ( SvROK(*svp) && SvTYPE(SvRV(*svp)) != SVt_PVAV)) {
warn(
"MQEncodePCF: ParameterList entry '%d' ByteStringFilter key is not an ARRAY reference.\n"
,index);
XSRETURN_UNDEF;
}
ValuesAV = (AV*)SvRV(*svp);
if
(av_len(ValuesAV) != 2) {
warn(
"MQEncodePCF: ParameterList entry '%d' ByteStringFilter ARRAY does not have three elements [ Parameter, Operator, Value ].\n"
,index);
XSRETURN_UNDEF;
}
svp = av_fetch(ValuesAV,2,0);
if
(svp == NULL || !SvPOK(*svp)) {
warn(
"MQEncodePCF: Unable to retrieve ParameterList entry '%d' ByteStringFilter entry '%d' (FilterValue).\n"
, index,2);
XSRETURN_UNDEF;
}
String = SvPV(*svp,StringLength);
StrucLength = MQCFBF_STRUC_LENGTH_FIXED + StringLength;
if
(StrucLength % 4)
StrucLength += 4 - (StrucLength%4);
if
((pByteStringFilter = (MQCFBF *)
malloc
(StrucLength)) == NULL) {
perror
(
"Unable to allocate memory"
);
XSRETURN_UNDEF;
}
pByteStringFilter->Type = MQCFT_BYTE_STRING_FILTER;
pByteStringFilter->StrucLength = StrucLength;
pByteStringFilter->FilterValueLength = StringLength;
memset
(pByteStringFilter->FilterValue,
'\0'
, StrucLength - MQCFBF_STRUC_LENGTH_FIXED);
memcpy
(pByteStringFilter->FilterValue, String, StringLength);
svp = av_fetch(ValuesAV,0,0);
if
(svp == NULL) {
warn(
"MQEncodePCF: Unable to retrieve ParameterList entry '%d' ByteStringFilter entry '%d' (Parameter).\n"
, index,0);
XSRETURN_UNDEF;
}
pByteStringFilter->Parameter = SvIV(*svp);
svp = av_fetch(ValuesAV,1,0);
if
(svp == NULL) {
warn(
"MQEncodePCF: Unable to retrieve ParameterList entry '%d' ByteStringFilter entry '%d' (Operator).\n"
, index,1);
XSRETURN_UNDEF;
}
pByteStringFilter->Operator = SvIV(*svp);
sv_catpvn(ParameterResult,(
char
*)pByteStringFilter,StrucLength);
free
(pByteStringFilter);
}
else
if
(Type == MQCFT_INTEGER_FILTER) {
MQCFIF IntegerFilter = {MQCFIF_DEFAULT};
svp = hv_fetch(ParameterHV,
"IntegerFilter"
,13,0);
if
(svp == NULL) {
warn(
"MQEncodePCF: ParameterList entry '%d' has no 'IntegerFilter' key.\n"
,index);
XSRETURN_UNDEF;
}
if
(!SvROK(*svp) || ( SvROK(*svp) && SvTYPE(SvRV(*svp)) != SVt_PVAV)) {
warn(
"MQEncodePCF: ParameterList entry '%d' IntegerFilter key is not an ARRAY reference.\n"
,index);
XSRETURN_UNDEF;
}
ValuesAV = (AV*)SvRV(*svp);
if
(av_len(ValuesAV) != 2) {
warn(
"MQEncodePCF: ParameterList entry '%d' IntegerFilter ARRAY does not have three elements [ Parameter, Operator, Value ].\n"
,index);
XSRETURN_UNDEF;
}
svp = av_fetch(ValuesAV,0,0);
if
(svp == NULL) {
warn(
"MQEncodePCF: Unable to retrieve ParameterList entry '%d' IntegerFilter entry '%d' (Parameter).\n"
, index,0);
XSRETURN_UNDEF;
}
IntegerFilter.Parameter = SvIV(*svp);
svp = av_fetch(ValuesAV,1,0);
if
(svp == NULL) {
warn(
"MQEncodePCF: Unable to retrieve ParameterList entry '%d' IntegerFilter entry '%d' (Operator).\n"
, index,1);
XSRETURN_UNDEF;
}
IntegerFilter.Operator = SvIV(*svp);
svp = av_fetch(ValuesAV,2,0);
if
(svp == NULL) {
warn(
"MQEncodePCF: Unable to retrieve ParameterList entry '%d' IntegerFilter entry '%d' (FilterValue).\n"
, index,2);
XSRETURN_UNDEF;
}
IntegerFilter.FilterValue = SvIV(*svp);
sv_catpvn(ParameterResult,(
char
*)&IntegerFilter,MQCFIF_STRUC_LENGTH);
}
else
if
(Type == MQCFT_STRING_FILTER) {
MQCFSF *pStringFilter;
svp = hv_fetch(ParameterHV,
"StringFilter"
,12,0);
if
(svp == NULL) {
warn(
"MQEncodePCF: ParameterList entry '%d' has no 'StringFilter' key.\n"
,index);
XSRETURN_UNDEF;
}
if
(!SvROK(*svp) || ( SvROK(*svp) && SvTYPE(SvRV(*svp)) != SVt_PVAV)) {
warn(
"MQEncodePCF: ParameterList entry '%d' StringFilter key is not an ARRAY reference.\n"
,index);
XSRETURN_UNDEF;
}
ValuesAV = (AV*)SvRV(*svp);
if
(av_len(ValuesAV) != 2) {
warn(
"MQEncodePCF: ParameterList entry '%d' StringFilter ARRAY does not have three elements [ Parameter, Operator, Value ].\n"
,index);
XSRETURN_UNDEF;
}
svp = av_fetch(ValuesAV,2,0);
if
(svp == NULL || !SvPOK(*svp)) {
warn(
"MQEncodePCF: Unable to retrieve ParameterList entry '%d' StringFilter entry '%d' (FilterValue).\n"
, index,2);
XSRETURN_UNDEF;
}
String = SvPV(*svp,StringLength);
StrucLength = MQCFSF_STRUC_LENGTH_FIXED + StringLength;
if
(StrucLength % 4)
StrucLength += 4 - (StrucLength%4);
if
((pStringFilter = (MQCFSF *)
malloc
(StrucLength)) == NULL) {
perror
(
"Unable to allocate memory"
);
XSRETURN_UNDEF;
}
pStringFilter->Type = MQCFT_STRING_FILTER;
pStringFilter->StrucLength = StrucLength;
pStringFilter->CodedCharSetId = CodedCharSetId;
pStringFilter->FilterValueLength = StringLength;
memset
(pStringFilter->FilterValue,
'\0'
, StrucLength - MQCFSF_STRUC_LENGTH_FIXED);
memcpy
(pStringFilter->FilterValue, String, StringLength);
svp = av_fetch(ValuesAV,0,0);
if
(svp == NULL) {
warn(
"MQEncodePCF: Unable to retrieve ParameterList entry '%d' StringFilter entry '%d' (Parameter).\n"
, index,0);
XSRETURN_UNDEF;
}
pStringFilter->Parameter = SvIV(*svp);
svp = av_fetch(ValuesAV,1,0);
if
(svp == NULL) {
warn(
"MQEncodePCF: Unable to retrieve ParameterList entry '%d' StringFilter entry '%d' (Operator).\n"
, index,1);
XSRETURN_UNDEF;
}
pStringFilter->Operator = SvIV(*svp);
sv_catpvn(ParameterResult,(
char
*)pStringFilter,StrucLength);
free
(pStringFilter);
#endif /* MQCFT_INTEGER_FILTER */
}
}
Result = newSVpv((
char
*)&Header, Header.StrucLength);
sv_catsv(Result,ParameterResult);
XPUSHs(sv_2mortal(Result));
}