blob: 332b54bfbe788a9ef3feb8d5e0480575035e34bc [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"
33#include "compile.h"
34#include "ceval.h"
35
36#define NCALLBACKS 8
37
38typedef struct {
39 OB_HEAD
40 CDPLAYER *ob_cdplayer;
41} cdplayerobject;
42
43#define CheckPlayer(self) if ((self)->ob_cdplayer == NULL) { \
44 err_setstr(RuntimeError, "no player active"); \
45 return NULL; \
46 }
47#define CheckParser(self) if ((self)->ob_cdparser == NULL) { \
48 err_setstr(RuntimeError, "no parser active"); \
49 return NULL; \
50 }
51
52static object *
53CD_allowremoval(self, args)
54 cdplayerobject *self;
55 object *args;
56{
57 CheckPlayer(self);
58
59 if (!getnoarg(args))
60 return NULL;
61
62 CDallowremoval(self->ob_cdplayer);
63
64 INCREF(None);
65 return None;
66}
67
68static object *
69CD_preventremoval(self, args)
70 cdplayerobject *self;
71 object *args;
72{
73 CheckPlayer(self);
74
75 if (!getnoarg(args))
76 return NULL;
77
78 CDpreventremoval(self->ob_cdplayer);
79
80 INCREF(None);
81 return None;
82}
83
84static object *
Guido van Rossum16b8f301992-04-13 18:22:53 +000085CD_bestreadsize(self, args)
86 cdplayerobject *self;
87 object *args;
88{
89 CheckPlayer(self);
90
91 if (!getnoarg(args))
92 return NULL;
93
94 return newintobject((long) CDbestreadsize(self->ob_cdplayer));
95}
96
97static object *
98CD_close(self, args)
99 cdplayerobject *self;
100 object *args;
101{
102 CheckPlayer(self);
103
104 if (!getnoarg(args))
105 return NULL;
106
107 if (!CDclose(self->ob_cdplayer)) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000108 err_errno(IOError); /* XXX - ??? */
Guido van Rossum16b8f301992-04-13 18:22:53 +0000109 return NULL;
110 }
111 self->ob_cdplayer = NULL;
112
113 INCREF(None);
114 return None;
115}
116
117static object *
118CD_eject(self, args)
119 cdplayerobject *self;
120 object *args;
121{
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000122 CDSTATUS status;
123
Guido van Rossum16b8f301992-04-13 18:22:53 +0000124 CheckPlayer(self);
125
126 if (!getnoarg(args))
127 return NULL;
128
129 if (!CDeject(self->ob_cdplayer)) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000130 if (CDgetstatus(self->ob_cdplayer, &status) &&
131 status.state == CD_NODISC)
132 err_setstr(IOError, "no disc in player");
133 else
134 err_setstr(IOError, "eject failed");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000135 return NULL;
136 }
137
138 INCREF(None);
139 return None;
140}
141
142static object *
143CD_getstatus(self, args)
144 cdplayerobject *self;
145 object *args;
146{
147 CDSTATUS status;
148
149 CheckPlayer(self);
150
151 if (!getnoarg(args))
152 return NULL;
153
154 if (!CDgetstatus(self->ob_cdplayer, &status)) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000155 err_errno(IOError); /* XXX - ??? */
Guido van Rossum16b8f301992-04-13 18:22:53 +0000156 return NULL;
157 }
158
Guido van Rossumece6efe1992-04-15 15:56:11 +0000159 return mkvalue("(ii(iii)(iii)(iii)iiii(iii))", status.state,
160 status.track, status.min, status.sec, status.frame,
161 status.abs_min, status.abs_sec, status.abs_frame,
162 status.total_min, status.total_sec, status.total_frame,
163 status.first, status.last, status.scsi_audio,
164 status.cur_block, status.polyfilla[0],
165 status.polyfilla[1], status.polyfilla[2]);
Guido van Rossum16b8f301992-04-13 18:22:53 +0000166}
167
168static object *
169CD_gettrackinfo(self, args)
170 cdplayerobject *self;
171 object *args;
172{
173 int track;
174 CDTRACKINFO info;
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000175 CDSTATUS status;
Guido van Rossum16b8f301992-04-13 18:22:53 +0000176
177 CheckPlayer(self);
178
179 if (!getargs(args, "i", &track))
180 return NULL;
181
182 if (!CDgettrackinfo(self->ob_cdplayer, track, &info)) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000183 if (CDgetstatus(self->ob_cdplayer, &status) &&
184 status.state == CD_NODISC)
185 err_setstr(IOError, "no disc in player");
186 else
187 err_setstr(IOError, "gettrackinfo failed");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000188 return NULL;
189 }
190
Guido van Rossumece6efe1992-04-15 15:56:11 +0000191 return mkvalue("((iii)(iii))",
Guido van Rossum16b8f301992-04-13 18:22:53 +0000192 info.start_min, info.start_sec, info.start_frame,
193 info.total_min, info.total_sec, info.total_frame);
194}
195
196static object *
197CD_msftoblock(self, args)
198 cdplayerobject *self;
199 object *args;
200{
201 int min, sec, frame;
202 unsigned long block;
203
204 CheckPlayer(self);
205
206 if (!getargs(args, "(iii)", &min, &sec, &frame))
207 return NULL;
208
209 block = CDmsftoblock(self->ob_cdplayer, min, sec, frame);
210 return newintobject((long) block);
211}
212
213static object *
214CD_play(self, args)
215 cdplayerobject *self;
216 object *args;
217{
218 int start, play;
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000219 CDSTATUS status;
Guido van Rossum16b8f301992-04-13 18:22:53 +0000220
221 CheckPlayer(self);
222
223 if (!getargs(args, "(ii)", &start, &play))
224 return NULL;
225
226 if (!CDplay(self->ob_cdplayer, start, play)) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000227 if (CDgetstatus(self->ob_cdplayer, &status) &&
228 status.state == CD_NODISC)
229 err_setstr(IOError, "no disc in player");
230 else
231 err_setstr(IOError, "play failed");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000232 return NULL;
233 }
234
235 INCREF(None);
236 return None;
237}
238
239static object *
240CD_playabs(self, args)
241 cdplayerobject *self;
242 object *args;
243{
244 int min, sec, frame, play;
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000245 CDSTATUS status;
Guido van Rossum16b8f301992-04-13 18:22:53 +0000246
247 CheckPlayer(self);
248
249 if (!getargs(args, "(iiii)", &min, &sec, &frame, &play))
250 return NULL;
251
252 if (!CDplayabs(self->ob_cdplayer, min, sec, frame, play)) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000253 if (CDgetstatus(self->ob_cdplayer, &status) &&
254 status.state == CD_NODISC)
255 err_setstr(IOError, "no disc in player");
256 else
257 err_setstr(IOError, "playabs failed");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000258 return NULL;
259 }
260
261 INCREF(None);
262 return None;
263}
264
265static object *
266CD_playtrack(self, args)
267 cdplayerobject *self;
268 object *args;
269{
270 int start, play;
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000271 CDSTATUS status;
Guido van Rossum16b8f301992-04-13 18:22:53 +0000272
273 CheckPlayer(self);
274
275 if (!getargs(args, "(ii)", &start, &play))
276 return NULL;
277
278 if (!CDplaytrack(self->ob_cdplayer, start, play)) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000279 if (CDgetstatus(self->ob_cdplayer, &status) &&
280 status.state == CD_NODISC)
281 err_setstr(IOError, "no disc in player");
282 else
283 err_setstr(IOError, "playtrack failed");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000284 return NULL;
285 }
286
287 INCREF(None);
288 return None;
289}
290
291static object *
292CD_playtrackabs(self, args)
293 cdplayerobject *self;
294 object *args;
295{
296 int track, min, sec, frame, play;
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000297 CDSTATUS status;
Guido van Rossum16b8f301992-04-13 18:22:53 +0000298
299 CheckPlayer(self);
300
301 if (!getargs(args, "(iiiii)", &track, &min, &sec, &frame, &play))
302 return NULL;
303
304 if (!CDplaytrackabs(self->ob_cdplayer, track, min, sec, frame, play)) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000305 if (CDgetstatus(self->ob_cdplayer, &status) &&
306 status.state == CD_NODISC)
307 err_setstr(IOError, "no disc in player");
308 else
309 err_setstr(IOError, "playtrackabs failed");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000310 return NULL;
311 }
312
313 INCREF(None);
314 return None;
315}
316
317static object *
318CD_readda(self, args)
319 cdplayerobject *self;
320 object *args;
321{
322 int numframes, n;
323 object *result;
324
325 CheckPlayer(self);
326
327 if (!getargs(args, "i", &numframes))
328 return NULL;
329
330 result = newsizedstringobject(NULL, numframes * sizeof(CDFRAME));
331 if (result == NULL)
332 return NULL;
333
334 n = CDreadda(self->ob_cdplayer, (CDFRAME *) getstringvalue(result), numframes);
335 if (n == -1) {
336 DECREF(result);
Guido van Rossumf16eda51992-08-03 19:06:59 +0000337 err_errno(IOError);
Guido van Rossum16b8f301992-04-13 18:22:53 +0000338 return NULL;
339 }
340 if (n < numframes)
341 if (resizestring(&result, n * sizeof(CDFRAME)))
342 return NULL;
343
344 return result;
345}
346
347static object *
348CD_seek(self, args)
349 cdplayerobject *self;
350 object *args;
351{
352 int min, sec, frame;
353 long block;
354
355 CheckPlayer(self);
356
357 if (!getargs(args, "(iii)", &min, &sec, &frame))
358 return NULL;
359
360 block = CDseek(self->ob_cdplayer, min, sec, frame);
361 if (block == -1) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000362 err_errno(IOError);
Guido van Rossum16b8f301992-04-13 18:22:53 +0000363 return NULL;
364 }
365
366 return newintobject(block);
367}
368
369static object *
370CD_seektrack(self, args)
371 cdplayerobject *self;
372 object *args;
373{
374 int track;
375 long block;
376
377 CheckPlayer(self);
378
379 if (!getargs(args, "i", &track))
380 return NULL;
381
382 block = CDseektrack(self->ob_cdplayer, track);
383 if (block == -1) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000384 err_errno(IOError);
Guido van Rossum16b8f301992-04-13 18:22:53 +0000385 return NULL;
386 }
387
388 return newintobject(block);
389}
390
391static object *
392CD_stop(self, args)
393 cdplayerobject *self;
394 object *args;
395{
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000396 CDSTATUS status;
397
Guido van Rossum16b8f301992-04-13 18:22:53 +0000398 CheckPlayer(self);
399
400 if (!getnoarg(args))
401 return NULL;
402
403 if (!CDstop(self->ob_cdplayer)) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000404 if (CDgetstatus(self->ob_cdplayer, &status) &&
405 status.state == CD_NODISC)
406 err_setstr(IOError, "no disc in player");
407 else
408 err_setstr(IOError, "stop failed");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000409 return NULL;
410 }
411
412 INCREF(None);
413 return None;
414}
415
416static object *
417CD_togglepause(self, args)
418 cdplayerobject *self;
419 object *args;
420{
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000421 CDSTATUS status;
422
Guido van Rossum16b8f301992-04-13 18:22:53 +0000423 CheckPlayer(self);
424
425 if (!getnoarg(args))
426 return NULL;
427
428 if (!CDtogglepause(self->ob_cdplayer)) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000429 if (CDgetstatus(self->ob_cdplayer, &status) &&
430 status.state == CD_NODISC)
431 err_setstr(IOError, "no disc in player");
432 else
433 err_setstr(IOError, "togglepause failed");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000434 return NULL;
435 }
436
437 INCREF(None);
438 return None;
439}
440
441static struct methodlist cdplayer_methods[] = {
442 {"allowremoval", CD_allowremoval},
443 {"bestreadsize", CD_bestreadsize},
444 {"close", CD_close},
445 {"eject", CD_eject},
446 {"getstatus", CD_getstatus},
447 {"gettrackinfo", CD_gettrackinfo},
Guido van Rossum16b8f301992-04-13 18:22:53 +0000448 {"msftoblock", CD_msftoblock},
449 {"play", CD_play},
450 {"playabs", CD_playabs},
451 {"playtrack", CD_playtrack},
452 {"playtrackabs", CD_playtrackabs},
453 {"preventremoval", CD_preventremoval},
454 {"readda", CD_readda},
455 {"seek", CD_seek},
456 {"seektrack", CD_seektrack},
Guido van Rossum16b8f301992-04-13 18:22:53 +0000457 {"stop", CD_stop},
458 {"togglepause", CD_togglepause},
459 {NULL, NULL} /* sentinel */
460};
461
462static void
463cdplayer_dealloc(self)
464 cdplayerobject *self;
465{
466 if (self->ob_cdplayer != NULL)
467 CDclose(self->ob_cdplayer);
468 DEL(self);
469}
470
471static object *
472cdplayer_getattr(cdp, name)
473 cdplayerobject *cdp;
474 char *name;
475{
476 return findmethod(cdplayer_methods, (object *)cdp, name);
477}
478
479typeobject CdPlayertype = {
480 OB_HEAD_INIT(&Typetype)
481 0, /*ob_size*/
482 "cdplayer", /*tp_name*/
483 sizeof(cdplayerobject), /*tp_size*/
484 0, /*tp_itemsize*/
485 /* methods */
486 cdplayer_dealloc, /*tp_dealloc*/
487 0, /*tp_print*/
488 cdplayer_getattr, /*tp_getattr*/
489 0, /*tp_setattr*/
490 0, /*tp_compare*/
491 0, /*tp_repr*/
492};
493
494static object *
495newcdplayerobject(cdp)
496 CDPLAYER *cdp;
497{
498 cdplayerobject *p;
499
500 p = NEWOBJ(cdplayerobject, &CdPlayertype);
501 if (p == NULL)
502 return NULL;
503 p->ob_cdplayer = cdp;
504 return (object *) p;
505}
506
507static object *
508CD_open(self, args)
509 object *self, *args;
510{
511 char *dev, *direction;
512 CDPLAYER *cdp;
513
514 /*
515 * Variable number of args.
516 * First defaults to "None", second defaults to "r".
517 */
518 dev = NULL;
519 direction = "r";
520 if (!getnoarg(args)) {
521 err_clear();
522 if (!getargs(args, "z", &dev)) {
523 err_clear();
524 if (!getargs(args, "(zs)", &dev, &direction))
525 return NULL;
526 }
527 }
528
529 cdp = CDopen(dev, direction);
530 if (cdp == NULL) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000531 err_errno(IOError);
Guido van Rossum16b8f301992-04-13 18:22:53 +0000532 return NULL;
533 }
534
535 return newcdplayerobject(cdp);
536}
537
538typedef struct {
539 OB_HEAD
540 CDPARSER *ob_cdparser;
541 struct {
542 object *ob_cdcallback;
543 object *ob_cdcallbackarg;
544 } ob_cdcallbacks[NCALLBACKS];
545} cdparserobject;
546
547static void
548CD_callback(arg, type, data)
549 void *arg;
550 CDDATATYPES type;
551 void *data;
552{
553 object *result, *args, *v;
554 char *p;
555 int i;
556 cdparserobject *self;
557
558 self = (cdparserobject *) arg;
559 args = newtupleobject(3);
560 if (args == NULL)
561 return;
562 INCREF(self->ob_cdcallbacks[type].ob_cdcallbackarg);
563 settupleitem(args, 0, self->ob_cdcallbacks[type].ob_cdcallbackarg);
564 settupleitem(args, 1, newintobject((long) type));
565 switch (type) {
566 case cd_audio:
567 v = newsizedstringobject(data, CDDA_DATASIZE);
568 break;
569 case cd_pnum:
570 case cd_index:
571 v = newintobject(((CDPROGNUM *) data)->value);
572 break;
573 case cd_ptime:
574 case cd_atime:
Guido van Rossumece6efe1992-04-15 15:56:11 +0000575#define ptr ((struct cdtimecode *) data)
576 v = mkvalue("(iii)", ptr->mhi * 10 + ptr->mlo,
577 ptr->shi * 10 + ptr->slo,
578 ptr->fhi * 10 + ptr->flo);
579#undef ptr
Guido van Rossum16b8f301992-04-13 18:22:53 +0000580 break;
581 case cd_catalog:
582 v = newsizedstringobject(NULL, 13);
583 p = getstringvalue(v);
584 for (i = 0; i < 13; i++)
585 *p++ = ((char *) data)[i] + '0';
586 break;
587 case cd_ident:
588 v = newsizedstringobject(NULL, 12);
589 p = getstringvalue(v);
590 CDsbtoa(p, ((struct cdident *) data)->country, 2);
591 p += 2;
592 CDsbtoa(p, ((struct cdident *) data)->owner, 3);
593 p += 3;
594 *p++ = ((struct cdident *) data)->year[0] + '0';
595 *p++ = ((struct cdident *) data)->year[1] + '0';
596 *p++ = ((struct cdident *) data)->serial[0] + '0';
597 *p++ = ((struct cdident *) data)->serial[1] + '0';
598 *p++ = ((struct cdident *) data)->serial[2] + '0';
599 *p++ = ((struct cdident *) data)->serial[3] + '0';
600 *p++ = ((struct cdident *) data)->serial[4] + '0';
601 break;
602 case cd_control:
603 v = newintobject((long) *((unchar *) data));
604 break;
605 }
606 settupleitem(args, 2, v);
607 if (err_occurred()) {
608 DECREF(args);
609 return;
610 }
611
612 result = call_object(self->ob_cdcallbacks[type].ob_cdcallback, args);
613 DECREF(args);
614 XDECREF(result);
615}
616
617static object *
618CD_deleteparser(self, args)
619 cdparserobject *self;
620 object *args;
621{
622 int i;
623
624 CheckParser(self);
625
626 if (!getnoarg(args))
627 return NULL;
628
629 CDdeleteparser(self->ob_cdparser);
630 self->ob_cdparser = NULL;
631
632 /* no sense in keeping the callbacks, so remove them */
633 for (i = 0; i < NCALLBACKS; i++) {
634 XDECREF(self->ob_cdcallbacks[i].ob_cdcallback);
635 self->ob_cdcallbacks[i].ob_cdcallback = NULL;
636 XDECREF(self->ob_cdcallbacks[i].ob_cdcallbackarg);
637 self->ob_cdcallbacks[i].ob_cdcallbackarg = NULL;
638 }
639
640 INCREF(None);
641 return None;
642}
643
644static object *
645CD_parseframe(self, args)
646 cdparserobject *self;
647 object *args;
648{
649 char *cdfp;
650 int length;
651 CDFRAME *p;
652
653 CheckParser(self);
654
655 if (!getargs(args, "s#", &cdfp, &length))
656 return NULL;
657
658 if (length % sizeof(CDFRAME) != 0) {
659 err_setstr(RuntimeError, "bad length");
660 return NULL;
661 }
662
663 p = (CDFRAME *) cdfp;
664 while (length > 0) {
665 CDparseframe(self->ob_cdparser, p);
666 length -= sizeof(CDFRAME);
667 p++;
668 if (err_occurred())
669 return NULL;
670 }
671
672 INCREF(None);
673 return None;
674}
675
676static object *
677CD_removecallback(self, args)
678 cdparserobject *self;
679 object *args;
680{
681 int type;
682
683 CheckParser(self);
684
685 if (!getargs(args, "i", &type))
686 return NULL;
687
Guido van Rossumf16eda51992-08-03 19:06:59 +0000688 if (type < 0 || type >= NCALLBACKS) {
689 err_setstr(RuntimeError, "bad type");
690 return NULL;
691 }
692
Guido van Rossum16b8f301992-04-13 18:22:53 +0000693 CDremovecallback(self->ob_cdparser, (CDDATATYPES) type);
694
695 XDECREF(self->ob_cdcallbacks[type].ob_cdcallback);
696 self->ob_cdcallbacks[type].ob_cdcallback = NULL;
697
698 XDECREF(self->ob_cdcallbacks[type].ob_cdcallbackarg);
699 self->ob_cdcallbacks[type].ob_cdcallbackarg = NULL;
700
701 INCREF(None);
702 return None;
703}
704
705static object *
706CD_resetparser(self, args)
707 cdparserobject *self;
708 object *args;
709{
710 CheckParser(self);
711
712 if (!getnoarg(args))
713 return NULL;
714
715 CDresetparser(self->ob_cdparser);
716
717 INCREF(None);
718 return None;
719}
720
721static object *
Guido van Rossumf16eda51992-08-03 19:06:59 +0000722CD_addcallback(self, args)
Guido van Rossum16b8f301992-04-13 18:22:53 +0000723 cdparserobject *self;
724 object *args;
725{
726 int type;
727 object *funcobject, *funcargobject;
728
729 CheckParser(self);
730
731 /* XXX - more work here */
732 if (!getargs(args, "(iOO)", &type, &funcobject, &funcargobject))
733 return NULL;
734
735 if (type < 0 || type >= NCALLBACKS) {
736 err_setstr(RuntimeError, "bad type");
737 return NULL;
738 }
739
Guido van Rossumf16eda51992-08-03 19:06:59 +0000740#ifdef IRIX_405
741 CDaddcallback(self->ob_cdparser, (CDDATATYPES) type, CD_callback, (void *) self);
742#else
Guido van Rossum16b8f301992-04-13 18:22:53 +0000743 CDsetcallback(self->ob_cdparser, (CDDATATYPES) type, CD_callback, (void *) self);
Guido van Rossumf16eda51992-08-03 19:06:59 +0000744#endif
Guido van Rossum16b8f301992-04-13 18:22:53 +0000745 XDECREF(self->ob_cdcallbacks[type].ob_cdcallback);
746 INCREF(funcobject);
747 self->ob_cdcallbacks[type].ob_cdcallback = funcobject;
748 XDECREF(self->ob_cdcallbacks[type].ob_cdcallbackarg);
749 INCREF(funcargobject);
750 self->ob_cdcallbacks[type].ob_cdcallbackarg = funcargobject;
751
752 INCREF(None);
753 return None;
754}
755
756static struct methodlist cdparser_methods[] = {
Guido van Rossumf16eda51992-08-03 19:06:59 +0000757 {"addcallback", CD_addcallback},
Guido van Rossum16b8f301992-04-13 18:22:53 +0000758 {"deleteparser", CD_deleteparser},
759 {"parseframe", CD_parseframe},
760 {"removecallback", CD_removecallback},
761 {"resetparser", CD_resetparser},
Guido van Rossumf16eda51992-08-03 19:06:59 +0000762 {"setcallback", CD_addcallback}, /* backward compatibility */
Guido van Rossum16b8f301992-04-13 18:22:53 +0000763 {NULL, NULL} /* sentinel */
764};
765
766static void
767cdparser_dealloc(self)
768 cdparserobject *self;
769{
770 int i;
771
772 for (i = 0; i < NCALLBACKS; i++) {
773 XDECREF(self->ob_cdcallbacks[i].ob_cdcallback);
774 self->ob_cdcallbacks[i].ob_cdcallback = NULL;
775 XDECREF(self->ob_cdcallbacks[i].ob_cdcallbackarg);
776 self->ob_cdcallbacks[i].ob_cdcallbackarg = NULL;
777 }
778 CDdeleteparser(self->ob_cdparser);
779 DEL(self);
780}
781
782static object *
783cdparser_getattr(cdp, name)
784 cdparserobject *cdp;
785 char *name;
786{
787 return findmethod(cdparser_methods, (object *)cdp, name);
788}
789
790typeobject CdParsertype = {
791 OB_HEAD_INIT(&Typetype)
792 0, /*ob_size*/
793 "cdparser", /*tp_name*/
794 sizeof(cdparserobject), /*tp_size*/
795 0, /*tp_itemsize*/
796 /* methods */
797 cdparser_dealloc, /*tp_dealloc*/
798 0, /*tp_print*/
799 cdparser_getattr, /*tp_getattr*/
800 0, /*tp_setattr*/
801 0, /*tp_compare*/
802 0, /*tp_repr*/
803};
804
805static object *
806newcdparserobject(cdp)
807 CDPARSER *cdp;
808{
809 cdparserobject *p;
810 int i;
811
812 p = NEWOBJ(cdparserobject, &CdParsertype);
813 if (p == NULL)
814 return NULL;
815 p->ob_cdparser = cdp;
816 for (i = 0; i < NCALLBACKS; i++) {
817 p->ob_cdcallbacks[i].ob_cdcallback = NULL;
818 p->ob_cdcallbacks[i].ob_cdcallbackarg = NULL;
819 }
820 return (object *) p;
821}
822
823static object *
824CD_createparser(self, args)
825 object *self, *args;
826{
827 CDPARSER *cdp;
828
829 if (!getnoarg(args))
830 return NULL;
831 cdp = CDcreateparser();
832 if (cdp == NULL) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000833 err_setstr(IOError, "createparser failed");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000834 return NULL;
835 }
836
837 return newcdparserobject(cdp);
838}
839
840static object *
841CD_sbtoa(self, args)
842 object *self;
843 object *args;
844{
845 char *sb;
846 int length;
847 object *result;
848
849 if (!getargs(args, "s#", &sb, &length))
850 return NULL;
851 result = newsizedstringobject(NULL, length);
852 CDsbtoa(getstringvalue(result), (unchar *) sb, length);
853 return result;
854}
855
856static object *
857CD_timetoa(self, args)
858 object *self;
859 object *args;
860{
861 char *tc;
862 int length;
863 object *result;
864
865 if (!getargs(args, "s#", &tc, &length))
866 return NULL;
867
868 if (length != sizeof(struct cdtimecode)) {
869 err_setstr(RuntimeError, "bad length");
870 return NULL;
871 }
872
873 result = newsizedstringobject(NULL, 8);
874 CDtimetoa(getstringvalue(result), (struct cdtimecode *) tc);
875 return result;
876}
877
878static struct methodlist CD_methods[] = {
879 {"sbtoa", CD_sbtoa},
880 {"open", CD_open},
881 {"createparser",CD_createparser},
882 {"timetoa", CD_timetoa},
883 {NULL, NULL} /* Sentinel */
884};
885
886void
887initcd()
888{
889 (void) initmodule("cd", CD_methods);
890}