📄 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 + -