ShaderOp.com

ShaderOp.com

Hi there. I have moved to a new website at Mhmmd.org. I'm no longer updating this one, but I'm keeping it around so the Internet wouldn't break. See you there.

Glossy Reflection and Refraction Shaders for 3Delight for Softimage

Watch:

Download:
SO_3DelightShaders_v0.2.xsiaddon.zip

Enjoy!

Update (July 5th 2011):
This version of the plug-in does not work with 3Delight v3.0.9 and later. If you are using that or a later version of 3Delight then you need to Grab the updated plug-in from here.

Buy This DVD: Creative Character Design Techniques

More accurately titled “Creative Character Design Techniques with Neville Page: Fostering Happy Accidents,” which is a short set of training videos showing one artist’s approach to generating character design ideas quickly and almost effortlessly.

For me it was an eye-opening experience. I don’t have any formal artistic training to speak of, and yet after watching the training videos and spending a few hours with a Wacom Intuos tablet and Sketchbook Pro, this came out:

Portrait-of-a-man

For me this a personal best, and it’s miles ahead of anything I have ever attempted to paint in my whole life. I’m specially proud of the fact that I didn’t use any reference images.

Thank you Mr. Page!

A Simple, Intra-Process Event Bus in C++, Part I

A previous post introduced a way of assigning a unique ID number to arbitrary C++ types. As already mentioned in that post, my motivation for doing this was to lay the foundation for a simple, intra-process messaging system suitable for use in games (particularly the examples presented in Programming Game AI by Example).

This post presents a possible implementation for such a messaging system. To avoid confusion with inter-process or network messaging, I’ll refer to “messages” as “events” from now on, which is a less loaded and more accurate term.

But first, let’s introduce the hero.

Saving the world from nine to five

We’ll be building a console-based, non-interactive game that depicts a normal day in the life of a superhero. And please don’t take the phrase “normal day in the life of a superhero” to be some sort of cynical commentary about the state of contemporary story telling or the human condition on my part.

Our hero’s day consists of six main events: waking up, driving to work, checking in, checking out, driving back, arriving home, and going to bed. Here’s one possible way to present his entire miserable existence in code:

class Hero
{
private:
    int m_clockTicks;

public:
    Hero(): m_clockTicks(0) {}

    void Update()
    {
        switch (m_clockTicks++ % 6)
        {
        case 0:
            std::cout << "Hero: Yaaaaawn!" << std::endl;
            break;
        case 1:
            std::cout << "Hero: Getting into the Hero Mobile(tm)."
                      << std::endl;
            break;
        case 2:
            std::cout << "Hero: Punching into the Hero Cave(tm)."
                      << std::endl;
            break;
        case 3:
            std::cout << "Hero: Phew! Finally going home."
                      << std::endl;
            break;
        case 4:
            std::cout << "Hero: Honey! I'm home!"
                      << std::endl;
            break;
        case 5:
            std::cout << "Hero: Zzzzzzz..." << std::endl;
            break;
        default:
            break;
        }
    }
};

int main(int argc, char** argv)
{
    Hero theHero;

    for (int i = 0; i < 12; ++i)
    {
        theHero.Update();
    }
    return 0;
}

The program iterates over just two days of the hero’s life (hence the 12 in the for loop), and produces the following output:

Hero: Yaaaaawn!
Hero: Getting into the Hero Mobile(tm).
Hero: Punching into the Hero Cave(tm).
Hero: Phew! Finally going home.
Hero: Honey! I'm home!
Hero: Zzzzzzz...
Hero: Yaaaaawn!
Hero: Getting into the Hero Mobile(tm).
Hero: Punching into the Hero Cave(tm).
Hero: Phew! Finally going home.
Hero: Honey! I'm home!
Hero: Zzzzzzz...

Certain species of plankton probably lead more exciting lives, but that’s beside the point.

This game, as awesome as it is already, is missing something. Something that would turn it into a classic. Something that would make it stand shoulder to shoulder next to Fallout 3, Fable II, and Torchlight. It needs a pet.

Like any good, faithful companion, the pet will greet our hero every time he comes back from work. So, we’ll need a way to communicate that event to the pet and any other interested parties (like, say, the Mad Scientist’s advanced abduction and extraction team).

There are many ways to go about implementing this, but for the purpose of maximum decoupling between components it would probably be best to use some sort of event bus, where any object can send an event to the bus, which in turn takes care of relaying the events to all objects interested in receiving them.

After some false starts and dead ends, I ended up with a solution composed of the following components:

  • TypeIdentifer<T>: discussed at length in a previous post.
  • Event: The base case for all events sent and received in the system.
  • IReceiver: An interface to be implemented by event receivers.
  • IEventBus: The interface for the event bus.
  • EventBus: A concrete implementation of IEventBus.

What follows is a closer look at some of these components.

The Event class

This one is ridiculously simple:

namespace Events
{
    class Event
    {
    public:
        virtual ~Event() {}
    };
}

It’s just a marker interface that does nothing on its own.

Our game will have just one event, HeroMovedEvent, defined as follows:

class HeroMovedEvent : public Events::Event
{
public:
    enum Locations { HOME, WORK, ROAD };
private:
    Locations m_location;
public:
    explicit HeroMovedEvent(Locations location)
        : m_location(location)
    {
    }

    Locations Location() const
    {
        return m_location;
    }
};

We’ll see how to use it a bit later.

The IReceiver interface

Which declares a single virtual method:

namespace Events
{
    class IReceiver
    {
    public:
        virtual void Receive(unsigned int eventId, Event* e) = 0;
        virtual ~IReceiver() {};
    };
}

A partial implementation of the Hero’s pet would look like this:

class HerosPet: public Events::IReceiver
{
    /* Some detailed omitted */
public:

    void Receive(unsigned int eventId, Events::Event* e)
    {
        if (eventId == Events::TypeIdentifier<HeroMovedEvent>::id())
        {
            HeroMovedEvent* e_ = static_cast<HeroMovedEvent*>(e);
            OnHeroMoved(e_);
        }
    }

    void OnHeroMoved(HeroMovedEvent* e)
    {
        if (e->Location() == HeroMovedEvent::HOME)
        {
            std::cout << "Pet:  Woof! Woof!" << std::endl;
        }
    }
};

We’ll add the missing details in just a bit.

The IEventBus interface

Defined thusly:

namespace Events
{
    class IEventBus
    {
    public:
        virtual void Register(unsigned int eventId, IReceiver* receiver) = 0;
        virtual void Unregister(unsigned int eventId, IReceiver* receiver) = 0;
        virtual void Unregister(IReceiver* receiver) = 0;
        virtual void Broadcast(unsigned int eventId, Event* event) = 0;
        virtual ~IEventBus() {}
    };
}

Any class that wants to be notified of events registers itself with the bus by passing the event id (obtained through TypeIdentifier<T>::id method) and itself to the Register method. The reverse operation is done by passing the same arguments to the Unregister method. The second version of Unregister is just a convenience method that unsubscribes a receiver from all events.

I provided an implementation for this interface in a class named EventBus, the details of which aren’t very interesting, so I won’t go over them here.

The Revised Game

Using the components above, the Hero class changes to this:

class Hero
{
private:
    int m_clockTicks;
    Events::IEventBus* m_eventBus;
public:
    explicit Hero(Events::IEventBus* eventBus)
        : m_clockTicks(0), m_eventBus(eventBus) {}

    void Update()
    {
        switch (m_clockTicks++ % 6)
        {
        case 0:
            {
                std::cout << "Hero: Yaaaaawn!" << std::endl;
                break;
            }
        case 1:
            {
                std::cout << "Hero: Getting into the Hero Mobile(tm)."
                          << std::endl;
                HeroMovedEvent e(HeroMovedEvent::ROAD);
                m_eventBus->Broadcast
                    ( Events::TypeIdentifier<HeroMovedEvent>::id()
                    , &e
                    );
                break;
            }
        case 2:
            {
                std::cout << "Hero: Punching into the Hero Cave(tm)."
                          << std::endl;
                HeroMovedEvent e(HeroMovedEvent::WORK);
                m_eventBus->Broadcast
                    ( Events::TypeIdentifier<HeroMovedEvent>::id()
                    , &e
                    );
                break;
            }
        case 3:
            {
                std::cout << "Hero: Phew! Finally going home."
                          << std::endl;
                HeroMovedEvent e(HeroMovedEvent::ROAD);
                m_eventBus->Broadcast
                    ( Events::TypeIdentifier<HeroMovedEvent>::id()
                    , &e
                    );
                break;
            }
        case 4:
            {
                std::cout << "Hero: Honey! I'm home!"
                          << std::endl;
                HeroMovedEvent e(HeroMovedEvent::HOME);
                m_eventBus->Broadcast
                    ( Events::TypeIdentifier<HeroMovedEvent>::id()
                    , &e
                    );
                break;
            }
        case 5:
            {
                std::cout << "Hero: Zzzzzzz..." << std::endl;
                break;
            }
        default:
            break;
        }
    }
};

Nothing fancy here. The Hero class raises a HeroMovedEvent whenever the Hero changes locations.

And here’s the full implementation of the HerosPet class presented earlier:

class HerosPet: public Events::IReceiver
{
private:
    Events::IEventBus* m_eventBus;
public:
    explicit HerosPet(Events::IEventBus* eventBus)
        : m_eventBus(eventBus)
    {
        m_eventBus->Register
            ( Events::TypeIdentifier<HeroMovedEvent>::id()
            , this
            );
    }

    ~HerosPet()
    {
        m_eventBus->Unregister(this);
    }

    void Receive(unsigned int eventId, Events::Event* e)
    {
        if (eventId == Events::TypeIdentifier<HeroMovedEvent>::id())
        {
            HeroMovedEvent* e_ = static_cast<HeroMovedEvent*>(e);
            OnHeroMoved(e_);
        }
    }

    void OnHeroMoved(HeroMovedEvent* e)
    {
        if (e->Location() == HeroMovedEvent::HOME)
        {
            std::cout << "Pet:  Woof! Woof!" << std::endl;
        }
    }
};

And here’s the main method that wires all the components together:

int main(int argc, char** argv)
{
    Events::EventBus theBus;
    Hero theHero(&theBus);
    HerosPet thePet(&theBus);

    for (int i = 0; i < 12; ++i)
    {
        theHero.Update();
    }
    return 0;
}

And here’s the output:

Hero: Yaaaaawn!
Hero: Getting into the Hero Mobile(tm).
Hero: Punching into the Hero Cave(tm).
Hero: Phew! Finally going home.
Hero: Honey! I'm home!
Pet:  Woof! Woof!
Hero: Zzzzzzz...
Hero: Yaaaaawn!
Hero: Getting into the Hero Mobile(tm).
Hero: Punching into the Hero Cave(tm).
Hero: Phew! Finally going home.
Hero: Honey! I'm home!
Pet:  Woof! Woof!
Hero: Zzzzzzz...

This works nicely. The sender and receiver only need to know about the IEventBus interface and the type of the events they wants to exchange. But there’s one problem, and that is the Receive method in HerosPet:

    void Receive(unsigned int eventId, Events::Event* e)
    {
        if (eventId == Events::TypeIdentifier<HeroMovedEvent>::id())
        {
            HeroMovedEvent* e_ = static_cast<HeroMovedEvent*>(e);
            OnHeroMoved(e_);
        }
    }

This is fine for now, but as the number of events increases, the Receive method will grow into a series of ugly if-else statements, reminiscent of the Windows message loop.

Ideally, this should be made easier by using something like event tables in wxWidgets or message maps in WTL, preferably without using any pre-processor hacks. And I’ll try do just that in the next post. So I’ll defer providing the full source code until then.

Uniquely Identifying Types in C++ without using RTTI

One of the books on my current reading list is Programming Game AI by Example by Mat Buckland. So far it has been an excellent read, except that some of the code snippets have a certain Win32 API feel to them that I find a bit less than optimal.

For example, Chapter 2 has a subsection about adding inter-object messaging capabilities to the sample presented in that chapter. The author proposes using enums to identify each message type that the system can send or receive. So somewhere in the program there should be one (possibly huge) header with the following:

enum message_type
{
    Msg_HeroMoved,
    Msg_WeaponFired,
    Msg_BulletHit,
    .
    .
};

There’s also a corresponding message class for each message_type enum that holds information related to the message, like the new location of the hero in case of a Msg_HeroMoved message, or the type of projectile fired in the case of a Msg_WeaponFired message.

I happen to think that using unique IDs for each message is actually a good idea because if its simplicity. I just have a problem with how it’s implemented. Maintaining both a long list of message IDs and the corresponding message classes feels redundant and error-prone to me.

One could move the ID to the message classes, like so:

class HeroMovedMessage
    : public MessageBase
{
    /* Some details omitted ... */

public:
    static unsigned int TypeId();
    Point Location() const;
}

But that leads to more potential issues. It’s not possible to force every message class to include a static TypeId method, and ensuring that the IDs don’t collide becomes a burden requiring the code author to either maintain a list of IDs externally or check all other message classes manually before adding a new ID.

I can think of a few ways that could make the process less tiresome, but the added complications make the original enum list solution look simple and elegant in comparison.

Something simpler is needed.

Back to the drawing board

What I would like to have is a method that looks like this:

template <typename T> unsigned int TypeId()
{
    // Should return a unique value for each T...
}

If such a method can be implemented, then it would become trivial to identify any message class (or any class in the system for that matter) like so:

class A{};

int main(int argc, char** argv)
{
    unsigned int id = TypeId<A>();

    return 0;
}

This would also work nicely in an ID-based messaging system, since both sender and receiver already know about the message classes they care about and can directly identify them using their type IDs. Message passing could look like the following code:

class HeroMovedMessage
    : public MessageBase
{
    /* some details omitted ... */
public:
    Point Location() const;
};

class Hero
{
private:
    void SendMessage(unsigned int messageId, Message* msg)
    {
        // ...
    }
public:
    void Update()
    {
        HeroMovedMessage msg = HeroMovedMessage(x_, y_);
        SendMessage(TypeId<HeroMovedMessage>(), &msg);
    }
};

class HerosPet
{
public:
    void ReceiveMessage(unsigned int messageId, Message* msg)
    {
        if (messageId == TypeId<HeroMovedMessage>())
        {
            Message* msg_ = static_cast<HeroMovedMessage>(msg);
            // ...
        }
    }
};

So, yes, a working TypeId function would actually work pretty well in this particular case. Now all that is left is an implementation for it. For that, I’ll need two ingredients:

  1. A way to obtain the name of a class as a string.
  2. A hashing algorithm that will produce a unique ID from said string.

Item number two is a solved problem. As discussed at length in the post titled “Hashing Algorithms,” a CRC32 checksum or a SHA-1 or MD5 digest of the name of the class should give a unique ID for any reasonably-sized set of classes. I’ll be using CRC32 for this example because it’s already implemented in Boost.

Item number one requires more effort.

Getting the type name through RTTI

The closest thing to reflection in C++ is Run-Time Type Information (RTTI). The bits I’ll need are the typeid operator and the type_info class. Extracting a class name this was is a breeze:

// Forward declaration
int GenerateCrcChecksum(const char* data);

template <typename T> unsigned int TypeId()
{
    return GenerateCrcChecksum(typeid(T).name());
}

The name method returns the fully qualified name of the class, including the namespace and template parameters (if any). And since it’s part of the standard it should be portable across all compilers.

But we’re not quite done yet. RTTI has a bit of a reputation for being slow. How slow it is is a subject of long and lengthy debates, but I would rather err on the side of mature optimization and avoid RTTI altogether if possible.

Fortunately, there is a way.

Getting some help from the preprocessor

After some furious head scratching I ended up looking through the Microsoft Visual C++ predefined macros for help. The most promising one was the nonstandard __FUNCTION__ macro, described thusly:

Valid only within a function and returns the undecorated name of the enclosing function (as a string). __FUNCTION__ is not expanded if you use the /EP or /P compiler option.

The initial test was disappointing. Here’s the code:

class A{};

template <typename T> void WhatsMyName()
{
    std::cout << __FUNCTION__ << std::endl;
}

int main(int argc, char** argv)
{
    WhatsMyName<A>();
    return 0;
}

And here’s the output

WhatsMyName

Which not useful at all since there’s no mention of the template type used to invoke the function.

I took a shot in the dark and tried using a static member function instead of a free standing one:

class A{};

template <typename T> class WhatsMyName
{
public:
    static void Name()
    {
        std::cout << __FUNCTION__ << std::endl;
    }
};

int main(int argc, char** argv)
{
    WhatsMyName<A>::Name();
    return 0;
}

Here’s the output:

WhatsMyName<class A>::Name

Which is just perfect. I don’t even need to trim the resulting string to extract only the name of the class. I only need to have the fully qualified name somewhere inside the string since all the other text around it is fixed. I have also tested this method with templates and namespaces, and it still works.

GCC has a similar macro called __PRETTY_FUNCTION__ that works along the same lines. Since MSVC and GCC are the only two compilers that I care about, I can fall back to the RTTI method for other compilers.

So the new implementation for TypeId (or TypeIdentifier as it’s now called) becomes:

#include "GenerateTypeId.h"

template<typename T> class TypeIdentifier
{
public:
    static unsigned int id()
    {
        #if defined (_MSC_VER)
            return GenerateTypeId(__FUNCTION__);
        #elif defined(__GNUC__)
            return GenerateTypeId(__PRETTY_FUNCTION__);
        #else
            return GenerateTypeId(typeid(T).name());
        #endif
    }
private:
    TypeIdentifier();
};

I have moved the actual generation of the CRC checksum to a separate function in a different file and added a bit of caching and some checking for duplicate IDs while I was at it. The full source code is provided at the end of this post.

Final thoughts

One caveat here is that I would be very careful about using IDs generated this way for persistence or for sending objects across the wire. CRC checksums are deterministic, but the data used to generate them in this case is not the same across different compilers or possibly different versions of the same compiler. So caveat emptor there.

The other issue is that the IDs might collide given a large set of classes (or a particularly unlucky choice of names). But that problem is easy to detect early on in debug builds, which is what I opted to do in my code. And if that problem does occur then switching from CRC32 to SHA-1 or MD5 or simply renaming one of the two offending classes should take care of it.

Now I’ll leave you with the code. I tested it with Visual C++ 2010, but it should compile on G++ with C++0x extensions enabled.

RAII by Example: Implementing GenerateSha1Hash

In the previous installment of the SHA-1—saga I didn’t provide an implementation for the function GenerateSha1Hash. So I thought it might be a good idea to milk the subject even more by coding it up and using the opportunity to demonstrate how the Resource Acquisition Is Initialization (or RAII, not be confused with Rai) idiom leads to code that is more maintainable and fault-tolerant.

If I were doing something more involved or required cross-platform portability, I would have been better off with the Crypto++ library or something similar. But instead I’ll be using the Cryptography functions from the Win32 API because they rely on manual acquisition and release of resources through handles, which is a better fit for demonstrating RAII in action.

I ended up using the following functions:

This is my initial, RAII-less implementation:

#include "GenerateSha1Hash.h"

#include <windows.h>

int GenerateSha1Hash(const char* data, int8_t** hash, int hashSize)
{
    if (hashSize == 0)
        return 0;

    HCRYPTPROV hCryptProvider = NULL;
    HCRYPTHASH hHash = NULL;

    BOOL status = ::CryptAcquireContext
        ( &hCryptProvider
        , NULL
        , NULL
        , PROV_RSA_FULL
        , 0
        );
    if (status == false)
        return -1;
    status = ::CryptCreateHash(hCryptProvider, CALG_SHA1, 0, 0, &hHash);
    if (status == false)
    {
        ::CryptReleaseContext(hCryptProvider, 0);
        return -1;
    }

    status = ::CryptHashData
        ( hHash
        , reinterpret_cast<const BYTE*>(data)
        , strlen(data) + 1
        , 0
        );

    if (status == false)
    {
        ::CryptDestroyHash(hHash);
        ::CryptReleaseContext(hCryptProvider, 0);
        return -1;
    }

    DWORD hashBufferSize = 0;
    DWORD hashBufferSizeSize = sizeof(DWORD)/sizeof(BYTE);

    status = ::CryptGetHashParam
        ( hHash
        , HP_HASHSIZE
        , reinterpret_cast<BYTE*>(&hashBufferSize)
        , &hashBufferSizeSize
        , 0
        );
    if (status == false)
    {
        ::CryptDestroyHash(hHash);
        ::CryptReleaseContext(hCryptProvider, 0);
        return -1;
    }

    BYTE* hashBuffer = new BYTE[hashBufferSize];
    status = ::CryptGetHashParam
        ( hHash
        , HP_HASHVAL
        , hashBuffer
        , &hashBufferSize
        , 0
        );
    if (status == false)
    {
        delete hashBuffer;
        ::CryptDestroyHash(hHash);
        ::CryptReleaseContext(hCryptProvider, 0);
        return -1;
    }

    int numberOfBytesToCopy = (static_cast<int>(hashBufferSize) < hashSize)?
                              hashBufferSize : hashSize;
    for (int i = 0; i < numberOfBytesToCopy; ++i)
        (*hash)[i] = hashBuffer[i];

    delete hashBuffer;
    ::CryptDestroyHash(hHash);
    ::CryptReleaseContext(hCryptProvider, 0);

    return numberOfBytesToCopy;
}

The mechanics are not that relevant to our example, and anyone could arrive to a similar implementation by reading the MSDN documentation at the links to above. But here are the basic, broad strokes:

  1. Ask the Win32 API for a CryptContext.
  2. Ask the CryptContext for a CryptHash that can produce SHA-1 hashes.
  3. Pass the data to be hashed to the CryptHash.
  4. Ask the CryptHash for the number of bytes it will need to store the hash.
  5. Pass a buffer to the CryptHash and ask it to store the hash in the buffer.
  6. Release all resources.

Which is simple enough. What complicates the code is this refrain:

    if (status == false)
    {
        ::CryptReleaseContext(hCryptProvider, 0);
        return -1;
    }

What later repeats and grows into this:

    if (status == false)
    {
        ::CryptDestroyHash(hHash);
        ::CryptReleaseContext(hCryptProvider, 0);
        return -1;
    }

Finally ending in this off-key crescendo:

    if (status == false)
    {
        delete hashBuffer;
        ::CryptDestroyHash(hHash);
        ::CryptReleaseContext(hCryptProvider, 0);
        return -1;
    }

I’m perfectly fine with the if statements being there. If one of those functions fail, then there’s nothing more to do and the code has to return. What I do have a problem with is the book keeping code that has to tag along at every step of the way, and that’s because it leads to two problems.

First one is maintainability. Repetition and maintainability don’t go well together.

The second and more important issue is this: What about errors I did not account for? What about this line for example:

BYTE* hashBuffer = new BYTE[hashBufferSize];

According to the standard, a call to new could fail by throwing a bad_alloc exception if memory can’t be allocated for one reason or another. Yes, I could surround it with a try-catch block and then repeat the clean up code yet again. But that’s not the point. The point is that exceptions can be thrown from seemingly innocent looking code, and accounting for all such cases is no trivial task.

One might argue that worrying about releasing resources after bad_alloc exceptions is like agonizing over filing the change of address forms at the local post office while the apocalypse is going down in T-minus five minutes.

Similarly one could argue that the chances of any of those cryptography functions failing is next to nil. How dangerous can generating a digest actually be?

I don’t know. And that’s the problem. I can reason, I can theorize, I can guestimate, but I simply don’t know the actual reliability of those functions, and I wouldn’t even know how to start testing it.

And that which you can’t test, you must guard against.

RIAA In Longhand

The best scenario would be to centralize the clean up code somewhere and still maintain robustness against both expected and unexpected errors. That’s where RIAA comes in.

Take for example the pair CryptAcquireContext and CrypeReleaseContext. If CryptAcquireContext is called successfully then its counterpart CryptReleaseContext must also be called at some point, regardless of what happens in the rest of the code.

In RIAA this is done by creating a class that has the sole purpose of calling the clean up code in its destructor. Here’s what such a class might look like in its simplest form:

class CrytpContextHandle{
public:
    CrytpContextHandle(HCRYPTPROV cryptContextHandle)
        : m_cryptContextHandle(cryptContextHandle)
    {
    }

    ~CrytpContextHandle()
    {
        if (m_cryptContextHandle == NULL)
            ::CryptReleaseContext(m_cryptContextHandle, 0);
    }

    HCRYPTPROV Handle() const
    {
        return m_cryptContextHandle;
    }

private:
    HCRYPTPROV m_cryptContextHandle;
};

And here’s how to use it:

    HCRYPTPROV hCryptProvider = NULL;
    HCRYPTHASH hHash = NULL;

    BOOL status = ::CryptAcquireContext
        (&hCryptProvider
        , NULL
        , NULL
        , PROV_RSA_FULL
        , 0
        );
    if (status == false)
        return -1;
    CrytpContextHandle cryptContextHandle(hCryptProvider);

Now CryptReleastContext will be called once the function terminates, whether it’s a normal termination or as a result of an unhandled exception.

Notice that the purpose of the class CrytpContextHandle isn’t to wrap the behavior of the Win32 Cryptography API in something more OO-friendly. It has a simpler and much narrower purpose, and the provided implementation satisfies that purpose succinctly.

A similar RAII class needs to be provided for CryptCreateHash and its counterpart CryptDestroyHash, and possibly another one to delete the hashBuffer. This is not a major burden, but these classes have limited utility since they’ll probably never be used elsewhere in the program.

Wouldn’t be nice if there was a simpler way yet?

Fortunately, there is.

RIAA in shorthand

Deleting the dynamically allocated hashBuffer can be made trivial by using boost::scoped_array. For the rest of the clean up code I’ll use a bit of magic called BOOST_SCOPE_EXIT. Here’s the revised implementation:

#include "GenerateSha1Hash.h"

#include <windows.h>
#include <algorithm>
#include <boost/scoped_array.hpp>
#include <boost/scope_exit.hpp>

int GenerateSha1Hash(const char* data, int8_t** hash, int hashSize)
{
    if (hashSize <= 0)
        return 0;

    HCRYPTPROV hCryptProvider = NULL;
    HCRYPTHASH hHash = NULL;

    BOOL status = ::CryptAcquireContext
        ( &hCryptProvider
        , NULL
        , NULL
        , PROV_RSA_FULL
        , 0
        );
    if (status == false)
        return -1;
    BOOST_SCOPE_EXIT((&hCryptProvider))
    {
        if (hCryptProvider != NULL)
            ::CryptReleaseContext(hCryptProvider, 0);
    } BOOST_SCOPE_EXIT_END

    status = ::CryptCreateHash(hCryptProvider, CALG_SHA1, 0, 0, &hHash);
    if (status == false)
        return -1;
    BOOST_SCOPE_EXIT((&hHash))
    {
        if (hHash != NULL)
            ::CryptDestroyHash(hHash);
    } BOOST_SCOPE_EXIT_END

    status = ::CryptHashData
        (hHash
        , reinterpret_cast<const BYTE*>(data)
        , strlen(data) + 1
        , 0
        );
    if (status == false)
        return -1;

    DWORD hashBufferSize = 0;
    DWORD hashBufferSizeSize = sizeof(DWORD)/sizeof(BYTE);

    status = ::CryptGetHashParam
        ( hHash
        , HP_HASHSIZE
        , reinterpret_cast<BYTE*>(&hashBufferSize)
        , &hashBufferSizeSize
        , 0
        );
     if (status == false)
        return -1;

    boost::scoped_array<BYTE> hashBuffer(new BYTE[hashBufferSize]);
    status = ::CryptGetHashParam
        ( hHash
        , HP_HASHVAL
        , hashBuffer.get()
        , &hashBufferSize
        , 0
        );
    if (status == false)
        return -1;

    int numberOfBytesToCopy = (static_cast<int>(hashBufferSize) < hashSize)?
                              hashBufferSize : hashSize;	

    std::copy(hashBuffer.get(), hashBuffer.get() + numberOfBytesToCopy, *hash);

    return numberOfBytesToCopy;}

This is much better and would have been even shorter if it wasn’t for my funky argument formatting style.

Here’s a closer look at one of the juicer bits:

    BOOL status = ::CryptAcquireContext
        ( &hCryptProvider
        , NULL
        , NULL
        , PROV_RSA_FULL
        , 0
        );
    if (status == false)
        return -1;
    BOOST_SCOPE_EXIT((&hCryptProvider))
    {
        if (hCryptProvider)
            ::CryptReleaseContext(hCryptProvider, 0);
    } BOOST_SCOPE_EXIT_END

Here a resource is acquired and the code that releases it is declared right underneath it inside the BOOST_SCOPE_EXIT macro, which will be called upon exit from the scope in which it resides.

The only hurdle is getting past the crusty ((&variableName)) syntax (which is explained in the Scope Exit tutorial). Otherwise, this is easier to maintain since the clean up code sits right next to the corresponding acquisition code and only has to be written once.

Summing Up

The RAII idiom rose out of necessity to compensate for missing features in C++ like automatic memory management. But I believe its usefulness extends well beyond that into areas like maintainability and fault tolerance. So much so that the RAII idiom is built into some languages that already have garbage collection, like C# with its using keyword and Python and its with statement.

Older posts Newer posts
Powered by: