1 /*
2    +----------------------------------------------------------------------+
3    | Copyright (c) The PHP Group                                          |
4    +----------------------------------------------------------------------+
5    | This source file is subject to version 3.01 of the PHP license,      |
6    | that is bundled with this package in the file LICENSE, and is        |
7    | available through the world-wide-web at the following url:           |
8    | http://www.php.net/license/3_01.txt                                  |
9    | If you did not receive a copy of the PHP license and are unable to   |
10    | obtain it through the world-wide-web, please send a note to          |
11    | license@php.net so we can mail you a copy immediately.               |
12    +----------------------------------------------------------------------+
13    | Authors:                                                             |
14    |          Israel Ekpo <iekpo@php.net>                                 |
15    |          Omar Shaban <omars@php.net>                                 |
16    +----------------------------------------------------------------------+
17 */
18 
19 #ifndef SOLR_MACROS_H
20 #define SOLR_MACROS_H
21 
22 #include <limits.h>
23 
24 /* Macros for Object constructors and destructors declaration */
25 #define SOLR_CTOR(class_name, func_name, arginfo) PHP_ME(class_name, func_name, arginfo, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
26 #define SOLR_DTOR(class_name, func_name, arginfo) PHP_ME(class_name, func_name, arginfo, ZEND_ACC_PUBLIC)
27 
28 /* Retrieve a unique hash index for this SolrDocument. Unique for this thread */
29 #define SOLR_UNIQUE_DOCUMENT_INDEX() solr_hashtable_get_new_index(SOLR_GLOBAL(documents))
30 
31 /* Retrieve a unique hash index for this SolrClient. Unique for this thread */
32 #define SOLR_UNIQUE_CLIENT_INDEX() solr_hashtable_get_new_index(SOLR_GLOBAL(clients))
33 
34 /* Retrieve a unique hash index for this SolrParams instance. Unique for this thread */
35 #define SOLR_UNIQUE_PARAMS_INDEX() solr_hashtable_get_new_index(SOLR_GLOBAL(params))
36 
37 /* Retrieve a unique hash index for this SolrFunction instance. Unique for this thread */
38 #define SOLR_UNIQUE_FUNCTION_INDEX() solr_hashtable_get_new_index(SOLR_GLOBAL(functions))
39 
40 /* Retrieve a unique hash index for this update stream instances. Unique for this thread */
41 #define SOLR_UNIQUE_USTREAM_INDEX() solr_hashtable_get_new_index(SOLR_GLOBAL(ustreams))
42 
43 /* Iterates through the HashTable pointer */
44 #define SOLR_HASHTABLE_FOR_LOOP(HashTablePtr) \
45 	if (HashTablePtr) for ( zend_hash_internal_pointer_reset((HashTablePtr)); \
46 	SUCCESS == zend_hash_has_more_elements((HashTablePtr)); \
47 	zend_hash_move_forward((HashTablePtr)) )
48 
49 #define SOLR_HASHTABLE_FOR_LOOP_EX(HashTablePtr, pos) \
50     if (HashTablePtr) for ( zend_hash_internal_pointer_reset_ex(HashTablePtr, &pos); \
51     SUCCESS == zend_hash_has_more_elements_ex((HashTablePtr), &pos); \
52     zend_hash_move_forward_ex((HashTablePtr), &pos) )
53 
54 #define SOLR_HASH_FOREACH_PTR(HashTablePtr, ptr) \
55     if (HashTablePtr) ZEND_HASH_FOREACH_PTR(HashTablePtr, ptr)
56 
57 #define SOLR_HASH_FOREACH_END() \
58     ZEND_HASH_FOREACH_END()
59 
60 /* Gets a random number between 1 and SHRT_MAX */
61 #define SOLR_GET_RANDOM_NUMBER() abs(rand() % SHRT_MAX + 1)
62 
63 /* {{{ Memory Allocation Macros */
64 /* Used only to release truly persistent allocations */
65 #define SOLR_FREE_PTR(ptr) { if (ptr != NULL) { pefree(ptr,SOLR_HASHTABLE_PERSISTENT); ptr = NULL; } else { printf("\nSOLR_FREE_PTR double free() from function %s() called in %s on line %d\n", __func__, __FILE__, __LINE__);  } }
66 /* }}} */
67 
68 /**
69  * Used to retrieve xmlAttr and xmlNode values
70  *
71  * At this time, I am not sure if the next and previous sibling links
72  * are guaranteed to be document order 100% of the time.
73  * This is why I am requiring matches for the attribute and element names before
74  * copying values from the attributes or element nodes.
75  * Since I am not 100%, I believe it is better to be safe than sorry.
76  * There may be a slight performance hit but at least correctness is guaranteed.
77  */
78 #define solr_xml_match_node(solrXmlNode, solrXmlNodeName) ( \
79 		xmlStrEqual(solrXmlNode->name, (xmlChar *) solrXmlNodeName) && \
80 		solrXmlNode->children && solrXmlNode->children->content )
81 
82 /* Checks if children is a valid struct */
83 #define solr_xml_child_content_is_valid(solrXmlNode) (solrXmlNode && solrXmlNode->children)
84 
85 /* Checks to prevent segmentation fault. Ensures that children is a valid struct before attempting to get content */
86 #define solr_xml_get_node_contents(solrXmlNode) (solr_xml_child_content_is_valid(solrXmlNode)? (solrXmlNode->children->content) : ((xmlChar *) ""))
87 
88 #define solr_xml_get_node_contents_int(solrXmlNode) atoi((char *)solr_xml_get_node_contents(solrXmlNode))
89 
90 #define solr_xml_get_node_contents_double(solrXmlNode) xmlXPathCastStringToNumber(solr_xml_get_node_contents(solrXmlNode))
91 
92 /* hack for optional value modifier */
93 #define solr_document_insert_field_value(queue, field_value, field_boost, ...) solr_document_insert_field_value_ex( queue, field_value, field_boost, (0, ##__VA_ARGS__))
94 
95 /**
96  * Used to manage SolrQuery parameters that allow overrides by field name.
97  *
98  * Many parameters may be overridden on a per-field basis with the following syntax
99  *
100  *  f.<fieldName>.<FacetParam>=<value>
101  *  f.<fieldName>.<originalParam>=<value>
102  *
103  * @buf pointer to a solr_string_t object
104  * @fname field name
105  * @fname_len length of the field name
106  * @pname a string constant representing the name of the parameter.
107  */
108 #define solr_query_field_override(buf, fname, fname_len, pname) { \
109 	if ((fname_len)) { \
110 		solr_string_append_const((buf), "f.");	\
111 		solr_string_appends((buf), (fname), (fname_len)); \
112 		solr_string_appendc((buf), '.');	\
113 	}	\
114 	solr_string_append_const((buf), (pname)); \
115 }
116 
117 /* Macro for returning SolrParams objects if requested */
118 #define solr_return_solr_params_object() { \
119     solr_set_return_solr_params_object(return_value, getThis()); \
120 }
121 
122 /* client macros */
123 #define SOLR_RESPONSE_CODE_BODY (client->handle.response_header.response_code), (client->handle.response_body.buffer.str)
124 
125 #define SOLR_SHOW_CURL_WARNING { \
126     if (client->handle.err.str) \
127     { \
128         php_error_docref(NULL, E_WARNING, "%s", ((solr_char_t *) client->handle.err.str)); \
129     } \
130 }
131 
132 /* if there was an error with the http request solr_make_request throws an exception by itself
133  * if it wasn't a curl connection error, throw exception
134  */
135 #define HANDLE_SOLR_SERVER_ERROR(clientPtr,requestType){ \
136     if(clientPtr->handle.result_code == CURLE_OK){ \
137         solr_throw_solr_server_exception(clientPtr, (const char *)requestType);\
138     } \
139 }
140 /* solr_throw_exception_ex(solr_ce_SolrClientException, SOLR_ERROR_1010, SOLR_FILE_LINE_FUNC, SOLR_ERROR_1010_MSG, requestType, SOLR_RESPONSE_CODE_BODY); \ */
141 
142 #define SOLR_RETURN_THIS() { \
143     RETURN_ZVAL(getThis(), 1, 0); \
144 }
145 
146 /* Used to release the (solr_document_t **) pointers */
147 #define SOLR_FREE_DOC_ENTRIES(ptr) { \
148     if ((ptr) != NULL)\
149     { \
150         pefree(ptr, SOLR_DOCUMENT_PERSISTENT); \
151         ptr = NULL; \
152     } \
153 }
154 /* }}} */
155 
156 /* Used to release the (solr_document_t **) pointers */
157 #define SOLR_FREE_DOC_ENTRIES(ptr) { \
158     if ((ptr) != NULL)\
159     { \
160         pefree(ptr, SOLR_DOCUMENT_PERSISTENT); \
161         ptr = NULL; \
162     } \
163 }
164 /* }}} */
165 
solr_get_ustream_object(zend_object * obj)166 static inline solr_ustream_t *solr_get_ustream_object(zend_object *obj)
167 {
168     return (solr_ustream_t *) ((char *) obj - XtOffsetOf(solr_ustream_t, std));
169 }
170 
171 #define Z_USTREAM_P(zv) solr_get_ustream_object(Z_OBJ_P(zv));
172 
173 #endif /* SOLR_MACROS_H */
174 
175 /*
176  * Local variables:
177  * tab-width: 4
178  * c-basic-offset: 4
179  * End:
180  * vim600: fdm=marker
181  * vim: noet sw=4 ts=4
182  */
183