8583解析类

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 " 8 0 0 2 , NULL, 0 }, 
 
/*  FLD 02  */  { 0 , " PRIMARY ACCOUNT NUMBER " 22 0 2 0 , NULL, 0 }, 
 
/*  FLD 03  */  { 0 , " PROCESSING CODE " 6 0 0 0 , NULL, 0 }, 
 
/*  FLD 04  */  { 0 , " AMOUNT, TRANSACTION " 12 0 0 1 , NULL, 0 }, 
 
/*  FLD 05  */  { 0 , " NO USE " 12 0 0 0 , NULL, 0 }, 
 
/*  FLD 06  */  { 0 , " NO USE " 12 0 0 0 , NULL, 0 }, 
 
/*  FLD 07  */  { 0 , " TRANSACTION DATE AND TIME " 10 0 0 0 , NULL, 0 }, 
 
/*  FLD 08  */  { 0 , " NO USE " 8 0 0 0 , NULL, 0 }, 
 
/*  FLD 09  */  { 0 , " NO USE " 8 0 0 0 , NULL, 0 }, 
 
/*  FLD 10  */  { 0 , " NO USE " 8 0 0 0 , NULL, 0 }, 
 
/*  FLD 11  */  { 0 , " SYSTEM TRACE AUDIT NUMBER " 6 0 0 1 , NULL, 0 }, 
 
/*  FLD 12  */  { 0 , " TIME, LOCAL TRANSACTION " 6 0 0 0 , NULL, 0 }, 
 
/*  FLD 13  */  { 0 , " DATE, LOCAL TRANSACTION " 4 0 0 0 , NULL, 0 }, 
 
/*  FLD 14  */  { 0 , " DATE, EXPIRATION " 4 0 0 0 , NULL, 0 }, 
 
/*  FLD 15  */  { 0 , " DATE, SETTLEMENT " 4 0 0 0 , NULL, 0 }, 
 
/*  FLD 16  */  { 0 , " NO USE " 4 0 0 0 , NULL, 0 }, 
 
/*  FLD 17  */  { 0 , " DATE, CAPTURE " 4 0 0 0 , NULL, 0 }, 
 
/*  FLD 18  */  { 0 , " MERCHANT'S TYPE " 4 0 0 0 , NULL, 0 }, 
 
/*  FLD 19  */  { 0 , " NO USE " 3 0 0 0 , NULL, 0 }, 
 
/*  FLD 20  */  { 0 , " NO USE " 3 0 0 0 , NULL, 0 }, 
 
/*  FLD 21  */  { 0 , " NO USE " 3 0 0 0 , NULL, 0 }, 
 
/*  FLD 22  */  { 0 , " POINT OF SERVICE ENTRY MODE " 3 0 0 0 , NULL, 0 }, 
 
/*  FLD 23  */  { 0 , " NO USE " 3 0 0 0 , NULL, 0 }, 
 
/*  FLD 24  */  { 0 , " NO USE " 3 0 0 0 , NULL, 0 }, 
 
/*  FLD 25  */  { 0 , " POINT OF SERVICE CONDITION CODE " 2 0 0 0 , NULL, 0 }, 
 
/*  FLD 26  */  { 0 , " NO USE " 2 0 0 0 , NULL, 0 }, 
 
/*  FLD 27  */  { 0 , " NO USE " 1 0 0 0 , NULL, 0 }, 
 
/*  FLD 28  */  { 0 , " field27 " 6 0 0 0 , NULL, 0 }, 
 
/*  FLD 29  */  { 0 , " NO USE " 8 0 1 0 , NULL, 0 }, 
 
/*  FLD 30  */  { 0 , " NO USE " 8 0 1 0 , NULL, 0 }, 
 
/*  FLD 31  */  { 0 , " NO USE " 8 0 1 0 , NULL, 0 }, 
 
/*  FLD 32  */  { 0 , " ACQUIRER INSTITUTION ID. CODE " 11 0 2 0 , NULL, 0 }, 
 
/*  FLD 33  */  { 0 , " FORWARDING INSTITUTION ID. CODE " 11 0 2 0 , NULL, 0 }, 
 
/*  FLD 34  */  { 0 , " NO USE " 28 0 2 0 , NULL, 0 }, 
 
/*  FLD 35  */  { 0 , " TRACK 2 DATA " 37 0 2 0 , NULL, 0 }, 
 
/*  FLD 36  */  { 0 , " TRACK 3 DATA " , 104 0 3 0 , NULL, 0 }, 
 
/*  FLD 37  */  { 0 , " RETRIEVAL REFERENCE NUMBER " 12 0 0 0 , NULL, 0 }, 
 
/*  FLD 38  */  { 0 , " AUTH. IDENTIFICATION RESPONSE " 6 0 0 0 , NULL, 0 }, 
 
/*  FLD 39  */  { 0 , " RESPONSE CODE " 2 0 0 0 , NULL, 0 }, 
 
/*  FLD 40  */  { 0 , " NO USE " 3 0 0 0 , NULL, 0 }, 
 
/*  FLD 41  */  { 0 , " CARD ACCEPTOR TERMINAL ID. " 8 0 0 0 , NULL, 0 }, 
 
/*  FLD 42  */  { 0 , " CARD ACCEPTOR IDENTIFICATION CODE " 15 0 0 0 , NULL, 0 }, 
 
/*  FLD 43  */  { 0 , " CARD ACCEPTOR NAME LOCATION " 40 0 0 0 , NULL, 0 }, 
 
/*  FLD 44  */  { 0 , " ADDITIONAL RESPONSE DATA " 25 0 2 0 , NULL, 0 }, 
 
/*  FLD 45  */  { 0 , " NO USE " 76 0 2 0 , NULL, 0 }, 
 
/*  FLD 46  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 47  */  { 0 , " field47 " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 48  */  { 0 , " ADDITIONAL DATA --- PRIVATE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 49  */  { 0 , " CURRENCY CODE,TRANSACTION " 3 0 0 0 , NULL, 0 }, 
 
/*  FLD 50  */  { 0 , " CURRENCY CODE,SETTLEMENT " 3 0 0 0 , NULL, 0 }, 
 
/*  FLD 51  */  { 0 , " NO USE " 3 0 0 0 , NULL, 0 }, 
 
/*  FLD 52  */  { 0 , " PERSONAL IDENTIFICATION NUMBER DATA " 8 0 0 2 , NULL, 0 }, 
 
/*  FLD 53  */  { 0 , " SECURITY RELATED CONTROL INformATION " 16 0 0 0 , NULL, 0 }, 
 
/*  FLD 54  */  { 0 , " ADDITIONAL AMOUNTS " , 120 0 3 0 , NULL, 0 }, 
 
/*  FLD 55  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 56  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 57  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 58  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 59  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 60  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 61  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 62  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 63  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 64  */  { 0 , " MESSAGE AUTHENTICATION CODE FIELD " 8 0 0 2 , NULL, 0 }, 
 
/*  FLD 65  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 66  */  { 0 , " NO USE " 1 0 0 0 , NULL, 0 }, 
 
/*  FLD 67  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 68  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 69  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 70  */  { 0 , " SYSTEM MANAGEMENT INformATION CODE " 3 0 0 0 , NULL, 0 }, 
 
/*  FLD 71  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 72  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 73  */  { 0 , " NO USE " 6 0 0 0 , NULL, 0 }, 
 
/*  FLD 74  */  { 0 , " NUMBER OF CREDITS " 10 0 0 0 , NULL, 0 }, 
 
/*  FLD 75  */  { 0 , " REVERSAL NUMBER OF CREDITS " 10 0 0 0 , NULL, 0 }, 
 
/*  FLD 76  */  { 0 , " NUMBER OF DEBITS " 10 0 0 0 , NULL, 0 }, 
 
/*  FLD 77  */  { 0 , " REVERSAL NUMBER OF DEBITS " 10 0 0 0 , NULL, 0 }, 
 
/*  FLD 78  */  { 0 , " NUMBER OF TRANSFER " 10 0 0 0 , NULL, 0 }, 
 
/*  FLD 79  */  { 0 , " REVERSAL NUMBER OF TRANSFER " 10 0 0 0 , NULL, 0 }, 
 
/*  FLD 80  */  { 0 , " NUMBER OF INQUIRS " 10 0 0 0 , NULL, 0 }, 
 
/*  FLD 81  */  { 0 , " AUTHORIZATION NUMBER " 10 0 0 0 , NULL, 0 }, 
 
/*  FLD 82  */  { 0 , " NO USE " 12 0 0 0 , NULL, 0 }, 
 
/*  FLD 83  */  { 0 , " CREDITS,TRANSCATION FEEAMOUNT " 12 0 0 0 , NULL, 0 }, 
 
/*  FLD 84  */  { 0 , " NO USE " 12 0 0 0 , NULL, 0 }, 
 
/*  FLD 85  */  { 0 , " DEBITS,TRANSCATION FEEAMOUNT " 12 0 0 0 , NULL, 0 }, 
 
/*  FLD 86  */  { 0 , " AMOUNT OF CREDITS " 16 0 0 0 , NULL, 0 }, 
 
/*  FLD 87  */  { 0 , " REVERSAL AMOUNT OF CREDITS " 16 0 0 0 , NULL, 0 }, 
 
/*  FLD 88  */  { 0 , " AMOUNT OF DEBITS " 16 0 0 0 , NULL, 0 }, 
 
/*  FLD 89  */  { 0 , " REVERSAL AMOUNT OF DEBITS " 16 0 0 0 , NULL, 0 }, 
 
/*  FLD 90  */  { 0 , " ORIGINAL DATA ELEMENTS " 42 0 0 0 , NULL, 0 }, 
 
/*  FLD 91  */  { 0 , " FILE UPDATE CODE " 1 0 0 0 , NULL, 0 }, 
 
/*  FLD 92  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 93  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 94  */  { 0 , " SERVICE INDICATOR " 7 0 0 0 , NULL, 0 }, 
 
/*  FLD 95  */  { 0 , " REPLACEMENT AMOUNTS " 42 0 0 0 , NULL, 0 }, 
 
/*  FLD 96  */  { 0 , " NO USE " 8 0 0 0 , NULL, 0 }, 
 
/*  FLD 97  */  { 0 , " AMOUNT OF NET SETTLEMENT " 16 0 0 0 , NULL, 0 }, 
 
/*  FLD 98  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 99  */  { 0 , " SETTLEMENT INSTITUTION ID " 11 0 2 0 , NULL, 0 }, 
 
/*  FLD 100  */  { 0 , " RECVEING INSTITUTION ID " 11 0 2 0 , NULL, 0 }, 
 
/*  FLD 101  */  { 0 , " FILENAME " 17 0 2 0 , NULL, 0 }, 
 
/*  FLD 102  */  { 0 , " ACCOUNT IDENTIFICATION1 " 28 0 2 0 , NULL, 0 }, 
 
/*  FLD 103  */  { 0 , " ACCOUNT IDENTIFICATION2 " 28 0 2 0 , NULL, 0 }, 
 
/*  FLD 104  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 105  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 106  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 107  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 108  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 109  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 110  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 111  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 112  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 113  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 114  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 115  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 116  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 117  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 118  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 119  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 120  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 121  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 122  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 123  */  { 0 , " NEW PIN DATA " 8 0 3 2 , NULL, 0 }, 
 
/*  FLD 124  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 125  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 126  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 127  */  { 0 , " NO USE " 999 0 3 0 , NULL, 0 }, 
 
/*  FLD 128  */  { 0 , " MESSAGE AUTHENTICATION CODE FIELD " 8 0 0 2 , 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, 
0 sizeof (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, 
0 sizeof (bitmap));
    map
< int , ISO8583FieldData > ::iterator it  =  m_fields.begin();
    
while  (it  !=  m_fields.end()) {
        setBit(bitmap, it
-> first);
        it
++ ;
    }
    
    fwrite(bitmap, 
1 sizeof (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(
"  ;  " 1 3 , 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(
"     " 1 3 , fp);
        fwrite(
"  ;  " 1 3 , 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,  0 16 );
    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, 
0 sizeof (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  >   128 return   - 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;
}

你可能感兴趣的:(解析)