]> git.sesse.net Git - xml-template/blob - php5-swig/xml-template.swig
Leak a little less memory in php5-swig.
[xml-template] / php5-swig / xml-template.swig
1 %module XML_Template_SWIG
2
3 %{
4
5 #include "../c++11/xml-template.h"
6                 
7 bool is_associative_array(HashTable *ht)
8 {
9         if (ht->nNumOfElements == 0) {
10                 return true;
11         }
12         for (unsigned i = 0; i < ht->nNumOfElements; ++i) {
13                 if (!zend_hash_index_exists(ht, i)) {
14                         return true;
15                 }
16         }
17         return false;
18 }
19
20 Directive* convert_php_objects_to_directive(zval *obj)
21 {
22         switch (Z_TYPE_P(obj)) {
23         case IS_ARRAY: {
24                 HashTable *ht = Z_ARRVAL_P(obj);
25                 if (is_associative_array(ht)) {
26                         std::unordered_map<std::string, Directive *> my_map;
27                         for (zend_hash_internal_pointer_reset(ht); zend_hash_has_more_elements(ht) == SUCCESS; zend_hash_move_forward(ht)) {
28                                 char *str_key;
29                                 ulong num_key;
30                                 zend_hash_get_current_key(ht, &str_key, &num_key, 0);
31
32                                 std::string key;
33                                 if (zend_hash_get_current_key_type(ht) == HASH_KEY_IS_STRING) {
34                                         key = str_key;
35                                 } else {
36                                         char buf[32];
37                                         sprintf(buf, "%lu", num_key);
38                                         key = buf;
39                                 }
40
41                                 zval **data;
42                                 zend_hash_get_current_data(ht, (void **)&data);
43                                 my_map.insert(make_pair(key, convert_php_objects_to_directive(*data)));
44                         }
45                         return new Substitute(my_map);
46                 } else {
47                         std::vector<Directive *> subdirectives;
48                         for (unsigned i = 0; i < ht->nNumOfElements; ++i) {
49                                 zval **data;
50                                 zend_hash_index_find(ht, i, (void **)&data);
51                                 subdirectives.push_back(convert_php_objects_to_directive(*data));
52                         }
53                         return new Clone(subdirectives);
54                 }
55                 break;
56         }
57         case IS_STRING: {
58                 char *str = Z_STRVAL_P(obj);
59                 return new Replace(str);
60         }
61         case IS_NULL:
62                 return NULL;
63         default:
64                 printf("WARNING: Unknown type %d!\n", Z_TYPE_P(obj));
65                 break;
66         }
67
68         return NULL;
69 }
70
71 xmlDocPtr XML_Template_process_file(const char *input_filename, Directive *root_directive, bool clean)
72 {
73         xmlDocPtr ret = process_file(input_filename, root_directive, clean);
74         delete root_directive;
75         return ret;
76 }
77
78 %}
79
80 %typemap(in) Directive* {
81         $1 = convert_php_objects_to_directive(*$input);
82 }
83
84 xmlDocPtr XML_Template_process_file(const char *input_filename, Directive *root_directive, bool clean);
85 void output_to_fd_and_free(xmlDocPtr doc, int fd);
86