name_python.cc 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681
  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. //
  16. // Declaration of the custom exceptions
  17. // Initialization and addition of these go in the module init at the
  18. // end
  19. //
  20. static PyObject* po_EmptyLabel;
  21. static PyObject* po_TooLongName;
  22. static PyObject* po_TooLongLabel;
  23. static PyObject* po_BadLabelType;
  24. static PyObject* po_BadEscape;
  25. static PyObject* po_IncompleteName;
  26. static PyObject* po_InvalidBufferPosition;
  27. static PyObject* po_DNSMessageFORMERR;
  28. //
  29. // Declaration of enums
  30. // Initialization and addition of these go in the module init at the
  31. // end
  32. //
  33. static PyObject* po_NameRelation;
  34. //
  35. // Definition of the classes
  36. //
  37. // For each class, we need a struct, a helper functions (init, destroy,
  38. // and static wrappers around the methods we export), a list of methods,
  39. // and a type description
  40. using namespace isc::dns;
  41. // NameComparisonResult
  42. class s_NameComparisonResult : public PyObject {
  43. public:
  44. isc::dns::NameComparisonResult* ncr;
  45. };
  46. static int NameComparisonResult_init(s_NameComparisonResult* self UNUSED_PARAM, PyObject* args UNUSED_PARAM);
  47. static void NameComparisonResult_destroy(s_NameComparisonResult* self);
  48. static PyObject* NameComparisonResult_getOrder(s_NameComparisonResult* self);
  49. static PyObject* NameComparisonResult_getCommonLabels(s_NameComparisonResult* self);
  50. static PyObject* NameComparisonResult_getRelation(s_NameComparisonResult* self);
  51. static PyMethodDef NameComparisonResult_methods[] = {
  52. { "get_order", reinterpret_cast<PyCFunction>(NameComparisonResult_getOrder), METH_NOARGS,
  53. "Returns the order" },
  54. { "get_common_labels", reinterpret_cast<PyCFunction>(NameComparisonResult_getCommonLabels), METH_NOARGS,
  55. "Returns the number of common labels" },
  56. { "get_relation", reinterpret_cast<PyCFunction>(NameComparisonResult_getRelation), METH_NOARGS,
  57. "Returns the relation" },
  58. { NULL, NULL, 0, NULL }
  59. };
  60. static PyTypeObject name_comparison_result_type = {
  61. PyVarObject_HEAD_INIT(NULL, 0)
  62. "libdns_python.NameComparisonResult",
  63. sizeof(s_NameComparisonResult), // tp_basicsize
  64. 0, // tp_itemsize
  65. (destructor)NameComparisonResult_destroy, // tp_dealloc
  66. NULL, // tp_print
  67. NULL, // tp_getattr
  68. NULL, // tp_setattr
  69. NULL, // tp_reserved
  70. NULL, // tp_repr
  71. NULL, // tp_as_number
  72. NULL, // tp_as_sequence
  73. NULL, // tp_as_mapping
  74. NULL, // tp_hash
  75. NULL, // tp_call
  76. NULL, // tp_str
  77. NULL, // tp_getattro
  78. NULL, // tp_setattro
  79. NULL, // tp_as_buffer
  80. Py_TPFLAGS_DEFAULT, // tp_flags
  81. "This is a supplemental class used only as a return value of Name.compare(). "
  82. "It encapsulate a tuple of the comparison: ordering, number of common labels, "
  83. "and relationship as follows:\n"
  84. "- ordering: relative ordering under the DNSSEC order relation\n"
  85. "- labels: the number of common significant labels of the two names being"
  86. " compared\n"
  87. "- relationship: see NameComparisonResult.NameRelation\n",
  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. NameComparisonResult_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)NameComparisonResult_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. NULL, // tp_del
  113. 0 // tp_version_tag
  114. };
  115. static int
  116. NameComparisonResult_init(s_NameComparisonResult* self UNUSED_PARAM,
  117. PyObject* args UNUSED_PARAM)
  118. {
  119. PyErr_SetString(PyExc_NotImplementedError,
  120. "NameComparisonResult can't be built directly");
  121. return (-1);
  122. }
  123. static void
  124. NameComparisonResult_destroy(s_NameComparisonResult* self) {
  125. delete self->ncr;
  126. self->ncr = NULL;
  127. Py_TYPE(self)->tp_free(self);
  128. }
  129. static PyObject*
  130. NameComparisonResult_getOrder(s_NameComparisonResult* self) {
  131. return (Py_BuildValue("i", self->ncr->getOrder()));
  132. }
  133. static PyObject*
  134. NameComparisonResult_getCommonLabels(s_NameComparisonResult* self) {
  135. return (Py_BuildValue("I", self->ncr->getCommonLabels()));
  136. }
  137. static PyObject*
  138. NameComparisonResult_getRelation(s_NameComparisonResult* self) {
  139. return (Py_BuildValue("I", self->ncr->getRelation()));
  140. }
  141. // end of NameComparisonResult
  142. // Name
  143. class s_Name : public PyObject {
  144. public:
  145. isc::dns::Name* name;
  146. size_t position;
  147. };
  148. static int Name_init(s_Name* self, PyObject* args);
  149. static void Name_destroy(s_Name* self);
  150. static PyObject* Name_toWire(s_Name* self, PyObject* args);
  151. static PyObject* Name_toText(s_Name* self);
  152. static PyObject* Name_str(PyObject* self);
  153. static PyObject* Name_getLabelCount(s_Name* self);
  154. static PyObject* Name_at(s_Name* self, PyObject* args);
  155. static PyObject* Name_getLength(s_Name* self);
  156. static PyObject* Name_compare(s_Name* self, PyObject* args);
  157. static PyObject* Name_equals(s_Name* self, PyObject* args);
  158. static PyObject* Name_richcmp(s_Name* self, s_Name* other, int op);
  159. static PyObject* Name_split(s_Name* self, PyObject* args);
  160. static PyObject* Name_reverse(s_Name* self);
  161. static PyObject* Name_concatenate(s_Name* self, PyObject* args);
  162. static PyObject* Name_downcase(s_Name* self);
  163. static PyObject* Name_isWildCard(s_Name* self);
  164. static PyMethodDef Name_methods[] = {
  165. { "at", reinterpret_cast<PyCFunction>(Name_at), METH_VARARGS,
  166. "Returns the integer value of the name data at the specified position" },
  167. { "get_length", reinterpret_cast<PyCFunction>(Name_getLength), METH_NOARGS,
  168. "Returns the length" },
  169. { "get_labelcount", reinterpret_cast<PyCFunction>(Name_getLabelCount), METH_NOARGS,
  170. "Returns the number of labels" },
  171. { "to_text", reinterpret_cast<PyCFunction>(Name_toText), METH_NOARGS,
  172. "Returns the string representation" },
  173. { "to_wire", reinterpret_cast<PyCFunction>(Name_toWire), METH_VARARGS,
  174. "Converts the Name object to wire format.\n"
  175. "The argument can be either a MessageRenderer or an object that "
  176. "implements the sequence interface. If the object is mutable "
  177. "(for instance a bytearray()), the wire data is added in-place.\n"
  178. "If it is not (for instance a bytes() object), a new object is "
  179. "returned" },
  180. { "compare", reinterpret_cast<PyCFunction>(Name_compare), METH_VARARGS,
  181. "Returns a NameComparisonResult object. The argument must be another Name object" },
  182. { "equals", reinterpret_cast<PyCFunction>(Name_equals), METH_VARARGS,
  183. "Returns true if the given Name object is equal to this one" },
  184. { "split", reinterpret_cast<PyCFunction>(Name_split), METH_VARARGS,
  185. "Splits the name, takes two arguments, the first is an integer "
  186. "specifying the first label to place in the result. The second "
  187. "is an integer specifying the number of labels to put in the "
  188. "result. Returns a new Name object" },
  189. { "reverse", reinterpret_cast<PyCFunction>(Name_reverse), METH_NOARGS,
  190. "Returns a new Name object that is the reverse of this one" },
  191. { "concatenate", reinterpret_cast<PyCFunction>(Name_concatenate), METH_VARARGS,
  192. "Concatenates the given Name object to this one and returns the "
  193. "result as a new Name object" },
  194. { "downcase", reinterpret_cast<PyCFunction>(Name_downcase), METH_NOARGS,
  195. "Downcases this name object (in-place). Returns a new reference to the Name." },
  196. { "is_wildcard", reinterpret_cast<PyCFunction>(Name_isWildCard), METH_NOARGS,
  197. "Returns True if the Name object represents a wildcard name." },
  198. { NULL, NULL, 0, NULL }
  199. };
  200. static PyTypeObject name_type = {
  201. PyVarObject_HEAD_INIT(NULL, 0)
  202. "libdns_python.Name",
  203. sizeof(s_Name), // tp_basicsize
  204. 0, // tp_itemsize
  205. (destructor)Name_destroy, // tp_dealloc
  206. NULL, // tp_print
  207. NULL, // tp_getattr
  208. NULL, // tp_setattr
  209. NULL, // tp_reserved
  210. NULL, // tp_repr
  211. NULL, // tp_as_number
  212. NULL, // tp_as_sequence
  213. NULL, // tp_as_mapping
  214. NULL, // tp_hash
  215. NULL, // tp_call
  216. Name_str, // tp_str
  217. NULL, // tp_getattro
  218. NULL, // tp_setattro
  219. NULL, // tp_as_buffer
  220. Py_TPFLAGS_DEFAULT, // tp_flags
  221. "The Name class encapsulates DNS names.\n"
  222. "It provides interfaces to construct a name from string or wire-format data, "
  223. "transform a name into a string or wire-format data, compare two names, get "
  224. "access to various properties of a name, etc.",
  225. NULL, // tp_traverse
  226. NULL, // tp_clear
  227. (richcmpfunc)Name_richcmp, // tp_richcompare
  228. 0, // tp_weaklistoffset
  229. NULL, // tp_iter
  230. NULL, // tp_iternext
  231. Name_methods, // tp_methods
  232. NULL, // tp_members
  233. NULL, // tp_getset
  234. NULL, // tp_base
  235. NULL, // tp_dict
  236. NULL, // tp_descr_get
  237. NULL, // tp_descr_set
  238. 0, // tp_dictoffset
  239. (initproc)Name_init, // tp_init
  240. NULL, // tp_alloc
  241. PyType_GenericNew, // tp_new
  242. NULL, // tp_free
  243. NULL, // tp_is_gc
  244. NULL, // tp_bases
  245. NULL, // tp_mro
  246. NULL, // tp_cache
  247. NULL, // tp_subclasses
  248. NULL, // tp_weaklist
  249. // Note: not sure if the following are correct. Added them just to
  250. // make the compiler happy.
  251. NULL, // tp_del
  252. 0 // tp_version_tag
  253. };
  254. static int
  255. Name_init(s_Name* self, PyObject* args) {
  256. const char* s;
  257. PyObject* downcase = Py_False;
  258. // Depending on the arguments in *args, we decide which of the
  259. // constructors is meant. If the first argument is of type string,
  260. // we use the string-based constructor. If it is a bytes object,
  261. // we use the wire-based one.
  262. if (PyArg_ParseTuple(args, "s|O!", &s, &PyBool_Type, &downcase)) {
  263. try {
  264. const std::string n(s);
  265. self->name = new Name(n, downcase == Py_True);
  266. self->position = 0;
  267. } catch (const EmptyLabel&) {
  268. PyErr_SetString(po_EmptyLabel, "EmptyLabel");
  269. return (-1);
  270. } catch (const TooLongLabel&) {
  271. PyErr_SetString(po_TooLongLabel, "TooLongLabel");
  272. return (-1);
  273. } catch (const BadLabelType&) {
  274. PyErr_SetString(po_BadLabelType, "BadLabelType");
  275. return (-1);
  276. } catch (const BadEscape&) {
  277. PyErr_SetString(po_BadEscape, "BadEscape");
  278. return (-1);
  279. } catch (const TooLongName&) {
  280. PyErr_SetString(po_TooLongName, "TooLongName");
  281. return (-1);
  282. } catch (const IncompleteName&) {
  283. PyErr_SetString(po_IncompleteName, "IncompleteName");
  284. return (-1);
  285. #ifdef CATCHMEMERR
  286. } catch (const std::bad_alloc&) {
  287. PyErr_NoMemory();
  288. return (-1);
  289. #endif
  290. } catch (...) {
  291. PyErr_SetString(po_IscException, "Unexpected?!");
  292. return (-1);
  293. }
  294. return (0);
  295. }
  296. PyErr_Clear();
  297. PyObject* bytes_obj;
  298. const char* bytes;
  299. Py_ssize_t len;
  300. unsigned int position = 0;
  301. // It was not a string (see comment above), so try bytes, and
  302. // create with buffer object
  303. if (PyArg_ParseTuple(args, "O|IO!", &bytes_obj, &position,
  304. &PyBool_Type, &downcase) &&
  305. PyObject_AsCharBuffer(bytes_obj, &bytes, &len) != -1) {
  306. try {
  307. InputBuffer buffer(bytes, len);
  308. buffer.setPosition(position);
  309. self->name = new Name(buffer, downcase == Py_True);
  310. self->position = buffer.getPosition();
  311. } catch (const InvalidBufferPosition&) {
  312. PyErr_SetString(po_InvalidBufferPosition,
  313. "InvalidBufferPosition");
  314. return (-1);
  315. } catch (const DNSMessageFORMERR&) {
  316. PyErr_SetString(po_DNSMessageFORMERR, "DNSMessageFORMERR");
  317. return (-1);
  318. } catch (...) {
  319. PyErr_SetString(po_IscException, "Unexpected?!");
  320. return (-1);
  321. }
  322. return (0);
  323. }
  324. PyErr_Clear();
  325. PyErr_SetString(PyExc_TypeError,
  326. "No valid types in Name constructor (should be string or sequence and offset");
  327. return (-1);
  328. }
  329. static void
  330. Name_destroy(s_Name* self) {
  331. delete self->name;
  332. self->name = NULL;
  333. Py_TYPE(self)->tp_free(self);
  334. }
  335. static PyObject*
  336. Name_at(s_Name* self, PyObject* args) {
  337. unsigned int pos;
  338. if (!PyArg_ParseTuple(args, "I", &pos)) {
  339. return (NULL);
  340. }
  341. try {
  342. return (Py_BuildValue("I", self->name->at(pos)));
  343. } catch (const isc::OutOfRange&) {
  344. PyErr_SetString(PyExc_IndexError,
  345. "name index out of range");
  346. return (NULL);
  347. }
  348. }
  349. static PyObject*
  350. Name_getLength(s_Name* self) {
  351. return (Py_BuildValue("i", self->name->getLength()));
  352. }
  353. static PyObject*
  354. Name_getLabelCount(s_Name* self) {
  355. return (Py_BuildValue("i", self->name->getLabelCount()));
  356. }
  357. static PyObject*
  358. Name_toText(s_Name* self) {
  359. return (Py_BuildValue("s", self->name->toText().c_str()));
  360. }
  361. static PyObject*
  362. Name_str(PyObject* self) {
  363. // Simply call the to_text method we already defined
  364. // str() is not defined in the c++ version, only to_text
  365. // and we already have a wrapper for that one.
  366. return PyObject_CallMethod(self,
  367. const_cast<char*>("to_text"),
  368. const_cast<char*>(""));
  369. }
  370. static PyObject*
  371. Name_toWire(s_Name* self, PyObject* args) {
  372. PyObject* bytes;
  373. s_MessageRenderer* mr;
  374. if (PyArg_ParseTuple(args, "O", &bytes) && PySequence_Check(bytes)) {
  375. PyObject* bytes_o = bytes;
  376. OutputBuffer buffer(Name::MAX_WIRE);
  377. self->name->toWire(buffer);
  378. PyObject* name_bytes = PyBytes_FromStringAndSize(static_cast<const char*>(buffer.getData()), buffer.getLength());
  379. PyObject* result = PySequence_InPlaceConcat(bytes_o, name_bytes);
  380. // We need to release the object we temporarily created here
  381. // to prevent memory leak
  382. Py_DECREF(name_bytes);
  383. return (result);
  384. } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, (PyObject**) &mr)) {
  385. self->name->toWire(*mr->messagerenderer);
  386. // If we return NULL it is seen as an error, so use this for
  387. // None returns
  388. Py_RETURN_NONE;
  389. }
  390. PyErr_Clear();
  391. PyErr_SetString(PyExc_TypeError,
  392. "toWire argument must be a sequence object or a MessageRenderer");
  393. return (NULL);
  394. }
  395. static PyObject*
  396. Name_compare(s_Name* self, PyObject* args) {
  397. s_Name* other;
  398. if (!PyArg_ParseTuple(args, "O!", &name_type, (PyObject* *) &other))
  399. return (NULL);
  400. s_NameComparisonResult* ret = PyObject_New(s_NameComparisonResult, &name_comparison_result_type);
  401. if (ret != NULL) {
  402. ret->ncr = new NameComparisonResult(
  403. self->name->compare(*other->name));
  404. }
  405. return (ret);
  406. }
  407. static PyObject*
  408. Name_equals(s_Name* self, PyObject* args) {
  409. s_Name* other;
  410. if (!PyArg_ParseTuple(args, "O!", &name_type, (PyObject* *) &other))
  411. return (NULL);
  412. if (self->name->equals(*other->name))
  413. Py_RETURN_TRUE;
  414. else
  415. Py_RETURN_FALSE;
  416. }
  417. static PyObject*
  418. Name_split(s_Name* self, PyObject* args) {
  419. unsigned int first, n;
  420. s_Name* ret = NULL;
  421. if (PyArg_ParseTuple(args, "II", &first, &n)) {
  422. ret = PyObject_New(s_Name, &name_type);
  423. if (ret != NULL) {
  424. ret->name = NULL;
  425. try {
  426. ret->name = new Name(self->name->split(first, n));
  427. } catch(const isc::OutOfRange& oor) {
  428. PyErr_SetString(PyExc_IndexError, oor.what());
  429. ret->name = NULL;
  430. }
  431. if (ret->name == NULL) {
  432. Py_DECREF(ret);
  433. return (NULL);
  434. }
  435. }
  436. } else if (PyArg_ParseTuple(args, "I", &n)) {
  437. ret = PyObject_New(s_Name, &name_type);
  438. if (ret != NULL) {
  439. ret->name = NULL;
  440. try {
  441. ret->name = new Name(self->name->split(n));
  442. } catch(const isc::OutOfRange& oor) {
  443. PyErr_SetString(PyExc_IndexError, oor.what());
  444. ret->name = NULL;
  445. }
  446. if (ret->name == NULL) {
  447. Py_DECREF(ret);
  448. return (NULL);
  449. }
  450. }
  451. }
  452. return (ret);
  453. }
  454. #include <iostream>
  455. //
  456. // richcmp defines the ==, !=, >, <, >= and <= operators in python
  457. // It is translated to a function that gets 3 arguments, an object,
  458. // an object to compare to, and an operator.
  459. //
  460. static PyObject*
  461. Name_richcmp(s_Name* self, s_Name* other, int op) {
  462. bool c;
  463. // Check for null and if the types match. If different type,
  464. // simply return False
  465. if (!other || (self->ob_type != other->ob_type)) {
  466. Py_RETURN_FALSE;
  467. }
  468. switch (op) {
  469. case Py_LT:
  470. c = *self->name < *other->name;
  471. break;
  472. case Py_LE:
  473. c = *self->name <= *other->name;
  474. break;
  475. case Py_EQ:
  476. c = *self->name == *other->name;
  477. break;
  478. case Py_NE:
  479. c = *self->name != *other->name;
  480. break;
  481. case Py_GT:
  482. c = *self->name > *other->name;
  483. break;
  484. case Py_GE:
  485. c = *self->name >= *other->name;
  486. break;
  487. default:
  488. PyErr_SetString(PyExc_IndexError,
  489. "Unhandled rich comparison operator");
  490. return (NULL);
  491. }
  492. if (c) {
  493. Py_RETURN_TRUE;
  494. } else {
  495. Py_RETURN_FALSE;
  496. }
  497. }
  498. static PyObject*
  499. Name_reverse(s_Name* self) {
  500. s_Name* ret = PyObject_New(s_Name, &name_type);
  501. if (ret != NULL) {
  502. ret->name = new Name(self->name->reverse());
  503. if (ret->name == NULL) {
  504. Py_DECREF(ret);
  505. return (NULL);
  506. }
  507. }
  508. return (ret);
  509. }
  510. static PyObject*
  511. Name_concatenate(s_Name* self, PyObject* args) {
  512. s_Name* other;
  513. if (!PyArg_ParseTuple(args, "O!", &name_type, (PyObject**) &other))
  514. return (NULL);
  515. s_Name* ret = PyObject_New(s_Name, &name_type);
  516. if (ret != NULL) {
  517. try {
  518. ret->name = new Name(self->name->concatenate(*other->name));
  519. } catch (const TooLongName& tln) {
  520. PyErr_SetString(po_TooLongName, tln.what());
  521. return (NULL);
  522. }
  523. }
  524. return (ret);
  525. }
  526. static PyObject*
  527. Name_downcase(s_Name* self) {
  528. self->name->downcase();
  529. Py_INCREF(self);
  530. return (self);
  531. }
  532. static PyObject*
  533. Name_isWildCard(s_Name* self) {
  534. if (self->name->isWildcard()) {
  535. Py_RETURN_TRUE;
  536. } else {
  537. Py_RETURN_FALSE;
  538. }
  539. }
  540. // end of Name
  541. // Module Initialization, all statics are initialized here
  542. bool
  543. initModulePart_Name(PyObject* mod) {
  544. // Add the classes to the module
  545. // We initialize the static description object with PyType_Ready(),
  546. // then add it to the module
  547. //
  548. // NameComparisonResult
  549. //
  550. if (PyType_Ready(&name_comparison_result_type) < 0) {
  551. return (false);
  552. }
  553. Py_INCREF(&name_comparison_result_type);
  554. // Add the enums to the module
  555. po_NameRelation = Py_BuildValue("{i:s,i:s,i:s,i:s}",
  556. NameComparisonResult::SUPERDOMAIN, "SUPERDOMAIN",
  557. NameComparisonResult::SUBDOMAIN, "SUBDOMAIN",
  558. NameComparisonResult::EQUAL, "EQUAL",
  559. NameComparisonResult::COMMONANCESTOR, "COMMONANCESTOR");
  560. addClassVariable(name_comparison_result_type, "NameRelation", po_NameRelation);
  561. PyModule_AddObject(mod, "NameComparisonResult",
  562. reinterpret_cast<PyObject*>(&name_comparison_result_type));
  563. //
  564. // Name
  565. //
  566. if (PyType_Ready(&name_type) < 0) {
  567. return (false);
  568. }
  569. Py_INCREF(&name_type);
  570. // Add the constants to the module
  571. addClassVariable(name_type, "MAX_WIRE", Py_BuildValue("I", Name::MAX_WIRE));
  572. addClassVariable(name_type, "MAX_LABELS", Py_BuildValue("I", Name::MAX_LABELS));
  573. addClassVariable(name_type, "MAX_LABELLEN", Py_BuildValue("I", Name::MAX_LABELLEN));
  574. addClassVariable(name_type, "MAX_COMPRESS_POINTER", Py_BuildValue("I", Name::MAX_COMPRESS_POINTER));
  575. addClassVariable(name_type, "COMPRESS_POINTER_MARK8", Py_BuildValue("I", Name::COMPRESS_POINTER_MARK8));
  576. addClassVariable(name_type, "COMPRESS_POINTER_MARK16", Py_BuildValue("I", Name::COMPRESS_POINTER_MARK16));
  577. s_Name* root_name = PyObject_New(s_Name, &name_type);
  578. root_name->name = new Name(Name::ROOT_NAME());
  579. PyObject* po_ROOT_NAME = root_name;
  580. addClassVariable(name_type, "ROOT_NAME", po_ROOT_NAME);
  581. PyModule_AddObject(mod, "Name",
  582. reinterpret_cast<PyObject*>(&name_type));
  583. // Add the exceptions to the module
  584. po_EmptyLabel = PyErr_NewException("libdns_python.EmptyLabel", NULL, NULL);
  585. PyModule_AddObject(mod, "EmptyLabel", po_EmptyLabel);
  586. po_TooLongName = PyErr_NewException("libdns_python.TooLongName", NULL, NULL);
  587. PyModule_AddObject(mod, "TooLongName", po_TooLongName);
  588. po_TooLongLabel = PyErr_NewException("libdns_python.TooLongLabel", NULL, NULL);
  589. PyModule_AddObject(mod, "TooLongLabel", po_TooLongLabel);
  590. po_BadLabelType = PyErr_NewException("libdns_python.BadLabelType", NULL, NULL);
  591. PyModule_AddObject(mod, "BadLabelType", po_BadLabelType);
  592. po_BadEscape = PyErr_NewException("libdns_python.BadEscape", NULL, NULL);
  593. PyModule_AddObject(mod, "BadEscape", po_BadEscape);
  594. po_IncompleteName = PyErr_NewException("libdns_python.IncompleteName", NULL, NULL);
  595. PyModule_AddObject(mod, "IncompleteName", po_IncompleteName);
  596. po_InvalidBufferPosition = PyErr_NewException("libdns_python.InvalidBufferPosition", NULL, NULL);
  597. PyModule_AddObject(mod, "InvalidBufferPosition", po_InvalidBufferPosition);
  598. // This one could have gone into the message_python.cc file, but is
  599. // already needed here.
  600. po_DNSMessageFORMERR = PyErr_NewException("libdns_python.DNSMessageFORMERR", NULL, NULL);
  601. PyModule_AddObject(mod, "DNSMessageFORMERR", po_DNSMessageFORMERR);
  602. return (true);
  603. }