How to model Go bindings to C structs that use unions? -
i'm writing go wrapper libfreefare. api of libfreefare contains following function:
struct mifare_desfire_file_settings { uint8_t file_type; uint8_t communication_settings; uint16_t access_rights; union { struct { uint32_t file_size; } standard_file; struct { int32_t lower_limit; int32_t upper_limit; int32_t limited_credit_value; uint8_t limited_credit_enabled; } value_file; struct { uint32_t record_size; uint32_t max_number_of_records; uint32_t current_number_of_records; } linear_record_file; } settings; }; int mifare_desfire_get_file_settings (mifaretag tag, uint8_t file_no, struct mifare_desfire_file_settings *settings);
what ideomatic solution wrapping such function? if struct mifare_desfire_file_settings
wouldn't contain unions, wrapper this:
type desfirefilesettings struct { // fields exported, no methods } func (t desfiretag) filesettings(fileno byte) (desfirefilesettings, error)
how should proceed?
you need consider how update fields in union. obviously, can't let users without validation. inconsistent updates. consider doing this:
package mifare const ( mdftstandardatafile = 0x00 mdftbackupdatafile = 0x01 mdftvaluefilewithbackup = 0x02 mdftlinearrecordfilewithbackup = 0x03 mdftcyclicrecordfilewithbackup = 0x04 ) type standardfile struct { filesize uint32 } type valuefile struct { lowerlimit int32 upperlimit int32 limitedcreditvalue int32 limitedcreditenabled uint8 } type linearrecordfile struct { record_size uint32 maxnumberofrecords uint32 currentnumberofrecords uint32 } type desfirefilesettings struct { filetype uint8 communicationsettings uint8 accessrights uint16 settings struct { standardfile valuefile linearrecordfile } } func (fs *desfirefilesettings) standardfile() (standardfile, error) { // if not valid filetype, return error return fs.settings.standardfile, nil } func (fs *desfirefilesettings) setstandardfile(standardfile standardfile) error { // if not valid filetype, return error fs.settings.standardfile = standardfile return nil } func (fs *desfirefilesettings) valuefile() (valuefile, error) { // if not valid filetype, return error return fs.settings.valuefile, nil } func (fs *desfirefilesettings) setvaluefile(valuefile valuefile) error { // if not valid filetype, return error fs.settings.valuefile = valuefile return nil } func (fs *desfirefilesettings) linearrecordfile() (linearrecordfile, error) { // if not valid filetype, return error return fs.settings.linearrecordfile, nil } func (fs *desfirefilesettings) setlinearrecordfile(linearrecordfile linearrecordfile) error { // if not valid filetype, return error fs.settings.linearrecordfile = linearrecordfile return nil }
Comments
Post a Comment