8583解析类

偶尔善良 提交于 2020-01-12 02:12:13
ISO8583报文是一种标准报文格式,主要用于金融等领域,网上有很多讲解此报文的文章,需要使用的可以查资料看一下,这里就不浪费空间了。 下面贴出读写该报文的类,需者自取!

/* ISO8583.h */
/* Create by jojoke */
#ifndef __ISO_8583_H__
#define __ISO_8583_H__

#include 
<map>
using namespace std;

typedef 
struct
{
    
int        bit_flag; /*域数据类型0 -- string, 1 -- int, 2 -- binary*/
    
char    *data_name;    /*域名*/
    
int        length;        /*数据域长度*/
    
int        length_in_byte;    /*实际长度(如果是变长)*/
    
int        variable_flag;    /*是否变长标志0:否 2:2位变长, 3:3位变长*/
    
int        datatype;        /*0 -- string, 1 -- int, 2 -- binary*/
    
char    *data;    /*存放具体值*/
    
int        attribute;    /*保留*/
} ISO8583Field; 

typedef 
struct {
    
int len;
    BYTE 
*data;
} ISO8583FieldData;

class CISO8583
{
public:
    
enum FileType
    {
        XML,
        BIN,
        HEX
    };
    
/* Get message length in bytes */
    
int GetMessageLength();
    
/* Write message out in xml format */
    
virtual bool WriteToFile(LPCTSTR pszFile, FileType type);
protected:
    
bool writeXML(LPCTSTR pszXMLFile);
    
bool writeBIN(LPCTSTR pszBINFile);
    
bool writeHEX(LPCTSTR pszHEXFile);

    
void setBit(BYTE *pBytes, int nPos);
    
bool testBit(const BYTE *pBytes, int nPos);
    map
<int, ISO8583FieldData> m_fields;
};

class CISO8583Writer : public CISO8583
{
public:
    CISO8583Writer();
    
~CISO8583Writer();

    
/* Copy message out */
    
int CopyOut(BYTE *pOutBuf, int nBufLen);
    
/* write specified field, if pFieldBuf is NULL then this field will be cleared */
    
const BYTE *WriteField(int nField, int nFieldLen, BYTE *pFieldBuf);
};

class CISO8583Reader : public CISO8583
{
public:
    CISO8583Reader();
    
~CISO8583Reader();
    
/* Read the message */
    
bool ReadMessage(const BYTE *pMessage);
    
/* Get field data */
    
int     GetFields(int *fields, int count);
    
/* Findout whether specified field exists */
    
bool FieldExist(int nField);
    
/* Findout whether specified fields exist. */
    
int FieldsExist(int *fields, int nCount);
    
/* Get fields total count */
    
int     FieldsCount();
    
/* Get specified field length */
    
int  FieldLength(int nField);
    
/* Get specified field data */
    
int  ReadField(int nField, BYTE *pOutBuf, int nBufLen);
protected:
    
bool parseFields(const BYTE *pMessage);
};
#endif

/* ISO8583.cpp */
/* Create by jojoke */
#include "StdAfx.h"
#include 
"ISO8583.h"
#include 
"math.h"
#include 
"assert.h"

ISO8583Field Tbl8583[
128= 

 
/* FLD 01 */ {0,"BIT MAP,EXTENDED"8002, NULL,0}, 
 
/* FLD 02 */ {0,"PRIMARY ACCOUNT NUMBER"22020, NULL,0}, 
 
/* FLD 03 */ {0,"PROCESSING CODE"6000, NULL,0}, 
 
/* FLD 04 */ {0,"AMOUNT, TRANSACTION"12001, NULL,0}, 
 
/* FLD 05 */ {0,"NO USE"12000, NULL,0}, 
 
/* FLD 06 */ {0,"NO USE"12000, NULL,0}, 
 
/* FLD 07 */ {0,"TRANSACTION DATE AND TIME"10000, NULL,0}, 
 
/* FLD 08 */ {0,"NO USE"8000, NULL,0}, 
 
/* FLD 09 */ {0,"NO USE"8000, NULL,0}, 
 
/* FLD 10 */ {0,"NO USE"8000, NULL,0}, 
 
/* FLD 11 */ {0,"SYSTEM TRACE AUDIT NUMBER"6001, NULL,0}, 
 
/* FLD 12 */ {0,"TIME, LOCAL TRANSACTION"6000, NULL,0}, 
 
/* FLD 13 */ {0,"DATE, LOCAL TRANSACTION"4000, NULL,0}, 
 
/* FLD 14 */ {0,"DATE, EXPIRATION"4000, NULL,0}, 
 
/* FLD 15 */ {0,"DATE, SETTLEMENT"4000, NULL,0}, 
 
/* FLD 16 */ {0,"NO USE"4000, NULL,0}, 
 
/* FLD 17 */ {0,"DATE, CAPTURE"4000, NULL,0}, 
 
/* FLD 18 */ {0,"MERCHANT'S TYPE"4000, NULL,0}, 
 
/* FLD 19 */ {0,"NO USE"3000, NULL,0}, 
 
/* FLD 20 */ {0,"NO USE"3000, NULL,0}, 
 
/* FLD 21 */ {0,"NO USE"3000, NULL,0}, 
 
/* FLD 22 */ {0,"POINT OF SERVICE ENTRY MODE"3000, NULL,0}, 
 
/* FLD 23 */ {0,"NO USE"3000, NULL,0}, 
 
/* FLD 24 */ {0,"NO USE"3000, NULL,0}, 
 
/* FLD 25 */ {0,"POINT OF SERVICE CONDITION CODE"2000, NULL,0}, 
 
/* FLD 26 */ {0,"NO USE"2000, NULL,0}, 
 
/* FLD 27 */ {0,"NO USE"1000, NULL,0}, 
 
/* FLD 28 */ {0,"field27"6000, NULL,0}, 
 
/* FLD 29 */ {0,"NO USE"8010, NULL,0}, 
 
/* FLD 30 */ {0,"NO USE"8010, NULL,0}, 
 
/* FLD 31 */ {0,"NO USE"8010, NULL,0}, 
 
/* FLD 32 */ {0,"ACQUIRER INSTITUTION ID. CODE"11020, NULL,0}, 
 
/* FLD 33 */ {0,"FORWARDING INSTITUTION ID. CODE"11020, NULL,0}, 
 
/* FLD 34 */ {0,"NO USE"28020, NULL,0}, 
 
/* FLD 35 */ {0,"TRACK 2 DATA"37020, NULL,0}, 
 
/* FLD 36 */ {0,"TRACK 3 DATA",104030, NULL,0}, 
 
/* FLD 37 */ {0,"RETRIEVAL REFERENCE NUMBER"12000, NULL,0}, 
 
/* FLD 38 */ {0,"AUTH. IDENTIFICATION RESPONSE"6000, NULL,0}, 
 
/* FLD 39 */ {0,"RESPONSE CODE"2000, NULL,0}, 
 
/* FLD 40 */ {0,"NO USE"3000, NULL,0}, 
 
/* FLD 41 */ {0,"CARD ACCEPTOR TERMINAL ID."8000, NULL,0}, 
 
/* FLD 42 */ {0,"CARD ACCEPTOR IDENTIFICATION CODE"15000, NULL,0}, 
 
/* FLD 43 */ {0,"CARD ACCEPTOR NAME LOCATION"40000, NULL,0}, 
 
/* FLD 44 */ {0,"ADDITIONAL RESPONSE DATA"25020, NULL,0}, 
 
/* FLD 45 */ {0,"NO USE"76020, NULL,0}, 
 
/* FLD 46 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 47 */ {0,"field47"999030, NULL,0}, 
 
/* FLD 48 */ {0,"ADDITIONAL DATA --- PRIVATE"999030, NULL,0}, 
 
/* FLD 49 */ {0,"CURRENCY CODE,TRANSACTION"3000, NULL,0}, 
 
/* FLD 50 */ {0,"CURRENCY CODE,SETTLEMENT"3000, NULL,0}, 
 
/* FLD 51 */ {0,"NO USE"3000, NULL,0}, 
 
/* FLD 52 */ {0,"PERSONAL IDENTIFICATION NUMBER DATA"8002, NULL,0}, 
 
/* FLD 53 */ {0,"SECURITY RELATED CONTROL INformATION"16000, NULL,0}, 
 
/* FLD 54 */ {0,"ADDITIONAL AMOUNTS",120030, NULL,0}, 
 
/* FLD 55 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 56 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 57 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 58 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 59 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 60 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 61 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 62 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 63 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 64 */ {0,"MESSAGE AUTHENTICATION CODE FIELD"8002, NULL,0}, 
 
/* FLD 65 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 66 */ {0,"NO USE"1000, NULL,0}, 
 
/* FLD 67 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 68 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 69 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 70 */ {0,"SYSTEM MANAGEMENT INformATION CODE"3000, NULL,0}, 
 
/* FLD 71 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 72 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 73 */ {0,"NO USE"6000, NULL,0}, 
 
/* FLD 74 */ {0,"NUMBER OF CREDITS"10000, NULL,0}, 
 
/* FLD 75 */ {0,"REVERSAL NUMBER OF CREDITS"10000, NULL,0}, 
 
/* FLD 76 */ {0,"NUMBER OF DEBITS"10000, NULL,0}, 
 
/* FLD 77 */ {0,"REVERSAL NUMBER OF DEBITS"10000, NULL,0}, 
 
/* FLD 78 */ {0,"NUMBER OF TRANSFER"10000, NULL,0}, 
 
/* FLD 79 */ {0,"REVERSAL NUMBER OF TRANSFER"10000, NULL,0}, 
 
/* FLD 80 */ {0,"NUMBER OF INQUIRS"10000, NULL,0}, 
 
/* FLD 81 */ {0,"AUTHORIZATION NUMBER"10000, NULL,0}, 
 
/* FLD 82 */ {0,"NO USE"12000, NULL,0}, 
 
/* FLD 83 */ {0,"CREDITS,TRANSCATION FEEAMOUNT"12000, NULL,0}, 
 
/* FLD 84 */ {0,"NO USE"12000, NULL,0}, 
 
/* FLD 85 */ {0,"DEBITS,TRANSCATION FEEAMOUNT"12000, NULL,0}, 
 
/* FLD 86 */ {0,"AMOUNT OF CREDITS"16000, NULL,0}, 
 
/* FLD 87 */ {0,"REVERSAL AMOUNT OF CREDITS"16000, NULL,0}, 
 
/* FLD 88 */ {0,"AMOUNT OF DEBITS"16000, NULL,0}, 
 
/* FLD 89 */ {0,"REVERSAL AMOUNT OF DEBITS"16000, NULL,0}, 
 
/* FLD 90 */ {0,"ORIGINAL DATA ELEMENTS"42000, NULL,0}, 
 
/* FLD 91 */ {0,"FILE UPDATE CODE"1000, NULL,0}, 
 
/* FLD 92 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 93 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 94 */ {0,"SERVICE INDICATOR"7000, NULL,0}, 
 
/* FLD 95 */ {0,"REPLACEMENT AMOUNTS"42000, NULL,0}, 
 
/* FLD 96 */ {0,"NO USE"8000, NULL,0}, 
 
/* FLD 97 */ {0,"AMOUNT OF NET SETTLEMENT"16000, NULL,0}, 
 
/* FLD 98 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 99 */ {0,"SETTLEMENT INSTITUTION ID"11020, NULL,0}, 
 
/* FLD 100 */ {0,"RECVEING INSTITUTION ID"11020, NULL,0}, 
 
/* FLD 101 */ {0,"FILENAME"17020, NULL,0}, 
 
/* FLD 102 */ {0,"ACCOUNT IDENTIFICATION1"28020, NULL,0}, 
 
/* FLD 103 */ {0,"ACCOUNT IDENTIFICATION2"28020, NULL,0}, 
 
/* FLD 104 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 105 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 106 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 107 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 108 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 109 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 110 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 111 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 112 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 113 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 114 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 115 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 116 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 117 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 118 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 119 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 120 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 121 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 122 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 123 */ {0,"NEW PIN DATA"8032, NULL,0}, 
 
/* FLD 124 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 125 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 126 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 127 */ {0,"NO USE"999030, NULL,0}, 
 
/* FLD 128 */ {0,"MESSAGE AUTHENTICATION CODE FIELD"8002, NULL,0}, 
}; 

/* Set bit in specified position */
void CISO8583::setBit(BYTE *pBytes, int nPos)
{
    
if (nPos % 8 == 0)
        pBytes[nPos 
/ 8 - 1|= 0x01;
    
else
        pBytes[(unsigned 
int)floor(nPos / 8)] |= (0x80 >> (nPos % 8 - 1));

    
if (nPos > 64)
        setBit(pBytes, 
1);
}

/* Test to see if bit position of p is set */
bool CISO8583::testBit(const BYTE *pBytes, int nPos)
{
    unsigned 
int nOffset;
    BYTE nMask;
    nOffset 
= nPos % 8 == 0 ? nPos / 8 - 1 : (unsigned int)floor(nPos / 8);
    nMask 
= nPos % 8 == 0 ? 0x01 : (0x80 >> (nPos % 8 - 1));

    
return (pBytes[nOffset] & nMask) == nMask;
}


/* Write message in xml format */
bool CISO8583::writeXML(LPCTSTR pszXMLFile)
{
    
int i = 0;
    BYTE bitmap[
16];
    
char sBitMap[33= {'\0'};
    TCHAR 
*szFieldType[3= {"string""int""binary"};
    FILE 
*fp = fopen(pszXMLFile, "w");
    
if (NULL == fp) 
        
return false;
    
    
/* write bitmap */
    memset(bitmap, 
0sizeof(bitmap));
    map
<int, ISO8583FieldData>::iterator it = m_fields.begin();
    
while (it != m_fields.end()) {
        setBit(bitmap, it
->first);
        it
++;
    }

    
for (i = 0; i < 16; i++
        _snprintf(sBitMap 
+ 2 * i, 2"%02x", bitmap[i]);
    fprintf(fp, 
"<?xml version=\"1.0\" encoding=\"GB2312\"?>\r\n");
    fprintf(fp, 
"<ISO8583 fieldscount=\"%d\" totalbytes=\"%d\" bitmap=\"%s\">", m_fields.size(), this->GetMessageLength(), sBitMap);

    
/* write fields */
    it 
= m_fields.begin();
    
while (it != m_fields.end()) {
        fprintf(fp, 
"\r\n\t<Field no=\"%d\" type=\"%s\" fieldlength=\"%d\" datalength=\"%d\">\n", it->first, szFieldType[Tbl8583[it->first - 1].datatype], Tbl8583[it->first - 1].length, it->second.len);
        
if (Tbl8583[it->first - 1].datatype == 1)
            fprintf(fp, 
"\t\t%s", (char *)it->second.data);
        
else {
            fprintf(fp, 
"\t\t");
            
for (i = 0; i < it->second.len; i++)
                fprintf(fp, 
"%02X", (BYTE)it->second.data[i]);
        }
            
        fprintf(fp, 
"\n\t</Field>");
        it
++;
    }
    
    fprintf(fp, 
"\n</ISO8583>");
    fclose(fp);
    
return true;
}

bool CISO8583::writeBIN(LPCTSTR pszBINFile)
{
    
int i = 0;
    BYTE bitmap[
16];
    FILE 
*fp = fopen(pszBINFile, "wb");
    
if (NULL == fp) 
        
return false;
    
    
/* write bitmap */
    memset(bitmap, 
0sizeof(bitmap));
    map
<int, ISO8583FieldData>::iterator it = m_fields.begin();
    
while (it != m_fields.end()) {
        setBit(bitmap, it
->first);
        it
++;
    }
    
    fwrite(bitmap, 
1sizeof(bitmap), fp);
    
/* write fields */
    it 
= m_fields.begin();
    
while (it != m_fields.end()) {
        
if (Tbl8583[it->first - 1].variable_flag == 0)
            fwrite(it
->second.data, 1, it->second.len, fp);
        
else if (Tbl8583[it->first - 1].variable_flag == 2) {
            fprintf(fp, 
"%02d", it->second.len);
            fwrite(it
->second.data, 1, it->second.len, fp);
        }
        
else if (Tbl8583[it->first - 1].variable_flag == 3) {
            fprintf(fp, 
"%03d", it->second.len);
            fwrite(it
->second.data, 1, it->second.len, fp);
        }

        it
++;
    }
    
    fclose(fp);
    
return true;
}

bool CISO8583::writeHEX(LPCTSTR pszHEXFile)
{
    
int i = 0, j = 0, round = 0, length = this->GetMessageLength();
    FILE 
*fp = fopen(pszHEXFile, "wb");
    
if (NULL == fp) 
        
return false;
    
    BYTE 
*pBytes = new BYTE[length];
    BYTE 
*= pBytes;
    
if (NULL == pBytes)
        
return false;

    memset(pBytes, 
0, length);
    
/* write bitmap */
    map
<int, ISO8583FieldData>::iterator it = m_fields.begin();
    
while (it != m_fields.end()) {
        setBit(pBytes, it
->first);
        it
++;
    }
    
    p 
+= 16;
    
/* write fields */
    it 
= m_fields.begin();
    
while (it != m_fields.end()) {
        
if (Tbl8583[it->first - 1].variable_flag == 0) {
            memcpy(p, it
->second.data, it->second.len);
        }
        
else if (Tbl8583[it->first - 1].variable_flag == 2) {
            _snprintf((
char *)p, 2"%02d", it->second.len);
            p 
+= 2;
            memcpy(p, it
->second.data, it->second.len);
        }
        
else if (Tbl8583[it->first - 1].variable_flag == 3) {
            _snprintf((
char *)p, 3"%03d", it->second.len);
            p 
+= 3;
            memcpy(p, it
->second.data, it->second.len);
        }
        
        p 
+= it->second.len;
        it
++;
    }

    
/* write to file in ultraedit hex-view format */
    
for (i = 0; i < length; i++) {
        
if (i == 0
            fprintf(fp, 
"%08Xh:", round);

        fprintf(fp, 
" %02X", pBytes[i]);

        
if (++round % 16 == 0 && i != length - 1) {
            fwrite(
" ; "13, fp);
            p 
= pBytes + i - 15;
            
for (j = 0; j < 16; j++
                fprintf(fp, 
"%c", (p[j] == 0 || p[j] == '\r' || p[j] == '\n')? '.' : p[j]);

            fprintf(fp, 
"\r\n%08Xh:", round);
        }
    }

    
if ((round = length % 16!= 0) {
        
for (i = 0; i < 16 - round; i++
            fwrite(
"   "13, fp);
        fwrite(
" ; "13, fp);
        p 
= pBytes + length - round;
        
for (i = 0; i < round; i++)
            fprintf(fp, 
"%c", (p[i] == 0 || p[i] == '\r' || p[i] == '\n'? '.' : p[i]);
    }

    delete pBytes;
    fclose(fp);
    
return true;
}

bool CISO8583::WriteToFile(LPCTSTR pszFile, FileType type)
{
    
if (type == CISO8583::XML)
        
return writeXML(pszFile);
    
else if (type == CISO8583::BIN)
        
return writeBIN(pszFile);
    
else if (type == CISO8583::HEX)
        
return writeHEX(pszFile);

    
return false;
}


/* Get message length in bytes */
int CISO8583::GetMessageLength()
{
    
int len = 0;
    map
<int, ISO8583FieldData>::iterator it = m_fields.begin();
    
while (it != m_fields.end()) {
        len 
= len + it->second.len + Tbl8583[it->first - 1].variable_flag;
        it
++;
    }
    
    
return len + 16;
}

CISO8583Writer::CISO8583Writer()
{
}

CISO8583Writer::
~CISO8583Writer()
{
    map
<int, ISO8583FieldData>::iterator it = m_fields.begin();
    
while (it != m_fields.end()) {
        delete it
->second.data;
        it
++;
    }
}



/* Copy message out */
int CISO8583Writer::CopyOut(BYTE *pOutBuf, int nBufLen)
{
    
int offset = 16;
    
if (NULL == pOutBuf || nBufLen < GetMessageLength())
        
return -1;
    
    
/* clear bitmap */
    memset((
void *)pOutBuf, 016);
    map
<int, ISO8583FieldData>::iterator it = m_fields.begin();
    
while (it != m_fields.end()) {
        
/* set bitmap */
        setBit(pOutBuf, it
->first);

        
/* copy data */
        
if (Tbl8583[it->first - 1].variable_flag == 0) {
            memcpy(pOutBuf 
+ offset, it->second.data, it->second.len);
            offset 
+= it->second.len;
        }
        
else if (Tbl8583[it->first - 1].variable_flag == 2) {
            _snprintf((
char *)(pOutBuf + offset), 2"%02d", it->second.len);
            memcpy(pOutBuf 
+ offset + 2, it->second.data, it->second.len);
            offset 
= offset + it->second.len + 2;
        }
        
else if (Tbl8583[it->first - 1].variable_flag == 3) {
            _snprintf((
char *)(pOutBuf + offset), 3"%03d", it->second.len);
            memcpy(pOutBuf 
+ offset + 3, it->second.data, it->second.len);
            offset 
= offset + it->second.len + 3;
        }

        it
++;
    }

    
return offset;
}

/* write specified field, if pFieldBuf is NULL then this field will be cleared */
const BYTE *CISO8583Writer::WriteField(int nField, int nFieldLen, BYTE *pFieldBuf)
{
    
if (nField > 128 || nField < 1)
        
throw "field should between 1 and 128";

    map
<int, ISO8583FieldData>::iterator it = m_fields.find(nField);
    
/* delete the specified field if it exists */
    
if (it != m_fields.end()) {
        delete it
->second.data;
        m_fields.erase(it);
    }

    
/* clear the specified field and return if pFieldBuf is NULL */
    
if (NULL == pFieldBuf) 
        
return NULL;

    
/* copy data */
    ISO8583FieldData field;
    field.len 
= nFieldLen;
    field.data 
= new BYTE[field.len];
    
if (NULL == field.data)
        
return NULL;

    memcpy(field.data, pFieldBuf, field.len);
    
/* add field */
    m_fields[nField] 
= field;
    
return field.data;
}



CISO8583Reader::CISO8583Reader()
{
}

CISO8583Reader::
~CISO8583Reader()
{
    m_fields.clear();
}

bool CISO8583Reader::ReadMessage(const BYTE *pMessage)
{
    
try {
        
return parseFields(pMessage);
    }
    
catch () {
        
return false;
    }
}


/* Get position and length for each field */
bool CISO8583Reader::parseFields(const BYTE *pMessage)
{
    
bool extensionMode = testBit(pMessage, 1);
    DWORD dwOffset 
= 16;
    BYTE len[
4];
    
/* Test bit pos 2 - 128 or 2 - 64 */
    
for (int i = 2; i <= 128 && extensionMode; i++) {
        
if (!testBit(pMessage, i)) continue;

        
/* find data position and length for each field */
        ISO8583FieldData field;
        
if (Tbl8583[i - 1].variable_flag == 0) {
            field.len 
= Tbl8583[i - 1].length;
            field.data 
= (BYTE *)pMessage + dwOffset;
            dwOffset 
+= field.len;
        }
        
else {
            memset(len, 
0sizeof(len));
            memcpy((
void *)len, (void *)(pMessage + dwOffset), Tbl8583[i - 1].variable_flag);
            field.len 
= atol((char *)len);
            field.data 
= (BYTE *)(pMessage + dwOffset + Tbl8583[i - 1].variable_flag);
            dwOffset 
= dwOffset + field.len + Tbl8583[i - 1].variable_flag;
        }

        m_fields[i] 
= field;
    }

    
return true;
}

/* Get fields number that is set in the bitmap, count should large than value return by FieldsCount() */
int CISO8583Reader::GetFields(int *fields, int count)
{
    
int fcount = m_fields.size() > count ? count : m_fields.size();
    map
<int, ISO8583FieldData>::iterator it = m_fields.begin();
    
for (int i = 0; i < fcount; i++) {
        fields[i] 
= it->first;
        it
++;
    }

    
return fcount;
}

/* Get fields count */
int CISO8583Reader::FieldsCount()
{
    
return m_fields.size();
}

/* Find to see whether the specified field exist */
bool CISO8583Reader::FieldExist(int nField)
{
    
return m_fields.find(nField) != m_fields.end();
}

/* Find to see whether all fields in pFields array exist */
int CISO8583Reader::FieldsExist(int *fields, int nCount)
{
    
for (int i = 0; i < nCount; i++) {
        
if (!FieldExist(fields[i]))
            
return fields[i];
    }

    
return 0;
}

/* Get field length exclusive the LLLVAR or LLVAR part */
int  CISO8583Reader::FieldLength(int nField)
{
    
if (nField > 128return -1;
    map
<int, ISO8583FieldData>::iterator it = m_fields.find(nField);
    
if (it == m_fields.end())
        
return -1;

    
/* substract the LLL or LL length */
    
return it->second.len - Tbl8583[nField - 1].variable_flag;
}

/* Get Field's data, not include the LL or LLL length value if it is varlength field */
int CISO8583Reader::ReadField(int nField, BYTE *pOutBuf, int nBufLen)
{
    map
<int, ISO8583FieldData>::iterator it = m_fields.find(nField);
    
if (it == m_fields.end())
        
return -1;

    
int nFieldLen = it->second.len;// - Tbl8583[nField - 1].variable_flag;
    if (nBufLen < it->second.len)
        
return -1;

    memcpy(pOutBuf, it
->second.data, nFieldLen);
    
return nFieldLen;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!