I am interested in hearing views on this new Module I am adding to an existing system to handle sale items from a 3rd party Software system. This system sends (XML) messages to our system, we need to look up our database and sell the item if present.
Before I continue going down the route I am, I would like opinions on the approach I am taking (be it right or wrong). I am restricted to using Visual Studio 6.0, non MFC application.
The code will start in RunSCO and proceeds from here.
A message like so will arrive:
<Layer Name="CORE"> <Message Name="SCOItem" SCO="true"> <Items> <Item PLU="101158489212" /> </Items> </Message> </Layer>
This will be picked up in the loop in SCO_Next_Item() @ string Msg = g_pclsMyCompanyMFController->HandleSCOMessage();
. From here we process the message and dispatch the correct method, which then replies with the correct XML response message.
There are many message types we can get <Message Name="SCOItem"
or <Message Name="SCOTender"
etc, I am handling these by reading the Name and mapping this to a function pointer.
// NewModule_CORE.cpp: implementation of the NewModule_CORE class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "NewModule_CORE.h" #include "MyCompanyMessaging.h" #include "MyCompanyMFController.h" #include "MyCompanyEposAddin.h" #include "Tenders.h" #include "MyCompanySHPLink.h" extern CMyCompanySHPLink *SHPHook; extern Tenders *tenderClass; extern MyCompanyEposAddin *cEposAddins; extern CMyCompanyMessaging g_MyCompanyMessaging; extern CMyCompanyMFController *g_pclsMyCompanyMFController; extern StockItem St; typedef struct { int iEndThread; } INFOPARAMS, *PINFOPARAMS; extern INFOPARAMS infoParams; typedef struct _EXCEPTION_POINTERS EXCEPTION_POINTERS, *PEXCEPTION_POINTERS; int __cdecl RecordExceptionInfo(PEXCEPTION_POINTERS data, const char *Message); extern VOID SHPHeartBeat_Thread( PVOID pvoid ); //Single cable thread extern void WriteMyCompanyLog(char *cTextToWrite); extern bool String_replace(std::string& str, const std::string& from, const std::string& to); extern void _Log_Sales_Entry_Exit(char *c); extern void HowMade(); extern void Get94CodeInfo(char *); extern int Check_Open_Ean(char *); ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// NewModule_CORE::NewModule_CORE() { g_pclsMyCompanyMFController = NULL; if ((g_pclsMyCompanyMFController = new CMyCompanyMFController())!=NULL) { g_MyCompanyMessaging.Init(); g_pclsMyCompanyMFController->MCSendFTVersionNo(); char cTheTillNo[3] = {0}; sprintf( cTheTillNo, "%02d", (int)_Get_Terminal_Number() ); g_pclsMyCompanyMFController->SetMsgID( "DTY" ); g_pclsMyCompanyMFController->GUISendFTTerminalNo( cTheTillNo ); } WriteMyCompanyVersions(); cEposAddins = new MyCompanyEposAddin(); tenderClass = new Tenders(); tenderClass->LoadTenders(); HowMade(); _Get_Open_Ean(); SHPHook = new CMyCompanySHPLink(); Sleep((DWORD)100); _beginthread(SHPHeartBeat_Thread, 0, &infoParams); ResetForNextSale(); } NewModule_CORE::~NewModule_CORE() { if (g_pclsMyCompanyMFController!=NULL) { delete g_pclsMyCompanyMFController; g_pclsMyCompanyMFController=NULL; } } void NewModule_CORE::ResetForNextSale() { SaleTotal = 0; SaleTotalPaid = 0; ItemCount = 0; blnSaleInProgress = false; } void NewModule_CORE::RunSCO() { __try { SCO_Main( ); } __except(RecordExceptionInfo(GetExceptionInformation(), "RunSCO")) { // Do nothing here - RecordExceptionInfo() has already done // everything that is needed. Actually this code won't even // get called unless you return EXCEPTION_EXECUTE_HANDLER from // the __except clause. } return; } void NewModule_CORE::SCO_Main() { while(true) //Needs to be changed to use the Exit condition { this->SCO_Next_Sale(); this->SCO_Next_Item(); this->SCO_CompleteSale(); this->ResetForNextSale(); } } void NewModule_CORE::SCO_Next_Sale() { blnSaleInProgress = true; } void NewModule_CORE::SCO_Next_Item() { string strKey = ""; while(blnSaleInProgress) { string Msg = g_pclsMyCompanyMFController->HandleSCOMessage(); g_pclsMyCompanyMFController->DoEvents(); if(Msg != "") { ProcessFunctionFromScoLayer(Msg); } Sleep((DWORD)10); } } void NewModule_CORE::SCO_CompleteSale() { g_pclsMyCompanyMFController->SCOSendEndTransaction("123456"); } bool NewModule_CORE::ProcessFunctionFromScoLayer(string Msg) { CMarkup XmlMsg; XmlMsg.SetDoc(Msg); XmlMsg.FindElem( "Layer" ); XmlMsg.IntoElem(); XmlMsg.FindElem( "Message" ); string strFunctionToExecute = XmlMsg.GetAttrib( "Name" ); struct STRUCTMESSHANDLERS { char cName[30]; void (NewModule_CORE::*pHandler)(CMarkup); }; #define NUM_SCOMESSAGES 2 STRUCTMESSHANDLERS aMessHandlers[NUM_SCOMESSAGES] = { { "SCOItem", NewModule_CORE::HandleSCOItem }, { "SCOTender", NewModule_CORE::SCOTender }, }; if (strFunctionToExecute != "") { void (NewModule_CORE::*pVPHandler)(CMarkup); for (int iMessageNo=0; iMessageNo<NUM_SCOMESSAGES; iMessageNo++) { if (strncmp(strFunctionToExecute.c_str(), aMessHandlers[iMessageNo].cName , strlen(aMessHandlers[iMessageNo].cName))==0) { pVPHandler = aMessHandlers[iMessageNo].pHandler; (this->*pVPHandler)( XmlMsg ); break; } } } return true; } void NewModule_CORE::HandleSCOItem(CMarkup XmlMsg) { XmlMsg.ResetPos(); XmlMsg.FindElem( "Layer" ); XmlMsg.IntoElem(); XmlMsg.FindElem( "Message" ); XmlMsg.IntoElem(); XmlMsg.FindElem( "Items" ); XmlMsg.IntoElem(); if(XmlMsg.FindElem( "Item" )) { string strPLU = XmlMsg.GetAttrib( "PLU" ); ItemInfo Item = GetItemInfo((char *)strPLU.c_str()); if(Item.bItemFound) { SCOprintf("Sale Item\r\n"); char cPrice[50] = {0}; sprintf(cPrice, "%ld", St.Price[0]); SaleTotal += St.Price[0]; double Qty = 1.0; char cText[100] = {0}; char cUnitPrice[20] = {0}; char cFullPrice[50] = {0}; _LongPrice_To_Char(St.Price[0], cUnitPrice); _LongPrice_To_Char(St.Price[0], cFullPrice); sprintf(cText, "% -14s %10.3f %10s %10s", Item.cItemCode, Qty, cUnitPrice, cFullPrice); MyCompany_Write_Journal("SALE", cText, NO_DATE); g_pclsMyCompanyMFController->SCOSendItemSold((char *)strPLU.c_str(), St.Des, cPrice); ItemCount++; this->SendTotals(); } else { if(IsLoyaltyCard(strPLU)) { SCOprintf("PLU ISLOYALTY\r\n"); g_pclsMyCompanyMFController->SCOSendLoyaltyCardSet((char *)strPLU.c_str()); } else { SCOprintf("NOT FOUND Sale Item\r\n"); g_pclsMyCompanyMFController->SCOSendItemNotFound((char *)strPLU.c_str()); } } } } void NewModule_CORE::SCOTender(CMarkup XmlMsg) { //blnSaleInProgress = false; XmlMsg.ResetPos(); XmlMsg.FindElem( "Layer" ); XmlMsg.IntoElem(); XmlMsg.FindElem( "Message" ); XmlMsg.IntoElem(); if(XmlMsg.FindElem( "Values" )) { string strAmount = XmlMsg.GetAttrib( "Amount" ); string strTenderType = XmlMsg.GetAttrib( "TenderType" ); if(StringToUpper(strTenderType) == "CASH") { char cSaleTotal[25] = {0}; sprintf(cSaleTotal, "%ld", SaleTotal); string sSaleTotal = cSaleTotal; if(sSaleTotal == strAmount) { //Sale Complete g_pclsMyCompanyMFController->SCOSendTenderAccepted((char *)strTenderType.c_str(), (char *)strAmount.c_str()); SaleTotalPaid = atol(strAmount.c_str()); this->SendTotals(); blnSaleInProgress = false; } } } } bool NewModule_CORE::IsLoyaltyCard(string strPLU) { if(strPLU.find("123456") != std::string::npos) { return true; } else { return false; } } NewModule_CORE::ItemInfo NewModule_CORE::GetItemInfo(char *cPLU) { bool bGotItemInfo = false; long lPluRec; char cBasePLU[15] = {0}; bool bOpenItem = false; ItemInfo m_ItemInfo = {0}; if ((strlen(cPLU) >= 20 && strncmp(cPLU,"94",2) == 0)) { Get94CodeInfo(cPLU); } else { // get plu record from stock file MakePLUCode( cPLU ); } strncpy( cBasePLU, cPLU, 13 ); if (Check_Open_Ean(cBasePLU)) { // Open Ean Exaction. _Extract_Open_Ean(cBasePLU); lPluRec = _Find_Plu(cBasePLU); bOpenItem = true; } else { lPluRec = _Find_Plu(cPLU); } if (lPluRec>0) { _Stock(STOCK_PRIM,MyCompany_READONLY, lPluRec); // St global structure has product details now memset( m_ItemInfo.cDescription, 0, 40 ); strncpy( m_ItemInfo.cDescription, St.Des, 35 ); memset( m_ItemInfo.cItemCode, 0, 20 ); memset( m_ItemInfo.cBaseCode, 0, 20 ); if (!bOpenItem) { strncpy( m_ItemInfo.cItemCode, cPLU, 15 ); } else { strncpy( m_ItemInfo.cItemCode, cPLU, 15 ); strncpy( m_ItemInfo.cBaseCode, cBasePLU, 15 ); } m_ItemInfo.lFilePrice = St.Price[0]; m_ItemInfo.iWeighed = St.Weighed; m_ItemInfo.iDept = atoi(St.Dept); m_ItemInfo.iArtGrp = St.ProdLabel; m_ItemInfo.iStopped = St.Stop; m_ItemInfo.bItemFound = true; } else { // PLU not on file m_ItemInfo.bItemFound = false; } return m_ItemInfo; } void NewModule_CORE::MakePLUCode(char *cPLU) { int i, Max; _Filter(cPLU, 0); Max = (int) _Control(MAX_PLU_LENGTH, TRUE); if (Max <= 0 || Max > 14) Max = 14; if (_Control(ZERO_FILL_PLUS, FALSE)) { while ((int) (strlen(cPLU)) < Max) { i = strlen(cPLU); _strrev(cPLU); cPLU[i] = 48; cPLU[i + 1] = 0; _strrev(cPLU); } } if (_Control(REMOVE_LEADING_ZEROS, FALSE)) { while (cPLU[0] == 48) { i = strlen(cPLU) - 1; if (!i) return; _strrev(cPLU); cPLU[i] = 0; _strrev(cPLU); } } i = strlen(cPLU); if (i > Max) cPLU[Max] = 0; return; } void NewModule_CORE::SCOprintf(string s) { printf(s.c_str()); } void NewModule_CORE::SendTotals() { char cTotals[25] = {0}; sprintf(cTotals, "%ld", SaleTotal); char cItemCount[20] = {0}; sprintf(cItemCount, "%ld", ItemCount); int iBalanceDue = SaleTotal - SaleTotalPaid; char cBalDue[20] = {0}; sprintf(cBalDue, "%ld", iBalanceDue); g_pclsMyCompanyMFController->SCOSendTotals(cBalDue,cTotals,cItemCount); } string NewModule_CORE::StringToUpper(string strToConvert) { std::transform(strToConvert.begin(), strToConvert.end(), strToConvert.begin(), ::toupper); return strToConvert; }
Header File
// NewModule_CORE.h: interface for the NewModule_CORE class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_NewModule_CORE_H__68E7990D_E328_418E_8A17_8DEB9EB9087A__INCLUDED_) #define AFX_NewModule_CORE_H__68E7990D_E328_418E_8A17_8DEB9EB9087A__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include <string> #include "Markup.h" using namespace std; class NewModule_CORE { public: struct ItemInfo { char cDescription[40]; char cItemCode[20]; long lPrice; long lFilePrice; int iWeighed; int iDept; short iArtGrp; int iStopped; int iQtyRequired; int iAgeRequired; int iSCOTag; bool bCustomerCard; char cLastScannedVoucher[20]; char cBaseCode[20]; bool bItemFound; }; public: void NewModule_CORE::RunSCO(); NewModule_CORE(); virtual ~NewModule_CORE(); private: void NewModule_CORE::SCO_Main(); void NewModule_CORE::SCO_Next_Item(); ItemInfo NewModule_CORE::GetItemInfo(char *cPLU); void NewModule_CORE::MakePLUCode(char *cPLU); bool NewModule_CORE::ProcessFunctionFromScoLayer(string strFunc); bool NewModule_CORE::IsLoyaltyCard(string strPLU); void NewModule_CORE::HandleSCOItem(CMarkup strMsg); void NewModule_CORE::ResetForNextSale(); void NewModule_CORE::SCOTender(CMarkup XmlMsg); string NewModule_CORE::StringToUpper(string strToConvert); void NewModule_CORE::SCO_CompleteSale(); void NewModule_CORE::SCO_Next_Sale(); void NewModule_CORE::SendTotals(); void NewModule_CORE::SCOprintf(string s); int SaleTotal; int SaleTotalPaid; int ItemCount; bool blnSaleInProgress; }; #endif // !defined(AFX_NewModule_CORE_H__68E7990D_E328_418E_8A17_8DEB9EB9087A__INCLUDED_)
Other Methods
int MyCompanyMF::SCOSendLoyaltyCardSet( char *cPLU ) { int iSentMsg = 0; char cGUIMsg[1024] = { 0 }; MyCompanyMFSCOLayer *pclsMFGL; if (IsInitialised()) { pclsMFGL = (MyCompanyMFSCOLayer*)pclsMFGUILayer; // construct message if (pclsMFGL->CreateMsgFTSCOLoyaltyCardSet( pclsMyCompanyPOSCore, cGUIMsg, cPLU )) { GUISaveMessage( cGUIMsg, false ); pclsMFLogFile->LogToFile( cGUIMsg ); if (SendMessage( cGUIMsg )) { pclsMFLogFile->LogResultToFile( "SendResult: Success" ); iSentMsg = 1; } else { pclsMFLogFile->LogResultToFile( "SendResult: Failed" ); } } } return iSentMsg; } int MyCompanyMF::SCOSendItemNotFound( char *cPLU ) { int iSentMsg = 0; char cGUIMsg[1024] = { 0 }; MyCompanyMFSCOLayer *pclsMFGL; if (IsInitialised()) { pclsMFGL = (MyCompanyMFSCOLayer*)pclsMFGUILayer; // construct message if (pclsMFGL->CreateMsgFTSCOItemNotFound( pclsMyCompanyPOSCore, cGUIMsg, cPLU )) { GUISaveMessage( cGUIMsg, false ); pclsMFLogFile->LogToFile( cGUIMsg ); if (SendMessage( cGUIMsg )) { pclsMFLogFile->LogResultToFile( "SendResult: Success" ); iSentMsg = 1; } else { pclsMFLogFile->LogResultToFile( "SendResult: Failed" ); } } } return iSentMsg; } int MyCompanyMF::SCOSendTenderAccepted( char *cTenderType, char *cAmount ) { int iSentMsg = 0; char cGUIMsg[1024] = { 0 }; MyCompanyMFSCOLayer *pclsMFGL; if (IsInitialised()) { pclsMFGL = (MyCompanyMFSCOLayer*)pclsMFGUILayer; // construct message if (pclsMFGL->CreateMsgFTSCOTenderAccepted( pclsMyCompanyPOSCore, cGUIMsg, cTenderType, cAmount )) { GUISaveMessage( cGUIMsg, false ); pclsMFLogFile->LogToFile( cGUIMsg ); if (SendMessage( cGUIMsg )) { pclsMFLogFile->LogResultToFile( "SendResult: Success" ); iSentMsg = 1; } else { pclsMFLogFile->LogResultToFile( "SendResult: Failed" ); } } } return iSentMsg; } int MyCompanyMF::SCOSendItemSold( char *cPLU, char *cDes, char *cPrice) { int iSentMsg = 0; char cMsg[1024] = { 0 }; MyCompanyMFSCOLayer *pclsMFSCOL; if (IsInitialised()) { pclsMFSCOL = (MyCompanyMFSCOLayer*)pclsMFGUILayer; // construct message if (pclsMFSCOL->CreateMsgFTSCOItemSold( pclsMyCompanyPOSCore, cMsg, cPLU, cDes, cPrice )) { GUISaveMessage( cMsg, false ); pclsMFLogFile->LogToFile( cMsg ); if (SendMessage( cMsg )) { pclsMFLogFile->LogResultToFile( "SendResult: Success" ); iSentMsg = 1; } else { pclsMFLogFile->LogResultToFile( "SendResult: Failed" ); } } } return iSentMsg; } int MyCompanyMF::SCOSendTotals( char *cBalDue, char *cTotalAmount, char *cItemCount) { int iSentMsg = 0; char cMsg[1024] = { 0 }; MyCompanyMFSCOLayer *pclsMFSCOL; if (IsInitialised()) { pclsMFSCOL = (MyCompanyMFSCOLayer*)pclsMFGUILayer; // construct message if (pclsMFSCOL->CreateMsgFTSCOTotals( pclsMyCompanyPOSCore, cMsg, cBalDue, cTotalAmount, cItemCount)) { GUISaveMessage( cMsg, false ); pclsMFLogFile->LogToFile( cMsg ); if (SendMessage( cMsg )) { pclsMFLogFile->LogResultToFile( "SendResult: Success" ); iSentMsg = 1; } else { pclsMFLogFile->LogResultToFile( "SendResult: Failed" ); } } } return iSentMsg; } int MyCompanyMF::SCOSendEndTransaction( char *cTransNo) { int iSentMsg = 0; char cMsg[1024] = { 0 }; MyCompanyMFSCOLayer *pclsMFSCOL; if (IsInitialised()) { pclsMFSCOL = (MyCompanyMFSCOLayer*)pclsMFGUILayer; // construct message if (pclsMFSCOL->CreateMsgFTEndTransaction( pclsMyCompanyPOSCore, cMsg, cTransNo )) { GUISaveMessage( cMsg, false ); pclsMFLogFile->LogToFile( cMsg ); if (SendMessage( cMsg )) { pclsMFLogFile->LogResultToFile( "SendResult: Success" ); iSentMsg = 1; } else { pclsMFLogFile->LogResultToFile( "SendResult: Failed" ); } } } return iSentMsg; } int MyCompanyMFSCOLayer::CreateMsgFTSCOItemSold( MyCompanyPOSCore *pclsMyCompanyPOSCore, char *cMsg, char *cPLU, char *cDesc, char *cPrice) { const char *pMsg = NULL; char cAttrName[100] = {0}; char cAttrValue[200] = {0}; long lMsgLen = 0; static char cLastMsg[300] = {0}; MyCompanyXMLMsgBuilder *pXMLBuild = new MyCompanyXMLMsgBuilder(); lMsgLen = pXMLBuild->GetXMLMsgLen(); lMsgLen = pXMLBuild->AddStandardProlog( "SCO", "CORE", "ItemSold" ); strncpy( cAttrName, cPLU, 99 ); lMsgLen = pXMLBuild->AddAttributeAndValue( "PLU", cAttrName ); strncpy( cAttrName, cDesc, 99 ); lMsgLen = pXMLBuild->AddAttributeAndValue( "Description", cAttrName ); strncpy( cAttrName, cPrice, 99 ); lMsgLen = pXMLBuild->AddAttributeAndValue( "Price", cAttrName ); lMsgLen = pXMLBuild->AddStandardEpiLog(); lMsgLen = pXMLBuild->GetXMLMsgLen(); pMsg = pXMLBuild->GetXMLMsg(); strncpy( cMsg, pMsg, lMsgLen+1 ); delete pXMLBuild; return (int)lMsgLen; // length of msg > 0 indicates success } int MyCompanyMFSCOLayer::CreateMsgFTEndTransaction( MyCompanyPOSCore *pclsMyCompanyPOSCore, char *cMsg, char *cTransNo ) { const char *pMsg = NULL; char cAttrName[100] = {0}; char cAttrValue[200] = {0}; long lMsgLen = 0; static char cLastMsg[300] = {0}; MyCompanyXMLMsgBuilder *pXMLBuild = new MyCompanyXMLMsgBuilder(); lMsgLen = pXMLBuild->GetXMLMsgLen(); lMsgLen = pXMLBuild->AddStandardProlog( "SCO", "CORE", "EndTransaction" ); strncpy( cAttrName, cTransNo, 99 ); lMsgLen = pXMLBuild->AddAttributeAndValue( "TransactionID", cAttrName ); lMsgLen = pXMLBuild->AddStandardEpiLog(); lMsgLen = pXMLBuild->GetXMLMsgLen(); pMsg = pXMLBuild->GetXMLMsg(); strncpy( cMsg, pMsg, lMsgLen+1 ); delete pXMLBuild; return (int)lMsgLen; } int MyCompanyMFSCOLayer::CreateMsgFTSCOTotals( MyCompanyPOSCore *pclsMyCompanyPOSCore, char *cMsg, char *cBalDue, char *cTotalAmount, char *cItemCount) { const char *pMsg = NULL; char cAttrName[100] = {0}; char cAttrValue[200] = {0}; long lMsgLen = 0; static char cLastMsg[300] = {0}; MyCompanyXMLMsgBuilder *pXMLBuild = new MyCompanyXMLMsgBuilder(); lMsgLen = pXMLBuild->GetXMLMsgLen(); lMsgLen = pXMLBuild->AddStandardProlog( "SCO", "CORE", "Totals" ); strncpy( cAttrName, cBalDue, 99 ); lMsgLen = pXMLBuild->AddAttributeAndValue( "BalanceDue", cAttrName ); strncpy( cAttrName, cTotalAmount, 99 ); lMsgLen = pXMLBuild->AddAttributeAndValue( "TotalAmount", cAttrName ); strncpy( cAttrName, cItemCount, 99 ); lMsgLen = pXMLBuild->AddAttributeAndValue( "ItemCount", cAttrName ); lMsgLen = pXMLBuild->AddStandardEpiLog(); lMsgLen = pXMLBuild->GetXMLMsgLen(); pMsg = pXMLBuild->GetXMLMsg(); strncpy( cMsg, pMsg, lMsgLen+1 ); delete pXMLBuild; return (int)lMsgLen; // length of msg > 0 indicates success } int MyCompanyMFSCOLayer::CreateMsgFTSCOItemNotFound( MyCompanyPOSCore *pclsMyCompanyPOSCore, char *cMsg, char *cPLU) { const char *pMsg = NULL; char cAttrName[100] = {0}; char cAttrValue[200] = {0}; long lMsgLen = 0; static char cLastMsg[300] = {0}; MyCompanyXMLMsgBuilder *pXMLBuild = new MyCompanyXMLMsgBuilder(); lMsgLen = pXMLBuild->GetXMLMsgLen(); lMsgLen = pXMLBuild->AddStandardProlog( "SCO", "CORE", "ItemNotFound" ); strncpy( cAttrName, cPLU, 99 ); lMsgLen = pXMLBuild->AddAttributeAndValue( "PLU", cAttrName ); lMsgLen = pXMLBuild->AddStandardEpiLog(); lMsgLen = pXMLBuild->GetXMLMsgLen(); pMsg = pXMLBuild->GetXMLMsg(); strncpy( cMsg, pMsg, lMsgLen+1 ); delete pXMLBuild; return (int)lMsgLen; // length of msg > 0 indicates success } int MyCompanyMFSCOLayer::CreateMsgFTSCOTenderAccepted( MyCompanyPOSCore *pclsMyCompanyPOSCore, char *cMsg, char *cTenderType, char *cAmount) { const char *pMsg = NULL; char cAttrName[100] = {0}; char cAttrValue[200] = {0}; long lMsgLen = 0; static char cLastMsg[300] = {0}; MyCompanyXMLMsgBuilder *pXMLBuild = new MyCompanyXMLMsgBuilder(); lMsgLen = pXMLBuild->GetXMLMsgLen(); lMsgLen = pXMLBuild->AddStandardProlog( "SCO", "CORE", "TenderAccepted" ); strncpy( cAttrName, cTenderType, 99 ); lMsgLen = pXMLBuild->AddAttributeAndValue( "TenderType", cAttrName ); strncpy( cAttrName, cAmount, 99 ); lMsgLen = pXMLBuild->AddAttributeAndValue( "Amount", cAttrName ); lMsgLen = pXMLBuild->AddStandardEpiLog(); lMsgLen = pXMLBuild->GetXMLMsgLen(); pMsg = pXMLBuild->GetXMLMsg(); strncpy( cMsg, pMsg, lMsgLen+1 ); delete pXMLBuild; return (int)lMsgLen; // length of msg > 0 indicates success } int MyCompanyMFSCOLayer::CreateMsgFTSCOLoyaltyCardSet( MyCompanyPOSCore *pclsMyCompanyPOSCore, char *cMsg, char *cPLU) { const char *pMsg = NULL; char cAttrName[100] = {0}; char cAttrValue[200] = {0}; long lMsgLen = 0; static char cLastMsg[300] = {0}; MyCompanyXMLMsgBuilder *pXMLBuild = new MyCompanyXMLMsgBuilder(); lMsgLen = pXMLBuild->GetXMLMsgLen(); lMsgLen = pXMLBuild->AddStandardProlog( "SCO", "CORE", "LoyaltyCard" ); strncpy( cAttrName, cPLU, 99 ); lMsgLen = pXMLBuild->AddAttributeAndValue( "Card", cAttrName ); // Card="1234567890123" lMsgLen = pXMLBuild->AddStandardEpiLog(); lMsgLen = pXMLBuild->GetXMLMsgLen(); pMsg = pXMLBuild->GetXMLMsg(); strncpy( cMsg, pMsg, lMsgLen+1 ); delete pXMLBuild; return (int)lMsgLen; }