|
Thanks, it's a good job !!
but there are many memory leaks in your app !!
Can you do something for this ??
thanks
|
|
|
|
|
There are a number of memory leaks dealing with bstr's (which I didn't take the time to track down and fix). However, many of the other leaks can be fixed by three simple changes:
Memory leak 1 (ZXmlParserImpl.h):
namespace XMLPrivate
{
. . .
class XmlParserProxyRead : public XmlParserProxy
{
virtual void do_attrib(const char* key, string& str)
{m_p.do_read_member(*(new Value2<string>(str)),key);}
// This method always allocates a new 'Value2<string>', but the new object
// is not always thrown. In fact, usually it is simply forgotten.
. . .
};
}
// Change to...
namespace XMLPrivate
{
. . .
class XmlParserProxyRead : public XmlParserProxy
{
virtual void do_attrib(const char* key, string& str)
{
XmlObject* pObj = new Value2<string>(str);
m_p.do_read_member(*pObj,key);
// If we made it to here, pObj was not thrown. Clean up.
delete pObj;
}
. . .
};
}
Memory leak 2 (ZXmlParserImpl.h):
inline XmlObject& xmlproxy(string &s) {return *(new XMLPrivate::Value2<string>(s));}
inline XmlObject& xmlproxy(int &i) {return *(new XMLPrivate::Value2<int>(i));}
inline XmlObject& xmlproxy(float &i) {return *(new XMLPrivate::Value2<float>(i));}
// ^ These functions always allocate a new object.
. . .
template <class T>
inline void determine(T& t,const char* str,XmlParserProxy& p,void*,common_t)
{
p.do_member(xmlproxy(t),str);
// ^ Always allocates a new XMLPrivate::Value2<> of some sort. If the
// new object is not thrown by p.do_member(), the object leaks.
}
class XmlParserProxyRead : public XmlParserProxy
{
. . .
virtual void do_member(XmlObject& t,const char* str) throw(XmlObject*)
{m_p.do_read_member(t,str);}
. . .
}
void ZXmlParserImpl::do_read_member(XmlObject& t,const char* str) throw(XmlObject*)
{
if(load()==str) // If this test is false, t leaks.
throw &t;
}
// Change to...
template <class T>
inline void determine(T& t,const char* str,XmlParserProxy& p,void*,common_t)
{
XmlObject* pObj = new XMLPrivate::Value2<T>(t);
p.do_member(*pObj,str);
// If we make it to here, pObj was not thrown. Clean up.
delete pObj;
}
Memory leak 3 (ZXmlParser.cpp):
void ZXmlParser::parse(const _bstr_t& strFileName, bool isFile)
{
XMLNode* hItemRoot = new XMLNode;
. . .
print(hItemRoot, "");
// ^ hItemRoot is allocated, but never freed.
}
// Change to...
void ZXmlParser::parse(const _bstr_t& strFileName, bool isFile)
{
XMLNode* hItemRoot = new XMLNode;
. . .
print(hItemRoot, "");
// Clean up.
delete hItemRoot;
}
I hope this helps
John Kirk
"Man - A figment of God's imagination" Mark Twain
|
|
|
|
|
Hi Mike,
What do u think about this changes???
|
|
|
|
|
Hey Mike:
Great job on the class. A couple questions/comments for you:
1. Personally, I really like third party classes to be in one .h file. I know it's somewhat... ugly when developing, but I hate having to put someone else's cpp files in my project... well, possibly a personal preference.
2. Will this class work if COM is initialized in Multithreaded mode? How about neutral?
3. I can't remember for sure, but I seem to recall reading in Effective STL that deriving from a container is a fairly bad idea... anyone else encountered this? I notice you're doing that with vector, just wondering if that might have bad consequences.
4. From what I understand of template specialization, you can't define a template function that takes a pointer, and then specialize it to take a base type. Indeed, when I compile your sample with VC.NET, it complains that it can't deduce the bool argument to _check from H* -- it's not picking up the specialization. I changed the H* to H, and tweaked your specialization so it now looks like this:
template<class H> inline bool _check(H hr)
{
return hr!=0;
}
template<> inline bool _check(bool hr)
{
return hr;
}
And that seems to work on VC.NET. (VC.NET supposadly implements more of the C++ standard than VC6... which would explain why VC6 would let it slide...)
Anyway, great job overall.
----------------------------------------
----I said my name wasn't important
---------------------------SlartiBartFast
|
|
|
|
|
Hello Eugene.
Sorry for delay. I just read your message
1. .h with .cpp
I guess that you put a lot of YOUR code in .cpp files and that is why don't like to see third party code there. You see, I put my code in .cpp
Without joke, it decreases compilation time.
2. Multithreaded mode
yes it is working in my 20 projects in Multithreaded mode. I don't make any CoInitialize in my "library" code.
3. deriving from a container
Yes is not good idea, but only for STL, I haven't read that book, but I think I will be near the author, because vector and etc. doesn't have virtual functions, may be some other issues. But I don't make any pointers to that vectors. You can use std::vector instead of vectordel, just don't forget to delete all stored pointers there.
4. typename in template
I wrote it to catch any pointer to a class , if _check(H ) work - very well.
Mike.
|
|
|
|
|
I really like your approach for XML processing.
However, in most cases I prefer std::list to std::vector , therefore I've made following additions to ZXmlParserImpl.h at the given positions:
line 175:
struct list_t{}; template <class T> list_t type(list<T>& ) {return list_t();}
line 260:
template <class T,typename NewT>
inline void determineList(list<T>& ls,const char* str,XmlParserProxy& p,NewT* _t, common_t t_)
{
if(p.isRead())
{
if(p.load()==str)
{
ls.push_back(T());
throw &xmlproxy(*ls.rbegin());
}
}
else
{
for (list<T>::iterator it = ls.begin (); it != ls.end(); ++it)
{
determine(*ls,str,p,_t,t_);
}
}
}
template <class T,typename NewT>
inline void determineList(list<T>& ls,const char* str,XmlParserProxy& p,NewT* _t,Object_t t_)
{
if(p.isRead())
{
if(p.load()==str)
{
NewT* node = new NewT();
ls.push_back(node);
throw node;
}
}
else
{
for (list<T>::iterator it = ls.begin (); it != ls.end(); ++it)
{
determine(*it,str,p,_t,ObjectPtr_t());
}
}
}
template <class T,typename NewT>
inline void determine(list<T>& ls,const char* str,XmlParserProxy& p,NewT* _t,list_t)
{
determineList(ls,str,p,_t,type(*_t));
}
Your usage of templates really facilitate the extension of your solution
Regards
Thomas
Sonork id: 100.10453 Thömmi
Disclaimer: Because of heavy processing requirements, we are currently using some of your unused brain capacity for backup processing. Please ignore any hallucinations, voices or unusual dreams you may experience. Please avoid concentration-intensive tasks until further notice. Thank you.
|
|
|
|
|
... just a bit more documentation would greatly enhance the use of your otherwise excellent implementation.
I think that its almost impossible for beginners to understand how and why it works.
Maybe you could add a more detailed and commented sample to your article?
cheers
Andreas
|
|
|
|
|
Thank you, Andreas
You are right.
Yes, I am planning to modify article (make some changes in sources and documentation) and give some more samples. Also I am planning to post one more article with a sample that will show real-life usage of my technology.
From another side, as I said in my article, I tried to simplify "clients" (programmers) work, that is why - "server" part (implementation) is enough complex.
Mike.
|
|
|
|
|
If u add some samples and improve a little the documentation ... It could beceome a great article!!!
I really hope u do it soon ´cause personally I do like the article.
|
|
|
|
|
I am using expat to read the xml files, this is my file
extern char **file(char *);
char html();
int index;
struct elementStruct
{
XML_Char elementData[9];
const XML_Char * elementArray;
const XML_Char ** elementAttr;
};
struct elementStruct EArray[3]={{NULL,"id",NULL},
{NULL,"number",NULL}, {NULL,"title",NULL}}
struct elementStruct EArray[3];
static void startElement(void *userData, const XML_Char *name, const XML_Char **atts){}
static void charHandler(void *userData, const char *s, int len){}
static void endElement(void *userData, const XML_Char *name){}
I can able to read the element name, and the all the data in order of xml file.
What I need is to able to read the element 'data' to pass through html form and display to the web using cgi.
Please help me with examle,
Thanks you very much
CD
cindy
|
|
|
|
|
Hallo Mike
If I load a xml file and change some settings and save the file, it works fine. But how to save a new Document?
Something like that dont work:
Document doc;
XML::ZXmlParserImpl parser(&doc);
doc.Pipeline.m_name = "SomeName";
parser.save(FileName);
An example would be nice.
Thanks in advance.
Daniel
|
|
|
|
|
Shame on me
please add constructor to iniialize Pipeline like this
Pipeline() : m_someObject(0),m_count(0),m_sum(0) {}
than your code should work
Document doc;
XML::ZXmlParserImpl parser(&doc);
doc.m_pipeline.m_name = "SomeName";
parser.save(_bstr_t("new_test.xml"));
Mike
|
|
|
|
|
Hallo Mike
Good job!
After playing around a little bit, I understand it now.
Its realy easy to use.
Thank you fore sharing!
Best regards, Daniel
|
|
|
|
|
Hi, developers
As I can see, most of you don't like my article
But please tell me, why (unuseful, bad programming style, uncommented, undocumented, not understandable, bad english) ?
I'll delete it after your explanations.
Mike.
|
|
|
|
|
Mike, I know NOTHING about XML, and haven't looked at your article in depth, but could I just say that:
a/ 5 people have voted and the averge vote is 2.8. With such a low number of people voting, one person giving you a 1 because they looked and then decided they don't use XML either would pull your total right down
b/ From the glance I gave your article, you have gone into some depth in explaining what you are doing, and it's my opinion that the fact that five people between them decided to mark you low but didn't comment doesn't equate to people hating it. Have a look at some of the REALLY low marked articles to see how quickly people around here present their opinion when it's really in the negative. It looks well written and worthwhile to me.
c/ As a result of a project I am involved with I believe I will be doing some XML soonish and when I do I will look up this article, so on a personal level I would prefer to see it remain.
I think it should stay and I don't think it's been badly recieved, more that it's been ignored because most of us don't have a use for it. That doesn't mean it's bad, and probably means that the people who need this info will *really* need it.
Christian
As I learn the innermost secrets of the around me, they reward me in many ways to keep quiet.
Men with pierced ears are better prepared for marriage. They've experienced pain and bought Jewellery.
|
|
|
|
|
Thanks, Christian, for your kind words.
I am opened for questions.
Mike
|
|
|
|
|
I like templates,
but your classes are a bit strange and I don't understand it that much.
But they seem powerful. I'll try to use them.
And maybe a working sample with source code would allow the developpers to understand it very quickly !
Also, you could correct all the "than" with "then" (the "bad" english)
|
|
|
|
|
oups sorry there is one !
I check it.
|
|
|
|
|