#pragma once
#include "tinyxml.h"
#include <string>
#include <map>
#ifndef NULL
#define NULL 0
#endif
class SoapMsgXml
{
public:
SoapMsgXml(const char* httpStream, unsigned int streamLen = 0);
virtual ~SoapMsgXml(void);
static bool TestClass();
const char* findXmlStartInHttpStram();
private:
bool init();
bool parseXml(const char* xmlStartInHttpStram);
bool parseSoapHead(std::string httpHead);
private:
const char* _httpStream; //传入的http消息流
unsigned int _streamLen; //消息流长度
TiXmlDocument _xmlDoc;
std::map<std::string,std::string> _mapHttpHead; //soap的开头协议
};
#include "SoapMsgXml.h"
#include <string>
#include <sstream>
#include <string.h>
#include <iostream>
#include <algorithm>
#include "MyToolFun.h"
using namespace std;
SoapMsgXml::SoapMsgXml(const char* httpStream, unsigned int streamLen):
_httpStream(httpStream), _streamLen(streamLen)
{
}
SoapMsgXml::~SoapMsgXml(void)
{
}
bool SoapMsgXml::TestClass()
{
const char* httpStream =
"POST /ProductQuote HTTP/1.1\r\n"
"Host: service.eMarketplace.com.cn\r\n"
"Content-Type: text/xml; charset=utf-8\r\n"
"Content-Length: 656\r\n"
"SOAPAction: http://schemas.microsoft.com/sqlserver/2004/SOAPsqlbatch\r\n"
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
"<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\r\n"
"\t<SOAP-ENV:Header>\r\n"
"\t\t<uniB2B:AccessAuthenticated xmlns:uniB2B=\"Some-URI\">\r\n"
"\t\t\t<SessionKey>76E4#12A@-98JA#V5GQ</SessionKey>\r\n"
"\t\t</uniB2B:AccessAuthenticated >\r\n"
"\t\t<uniB2B:GetLastProductPrice xmlns:uniB2B =\"Some-URI\">\r\n"
"\t\t\t<Price>243900.00</Price>\r\n"
"\t\t</uniB2B:GetLastProductPrice>\r\n"
"\t</SOAP-ENV:Header>\r\n"
"\t<SOAP-ENV:Body>\r\n"
"\t\t<uniB2B:RequestPurchaseOrder xmlns:uniB2B =\"Some-URI\">\r\n"
"\t\t\t<ProductID>Jaguar_X_Type</ProductID >\r\n"
"\t\t\t<ProductPrice>243900.00</ProductPrice>\r\n"
"\t\t</uniB2B:RequestPurchaseOrder >\r\n"
"\t</SOAP-ENV:Body>\r\n"
"</SOAP-ENV:Envelope>\r\n";
cout<<"接收的Http消息包:"<<endl
<<httpStream<<endl;
SoapMsgXml soapMsgXml(httpStream);
if (!soapMsgXml.init()){
return false;
}
return true;
}
const char* SoapMsgXml::findXmlStartInHttpStram()
{
return findLineStartWith(_httpStream, _streamLen,'<');
}
bool SoapMsgXml::init()
{
if (0 == _streamLen){
_streamLen = strlen(_httpStream);
}
//消息流中xml标示开始位置
const char* xmlStartInHttpStram = findXmlStartInHttpStram();
//没有找到,返回false
if (!xmlStartInHttpStram){
return false;
}
if (!parseXml(xmlStartInHttpStram)){
return false;
}
string httpHead(_httpStream, xmlStartInHttpStram);
if (!parseSoapHead(httpHead)){
return false;
}
return true;
}
bool SoapMsgXml::parseXml(const char* xmlStartInHttpStram)
{
//解析XML部分
_xmlDoc.Parse(xmlStartInHttpStram);
if (_xmlDoc.Error()){
return false;
}
return true;
}
bool SoapMsgXml::parseSoapHead(string httpHead)
{
stringstream streamHttpHead(httpHead);
string lineData;
string mapKey;
string mapValue;
std::string::iterator itFind;
_mapHttpHead.clear();
while(getline(streamHttpHead,lineData)){
if (lineData.length() == 0 ){
continue;
}
//第一行是POST /ProductQuote HTTP/1.1,以空格分割,其他的以:分割
if (_mapHttpHead.size() == 0) {
itFind = std::find(lineData.begin(), lineData.end(), ' ');
} else {
itFind = std::find(lineData.begin(), lineData.end(), ':');
}
if (itFind != lineData.end())
{
mapKey.assign(lineData.begin(), itFind);
mapValue.assign(++itFind, lineData.end());
trim(mapKey);
trim(mapValue);
_mapHttpHead.insert(std::map<string, string>::value_type(mapKey, mapValue));
}
}
return true;
}
-----------------------------------------------------------------------------
#ifdef TIXML_USE_STL
#include <iostream>
#include <sstream>
using namespace std;
#else
#include <stdio.h>
#endif
#if defined( WIN32 )
#include <conio.h>
#endif
#include "SoapMsgXml.h"
#include "MyToolFun.h"
int main()
{
string now[4];
getCurTimeWithMillSec1(&(now[0]),"getCurTimeWithMillSec1::0::");
getCurTimeWithMillSec1(&(now[1]),"getCurTimeWithMillSec1::1::");
getCurTimeWithMillSec2(&(now[2]),"getCurTimeWithMillSec2::0::");
getCurTimeWithMillSec2(&(now[3]),"getCurTimeWithMillSec2::1::");
cout<<now[0]<<endl;
cout<<now[1]<<endl;
cout<<now[2]<<endl;
cout<<now[3]<<endl;
//SoapMsgXml::TestClass();
#if defined( WIN32 )
_getch();
#endif
return 1;
}
-----------------------------------------------------------------------------
#include <time.h>
#include <sys/types.h>
#include <sys/timeb.h>
#include <windows.h>
#include <sstream>
#include <iostream>
#include <iomanip>
#include "MyToolFun.h"
void outTime(string *dest, int year, int month, int day, int hour,int minute, int second, int millsec, const char *promptMsg)
{
stringstream ss("");
if (promptMsg){
ss<<promptMsg;
}
ss<<setw(4)<<setfill('0')<<year<<"-"
<<setw(2)<<setfill('0')<<month<<"-"
<<setw(2)<<setfill('0')<<day<<" "
<<setw(2)<<setfill('0')<<hour<<":"
<<setw(2)<<setfill('0')<<minute<<":"
<<setw(2)<<setfill('0')<<second<<"."
<<setfill('0')<<setw(3)<<millsec
<<endl;
if (dest){
*dest = ss.str();
} else {
cout<<ss<<endl;
}
}
void getCurTimeWithMillSec1(string *dest, const char *promptMsg)
{
struct timeb tp;
ftime (&tp);
struct tm* tm = localtime(&(tp.time));
outTime(dest, tm->tm_year, tm->tm_mon, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec, tp.millitm,
promptMsg);
}
void getCurTimeWithMillSec2(string *dest, const char *promptMsg)
{
SYSTEMTIME Systime;
GetLocalTime(&Systime);
outTime(dest, Systime.wYear, Systime.wMonth, Systime.wDay, Systime.wHour,
Systime.wMinute, Systime.wSecond, Systime.wMilliseconds,
promptMsg);
}
void trim(std::string & src)
{
src.erase(0, src.find_first_not_of(' '));
src.erase(0, src.find_first_not_of('\t'));
src.erase(0, src.find_first_not_of('\r'));
src.erase(0, src.find_first_not_of('\n'));
src.erase(src.find_last_not_of(' ') + 1);
src.erase(src.find_last_not_of('\t') + 1);
src.erase(src.find_last_not_of('\r') + 1);
src.erase(src.find_last_not_of('\n') + 1);
}
const char* findLineStartWith(const char* httpStream, unsigned int streamLen, const char startChar)
{
const char* xmlStartInHttpStram = NULL;
//如果httpStream为空指针或长度为0,则长度为NULL
if (!httpStream || !streamLen){
return xmlStartInHttpStram;
}
bool newLineHead = true; //新行开始标志
bool findXmlStart = false; //找到XML的开头
for(xmlStartInHttpStram = httpStream;
xmlStartInHttpStram < httpStream + streamLen;
xmlStartInHttpStram++){
//跳过\r \t 和空格
if ('\r' == *xmlStartInHttpStram || '\t' == *xmlStartInHttpStram
|| ' ' == *xmlStartInHttpStram){
continue;
}
//如果新行的头一个非控字符为<,则标示XmlStart
if (newLineHead && startChar == *xmlStartInHttpStram){
findXmlStart = true;
break;
}
//如果发现\n,设置新一行开始,否则置为false
if ('\n' == *xmlStartInHttpStram){
newLineHead = true;
} else {
newLineHead = false;
}
}
if (!findXmlStart){
xmlStartInHttpStram = NULL;
}
return xmlStartInHttpStram;
}
------------------------------------------------------
//filename:MyToolFun.h
#ifndef ZMY_TOOL_FUN_H
#define ZMY_TOOL_FUN_H
#include <string>
using namespace std;
void outTime(string *dest, int year, int month, int day,
int hour,int minute, int second,
int millsec, const char *promptMsg);
void getCurTimeWithMillSec1(string *dest, const char *promptMsg = NULL);
void getCurTimeWithMillSec2(string *dest, const char *promptMsg = NULL);
inline unsigned long long GetCycleCount()
{
__asm RDTSC
}
void trim(std::string & src);
const char* findLineStartWith(const char* httpStream, unsigned int streamLen, const char startChar);
#endif //ZMY_TOOL_FUN_H