You could use dynamic array for that or a list with a Uri_PROPERTY value as a key for example and a data as an offset and length. Another way is to compute each property offset only when it's requested and store it. An obvious bad case for that is a long uri. So probably one pass property computation while building IUri instance is not bad.
I like the idea of making a lightweight data structure which stores the offset and length for each component property. I'd imagine it would look something like this:
typedef struct { DWORD offset; DWORD length; } UriComponent;
Although it becomes a little more tricky on how to store the UriComponents, but, I have a few ideas if anyone has any suggestions.
I do like the idea of using an array inside the Uri struct to store the UriComponents but not all of the values in the Uri_PROPERTY enum actually mean anything (at least thats what I have gathered from reading the MSDN docs), like the Uri_PROPERTY_STRING_START and the Uri_PROPERTY_STRING_LAST are just there to say all the enum values between >= START and <= LAST correspond the string components of the URI.
So I'm thinking the Uri struct should have a constant size array of UriComponents of length Uri_PROPERTY_STRING_LAST (which would be 15.. correct me if I'm wrong).
So it would look something like...
typedef struct { /** The other stuff */
BSTR *uri; UriComponents components[15]; } Uri;
and then for the GetPropertyBSTR(BSTR *component, Uri_PROPERTY prop) function you could just have something like.
if(prop >= Uri_PROPERTY_START && prop <= Uri_PROPERTY_LAST) { UriComponent comp; comp = uri->components[prop];
/** Parse the component out */ }
And that should get you the necessary offsets and lengths for the component you need.
I also like the idea suggested before using a one-pass solution to find everything when the Uri is constructed.
Thank you for the quick responses and suggestions, I hope to have a proposal ready in the next few days.