Reputation: 1001
I am trying to analyze a geotiff file, very simple, just trying to get all the tag information. I know there are libs available such as libtiff and libgeotiff. What I want to do is simple: read out all the tags.
The tag structure is:
struct ifd_entry
{
_int16 tag_id;
_int16 field_type;
_int16 field_count;
_int16 field_offset;
};
the field type is an int16, which stands for int8, int16, int32, float, double and other formats. The field_count indicates the number of data in the type. Field_offset indicates the field data location in the file starting from the file beginning.
What I want to do is to retrieve the tag and the field data it points to. I would like to write in a neat c++ way, but I do not know how to do that. It seems I cannot avoid using the switch statement to deal with each type separately:
class ifd
{
ifd_entry hd;
char *pfield;
public:
ifd(ifd_entry hd0,char *p); //allocate and copy the field data
void print(); //print the ifd_entry and its field, have to use switch to cast to the correct type;
};
It might be trivial, but I wonder what would be the neat way in C++ to deal with such problems. Thank you.
Upvotes: 0
Views: 340
Reputation: 66922
std::ifstream instream("settings.txt");
template<> id<_int8> {enum{value=1};};
template<> id<_int16> {enum{value=2};};
template<> id<_int32> {enum{value=2};};
template<class TYPE>
std::vector<TYPE> read(const ifd_entry& entry) {
assert(id<TYPE>::value == entry.tag_id);
instream.seek(entry.field_offset);
std::vector<TYPE> result.resize(entry.field_count);
instream.read((char*)(TYPE*)(&result[0]), sizeof(entry.field_type)*entry.field_count);
return result;
}
int main() {
ifd_entry entry;
// read in entry
// you know it points to _int32's because it's player's scores
std::vector<_int32> result = read<_int32>(entry);
}
This assumes that you only know the return type in the calling code. This may or may not be applicable to your situation. Also, it's dubious that the code above would compile as-is.
Upvotes: 0
Reputation: 81349
If the number of types is fixed and short, I would use Boost.Variant
. Having a variant over the possible types, then the visitor pattern can be applied to for instance print the fields. The internal implementation may not be too different from what you are currently doing, but I find it more idiomatic.
Upvotes: 1