EMAN2
Public Types | Public Member Functions | Private Member Functions | Private Attributes
EMAN::GatanDM4::TagData Class Reference

#include <dm4io.h>

Collaboration diagram for EMAN::GatanDM4::TagData:
Collaboration graph
[legend]

List of all members.

Public Types

enum  Type {
  UNKNOWN = 0, SHORT = 2, INT = 3, USHORT = 4,
  UINT = 5, FLOAT = 6, DOUBLE = 7, BOOLEAN = 8,
  CHAR = 9, OCTET = 10, OCTEU = 11, OCTEV = 12,
  STRUCT = 15, STRING = 18, ARRAY = 20
}

Public Member Functions

 TagData (FILE *data_file, TagTable *tagtable, const string &tagname)
 ~TagData ()
int read_tag_data (bool nodata=false, int image_index=0, int num_images=1)

Private Member Functions

size_t typesize () const
size_t typesize (int type) const
int read_any (bool nodata=false, int image_index=0, int num_images=1)
vector< int > read_array_types ()
int read_array_data (vector< int >item_types, bool nodata=false, int image_index=0, int num_images=1)
vector< int > read_struct_types ()
string read_native (bool is_value_stored)
string read_string (int size)

Private Attributes

FILE * in
TagTabletagtable
string name
long long tag_type

Detailed Description

Definition at line 100 of file dm4io.h.


Member Enumeration Documentation

Enumerator:
UNKNOWN 
SHORT 
INT 
USHORT 
UINT 
FLOAT 
DOUBLE 
BOOLEAN 
CHAR 
OCTET 
OCTEU 
OCTEV 
STRUCT 
STRING 
ARRAY 

Definition at line 103 of file dm4io.h.

                        {
                                UNKNOWN = 0,
                                SHORT = 2,
                                INT = 3,
                                USHORT = 4,
                                UINT = 5,
                                FLOAT = 6,
                                DOUBLE = 7,
                                BOOLEAN = 8,
                                CHAR = 9,
                                OCTET = 10,
                                OCTEU = 11,
                                OCTEV = 12,
                                STRUCT = 15,
                                STRING = 18,
                                ARRAY = 20
                        };

Constructor & Destructor Documentation

TagData::TagData ( FILE *  data_file,
TagTable tagtable,
const string &  tagname 
)

Definition at line 181 of file dm4io.cpp.

        :       in(data_file), tagtable(table), name(tagname), tag_type(UNKNOWN)
{
}
TagData::~TagData ( )

Definition at line 186 of file dm4io.cpp.

{
}

Member Function Documentation

int TagData::read_any ( bool  nodata = false,
int  image_index = 0,
int  num_images = 1 
) [private]

Definition at line 441 of file dm4io.cpp.

References EMAN::GatanDM4::TagTable::add(), ARRAY, EMAN::ByteOrder::become_big_endian(), in, LOGVAR, name, read_array_data(), read_array_types(), read_native(), read_struct_types(), STRING, STRUCT, tag_type, tagtable, and EMAN::GatanDM4::to_str().

Referenced by read_tag_data().

{
        int err = 0;

        size_t nr;
        nr = fread(&tag_type, sizeof(tag_type), 1, in);
        
        ByteOrder::become_big_endian(&tag_type);
        LOGVAR("TagData::read_any tag type = '%s'\n", GatanDM4::to_str((Type) tag_type));


        if (tag_type == ARRAY) {
                vector < int >item_types = read_array_types();
                err = read_array_data(item_types, nodata, image_index, num_images);
        }
        else if (tag_type == STRUCT) {
                vector < int >field_types = read_struct_types();

                for (unsigned int i = 0; i < field_types.size(); i++) {
                        
                        tag_type = static_cast < Type > (field_types[i]);
                        
                        string val = read_native(false);
                        
                        char int_str[32];
                        sprintf(int_str, " #%d", i);
                        string fieldname = name + string(int_str);
                        tagtable->add(fieldname, val);
                }
        }
        else if (tag_type == STRING) {

                int str_sz = 0;
                size_t nr;
                nr = fread(&str_sz, sizeof(str_sz), 1, in);
                ByteOrder::become_big_endian(&str_sz);

                char *val = new char[str_sz + 1];
                nr = fread(val, str_sz, 1, in);
                val[str_sz] = '\0';
                string val_str = string(val);

                if (val) {
                        delete [] val;
                        val = NULL;
                }

                tagtable->add(name, val_str);
        }
        else {
                read_native(true);
        }

        return err;
}
int TagData::read_array_data ( vector< int >  item_types,
bool  nodata = false,
int  image_index = 0,
int  num_images = 1 
) [private]

Definition at line 331 of file dm4io.cpp.

References EMAN::GatanDM4::TagTable::add(), EMAN::GatanDM4::TagTable::add_data(), EMAN::ByteOrder::become_big_endian(), EMAN::GatanDM4::TagTable::become_host_endian(), data, ENTERFUNC, EXITFUNC, EMAN::GatanDM4::TagTable::get_num_images_found(), in, LOGERR, LOGVAR, name, portable_fseek(), read_string(), EMAN::GatanDM4::TagTable::set_num_images_found(), tagtable, typesize(), and USHORT.

Referenced by read_any().

{
        ENTERFUNC;
        if (item_types.size() == 0) {
                LOGERR("DM4 item types cannot be empty");
                return 1;
        }

        int err = 0;
        long long array_size = 0;

        size_t nr;
        nr = fread(&array_size, sizeof(array_size), 1, in);
        ByteOrder::become_big_endian(&array_size);

        LOGVAR("array size = %lld\n", array_size);

        size_t item_size = 0;
        for (size_t i = 0; i < item_types.size(); i++) {
                item_size += typesize(item_types[i]);
        }

        LOGVAR("%s array item size = %lld\n", name.c_str(), item_size);

        size_t buf_size = item_size * array_size;

        if (item_types.size() == 1 && item_types[0] == USHORT && nodata) {
                string val = read_string(array_size);
                tagtable->add(name, val);
                LOGVAR("value: %s", val.c_str());
        }
        else if (!nodata && name == "Data") {
                int num_found = tagtable->get_num_images_found();
                num_found++;
                tagtable->set_num_images_found(num_found);

                char * data;

                if (image_index < 0  ||  buf_size % num_images != 0  ||  num_found == 1) {
                        data = new char[buf_size];
                        nr = fread(data, item_size, array_size, in);
                }
                else {
                        size_t image_size = buf_size / num_images;

                        data = new char[image_size];
                        portable_fseek(in, image_index * image_size, SEEK_CUR);
                        nr = fread(data, image_size, 1, in);
                        portable_fseek(in, (num_images - image_index - 1) * image_size, SEEK_CUR);
                        array_size = array_size / num_images;
                }

                if (item_size == sizeof(short)) {
                        tagtable->become_host_endian((short *) data, array_size);
                }
                else if (item_size == sizeof(int)) {
                        tagtable->become_host_endian((int *) data, array_size);
                }
                else if (item_size == sizeof(double)) {
                        tagtable->become_host_endian((double *) data, array_size);
                }
                else {
                        LOGERR("cannot handle this type of DM4 image data");
                        return 1;
                }

                tagtable->add_data(data);
        }
        else {
                portable_fseek(in, buf_size, SEEK_CUR);
        }
        EXITFUNC;
        return err;
}
vector< int > TagData::read_array_types ( ) [private]

Definition at line 269 of file dm4io.cpp.

References ARRAY, EMAN::ByteOrder::become_big_endian(), in, LOGERR, LOGVAR, read_struct_types(), STRUCT, and EMAN::GatanDM4::to_str().

Referenced by read_any().

{
        LOGVAR("TagData::read_array_types()");

        long long array_type = 0;
        size_t nr;
        nr = fread(&array_type, sizeof(array_type), 1, in);

        ByteOrder::become_big_endian(&array_type);

        LOGVAR("array data type = '%s'", GatanDM4::to_str((Type) array_type));

        vector < int >item_types;

        if (array_type == STRUCT) {
                item_types = read_struct_types();
        }
        else if (array_type == ARRAY) {
                item_types = read_array_types();
                LOGERR("DM4: don't know how to handle this array type");
        }
        else {
                item_types.push_back(array_type);
        }

        return item_types;
}
string TagData::read_native ( bool  is_value_stored) [private]

Definition at line 190 of file dm4io.cpp.

References EMAN::GatanDM4::TagTable::add(), EMAN::GatanDM4::TagTable::become_host_endian(), BOOLEAN, CHAR, DOUBLE, FLOAT, in, INT, LOGERR, LOGVAR, name, OCTET, OCTEU, OCTEV, SHORT, tag_type, tagtable, typesize(), UINT, and USHORT.

Referenced by read_any().

{
        size_t sz = typesize();
        size_t nr;
        char val_str[32];

        if (tag_type == SHORT) {
                short val = 0;
                nr = fread(&val, sz, 1, in);
                tagtable->become_host_endian(&val);
                sprintf(val_str, "%d", val);
        }
        else if (tag_type == USHORT) {
                unsigned short val = 0;
                nr = fread(&val, sz, 1, in);
                tagtable->become_host_endian(&val);
                sprintf(val_str, "%d", val);
        }
        else if (tag_type == INT) {
                int val = 0;
                nr = fread(&val, sz, 1, in);
                tagtable->become_host_endian(&val);
                sprintf(val_str, "%d", val);
        }
        else if (tag_type == CHAR || tag_type == OCTET) {
                char val = 0;
                nr = fread(&val, sz, 1, in);
                sprintf(val_str, "%d", val);
        }
        else if (tag_type == BOOLEAN) {
                bool val = false;
                nr = fread(&val, sz, 1, in);
                tagtable->become_host_endian(&val);
                sprintf(val_str, "%d", val);
        }
        else if (tag_type == UINT) {
                unsigned int val = 0;
                nr = fread(&val, sz, 1, in);
                tagtable->become_host_endian(&val);
                sprintf(val_str, "%u", (int) val);
        }
        else if (tag_type == FLOAT) {
                float val = 0;
                nr = fread(&val, sz, 1, in);
                tagtable->become_host_endian(&val);
                sprintf(val_str, "%f", val);
        }
        else if (tag_type == DOUBLE) {
                double val = 0;
                nr = fread(&val, sz, 1, in);
                tagtable->become_host_endian(&val);
                sprintf(val_str, "%10e", val);
        }
        else if (tag_type == OCTEU) {
                long long val = 0;
                nr = fread(&val, sz, 1, in);
                tagtable->become_host_endian(&val);
                sprintf(val_str, "%lld", val);
        }
        else if (tag_type == OCTEV) {
                unsigned long long val = 0;
                nr = fread(&val, sz, 1, in);
                tagtable->become_host_endian(&val);
                sprintf(val_str, "%lld", val);
        }
        else {
                LOGERR("invalid tag type: '%lld'", tag_type);
                exit(1);
        }

        if (is_value_stored) {
                tagtable->add(name, val_str);
        }

        LOGVAR("value = '%s'", val_str);

        return string(val_str);
}
string TagData::read_string ( int  size) [private]

Definition at line 298 of file dm4io.cpp.

References EMAN::GatanDM4::TagTable::become_host_endian(), in, and tagtable.

Referenced by read_array_data().

{
        if (size <= 0) {
                return string("");
        }

        unsigned short *buf = new unsigned short[size];
        char *str = new char[size + 1];

        size_t nr;
        nr = fread(buf, size * sizeof(unsigned short), 1, in);
        tagtable->become_host_endian < unsigned short >(buf, size);

        for (int i = 0; i < size; i++) {
                str[i] = static_cast < char >(buf[i]);
        }

        str[size] = '\0';
        string str1 = string(str);

        if (str) {
                delete [] str;
                str = NULL;
        }

        if (buf) {
                delete [] buf;
                buf = NULL;
        }

        return str1;
}
vector< int > TagData::read_struct_types ( ) [private]

Definition at line 406 of file dm4io.cpp.

References EMAN::ByteOrder::become_big_endian(), in, LOGVAR, and EMAN::GatanDM4::to_str().

Referenced by read_any(), and read_array_types().

{
        LOGVAR("TagData::read_struct_types()");

        long long namelength = 0;
        long long nfields = 0;

        size_t nr;
        nr = fread(&namelength, sizeof(namelength), 1, in);
        ByteOrder::become_big_endian(&namelength);

        nr = fread(&nfields, sizeof(nfields), 1, in);
        ByteOrder::become_big_endian(&nfields);

        LOGVAR("namelength = %lld\n", namelength);
        LOGVAR("num fields = %lld\n", nfields);

        vector < int >field_types;

        for (unsigned int i = 0; i < nfields; i++) {
                nr = fread(&namelength, sizeof(namelength), 1, in);
                ByteOrder::become_big_endian(&namelength);

                long long field_type = 0;
                nr = fread(&field_type, sizeof(field_type), 1, in);
                ByteOrder::become_big_endian(&field_type);
                
                LOGVAR("%dth namelength = %lld, type = '%s'",
                           i, namelength, GatanDM4::to_str((Type) field_type));
                field_types.push_back(field_type);
        }

        return field_types;
}
int TagData::read_tag_data ( bool  nodata = false,
int  image_index = 0,
int  num_images = 1 
)

Definition at line 497 of file dm4io.cpp.

References EMAN::ByteOrder::become_big_endian(), in, LOGERR, LOGVAR, and read_any().

Referenced by EMAN::GatanDM4::TagEntry::read_tag_entry().

{
        LOGVAR("TagData::read_tag_data()");
        int err = 0;

        const char *DATA_TYPE_MARK = "%%%%";
        const size_t mark_sz = strlen(DATA_TYPE_MARK);
        char *mark = new char[mark_sz + 1];

        long long interval;
        
        size_t nr;
        nr = fread(&interval, sizeof(interval), 1, in);

        ByteOrder::become_big_endian(&interval);

        nr = fread(mark, mark_sz, 1, in);
        mark[mark_sz] = '\0';

        if (strcmp(mark, DATA_TYPE_MARK) != 0) {
                LOGERR("data type label has been changed from '%s' to '%s'",
                           DATA_TYPE_MARK, mark);
                return 1;
        }

        if (mark) {
                delete [] mark;
                mark = NULL;
        }

        long long encoded_types_size = 0;
        nr = fread(&encoded_types_size, sizeof(long long), 1, in);
        ByteOrder::become_big_endian(&encoded_types_size);

        LOGVAR("encoded types size = %lld\n", encoded_types_size);

        err = read_any(nodata, image_index, num_images);

        return err;
}
size_t TagData::typesize ( int  type) const [private]

Definition at line 543 of file dm4io.cpp.

References BOOLEAN, CHAR, DOUBLE, FLOAT, INT, LOGERR, OCTET, OCTEU, OCTEV, SHORT, t, UINT, and USHORT.

{
        size_t size = 0;
        Type type = static_cast < Type > (t);

        
        switch (type) {
        case SHORT:
                size = sizeof(short);
                break;
        case USHORT:
                size = sizeof(unsigned short);
                break;
        case INT:
                size = sizeof(int);
                break;
        case UINT:
                size = sizeof(unsigned int);
                break;
        case FLOAT:
                size = sizeof(float);
                break;
        case DOUBLE:
                size = sizeof(double);
                break;
        case BOOLEAN:
                size = sizeof(bool);
                break;
        case CHAR:
        case OCTET:
                size = sizeof(char);
                break;
        case OCTEU:
                size = sizeof(double);
                break;
        case OCTEV:
                size = sizeof(double);
                break;
        default:
                LOGERR("no such type: '%d'\n", type);
                break;
        }

        return size;
}
size_t TagData::typesize ( ) const [private]

Definition at line 538 of file dm4io.cpp.

References tag_type.

Referenced by read_array_data(), and read_native().

{
        return typesize((int) tag_type);
}

Member Data Documentation

FILE* EMAN::GatanDM4::TagData::in [private]

Definition at line 141 of file dm4io.h.

Referenced by read_any(), read_array_data(), and read_native().

long long EMAN::GatanDM4::TagData::tag_type [private]

Definition at line 142 of file dm4io.h.

Referenced by read_any(), read_native(), and typesize().

Definition at line 140 of file dm4io.h.

Referenced by read_any(), read_array_data(), read_native(), and read_string().


The documentation for this class was generated from the following files: