cpp_binding.cc 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768
  1. // Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. // $Id$
  15. /* isc::dns::Name Python bindings */
  16. #define PY_SSIZE_T_CLEAN
  17. #include "config.h"
  18. #include <Python.h>
  19. #include <structmember.h>
  20. #include <exceptions/exceptions.h>
  21. #include <dns/buffer.h>
  22. #include <dns/exceptions.h>
  23. #include <dns/name.h>
  24. #include <dns/messagerenderer.h>
  25. #include <cassert>
  26. using isc::OutOfRange;
  27. using isc::dns::DNSMessageFORMERR;
  28. using isc::dns::InvalidBufferPosition;
  29. using isc::dns::InputBuffer;
  30. using isc::dns::OutputBuffer;
  31. using isc::dns::EmptyLabel;
  32. using isc::dns::TooLongName;
  33. using isc::dns::TooLongLabel;
  34. using isc::dns::BadLabelType;
  35. using isc::dns::BadEscape;
  36. using isc::dns::IncompleteName;
  37. using isc::dns::NameComparisonResult;
  38. using isc::dns::Name;
  39. using isc::dns::MessageRenderer;
  40. static PyObject *cName_Exception;
  41. static PyObject *cName_Relation;
  42. static PyObject *cName_MAX_WIRE;
  43. static PyObject *cName_MAX_LABELS;
  44. static PyObject *cName_MAX_LABELLEN;
  45. static PyObject *cName_MAX_COMPRESS_POINTER;
  46. static PyObject *cName_COMPRESS_POINTER_MARK8;
  47. static PyObject *cName_COMPRESS_POINTER_MARK16;
  48. typedef struct {
  49. PyObject_HEAD
  50. NameComparisonResult *ncr;
  51. } cNCR;
  52. static void cNCR_dealloc(cNCR *self);
  53. static int cNCR_init(cNCR *self, PyObject *args);
  54. static PyObject *cNCR_getOrder(cNCR *self);
  55. static PyObject *cNCR_getCommonLabels(cNCR *self);
  56. static PyObject *cNCR_getRelation(cNCR *self);
  57. static PyMethodDef cNCR_Methods[] = {
  58. { "getOrder", (PyCFunction)cNCR_getOrder, METH_NOARGS,
  59. "Return the ordering of the comparison result" },
  60. { "getCommonLabels", (PyCFunction)cNCR_getCommonLabels, METH_NOARGS,
  61. "Return the number of common labels of the comparison result" },
  62. { "getRelation", (PyCFunction)cNCR_getRelation, METH_NOARGS,
  63. "Return the NameRelation of the comparison result" },
  64. { NULL, NULL, 0, NULL }
  65. };
  66. static PyTypeObject cNCR_Type = {
  67. PyVarObject_HEAD_INIT(NULL, 0)
  68. "bind10_dns_noboost.cNameComparisonResult", /* tp_name */
  69. sizeof(cNCR), /* tp_basicsize */
  70. 0, /* tp_itemsize */
  71. (destructor)cNCR_dealloc, /* tp_dealloc */
  72. NULL, /* tp_print */
  73. NULL, /* tp_getattr */
  74. NULL, /* tp_setattr */
  75. NULL, /* tp_reserved */
  76. NULL, /* tp_repr */
  77. NULL, /* tp_as_number */
  78. NULL, /* tp_as_sequence */
  79. NULL, /* tp_as_mapping */
  80. NULL, /* tp_hash */
  81. NULL, /* tp_call */
  82. NULL, /* tp_str */
  83. NULL, /* tp_getattro */
  84. NULL, /* tp_setattro */
  85. NULL, /* tp_as_buffer */
  86. Py_TPFLAGS_DEFAULT, /* tp_flags */
  87. "C++ NameComparisonResult Object", /* tp_doc */
  88. NULL, /* tp_traverse */
  89. NULL, /* tp_clear */
  90. NULL, /* tp_richcompare */
  91. 0, /* tp_weaklistoffset */
  92. NULL, /* tp_iter */
  93. NULL, /* tp_iternext */
  94. cNCR_Methods, /* tp_methods */
  95. NULL, /* tp_members */
  96. NULL, /* tp_getset */
  97. NULL, /* tp_base */
  98. NULL, /* tp_dict */
  99. NULL, /* tp_descr_get */
  100. NULL, /* tp_descr_set */
  101. 0, /* tp_dictoffset */
  102. (initproc)cNCR_init, /* tp_init */
  103. NULL, /* tp_alloc */
  104. PyType_GenericNew, /* tp_new */
  105. NULL, /* tp_free */
  106. NULL, /* tp_is_gc */
  107. NULL, /* tp_bases */
  108. NULL, /* tp_mro */
  109. NULL, /* tp_cache */
  110. NULL, /* tp_subclasses */
  111. NULL, /* tp_weaklist */
  112. // Note: not sure if the following are correct. Added them just to
  113. // make the compiler happy.
  114. NULL, /* tp_del */
  115. 0 /* tp_version_tag */
  116. };
  117. static void
  118. cNCR_dealloc(cNCR *self) {
  119. if (self->ncr != NULL)
  120. delete self->ncr;
  121. self->ncr = NULL;
  122. Py_TYPE(self)->tp_free(self);
  123. }
  124. static int
  125. cNCR_init(cNCR *self UNUSED_PARAM, PyObject *args UNUSED_PARAM) {
  126. PyErr_SetString(PyExc_NotImplementedError,
  127. "cNameComparisonResult can't be built");
  128. return -1;
  129. }
  130. static PyObject *
  131. cNCR_getOrder(cNCR *self) {
  132. return Py_BuildValue("i", self->ncr->getOrder());
  133. }
  134. static PyObject *
  135. cNCR_getCommonLabels(cNCR *self) {
  136. return Py_BuildValue("I", self->ncr->getCommonLabels());
  137. }
  138. static PyObject *
  139. cNCR_getRelation(cNCR *self) {
  140. return Py_BuildValue("i", (int) self->ncr->getRelation());
  141. }
  142. typedef struct {
  143. PyObject_HEAD
  144. Name *name;
  145. size_t position;
  146. } cName;
  147. static void cName_dealloc(cName *self);
  148. static int cName_init(cName *self, PyObject *args);
  149. static PyObject *cName_getLength(cName *self);
  150. static PyObject *cName_getLabelCount(cName *self);
  151. static PyObject *cName_toText(cName *self, PyObject *args);
  152. static PyObject *cName_toWire(cName *self, PyObject *args);
  153. static PyObject *cName_compare(cName *self, PyObject *args);
  154. static PyObject *cName_equals(cName *self, PyObject *args);
  155. static PyObject *cName_nequals(cName *self, PyObject *args);
  156. static PyObject *cName_richcmp(cName *n1, cName *n2, int op);
  157. static PyObject *cName_split(cName *self, PyObject *args);
  158. static PyObject *cName_concatenate(cName *self, PyObject *args);
  159. static PyObject *cName_downcase(cName *self);
  160. static PyObject *cName_isWildcard(cName *self);
  161. static PyObject *cName_getPosition(cName *self);
  162. static PyObject *cName_clone(cName *self, PyObject *args);
  163. static PyMethodDef cName_Methods[] = {
  164. { "getLength", (PyCFunction)cName_getLength, METH_NOARGS,
  165. "Return the length of the Name" },
  166. { "getLabelCount", (PyCFunction)cName_getLabelCount, METH_NOARGS,
  167. "Return the number of labels" },
  168. { "toText", (PyCFunction)cName_toText, METH_VARARGS,
  169. "Convert the Name to a string" },
  170. { "toWire", (PyCFunction)cName_toWire, METH_VARARGS,
  171. "Render the Name in the wire format" },
  172. { "compare", (PyCFunction)cName_compare, METH_VARARGS,
  173. "Compare two Names" },
  174. { "equals", (PyCFunction)cName_equals, METH_VARARGS,
  175. "Return true iff two Names are equal" },
  176. { "nequals", (PyCFunction)cName_nequals, METH_VARARGS,
  177. "Return true iff two Names are not equal" },
  178. { "split", (PyCFunction)cName_split, METH_VARARGS,
  179. "Extract a specified subpart of Name" },
  180. { "concatenate", (PyCFunction)cName_concatenate, METH_VARARGS,
  181. "Concatenate two Names" },
  182. { "downcase", (PyCFunction)cName_downcase, METH_NOARGS,
  183. "Downcase the calling object" },
  184. { "isWildcard", (PyCFunction)cName_isWildcard, METH_NOARGS,
  185. "Test if this is a wildcard Name" },
  186. { "getPosition", (PyCFunction)cName_getPosition, METH_NOARGS,
  187. "Return the end position in the wire buffer" },
  188. { "clone", (PyCFunction)cName_clone, METH_NOARGS,
  189. "Clone a Name" },
  190. { NULL, NULL, 0, NULL }
  191. };
  192. static PyTypeObject cName_Type = {
  193. PyVarObject_HEAD_INIT(NULL, 0)
  194. "bind10_dns_noboost.cName", /* tp_name */
  195. sizeof(cName), /* tp_basicsize */
  196. 0, /* tp_itemsize */
  197. (destructor)cName_dealloc, /* tp_dealloc */
  198. NULL, /* tp_print */
  199. NULL, /* tp_getattr */
  200. NULL, /* tp_setattr */
  201. NULL, /* tp_reserved */
  202. NULL, /* tp_repr */
  203. NULL, /* tp_as_number */
  204. NULL, /* tp_as_sequence */
  205. NULL, /* tp_as_mapping */
  206. NULL, /* tp_hash */
  207. NULL, /* tp_call */
  208. NULL, /* tp_str */
  209. NULL, /* tp_getattro */
  210. NULL, /* tp_setattro */
  211. NULL, /* tp_as_buffer */
  212. Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
  213. "C++ Name Object", /* tp_doc */
  214. NULL, /* tp_traverse */
  215. NULL, /* tp_clear */
  216. (richcmpfunc)cName_richcmp, /* tp_richcompare */
  217. 0, /* tp_weaklistoffset */
  218. NULL, /* tp_iter */
  219. NULL, /* tp_iternext */
  220. cName_Methods, /* tp_methods */
  221. NULL, /* tp_members */
  222. NULL, /* tp_getset */
  223. NULL, /* tp_base */
  224. NULL, /* tp_dict */
  225. NULL, /* tp_descr_get */
  226. NULL, /* tp_descr_set */
  227. 0, /* tp_dictoffset */
  228. (initproc)cName_init, /* tp_init */
  229. NULL, /* tp_alloc */
  230. PyType_GenericNew, /* tp_new */
  231. NULL, /* tp_free */
  232. NULL, /* tp_is_gc */
  233. NULL, /* tp_bases */
  234. NULL, /* tp_mro */
  235. NULL, /* tp_cache */
  236. NULL, /* tp_subclasses */
  237. NULL, /* tp_weaklist */
  238. // Note: not sure if the following are correct. Added them just to
  239. // make the compiler happy.
  240. NULL, /* tp_del */
  241. 0 /* tp_version_tag */
  242. };
  243. static void
  244. cName_dealloc(cName *self) {
  245. if (self->name != NULL)
  246. delete self->name;
  247. self->name = NULL;
  248. Py_TYPE(self)->tp_free(self);
  249. }
  250. static int
  251. cName_init(cName *self, PyObject *args) {
  252. const char *s;
  253. PyObject *downcase = Py_False;
  254. /* fromText */
  255. if (PyArg_ParseTuple(args, "s|O!", &s, &PyBool_Type, &downcase)) {
  256. try {
  257. const std::string n(s);
  258. self->name = new Name(n, downcase == Py_True);
  259. self->position = 0;
  260. } catch (EmptyLabel) {
  261. PyErr_SetString(cName_Exception, "EmptyLabel");
  262. return -1;
  263. } catch (TooLongLabel) {
  264. PyErr_SetString(cName_Exception, "TooLongLabel");
  265. return -1;
  266. } catch (BadLabelType) {
  267. PyErr_SetString(cName_Exception, "BadLabelType");
  268. return -1;
  269. } catch (BadEscape) {
  270. PyErr_SetString(cName_Exception, "BadEscape");
  271. return -1;
  272. } catch (TooLongName) {
  273. PyErr_SetString(cName_Exception, "TooLongName");
  274. return -1;
  275. } catch (IncompleteName) {
  276. PyErr_SetString(cName_Exception, "IncompleteName");
  277. return -1;
  278. #ifdef CATCHMEMERR
  279. } catch (std::bad_alloc) {
  280. PyErr_NoMemory();
  281. return -1;
  282. #endif
  283. } catch (...) {
  284. PyErr_SetString(cName_Exception, "Unexpected?!");
  285. return -1;
  286. }
  287. return 0;
  288. }
  289. PyErr_Clear();
  290. const char *b;
  291. Py_ssize_t len;
  292. unsigned int position;
  293. /* fromWire */
  294. if (PyArg_ParseTuple(args, "y#I|O!", &b, &len, &position,
  295. &PyBool_Type, &downcase)) {
  296. try {
  297. InputBuffer buffer(b, len);
  298. buffer.setPosition(position);
  299. self->name = new Name(buffer, downcase == Py_True);
  300. self->position = buffer.getPosition();
  301. } catch (InvalidBufferPosition) {
  302. PyErr_SetString(cName_Exception,
  303. "InvalidBufferPosition");
  304. return -1;
  305. } catch (TooLongName) {
  306. PyErr_SetString(cName_Exception, "TooLongName");
  307. return -1;
  308. } catch (BadLabelType) {
  309. PyErr_SetString(cName_Exception, "BadLabelType");
  310. return -1;
  311. } catch (DNSMessageFORMERR) {
  312. PyErr_SetString(cName_Exception, "DNSMessageFORMERR");
  313. return -1;
  314. } catch (IncompleteName) {
  315. PyErr_SetString(cName_Exception, "IncompleteName");
  316. return -1;
  317. #ifdef CATCHMEMERR
  318. } catch (std::bad_alloc) {
  319. PyErr_NoMemory();
  320. return -1;
  321. #endif
  322. } catch (...) {
  323. PyErr_SetString(cName_Exception, "Unexpected?!");
  324. return -1;
  325. }
  326. return 0;
  327. }
  328. PyErr_Clear();
  329. PyErr_SetString(PyExc_TypeError,
  330. "fromText and fromWire Name constructors don't match");
  331. return -1;
  332. }
  333. static PyObject *
  334. cName_getLength(cName *self) {
  335. return Py_BuildValue("I", (unsigned int) self->name->getLength());
  336. }
  337. static PyObject *
  338. cName_getLabelCount(cName *self) {
  339. return Py_BuildValue("I", self->name->getLabelCount());
  340. }
  341. static PyObject *
  342. cName_toText(cName *self, PyObject *args) {
  343. PyObject *omit = Py_False;
  344. if (!PyArg_ParseTuple(args, "|O!", &PyBool_Type, &omit))
  345. return NULL;
  346. try {
  347. std::string s = self->name->toText(omit == Py_True);
  348. return Py_BuildValue("s", s.c_str());
  349. } catch (BadLabelType) {
  350. PyErr_SetString(cName_Exception, "BadLabelType");
  351. return NULL;
  352. }
  353. }
  354. static PyObject *
  355. cName_toWire(cName *self, PyObject *args) {
  356. if (!PyArg_ParseTuple(args, ""))
  357. return NULL;
  358. OutputBuffer buffer(255);
  359. self->name->toWire(buffer);
  360. return Py_BuildValue("y#", buffer.getData(),
  361. (Py_ssize_t) buffer.getLength());
  362. }
  363. static PyObject *
  364. cName_compare(cName *self, PyObject *args) {
  365. cName *other;
  366. if (!PyArg_ParseTuple(args, "O!", &cName_Type, (PyObject **) &other))
  367. return NULL;
  368. cNCR *ret = PyObject_New(cNCR, &cNCR_Type);
  369. if (ret != NULL) {
  370. ret->ncr = new NameComparisonResult(
  371. self->name->compare(*other->name));
  372. if (ret->ncr == NULL) {
  373. Py_DECREF(ret);
  374. return NULL;
  375. }
  376. }
  377. return (PyObject *) ret;
  378. }
  379. static PyObject *
  380. cName_equals(cName *self, PyObject *args) {
  381. cName *other;
  382. if (!PyArg_ParseTuple(args, "O!", &cName_Type, (PyObject **) &other))
  383. return NULL;
  384. if (self->name->equals(*other->name))
  385. Py_RETURN_TRUE;
  386. else
  387. Py_RETURN_FALSE;
  388. }
  389. static PyObject *
  390. cName_nequals(cName *self, PyObject *args) {
  391. cName *other;
  392. if (!PyArg_ParseTuple(args, "O!", &cName_Type, (PyObject **) &other))
  393. return NULL;
  394. if (self->name->nequals(*other->name))
  395. Py_RETURN_TRUE;
  396. else
  397. Py_RETURN_FALSE;
  398. }
  399. static PyObject *
  400. cName_richcmp(cName *n1, cName *n2, int op) {
  401. bool c;
  402. switch (op) {
  403. case Py_LT:
  404. c = n1->name->lthan(*n2->name);
  405. break;
  406. case Py_LE:
  407. c = n1->name->leq(*n2->name);
  408. break;
  409. case Py_EQ:
  410. c = n1->name->equals(*n2->name);
  411. break;
  412. case Py_NE:
  413. c = n1->name->nequals(*n2->name);
  414. break;
  415. case Py_GT:
  416. c = n1->name->gthan(*n2->name);
  417. break;
  418. case Py_GE:
  419. c = n1->name->geq(*n2->name);
  420. break;
  421. default:
  422. assert(0); // XXX: should trigger an exception
  423. }
  424. if (c)
  425. Py_RETURN_TRUE;
  426. else
  427. Py_RETURN_FALSE;
  428. }
  429. static PyObject *
  430. cName_split(cName *self, PyObject *args) {
  431. unsigned int first, n;
  432. if (!PyArg_ParseTuple(args, "II", &first, &n))
  433. return NULL;
  434. cName *ret = PyObject_New(cName, &cName_Type);
  435. if (ret != NULL) {
  436. ret->name = NULL;
  437. try {
  438. ret->name = new Name(self->name->split(first, n));
  439. } catch(OutOfRange) {
  440. PyErr_SetString(cName_Exception, "OutOfRange");
  441. }
  442. if (ret->name == NULL) {
  443. Py_DECREF(ret);
  444. return NULL;
  445. }
  446. }
  447. return (PyObject *) ret;
  448. }
  449. static PyObject *
  450. cName_concatenate(cName *self, PyObject *args) {
  451. cName *suffix;
  452. if (!PyArg_ParseTuple(args, "O!", &cName_Type, (PyObject **) &suffix))
  453. return NULL;
  454. cName *ret = PyObject_New(cName, &cName_Type);
  455. if (ret != NULL) {
  456. ret->name = NULL;
  457. try {
  458. ret->name = new Name(
  459. self->name->concatenate(*suffix->name));
  460. } catch(TooLongName) {
  461. PyErr_SetString(cName_Exception, "TooLongName");
  462. }
  463. if (ret->name == NULL) {
  464. Py_DECREF(ret);
  465. return NULL;
  466. }
  467. }
  468. return (PyObject *) ret;
  469. }
  470. static PyObject *
  471. cName_downcase(cName *self) {
  472. self->name->downcase();
  473. Py_RETURN_NONE;
  474. }
  475. static PyObject *
  476. cName_isWildcard(cName *self) {
  477. if (self->name->isWildcard())
  478. Py_RETURN_TRUE;
  479. else
  480. Py_RETURN_FALSE;
  481. }
  482. static PyObject *
  483. cName_getPosition(cName *self) {
  484. return Py_BuildValue("I", (unsigned int) self->position);
  485. }
  486. static PyObject *
  487. cName_clone(cName *self, PyObject *args UNUSED_PARAM) {
  488. cName *copy = PyObject_New(cName, &cName_Type);
  489. if (copy != NULL) {
  490. copy->name = new Name(*self->name);
  491. if (copy->name == NULL) {
  492. Py_DECREF(copy);
  493. return NULL;
  494. }
  495. }
  496. return (PyObject *) copy;
  497. }
  498. typedef struct {
  499. PyObject_HEAD
  500. MessageRenderer *mr;
  501. OutputBuffer *buffer;
  502. } cMR;
  503. static void cMR_dealloc(cMR *self);
  504. static int cMR_init(cMR *self, PyObject *args);
  505. static PyObject *cMR_dump(cMR *self);
  506. static PyObject *cMR_writeData(cMR *self, PyObject *args);
  507. static PyObject *cMR_writeName(cMR *self, PyObject *args);
  508. static PyMethodDef cMR_Methods[] = {
  509. { "dump", (PyCFunction)cMR_dump, METH_NOARGS,
  510. "Return content of the MessageRenderer" },
  511. { "writeData", (PyCFunction)cMR_writeData, METH_VARARGS,
  512. "Write data into the MessageRenderer" },
  513. { "writeName", (PyCFunction)cMR_writeName, METH_VARARGS,
  514. "Write a Name into the MessageRenderer" },
  515. { NULL, NULL, 0, NULL }
  516. };
  517. static PyTypeObject cMR_Type = {
  518. PyVarObject_HEAD_INIT(NULL, 0)
  519. "bind10_dns_noboost.cMessageRenderer", /* tp_name */
  520. sizeof(cMR), /* tp_basicsize */
  521. 0, /* tp_itemsize */
  522. (destructor)cMR_dealloc, /* tp_dealloc */
  523. NULL, /* tp_print */
  524. NULL, /* tp_getattr */
  525. NULL, /* tp_setattr */
  526. NULL, /* tp_reserved */
  527. NULL, /* tp_repr */
  528. NULL, /* tp_as_number */
  529. NULL, /* tp_as_sequence */
  530. NULL, /* tp_as_mapping */
  531. NULL, /* tp_hash */
  532. NULL, /* tp_call */
  533. NULL, /* tp_str */
  534. NULL, /* tp_getattro */
  535. NULL, /* tp_setattro */
  536. NULL, /* tp_as_buffer */
  537. Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
  538. "C++ MessageRenderer Object", /* tp_doc */
  539. NULL, /* tp_traverse */
  540. NULL, /* tp_clear */
  541. NULL, /* tp_richcompare */
  542. 0, /* tp_weaklistoffset */
  543. NULL, /* tp_iter */
  544. NULL, /* tp_iternext */
  545. cMR_Methods, /* tp_methods */
  546. NULL, /* tp_members */
  547. NULL, /* tp_getset */
  548. NULL, /* tp_base */
  549. NULL, /* tp_dict */
  550. NULL, /* tp_descr_get */
  551. NULL, /* tp_descr_set */
  552. 0, /* tp_dictoffset */
  553. (initproc)cMR_init, /* tp_init */
  554. NULL, /* tp_alloc */
  555. PyType_GenericNew, /* tp_new */
  556. NULL, /* tp_free */
  557. NULL, /* tp_is_gc */
  558. NULL, /* tp_bases */
  559. NULL, /* tp_mro */
  560. NULL, /* tp_cache */
  561. NULL, /* tp_subclasses */
  562. NULL, /* tp_weaklist */
  563. // Note: not sure if the following are correct. Added them just to
  564. // make the compiler happy.
  565. NULL, /* tp_del */
  566. 0 /* tp_version_tag */
  567. };
  568. static void
  569. cMR_dealloc(cMR *self) {
  570. if (self->mr != NULL)
  571. delete self->mr;
  572. self->mr = NULL;
  573. if (self->buffer != NULL)
  574. delete self->buffer;
  575. self->buffer = NULL;
  576. Py_TYPE(self)->tp_free(self);
  577. }
  578. static int
  579. cMR_init(cMR *self, PyObject *args) {
  580. if (!PyArg_ParseTuple(args, ""))
  581. return -1;
  582. self->buffer = new OutputBuffer(1024);
  583. if (self->buffer == NULL) {
  584. (void) PyErr_NoMemory();
  585. return -1;
  586. }
  587. self->mr = new MessageRenderer(*self->buffer);
  588. if (self->mr == NULL) {
  589. delete self->buffer;
  590. self->buffer = NULL;
  591. return -1;
  592. }
  593. return 0;
  594. }
  595. static PyObject *
  596. cMR_dump(cMR *self) {
  597. return Py_BuildValue("y#", self->buffer->getData(),
  598. (Py_ssize_t) self->buffer->getLength());
  599. }
  600. static PyObject *
  601. cMR_writeData(cMR *self, PyObject *args) {
  602. const char *b;
  603. Py_ssize_t len;
  604. if (!PyArg_ParseTuple(args, "y#", &b, &len))
  605. return NULL;
  606. self->buffer->writeData(b, len);
  607. Py_RETURN_NONE;
  608. }
  609. static PyObject *
  610. cMR_writeName(cMR *self, PyObject *args) {
  611. cName *name;
  612. PyObject *compress = Py_True;
  613. if (!PyArg_ParseTuple(args, "O!|O!",
  614. &cName_Type, (PyObject **) &name,
  615. &PyBool_Type, &compress))
  616. return NULL;
  617. self->mr->writeName(*name->name, compress == Py_True);
  618. Py_RETURN_NONE;
  619. }
  620. static PyModuleDef cName_Module = {
  621. { PyObject_HEAD_INIT(NULL) NULL, 0, NULL}, // XXX: ad hoc init values
  622. "bind10_dns_noboost", /* m_name */
  623. "Python bindings for C++ Name Module", /* m_doc */
  624. -1, /* m_size */
  625. NULL, /* m_methods */
  626. NULL, /* m_reload */
  627. NULL, /* m_traverse */
  628. NULL, /* m_clear */
  629. NULL, /* m_free */
  630. };
  631. PyMODINIT_FUNC
  632. PyInit_bind10_dns_noboost(void) {
  633. if (PyType_Ready(&cName_Type) < 0)
  634. return NULL;
  635. if (PyType_Ready(&cNCR_Type) < 0)
  636. return NULL;
  637. if (PyType_Ready(&cMR_Type) < 0)
  638. return NULL;
  639. PyObject *mod;
  640. mod = PyModule_Create(&cName_Module);
  641. if (mod == NULL)
  642. return NULL;
  643. Py_INCREF(&cName_Type);
  644. PyModule_AddObject(mod, "cName", (PyObject *) &cName_Type);
  645. Py_INCREF(&cNCR_Type);
  646. PyModule_AddObject(mod, "cNameComparisonResult",
  647. (PyObject *) &cNCR_Type);
  648. Py_INCREF(&cMR_Type);
  649. PyModule_AddObject(mod, "cMessageRenderer", (PyObject *) &cMR_Type);
  650. cName_Exception = PyErr_NewException("bind10_dns_noboost.DNSException", NULL,
  651. NULL);
  652. Py_INCREF(cName_Exception);
  653. PyModule_AddObject(mod, "DNSException", cName_Exception);
  654. cName_Relation = Py_BuildValue("{i:s,i:s,i:s,i:s}",
  655. 0, "SUPERDOMAIN",
  656. 1, "SUBDOMAIN",
  657. 2, "EQUAL",
  658. 3, "COMMONANCESTOR");
  659. Py_INCREF(cName_Relation);
  660. PyModule_AddObject(mod, "NameRelation", cName_Relation);
  661. cName_MAX_WIRE = Py_BuildValue("I", 255U);
  662. Py_INCREF(cName_MAX_WIRE);
  663. PyModule_AddObject(mod, "MAX_WIRE", cName_MAX_WIRE);
  664. cName_MAX_LABELS = Py_BuildValue("I", 128U);
  665. Py_INCREF(cName_MAX_LABELS);
  666. PyModule_AddObject(mod, "MAX_LABELS", cName_MAX_LABELS);
  667. cName_MAX_LABELLEN = Py_BuildValue("I", 63U);
  668. Py_INCREF(cName_MAX_LABELLEN);
  669. PyModule_AddObject(mod, "MAX_LABELLEN", cName_MAX_LABELLEN);
  670. cName_MAX_COMPRESS_POINTER = Py_BuildValue("I", 0x3fffU);
  671. Py_INCREF(cName_MAX_COMPRESS_POINTER);
  672. PyModule_AddObject(mod, "MAX_COMPRESS_POINTER",
  673. cName_MAX_COMPRESS_POINTER);
  674. cName_COMPRESS_POINTER_MARK8 = Py_BuildValue("I", 0xc0U);
  675. Py_INCREF(cName_COMPRESS_POINTER_MARK8);
  676. PyModule_AddObject(mod, "COMPRESS_POINTER_MARK8",
  677. cName_COMPRESS_POINTER_MARK8);
  678. cName_COMPRESS_POINTER_MARK16 = Py_BuildValue("I", 0xc000U);
  679. Py_INCREF(cName_COMPRESS_POINTER_MARK16);
  680. PyModule_AddObject(mod, "COMPRESS_POINTER_MARK16",
  681. cName_COMPRESS_POINTER_MARK16);
  682. return mod;
  683. }