Hi,
In my current ATL server project, I have to parse the
input in the client application's request to find out
the different combination of parameters, instead of
using SOAP. For this reason, I am not using ATL server
web service project. On client side, I use POST to send
XML to web server. I know I should use ISAXXMLReader in
the server program. I also know that the parser can be
used for many different handlers in the DLL. I found some
example of SAX2 from Microsoft as standalone program.
ISAXXMLReader* pRdr = NULL;
HRESULT hr = CoCreateInstance(
__uuidof(SAXXMLReader),
NULL,
CLSCTX_ALL,
__uuidof(ISAXXMLReader),
(void **)&pRdr);
if(!FAILED(hr))
{
MyContent * pMc = new MyContent();
hr = pRdr->putContentHandler(pMc);
SAXErrorHandlerImpl * pEc =
new SAXErrorHandlerImpl();
hr = pRdr->putErrorHandler(pEc);
static wchar_t URL[1000];
mbstowcs( URL, argv[1], 999 );
wprintf(L"\nParsing document: %s\n", URL);
hr = pRdr->parseURL(URL);
printf("\nParse result code: %08x\n\n",hr);
pRdr->Release();
delete pMc;
}
This looks like a half COM program. Is this against
ATL Server project? How to make this per thread function?
What should I do to make it safe, thread-safe, no memory
leak, etc. Due to the lack of documents and books, I
cannot find more examples or information. Now, I still
have some trouble in using it in ATL server application.
Coud anyone help?
Thank you very much.
FS Liu 6 4579
Hi
Mostly for SOAP purposes, ATL Server applications already provide a
per-thread ISAXXMLReader.
( You can disable this feature by defining #define ATL_NO_SOAP, but it is ON
by default)
You can access this per-thread ISAXXMLReader in your request handler with
code like below:
CComPtr<ISAXXMLReader> spReader;
HRESULT hRet =
m_spServiceProvider->QueryService(__uuidof(ISAXXMLReader),
__uuidof(ISAXXMLReader), &spReader)
Hope this helps,
--
--
--
This posting is provided "AS IS" with no warranties, and confers no rights.
Please do not send email directly to this alias. It is for newsgroup
purposes only.
thanks,
bogdan
"FS Liu" <fa***********@hotmail.com> wrote in message
news:0d****************************@phx.gbl... Hi,
In my current ATL server project, I have to parse the input in the client application's request to find out the different combination of parameters, instead of using SOAP. For this reason, I am not using ATL server web service project. On client side, I use POST to send XML to web server. I know I should use ISAXXMLReader in the server program. I also know that the parser can be used for many different handlers in the DLL. I found some example of SAX2 from Microsoft as standalone program.
ISAXXMLReader* pRdr = NULL; HRESULT hr = CoCreateInstance( __uuidof(SAXXMLReader), NULL, CLSCTX_ALL, __uuidof(ISAXXMLReader), (void **)&pRdr); if(!FAILED(hr)) { MyContent * pMc = new MyContent(); hr = pRdr->putContentHandler(pMc); SAXErrorHandlerImpl * pEc = new SAXErrorHandlerImpl(); hr = pRdr->putErrorHandler(pEc); static wchar_t URL[1000]; mbstowcs( URL, argv[1], 999 ); wprintf(L"\nParsing document: %s\n", URL); hr = pRdr->parseURL(URL); printf("\nParse result code: %08x\n\n",hr); pRdr->Release(); delete pMc; } This looks like a half COM program. Is this against ATL Server project? How to make this per thread function? What should I do to make it safe, thread-safe, no memory leak, etc. Due to the lack of documents and books, I cannot find more examples or information. Now, I still have some trouble in using it in ATL server application.
Coud anyone help?
Thank you very much.
FS Liu
Hi, Bogdan,
Thank you so much for the example. I still have a problem
about the use of content handler class, MyContent. All the
Microsoft examples use
MyContent * pMc = new MyContent();
I defined a content handler that has member variables for
pairs of node and value. After running spReader->parse(),
I use the resultant pairs in the rest of the program. Is
it a better idea to use
CComPtr<MyContent> pMc;
in ATL Server application project for easier memory
management? To do so, is there any special requirement to
define the content handler MyContent? Here is my code:
CComHeapPtr<CHAR> m_RequestBuffer;// buffer for
client POST data.
CComPtr<ISAXXMLReader> spReader;
HRESULT hr = m_spServiceProvider->QueryService(
__uuidof(ISAXXMLReader), &spReader)
if(!FAILED(hr))
{
CComPtr<MyContent> pMc;
if (!pMc)
return S_ERROR;
hr = spReader->putContentHandler(pMc);
SAXErrorHandlerImpl * pEc =
new SAXErrorHandlerImpl();
hr = spReader->putErrorHandler(pEc);
static wchar_t URL[1000];
mbstowcs( URL, argv[1], 999 );
VARIANT MyVariant;
MyVariant.vt = VT_BSTR;
MyVariant.bstrVal =
(BSTR)m_RequestBuffer;// ERROR HERE!
hr = spReader->parse(MyVariant);
spReader->Release();//Do we need this here?
ATLTRACE("Node: %s Value:%d\n",pMc->Name,
pMc->Value);
}
On the other hand, given m_RequestBuffer as a dynamically
allocated memory according to the data length of client
POST, I have trouble in packing m_RequestBuffer into a
VARIANT to pass to parse(), because the compiler cannot
convert m_RequestBuffer from CHAR to BSTR (Please read the
comment in the program.) Is there an efficient way (e.g.
data type or class) to get client POST data and pass it to
spReader->parse() directly, without converting from WCS to
MBS or vice versa. Finally, do I have to do clean up
with "spReader->Release();" for the per-thread spReader?
Thank you very much. -----Original Message----- Hi
Mostly for SOAP purposes, ATL Server applications already
provide aper-thread ISAXXMLReader. ( You can disable this feature by defining #define
ATL_NO_SOAP, but it is ONby default) You can access this per-thread ISAXXMLReader in your
request handler withcode like below:
CComPtr<ISAXXMLReader> spReader; HRESULT hRet = m_spServiceProvider->QueryService(__uuidof(ISAXXMLReader), __uuidof(ISAXXMLReader), &spReader)
Hope this helps,
-- -- -- This posting is provided "AS IS" with no warranties, and
confers no rights.Please do not send email directly to this alias. It is
for newsgrouppurposes only.
thanks, bogdan
"FS Liu" <fa***********@hotmail.com> wrote in message news:0d****************************@phx.gbl... Hi,
In my current ATL server project, I have to parse the input in the client application's request to find out the different combination of parameters, instead of using SOAP. For this reason, I am not using ATL server web service project. On client side, I use POST to send XML to web server. I know I should use ISAXXMLReader in the server program. I also know that the parser can be used for many different handlers in the DLL. I found
some example of SAX2 from Microsoft as standalone program.
ISAXXMLReader* pRdr = NULL; HRESULT hr = CoCreateInstance( __uuidof(SAXXMLReader), NULL, CLSCTX_ALL, __uuidof(ISAXXMLReader), (void **)&pRdr); if(!FAILED(hr)) { MyContent * pMc = new MyContent(); hr = pRdr->putContentHandler(pMc); SAXErrorHandlerImpl * pEc = new SAXErrorHandlerImpl(); hr = pRdr->putErrorHandler(pEc); static wchar_t URL[1000]; mbstowcs( URL, argv[1], 999 ); wprintf(L"\nParsing document: %s\n", URL); hr = pRdr->parseURL(URL); printf("\nParse result code: %08x\n\n",hr); pRdr->Release(); delete pMc; } This looks like a half COM program. Is this against ATL Server project? How to make this per thread
function? What should I do to make it safe, thread-safe, no memory leak, etc. Due to the lack of documents and books, I cannot find more examples or information. Now, I still have some trouble in using it in ATL server application.
Coud anyone help?
Thank you very much.
FS Liu
.
Please see inlines (look for [Bogdan Crivat])
Hope this helps, let me know if you run into any other issues
--
--
--
This posting is provided "AS IS" with no warranties, and confers no rights.
Please do not send email directly to this alias. It is for newsgroup
purposes only.
thanks,
bogdan
"FS Liu" <fa***********@hotmail.com> wrote in message
news:07****************************@phx.gbl... Hi, Bogdan,
Thank you so much for the example. I still have a problem about the use of content handler class, MyContent. All the Microsoft examples use MyContent * pMc = new MyContent(); I defined a content handler that has member variables for pairs of node and value. After running spReader->parse(), I use the resultant pairs in the rest of the program. Is it a better idea to use CComPtr<MyContent> pMc; in ATL Server application project for easier memory management? To do so, is there any special requirement to define the content handler MyContent? Here is my code:
[Bogdan Crivat] -- Yes, this should be a smart pointer. The SAX Reader will
AddRef and Release the handler repeatedly. CComPtr is the right way of
ensuring the
life span of the handler object
CComHeapPtr<CHAR> m_RequestBuffer;// buffer for client POST data. CComPtr<ISAXXMLReader> spReader; HRESULT hr = m_spServiceProvider->QueryService( __uuidof(ISAXXMLReader), &spReader) if(!FAILED(hr)) { CComPtr<MyContent> pMc;
[Bogdan Crivat] -- Based on my understanding of your code, I guess a
CreateInstance should appear here. I might be wrong, though
Also, below, you might want to have your own implementation of
ISAXErrorHandler (which can be included in your SAX Handler class)
This would allow you to collect the error and decide later what to do (how
to send the information back to the client).
I might be wrong, as I am not familiar with the SAXErrorHandlerImpl
if (!pMc) return S_ERROR; hr = spReader->putContentHandler(pMc); SAXErrorHandlerImpl * pEc = new SAXErrorHandlerImpl(); hr = spReader->putErrorHandler(pEc); static wchar_t URL[1000]; mbstowcs( URL, argv[1], 999 ); VARIANT MyVariant; MyVariant.vt = VT_BSTR; MyVariant.bstrVal = (BSTR)m_RequestBuffer;// ERROR HERE! hr = spReader->parse(MyVariant); spReader->Release();//Do we need this here? ATLTRACE("Node: %s Value:%d\n",pMc->Name, pMc->Value); } On the other hand, given m_RequestBuffer as a dynamically allocated memory according to the data length of client POST, I have trouble in packing m_RequestBuffer into a VARIANT to pass to parse(), because the compiler cannot convert m_RequestBuffer from CHAR to BSTR (Please read the comment in the program.) Is there an efficient way (e.g. data type or class) to get client POST data and pass it to spReader->parse() directly, without converting from WCS to MBS or vice versa.
[Bogdan Crivat]
The Client POST data does not have to be copied. It is available as a stream
interface and
can be passed directly to the SAXXMLReader. See the following code snippet
for an example:
// Create a stream wrapper on top of the HTTP Server Context
CStreamOnServerContext s(m_pRequestInfo->pServerContext);
// Now create a variant that will contain the IUnknown of the IStream object
above
CComVariant varStream;
varStream = static_cast<IUnknown*>(&s);
HRESULT hr = spReader->parse(varStream);
If posible, please try to take a look at the atlsoap.h file coming with VS.
That file (the ATL Server SOAP implementation)
has to solve problems similar to the ones you have
Finally, do I have to do clean up with "spReader->Release();" for the per-thread spReader?
[Bogdan Crivat]
No, you don't have to call an extra release. Basically, your code should
look like:
{
CComPtr<ISAXXMLReader> spReader;
m_spServiceProvider->QueryService(..., &spReader);
...
spReader->putContentHandler(...)
...
spReader->parse()
...
}
Let's assume that initially the ref count for the per-thread reader is 1.
QueryService will make it 2.
The destructor of the spReader smart pointer will call Release once and make
it back to 1, therefore ready for being used again on the same thread, with
different
data Thank you very much.
-----Original Message----- Hi
Mostly for SOAP purposes, ATL Server applications already provide aper-thread ISAXXMLReader. ( You can disable this feature by defining #define ATL_NO_SOAP, but it is ONby default) You can access this per-thread ISAXXMLReader in your request handler withcode like below:
CComPtr<ISAXXMLReader> spReader; HRESULT hRet = m_spServiceProvider->QueryService(__uuidof(ISAXXMLReader), __uuidof(ISAXXMLReader), &spReader)
Hope this helps,
-- -- -- This posting is provided "AS IS" with no warranties, and confers no rights.Please do not send email directly to this alias. It is for newsgrouppurposes only.
thanks, bogdan
"FS Liu" <fa***********@hotmail.com> wrote in message news:0d****************************@phx.gbl... Hi,
In my current ATL server project, I have to parse the input in the client application's request to find out the different combination of parameters, instead of using SOAP. For this reason, I am not using ATL server web service project. On client side, I use POST to send XML to web server. I know I should use ISAXXMLReader in the server program. I also know that the parser can be used for many different handlers in the DLL. I found some example of SAX2 from Microsoft as standalone program.
ISAXXMLReader* pRdr = NULL; HRESULT hr = CoCreateInstance( __uuidof(SAXXMLReader), NULL, CLSCTX_ALL, __uuidof(ISAXXMLReader), (void **)&pRdr); if(!FAILED(hr)) { MyContent * pMc = new MyContent(); hr = pRdr->putContentHandler(pMc); SAXErrorHandlerImpl * pEc = new SAXErrorHandlerImpl(); hr = pRdr->putErrorHandler(pEc); static wchar_t URL[1000]; mbstowcs( URL, argv[1], 999 ); wprintf(L"\nParsing document: %s\n", URL); hr = pRdr->parseURL(URL); printf("\nParse result code: %08x\n\n",hr); pRdr->Release(); delete pMc; } This looks like a half COM program. Is this against ATL Server project? How to make this per thread function? What should I do to make it safe, thread-safe, no memory leak, etc. Due to the lack of documents and books, I cannot find more examples or information. Now, I still have some trouble in using it in ATL server application.
Coud anyone help?
Thank you very much.
FS Liu
.
Hi, Bogdan,
Thank you very much for the valuable message. After I
declare
CComPtr <MyContent> pContent;
pContent is NULL. Yes, you are right. I should
CreateInstance after this line. So, I change my program
as (a simplified version):
CComPtr <ISAXXMLReader> spReader;
hr = m_spServiceProvider->QueryService(
__uuidof(ISAXXMLReader), &spReader);
CComPtr <MyContent> pContent;
//pContent = new MyContent();
//hr = pContent.CoCreateInstance(
// __uuidof(MyContent), NULL,
// CLSCTX_INPROC_SERVER);
hr = spReader->putContentHandler(pContent);
CStreamOnServerContext s(m_pRequestInfo- pServerContext);
CComVariant varStream;
varStream = static_cast<IUnknown*>(&s);
ATLTRACE((char *)(varStream.bstrVal));
hr = spReader->parse (varStream);
When I use
pContent = new MyContent();
to create the instance, VS.NET compiler reports a message
saying "cannot instanciate the class" (I am using a
Japanese version. I don't know the exact wording of the
message in English). Does this mean that I have to include
some header files from VS.NET, such as msxml2.h or
something else? When I use
hr = pContent.CoCreateInstance(__uuidof
(MyContent), NULL, CLSCTX_INPROC_SERVER);
the compiler also complains: there is no associated GUID.
I read atlsoap.h and found the parseFault() function. It
is similar to the above code, except the creation of
content handler. I tried several ways to create an
instance, but failed.
I feel I just have one step further to clearify this
issue, but cannot find enough document. Could you help? By
the way, "ATLTRACE((char *)(varStream.bstrVal));" does
not print the XML string. Do you know why?
Thank you very much.
FS Liu
-----Original Message----- Please see inlines (look for [Bogdan Crivat]) Hope this helps, let me know if you run into any other
issues -- -- -- This posting is provided "AS IS" with no warranties, and
confers no rights.Please do not send email directly to this alias. It is
for newsgrouppurposes only.
thanks, bogdan
"FS Liu" <fa***********@hotmail.com> wrote in message news:07****************************@phx.gbl... Hi, Bogdan,
Thank you so much for the example. I still have a
problem about the use of content handler class, MyContent. All
the Microsoft examples use MyContent * pMc = new MyContent(); I defined a content handler that has member variables
for pairs of node and value. After running spReader->parse
(), I use the resultant pairs in the rest of the program. Is it a better idea to use CComPtr<MyContent> pMc; in ATL Server application project for easier memory management? To do so, is there any special requirement
to define the content handler MyContent? Here is my code: [Bogdan Crivat] -- Yes, this should be a smart pointer.
The SAX Reader willAddRef and Release the handler repeatedly. CComPtr is the
right way ofensuring the life span of the handler object
CComHeapPtr<CHAR> m_RequestBuffer;// buffer for client POST data. CComPtr<ISAXXMLReader> spReader; HRESULT hr = m_spServiceProvider->QueryService( __uuidof(ISAXXMLReader), &spReader) if(!FAILED(hr)) { CComPtr<MyContent> pMc;
[Bogdan Crivat] -- Based on my understanding of your
code, I guess aCreateInstance should appear here. I might be wrong,
thoughAlso, below, you might want to have your own
implementation ofISAXErrorHandler (which can be included in your SAX
Handler class)This would allow you to collect the error and decide
later what to do (howto send the information back to the client). I might be wrong, as I am not familiar with the
SAXErrorHandlerImpl
if (!pMc) return S_ERROR; hr = spReader->putContentHandler(pMc); SAXErrorHandlerImpl * pEc = new SAXErrorHandlerImpl(); hr = spReader->putErrorHandler(pEc); static wchar_t URL[1000]; mbstowcs( URL, argv[1], 999 ); VARIANT MyVariant; MyVariant.vt = VT_BSTR; MyVariant.bstrVal = (BSTR)m_RequestBuffer;// ERROR HERE! hr = spReader->parse(MyVariant); spReader->Release();//Do we need this here? ATLTRACE("Node: %s Value:%d\n",pMc->Name, pMc->Value); } On the other hand, given m_RequestBuffer as a
dynamically allocated memory according to the data length of client POST, I have trouble in packing m_RequestBuffer into a VARIANT to pass to parse(), because the compiler cannot convert m_RequestBuffer from CHAR to BSTR (Please read
the comment in the program.) Is there an efficient way (e.g. data type or class) to get client POST data and pass it
to spReader->parse() directly, without converting from WCS
to MBS or vice versa. [Bogdan Crivat] The Client POST data does not have to be copied. It is
available as a streaminterface and can be passed directly to the SAXXMLReader. See the
following code snippetfor an example:
// Create a stream wrapper on top of the HTTP Server
ContextCStreamOnServerContext s(m_pRequestInfo->pServerContext); // Now create a variant that will contain the IUnknown of
the IStream objectabove CComVariant varStream; varStream = static_cast<IUnknown*>(&s); HRESULT hr = spReader->parse(varStream); If posible, please try to take a look at the atlsoap.h
file coming with VS.That file (the ATL Server SOAP implementation) has to solve problems similar to the ones you have
Finally, do I have to do clean up with "spReader->Release();" for the per-thread spReader?[Bogdan Crivat] No, you don't have to call an extra release. Basically,
your code shouldlook like: { CComPtr<ISAXXMLReader> spReader; m_spServiceProvider->QueryService(..., &spReader); ... spReader->putContentHandler(...) ... spReader->parse() ... } Let's assume that initially the ref count for the per-
thread reader is 1.QueryService will make it 2. The destructor of the spReader smart pointer will call
Release once and makeit back to 1, therefore ready for being used again on the
same thread, withdifferent data
Thank you very much.
>-----Original Message----- >Hi > >Mostly for SOAP purposes, ATL Server applications
already provide a >per-thread ISAXXMLReader. >( You can disable this feature by defining #define ATL_NO_SOAP, but it is ON >by default) >You can access this per-thread ISAXXMLReader in your request handler with >code like below: > >CComPtr<ISAXXMLReader> spReader; >HRESULT hRet = >m_spServiceProvider->QueryService(__uuidof
(ISAXXMLReader), >__uuidof(ISAXXMLReader), &spReader) > >Hope this helps, > >-- >-- >-- >This posting is provided "AS IS" with no warranties,
and confers no rights. >Please do not send email directly to this alias. It is for newsgroup >purposes only. > >thanks, >bogdan > > > > >"FS Liu" <fa***********@hotmail.com> wrote in message >news:0d****************************@phx.gbl... >> Hi, >> >> In my current ATL server project, I have to parse the >> input in the client application's request to find out >> the different combination of parameters, instead of >> using SOAP. For this reason, I am not using ATL
server >> web service project. On client side, I use POST to
send >> XML to web server. I know I should use ISAXXMLReader
in >> the server program. I also know that the parser can
be >> used for many different handlers in the DLL. I found some >> example of SAX2 from Microsoft as standalone program. >> >> ISAXXMLReader* pRdr = NULL; >> HRESULT hr = CoCreateInstance( >> __uuidof(SAXXMLReader), >> NULL, >> CLSCTX_ALL, >> __uuidof(ISAXXMLReader), >> (void **)&pRdr); >> if(!FAILED(hr)) >> { >> MyContent * pMc = new MyContent(); >> hr = pRdr->putContentHandler(pMc); >> SAXErrorHandlerImpl * pEc = >> new SAXErrorHandlerImpl(); >> hr = pRdr->putErrorHandler(pEc); >> static wchar_t URL[1000]; >> mbstowcs( URL, argv[1], 999 ); >> wprintf(L"\nParsing document: %s\n", URL); >> hr = pRdr->parseURL(URL); >> printf("\nParse result code: %08x\n\n",hr); >> pRdr->Release(); >> delete pMc; >> } >> This looks like a half COM program. Is this against >> ATL Server project? How to make this per thread function? >> What should I do to make it safe, thread-safe, no
memory >> leak, etc. Due to the lack of documents and books, I >> cannot find more examples or information. Now, I
still >> have some trouble in using it in ATL server
application. >> >> Coud anyone help? >> >> Thank you very much. >> >> FS Liu >> > > >. >
.
Hello,
For the construction issue //hr = pContent.CoCreateInstance( // __uuidof(MyContent), NULL, // CLSCTX_INPROC_SERVER); hr = spReader->putContentHandler(pContent);
This will work only if your class is a registered COM server (and you will
have to pass the GUID of the registered server in CoCreate)
Assuming you wrote a C++ class,
class MyContent : public ISAXContentHandler
{
virtual HRESULT startElement(.....)
.....
}
your code while handling request should look like one of the following:
1. {
MyContent content;
hr = spReader->putContentHandler((ISAXContentHandler*)&content );
...
spReader->parse(...)
...
hr = spReader->putContentHandler(NULL); // disable the reference to
the content handler
}
(or 2.)
{
CComPtr< ISAXContentHandler> spHandler;
GetAHandler(&spHandler)
hr = spReader->putContentHandler(spHandler);
...
spReader->parse(...)
...
hr = spReader->putContentHandler(NULL); // disable the reference to
the content handler
}
HRESULT GetAHandler( ISAXContentHandler** out_ppHandler)
{
MyContent * pNew = new MyContent;
*out_ppHandler = pNew;
return S_OK
}
In this latter case, make sure that Release on MyContent calls "delete
this" when the ref count reaches 0.
On the second issue: CComVariant varStream; varStream = static_cast<IUnknown*>(&s); ATLTRACE((char *)(varStream.bstrVal));
This will not work for a few reasons:
1 -
assigning an IUnknown* to a CComVariant will invoke CComVariant& operator
=(IUnknown* pSrc );
After this, the type of the variant is VT_UNKNOWN, so using
varStream.bstrVal in a trace is incorrect (and might lead to an access
violation)
2 -
varStream is a stream, that is an IStream implementationm which is
forward-only (can only be read once). ISAXXMLReader->parse will do this
If you would be able to trace the IStream, then ISAXXMLReader will start
parsing at the end of the stream and will find no content
The advantage of the stream approach is that the content is only read once
from the Server context (which means, from the client) and is not copied in
intermediary buffers.
If you want to do the trace, you have at least 3 options:
- (for a complete ATL trace) -- instead of using the stream copy everything
into a BSTR. Trace the BSTR then parse the BSTR to the ISAXXMLReader (the
way
you were initially handling the content). This will create at least one
supplementary copy of the content and might be slow, especially if the
content to be parsed is big
- (IMO, the best and simplest solution) Derive your own class from
CStreamOnServerContext, override the Read virtual with code like:
HRESULT __stdcall Read(void* pDest, ULONG nMaxLen, ULONG* pnRead)
{
HRESULT hRet =__super::Read( pDest, nMaxLen, pnRead);
if( SUCCEEDED(hRet) )
{
char* buff = new char[*pnRead + 1];
strncpy( buff, (char*)pDest, *pnRead);
buff[*pnRead] = 0;
ATLTRACE((char*)pDest);
}
return hRet;
}
- you could write an ISAPI filter that traces the content before getting to
your ISAPI DLL. See the ISAPIFilter sample coming with ATL Server for a
templatye of an ISAPI filter
Hope it work fine for you
--
--
--
This posting is provided "AS IS" with no warranties, and confers no rights.
Please do not send email directly to this alias. It is for newsgroup
purposes only.
thanks,
bogdan
"FS Liu" <fa***********@hotmail.com> wrote in message
news:05****************************@phx.gbl... Hi, Bogdan,
Thank you very much for the valuable message. After I declare CComPtr <MyContent> pContent; pContent is NULL. Yes, you are right. I should CreateInstance after this line. So, I change my program as (a simplified version): CComPtr <ISAXXMLReader> spReader; hr = m_spServiceProvider->QueryService( __uuidof(ISAXXMLReader), &spReader); CComPtr <MyContent> pContent; //pContent = new MyContent(); //hr = pContent.CoCreateInstance( // __uuidof(MyContent), NULL, // CLSCTX_INPROC_SERVER); hr = spReader->putContentHandler(pContent); CStreamOnServerContext s(m_pRequestInfo-pServerContext); CComVariant varStream; varStream = static_cast<IUnknown*>(&s); ATLTRACE((char *)(varStream.bstrVal)); hr = spReader->parse (varStream);
When I use pContent = new MyContent(); to create the instance, VS.NET compiler reports a message saying "cannot instanciate the class" (I am using a Japanese version. I don't know the exact wording of the message in English). Does this mean that I have to include some header files from VS.NET, such as msxml2.h or something else? When I use hr = pContent.CoCreateInstance(__uuidof (MyContent), NULL, CLSCTX_INPROC_SERVER); the compiler also complains: there is no associated GUID. I read atlsoap.h and found the parseFault() function. It is similar to the above code, except the creation of content handler. I tried several ways to create an instance, but failed.
I feel I just have one step further to clearify this issue, but cannot find enough document. Could you help? By the way, "ATLTRACE((char *)(varStream.bstrVal));" does not print the XML string. Do you know why?
Thank you very much.
FS Liu
-----Original Message----- Please see inlines (look for [Bogdan Crivat]) Hope this helps, let me know if you run into any other issues -- -- -- This posting is provided "AS IS" with no warranties, and
confers no rights.Please do not send email directly to this alias. It is for newsgrouppurposes only.
thanks, bogdan
"FS Liu" <fa***********@hotmail.com> wrote in message news:07****************************@phx.gbl... Hi, Bogdan,
Thank you so much for the example. I still have a problem about the use of content handler class, MyContent. All the Microsoft examples use MyContent * pMc = new MyContent(); I defined a content handler that has member variables for pairs of node and value. After running spReader->parse (), I use the resultant pairs in the rest of the program. Is it a better idea to use CComPtr<MyContent> pMc; in ATL Server application project for easier memory management? To do so, is there any special requirement to define the content handler MyContent? Here is my code:
[Bogdan Crivat] -- Yes, this should be a smart pointer. The SAX Reader willAddRef and Release the handler repeatedly. CComPtr is the right way ofensuring the life span of the handler object
CComHeapPtr<CHAR> m_RequestBuffer;// buffer for client POST data. CComPtr<ISAXXMLReader> spReader; HRESULT hr = m_spServiceProvider->QueryService( __uuidof(ISAXXMLReader), &spReader) if(!FAILED(hr)) { CComPtr<MyContent> pMc;
[Bogdan Crivat] -- Based on my understanding of your code, I guess aCreateInstance should appear here. I might be wrong, thoughAlso, below, you might want to have your own implementation ofISAXErrorHandler (which can be included in your SAX Handler class)This would allow you to collect the error and decide later what to do (howto send the information back to the client). I might be wrong, as I am not familiar with the SAXErrorHandlerImpl
if (!pMc) return S_ERROR; hr = spReader->putContentHandler(pMc); SAXErrorHandlerImpl * pEc = new SAXErrorHandlerImpl(); hr = spReader->putErrorHandler(pEc); static wchar_t URL[1000]; mbstowcs( URL, argv[1], 999 ); VARIANT MyVariant; MyVariant.vt = VT_BSTR; MyVariant.bstrVal = (BSTR)m_RequestBuffer;// ERROR HERE! hr = spReader->parse(MyVariant); spReader->Release();//Do we need this here? ATLTRACE("Node: %s Value:%d\n",pMc->Name, pMc->Value); } On the other hand, given m_RequestBuffer as a dynamically allocated memory according to the data length of client POST, I have trouble in packing m_RequestBuffer into a VARIANT to pass to parse(), because the compiler cannot convert m_RequestBuffer from CHAR to BSTR (Please read the comment in the program.) Is there an efficient way (e.g. data type or class) to get client POST data and pass it to spReader->parse() directly, without converting from WCS to MBS or vice versa.
[Bogdan Crivat] The Client POST data does not have to be copied. It is
available as a streaminterface and can be passed directly to the SAXXMLReader. See the following code snippetfor an example:
// Create a stream wrapper on top of the HTTP Server ContextCStreamOnServerContext s(m_pRequestInfo->pServerContext); // Now create a variant that will contain the IUnknown of the IStream objectabove CComVariant varStream; varStream = static_cast<IUnknown*>(&s); HRESULT hr = spReader->parse(varStream); If posible, please try to take a look at the atlsoap.h file coming with VS.That file (the ATL Server SOAP implementation) has to solve problems similar to the ones you have
Finally, do I have to do clean up with "spReader->Release();" for the per-thread spReader? [Bogdan Crivat] No, you don't have to call an extra release. Basically, your code shouldlook like: { CComPtr<ISAXXMLReader> spReader; m_spServiceProvider->QueryService(..., &spReader); ... spReader->putContentHandler(...) ... spReader->parse() ... } Let's assume that initially the ref count for the per- thread reader is 1.QueryService will make it 2. The destructor of the spReader smart pointer will call Release once and makeit back to 1, therefore ready for being used again on the same thread, withdifferent data
Thank you very much.
>-----Original Message----- >Hi > >Mostly for SOAP purposes, ATL Server applications already provide a >per-thread ISAXXMLReader. >( You can disable this feature by defining #define ATL_NO_SOAP, but it is ON >by default) >You can access this per-thread ISAXXMLReader in your request handler with >code like below: > >CComPtr<ISAXXMLReader> spReader; >HRESULT hRet = >m_spServiceProvider->QueryService(__uuidof (ISAXXMLReader), >__uuidof(ISAXXMLReader), &spReader) > >Hope this helps, > >-- >-- >-- >This posting is provided "AS IS" with no warranties, and confers no rights. >Please do not send email directly to this alias. It is for newsgroup >purposes only. > >thanks, >bogdan > > > > >"FS Liu" <fa***********@hotmail.com> wrote in message >news:0d****************************@phx.gbl... >> Hi, >> >> In my current ATL server project, I have to parse the >> input in the client application's request to find out >> the different combination of parameters, instead of >> using SOAP. For this reason, I am not using ATL server >> web service project. On client side, I use POST to send >> XML to web server. I know I should use ISAXXMLReader in >> the server program. I also know that the parser can be >> used for many different handlers in the DLL. I found some >> example of SAX2 from Microsoft as standalone program. >> >> ISAXXMLReader* pRdr = NULL; >> HRESULT hr = CoCreateInstance( >> __uuidof(SAXXMLReader), >> NULL, >> CLSCTX_ALL, >> __uuidof(ISAXXMLReader), >> (void **)&pRdr); >> if(!FAILED(hr)) >> { >> MyContent * pMc = new MyContent(); >> hr = pRdr->putContentHandler(pMc); >> SAXErrorHandlerImpl * pEc = >> new SAXErrorHandlerImpl(); >> hr = pRdr->putErrorHandler(pEc); >> static wchar_t URL[1000]; >> mbstowcs( URL, argv[1], 999 ); >> wprintf(L"\nParsing document: %s\n", URL); >> hr = pRdr->parseURL(URL); >> printf("\nParse result code: %08x\n\n",hr); >> pRdr->Release(); >> delete pMc; >> } >> This looks like a half COM program. Is this against >> ATL Server project? How to make this per thread function? >> What should I do to make it safe, thread-safe, no memory >> leak, etc. Due to the lack of documents and books, I >> cannot find more examples or information. Now, I still >> have some trouble in using it in ATL server application. >> >> Coud anyone help? >> >> Thank you very much. >> >> FS Liu >> > > >. >
.
Thank you so much. It starts to work.
Best regards.
FS Liu This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Maansi Gupta |
last post by:
Hello,
MSXML Version used : MSXML3.0
Language used: VC6.0
Platform: Windows 2000
Am trying to parse a DTD file to create a tree like hierarchical structure
based on certain business rules.
...
|
by: Developer |
last post by:
CoInitialize(NULL);
ISAXXMLReaderPtr pReader = NULL;
CHR(pReader.CreateInstance(__uuidof(SAXXMLReader)));
A1ContentHandler * pA1ContentHandler = A1ContentHandler::CreateInstance();...
|
by: Dhilip Kumar |
last post by:
Hi all,
I have developed a windows service using the windows service project
template in VS.NET. I have used three controls in the service, a timer,
performance counter and a message queue...
|
by: SammyBar |
last post by:
Hi all,
My problem is basic. I'm starting to try web services with Visual
Studio .NET 2002, .NET Framework 1.0. I'm testing the following
configuration for my project. It's a ASP.NET Web Service...
|
by: Jobs |
last post by:
Download the JAVA , .NET and SQL Server interview with answers
Download the JAVA , .NET and SQL Server interview sheet and rate
yourself. This will help you judge yourself are you really worth of...
|
by: Tony Girgenti |
last post by:
Hello.
I'm developing and testing a web application using VS.NET 2003, VB, .NET
Framework 1.1.4322, ASP.NET 1.1.4322 and IIS5.1 on a WIN XP Pro, SP2
computer. I'm using a web form.
How do I...
|
by: Aslane |
last post by:
I have followed the Sax2 JumpStart example (http://msdn2.microsoft.com/en-us/library/ms994335.aspx), to implement a xml Parser in my project. The projects uses DirectX to create a device and use it,...
|
by: erikbower65 |
last post by:
Here's a concise step-by-step guide for manually installing IntelliJ IDEA:
1. Download: Visit the official JetBrains website and download the IntelliJ IDEA Community or Ultimate edition based on...
|
by: Taofi |
last post by:
I try to insert a new record but the error message says the number of query names and destination fields are not the same
This are my field names
ID, Budgeted, Actual, Status and Differences
...
|
by: DJRhino1175 |
last post by:
When I run this code I get an error, its Run-time error# 424 Object required...This is my first attempt at doing something like this. I test the entire code and it worked until I added this -
If...
|
by: Rina0 |
last post by:
I am looking for a Python code to find the longest common subsequence of two strings. I found this blog post that describes the length of longest common subsequence problem and provides a solution in...
|
by: DJRhino |
last post by:
Private Sub CboDrawingID_BeforeUpdate(Cancel As Integer)
If = 310029923 Or 310030138 Or 310030152 Or 310030346 Or 310030348 Or _
310030356 Or 310030359 Or 310030362 Or...
|
by: lllomh |
last post by:
Define the method first
this.state = {
buttonBackgroundColor: 'green',
isBlinking: false, // A new status is added to identify whether the button is blinking or not
}
autoStart=()=>{
|
by: lllomh |
last post by:
How does React native implement an English player?
|
by: Mushico |
last post by:
How to calculate date of retirement from date of birth
|
by: DJRhino |
last post by:
Was curious if anyone else was having this same issue or not....
I was just Up/Down graded to windows 11 and now my access combo boxes are not acting right. With win 10 I could start typing...
| |