Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: a guest on May 17th, 2012  |  syntax: None  |  size: 4.01 KB  |  hits: 11  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. static PyObject * convert_zval_to_pyobject(zval **val)
  2.  
  3. {
  4.  
  5.         PyObject *ret;
  6.  
  7.  
  8.  
  9.         if (val == NULL) {
  10.  
  11.                 return NULL;
  12.  
  13.         }
  14.  
  15.  
  16.  
  17.         switch (Z_TYPE_PP(val)) {
  18.  
  19.         case IS_BOOL:
  20.  
  21.                 ret = Py_BuildValue("i", Z_LVAL_PP(val) ? 1 : 0);
  22.  
  23.                 break;
  24.  
  25.         case IS_LONG:
  26.  
  27.                 ret = Py_BuildValue("l", Z_LVAL_PP(val));
  28.  
  29.                 break;
  30.  
  31.         case IS_DOUBLE:
  32.  
  33.                 ret = Py_BuildValue("d", Z_DVAL_PP(val));
  34.  
  35.                 break;
  36.  
  37.         case IS_STRING:
  38.  
  39.                 ret = Py_BuildValue("s", Z_STRVAL_PP(val));
  40.  
  41.                 break;
  42.  
  43.         case IS_ARRAY:
  44.  
  45.                 {
  46.  
  47.                         PyObject *tuple, *dict, *item, *str;
  48.  
  49.                         zval **entry;
  50.  
  51.                         char *string_key;
  52.  
  53.                         long num_key, string_counter = 0;
  54.  
  55.  
  56.  
  57.                         /*
  58.  
  59.                          * Start by building both a tuple and a dictionary.  Because we
  60.  
  61.                          * don't know with any certainty whether the array we've been
  62.  
  63.                          * given is associative, we must create both a sequence and a
  64.  
  65.                          * mapping.
  66.  
  67.                          *
  68.  
  69.                          * If, at the end of the conversion, we find that the original
  70.  
  71.                          * array did _not_ contain any string keys, we return the tuple
  72.  
  73.                          * instead of the dictionary.
  74.  
  75.                          */
  76.  
  77.                         tuple = PyTuple_New(zend_hash_num_elements(Z_ARRVAL_PP(val)));
  78.  
  79.                         dict = PyDict_New();
  80.  
  81.  
  82.  
  83.                         /* Let's start at the very beginning, a very good place to start */
  84.  
  85.                         zend_hash_internal_pointer_reset(Z_ARRVAL_PP(val));
  86.  
  87.  
  88.  
  89.                         /* Iterate over the array's elements */
  90.  
  91.                         while (zend_hash_get_current_data(Z_ARRVAL_PP(val),
  92.  
  93.                                                                                           (void **)&entry) == SUCCESS) {
  94.  
  95.  
  96.  
  97.                                 /* Convert the PHP value to its Python equivalent (recursion) */
  98.  
  99.                                 item = convert_zval_to_pyobject(entry);
  100.  
  101.  
  102.  
  103.                                 switch (zend_hash_get_current_key(Z_ARRVAL_PP(val),
  104.  
  105.                                                                                                   &string_key, &num_key, 0)) {
  106.  
  107.                                         case HASH_KEY_IS_STRING:
  108.  
  109.                                                 PyDict_SetItemString(dict, string_key, item);
  110.  
  111.                                                 string_counter++;
  112.  
  113.                                                 break;
  114.  
  115.                                         case HASH_KEY_IS_LONG:
  116.  
  117.                                                 PyTuple_SetItem(tuple, num_key, item);
  118.  
  119.  
  120.  
  121.                                                 str = PyString_FromFormat("%d", num_key);
  122.  
  123.                                                 PyDict_SetItem(dict, str, item);
  124.  
  125.                                                 Py_DECREF(str);
  126.  
  127.                                                 break;
  128.  
  129.                                         case HASH_KEY_NON_EXISTANT:
  130.  
  131.                                                 php_error(E_ERROR, "No array key");
  132.  
  133.                                                 break;
  134.  
  135.                                 }
  136.  
  137.  
  138.  
  139.                                 /* Advance to the next entry */
  140.  
  141.                                 zend_hash_move_forward(Z_ARRVAL_PP(val));
  142.  
  143.                         }
  144.  
  145.  
  146.  
  147.                         /*
  148.  
  149.                          * If no string keys were used, return the tuple and free the
  150.  
  151.                          * dictionary.  Otherwise, return the dictionary and free the
  152.  
  153.                          * tuple.
  154.  
  155.                          */
  156.  
  157.                         if (string_counter == 0) {
  158.  
  159.                                 ret = tuple;
  160.  
  161.                                 Py_DECREF(dict);
  162.  
  163.                         } else {
  164.  
  165.                                 ret = dict;
  166.  
  167.                                 Py_DECREF(tuple);
  168.  
  169.                         }
  170.  
  171.                 }
  172.  
  173.                 break;
  174.  
  175.         case IS_OBJECT:
  176.  
  177.                 {
  178.  
  179.                         PyObject *item, *str;
  180.  
  181.                         zval **entry;
  182.  
  183.                         char *string_key;
  184.  
  185.                         long num_key;
  186.  
  187.  
  188.  
  189.                         /*
  190.  
  191.                          * At this point, we represent a PHP object as a dictionary of
  192.  
  193.                          * its properties.  In the future, we may provide a true object
  194.  
  195.                          * conversion (which is entirely possible, but it's more work
  196.  
  197.                          * that I plan on doing right now).
  198.  
  199.                          */
  200.  
  201.                         ret = PyDict_New();
  202.  
  203.  
  204.  
  205.                         /* Start at the beginning of the object properties hash */
  206.  
  207.                         zend_hash_internal_pointer_reset(Z_OBJPROP_PP(val));
  208.  
  209.  
  210.  
  211.                         while (zend_hash_get_current_data(Z_OBJPROP_PP(val),
  212.  
  213.                                                                                           (void **)&entry) == SUCCESS) {
  214.  
  215.  
  216.  
  217.                                 /* Convert the PHP value to its Python equivalent (recursion) */
  218.  
  219.                                 item = convert_zval_to_pyobject(entry);
  220.  
  221.  
  222.  
  223.                                 switch (zend_hash_get_current_key(Z_OBJPROP_PP(val),
  224.  
  225.                                                                                                   &string_key, &num_key, 0)) {
  226.  
  227.                                         case HASH_KEY_IS_STRING:
  228.  
  229.                                                 PyDict_SetItemString(ret, string_key, item);
  230.  
  231.                                                 break;
  232.  
  233.                                         case HASH_KEY_IS_LONG:
  234.  
  235.                                                 str = PyString_FromFormat("%d", num_key);
  236.  
  237.                                                 PyObject_SetItem(ret, str, item);
  238.  
  239.                                                 Py_DECREF(str);
  240.  
  241.                                                 break;
  242.  
  243.                                         case HASH_KEY_NON_EXISTANT:
  244.  
  245.                                                 php_error(E_ERROR, "No array key");
  246.  
  247.                                                 break;
  248.  
  249.                                 }
  250.  
  251.  
  252.  
  253.                                 /* Advance to the next entry */
  254.  
  255.                                 zend_hash_move_forward(Z_OBJPROP_PP(val));
  256.  
  257.                         }
  258.  
  259.                 }
  260.  
  261.                 break;
  262.  
  263.         case IS_NULL:
  264.  
  265.                 Py_INCREF(Py_None);
  266.  
  267.                 ret = Py_None;
  268.  
  269.                 break;
  270.  
  271.         default:
  272.  
  273.                 ret = NULL;
  274.  
  275.                 break;
  276.  
  277.         }
  278.  
  279.  
  280.  
  281.         return ret;
  282.  
  283. }