blob: 04451a1f68c889c8ecb9f2f540efc54072ed112f [file] [log] [blame]
Guido van Rossum16b8f301992-04-13 18:22:53 +00001/**********************************************************
2Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
3Netherlands.
4
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
25/* CD module -- interface to Mark Callow's and Roger Chickering's */
26 /* CD Audio Library (CD). */
27
28#include <sys/types.h>
29#include <cdaudio.h>
30#include "allobjects.h"
31#include "import.h"
32#include "modsupport.h"
Guido van Rossum16b8f301992-04-13 18:22:53 +000033#include "ceval.h"
34
35#define NCALLBACKS 8
36
37typedef struct {
38 OB_HEAD
39 CDPLAYER *ob_cdplayer;
40} cdplayerobject;
41
42#define CheckPlayer(self) if ((self)->ob_cdplayer == NULL) { \
43 err_setstr(RuntimeError, "no player active"); \
44 return NULL; \
45 }
46#define CheckParser(self) if ((self)->ob_cdparser == NULL) { \
47 err_setstr(RuntimeError, "no parser active"); \
48 return NULL; \
49 }
50
51static object *
52CD_allowremoval(self, args)
53 cdplayerobject *self;
54 object *args;
55{
56 CheckPlayer(self);
57
58 if (!getnoarg(args))
59 return NULL;
60
61 CDallowremoval(self->ob_cdplayer);
62
63 INCREF(None);
64 return None;
65}
66
67static object *
68CD_preventremoval(self, args)
69 cdplayerobject *self;
70 object *args;
71{
72 CheckPlayer(self);
73
74 if (!getnoarg(args))
75 return NULL;
76
77 CDpreventremoval(self->ob_cdplayer);
78
79 INCREF(None);
80 return None;
81}
82
83static object *
Guido van Rossum16b8f301992-04-13 18:22:53 +000084CD_bestreadsize(self, args)
85 cdplayerobject *self;
86 object *args;
87{
88 CheckPlayer(self);
89
90 if (!getnoarg(args))
91 return NULL;
92
93 return newintobject((long) CDbestreadsize(self->ob_cdplayer));
94}
95
96static object *
97CD_close(self, args)
98 cdplayerobject *self;
99 object *args;
100{
101 CheckPlayer(self);
102
103 if (!getnoarg(args))
104 return NULL;
105
106 if (!CDclose(self->ob_cdplayer)) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000107 err_errno(IOError); /* XXX - ??? */
Guido van Rossum16b8f301992-04-13 18:22:53 +0000108 return NULL;
109 }
110 self->ob_cdplayer = NULL;
111
112 INCREF(None);
113 return None;
114}
115
116static object *
117CD_eject(self, args)
118 cdplayerobject *self;
119 object *args;
120{
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000121 CDSTATUS status;
122
Guido van Rossum16b8f301992-04-13 18:22:53 +0000123 CheckPlayer(self);
124
125 if (!getnoarg(args))
126 return NULL;
127
128 if (!CDeject(self->ob_cdplayer)) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000129 if (CDgetstatus(self->ob_cdplayer, &status) &&
130 status.state == CD_NODISC)
131 err_setstr(IOError, "no disc in player");
132 else
133 err_setstr(IOError, "eject failed");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000134 return NULL;
135 }
136
137 INCREF(None);
138 return None;
139}
140
141static object *
142CD_getstatus(self, args)
143 cdplayerobject *self;
144 object *args;
145{
146 CDSTATUS status;
147
148 CheckPlayer(self);
149
150 if (!getnoarg(args))
151 return NULL;
152
153 if (!CDgetstatus(self->ob_cdplayer, &status)) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000154 err_errno(IOError); /* XXX - ??? */
Guido van Rossum16b8f301992-04-13 18:22:53 +0000155 return NULL;
156 }
157
Guido van Rossumece6efe1992-04-15 15:56:11 +0000158 return mkvalue("(ii(iii)(iii)(iii)iiii(iii))", status.state,
159 status.track, status.min, status.sec, status.frame,
160 status.abs_min, status.abs_sec, status.abs_frame,
161 status.total_min, status.total_sec, status.total_frame,
162 status.first, status.last, status.scsi_audio,
163 status.cur_block, status.polyfilla[0],
164 status.polyfilla[1], status.polyfilla[2]);
Guido van Rossum16b8f301992-04-13 18:22:53 +0000165}
166
167static object *
168CD_gettrackinfo(self, args)
169 cdplayerobject *self;
170 object *args;
171{
172 int track;
173 CDTRACKINFO info;
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000174 CDSTATUS status;
Guido van Rossum16b8f301992-04-13 18:22:53 +0000175
176 CheckPlayer(self);
177
178 if (!getargs(args, "i", &track))
179 return NULL;
180
181 if (!CDgettrackinfo(self->ob_cdplayer, track, &info)) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000182 if (CDgetstatus(self->ob_cdplayer, &status) &&
183 status.state == CD_NODISC)
184 err_setstr(IOError, "no disc in player");
185 else
186 err_setstr(IOError, "gettrackinfo failed");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000187 return NULL;
188 }
189
Guido van Rossumece6efe1992-04-15 15:56:11 +0000190 return mkvalue("((iii)(iii))",
Guido van Rossum16b8f301992-04-13 18:22:53 +0000191 info.start_min, info.start_sec, info.start_frame,
192 info.total_min, info.total_sec, info.total_frame);
193}
194
195static object *
196CD_msftoblock(self, args)
197 cdplayerobject *self;
198 object *args;
199{
200 int min, sec, frame;
201 unsigned long block;
202
203 CheckPlayer(self);
204
205 if (!getargs(args, "(iii)", &min, &sec, &frame))
206 return NULL;
207
208 block = CDmsftoblock(self->ob_cdplayer, min, sec, frame);
209 return newintobject((long) block);
210}
211
212static object *
213CD_play(self, args)
214 cdplayerobject *self;
215 object *args;
216{
217 int start, play;
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000218 CDSTATUS status;
Guido van Rossum16b8f301992-04-13 18:22:53 +0000219
220 CheckPlayer(self);
221
222 if (!getargs(args, "(ii)", &start, &play))
223 return NULL;
224
225 if (!CDplay(self->ob_cdplayer, start, play)) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000226 if (CDgetstatus(self->ob_cdplayer, &status) &&
227 status.state == CD_NODISC)
228 err_setstr(IOError, "no disc in player");
229 else
230 err_setstr(IOError, "play failed");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000231 return NULL;
232 }
233
234 INCREF(None);
235 return None;
236}
237
238static object *
239CD_playabs(self, args)
240 cdplayerobject *self;
241 object *args;
242{
243 int min, sec, frame, play;
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000244 CDSTATUS status;
Guido van Rossum16b8f301992-04-13 18:22:53 +0000245
246 CheckPlayer(self);
247
248 if (!getargs(args, "(iiii)", &min, &sec, &frame, &play))
249 return NULL;
250
251 if (!CDplayabs(self->ob_cdplayer, min, sec, frame, play)) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000252 if (CDgetstatus(self->ob_cdplayer, &status) &&
253 status.state == CD_NODISC)
254 err_setstr(IOError, "no disc in player");
255 else
256 err_setstr(IOError, "playabs failed");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000257 return NULL;
258 }
259
260 INCREF(None);
261 return None;
262}
263
264static object *
265CD_playtrack(self, args)
266 cdplayerobject *self;
267 object *args;
268{
269 int start, play;
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000270 CDSTATUS status;
Guido van Rossum16b8f301992-04-13 18:22:53 +0000271
272 CheckPlayer(self);
273
274 if (!getargs(args, "(ii)", &start, &play))
275 return NULL;
276
277 if (!CDplaytrack(self->ob_cdplayer, start, play)) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000278 if (CDgetstatus(self->ob_cdplayer, &status) &&
279 status.state == CD_NODISC)
280 err_setstr(IOError, "no disc in player");
281 else
282 err_setstr(IOError, "playtrack failed");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000283 return NULL;
284 }
285
286 INCREF(None);
287 return None;
288}
289
290static object *
291CD_playtrackabs(self, args)
292 cdplayerobject *self;
293 object *args;
294{
295 int track, min, sec, frame, play;
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000296 CDSTATUS status;
Guido van Rossum16b8f301992-04-13 18:22:53 +0000297
298 CheckPlayer(self);
299
300 if (!getargs(args, "(iiiii)", &track, &min, &sec, &frame, &play))
301 return NULL;
302
303 if (!CDplaytrackabs(self->ob_cdplayer, track, min, sec, frame, play)) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000304 if (CDgetstatus(self->ob_cdplayer, &status) &&
305 status.state == CD_NODISC)
306 err_setstr(IOError, "no disc in player");
307 else
308 err_setstr(IOError, "playtrackabs failed");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000309 return NULL;
310 }
311
312 INCREF(None);
313 return None;
314}
315
316static object *
317CD_readda(self, args)
318 cdplayerobject *self;
319 object *args;
320{
321 int numframes, n;
322 object *result;
323
324 CheckPlayer(self);
325
326 if (!getargs(args, "i", &numframes))
327 return NULL;
328
329 result = newsizedstringobject(NULL, numframes * sizeof(CDFRAME));
330 if (result == NULL)
331 return NULL;
332
333 n = CDreadda(self->ob_cdplayer, (CDFRAME *) getstringvalue(result), numframes);
334 if (n == -1) {
335 DECREF(result);
Guido van Rossumf16eda51992-08-03 19:06:59 +0000336 err_errno(IOError);
Guido van Rossum16b8f301992-04-13 18:22:53 +0000337 return NULL;
338 }
339 if (n < numframes)
340 if (resizestring(&result, n * sizeof(CDFRAME)))
341 return NULL;
342
343 return result;
344}
345
346static object *
347CD_seek(self, args)
348 cdplayerobject *self;
349 object *args;
350{
351 int min, sec, frame;
352 long block;
353
354 CheckPlayer(self);
355
356 if (!getargs(args, "(iii)", &min, &sec, &frame))
357 return NULL;
358
359 block = CDseek(self->ob_cdplayer, min, sec, frame);
360 if (block == -1) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000361 err_errno(IOError);
Guido van Rossum16b8f301992-04-13 18:22:53 +0000362 return NULL;
363 }
364
365 return newintobject(block);
366}
367
368static object *
369CD_seektrack(self, args)
370 cdplayerobject *self;
371 object *args;
372{
373 int track;
374 long block;
375
376 CheckPlayer(self);
377
378 if (!getargs(args, "i", &track))
379 return NULL;
380
381 block = CDseektrack(self->ob_cdplayer, track);
382 if (block == -1) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000383 err_errno(IOError);
Guido van Rossum16b8f301992-04-13 18:22:53 +0000384 return NULL;
385 }
386
387 return newintobject(block);
388}
389
390static object *
391CD_stop(self, args)
392 cdplayerobject *self;
393 object *args;
394{
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000395 CDSTATUS status;
396
Guido van Rossum16b8f301992-04-13 18:22:53 +0000397 CheckPlayer(self);
398
399 if (!getnoarg(args))
400 return NULL;
401
402 if (!CDstop(self->ob_cdplayer)) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000403 if (CDgetstatus(self->ob_cdplayer, &status) &&
404 status.state == CD_NODISC)
405 err_setstr(IOError, "no disc in player");
406 else
407 err_setstr(IOError, "stop failed");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000408 return NULL;
409 }
410
411 INCREF(None);
412 return None;
413}
414
415static object *
416CD_togglepause(self, args)
417 cdplayerobject *self;
418 object *args;
419{
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000420 CDSTATUS status;
421
Guido van Rossum16b8f301992-04-13 18:22:53 +0000422 CheckPlayer(self);
423
424 if (!getnoarg(args))
425 return NULL;
426
427 if (!CDtogglepause(self->ob_cdplayer)) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000428 if (CDgetstatus(self->ob_cdplayer, &status) &&
429 status.state == CD_NODISC)
430 err_setstr(IOError, "no disc in player");
431 else
432 err_setstr(IOError, "togglepause failed");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000433 return NULL;
434 }
435
436 INCREF(None);
437 return None;
438}
439
440static struct methodlist cdplayer_methods[] = {
441 {"allowremoval", CD_allowremoval},
442 {"bestreadsize", CD_bestreadsize},
443 {"close", CD_close},
444 {"eject", CD_eject},
445 {"getstatus", CD_getstatus},
446 {"gettrackinfo", CD_gettrackinfo},
Guido van Rossum16b8f301992-04-13 18:22:53 +0000447 {"msftoblock", CD_msftoblock},
448 {"play", CD_play},
449 {"playabs", CD_playabs},
450 {"playtrack", CD_playtrack},
451 {"playtrackabs", CD_playtrackabs},
452 {"preventremoval", CD_preventremoval},
453 {"readda", CD_readda},
454 {"seek", CD_seek},
455 {"seektrack", CD_seektrack},
Guido van Rossum16b8f301992-04-13 18:22:53 +0000456 {"stop", CD_stop},
457 {"togglepause", CD_togglepause},
458 {NULL, NULL} /* sentinel */
459};
460
461static void
462cdplayer_dealloc(self)
463 cdplayerobject *self;
464{
465 if (self->ob_cdplayer != NULL)
466 CDclose(self->ob_cdplayer);
467 DEL(self);
468}
469
470static object *
471cdplayer_getattr(cdp, name)
472 cdplayerobject *cdp;
473 char *name;
474{
475 return findmethod(cdplayer_methods, (object *)cdp, name);
476}
477
478typeobject CdPlayertype = {
479 OB_HEAD_INIT(&Typetype)
480 0, /*ob_size*/
481 "cdplayer", /*tp_name*/
482 sizeof(cdplayerobject), /*tp_size*/
483 0, /*tp_itemsize*/
484 /* methods */
485 cdplayer_dealloc, /*tp_dealloc*/
486 0, /*tp_print*/
487 cdplayer_getattr, /*tp_getattr*/
488 0, /*tp_setattr*/
489 0, /*tp_compare*/
490 0, /*tp_repr*/
491};
492
493static object *
494newcdplayerobject(cdp)
495 CDPLAYER *cdp;
496{
497 cdplayerobject *p;
498
499 p = NEWOBJ(cdplayerobject, &CdPlayertype);
500 if (p == NULL)
501 return NULL;
502 p->ob_cdplayer = cdp;
503 return (object *) p;
504}
505
506static object *
507CD_open(self, args)
508 object *self, *args;
509{
510 char *dev, *direction;
511 CDPLAYER *cdp;
512
513 /*
514 * Variable number of args.
515 * First defaults to "None", second defaults to "r".
516 */
517 dev = NULL;
518 direction = "r";
519 if (!getnoarg(args)) {
520 err_clear();
521 if (!getargs(args, "z", &dev)) {
522 err_clear();
523 if (!getargs(args, "(zs)", &dev, &direction))
524 return NULL;
525 }
526 }
527
528 cdp = CDopen(dev, direction);
529 if (cdp == NULL) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000530 err_errno(IOError);
Guido van Rossum16b8f301992-04-13 18:22:53 +0000531 return NULL;
532 }
533
534 return newcdplayerobject(cdp);
535}
536
537typedef struct {
538 OB_HEAD
539 CDPARSER *ob_cdparser;
540 struct {
541 object *ob_cdcallback;
542 object *ob_cdcallbackarg;
543 } ob_cdcallbacks[NCALLBACKS];
544} cdparserobject;
545
546static void
547CD_callback(arg, type, data)
548 void *arg;
549 CDDATATYPES type;
550 void *data;
551{
552 object *result, *args, *v;
553 char *p;
554 int i;
555 cdparserobject *self;
556
557 self = (cdparserobject *) arg;
558 args = newtupleobject(3);
559 if (args == NULL)
560 return;
561 INCREF(self->ob_cdcallbacks[type].ob_cdcallbackarg);
562 settupleitem(args, 0, self->ob_cdcallbacks[type].ob_cdcallbackarg);
563 settupleitem(args, 1, newintobject((long) type));
564 switch (type) {
565 case cd_audio:
566 v = newsizedstringobject(data, CDDA_DATASIZE);
567 break;
568 case cd_pnum:
569 case cd_index:
570 v = newintobject(((CDPROGNUM *) data)->value);
571 break;
572 case cd_ptime:
573 case cd_atime:
Guido van Rossumece6efe1992-04-15 15:56:11 +0000574#define ptr ((struct cdtimecode *) data)
575 v = mkvalue("(iii)", ptr->mhi * 10 + ptr->mlo,
576 ptr->shi * 10 + ptr->slo,
577 ptr->fhi * 10 + ptr->flo);
578#undef ptr
Guido van Rossum16b8f301992-04-13 18:22:53 +0000579 break;
580 case cd_catalog:
581 v = newsizedstringobject(NULL, 13);
582 p = getstringvalue(v);
583 for (i = 0; i < 13; i++)
584 *p++ = ((char *) data)[i] + '0';
585 break;
586 case cd_ident:
587 v = newsizedstringobject(NULL, 12);
588 p = getstringvalue(v);
589 CDsbtoa(p, ((struct cdident *) data)->country, 2);
590 p += 2;
591 CDsbtoa(p, ((struct cdident *) data)->owner, 3);
592 p += 3;
593 *p++ = ((struct cdident *) data)->year[0] + '0';
594 *p++ = ((struct cdident *) data)->year[1] + '0';
595 *p++ = ((struct cdident *) data)->serial[0] + '0';
596 *p++ = ((struct cdident *) data)->serial[1] + '0';
597 *p++ = ((struct cdident *) data)->serial[2] + '0';
598 *p++ = ((struct cdident *) data)->serial[3] + '0';
599 *p++ = ((struct cdident *) data)->serial[4] + '0';
600 break;
601 case cd_control:
602 v = newintobject((long) *((unchar *) data));
603 break;
604 }
605 settupleitem(args, 2, v);
606 if (err_occurred()) {
607 DECREF(args);
608 return;
609 }
610
611 result = call_object(self->ob_cdcallbacks[type].ob_cdcallback, args);
612 DECREF(args);
613 XDECREF(result);
614}
615
616static object *
617CD_deleteparser(self, args)
618 cdparserobject *self;
619 object *args;
620{
621 int i;
622
623 CheckParser(self);
624
625 if (!getnoarg(args))
626 return NULL;
627
628 CDdeleteparser(self->ob_cdparser);
629 self->ob_cdparser = NULL;
630
631 /* no sense in keeping the callbacks, so remove them */
632 for (i = 0; i < NCALLBACKS; i++) {
633 XDECREF(self->ob_cdcallbacks[i].ob_cdcallback);
634 self->ob_cdcallbacks[i].ob_cdcallback = NULL;
635 XDECREF(self->ob_cdcallbacks[i].ob_cdcallbackarg);
636 self->ob_cdcallbacks[i].ob_cdcallbackarg = NULL;
637 }
638
639 INCREF(None);
640 return None;
641}
642
643static object *
644CD_parseframe(self, args)
645 cdparserobject *self;
646 object *args;
647{
648 char *cdfp;
649 int length;
650 CDFRAME *p;
651
652 CheckParser(self);
653
654 if (!getargs(args, "s#", &cdfp, &length))
655 return NULL;
656
657 if (length % sizeof(CDFRAME) != 0) {
658 err_setstr(RuntimeError, "bad length");
659 return NULL;
660 }
661
662 p = (CDFRAME *) cdfp;
663 while (length > 0) {
664 CDparseframe(self->ob_cdparser, p);
665 length -= sizeof(CDFRAME);
666 p++;
667 if (err_occurred())
668 return NULL;
669 }
670
671 INCREF(None);
672 return None;
673}
674
675static object *
676CD_removecallback(self, args)
677 cdparserobject *self;
678 object *args;
679{
680 int type;
681
682 CheckParser(self);
683
684 if (!getargs(args, "i", &type))
685 return NULL;
686
Guido van Rossumf16eda51992-08-03 19:06:59 +0000687 if (type < 0 || type >= NCALLBACKS) {
688 err_setstr(RuntimeError, "bad type");
689 return NULL;
690 }
691
Guido van Rossum16b8f301992-04-13 18:22:53 +0000692 CDremovecallback(self->ob_cdparser, (CDDATATYPES) type);
693
694 XDECREF(self->ob_cdcallbacks[type].ob_cdcallback);
695 self->ob_cdcallbacks[type].ob_cdcallback = NULL;
696
697 XDECREF(self->ob_cdcallbacks[type].ob_cdcallbackarg);
698 self->ob_cdcallbacks[type].ob_cdcallbackarg = NULL;
699
700 INCREF(None);
701 return None;
702}
703
704static object *
705CD_resetparser(self, args)
706 cdparserobject *self;
707 object *args;
708{
709 CheckParser(self);
710
711 if (!getnoarg(args))
712 return NULL;
713
714 CDresetparser(self->ob_cdparser);
715
716 INCREF(None);
717 return None;
718}
719
720static object *
Guido van Rossumf16eda51992-08-03 19:06:59 +0000721CD_addcallback(self, args)
Guido van Rossum16b8f301992-04-13 18:22:53 +0000722 cdparserobject *self;
723 object *args;
724{
725 int type;
726 object *funcobject, *funcargobject;
727
728 CheckParser(self);
729
730 /* XXX - more work here */
731 if (!getargs(args, "(iOO)", &type, &funcobject, &funcargobject))
732 return NULL;
733
734 if (type < 0 || type >= NCALLBACKS) {
735 err_setstr(RuntimeError, "bad type");
736 return NULL;
737 }
738
Guido van Rossumf16eda51992-08-03 19:06:59 +0000739#ifdef IRIX_405
740 CDaddcallback(self->ob_cdparser, (CDDATATYPES) type, CD_callback, (void *) self);
741#else
Guido van Rossum16b8f301992-04-13 18:22:53 +0000742 CDsetcallback(self->ob_cdparser, (CDDATATYPES) type, CD_callback, (void *) self);
Guido van Rossumf16eda51992-08-03 19:06:59 +0000743#endif
Guido van Rossum16b8f301992-04-13 18:22:53 +0000744 XDECREF(self->ob_cdcallbacks[type].ob_cdcallback);
745 INCREF(funcobject);
746 self->ob_cdcallbacks[type].ob_cdcallback = funcobject;
747 XDECREF(self->ob_cdcallbacks[type].ob_cdcallbackarg);
748 INCREF(funcargobject);
749 self->ob_cdcallbacks[type].ob_cdcallbackarg = funcargobject;
750
751 INCREF(None);
752 return None;
753}
754
755static struct methodlist cdparser_methods[] = {
Guido van Rossumf16eda51992-08-03 19:06:59 +0000756 {"addcallback", CD_addcallback},
Guido van Rossum16b8f301992-04-13 18:22:53 +0000757 {"deleteparser", CD_deleteparser},
758 {"parseframe", CD_parseframe},
759 {"removecallback", CD_removecallback},
760 {"resetparser", CD_resetparser},
Guido van Rossumf16eda51992-08-03 19:06:59 +0000761 {"setcallback", CD_addcallback}, /* backward compatibility */
Guido van Rossum16b8f301992-04-13 18:22:53 +0000762 {NULL, NULL} /* sentinel */
763};
764
765static void
766cdparser_dealloc(self)
767 cdparserobject *self;
768{
769 int i;
770
771 for (i = 0; i < NCALLBACKS; i++) {
772 XDECREF(self->ob_cdcallbacks[i].ob_cdcallback);
773 self->ob_cdcallbacks[i].ob_cdcallback = NULL;
774 XDECREF(self->ob_cdcallbacks[i].ob_cdcallbackarg);
775 self->ob_cdcallbacks[i].ob_cdcallbackarg = NULL;
776 }
777 CDdeleteparser(self->ob_cdparser);
778 DEL(self);
779}
780
781static object *
782cdparser_getattr(cdp, name)
783 cdparserobject *cdp;
784 char *name;
785{
786 return findmethod(cdparser_methods, (object *)cdp, name);
787}
788
789typeobject CdParsertype = {
790 OB_HEAD_INIT(&Typetype)
791 0, /*ob_size*/
792 "cdparser", /*tp_name*/
793 sizeof(cdparserobject), /*tp_size*/
794 0, /*tp_itemsize*/
795 /* methods */
796 cdparser_dealloc, /*tp_dealloc*/
797 0, /*tp_print*/
798 cdparser_getattr, /*tp_getattr*/
799 0, /*tp_setattr*/
800 0, /*tp_compare*/
801 0, /*tp_repr*/
802};
803
804static object *
805newcdparserobject(cdp)
806 CDPARSER *cdp;
807{
808 cdparserobject *p;
809 int i;
810
811 p = NEWOBJ(cdparserobject, &CdParsertype);
812 if (p == NULL)
813 return NULL;
814 p->ob_cdparser = cdp;
815 for (i = 0; i < NCALLBACKS; i++) {
816 p->ob_cdcallbacks[i].ob_cdcallback = NULL;
817 p->ob_cdcallbacks[i].ob_cdcallbackarg = NULL;
818 }
819 return (object *) p;
820}
821
822static object *
823CD_createparser(self, args)
824 object *self, *args;
825{
826 CDPARSER *cdp;
827
828 if (!getnoarg(args))
829 return NULL;
830 cdp = CDcreateparser();
831 if (cdp == NULL) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000832 err_setstr(IOError, "createparser failed");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000833 return NULL;
834 }
835
836 return newcdparserobject(cdp);
837}
838
839static object *
840CD_sbtoa(self, args)
841 object *self;
842 object *args;
843{
844 char *sb;
845 int length;
846 object *result;
847
848 if (!getargs(args, "s#", &sb, &length))
849 return NULL;
850 result = newsizedstringobject(NULL, length);
851 CDsbtoa(getstringvalue(result), (unchar *) sb, length);
852 return result;
853}
854
855static object *
856CD_timetoa(self, args)
857 object *self;
858 object *args;
859{
860 char *tc;
861 int length;
862 object *result;
863
864 if (!getargs(args, "s#", &tc, &length))
865 return NULL;
866
867 if (length != sizeof(struct cdtimecode)) {
868 err_setstr(RuntimeError, "bad length");
869 return NULL;
870 }
871
872 result = newsizedstringobject(NULL, 8);
873 CDtimetoa(getstringvalue(result), (struct cdtimecode *) tc);
874 return result;
875}
876
877static struct methodlist CD_methods[] = {
878 {"sbtoa", CD_sbtoa},
879 {"open", CD_open},
880 {"createparser",CD_createparser},
881 {"timetoa", CD_timetoa},
882 {NULL, NULL} /* Sentinel */
883};
884
885void
886initcd()
887{
888 (void) initmodule("cd", CD_methods);
889}