tags:

views:

70

answers:

1

I am creating an application which uses a vCard struct. Currently, this struct looks like this:

typedef struct {
    char        *version;
    char        **names;
    char        *formatted_name;
    char        *nickname;
    char        *organisation;
    char        *title;
    struct {    /* Emails */
        char        *global_type;
        char        *type;
        char        *address;
        /* Meant to be a boolean which C doesn't have -_- */
        unsigned    preferred : 1;
    } *emails;
    struct {    /* Phones */
        char        *type;
        char        *number;
        unsigned    preferred : 1;
    } *phones;
    struct {    /* Addresses */
        char        *type;
        char        *street;
        char        *city;
        char        *postal_code;
        char        *country;
        unsigned    preferred : 1;
    } *addresses;
    time_t      birthday;
    struct {    /* Custom Fields */
        char        *field_name;
        union {
            /* Single value */
            int         i;
            float       f;
            double      d;
            time_t      t;
            struct {
                char        *global_type;
                char        *type;
                char        *address;
                /* Meant to be a boolean which C doesn't have -_- */
                unsigned    preferred : 1;
            } email;
            struct {
                char        *type;
                char        *number;
                unsigned    preferred : 1;
            } phone;
            struct {
                char        *type;
                char        *street;
                char        *city;
                char        *postal_code;
                char        *country;
                unsigned    preferred : 1;
            } address;
            char        *s;
            /* Multiple values */
            int         *is;
            float       *fs;
            double      *ds;
            time_t      *ts;
            struct {
                char        *global_type;
                char        *type;
                char        *address;
                /* Meant to be a boolean which C doesn't have -_- */
                unsigned    preferred : 1;
            } *emails;
            struct {
                char        *type;
                char        *number;
                unsigned    preferred : 1;
            } *phones;
            struct {
                char        *type;
                char        *street;
                char        *city;
                char        *postal_code;
                char        *country;
                unsigned    preferred : 1;
            } *addresses;
            char        **ss;
        } field_value;
    } *custom_fields;
} vCard;

This one is huge and takes much memory. I also use much pointers. Is there a better and cleaner way to declare this struct? Thanks.


Also, is it a good practise to use unions inside of structs and vice versa?

+5  A: 

Yes! Split structs apart! (just like when there's a huge function.)

typedef struct {
    char        *global_type;
    char        *type;
    char        *address;
    /* Meant to be a boolean which C doesn't have -_- */
    unsigned    preferred : 1;
} vCardEmail;

...

typedef struct {    /* Custom Fields */
    char        *field_name;
    union {
        /* Single value */
        int         i;
        float       f;
        double      d;
        time_t      t;
        vCardEmail email;
        vCardPhone phone;
        vCardAddress address;
        char        *s;
        /* Multiple values */
        int         *is;
        float       *fs;
        double      *ds;
        time_t      *ts;
        vCardEmail *emails;
        vCardPhone *phones;
        vCardAddress *addresses;
        char        **ss;
    } field_value;
} vCardCustomField;

typedef struct {
    char        *version;
    char        **names;
    char        *formatted_name;
    char        *nickname;
    char        *organisation;
    char        *title;
    vCardEmail *emails;
    vCardPhone *phones;
    vCardAddress *addresses;
    time_t      birthday;
    vCardCustomField *custom_fields;
} vCard;
KennyTM
Of course! Thanks :D
Time Machine
And... This is also better as you can more easily put emails, addresses and phone numbers into variables :)
Time Machine