Initial commit.
[ruby-discid.git] / ext / ext.c
1 /*
2  * Copyright (c) 2007 Tilman Sauerbeck (tilman at code-monkey de)
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sublicense, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23
24 #include <ruby.h>
25 #include <stdio.h>
26 #include <stdbool.h>
27 #include <errno.h>
28 #include <assert.h>
29
30 #include <discid/discid.h>
31
32 static VALUE eReadError;
33
34 typedef struct {
35         DiscId *real;
36 } RbDiscID;
37
38 static void
39 c_free (RbDiscID *o)
40 {
41         discid_free (o->real);
42
43         ruby_xfree (o);
44 }
45
46 static VALUE
47 c_alloc (VALUE klass)
48 {
49         RbDiscID *o;
50
51         return Data_Make_Struct (klass, RbDiscID, NULL, c_free, o);
52 }
53
54 /*
55  * call-seq:
56  *  DiscID.default_device -> string
57  *
58  * Returns the default device that's used in DiscID::DiscID.read if
59  * the device isn't specified explicitly.
60  */
61 static VALUE
62 m_default_device (VALUE self)
63 {
64         return rb_str_new2 (discid_get_default_device ());
65 }
66
67 /*
68  * call-seq:
69  *  DiscID::DiscID.read([device]) -> object
70  *
71  * Read the disc id from the medium in the given device.
72  * If the argument is ommitted, DiscID.default_device is used instead.
73  */
74 static VALUE
75 c_read (int argc, VALUE *argv, VALUE klass)
76 {
77         VALUE self, device;
78         RbDiscID *o;
79         char *cdev = NULL;
80         int s;
81
82         rb_scan_args (argc, argv, "01", &device);
83
84         if (!NIL_P (device))
85                 cdev = StringValuePtr (device);
86
87         self = rb_class_new_instance (0, NULL, klass);
88
89         Data_Get_Struct (self, RbDiscID, o);
90
91         s = discid_read (o->real, cdev);
92         if (!s)
93                 rb_raise (eReadError, discid_get_error_msg (o->real));
94
95         return self;
96 }
97
98 static VALUE
99 c_init (VALUE self)
100 {
101         RbDiscID *o;
102
103         Data_Get_Struct (self, RbDiscID, o);
104
105         o->real = discid_new ();
106
107         return self;
108 }
109
110 /*
111  * call-seq:
112  *  discid.id -> string
113  *
114  * Returns the MusicBrainz disc id.
115  */
116 static VALUE
117 c_id (VALUE self)
118 {
119         RbDiscID *o;
120         char *s;
121
122         Data_Get_Struct (self, RbDiscID, o);
123
124         s = discid_get_id (o->real);
125
126         return rb_str_new2 (s);
127 }
128
129 /*
130  * call-seq:
131  *  discid.submission_url -> string
132  *
133  * Returns the submission url for the disc id.
134  */
135 static VALUE
136 c_submission_url (VALUE self)
137 {
138         RbDiscID *o;
139         char *s;
140
141         Data_Get_Struct (self, RbDiscID, o);
142
143         s = discid_get_submission_url (o->real);
144
145         return rb_str_new2 (s);
146 }
147
148 /*
149  * call-seq:
150  *  discid.freedb_id -> string
151  *
152  * Returns the FreeDB disc id.
153  */
154 static VALUE
155 c_freedb_id (VALUE self)
156 {
157         RbDiscID *o;
158         char *s;
159
160         Data_Get_Struct (self, RbDiscID, o);
161
162         s = discid_get_freedb_id (o->real);
163
164         return rb_str_new2 (s);
165 }
166
167 void
168 Init_discid_ext (void)
169 {
170         VALUE m, c;
171         VALUE eDiscIDError;
172
173         m = rb_define_module ("DiscID");
174         c = rb_define_class_under (m, "DiscID", rb_cObject);
175
176         rb_define_alloc_func (c, c_alloc);
177
178         rb_define_module_function (m, "default_device", m_default_device, 0);
179         rb_define_singleton_method (c, "read", c_read, -1);
180         rb_define_method (c, "initialize", c_init, 0);
181         rb_define_method (c, "id", c_id, 0);
182         rb_define_method (c, "submission_url", c_submission_url, 0);
183         rb_define_method (c, "freedb_id", c_freedb_id, 0);
184
185         eDiscIDError = rb_define_class_under (m, "DiscIDError", rb_eStandardError);
186         eReadError = rb_define_class_under (m, "ReadError", eDiscIDError);
187 }