STL Map Use

STL 2 Comments »

What’s wrong with the following code?

  1. template<typename T1, typename T2>
  2. struct my_pair
  3. {
  4.     typedef T1 first_type;
  5.     typedef T2 second_type;
  6.  
  7.     my_pair() : first(T1()), second(T2()) {}
  8.     my_pair(const T1& v1, const T2& v2) : first(v1), second(v2) {}
  9.  
  10.     T1 first;
  11.     T2 second;
  12. };
  13.  
  14. template<typename T1, typename T2>
  15. inline bool operator<
  16.     (
  17.     const my_pair<T1, T2>& x,
  18.     const my_pair<T1, T2>& y
  19.     )
  20. {
  21.     return (x.first < y.first || x.second < y.second);
  22. }
  23.  
  24. void f()
  25. {
  26.     typedef my_pair<…, …> key_type;
  27.     typedefvalue_type;
  28.     typedef std::map<key_type, value_type> map_type;
  29.  
  30.     map_type map;
  31.     // Use map
  32. }

Read the rest of this entry »

STL Vector Use

STL 5 Comments »

I recently wrote a piece of code that looked something like the following:

  1. static const int NUM_TOTAL_VALUES = …;
  2. typedefT;
  3.  
  4. // Create vec and reserve NUM_TOTAL_VALUES spaces for later insertion
  5. std::vector<T> vec(NUM_TOTAL_VALUES);
  6.  
  7. // Insert values into vec
  8. for (int i = 0; i != NUM_TOTAL_VALUES; ++i)
  9.     vec.push_back();
  10.  
  11. // vec should now have NUM_TOTAL_VALUES values in it (but doesn’t!)

What’s wrong with this code?

Read the rest of this entry »

Managed Wrappers and Hidden Interdependencies

C#, C++ 2 Comments »

Let’s say you have the following unmanaged code:

  1. #pragma unmanaged
  2.  
  3. class Stream {}; // Conceptual stream class
  4.  
  5. class StreamWriter
  6. {
  7. public:
  8.     StreamWriter(Stream* pStream) : m_pStream(pStream) {}
  9.     ~StreamWriter() { /* Use m_pStream in some way */ }
  10.  
  11.     …
  12. private:
  13.     Stream* m_pStream;
  14. };
  15.  
  16. void f()
  17. {
  18.     Stream stream;
  19.     StreamWriter streamWriter(&stream);
  20.  
  21.     // Use streamWriter
  22.  
  23.     // streamWriter is destroyed
  24.     // stream is destroyed
  25. }

Note that StreamWriter’s destructor uses m_pStream (perhaps by flushing the stream). This means that the order of destruction is importantStreamWriter must be destroyed before its underlying Stream is.

Now let’s try to write and use some simple managed C++ wrappers for these classes:

  1. #pragma managed
  2.  
  3. public __gc class ManagedStream
  4. {
  5. public:
  6.     ManagedStream() : m_pStream(new Stream) {}
  7.  
  8.     // NOTE: This is a finalizer, not a determinstic destructor  
  9.     ~ManagedStream() { delete m_pStream; }
  10.  
  11. public private: // Make accessible by ManagedStreamWriter
  12.     Stream __nogc* m_pStream;
  13. };
  14.  
  15. public __gc class ManagedStreamWriter
  16. {
  17. public:
  18.     ManagedStreamWriter(ManagedStream* pStream) :
  19.         m_pStreamWriter(new StreamWriter(pStream->m_pStream)) {}
  20.  
  21.     // NOTE: This is a finalizer, not a determinstic destructor  
  22.     ~ManagedStreamWriter() { delete m_pStreamWriter; }
  23.  
  24. private:
  25.     StreamWriter __nogc* m_pStreamWriter;
  26. };
  27.  
  28. void f()
  29. {
  30.     ManagedStream stream = __gc new ManagedStream();
  31.     ManagedStreamWriter streamWriter =
  32.         __gc new ManagedStreamWriter(stream);
  33.  
  34.     // Use streamWriter
  35.  
  36.     // GC will clean up stream and streamWriter
  37. }

See the problem?

Read the rest of this entry »

XSLT Variable Scoping Differences Across MSXML Versions

XSLT No Comments »

Subtle differences in variable scoping in XSLTs between MSXML 3.0 and 4.0 can result in XSLT files breaking if you upgrade your version of MSXML. Consider the following XSLT:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml"
                version="1.0"
                encoding="UTF-8"
                indent="yes" />

    <xsl:template match="/">
        <root>
            <elem>
                <xsl:variable name="foo">Value</xsl:variable>
                <xsl:value-of select="$foo" />
            </elem>
            <elem>
                <!-- This refers to the variable defined in
                     the previous sibling elem node -->
                <xsl:value-of select="$foo" />
            </elem>
        </root>
    </xsl:template>
</xsl:stylesheet>

This stylesheet (which does not depend on the input XML) works on MSXML 3.0 but fails on MSXML 4.0 with the error message

A reference to variable or parameter ‘foo’ cannot be resolved. The variable or parameter may not be defined, or it may not be in scope.

Clearly, MSXML 4.0 limits the scope of the foo variable to the first elem node, whereas MSXML 3.0 does not. I suspect MSXML 3.0 scopes a variable to its enclosing template.

These scoping differences cut both ways. Consider this attempt to fix the XSLT:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml"
                version="1.0"
                encoding="UTF-8"
                indent="yes" />

    <xsl:template match="/">
        <root>
            <elem>
                <xsl:variable name="foo">Value</xsl:variable>
                <xsl:value-of select="$foo" />
            </elem>
            <elem>
                <xsl:variable name="foo">Value</xsl:variable>
                <xsl:value-of select="$foo" />
            </elem>
        </root>
    </xsl:template>
</xsl:stylesheet>

This stylesheet works on MSXML 4.0 but fails on MSXML 3.0 with the error message

Variable or parameter ‘foo’ cannot be defined twice within the same template.

If you want the stylesheet to work on both processors, you must push up the variable declaration as follows:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml"
                version="1.0"
                encoding="UTF-8"
                indent="yes" />

    <xsl:template match="/">
        <root>
            <xsl:variable name="foo">Value</xsl:variable>
            <elem>
                <xsl:value-of select="$foo" />
            </elem>
            <elem>
                <xsl:value-of select="$foo" />
            </elem>
        </root>
    </xsl:template>
</xsl:stylesheet>

Be careful. Even the smallest of changes can break your software.

Generating PDFs

C No Comments »

I was looking for a free, open source software library for generating PDFs, and Sean O’Connor pointed me to HARU. I’ll have to check it out.

Smart Pointers Aren’t Quite Smart Enough…

C++, COM No Comments »

What’s wrong with this code? (It is adapted from something I wrote yesterday)

  1. void f()
  2. {
  3.     HRESULT hr;
  4.  
  5.     hr = ::CoInitialize(NULL);
  6.     if (SUCCEEDED(hr)) {
  7.         MSXML2::IMXWriterPtr spMXWriter;
  8.         hr = spMXWriter.CreateInstance(__uuidof(MSXML2::MXXMLWriter30));
  9.         if (SUCCEEDED(hr)) {
  10.             // Use spMXWriter
  11.         }
  12.  
  13.         ::CoUninitialize();
  14.     }
  15. }

Read the rest of this entry »

Writing Streaming XML Using MSXML

C++, COM, Win32, XML No Comments »

In my posts Implementing IXmlWriter Series, I wrote a streaming XML writing class whose interface is based on .NET’s XmlWriter. I recently discovered that MSXML provides its own method to write streaming XML through the class MXXMLWriter.

MXXMLWriter supports a large set of functionality including encoding, indentation, disabling output escaping, and writing XML fragments. The generated XML can be written to an IStream, a BSTR, or a DOMDocument object. However, it’s interface leaves much to be desired. Usage looks like this:

  1. #import <msxml3.dll>
  2.  
  3.  
  4. // I’m using the #import-generated _com_ptr_t-based smart pointers
  5. MSXML2::IMXWriterPtr spMXWriter;
  6. hr = spMXWriter.CreateInstance(__uuidof(MSXML2::MXXMLWriter30));
  7. _ASSERT(SUCCEEDED(hr)); // TODO
  8.  
  9. // Configure the IMXWriter as appropriate.  We will be using the default of
  10. // writing to a BSTR which can be retrieved using spMXWriter->get_output().
  11.  
  12. MSXML2::ISAXContentHandlerPtr spSAXContentHandler(spMXWriter);
  13. _ASSERT(spSAXContentHandler != NULL); // TODO
  14.  
  15. // Be sure to check the hrs below
  16.  
  17. hr = spSAXContentHandler->startDocument();
  18. hr = spSAXContentHandler->startElement(L"", 0, L"root", 4, L"root", 4, NULL);
  19. hr = spSAXContentHandler->characters(L"text", 4);
  20. // endElement also takes the element name.  This means we may need to
  21. // maintain our own open element stack.
  22. hr = spSAXContentHandler->endElement(L"", 0, L"root", 4, L"root", 4);
  23. hr = spSAXContentHandler->endDocument();

The rough IXmlWriter equivalent is:

  1. #include "StringXmlWriter.h"
  2.  
  3.  
  4. StringXmlWriter xw;
  5. xw.WriteStartDocument();
  6.   xw.WriteStartElement("root");
  7.     xw.WriteString("text");
  8.   xw.WriteEndElement(); // /root
  9. xw.WriteEndDocument();

However, there might be a case to change IXmlWriter to use MXXMLWriter internally.

MSXML Versions

Win32, XML No Comments »

The Microsoft XML team recently posted in their blog a set of recommendations on which version of MSXML to use. In short, they recommend using MSXML 6.0 but falling back to 3.0 if it isn’t available.

My product currently tries MSXML 4.0 first — but only SP2 and above. We ran into bugs with previous versions of MSXML 4.0. I will have to evaluate moving to MSXML 6.0.

Exception Handling: A False Sense Of Security

C++, Error Handling No Comments »

Long-time readers know that I have a bit of a penchant for error handling, especially with respect to exceptions. I just noticed that I have never, to my knowledge, posted about the classic article “Exception Handling: A False Sense of Security” by Tom Cargill.

Read it and weep.

Google Code Search

Programming No Comments »

Google Code Search logo

Google has released a new application called Google Code Search that allows you to search for arbitrary strings in public source code. Here is a search for the phrase “Steven Engelhardt”.

This makes me want to write more public source code.

WP Theme & Icons by N.Design Studio
Entries RSS Comments RSS Log in