Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Alignment problem with libdespotify #1

Closed
jakobwenzel opened this issue Sep 26, 2012 · 3 comments
Closed

Alignment problem with libdespotify #1

jakobwenzel opened this issue Sep 26, 2012 · 3 comments

Comments

@jakobwenzel
Copy link

Hi there,

I am currently trying to interface libdespotify (see despotify.se) with node / ffi. Libdespotify makes heavy use of structs to store information about artists, albums and tracks.
However, the data in the struct is not aligned to four bits as ref-struct seems to assume. The fields of the structs mostly appear directly after each other, but sometimes there are 2 or 3 bytes of nothingness inbetween. I do not know C very well and have not yet been able to figure out why this happens.
I have gotten it to work by patching ref-struct to always set the alignment to zero and and inserting the random padding bytes manually after figuring out where they have to be by trial and error.

Setting alignment to zero in struct.js:

     }
     struct.alignment = Math.max(struct.alignment, alignment)
   })
+  
+  struct.alignment = 0;

   // second loop through sets the `offset` property on each "field"
   // object, and sets the `struct.size` as we go along

Struct definition in libdespotify:

#define STRING_LENGTH 256
struct track
{
    bool has_meta_data;   
    bool playable;
    bool geo_restricted;
    unsigned char track_id[33];
    unsigned char file_id[41];
    unsigned int file_bitrate;
    unsigned char album_id[33];
    unsigned char cover_id[41];
    unsigned char *key;

    char *allowed;
    char *forbidden;

    char title[STRING_LENGTH];
    struct artist* artist;
    char album[STRING_LENGTH];
    int length;
    int tracknumber;
    int year;
    float popularity;
    struct track *next; /* in case of multiple tracks
                           in an album or playlist struct */
};

Working implementation in node.js:

var char = ref.types.char
var char256 = ArrayType(char, 256);
var char33  = ArrayType(char, 33 );
var char41  = ArrayType(char, 41 );
var char3   = ArrayType(char, 3  );
var char2   = ArrayType(char, 2  );
var track = StructType({
  'has_meta_data': 'bool',
  'playable': 'bool',
  'geo_restricted': 'bool',
  'track_id': char33,
  'file_id': char41,
  '___padding1': char3,   
  'file_bitrate': 'uint',
  'album_id':char33,
  'cover_id':char41,
  '___padding2': char2,
  'key':'string',
  'allowed':'string',
  'forbidden':'string',
  'title':char256,
  'artist':artistPtr,
  'album':char256,
  'length':'int',
  'tracknumber':'int',
  'year':'int',
  'popularity':'float'
});

Is this a bug in ref-struct or am I just doing something wrong?

Greetings,
antidau

@TooTallNate
Copy link
Owner

Thanks for the sample, I'll add it to the test cases. I think you are actually hitting a bug with the way that ref-array types are currently being aligned. I haven't yet learned what the correct way to align arrays inside of structs is, but there is at least one other failing test currently that fails for similar reasons. Once I learn the correct way to align arrays, I'll be sure to fix it!

TooTallNate added a commit that referenced this issue Sep 26, 2012
TooTallNate pushed a commit that referenced this issue Sep 26, 2012
Fixes the failing tests and #1 :)
@TooTallNate
Copy link
Owner

Fixed by @tjfontaine in da85dac :)

@jakobwenzel
Copy link
Author

I'm amazed at how fast the open source community works.
Great work guys, works perfectly!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants