home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
c't freeware shareware 1997
/
CT_SW_97.ISO
/
mac
/
Software
/
finanzen
/
win95
/
quotenow.exe
/
data.z
/
tradepbs.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1997-04-06
|
19KB
|
779 lines
// tradepbs.cpp : Defines the initialization routines for the DLL.
//
/*
QuotesNow! is trademark and (C)opyright 1996
by Federated Telecommunications Corp. and
Windows Xpert Systems
You or any entity using this code must purchase a copy of QuotesNow!
(tm) for each person that will use this source code. The purchaser/
registered user may freely distribute compiled derivative
(machine readable code only) versions of this code.
Registered Users (Users who have purchased the QuotesNow! (tm) program
from Federated Telecommunications Corp. or Windows Xpert Systems)
Once you have purchased the application, you may use one copy
of the program. The program is licensed to YOU (the purchaser/user
by name), no other user may legally use the software.
It is understood that you use the software at your own risk.
Registered Users may produce compiled derivative works of the
source code provided with this program as long as it's intended use
is only for use with the QuotesNow! (tm) program by Windows Xpert Systems
and Federated Telecommunications Corp. The derivative source code
may be distributed as long as all notices in all code, including
copyright and trademark notices remain intact and the author makes it
clear that the source code may only be used to work with the
QuotesNow! (tm) program by Windows Xpert Systems and
Federated Telecommunications, and that any user of the source code must
purchase the QuotesNow! (tm) program to use it. The header files
(files ending in .h, such as server.h) may not be distributed
seperately from the QuotesNow! (tm) program.
The add-in .SRV/.DLL source code itself may only be distributed
as a derivative work as mentioned above
(with all notices intact and the author notifying any potential
user of the required uses of the source code - only a Registered
QuotesNow! (tm) user may distribute/use the Source code derivative
work.)
*/
#include "stdafx.h"
#include <afxdllx.h>
#include "resource.h"
#include "../../server.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//stock parsing callback declare
__declspec(dllexport) ParseTradePBSSServer(char *buffer,
DWORD len,
CPUBSTOCKOBJ &pobjArray,
int iIgnore,CServerObject *srvo);
//option parsing callback declare
__declspec(dllexport) ParseTradePBSOServer(char *buffer,
DWORD len,
CPUBSTOCKOBJ &pobjArray,
int iIgnore,CServerObject *srvo);
__declspec(dllexport) int QuickenFileFormat(CPUBSTOCKOBJ &aStocks,
HANDLE fp,DWORD dwSettings);
//defines to simplify calling helper functions
#define GetTagS (*wxsinfo.lpfnGetTagS)
#define GetTableItems (*wxsinfo.lpfnGetTableItems)
#define SplitStringDash (*wxsinfo.lpfnSplitStringDash)
#define FixupNumber (*wxsinfo.lpfnFixupNumber)
#define FindDataField (*wxsinfo.lpfnFindDataField)
#define GetNumberAndFraction (*wxsinfo.lpfnGetNumberAndFraction)
#define RegisterFileFormat (*wxsinfo.lpfnRegisterFileFormat)
#define RegisterImportFileFormat (*wxsinfo.lpfnRegisterImportFileFormat)
HINSTANCE g_hInstance;
//globally defined structure so that our helper function
//macros will work
WXSINFO wxsinfo;
static AFX_EXTENSION_MODULE TradepbsDLL = { NULL, NULL };
extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
TRACE0("TRADEPBS.DLL Initializing!\n");
g_hInstance=hInstance;
// Extension DLL one-time initialization
AfxInitExtensionModule(TradepbsDLL, hInstance);
// Insert this DLL into the resource chain
new CDynLinkLibrary(TradepbsDLL);
}
else if (dwReason == DLL_PROCESS_DETACH)
{
TRACE0("TRADEPBS.DLL Terminating!\n");
}
return 1; // ok
}
//WxsGetApiVersion required function
extern "C" __declspec(dllexport) float WxsGetApiVersion()
{
return (float)WXSSERVER_APIVERSION;
}
//WxsServerInit required function
extern "C" __declspec(dllexport) BOOL WxsServerInit(CServerObject *srv,float fApiVersion,int iCServerObject,
WXSINFO *pwxs)
{
HINSTANCE hInst=AfxGetResourceHandle();
//This is true only if the client exactly matches how the .DLL
//was compiled. (This can be different when the .DLL
//version doesn't match the client version) Though it could be
//the same. Depends on whether or not we have made changes to
//the CServerObject data strcuture for a prticular version
//this test is only for our sanity test purposes.
//If possible you should handle older versions of the client
//so this ASSERT(sizeof(CServerObject)==iCServerObject);
//should not be included at runtime and you may need to remove
//it for testing purposes to test with different versions of
//the client
if (sizeof(CServerObject)!=iCServerObject)
{
//ASSERT(sizeof(CServerObject)==iCServerObject);
return FALSE;
}
//set the resourceHandle to point to this .DLL
AfxSetResourceHandle(g_hInstance);
//save the helper function pointers in the
//global structure. Need to save these here as the
// pointer to the WXSINFO structure (pwxs) will be invalid
//after this function completes.
wxsinfo.lpfnGetTagS=pwxs->lpfnGetTagS;
wxsinfo.lpfnGetTableItems=pwxs->lpfnGetTableItems;
wxsinfo.lpfnSplitStringDash=pwxs->lpfnSplitStringDash;
wxsinfo.lpfnFixupNumber=pwxs->lpfnFixupNumber;
wxsinfo.lpfnFindDataField=pwxs->lpfnFindDataField;
wxsinfo.lpfnGetNumberAndFraction=pwxs->lpfnGetNumberAndFraction;
wxsinfo.lpfnRegisterFileFormat=pwxs->lpfnRegisterFileFormat;
//store the strings and data into the server object
//so it can be returned to the client
srv->m_dwSize=sizeof(CServerObject);
//Server name :Trade PBS
srv->m_sServerName.LoadString(IDS_NNAME_TRADEPBS);
//Server www address : www.tradepbs.com
srv->m_httpAddress.LoadString(IDS_SSERVER_TRADEPBS);
//stock quote format string
srv->m_httpSQuoteFormat.LoadString(IDS_SSERVER_TRADEPBS_REQ);
//option quot format string
srv->m_httpOQuoteFormat.LoadString(IDS_OSERVER_TRADEPBS_REQ);
srv->m_httpGraphFormat="";
srv->m_httpNewsFormat="";
srv->m_httpHistoricalDataFormat="";
srv->m_httpSTickerLookupFormat="";
//option lookup http address
srv->m_httpOSymbolLookup.LoadString(IDS_OSRV_TRADEPBS_OLOOKUP);
srv->m_httpStockHomePageFormat="";
//stock parse callback
srv->m_lpParseCallback=(SERVERPARSE_CALLBACK)ParseTradePBSSServer;
//option parse callback
srv->m_lpOParseCallback=(SERVERPARSE_CALLBACK)ParseTradePBSOServer;
srv->m_lpStockUpdate=NULL;
//server can handle options and stock quotes
srv->m_srvCaps=CServerObject::SRV_CAP_SQUOTE|
CServerObject::SRV_CAP_OQUOTE|
CServerObject::SRV_CAP_OSYMBOLLOOKUP;
srv->m_dwBufferSize=0; //use default buffer
//if we know we can handle older versions of API with this
//.DLL we can assign m_fApiVersion=fApiVersion passed in
//so that the client won't complain about an inproper version
srv->m_fApiVersion=(float)WXSSERVER_APIVERSION;
CString sQuicken;
CString sQFmt;
sQFmt.LoadString(IDS_SQUICKENFILEEXT);
sQuicken.LoadString(IDS_SQUICKENFORMAT);
RegisterFileFormat((LPCTSTR)sQuicken,
(FILEEXPORT_CALLBACK)QuickenFileFormat,
(LPCTSTR)sQFmt,(LPCTSTR)srv->m_sServerName);
//restore the resource handle back to the client .DLL
AfxSetResourceHandle(hInst);
return TRUE;
}
#define TABLE_ROW 6
#define TABLE_ITEMS 11
#define DTABLE_NAME 0
#define DTABLE_PRICE 1
#define DTABLE_DCHANGE 2
#define DTABLE_HIGH 3
#define DTABLE_LOW 4
#define DTABLE_VOLUME 5
#define DTABLE_BID 6
#define DTABLE_ASK 7
#define DTABLE_52HIGH 8
#define DTABLE_52LOW 9
#define DTABLE_LASTUPDATED 10
const UINT aTradeItems[TABLE_ITEMS][TABLE_ROW]= {
//object,table,level,subtable,row,column
{DTABLE_NAME,1,0,0,0,1},
{DTABLE_LASTUPDATED,1,0,0,0,3},
{DTABLE_PRICE,2,0,0,2,2},
{DTABLE_DCHANGE,2,0,0,2,3},
{DTABLE_BID,10,0,0,0,0}, //no bid invalid server doesn't support
{DTABLE_ASK,10,0,0,0,0}, //no ask invalid server doesn't support
{DTABLE_VOLUME,2,0,0,2,8},
{DTABLE_HIGH,2,0,0,2,6},
{DTABLE_LOW,2,0,0,2,7},
{DTABLE_52HIGH,3,0,0,2,7},
{DTABLE_52LOW,3,0,0,2,8}
};
#define TITEM 0
#define TMTABLE 1
#define TLEVEL 2
#define TTABLE 3
#define TROW 4
#define TCOLUMN 5
struct TRADETABLEDATA {
CPubSrvStockObj *sobj;
int iIgnore;
};
BOOL GetTradeTableCallback(UINT uMTable,UINT uLevel,UINT uSubTable,
UINT uRow,UINT uColumn,
char *pStart,char *pEnd,LONG lData)
{
int x;
BOOL bFound=FALSE;
int bRet=TRUE;
int iRet=0;
#ifdef _DEBUG
TRACE("Table: %d, Level:%d, SubTable:%d, Row:%d, Column:%d\n",uMTable,uLevel,uSubTable,uRow,uColumn);
#endif
for (x=0; x<TABLE_ITEMS; x++)
if (aTradeItems[x][TMTABLE]==uMTable && //table
aTradeItems[x][TLEVEL]==uLevel && //level
aTradeItems[x][TTABLE]==uSubTable && //subtable
aTradeItems[x][TROW]==uRow && //row
aTradeItems[x][TCOLUMN]==uColumn) //column
{
bFound=TRUE;
break;
}
if (!bFound)
return TRUE;
char szTemp[256];
char szData[256];
CString sData;
char *end;
char *p=pStart;
float fValue=(float)0.0;
TRADETABLEDATA *tdp=(TRADETABLEDATA *)lData;
CPubSrvStockObj *sobj=(CPubSrvStockObj *)tdp->sobj;
int iIgnore=tdp->iIgnore;
sData="";
while (NULL!=*p && p<pEnd)
if (NULL==(p=FindDataField(p,&end)))
{
//error getting the number and fraction
TRACE("Error FindDataField file: %s. FindAndGetNumber Line:%d\n",__FILE__,__LINE__);
//exit out of switch, no data in field
} else {
UINT len=end-p;
if (end<=pEnd)
{
lstrcpyn(szTemp,p,((len+1) > sizeof(szTemp)) ? sizeof(szTemp) : (len+1));
sData=sData+szTemp;
sData=sData+" ";
}
p=end;
}
sData.TrimLeft();
sData.TrimRight();
lstrcpy(szData,(LPCTSTR)sData);
switch (aTradeItems[x][TITEM])
{
case DTABLE_NAME:
sobj->m_sName.Format("%s",szData);
break;
case DTABLE_PRICE:
fValue=(float)0.0;
FixupNumber(sData);
lstrcpy(szData,(LPCTSTR)sData);
iRet=GetNumberAndFraction(szData,NULL,fValue);
sobj->m_fPrice=(-1==iRet) ? (float)0.0 : fValue;
break;
case DTABLE_DCHANGE:
{
CString s;
s=szData;
fValue=(float)0.0;
FixupNumber(s);
lstrcpy(szData,(LPCTSTR)s);
iRet=GetNumberAndFraction(szData,NULL,fValue);
sobj->m_fChange=(-1==iRet) ? (float)0.0 : fValue;
}
break;
case DTABLE_HIGH:
{
fValue=(float)0.0;
FixupNumber(sData);
lstrcpy(szData,(LPCTSTR)sData);
iRet=GetNumberAndFraction(szData,NULL,fValue);
sobj->m_fHigh=(-1==iRet) ? (float)0.0 : fValue;
}
break;
case DTABLE_LOW:
fValue=(float)0.0;
FixupNumber(sData);
lstrcpy(szData,(LPCTSTR)sData);
iRet=GetNumberAndFraction(szData,NULL,fValue);
sobj->m_fLow=(-1==iRet) ? 0 : fValue;
break;
case DTABLE_VOLUME:
fValue=(float)0.0;
iRet=GetNumberAndFraction(szData,NULL,fValue);
sobj->m_nVolume=(-1==iRet) ? 0 : (UINT)fValue;
break;
case DTABLE_BID:
fValue=(float)0.0;
FixupNumber(sData);
lstrcpy(szData,(LPCTSTR)sData);
iRet=GetNumberAndFraction(szData,NULL,fValue);
sobj->m_fBid=(-1==iRet) ? (float)0.0 : fValue;
break;
case DTABLE_ASK:
fValue=(float)0.0;
FixupNumber(sData);
lstrcpy(szData,(LPCTSTR)sData);
iRet=GetNumberAndFraction(szData,NULL,fValue);
sobj->m_fAsk=(-1==iRet) ? (float)0.0 : fValue;
break;
case DTABLE_52HIGH:
{
fValue=(float)0.0;
FixupNumber(sData);
lstrcpy(szData,(LPCTSTR)sData);
iRet=GetNumberAndFraction(szData,NULL,fValue);
sobj->m_fYearHigh=(-1==iRet) ? (float)0.0 : fValue;
}
break;
case DTABLE_52LOW:
iRet=GetNumberAndFraction(szData,NULL,fValue);
sobj->m_fYearLow=(-1==iRet) ? (float)0.0 : fValue;
break;
case DTABLE_LASTUPDATED:
//hande time here
break;
}
if (-1==iRet)
{
#ifdef _DEBUG
TRACE("iRet=-1: item:%d, File: %s, Line:%d\n",aTradeItems[x][TITEM],
__FILE__,__LINE__);
#endif
return FALSE; //stop callback and return error
}
return TRUE;
}
//handles stock quote parsing
__declspec(dllexport) ParseTradePBSSServer(char *buffer,
DWORD len,
CPUBSTOCKOBJ &pobjArray,
int iIgnore,CServerObject *srvo)
{
CString sTest,sTest2;
TRADETABLEDATA td;
CPubSrvStockObj *sobj=(CPubSrvStockObj *)&pobjArray[0];
sTest2=sTest=sobj->m_sSymbol;
sTest.MakeUpper();
sTest2.MakeLower();
if (!strstr(buffer,(LPCTSTR)sTest) &&
!strstr(buffer,(LPCTSTR)sTest2))
{
//Probably an error -- could not find the symbol anywhere
// in the HTML page as upper or lowercase
TRACE("Initial symbol check. TRADEPBS: File: %s, Line:%d\n",__FILE__,__LINE__);
return PARSERET_ERROR;
}
td.sobj=sobj;
td.iIgnore=iIgnore;
if (FALSE==GetTableItems(buffer,(GTI_CALLBACK)GetTradeTableCallback,(LONG)&td))
return PARSERET_ERROR;
return PARSERET_OK;
}
//option table format
const UINT aOTradeItems[TABLE_ITEMS][TABLE_ROW]= {
//object,table,level,subtable,row,column
{DTABLE_NAME,2,0,0,0,1},
{DTABLE_LASTUPDATED,1,0,0,1,2},
{DTABLE_PRICE,3,0,0,2,2},
{DTABLE_DCHANGE,3,0,0,2,3},
{DTABLE_BID,10,0,0,0,0}, //no bid invalid
{DTABLE_ASK,10,0,0,0,0}, //no ask invalid
{DTABLE_VOLUME,3,0,0,2,8},
{DTABLE_HIGH,3,0,0,2,6},
{DTABLE_LOW,3,0,0,2,7},
{DTABLE_52HIGH,10,0,0,2,7}, // NO 52high invalid
{DTABLE_52LOW,10,0,0,2,8} //NO 52 week low invalid
};
//Option table callback
BOOL GetTradeOTableCallback(UINT uMTable,UINT uLevel,UINT uSubTable,
UINT uRow,UINT uColumn,
char *pStart,char *pEnd,LONG lData)
{
int x;
BOOL bFound=FALSE;
int bRet=TRUE;
int iRet=0;
#ifdef _DEBUG
TRACE("Table: %d, Level:%d, SubTable:%d, Row:%d, Column:%d\n",uMTable,uLevel,uSubTable,uRow,uColumn);
#endif
for (x=0; x<TABLE_ITEMS; x++)
if (aOTradeItems[x][TMTABLE]==uMTable && //table
aOTradeItems[x][TLEVEL]==uLevel && //level
aOTradeItems[x][TTABLE]==uSubTable && //subtable
aOTradeItems[x][TROW]==uRow && //row
aOTradeItems[x][TCOLUMN]==uColumn) //column
{
bFound=TRUE;
break;
}
if (!bFound)
return TRUE;
char szTemp[256];
char szData[256];
CString sData;
char *end;
char *p=pStart;
float fValue=(float)0.0;
TRADETABLEDATA *tdp=(TRADETABLEDATA *)lData;
CPubSrvStockObj *sobj=(CPubSrvStockObj *)tdp->sobj;
int iIgnore=tdp->iIgnore;
sData="";
while (NULL!=*p && p<pEnd)
if (NULL==(p=FindDataField(p,&end)))
{
//error getting the number and fraction
TRACE("Error FindDataField file: %s. FindAndGetNumber Line:%d\n",__FILE__,__LINE__);
//exit out of switch, no data in field
} else {
UINT len=end-p;
if (end<=pEnd)
{
lstrcpyn(szTemp,p,((len+1) > sizeof(szTemp)) ? sizeof(szTemp) : (len+1));
sData=sData+szTemp;
sData=sData+" ";
}
p=end;
}
sData.TrimLeft();
sData.TrimRight();
lstrcpy(szData,(LPCTSTR)sData);
switch (aTradeItems[x][TITEM])
{
case DTABLE_NAME:
sobj->m_sName.Format("%s",szData);
break;
case DTABLE_PRICE:
fValue=(float)0.0;
FixupNumber(sData);
lstrcpy(szData,(LPCTSTR)sData);
iRet=GetNumberAndFraction(szData,NULL,fValue);
sobj->m_fPrice=(-1==iRet) ? (float)0.0 : fValue;
break;
case DTABLE_DCHANGE:
{
CString s;
s=szData;
fValue=(float)0.0;
FixupNumber(s);
lstrcpy(szData,(LPCTSTR)s);
iRet=GetNumberAndFraction(szData,NULL,fValue);
sobj->m_fChange=(-1==iRet) ? (float)0.0 : fValue;
}
break;
case DTABLE_HIGH:
{
fValue=(float)0.0;
FixupNumber(sData);
lstrcpy(szData,(LPCTSTR)sData);
iRet=GetNumberAndFraction(szData,NULL,fValue);
sobj->m_fHigh=(-1==iRet) ? (float)0.0 : fValue;
}
break;
case DTABLE_LOW:
fValue=(float)0.0;
FixupNumber(sData);
lstrcpy(szData,(LPCTSTR)sData);
iRet=GetNumberAndFraction(szData,NULL,fValue);
sobj->m_fLow=(-1==iRet) ? 0 : fValue;
break;
case DTABLE_VOLUME:
fValue=(float)0.0;
iRet=GetNumberAndFraction(szData,NULL,fValue);
sobj->m_nVolume=(-1==iRet) ? 0 : (UINT)fValue;
break;
case DTABLE_BID:
fValue=(float)0.0;
FixupNumber(sData);
lstrcpy(szData,(LPCTSTR)sData);
iRet=GetNumberAndFraction(szData,NULL,fValue);
sobj->m_fBid=(-1==iRet) ? (float)0.0 : fValue;
break;
case DTABLE_ASK:
fValue=(float)0.0;
FixupNumber(sData);
lstrcpy(szData,(LPCTSTR)sData);
iRet=GetNumberAndFraction(szData,NULL,fValue);
sobj->m_fAsk=(-1==iRet) ? (float)0.0 : fValue;
break;
case DTABLE_52HIGH:
{
fValue=(float)0.0;
FixupNumber(sData);
lstrcpy(szData,(LPCTSTR)sData);
iRet=GetNumberAndFraction(szData,NULL,fValue);
sobj->m_fYearHigh=(-1==iRet) ? (float)0.0 : fValue;
}
break;
case DTABLE_52LOW:
iRet=GetNumberAndFraction(szData,NULL,fValue);
sobj->m_fYearLow=(-1==iRet) ? (float)0.0 : fValue;
break;
case DTABLE_LASTUPDATED:
sobj->m_sTime=sData;
iRet=1;
//hande time here
break;
}
if (-1==iRet)
{
#ifdef _DEBUG
TRACE("iRet=-1: item:%d, File: %s, Line:%d\n",aTradeItems[x][TITEM],
__FILE__,__LINE__);
#endif
return FALSE; //stop callback and return error
}
return TRUE;
}
//Handles Option Parsing
__declspec(dllexport) ParseTradePBSOServer(char *buffer,
DWORD len,
CPUBSTOCKOBJ &pobjArray,
int iIgnore,CServerObject *srvo)
{
CString sTest,sTest2;
TRADETABLEDATA td;
CPubSrvStockObj *sobj=(CPubSrvStockObj *)&pobjArray[0];
sTest2=sTest=sobj->m_sSymbol;
sTest.MakeUpper();
sTest2.MakeLower();
if (!strstr(buffer,(LPCTSTR)sTest) &&
!strstr(buffer,(LPCTSTR)sTest2))
{
//Probably an error -- could not find the symbol anywhere
// in the HTML page as upper or lowercase
TRACE("Initial symbol check. TRADEPBS: File: %s, Line:%d\n",__FILE__,__LINE__);
return PARSERET_ERROR;
}
td.sobj=sobj;
td.iIgnore=iIgnore;
if (FALSE==GetTableItems(buffer,(GTI_CALLBACK)GetTradeOTableCallback,(LONG)&td))
return PARSERET_ERROR;
return PARSERET_OK;
}
#define BUFFER_SIZE 128
__declspec(dllexport) int QuickenFileFormat(CPUBSTOCKOBJ &aStocks,
HANDLE fp,DWORD dwSettings)
{
int iSize=aStocks.GetSize();
int i;
char szBuffer[BUFFER_SIZE];
DWORD dwBytes;
for (i=0; i<iSize; i++)
{
BOOL bRet;
//can't use a CTime in a .DLL so we'll use the
//integer items m_iDay,m_iMonth,m_iYear
sprintf(szBuffer,"%s,%.04f,%d/%d/%d\n",aStocks[i].m_sSymbol,
aStocks[i].m_fPrice,
aStocks[i].m_iDay,
aStocks[i].m_iMonth,
aStocks[i].m_iYear);
bRet=WriteFile(fp,szBuffer,lstrlen(szBuffer),&dwBytes,NULL);
if (!bRet)
return 0;
}
return 1;
}