📄 dl_iso8583_fields.c
字号:
DL_ISO8583_MSG *ioMsg,
const DL_ISO8583_FIELD_DEF *iFieldDefPtr,
DL_UINT8 **ioPtr )
{
DL_ERR err = kDL_ERR_NONE;
DL_UINT8 *tmpPtr = *ioPtr;
DL_UINT16 size = 0;
DL_UINT8 *tmpDataPtr = NULL;
/* variable length handling */
err = VarLen_Get(&tmpPtr,iFieldDefPtr->varLen,iFieldDefPtr->len,&size);
/* allocate field */
if ( !err )
err = _DL_ISO8583_MSG_AllocField(iField,size,ioMsg,&tmpDataPtr);
if ( !err )
{
DL_MEM_memcpy(tmpDataPtr,tmpPtr,size);
tmpPtr += size;
tmpDataPtr += size;
*tmpDataPtr = kDL_ASCII_NULL; /* null terminate */
}
*ioPtr = tmpPtr;
return err;
}
/******************************************************************************/
DL_ERR _pack_iso_BINARY ( DL_UINT16 iField,
const DL_ISO8583_MSG *iMsg,
const DL_ISO8583_FIELD_DEF *iFieldDefPtr,
DL_UINT8 **ioPtr )
{
DL_ERR err = kDL_ERR_NONE;
DL_UINT8 *tmpPtr = *ioPtr;
DL_ISO8583_MSG_FIELD *fieldPtr = ((DL_ISO8583_MSG*)iMsg)->field + iField;
DL_UINT32 actLen = fieldPtr->len;
DL_UINT8 *dataPtr = fieldPtr->ptr;
DL_UINT32 reqLen = iFieldDefPtr->len;
/* variable length handling */
err = VarLen_Put(iFieldDefPtr->varLen,actLen,&reqLen,&tmpPtr);
if ( !err )
{
if ( actLen > reqLen ) /* too long */
{
err = kDL_ERR_OTHER;
}
else if ( actLen == reqLen ) /* exact size */
{
/* copy up to 'required' amount */
DL_MEM_memcpy(tmpPtr,dataPtr,reqLen);
tmpPtr += reqLen;
}
else /* shorter - so need to right pad (space) */
{
/* copy what data we have (actual length) */
DL_MEM_memcpy(tmpPtr,dataPtr,actLen);
/* right pad as required */
DL_MEM_memset(tmpPtr+actLen,(int)0,reqLen-actLen);
tmpPtr += reqLen;
}
}
*ioPtr = tmpPtr;
return err;
}
/******************************************************************************/
// NB doesn't remove any trailing padding (0's)
DL_ERR _unpack_iso_BINARY ( DL_UINT16 iField,
DL_ISO8583_MSG *ioMsg,
const DL_ISO8583_FIELD_DEF *iFieldDefPtr,
DL_UINT8 **ioPtr )
{
DL_ERR err = kDL_ERR_NONE;
DL_UINT8 *tmpPtr = *ioPtr;
DL_UINT16 size = 0;
DL_UINT8 *tmpDataPtr = NULL;
/* variable length handling */
err = VarLen_Get(&tmpPtr,iFieldDefPtr->varLen,iFieldDefPtr->len,&size);
/* allocate field */
if ( !err )
err = _DL_ISO8583_MSG_AllocField(iField,size,ioMsg,&tmpDataPtr);
if ( !err )
{
DL_MEM_memcpy(tmpDataPtr,tmpPtr,size);
tmpPtr += size;
tmpDataPtr += size;
*tmpDataPtr = kDL_ASCII_NULL; /* null terminate */
}
*ioPtr = tmpPtr;
return err;
}
/******************************************************************************/
DL_ERR _pack_iso_BITMAP ( DL_UINT16 iField,
const DL_ISO8583_MSG *iMsg,
const DL_ISO8583_FIELD_DEF *iFieldDefPtr,
DL_UINT8 **ioPtr )
{
DL_ERR err = kDL_ERR_NONE;
DL_UINT8 *tmpPtr = *ioPtr;
DL_UINT16 curFieldIdx = iField;
int i;
/* for each possible bitmap segment */
for ( i=0 ; i<((kDL_ISO8583_MAX_FIELD_IDX-iField+1)+63)/64 ; i++ )
{
DL_UINT32 ms=0,
ls=0;
int j;
/* move to next field */
curFieldIdx++;
for ( j=0 ; j<31 ; j++,curFieldIdx++ )
{
ms <<= 1;
if ( (curFieldIdx <= kDL_ISO8583_MAX_FIELD_IDX) &&
(NULL != iMsg->field[curFieldIdx].ptr) )
ms++;
}
for ( j=0 ; j<32 ; j++,curFieldIdx++ )
{
ls <<= 1;
if ( (curFieldIdx <= kDL_ISO8583_MAX_FIELD_IDX) &&
(NULL != iMsg->field[curFieldIdx].ptr) )
ls++;
}
/* output bitmap segment (if required) */
if ( 0 == i )
{
/* NB 1st segment is always output */
DL_UINT32_TO_BYTES(ms,tmpPtr);
DL_UINT32_TO_BYTES(ls,tmpPtr+4);
tmpPtr += 8;
}
else
{
if ( ms || ls )
{
/* set continuation bit of previous segment */
*(tmpPtr-8) |= 0x80;
DL_UINT32_TO_BYTES(ms,tmpPtr);
DL_UINT32_TO_BYTES(ls,tmpPtr+4);
tmpPtr += 8;
}
else
{
/* no fields present, so don't output */
break;
}
}
} /* end-for(i) */
*ioPtr = tmpPtr;
return err;
}
/******************************************************************************/
DL_ERR _unpack_iso_BITMAP ( DL_UINT16 iField,
DL_ISO8583_MSG *ioMsg,
const DL_ISO8583_FIELD_DEF *iFieldDefPtr,
DL_UINT8 **ioPtr )
{
DL_ERR err = kDL_ERR_NONE;
DL_UINT8 *tmpPtr = *ioPtr;
{
DL_UINT16 curFieldIdx = iField;
/* for each bitmap segment (8 bytes) */
do
{
DL_UINT32 ms,ls;
int j;
/* get bitmap segment (8 bytes) */
ms = DL_BYTES_TO_UINT32(tmpPtr);
ls = DL_BYTES_TO_UINT32(tmpPtr+4);
tmpPtr += 8;
/* move to next field */
curFieldIdx++;
/* ms part */
for ( j=30 ; j>=0 ; j--,curFieldIdx++ )
{
if ( DL_BIT_TEST(ms,j) )
{
if ( curFieldIdx > kDL_ISO8583_MAX_FIELD_IDX )
return kDL_ERR_OTHER;
/* set length to non-zero value to indicate field presence */
ioMsg->field[curFieldIdx].len = 1;
}
} /* end-for(j) */
/* ls part */
for ( j=31 ; j>=0 ; j--,curFieldIdx++ )
{
if ( DL_BIT_TEST(ls,j) )
{
if ( curFieldIdx > kDL_ISO8583_MAX_FIELD_IDX )
return kDL_ERR_OTHER;
/* set length to non-zero value to indicate field presence */
ioMsg->field[curFieldIdx].len = 1;
}
} /* end-for(j) */
/* stop if no more bitmap segments */
if ( 0 == DL_BIT_TEST(ms,31) )
break;
} while ( !err );
}
*ioPtr = tmpPtr;
return err;
}
/******************************************************************************/
// returns the bcd encoded value - based on decValue (0..99)
#define output_bcd_byte(decValue)\
((DL_UINT8)((((decValue)/10)<<4)|((decValue)%10)))
// outputs the variable length element
// iVarLenType - e.g. kDL_ISO8583_LLVAR
static DL_ERR VarLen_Put ( DL_UINT8 iVarLenType,
DL_UINT32 iActLen,
DL_UINT32 *ioReqLen,
DL_UINT8 **ioPtr )
{
DL_ERR err = kDL_ERR_NONE;
DL_UINT8 *tmpPtr = *ioPtr;
switch ( iVarLenType )
{
case kDL_ISO8583_FIXED:
/* do nothing */
break;
case kDL_ISO8583_LLVAR:
iActLen %= 100;
*ioReqLen = iActLen;
*tmpPtr++ = output_bcd_byte(iActLen);
break;
case kDL_ISO8583_LLLVAR:
iActLen %= 1000;
*ioReqLen = iActLen;
*tmpPtr++ = output_bcd_byte(iActLen/100);
*tmpPtr++ = output_bcd_byte(iActLen%100);
break;
case kDL_ISO8583_LLLLVAR:
iActLen %= 10000;
*ioReqLen = iActLen;
*tmpPtr++ = output_bcd_byte(iActLen/100);
*tmpPtr++ = output_bcd_byte(iActLen%100);
break;
default:
/* [ERROR] unsupported length type */
err = kDL_ERR_OTHER;
} /* end-switch */
*ioPtr = tmpPtr;
return err;
}
/******************************************************************************/
// determines variable length element
static DL_ERR VarLen_Get ( const DL_UINT8 **ioPtr,
DL_UINT8 iVarLenDigits,
DL_UINT16 iMaxValue,
DL_UINT16 *oLen )
{
DL_ERR err = kDL_ERR_NONE;
DL_UINT8 *tmpPtr = (DL_UINT8*)*ioPtr;
/* init outputs */
*oLen = iMaxValue;
if ( kDL_ISO8583_FIXED != iVarLenDigits )
{
*oLen = 0;
if ( iVarLenDigits % 2 )
iVarLenDigits++;
while ( iVarLenDigits > 0 )
{
*oLen = (*oLen * 100) +
((((int)(*tmpPtr) >> 4) & 0xf) * 10) +
((int)(*tmpPtr) & 0xf);
iVarLenDigits -= 2;
tmpPtr++;
} /* end-while */
/* limit if exceeds max */
*oLen = MIN(iMaxValue,*oLen);
}
*ioPtr = tmpPtr;
return err;
}
/******************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -