1

Various libspotify API functions deal with image IDs:

These all return an image ID as a const byte*:

sp_album_cover
sp_artist_portrait
sp_artistbrowse_portrait
sp_image_image_id

sp_image_create takes an image ID parameter as const byte[20], while sp_playlist_get_image takes an image ID parameter as byte[20] and fills it with an image ID value.

In this question, a Spotify employee says both that the content of the image ID is opaque and that the size of 20 is not necessarily an accurate length for the image ID: libspotify API: image ID format?

sp_image_create takes 20 bytes long image_id parameter. Does that mean the maximum length of image id is 20 bytes?

No. sp_subscribers is another example of where we've put a fake number in for the compiler. The contents of an image id pointer are opaque and likely to change between releases. Don't write code that makes assumptions about them, because it'll break.

However, in order to use sp_playlist_get_image, the caller needs to allocate the array to store the image ID. This seems to be inconsistent advice, or is at least surprising. Which of the following is true?

  • Interpretation A: Image IDs will always be exactly 20 bytes.
  • Interpretation B: Image IDs might be of any length up to 20 bytes.
  • Interpretation C: Image IDs might be of any length, but the image IDs returned by sp_playlist_get_image are guaranteed to be no more than 20 bytes.
  • Interpretation D: Image IDs might be of any length and sp_playlist_get_image cannot be used safely at all.

I think the answer to the linked question rules out A and probably B, so I think the answer is probably C, as frustrating as that is. An utter pessimist might go with D.

I'm interested because I'm trying to write a safer and higher-level .NET wrapper than the existing libspotify.net, and I'm unsure how to present image IDs in managed code. I think the only thing for it is to have two alternative implementations - one with a 20 byte buffer that represents an image ID returned from sp_playlist_get_image, and one with an IntPtr that represents an image ID returned from anything else. If the library made sufficient guarantees about the size and nature of an image ID I could always use my own buffer and copy into it when necessary, but I fear it's looking unlikely that libspotify makes guarantees anywhere near strong enough to allow this.

Community
  • 1
  • 1
Weeble
  • 17,058
  • 3
  • 60
  • 75

1 Answers1

3

For the current release of libSpotify, Interpretation C is correct for that specific call. Since it takes byte[20], the function guarantees that if you allocate 20 bytes, you'll always have enough for the playlist's image ID. If that guarantee changes in the future the function signature will be changed, assuming we haven't made it work like everything else by then.

Your hybrid solution actually sounds the best for now, considering the state of that API. Using IntPtr where you can will be a lot more future-proof when that nasty sp_playlist_get_image goes away.

I hope your project goes well — we've been wanting a decent .NET wrapper for ages but have never had the time to do the whole thing ourselves. If it's open source, I'll gladly contribute.

iKenndac
  • 18,730
  • 3
  • 35
  • 51
  • The intention is to open-source it. I'd hope to put it on github in the next month or so. When I do it will be under https://github.com/organizations/openhome somewhere. – Weeble Jan 04 '13 at 13:44
  • The aforementioned C# wrapper library is now here: https://github.com/openhome/ohLibSpotify – Weeble Jan 17 '13 at 16:19
  • Did you get the imageID thing for playlists working? I'm using it with type Byte[] for the interop call, and the buffer I pass in never seems to be filled or changed by libspotfiy.. – Tom Davies Jan 30 '13 at 01:10
  • EDIT. Seems I have to pass in an IntPtr, pointing to a buffer allocated by the Marshal.AllocHGlobal function. – Tom Davies Jan 30 '13 at 01:19