📄 tw.cpp
字号:
// TW.cpp : implementation file
//
#include "stdafx.h"
#include "TW.h"
#include "SPTime.h"
#include "TSCache.h"
#include <math.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// TW Interface
static BYTE g_serial = 0x00;
static CTWStockArray g_serial_stocks[0x80];
static int g_serial_count[0x80];
BYTE GetNextSerial( TW_STOCK & stock, int count = 0 )
{
g_serial ++;
if( g_serial > 0x7f ) g_serial = 0x01;
if( g_serial >= 1 && g_serial <= 0x7f )
{
g_serial_stocks[g_serial].RemoveAll();
g_serial_stocks[g_serial].Add(stock);
g_serial_count[g_serial] = count;
}
return g_serial;
}
BYTE GetNextSerial( CTWStockArray & stocks, int count = 0 )
{
g_serial ++;
if( g_serial > 0x7f ) g_serial = 0x01;
if( g_serial >= 1 && g_serial <= 0x7f )
{
g_serial_stocks[g_serial].RemoveAll();
g_serial_stocks[g_serial].Copy(stocks);
g_serial_count[g_serial] = count;
}
return g_serial;
}
BOOL GetSerialStock( BYTE serial, TW_STOCK & stock, int * pcount = NULL )
{
if( serial >= 1 && serial <= 0x7f )
{
memset( &stock, 0, sizeof(stock) );
if( g_serial_stocks[serial].GetSize() > 0 )
memcpy( &stock, &(g_serial_stocks[serial].ElementAt(0)), sizeof(stock) );
if( pcount )
*pcount = g_serial_count[serial];
return TRUE;
}
return FALSE;
}
BOOL GetSerialStock( BYTE serial, CTWStockArray & stocks, int * pcount = NULL )
{
if( serial >= 1 && serial <= 0x7f )
{
stocks.RemoveAll();
if( g_serial_stocks[serial].GetSize() > 0 )
stocks.Copy( g_serial_stocks[serial] );
if( pcount )
*pcount = g_serial_count[serial];
return TRUE;
}
return FALSE;
}
int ConstructLength( TW_HEADER & header, int len )
{
CString string = itoa(len,header.m_length,16);
int nZeros = TW_LENGTH_LEN-string.GetLength();
int i;
for( i=0; i<nZeros; i++ )
for( i=0; i<TW_LENGTH_LEN; i++ )
{
if( i< nZeros )
header.m_length[i] = '0';
else
header.m_length[i] = string[i-nZeros];
}
return len;
}
int ConstructLoginBuffer( BYTE * buffer, size_t maxlen, LPCTSTR lpszUser, LPCTSTR lpszPasswd )
{
int nLen = 0;
int nLenUser = strlen(lpszUser);
int nLenPasswd = strlen(lpszPasswd);
TW_LOGIN packet;
memset(&packet,0,sizeof(packet));
packet.m_header.m_magic = TW_MAGIC;
if( maxlen < (int)(5 + sizeof(TW_HEADER) + nLenUser + nLenPasswd) )
{
nLen = 5 + sizeof(TW_HEADER);
return -1;
}
packet.m_name_len = (WORD)nLenUser;
memcpy( packet.m_data, lpszUser, nLenUser );
*(WORD*)(packet.m_data + nLenUser) = (WORD)nLenPasswd;
memcpy( packet.m_data + nLenUser + sizeof(WORD), lpszPasswd, nLenPasswd );
nLen = 5 + sizeof(TW_HEADER) + nLenUser + nLenPasswd;
ConstructLength( packet.m_header, nLen - sizeof(packet.m_header) );
if( buffer )
memcpy( buffer, &packet, nLen );
return nLen;
}
int ConstructAskInitBuffer( TW_ASK & ask )
{
memset( &ask, 0, sizeof(ask) );
ask.m_header.m_magic = TW_MAGIC;
const char * str_tag = "E013.45D013.04D022.03D043.20xcs1.00.is2.00";
ask.m_tag1 = 0x01;
ask.m_tag2 = 0x01;
ask.m_serial = 0x00;
ask.m_size = 0x0007;
CSPTime sptime = CTSCache::GetInstance().GetLocalLatest();
DWORD date = sptime.ToStockTimeDay();
memcpy( &(ask.m_stocks[0].m_type), &date, sizeof(date) );
// ask.m_stocks[0].m_type = 0xdc;
// ask.m_stocks[0].m_code[0] = (char)0xcc;
// ask.m_stocks[0].m_code[1] = 0x31;
// ask.m_stocks[0].m_code[2] = (char)0x01; //0xdc cc 31 01 = 20040924
ask.m_stocks[0].m_code[3] = 0x00;
ask.m_stocks[0].m_code[4] = 0x00;
ask.m_stocks[0].m_code[5] = 0x00;
memcpy( &(ask.m_stocks[1]), str_tag, strlen(str_tag) );
int ret = (6 + sizeof(ask.m_header) + sizeof(TW_STOCK) + strlen(str_tag));
ConstructLength( ask.m_header, ret - sizeof(ask.m_header) );
return ret;
}
int ConstructAskReportBuffer( TW_ASK & ask, TW_STOCK * pStocks, size_t size )
{
memset( &ask, 0, sizeof(ask) );
ask.m_header.m_magic = TW_MAGIC;
SHORT shortSize = (SHORT)size;
if( shortSize > sizeof(ask.m_stocks)/sizeof(TW_STOCK) )
shortSize = sizeof(ask.m_stocks)/sizeof(TW_STOCK);
if( shortSize <= 0 )
return -1;
ask.m_tag1 = 0x00;
ask.m_tag2 = 0x03;
CTWStockArray astocks;
astocks.SetSize( 0, size+1 );
for( size_t i=0; i<size; i++ ) astocks.Add( pStocks[i] );
ask.m_serial = GetNextSerial(astocks);
ask.m_size = shortSize;
if( size > sizeof(ask.m_stocks)/sizeof(TW_STOCK) )
return -1;
if( pStocks && shortSize > 0 )
memcpy( ask.m_stocks, pStocks, shortSize*sizeof(TW_STOCK) );
int ret = (6 + sizeof(ask.m_header) + shortSize * sizeof(TW_STOCK));
ConstructLength( ask.m_header, ret - sizeof(ask.m_header) );
return ret;
}
int ConstructAskMinuteBuffer( TW_ASK & ask, TW_STOCK * pStock )
{
memset( &ask, 0, sizeof(ask) );
ask.m_header.m_magic = TW_MAGIC;
ask.m_tag1 = 0x01;
ask.m_tag2 = 0x04;
ask.m_size = 0x0001;
memcpy( &(ask.m_stocks[0]), pStock, sizeof(TW_STOCK) );
ask.m_serial = GetNextSerial(ask.m_stocks[0]);
int ret = (6 + sizeof(ask.m_header) + sizeof(TW_STOCK));
ConstructLength( ask.m_header, ret - sizeof(ask.m_header) );
return ret;
}
int ConstructAskHistoryBuffer(TW_ASK & ask, TW_STOCK * pStock, int nKType, int nDataCount,
BOOL bChangeStock, BOOL bFirstRequest )
{
memset( &ask, 0, sizeof(ask) );
ask.m_header.m_magic = TW_MAGIC;
SHORT shortSize = (SHORT)nDataCount;
ask.m_tag1 = 0x00;
ask.m_tag2 = 0x09;
ask.m_size = - shortSize;
memcpy( &(ask.m_stocks[0]), pStock, sizeof(TW_STOCK) );
ask.m_serial = GetNextSerial(ask.m_stocks[0],nDataCount);
if( ktypeMin5 == nKType )
ask.m_tag1 |= 0x30;
else if( ktypeMin15 == nKType )
ask.m_tag1 |= 0x40;
else if( ktypeMin30 == nKType )
ask.m_tag1 |= 0x50;
else if( ktypeMin60 == nKType )
ask.m_tag1 |= 0x60;
else if( ktypeDay == nKType )
ask.m_tag1 |= 0x10;
else if( ktypeWeek == nKType )
ask.m_tag1 |= 0x80;
else if( ktypeMonth == nKType )
ask.m_tag1 |= 0x90;
if( bChangeStock )
ask.m_tag1 |= 0x03;
else if( bFirstRequest )
ask.m_tag1 |= 0x01;
else
ask.m_tag1 |= 0x02;
if( ktypeDay == nKType && bChangeStock )
ask.m_tag1 = 0x20;
int ret = (6 + sizeof(ask.m_header) + sizeof(TW_STOCK));
ConstructLength( ask.m_header, ret - sizeof(ask.m_header) );
return ret;
}
int ConstructAskMultisortBuffer( TW_ASK & ask, TW_STOCK * pStock )
{
memset( &ask, 0, sizeof(ask) );
ask.m_header.m_magic = TW_MAGIC;
BYTE type = typeshA;
if( pStock )
type = pStock->m_type;
TW_STOCK stock;
memset( &stock, 0, sizeof(stock) );
SHORT shortSize = 9;
ask.m_tag1 = 0x0a;
ask.m_tag2 = 0x08;
ask.m_size = - shortSize;
ask.m_stocks[0].m_type = type;
ask.m_stocks[0].m_code[0] = 0x06;
ask.m_stocks[0].m_code[1] = 0x00;
ask.m_stocks[0].m_code[2] = (char)0xff;
ask.m_stocks[0].m_code[3] = 0x01;
ask.m_stocks[0].m_code[4] = 0x00;
ask.m_stocks[0].m_code[5] = 0x00;
ask.m_serial = GetNextSerial(stock);
int ret = (6 + sizeof(ask.m_header) + sizeof(TW_STOCK));
ConstructLength( ask.m_header, ret - sizeof(ask.m_header) );
return ret;
}
int ConstructAskDetailBuffer( TW_ASK & ask, TW_STOCK * pStock )
{
memset( &ask, 0, sizeof(ask) );
ask.m_header.m_magic = TW_MAGIC;
ask.m_tag1 = 0x01;
ask.m_tag2 = 0x02;
ask.m_size = 0x0001;
memcpy( &(ask.m_stocks[0]), pStock, sizeof(TW_STOCK) );
ask.m_serial = GetNextSerial(ask.m_stocks[0]);
int ret = (6 + sizeof(ask.m_header) + sizeof(TW_STOCK));
ConstructLength( ask.m_header, ret - sizeof(ask.m_header) );
return ret;
}
int ConstructAskBaseBuffer( TW_ASK & ask, TW_STOCK * pStock )
{
memset( &ask, 0, sizeof(ask) );
ask.m_header.m_magic = TW_MAGIC;
ask.m_tag1 = 0x05;
ask.m_tag2 = 0x0b;
ask.m_size = 0x0005;
memcpy( &(ask.m_stocks[0]), pStock, sizeof(TW_STOCK) );
ask.m_serial = GetNextSerial(ask.m_stocks[0]);
int ret = (6 + sizeof(ask.m_header) + 5*sizeof(TW_STOCK));
ConstructLength( ask.m_header, ret - sizeof(ask.m_header) );
return ret;
}
size_t TryGetLength( TW_HEADER & header )
{
if( TW_MAGIC != header.m_magic || 0 != header.m_end )
return 0;
int len = (int)strtol(header.m_length,NULL,16);
if( len < 0 )
return 0;
return (size_t)len;
}
size_t TryGetLength( BYTE * buffer, size_t len )
{
if( len < sizeof(TW_HEADER) )
return 0;
TW_HEADER * pheader = (TW_HEADER*)buffer;
return TryGetLength( *pheader );
}
BOOL IsLoginOK( BYTE * buffer, size_t len )
{
if( len < sizeof(TW_ANS) )
return FALSE;
TW_ANS * pans = (TW_ANS *)buffer;
if( TW_MAGIC != pans->m_header.m_magic )
return FALSE;
if( 0x00 != pans->m_tag1 || 0x00 != pans->m_tag2 )
return FALSE;
return TRUE;
}
int TryGetInit( BYTE * buffer, size_t len, PRCV_DATA pRCV_DATA )
{
if( len < sizeof(TW_ANS) )
return 0;
TW_ANS * pans = (TW_ANS*)buffer;
if( TW_MAGIC != pans->m_header.m_magic )
return 0;
if( 0x02 != pans->m_tag1 || 0x01 != pans->m_tag2 )
return 0;
// get it, fill pRCV_DATA
size_t dataoffset = 469;
int datalen = len - dataoffset;
CSPTime tLatest( CSPTime::GetLatestTradeTime(time(NULL)) );
if( len > 128 )
{
DWORD date = (*(DWORD*)(buffer+45));
CSPTime sptime;
if( sptime.FromStockTimeDay( date ) )
tLatest = CSPTime(sptime.GetYear(),sptime.GetMonth(),sptime.GetDay(),9,15,0).GetTime();
}
if( pRCV_DATA && datalen >= (int)sizeof(TW_ANS_INIT) )
{
// 每组28个字节, 共XXXX组,最后以0xfdfdfdfd为结尾
TW_ANS_INIT * pinit = (TW_ANS_INIT*)(buffer+dataoffset);
int packetsize = datalen/(int)sizeof(TW_ANS_INIT);
memset( pRCV_DATA, 0, sizeof(RCV_DATA) );
pRCV_DATA->m_wDataType = RCV_REPORT; // no use
pRCV_DATA->m_nPacketNum = packetsize;
pRCV_DATA->m_bDISK = FALSE;
pRCV_DATA->m_pReport = new RCV_REPORT_STRUCTEx[packetsize];
memset( pRCV_DATA->m_pReport, 0, sizeof(RCV_REPORT_STRUCTEx)*packetsize );
for( int i=0;i <packetsize; i++ )
{
if( pinit[i].m_tag != TW_MAGIC_BYTE )
continue;
pRCV_DATA->m_pReport[i].m_cbSize = sizeof(RCV_REPORT_STRUCTEx);
pRCV_DATA->m_pReport[i].m_time = tLatest.GetTime();
pRCV_DATA->m_pReport[i].m_wMarket = (pinit[i].m_type & 0x20) ? SZ_MARKET_EX : SH_MARKET_EX;
pRCV_DATA->m_pReport[i].m_fLastClose = (float)(pinit[i].m_lastclose * 0.001);
strncpy(pRCV_DATA->m_pReport[i].m_szLabel, pinit[i].m_code,
min(sizeof(pRCV_DATA->m_pReport[i].m_szLabel),sizeof(pinit[i].m_code)));
strncpy(pRCV_DATA->m_pReport[i].m_szName, pinit[i].m_name,
min(sizeof(pRCV_DATA->m_pReport[i].m_szName),sizeof(pinit[i].m_name)));
strncpy(pRCV_DATA->m_pReport[i].m_szName+sizeof(pinit[i].m_name)+2, pinit[i].m_shortname,
min(sizeof(pRCV_DATA->m_pReport[i].m_szName)-sizeof(pinit[i].m_name)-2,sizeof(pinit[i].m_shortname)));
}
return len;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -