⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dl_iso8583_fields.c

📁 This package contains the following source code files: - demo.c Demo application sourc
💻 C
📖 第 1 页 / 共 2 页
字号:
						   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 + -