lib/spotify/structs/subscribers.rb
module Spotify
# Spotify::Struct for Subscribers of a Playlist.
#
# Memory looks like this:
# 00 00 00 00 <- count of subscribers
# 00 00 00 00 <- pointer to subscriber 1
# …… …… …… ……
# 00 00 00 00 <- pointer to subscriber n
#
# @attr [Fixnum] count
# @attr [Array<Pointer<String>>] subscribers
class Subscribers < Spotify::Struct
include Enumerable
class << self
# Releases the given subscribers structure if it is not null.
#
# @param [FFI::Pointer] pointer pointing to a subscribers struct
def release(pointer)
unless pointer.null?
Spotify.performer.async do
Spotify.log "Spotify.playlist_subscribers_free(#{pointer})"
Spotify.playlist_subscribers_free(pointer)
end
end
end
end
layout :count => :uint,
:subscribers => [UTF8StringPointer, 0] # array of pointers to strings
# Redefined, as the layout of the Struct can only be determined
# at run-time.
#
# @param [FFI::Pointer, Integer] pointer_or_count
def initialize(pointer_or_count)
count = if pointer_or_count.is_a?(FFI::Pointer)
if pointer_or_count.null?
0
else
pointer_or_count.read_uint
end
else
pointer_or_count
end
layout = [:count, :uint]
layout += [:subscribers, [UTF8StringPointer, count]]
if pointer_or_count.is_a?(FFI::Pointer)
super(pointer_or_count, *layout)
else
super(nil, *layout)
self[:count] = count
end
end
# Yields every subscriber as a UTF8-encoded string.
#
# @yield [subscriber]
# @yieldparam [String] subscriber
def each
return enum_for(__method__) { count } unless block_given?
count.times { |index| yield self[:subscribers][index] }
end
private
# @return [Integer] number of subscribers in the struct.
def count
if null?
0
else
self[:count]
end
end
end
end