Mercurial > cpython-lru_cache-weakref
view Modules/cdmodule.c @ 58973:db86bf39ccaa legacy-trunk
Issue 7970: When email.Parser.Parser parses a MIME message of type
message/rfc822 it turns it into an object whose body consists of
a list containing a single Message object. HeaderParser, on the
other hand, just copies the body as a string. Generator.flatten
has a special handler for the message mime type that expected the
body to be the one item list. This fails if the message was parsed
by HeaderParser. So we now check to see if the body is a string
first, and if so just we just emit it.
| author | R. David Murray <rdmurray@bitdance.com> |
|---|---|
| date | Sun, 21 Feb 2010 04:23:00 +0000 |
| parents | 52294af4b663 |
| children | fd25030223b0 |
line wrap: on
line source
/* CD module -- interface to Mark Callow's and Roger Chickering's */ /* CD Audio Library (CD). */ #include <sys/types.h> #include <cdaudio.h> #include "Python.h" #define NCALLBACKS 8 typedef struct { PyObject_HEAD CDPLAYER *ob_cdplayer; } cdplayerobject; static PyObject *CdError; /* exception cd.error */ static PyObject * CD_allowremoval(cdplayerobject *self, PyObject *args) { if (!PyArg_ParseTuple(args, ":allowremoval")) return NULL; CDallowremoval(self->ob_cdplayer); Py_INCREF(Py_None); return Py_None; } static PyObject * CD_preventremoval(cdplayerobject *self, PyObject *args) { if (!PyArg_ParseTuple(args, ":preventremoval")) return NULL; CDpreventremoval(self->ob_cdplayer); Py_INCREF(Py_None); return Py_None; } static PyObject * CD_bestreadsize(cdplayerobject *self, PyObject *args) { if (!PyArg_ParseTuple(args, ":bestreadsize")) return NULL; return PyInt_FromLong((long) CDbestreadsize(self->ob_cdplayer)); } static PyObject * CD_close(cdplayerobject *self, PyObject *args) { if (!PyArg_ParseTuple(args, ":close")) return NULL; if (!CDclose(self->ob_cdplayer)) { PyErr_SetFromErrno(CdError); /* XXX - ??? */ return NULL; } self->ob_cdplayer = NULL; Py_INCREF(Py_None); return Py_None; } static PyObject * CD_eject(cdplayerobject *self, PyObject *args) { CDSTATUS status; if (!PyArg_ParseTuple(args, ":eject")) return NULL; if (!CDeject(self->ob_cdplayer)) { if (CDgetstatus(self->ob_cdplayer, &status) && status.state == CD_NODISC) PyErr_SetString(CdError, "no disc in player"); else PyErr_SetString(CdError, "eject failed"); return NULL; } Py_INCREF(Py_None); return Py_None; } static PyObject * CD_getstatus(cdplayerobject *self, PyObject *args) { CDSTATUS status; if (!PyArg_ParseTuple(args, ":getstatus")) return NULL; if (!CDgetstatus(self->ob_cdplayer, &status)) { PyErr_SetFromErrno(CdError); /* XXX - ??? */ return NULL; } return Py_BuildValue("(ii(iii)(iii)(iii)iiii)", status.state, status.track, status.min, status.sec, status.frame, status.abs_min, status.abs_sec, status.abs_frame, status.total_min, status.total_sec, status.total_frame, status.first, status.last, status.scsi_audio, status.cur_block); } static PyObject * CD_gettrackinfo(cdplayerobject *self, PyObject *args) { int track; CDTRACKINFO info; CDSTATUS status; if (!PyArg_ParseTuple(args, "i:gettrackinfo", &track)) return NULL; if (!CDgettrackinfo(self->ob_cdplayer, track, &info)) { if (CDgetstatus(self->ob_cdplayer, &status) && status.state == CD_NODISC) PyErr_SetString(CdError, "no disc in player"); else PyErr_SetString(CdError, "gettrackinfo failed"); return NULL; } return Py_BuildValue("((iii)(iii))", info.start_min, info.start_sec, info.start_frame, info.total_min, info.total_sec, info.total_frame); } static PyObject * CD_msftoblock(cdplayerobject *self, PyObject *args) { int min, sec, frame; if (!PyArg_ParseTuple(args, "iii:msftoblock", &min, &sec, &frame)) return NULL; return PyInt_FromLong((long) CDmsftoblock(self->ob_cdplayer, min, sec, frame)); } static PyObject * CD_play(cdplayerobject *self, PyObject *args) { int start, play; CDSTATUS status; if (!PyArg_ParseTuple(args, "ii:play", &start, &play)) return NULL; if (!CDplay(self->ob_cdplayer, start, play)) { if (CDgetstatus(self->ob_cdplayer, &status) && status.state == CD_NODISC) PyErr_SetString(CdError, "no disc in player"); else PyErr_SetString(CdError, "play failed"); return NULL; } Py_INCREF(Py_None); return Py_None; } static PyObject * CD_playabs(cdplayerobject *self, PyObject *args) { int min, sec, frame, play; CDSTATUS status; if (!PyArg_ParseTuple(args, "iiii:playabs", &min, &sec, &frame, &play)) return NULL; if (!CDplayabs(self->ob_cdplayer, min, sec, frame, play)) { if (CDgetstatus(self->ob_cdplayer, &status) && status.state == CD_NODISC) PyErr_SetString(CdError, "no disc in player"); else PyErr_SetString(CdError, "playabs failed"); return NULL; } Py_INCREF(Py_None); return Py_None; } static PyObject * CD_playtrack(cdplayerobject *self, PyObject *args) { int start, play; CDSTATUS status; if (!PyArg_ParseTuple(args, "ii:playtrack", &start, &play)) return NULL; if (!CDplaytrack(self->ob_cdplayer, start, play)) { if (CDgetstatus(self->ob_cdplayer, &status) && status.state == CD_NODISC) PyErr_SetString(CdError, "no disc in player"); else PyErr_SetString(CdError, "playtrack failed"); return NULL; } Py_INCREF(Py_None); return Py_None; } static PyObject * CD_playtrackabs(cdplayerobject *self, PyObject *args) { int track, min, sec, frame, play; CDSTATUS status; if (!PyArg_ParseTuple(args, "iiiii:playtrackabs", &track, &min, &sec, &frame, &play)) return NULL; if (!CDplaytrackabs(self->ob_cdplayer, track, min, sec, frame, play)) { if (CDgetstatus(self->ob_cdplayer, &status) && status.state == CD_NODISC) PyErr_SetString(CdError, "no disc in player"); else PyErr_SetString(CdError, "playtrackabs failed"); return NULL; } Py_INCREF(Py_None); return Py_None; } static PyObject * CD_readda(cdplayerobject *self, PyObject *args) { int numframes, n; PyObject *result; if (!PyArg_ParseTuple(args, "i:readda", &numframes)) return NULL; result = PyString_FromStringAndSize(NULL, numframes * sizeof(CDFRAME)); if (result == NULL) return NULL; n = CDreadda(self->ob_cdplayer, (CDFRAME *) PyString_AsString(result), numframes); if (n == -1) { Py_DECREF(result); PyErr_SetFromErrno(CdError); return NULL; } if (n < numframes) _PyString_Resize(&result, n * sizeof(CDFRAME)); return result; } static PyObject * CD_seek(cdplayerobject *self, PyObject *args) { int min, sec, frame; long PyTryBlock; if (!PyArg_ParseTuple(args, "iii:seek", &min, &sec, &frame)) return NULL; PyTryBlock = CDseek(self->ob_cdplayer, min, sec, frame); if (PyTryBlock == -1) { PyErr_SetFromErrno(CdError); return NULL; } return PyInt_FromLong(PyTryBlock); } static PyObject * CD_seektrack(cdplayerobject *self, PyObject *args) { int track; long PyTryBlock; if (!PyArg_ParseTuple(args, "i:seektrack", &track)) return NULL; PyTryBlock = CDseektrack(self->ob_cdplayer, track); if (PyTryBlock == -1) { PyErr_SetFromErrno(CdError); return NULL; } return PyInt_FromLong(PyTryBlock); } static PyObject * CD_seekblock(cdplayerobject *self, PyObject *args) { unsigned long PyTryBlock; if (!PyArg_ParseTuple(args, "l:seekblock", &PyTryBlock)) return NULL; PyTryBlock = CDseekblock(self->ob_cdplayer, PyTryBlock); if (PyTryBlock == (unsigned long) -1) { PyErr_SetFromErrno(CdError); return NULL; } return PyInt_FromLong(PyTryBlock); } static PyObject * CD_stop(cdplayerobject *self, PyObject *args) { CDSTATUS status; if (!PyArg_ParseTuple(args, ":stop")) return NULL; if (!CDstop(self->ob_cdplayer)) { if (CDgetstatus(self->ob_cdplayer, &status) && status.state == CD_NODISC) PyErr_SetString(CdError, "no disc in player"); else PyErr_SetString(CdError, "stop failed"); return NULL; } Py_INCREF(Py_None); return Py_None; } static PyObject * CD_togglepause(cdplayerobject *self, PyObject *args) { CDSTATUS status; if (!PyArg_ParseTuple(args, ":togglepause")) return NULL; if (!CDtogglepause(self->ob_cdplayer)) { if (CDgetstatus(self->ob_cdplayer, &status) && status.state == CD_NODISC) PyErr_SetString(CdError, "no disc in player"); else PyErr_SetString(CdError, "togglepause failed"); return NULL; } Py_INCREF(Py_None); return Py_None; } static PyMethodDef cdplayer_methods[] = { {"allowremoval", (PyCFunction)CD_allowremoval, METH_VARARGS}, {"bestreadsize", (PyCFunction)CD_bestreadsize, METH_VARARGS}, {"close", (PyCFunction)CD_close, METH_VARARGS}, {"eject", (PyCFunction)CD_eject, METH_VARARGS}, {"getstatus", (PyCFunction)CD_getstatus, METH_VARARGS}, {"gettrackinfo", (PyCFunction)CD_gettrackinfo, METH_VARARGS}, {"msftoblock", (PyCFunction)CD_msftoblock, METH_VARARGS}, {"play", (PyCFunction)CD_play, METH_VARARGS}, {"playabs", (PyCFunction)CD_playabs, METH_VARARGS}, {"playtrack", (PyCFunction)CD_playtrack, METH_VARARGS}, {"playtrackabs", (PyCFunction)CD_playtrackabs, METH_VARARGS}, {"preventremoval", (PyCFunction)CD_preventremoval, METH_VARARGS}, {"readda", (PyCFunction)CD_readda, METH_VARARGS}, {"seek", (PyCFunction)CD_seek, METH_VARARGS}, {"seekblock", (PyCFunction)CD_seekblock, METH_VARARGS}, {"seektrack", (PyCFunction)CD_seektrack, METH_VARARGS}, {"stop", (PyCFunction)CD_stop, METH_VARARGS}, {"togglepause", (PyCFunction)CD_togglepause, METH_VARARGS}, {NULL, NULL} /* sentinel */ }; static void cdplayer_dealloc(cdplayerobject *self) { if (self->ob_cdplayer != NULL) CDclose(self->ob_cdplayer); PyObject_Del(self); } static PyObject * cdplayer_getattr(cdplayerobject *self, char *name) { if (self->ob_cdplayer == NULL) { PyErr_SetString(PyExc_RuntimeError, "no player active"); return NULL; } return Py_FindMethod(cdplayer_methods, (PyObject *)self, name); } PyTypeObject CdPlayertype = { PyObject_HEAD_INIT(&PyType_Type) 0, /*ob_size*/ "cd.cdplayer", /*tp_name*/ sizeof(cdplayerobject), /*tp_size*/ 0, /*tp_itemsize*/ /* methods */ (destructor)cdplayer_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ (getattrfunc)cdplayer_getattr, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ }; static PyObject * newcdplayerobject(CDPLAYER *cdp) { cdplayerobject *p; p = PyObject_New(cdplayerobject, &CdPlayertype); if (p == NULL) return NULL; p->ob_cdplayer = cdp; return (PyObject *) p; } static PyObject * CD_open(PyObject *self, PyObject *args) { char *dev, *direction; CDPLAYER *cdp; /* * Variable number of args. * First defaults to "None", second defaults to "r". */ dev = NULL; direction = "r"; if (!PyArg_ParseTuple(args, "|zs:open", &dev, &direction)) return NULL; cdp = CDopen(dev, direction); if (cdp == NULL) { PyErr_SetFromErrno(CdError); return NULL; } return newcdplayerobject(cdp); } typedef struct { PyObject_HEAD CDPARSER *ob_cdparser; struct { PyObject *ob_cdcallback; PyObject *ob_cdcallbackarg; } ob_cdcallbacks[NCALLBACKS]; } cdparserobject; static void CD_callback(void *arg, CDDATATYPES type, void *data) { PyObject *result, *args, *v = NULL; char *p; int i; cdparserobject *self; self = (cdparserobject *) arg; args = PyTuple_New(3); if (args == NULL) return; Py_INCREF(self->ob_cdcallbacks[type].ob_cdcallbackarg); PyTuple_SetItem(args, 0, self->ob_cdcallbacks[type].ob_cdcallbackarg); PyTuple_SetItem(args, 1, PyInt_FromLong((long) type)); switch (type) { case cd_audio: v = PyString_FromStringAndSize(data, CDDA_DATASIZE); break; case cd_pnum: case cd_index: v = PyInt_FromLong(((CDPROGNUM *) data)->value); break; case cd_ptime: case cd_atime: #define ptr ((struct cdtimecode *) data) v = Py_BuildValue("(iii)", ptr->mhi * 10 + ptr->mlo, ptr->shi * 10 + ptr->slo, ptr->fhi * 10 + ptr->flo); #undef ptr break; case cd_catalog: v = PyString_FromStringAndSize(NULL, 13); p = PyString_AsString(v); for (i = 0; i < 13; i++) *p++ = ((char *) data)[i] + '0'; break; case cd_ident: #define ptr ((struct cdident *) data) v = PyString_FromStringAndSize(NULL, 12); p = PyString_AsString(v); CDsbtoa(p, ptr->country, 2); p += 2; CDsbtoa(p, ptr->owner, 3); p += 3; *p++ = ptr->year[0] + '0'; *p++ = ptr->year[1] + '0'; *p++ = ptr->serial[0] + '0'; *p++ = ptr->serial[1] + '0'; *p++ = ptr->serial[2] + '0'; *p++ = ptr->serial[3] + '0'; *p++ = ptr->serial[4] + '0'; #undef ptr break; case cd_control: v = PyInt_FromLong((long) *((unchar *) data)); break; } PyTuple_SetItem(args, 2, v); if (PyErr_Occurred()) { Py_DECREF(args); return; } result = PyEval_CallObject(self->ob_cdcallbacks[type].ob_cdcallback, args); Py_DECREF(args); Py_XDECREF(result); } static PyObject * CD_deleteparser(cdparserobject *self, PyObject *args) { int i; if (!PyArg_ParseTuple(args, ":deleteparser")) return NULL; CDdeleteparser(self->ob_cdparser); self->ob_cdparser = NULL; /* no sense in keeping the callbacks, so remove them */ for (i = 0; i < NCALLBACKS; i++) { Py_XDECREF(self->ob_cdcallbacks[i].ob_cdcallback); self->ob_cdcallbacks[i].ob_cdcallback = NULL; Py_XDECREF(self->ob_cdcallbacks[i].ob_cdcallbackarg); self->ob_cdcallbacks[i].ob_cdcallbackarg = NULL; } Py_INCREF(Py_None); return Py_None; } static PyObject * CD_parseframe(cdparserobject *self, PyObject *args) { char *cdfp; int length; CDFRAME *p; if (!PyArg_ParseTuple(args, "s#:parseframe", &cdfp, &length)) return NULL; if (length % sizeof(CDFRAME) != 0) { PyErr_SetString(PyExc_TypeError, "bad length"); return NULL; } p = (CDFRAME *) cdfp; while (length > 0) { CDparseframe(self->ob_cdparser, p); length -= sizeof(CDFRAME); p++; if (PyErr_Occurred()) return NULL; } Py_INCREF(Py_None); return Py_None; } static PyObject * CD_removecallback(cdparserobject *self, PyObject *args) { int type; if (!PyArg_ParseTuple(args, "i:removecallback", &type)) return NULL; if (type < 0 || type >= NCALLBACKS) { PyErr_SetString(PyExc_TypeError, "bad type"); return NULL; } CDremovecallback(self->ob_cdparser, (CDDATATYPES) type); Py_XDECREF(self->ob_cdcallbacks[type].ob_cdcallback); self->ob_cdcallbacks[type].ob_cdcallback = NULL; Py_XDECREF(self->ob_cdcallbacks[type].ob_cdcallbackarg); self->ob_cdcallbacks[type].ob_cdcallbackarg = NULL; Py_INCREF(Py_None); return Py_None; } static PyObject * CD_resetparser(cdparserobject *self, PyObject *args) { if (!PyArg_ParseTuple(args, ":resetparser")) return NULL; CDresetparser(self->ob_cdparser); Py_INCREF(Py_None); return Py_None; } static PyObject * CD_addcallback(cdparserobject *self, PyObject *args) { int type; PyObject *func, *funcarg; /* XXX - more work here */ if (!PyArg_ParseTuple(args, "iOO:addcallback", &type, &func, &funcarg)) return NULL; if (type < 0 || type >= NCALLBACKS) { PyErr_SetString(PyExc_TypeError, "argument out of range"); return NULL; } #ifdef CDsetcallback CDaddcallback(self->ob_cdparser, (CDDATATYPES) type, CD_callback, (void *) self); #else CDsetcallback(self->ob_cdparser, (CDDATATYPES) type, CD_callback, (void *) self); #endif Py_XDECREF(self->ob_cdcallbacks[type].ob_cdcallback); Py_INCREF(func); self->ob_cdcallbacks[type].ob_cdcallback = func; Py_XDECREF(self->ob_cdcallbacks[type].ob_cdcallbackarg); Py_INCREF(funcarg); self->ob_cdcallbacks[type].ob_cdcallbackarg = funcarg; /* if (type == cd_audio) { sigfpe_[_UNDERFL].repls = _ZERO; handle_sigfpes(_ON, _EN_UNDERFL, NULL, _ABORT_ON_ERROR, NULL); } */ Py_INCREF(Py_None); return Py_None; } static PyMethodDef cdparser_methods[] = { {"addcallback", (PyCFunction)CD_addcallback, METH_VARARGS}, {"deleteparser", (PyCFunction)CD_deleteparser, METH_VARARGS}, {"parseframe", (PyCFunction)CD_parseframe, METH_VARARGS}, {"removecallback", (PyCFunction)CD_removecallback, METH_VARARGS}, {"resetparser", (PyCFunction)CD_resetparser, METH_VARARGS}, /* backward compatibility */ {"setcallback", (PyCFunction)CD_addcallback, METH_VARARGS}, {NULL, NULL} /* sentinel */ }; static void cdparser_dealloc(cdparserobject *self) { int i; for (i = 0; i < NCALLBACKS; i++) { Py_XDECREF(self->ob_cdcallbacks[i].ob_cdcallback); self->ob_cdcallbacks[i].ob_cdcallback = NULL; Py_XDECREF(self->ob_cdcallbacks[i].ob_cdcallbackarg); self->ob_cdcallbacks[i].ob_cdcallbackarg = NULL; } CDdeleteparser(self->ob_cdparser); PyObject_Del(self); } static PyObject * cdparser_getattr(cdparserobject *self, char *name) { if (self->ob_cdparser == NULL) { PyErr_SetString(PyExc_RuntimeError, "no parser active"); return NULL; } return Py_FindMethod(cdparser_methods, (PyObject *)self, name); } PyTypeObject CdParsertype = { PyObject_HEAD_INIT(&PyType_Type) 0, /*ob_size*/ "cd.cdparser", /*tp_name*/ sizeof(cdparserobject), /*tp_size*/ 0, /*tp_itemsize*/ /* methods */ (destructor)cdparser_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ (getattrfunc)cdparser_getattr, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ }; static PyObject * newcdparserobject(CDPARSER *cdp) { cdparserobject *p; int i; p = PyObject_New(cdparserobject, &CdParsertype); if (p == NULL) return NULL; p->ob_cdparser = cdp; for (i = 0; i < NCALLBACKS; i++) { p->ob_cdcallbacks[i].ob_cdcallback = NULL; p->ob_cdcallbacks[i].ob_cdcallbackarg = NULL; } return (PyObject *) p; } static PyObject * CD_createparser(PyObject *self, PyObject *args) { CDPARSER *cdp; if (!PyArg_ParseTuple(args, ":createparser")) return NULL; cdp = CDcreateparser(); if (cdp == NULL) { PyErr_SetString(CdError, "createparser failed"); return NULL; } return newcdparserobject(cdp); } static PyObject * CD_msftoframe(PyObject *self, PyObject *args) { int min, sec, frame; if (!PyArg_ParseTuple(args, "iii:msftoframe", &min, &sec, &frame)) return NULL; return PyInt_FromLong((long) CDmsftoframe(min, sec, frame)); } static PyMethodDef CD_methods[] = { {"open", (PyCFunction)CD_open, METH_VARARGS}, {"createparser", (PyCFunction)CD_createparser, METH_VARARGS}, {"msftoframe", (PyCFunction)CD_msftoframe, METH_VARARGS}, {NULL, NULL} /* Sentinel */ }; void initcd(void) { PyObject *m, *d; if (PyErr_WarnPy3k("the cd module has been removed in " "Python 3.0", 2) < 0) return; m = Py_InitModule("cd", CD_methods); if (m == NULL) return; d = PyModule_GetDict(m); CdError = PyErr_NewException("cd.error", NULL, NULL); PyDict_SetItemString(d, "error", CdError); /* Identifiers for the different types of callbacks from the parser */ PyDict_SetItemString(d, "audio", PyInt_FromLong((long) cd_audio)); PyDict_SetItemString(d, "pnum", PyInt_FromLong((long) cd_pnum)); PyDict_SetItemString(d, "index", PyInt_FromLong((long) cd_index)); PyDict_SetItemString(d, "ptime", PyInt_FromLong((long) cd_ptime)); PyDict_SetItemString(d, "atime", PyInt_FromLong((long) cd_atime)); PyDict_SetItemString(d, "catalog", PyInt_FromLong((long) cd_catalog)); PyDict_SetItemString(d, "ident", PyInt_FromLong((long) cd_ident)); PyDict_SetItemString(d, "control", PyInt_FromLong((long) cd_control)); /* Block size information for digital audio data */ PyDict_SetItemString(d, "DATASIZE", PyInt_FromLong((long) CDDA_DATASIZE)); PyDict_SetItemString(d, "BLOCKSIZE", PyInt_FromLong((long) CDDA_BLOCKSIZE)); /* Possible states for the cd player */ PyDict_SetItemString(d, "ERROR", PyInt_FromLong((long) CD_ERROR)); PyDict_SetItemString(d, "NODISC", PyInt_FromLong((long) CD_NODISC)); PyDict_SetItemString(d, "READY", PyInt_FromLong((long) CD_READY)); PyDict_SetItemString(d, "PLAYING", PyInt_FromLong((long) CD_PLAYING)); PyDict_SetItemString(d, "PAUSED", PyInt_FromLong((long) CD_PAUSED)); PyDict_SetItemString(d, "STILL", PyInt_FromLong((long) CD_STILL)); #ifdef CD_CDROM /* only newer versions of the library */ PyDict_SetItemString(d, "CDROM", PyInt_FromLong((long) CD_CDROM)); #endif }
