/** * call-seq: * read(device=nil) * * Read the disc ID from the given device. * * If no device is given the default device of the platform will be used. * Throws an _Exception_ if the CD's TOC can not be read. * * Raises:: ArgumentError, TypeError, Exception */ static VALUE mb_discid_read(int argc, VALUE *argv, VALUE self) { DiscId *disc; /* Pointer to the disc struct */ VALUE device = Qnil; /* The device string as a Ruby string */ char* cdevice; /* The device string as a C string */ Data_Get_Struct(self, DiscId, disc); /* Check the number and types of arguments */ rb_scan_args(argc, argv, "01", &device); /* Use the default device if none was given. */ if (device == Qnil) cdevice = discid_get_default_device(); else if (rb_respond_to(device, rb_intern("to_s"))) { device = rb_funcall(device, rb_intern("to_s"), 0, 0); cdevice = StringValuePtr(device); } else rb_raise(rb_eTypeError, "wrong argument type (expected String)"); /* Mark the disc id as unread in case something goes wrong. */ rb_iv_set(self, "@read", Qfalse); /* Read the discid */ if (discid_read(disc, cdevice) == 0) rb_raise(rb_eException, discid_get_error_msg(disc)); else /* Remember that we already read the ID. */ rb_iv_set(self, "@read", Qtrue); return Qnil; }
/* * Virtual methods */ static GList * mb4_list_albums (SjMetadata *metadata, char **url, GError **error) { SjMetadataMusicbrainz4Private *priv; GList *albums = NULL; Mb4ReleaseList releases; Mb4Release release; const char *discid = NULL; char buffer[1024]; int i; g_return_val_if_fail (SJ_IS_METADATA_MUSICBRAINZ4 (metadata), NULL); priv = GET_PRIVATE (metadata); if (sj_metadata_helper_check_media (priv->cdrom, error) == FALSE) { return NULL; } priv->disc = discid_new (); if (priv->disc == NULL) return NULL; if (discid_read (priv->disc, priv->cdrom) == 0) return NULL; if (url != NULL) *url = g_strdup (discid_get_submission_url (priv->disc)); if (g_getenv("MUSICBRAINZ_FORCE_DISC_ID")) { discid = g_getenv("MUSICBRAINZ_FORCE_DISC_ID"); } else { discid = discid_get_id (priv->disc); } releases = mb4_query_lookup_discid(priv->mb, discid); if (releases == NULL) { return NULL; } if (mb4_release_list_size (releases) == 0) { return NULL; } for (i = 0; i < mb4_release_list_size (releases); i++) { AlbumDetails *album; release = mb4_release_list_item (releases, i); if (release) { char *releaseid = NULL; Mb4Release full_release; releaseid = NULL; GET(releaseid, mb4_release_get_id, release); full_release = mb4_query_lookup_release (priv->mb, releaseid); g_free (releaseid); if (full_release) { Mb4MediumList media; Mb4Metadata metadata = NULL; Mb4ReleaseGroup group; unsigned int j; group = mb4_release_get_releasegroup (full_release); if (group) { /* The release-group information we can extract from the * lookup_release query doesn't have the url relations for the * release-group, so run a separate query to get these urls */ char *releasegroupid = NULL; char *params_names[] = { "inc" }; char *params_values[] = { "artists url-rels" }; GET (releasegroupid, mb4_releasegroup_get_id, group); metadata = mb4_query_query (priv->mb, "release-group", releasegroupid, "", 1, params_names, params_values); g_free (releasegroupid); } if (metadata && mb4_metadata_get_releasegroup (metadata)) group = mb4_metadata_get_releasegroup (metadata); media = mb4_release_media_matching_discid (full_release, discid); for (j = 0; j < mb4_medium_list_size (media); j++) { Mb4Medium medium; medium = mb4_medium_list_item (media, j); if (medium) { album = make_album_from_release (group, full_release, medium); album->metadata_source = SOURCE_MUSICBRAINZ; albums = g_list_append (albums, album); } } mb4_metadata_delete (metadata); mb4_medium_list_delete (media); mb4_release_delete (full_release); } } } mb4_release_list_delete (releases); return albums; }
int main(int argc, char *argv[]) { DiscId *d; char *features[DISCID_FEATURE_LENGTH]; char *feature; int i, found_features, invalid; int result; announce("discid_get_version_string"); evaluate(strlen(discid_get_version_string()) > 0); announce("discid_get_feature_list"); discid_get_feature_list(features); found_features = 0; invalid = 0; for (i = 0; i < DISCID_FEATURE_LENGTH; i++) { feature = features[i]; if (feature) { found_features++; if (!feature_consistent(feature)) { invalid++; } } } evaluate(!invalid && found_features == discid_has_feature(DISCID_FEATURE_READ) + discid_has_feature(DISCID_FEATURE_MCN) + discid_has_feature(DISCID_FEATURE_ISRC)); announce("discid_get_default_device"); /* this doesn't test much, but shouldn't fail completely * TODO: make sure there is always something > 0 returned */ evaluate(strlen(discid_get_default_device()) >= 0); /* TODO * test access with/without initialization doesn't fail */ announce("discid_new"); d = discid_new(); evaluate(d != NULL); announce("giving invalid device"); result = discid_read(d, "invalid_device_name"); evaluate(!result); announce("discid_get_error_msg"); /* depending on result from invalid read * If that fails, it still is only one failure.*/ if (result) { evaluate(strlen(discid_get_error_msg(d)) == 0); } else { evaluate(strlen(discid_get_error_msg(d)) > 0); } /* announce("empty values"); evaluate(discid_get_id(d) == NULL); */ /* TODO * This needs implementation. * Right now we get segmentation faults in debug builds (assert) * and have to test for NULL in release builds. announce("empty values"); evaluate(strlen(discid_get_id(d)) == 0 && strlen(discid_get_freedb_id(d)) == 0 && strlen(discid_get_submission_url(d)) == 0 && strlen(discid_get_mcn(d)) == 0 && discid_get_first_track_num(d) == 0 && discid_get_last_track_num(d) == 0 && discid_get_sectors(d) == 0); */ announce("discid_free"); discid_free(d); evaluate(1); /* only segfaults etc. would "show" */ return !test_result(); }