/** * call-seq: * tracks() -> array * tracks() {|offset, length| block } * * Returns an array of <tt>[offset, length]</tt> tuples for each track. * * Offset and length are both integer values representing sectors. * If a block is given this method returns +nil+ and instead iterates over the * block calling the block with two arguments <tt>|offset, length|</tt>. * * Returns always +nil+ if no ID was yet read. The block won't be called in * this case. * * You may want to use the method track_details instead of this method to * retrieve more detailed information about the tracks. */ static VALUE mb_discid_tracks(VALUE self) { if (rb_iv_get(self, "@read") == Qfalse) return Qnil; else { DiscId *disc; /* Pointer to the disc struct */ VALUE result = rb_ary_new(); /* Array of all [offset, length] tuples */ VALUE tuple; /* Array to store one [offset, length] tuple. */ int track; /* Counter for the track number to process. */ Data_Get_Struct(self, DiscId, disc); track = discid_get_first_track_num(disc); /* First track number */ while (track <= discid_get_last_track_num(disc)) { tuple = rb_ary_new3(2, INT2FIX(discid_get_track_offset(disc, track)), INT2FIX(discid_get_track_length(disc, track)) ); if (rb_block_given_p()) rb_yield(tuple); else rb_ary_push(result, tuple); track++; } if (rb_block_given_p()) return Qnil; else return result; } }