1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 #include <limits.h>
46 #include "pblock.h"
47 #include "plist_pvt.h"
48 #include "plist.h"
49 #include "LinkedList.hh"
50 #include "util.h"
51 #include "pool.h"
52 #include "systhr.h"
53
54 #define MALLOC_POOL_HANDLE (thread_malloc_key != -
1 ? (
pool_handle_t *)systhread_getdata(thread_malloc_key) : getThreadMallocPool())
55
56 static int thread_malloc_key = -
1;
57 static int _pblock_str2pblock(
const char* str, pblock* pb, PRBool lowerCase);
58
59 static pool_handle_t *getThreadMallocPool()
60 {
61 pool_handle_t *thread_malloc_pool =
0;
62
63 thread_malloc_key = getThreadMallocKey();
64 if (thread_malloc_key != -
1) {
65 thread_malloc_pool = (
pool_handle_t *)systhread_getdata(thread_malloc_key);
66 }
67
68 return thread_malloc_pool;
69 }
70
71
72
73 template <class Name, class Value>
74 class HashList {
75 public:
76 HashList(
int mask)
77 : _mask(mask),
78 _list(new CList<Value>[mask +
1])
79 { }
80
81 void Insert(Name name, Value *value)
82 {
83 _list[name & _mask].Append(value);
84 }
85
86 const CList<Value>& Find(Name name)
87 {
88 return _list[name & _mask];
89 }
90
91 private:
92 CList<Value> *_list;
93 unsigned int _mask;
94 };
95
96
97
98
99
100
101
102
103 typedef struct pb_key pb_key;
104 struct pb_key {
105 const char *name;
106 int namelen;
107 unsigned int hashval;
108 int sizendx;
109 int hashndx;
110 };
111
112 static HashList<
unsigned int, pb_key> _hashKeys(0x7f);
113 CList<pb_key> _listKeys;
114
115 static const pb_key *
const _create_key(
const char *name,
int sizendx =
0)
116 {
117
118 pb_key *key = (pb_key*)malloc(
sizeof(pb_key));
119 key->name =
STRDUP(name);
120 key->namelen = strlen(name);
121 key->hashval = PListHash(name);
122 key->sizendx = sizendx;
123 key->hashndx = key->hashval %
PLSIZENDX(sizendx);
124
125
126 _hashKeys.Insert(key->hashval, key);
127
128
129 _listKeys.Append(key);
130
131 return key;
132 }
133
134 const pb_key *
const pb_key_accept = _create_key(
"accept");
135 const pb_key *
const pb_key_accept_charset = _create_key(
"accept-charset");
136 const pb_key *
const pb_key_accept_encoding = _create_key(
"accept-encoding");
137 const pb_key *
const pb_key_accept_language = _create_key(
"accept-language");
138 const pb_key *
const pb_key_accept_ranges = _create_key(
"accept-ranges");
139 const pb_key *
const pb_key_actual_route = _create_key(
"actual-route");
140 const pb_key *
const pb_key_age = _create_key(
"age");
141 const pb_key *
const pb_key_always_allow_chunked = _create_key(
"always-allow-chunked");
142 const pb_key *
const pb_key_always_use_keep_alive = _create_key(
"always-use-keep-alive");
143 const pb_key *
const pb_key_auth_cert = _create_key(
"auth-cert");
144 const pb_key *
const pb_key_auth_expiring = _create_key(
"auth-expiring");
145 const pb_key *
const pb_key_auth_group = _create_key(
"auth-group");
146 const pb_key *
const pb_key_auth_type = _create_key(
"auth-type");
147 const pb_key *
const pb_key_auth_user = _create_key(
"auth-user");
148 const pb_key *
const pb_key_authorization = _create_key(
"authorization");
149 const pb_key *
const pb_key_browser = _create_key(
"browser");
150 const pb_key *
const pb_key_c2p_cl = _create_key(
"c2p-cl");
151 const pb_key *
const pb_key_c2p_hl = _create_key(
"c2p-hl");
152 const pb_key *
const pb_key_cache_info = _create_key(
"cache-info");
153 const pb_key *
const pb_key_charset = _create_key(
"charset");
154 const pb_key *
const pb_key_check_http_server = _create_key(
"check-http-server");
155 const pb_key *
const pb_key_ChunkedRequestBufferSize = _create_key(
"ChunkedRequestBufferSize");
156 const pb_key *
const pb_key_ChunkedRequestTimeout = _create_key(
"ChunkedRequestTimeout");
157 const pb_key *
const pb_key_cipher = _create_key(
"cipher");
158 const pb_key *
const pb_key_clf_request = _create_key(
"clf-request");
159 const pb_key *
const pb_key_cli_status = _create_key(
"cli-status");
160 const pb_key *
const pb_key_client_cert_nickname = _create_key(
"client-cert-nickname");
161 const pb_key *
const pb_key_client_ip = _create_key(
"client-ip");
162 const pb_key *
const pb_key_close = _create_key(
"close");
163 const pb_key *
const pb_key_connect_timeout = _create_key(
"connect-timeout");
164 const pb_key *
const pb_key_connection = _create_key(
"connection");
165 const pb_key *
const pb_key_cont = _create_key(
"cont");
166 const pb_key *
const pb_key_content_encoding = _create_key(
"content-encoding");
167 const pb_key *
const pb_key_content_language = _create_key(
"content-language");
168 const pb_key *
const pb_key_content_length = _create_key(
"content-length");
169 const pb_key *
const pb_key_content_location = _create_key(
"content-location");
170 const pb_key *
const pb_key_content_md5 = _create_key(
"content-md5");
171 const pb_key *
const pb_key_content_range = _create_key(
"content-range");
172 const pb_key *
const pb_key_content_type = _create_key(
"content-type");
173 const pb_key *
const pb_key_cookie = _create_key(
"cookie");
174 const pb_key *
const pb_key_date = _create_key(
"date");
175 const pb_key *
const pb_key_DATE_GMT = _create_key(
"DATE_GMT");
176 const pb_key *
const pb_key_DATE_LOCAL = _create_key(
"DATE_LOCAL");
177 const pb_key *
const pb_key_dir = _create_key(
"dir");
178 const pb_key *
const pb_key_Directive = _create_key(
"Directive");
179 const pb_key *
const pb_key_dns = _create_key(
"dns");
180 const pb_key *
const pb_key_DOCUMENT_NAME = _create_key(
"DOCUMENT_NAME");
181 const pb_key *
const pb_key_DOCUMENT_URI = _create_key(
"DOCUMENT_URI");
182 const pb_key *
const pb_key_domain = _create_key(
"domain");
183 const pb_key *
const pb_key_enc = _create_key(
"enc");
184 const pb_key *
const pb_key_engine = _create_key(
"engine");
185 const pb_key *
const pb_key_error_action = _create_key(
"error-action");
186 const pb_key *
const pb_key_error_desc = _create_key(
"error-desc");
187 const pb_key *
const pb_key_error_fn = _create_key(
"error-fn");
188 const pb_key *
const pb_key_escape = _create_key(
"escape");
189 const pb_key *
const pb_key_escaped = _create_key(
"escaped");
190 const pb_key *
const pb_key_etag = _create_key(
"etag");
191 const pb_key *
const pb_key_expect = _create_key(
"expect");
192 const pb_key *
const pb_key_expires = _create_key(
"expires");
193 const pb_key *
const pb_key_expr = _create_key(
"expr");
194 const pb_key *
const pb_key_filter = _create_key(
"filter");
195 const pb_key *
const pb_key_find_pathinfo_forward = _create_key(
"find-pathinfo-forward");
196 const pb_key *
const pb_key_flushTimer = _create_key(
"flushTimer");
197 const pb_key *
const pb_key_fn = _create_key(
"fn");
198 const pb_key *
const pb_key_from = _create_key(
"from");
199 const pb_key *
const pb_key_full_headers = _create_key(
"full-headers");
200 const pb_key *
const pb_key_hdr = _create_key(
"hdr");
201 const pb_key *
const pb_key_host = _create_key(
"host");
202 const pb_key *
const pb_key_hostname = _create_key(
"hostname");
203 const pb_key *
const pb_key_if_match = _create_key(
"if-match");
204 const pb_key *
const pb_key_if_modified_since = _create_key(
"if-modified-since");
205 const pb_key *
const pb_key_if_none_match = _create_key(
"if-none-match");
206 const pb_key *
const pb_key_if_range = _create_key(
"if-range");
207 const pb_key *
const pb_key_if_unmodified_since = _create_key(
"if-unmodified-since");
208 const pb_key *
const pb_key_ip = _create_key(
"ip");
209 const pb_key *
const pb_key_iponly = _create_key(
"iponly");
210 const pb_key *
const pb_key_issuer_dn = _create_key(
"issuer_dn");
211 const pb_key *
const pb_key_jroute = _create_key(
"jroute");
212 const pb_key *
const pb_key_keep_alive = _create_key(
"keep-alive");
213 const pb_key *
const pb_key_keep_alive_timeout = _create_key(
"keep-alive-timeout");
214 const pb_key *
const pb_key_keysize = _create_key(
"keysize");
215 const pb_key *
const pb_key_lang = _create_key(
"lang");
216 const pb_key *
const pb_key_LAST_MODIFIED = _create_key(
"LAST_MODIFIED");
217 const pb_key *
const pb_key_last_modified = _create_key(
"last-modified");
218 const pb_key *
const pb_key_level = _create_key(
"level");
219 const pb_key *
const pb_key_location = _create_key(
"location");
220 const pb_key *
const pb_key_lock_owner = _create_key(
"lock-owner");
221 const pb_key *
const pb_key_magnus_charset = _create_key(
"magnus-charset");
222 const pb_key *
const pb_key_magnus_internal = _create_key(
"magnus-internal");
223 const pb_key *
const pb_key_magnus_internal_dav_src = _create_key(
"magnus-internal/dav-src");
224 const pb_key *
const pb_key_magnus_internal_default_acls_only = _create_key(
"magnus-internal/default-acls-only");
225 const pb_key *
const pb_key_magnus_internal_error_j2ee = _create_key(
"magnus-internal/error-j2ee");
226 const pb_key *
const pb_key_magnus_internal_j2ee_nsapi = _create_key(
"magnus-internal/j2ee-nsapi");
227 const pb_key *
const pb_key_magnus_internal_preserve_srvhdrs = _create_key(
"magnus-internal/preserve-srvhdrs-after-req-restart");
228 const pb_key *
const pb_key_magnus_internal_set_request_status = _create_key(
"magnus-internal/set-request-status");
229 const pb_key *
const pb_key_magnus_internal_set_response_status = _create_key(
"magnus-internal/set-response-status");
230 const pb_key *
const pb_key_magnus_internal_webapp_errordesc = _create_key(
"magnus-internal/webapp-errordesc");
231 const pb_key *
const pb_key_matched_browser = _create_key(
"matched-browser");
232 const pb_key *
const pb_key_max_age = _create_key(
"max-age");
233 const pb_key *
const pb_key_max_forwards = _create_key(
"max-forwards");
234 const pb_key *
const pb_key_message = _create_key(
"message");
235 const pb_key *
const pb_key_method = _create_key(
"method");
236 const pb_key *
const pb_key_name = _create_key(
"name");
237 const pb_key *
const pb_key_nocache = _create_key(
"nocache");
238 const pb_key *
const pb_key_nostat = _create_key(
"nostat");
239 const pb_key *
const pb_key_ntrans_base = _create_key(
"ntrans-base");
240 const pb_key *
const pb_key_offline_origin_addr = _create_key(
"offline-origin-addr");
241 const pb_key *
const pb_key_offline_proxy_addr = _create_key(
"offline-proxy-addr");
242 const pb_key *
const pb_key_origin_addr = _create_key(
"origin-addr");
243 const pb_key *
const pb_key_p2c_cl = _create_key(
"p2c-cl");
244 const pb_key *
const pb_key_p2c_hl = _create_key(
"p2c-hl");
245 const pb_key *
const pb_key_p2r_cl = _create_key(
"p2r-cl");
246 const pb_key *
const pb_key_p2r_hl = _create_key(
"p2r-hl");
247 const pb_key *
const pb_key_parse_timeout = _create_key(
"parse-timeout");
248 const pb_key *
const pb_key_password = _create_key(
"password");
249 const pb_key *
const pb_key_path = _create_key(
"path");
250 const pb_key *
const pb_key_PATH_INFO = _create_key(
"PATH_INFO");
251 const pb_key *
const pb_key_path_info = _create_key(
"path-info");
252 const pb_key *
const pb_key_pblock = _create_key(
"pblock");
253 const pb_key *
const pb_key_poll_interval = _create_key(
"poll-interval");
254 const pb_key *
const pb_key_pool = _create_key(
"pool");
255 const pb_key *
const pb_key_port = _create_key(
"port");
256 const pb_key *
const pb_key_ppath = _create_key(
"ppath");
257 const pb_key *
const pb_key_pragma = _create_key(
"pragma");
258 const pb_key *
const pb_key_process_request_body = _create_key(
"process-request-body");
259 const pb_key *
const pb_key_process_response_body = _create_key(
"process-response-body");
260 const pb_key *
const pb_key_protocol = _create_key(
"protocol");
261 const pb_key *
const pb_key_proxy_addr = _create_key(
"proxy-addr");
262 const pb_key *
const pb_key_proxy_agent = _create_key(
"proxy-agent");
263 const pb_key *
const pb_key_proxy_auth_cert = _create_key(
"proxy-auth-cert");
264 const pb_key *
const pb_key_proxy_authorization = _create_key(
"proxy-authorization");
265 const pb_key *
const pb_key_proxy_cipher = _create_key(
"proxy-cipher");
266 const pb_key *
const pb_key_proxy_issuer_dn = _create_key(
"proxy-issuer-dn");
267 const pb_key *
const pb_key_proxy_jroute = _create_key(
"proxy-jroute");
268 const pb_key *
const pb_key_proxy_keysize = _create_key(
"proxy-keysize");
269 const pb_key *
const pb_key_proxy_ping = _create_key(
"proxy-ping");
270 const pb_key *
const pb_key_proxy_request = _create_key(
"proxy-request");
271 const pb_key *
const pb_key_proxy_secret_keysize = _create_key(
"proxy-secret-keysize");
272 const pb_key *
const pb_key_proxy_ssl_id = _create_key(
"proxy-ssl-id");
273 const pb_key *
const pb_key_proxy_user_dn = _create_key(
"proxy-user-dn");
274 const pb_key *
const pb_key_query = _create_key(
"query");
275 const pb_key *
const pb_key_QUERY_STRING = _create_key(
"QUERY_STRING");
276 const pb_key *
const pb_key_QUERY_STRING_UNESCAPED = _create_key(
"QUERY_STRING_UNESCAPED");
277 const pb_key *
const pb_key_r2p_cl = _create_key(
"r2p-cl");
278 const pb_key *
const pb_key_r2p_hl = _create_key(
"r2p-hl");
279 const pb_key *
const pb_key_range = _create_key(
"range");
280 const pb_key *
const pb_key_referer = _create_key(
"referer");
281 const pb_key *
const pb_key_reformat_request_headers = _create_key(
"reformat-request-headers");
282 const pb_key *
const pb_key_remote_status = _create_key(
"remote-status");
283 const pb_key *
const pb_key_request_jroute = _create_key(
"request-jroute");
284 const pb_key *
const pb_key_required_rights = _create_key(
"required-rights");
285 const pb_key *
const pb_key_retries = _create_key(
"retries");
286 const pb_key *
const pb_key_rewrite_content_location = _create_key(
"rewrite-content-location");
287 const pb_key *
const pb_key_rewrite_host = _create_key(
"rewrite-host");
288 const pb_key *
const pb_key_rewrite_location = _create_key(
"rewrite-location");
289 const pb_key *
const pb_key_rewrite_set_cookie = _create_key(
"rewrite-set-cookie");
290 const pb_key *
const pb_key_root = _create_key(
"root");
291 const pb_key *
const pb_key_route = _create_key(
"route");
292 const pb_key *
const pb_key_route_cookie = _create_key(
"route-cookie");
293 const pb_key *
const pb_key_route_hdr = _create_key(
"route-hdr");
294 const pb_key *
const pb_key_route_offline = _create_key(
"route-offline");
295 const pb_key *
const pb_key_script_name = _create_key(
"script-name");
296 const pb_key *
const pb_key_secret_keysize = _create_key(
"secret-keysize");
297 const pb_key *
const pb_key_secure = _create_key(
"secure");
298 const pb_key *
const pb_key_server = _create_key(
"server");
299 const pb_key *
const pb_key_set_cookie = _create_key(
"set-cookie");
300 const pb_key *
const pb_key_socks_addr = _create_key(
"socks_addr");
301 const pb_key *
const pb_key_ssl_id = _create_key(
"ssl-id");
302 const pb_key *
const pb_key_ssl_unclean_shutdown = _create_key(
"ssl-unclean-shutdown");
303 const pb_key *
const pb_key_status = _create_key(
"status");
304 const pb_key *
const pb_key_sticky_cookie = _create_key(
"sticky-cookie");
305 const pb_key *
const pb_key_sticky_param = _create_key(
"sticky-param");
306 const pb_key *
const pb_key_suppress_request_headers = _create_key(
"suppress-request-headers");
307 const pb_key *
const pb_key_svr_status = _create_key(
"svr-status");
308 const pb_key *
const pb_key_timeout = _create_key(
"timeout");
309 const pb_key *
const pb_key_to = _create_key(
"to");
310 const pb_key *
const pb_key_transfer_encoding = _create_key(
"transfer-encoding");
311 const pb_key *
const pb_key_transmit_timeout = _create_key(
"transmit-timeout");
312 const pb_key *
const pb_key_tunnel_non_http_response = _create_key(
"tunnel-non-http-response");
313 const pb_key *
const pb_key_type = _create_key(
"type");
314 const pb_key *
const pb_key_upstream_jroute = _create_key(
"upstream-jroute");
315 const pb_key *
const pb_key_uri = _create_key(
"uri");
316 const pb_key *
const pb_key_url = _create_key(
"url");
317 const pb_key *
const pb_key_url_prefix = _create_key(
"url-prefix");
318 const pb_key *
const pb_key_UseOutputStreamSize = _create_key(
"UseOutputStreamSize");
319 const pb_key *
const pb_key_user = _create_key(
"user");
320 const pb_key *
const pb_key_user_agent = _create_key(
"user-agent");
321 const pb_key *
const pb_key_user_dn = _create_key(
"user_dn");
322 const pb_key *
const pb_key_validate_server_cert = _create_key(
"validate-server-cert");
323 const pb_key *
const pb_key_value = _create_key(
"value");
324 const pb_key *
const pb_key_vary = _create_key(
"vary");
325 const pb_key *
const pb_key_via = _create_key(
"via");
326 const pb_key *
const pb_key_warning = _create_key(
"warning");
327
328
329
330
331 static inline
const pb_key *_find_key(
const char *name,
unsigned int hashval)
332 {
333
334 CListConstIterator<pb_key> iter(&_hashKeys.Find(hashval));
335 const pb_key *key;
336 while((key = ++iter)) {
337 if (key->hashval == hashval && !strcmp(key->name, name))
338 return key;
339 }
340 return NULL;
341 }
342
343
344
345
346 static inline
int _get_hash_index(
const PListStruct_t *pl,
const pb_key *key)
347 {
348
349 int i;
350 if (key->sizendx == pl->pl_symtab->pt_sizendx)
351 i = key->hashndx;
352 else
353 i = key->hashval %
PLSIZENDX(pl->pl_symtab->pt_sizendx);
354 return i;
355 }
356
357
358
359
360 static inline pb_param *_param_create(
pool_handle_t *pool_handle,
const char *name,
int namelen,
const char *value,
int valuelen)
361 {
362 PLValueStruct_t *ret;
363
364 ret = (
PLValueStruct_t *)pool_malloc(pool_handle,
sizeof(
PLValueStruct_t));
365
366 ret->pv_pbentry.param = &ret->pv_pbparam;
367 ret->pv_pbentry.next =
0;
368 ret->pv_next =
0;
369 ret->pv_type =
0;
370 ret->pv_mempool = pool_handle;
371
372 if (name || namelen) {
373 ret->pv_name = (
char*)pool_malloc(pool_handle, namelen +
1);
374 if (name) {
375 memcpy(ret->pv_name, name, namelen);
376 ret->pv_name[namelen] =
'\0';
377 }
else {
378 ret->pv_name[
0] =
'\0';
379 }
380 }
else {
381 ret->pv_name =
0;
382 }
383
384 if (value || valuelen) {
385 ret->pv_value = (
char*)pool_malloc(pool_handle, valuelen +
1);
386 if (value) {
387 memcpy(ret->pv_value, value, valuelen);
388 ret->pv_value[valuelen] =
'\0';
389 }
else {
390 ret->pv_value[
0] =
'\0';
391 }
392 }
else {
393 ret->pv_value =
0;
394 }
395
396 return &ret->pv_pbparam;
397 }
398
399
400
401
402 NSAPI_PUBLIC pb_param *pblock_key_param_create(pblock *pb,
const pb_key *key,
const char *value,
int valuelen)
403 {
404
405
406
407 PListStruct_t *pl =
PBTOPL(pb);
408 return _param_create(pl->pl_mempool, key->name, key->namelen, value, valuelen);
409 }
410
411
412
413
414 NSAPI_PUBLIC pb_param *pblock_param_create(pblock *pb,
const char *name,
const char *value)
415 {
416
417
418
419 PListStruct_t *pl =
PBTOPL(pb);
420 return _param_create(pl->pl_mempool, name, name ? strlen(name) :
0, value, value ? strlen(value) :
0);
421 }
422
423
424
425
426 NSAPI_PUBLIC pb_param *param_create(
const char *name,
const char *value)
427 {
428
429
430
431
432
433
434
435 return _param_create(system_pool(), name, name ? strlen(name) :
0, value, value ? strlen(value) :
0);
436 }
437
438
439
440
441 NSAPI_PUBLIC int param_free(pb_param *pp)
442 {
443 if (pp) {
444 PLValueStruct_t *pv =
PATOPV(pp);
445
446
447 if (!pv->pv_mempool) {
448 pool_free(pv->pv_mempool, pv->pv_name);
449 pool_free(pv->pv_mempool, pv->pv_value);
450 pool_free(pv->pv_mempool, pv);
451 }
452
453 return 1;
454 }
455
456 return 0;
457 }
458
459
460
461
462 NSAPI_PUBLIC pblock *pblock_create_pool(
pool_handle_t *pool_handle,
int n)
463 {
464
465 PListStruct_t *plist = (
PListStruct_t *)PListCreate(pool_handle, n,
0,
0);
466 if (!plist)
467 return NULL;
468
469 plist->pl_resvpi =
0;
470
471 return &plist->pl_pb;
472 }
473
474
475
476
477 NSAPI_PUBLIC pool_handle_t *pblock_pool(pblock *pb)
478 {
479 PListStruct_t *pl =
PBTOPL(pb);
480 return pl->pl_mempool;
481 }
482
483
484
485
486 NSAPI_PUBLIC pblock *pblock_create(
int n)
487 {
488 return pblock_create_pool(
MALLOC_POOL_HANDLE, n);
489 }
490
491
492
493
494 NSAPI_PUBLIC void pblock_free(pblock *pb)
495 {
496 PListStruct_t *pl =
PBTOPL(pb);
497 PLValueStruct_t **ppval;
498 PLValueStruct_t *pv;
499 int i;
500
501 if (!pb) {
502 return;
503 }
504
505
506
507
508 if (pl->pl_mempool || pool_enabled()) {
509 return;
510 }
511
512
513 if (pl->pl_symtab) {
514 pool_free(pl->pl_mempool, (
void *)(pl->pl_symtab));
515 }
516
517 ppval = (
PLValueStruct_t **)(pl->pl_ppval);
518
519
520 for (i =
0; i < pl->pl_initpi; ++i) {
521
522
523 pv = ppval[i];
524 if (pv) {
525
526 param_free(&pv->pv_pbparam);
527 }
528 }
529
530
531 pool_free(pl->pl_mempool, (
void *)ppval);
532
533
534 pool_free(pl->pl_mempool, (
void *)pl);
535 }
536
537
538
539
540 NSAPI_PUBLIC const pb_key *pblock_key(
const char *name)
541 {
542 if (!name)
543 return NULL;
544
545 return _find_key(name, PListHash(name));
546 }
547
548
549
550
551 NSAPI_PUBLIC void pblock_kpinsert(
const pb_key *key, pb_param *pp, pblock *pb)
552 {
553 PListStruct_t *pl =
PBTOPL(pb);
554 PLValueStruct_t *pv =
PATOPV(pp);
555
556
557
558
559 unsigned int hashval;
560 if (!key) {
561 hashval = PListHash(pv->pv_name);
562 key = _find_key(pv->pv_name, hashval);
563 }
564
565
566 int pindex = PListGetFreeIndex(pl);
567 if (pindex <
1) {
568
569 printf(
"Error - invalid property index\n");
570 return;
571 }
572
573
574 PLSymbolTable_t *pt = PListSymbolTable(pl);
575 if (!pt) {
576 printf(
"!pt\n");
577 return;
578 }
579
580
581 PLValueStruct_t **ppval = (
PLValueStruct_t **)(pl->pl_ppval);
582 pv->pv_pbkey = key;
583 pv->pv_pi = pindex;
584 ppval[pv->pv_pi -
1] = pv;
585
586
587 int i = key ? _get_hash_index(pl, key) : (hashval %
PLSIZENDX(pt->pt_sizendx));
588 pv->pv_next = pt->pt_hash[i];
589 pt->pt_hash[i] = pv;
590 pt->pt_nsyms++;
591
592
593 }
594
595
596
597
598 NSAPI_PUBLIC void pblock_pinsert(pb_param *pp, pblock *pb)
599 {
600 pblock_kpinsert(
NULL, pp, pb);
601 }
602
603
604
605
606 NSAPI_PUBLIC pb_param *pblock_nvinsert(
const char *name,
const char *value, pblock *pb)
607 {
608 pb_param *pp = pblock_param_create(pb, name, value);
609 if (pp)
610 pblock_kpinsert(
NULL, pp, pb);
611 return pp;
612 }
613
614
615
616
617 NSAPI_PUBLIC pb_param *pblock_kvinsert(
const pb_key *key,
const char *value,
int valuelen, pblock *pb)
618 {
619 pb_param *pp = pblock_key_param_create(pb, key, value, valuelen);
620 if (pp)
621 pblock_kpinsert(key, pp, pb);
622 return pp;
623 }
624
625
626
627
628 NSAPI_PUBLIC pb_param *pblock_nninsert(
const char *name,
int value, pblock *pb)
629 {
630 char num[
UTIL_ITOA_SIZE];
631
632 util_itoa(value, num);
633 return pblock_nvinsert(name, num, pb);
634 }
635
636
637
638
639 NSAPI_PUBLIC pb_param *pblock_kninsert(
const pb_key *key,
int value, pblock *pb)
640 {
641 pb_param *pp = pblock_key_param_create(pb, key,
NULL,
UTIL_ITOA_SIZE);
642 if (pp) {
643 util_itoa(value, pp->value);
644 pblock_kpinsert(key, pp, pb);
645 }
646 return pp;
647 }
648
649
650
651
652 NSAPI_PUBLIC pb_param *pblock_kllinsert(
const pb_key *key,
int64_t value, pblock *pb)
653 {
654 pb_param *pp = pblock_key_param_create(pb, key,
NULL,
UTIL_I64TOA_SIZE);
655 if (pp) {
656 util_i64toa(value, pp->value);
657 pblock_kpinsert(key, pp, pb);
658 }
659 return pp;
660 }
661
662
663
664
665 NSAPI_PUBLIC pb_param *pblock_nvlinsert(
const char *name,
int namelen,
const char *value,
int valuelen, pblock *pb)
666 {
667 PListStruct_t *pl =
PBTOPL(pb);
668
669 pb_param *pp = _param_create(pl->pl_mempool, name, namelen, value, valuelen);
670
671 if(pp) {
672 pblock_kpinsert(
NULL, pp, pb);
673 }
674
675 return pp;
676 }
677
678
679
680
681 NSAPI_PUBLIC pb_param *pblock_findkey(
const pb_key *key,
const pblock *pb)
682 {
683 PListStruct_t *pl =
PBTOPL(pb);
684
685
686 if (pl->pl_symtab) {
687 int i = _get_hash_index(pl, key);
688 PLValueStruct_t *pv;
689
690
691 for (pv = pl->pl_symtab->pt_hash[i]; pv; pv = pv->pv_next) {
692 if (pv->pv_pbkey == key)
693 return &pv->pv_pbparam;
694 }
695 }
696
697 return NULL;
698 }
699
700
701
702
703 NSAPI_PUBLIC char *pblock_findkeyval(
const pb_key *key,
const pblock *pb)
704 {
705 pb_param *pp = pblock_findkey(key, pb);
706 return pp ? pp->value :
NULL;
707 }
708
709
710
711
712 NSAPI_PUBLIC char *pblock_findval(
const char *name,
const pblock *pb)
713 {
714 void *pvalue =
0;
715
716 (
void)PListFindValue((
PList_t)(
PBTOPL(pb)), name, &pvalue,
0);
717
718 return (
char *)pvalue;
719 }
720
721
722
723
724 NSAPI_PUBLIC pb_param *pblock_fr(
const char *name, pblock *pb,
int remove)
725 {
726 PListStruct_t *pl =
PBTOPL(pb);
727 PLValueStruct_t **ppval;
728 PLValueStruct_t **pvp;
729 PLValueStruct_t *pv =
NULL;
730 int pindex;
731 int i;
732
733 if (pl->pl_symtab) {
734
735
736 i = PListHashName(pl->pl_symtab, name);
737
738
739 for (pvp = &pl->pl_symtab->pt_hash[i];
740 (pv = *pvp); pvp = &(*pvp)->pv_next) {
741
742 if (!strcmp(name, pv->pv_name)) {
743
744 if (remove) {
745
746 *pvp = pv->pv_next;
747 pl->pl_symtab->pt_nsyms--;
748
749
750 ppval = (
PLValueStruct_t **)(pl->pl_ppval);
751 pindex = pv->pv_pi;
752 ppval[pindex -
1] =
0;
753 }
754 break;
755 }
756 }
757 }
758
759 return (pv) ? &pv->pv_pbparam :
NULL;
760 }
761
762
763
764
765 NSAPI_PUBLIC pb_param *pblock_removekey(
const pb_key *key, pblock *pb)
766 {
767 PListStruct_t *pl =
PBTOPL(pb);
768 PLValueStruct_t **ppval;
769 PLValueStruct_t **pvp;
770 PLValueStruct_t *pv =
NULL;
771 int pindex;
772 int i;
773
774 if (pl->pl_symtab) {
775
776 i = _get_hash_index(pl, key);
777
778
779 for (pvp = &pl->pl_symtab->pt_hash[i]; (pv = *pvp); pvp = &pv->pv_next) {
780
781 if (pv->pv_pbkey == key) {
782
783 *pvp = pv->pv_next;
784 pl->pl_symtab->pt_nsyms--;
785
786
787 ppval = (
PLValueStruct_t **)(pl->pl_ppval);
788 pindex = pv->pv_pi;
789 ppval[pindex -
1] =
0;
790
791 break;
792 }
793 }
794 }
795
796 return (pv) ? &pv->pv_pbparam :
NULL;
797 }
798
799
800
801
802 NSAPI_PUBLIC pb_param *pblock_removeone(pblock *pb)
803 {
804 PListStruct_t *pl =
PBTOPL(pb);
805
806 if (pl && pl->pl_symtab) {
807
808 for (
int i =
0; i <
PLSIZENDX(pl->pl_symtab->pt_sizendx); i++) {
809
810 PLValueStruct_t *pv = pl->pl_symtab->pt_hash[i];
811 if (pv) {
812
813 pl->pl_symtab->pt_hash[i] = pv->pv_next;
814 pl->pl_symtab->pt_nsyms--;
815
816
817 PLValueStruct_t **ppval = (
PLValueStruct_t**)pl->pl_ppval;
818 ppval[pv->pv_pi -
1] =
0;
819
820 return &pv->pv_pbparam;
821 }
822 }
823 }
824
825 return NULL;
826 }
827
828
829
830
831
832 int _verify_pbstr(
const char *str)
833 {
834 const char *cp;
835 const char *scp;
836 int np;
837 int state;
838 int quote;
839
840 for(cp = str, np =
0, state =
0; *cp; ) {
841 switch (state) {
842 case 0:
843
844 while (*cp && isspace(*cp)) ++cp;
845 if (*cp ==
'=') {
846 return -
1;
847 }
848 if (*cp) state =
1;
849 break;
850
851 case 1:
852
853 scp = cp;
854 while (*cp && (*cp !=
'=') && !isspace(*cp)) ++cp;
855 if (*cp ==
'=') ++cp;
856 else cp = scp;
857 state =
2;
858 break;
859
860 case 2:
861 quote =
0;
862 if (*cp ==
'\"') {
863 quote =
1;
864 ++cp;
865 }
866 for (;;) {
867 if (*cp ==
'\\') {
868 ++cp;
869 if (*cp ==
0) {
870 return -
1;
871 }
872 }
873 else if (*cp ==
'\"') {
874 if (!quote) {
875 return -
1;
876 }
877 ++np;
878 ++cp;
879 quote =
0;
880 state =
0;
881 break;
882 }
883 else if (!quote && (!*cp || isspace(*cp))) {
884 ++np;
885 if (*cp) ++cp;
886 state =
0;
887 break;
888 }
889 else if (*cp ==
0) {
890 return -
1;
891 }
892 ++cp;
893 }
894 if (quote) {
895 return -
1;
896 }
897 break;
898 }
899 }
900
901 return (state ==
0) ? np : -
1;
902 }
903
904 NSAPI_PUBLIC int
905 INTpblock_str2pblock_lowercasename(
const char *str, pblock *pb)
906 {
907 return _pblock_str2pblock(str, pb,
PR_TRUE);
908 }
909
910 NSAPI_PUBLIC int pblock_str2pblock(
const char *str, pblock *pb)
911 {
912 return _pblock_str2pblock(str, pb,
PR_FALSE);
913 }
914
915 int
916 _pblock_str2pblock(
const char* str, pblock* pb, PRBool lowerCase)
917 {
918 char *cpy;
919 char *cp;
920 char *dp;
921 char *pname;
922 char *pvalue;
923 int np;
924 int quote;
925 int state;
926 char numbuf[
UTIL_ITOA_SIZE];
927
928 if((np = _verify_pbstr(str)) <
1)
929 return -
1;
930
931 while (*str && isspace(*str)) ++str;
932
933 cpy =
STRDUP(str);
934
935 for (np =
0, cp = cpy, state =
0; *cp; ) {
936 switch (state) {
937
938 case 0:
939
940 while (*cp && isspace(*cp)) ++cp;
941 if (*cp) state =
1;
942 break;
943
944 case 1:
945
946 pname = cp;
947 while (*cp && (*cp !=
'=') && !isspace(*cp)) ++cp;
948 if (*cp ==
'=') {
949 *cp++ =
0;
950 }
951 else {
952 cp = pname;
953 pname = numbuf;
954 util_itoa(np+
1, numbuf);
955 }
956 state =
2;
957 break;
958
959 case 2:
960 quote =
0;
961 if (*cp ==
'\"') {
962 quote =
1;
963 ++cp;
964 }
965 for (pvalue = cp, dp = cp; ; ++cp, ++dp) {
966 if (*cp ==
'\\') {
967 ++cp;
968 }
969 else if (*cp ==
'\"') {
970 ++np;
971 ++cp;
972 *dp =
0;
973 quote =
0;
974 state =
0;
975 break;
976 }
977 else if (!quote && ((*cp ==
0) || isspace(*cp))) {
978 ++np;
979 if (*cp !=
0) {
980 ++cp;
981 }
982 *dp =
0;
983 state =
0;
984 break;
985 }
986 if (cp != dp) *dp = *cp;
987 }
988 if (lowerCase ==
PR_TRUE) {
989 for (
char* p = pname; *p; p++) {
990 *p = tolower(*p);
991 }
992 }
993 pblock_nvinsert(pname, pvalue, pb);
994 break;
995 }
996 }
997
998 FREE(cpy);
999
1000 return np;
1001 }
1002
1003
1004
1005
1006
1007 NSAPI_PUBLIC char *pblock_pblock2str(
const pblock *pb,
char *str)
1008 {
1009 register char *s = str, *t, *u;
1010 PListStruct_t *pl =
PBTOPL(pb);
1011 PLValueStruct_t **ppval;
1012 PLValueStruct_t *pv;
1013 int i;
1014 int sl;
1015 int xlen;
1016
1017 ppval = (
PLValueStruct_t **)(pl->pl_ppval);
1018
1019
1020 for (i =
0, xlen =
0; i < pl->pl_initpi; ++i) {
1021
1022
1023 pv = ppval[i];
1024 if (pv && pv->pv_name) {
1025
1026 int ln = strlen(pv->pv_name);
1027 int lv = strlen((
char *)(pv->pv_value));
1028
1029
1030 for (t = (
char *)(pv->pv_value); *t; ++t) {
1031 if ((*t ==
'\"') || (*t ==
'\\')) ++lv;
1032 }
1033
1034
1035 xlen += (ln + lv +
4);
1036 }
1037 }
1038
1039
1040 if (!s) {
1041 s = (
char *)
MALLOC(xlen);
1042 s[
0] =
'\0';
1043 t = &s[
0];
1044 sl = xlen;
1045 }
1046 else {
1047 sl = strlen(s);
1048 t = &s[sl];
1049 sl += xlen;
1050 s = (
char *)
REALLOC(s, sl);
1051 }
1052
1053
1054 for (i =
0; i < pl->pl_initpi; ++i) {
1055
1056
1057 pv = ppval[i];
1058 if (pv && pv->pv_name) {
1059
1060 if (t != s) *t++ =
' ';
1061
1062 for (u = pv->pv_name; *u; ) *t++ = *u++;
1063
1064 *t++ =
'=';
1065 *t++ =
'\"';
1066
1067 for (u = (
char *)(pv->pv_value); *u; ) {
1068 if ((*u ==
'\\') || (*u ==
'\"')) *t++ =
'\\';
1069 *t++ = *u++;
1070 }
1071
1072 *t++ =
'\"';
1073 *t =
'\0';
1074 }
1075 }
1076
1077 return s;
1078 }
1079
1080
1081
1082
1083
1084 NSAPI_PUBLIC int pblock_copy(
const pblock *src, pblock *dst)
1085 {
1086 PListStruct_t *pl =
PBTOPL(src);
1087 PLValueStruct_t **ppval;
1088 PLValueStruct_t *pv;
1089 int rv =
0;
1090 int i;
1091
1092 ppval = (
PLValueStruct_t **)(pl->pl_ppval);
1093
1094 for (i =
0; i < pl->pl_initpi; ++i) {
1095 pv = ppval[i];
1096 if (pv) {
1097 if (pv->pv_pbkey) {
1098 if (pv->pv_pbkey != pb_key_magnus_internal) {
1099 if (!pblock_kvinsert(pv->pv_pbkey, (
char *)(pv->pv_value), strlen(pv->pv_value), dst))
1100 rv = -
1;
1101 }
1102 }
else {
1103 if (!pblock_nvinsert(pv->pv_name, (
char *)(pv->pv_value), dst))
1104 rv = -
1;
1105 }
1106 }
1107 }
1108
1109 return rv;
1110 }
1111
1112
1113
1114 NSAPI_PUBLIC pblock *pblock_dup(
const pblock *src)
1115 {
1116 pblock *dst;
1117
1118 if (!src)
1119 return NULL;
1120
1121 if ( (dst = pblock_create(src->hsize)) )
1122 pblock_copy(src, dst);
1123
1124 return dst;
1125 }
1126
1127
1128
1129
1130
1131 NSAPI_PUBLIC char **pblock_pb2env(
const pblock *pb,
char **env)
1132 {
1133 PListStruct_t *pl =
PBTOPL(pb);
1134 PLValueStruct_t **ppval;
1135 PLValueStruct_t *pv;
1136 int i;
1137 int nval;
1138 int pos;
1139
1140
1141
1142 ppval = (
PLValueStruct_t **)(pl->pl_ppval);
1143
1144 for (i =
0, nval =
0; i < pl->pl_initpi; ++i) {
1145 if (ppval[i]) ++nval;
1146 }
1147
1148 env = util_env_create(env, nval, &pos);
1149
1150 for (i =
0; i < pl->pl_initpi; ++i) {
1151 pv = ppval[i];
1152 if (pv) {
1153 env[pos++] = util_env_str(pv->pv_name, (
char *)(pv->pv_value));
1154 }
1155 }
1156 env[pos] =
NULL;
1157
1158 return env;
1159 }
1160
1161
1162
1163
1164 NSAPI_PUBLIC char * pblock_replace(
const char *name,
1165 char * new_value, pblock *pb)
1166 {
1167 PListStruct_t *pl =
PBTOPL(pb);
1168
1169
1170 pb_param *pp = pblock_find(name, pb);
1171 if (!pp)
1172 return NULL;
1173 pool_free(pl->pl_mempool, pp->value);
1174 pp->value = new_value;
1175
1176 return new_value;
1177 }
1178
1179
1180
1181
1182 NSAPI_PUBLIC void pblock_nvreplace (
const char *name,
const char *value, pblock *pb)
1183 {
1184 PListStruct_t *pl =
PBTOPL(pb);
1185
1186
1187 pb_param *pp = pblock_find(name, pb);
1188 if (pp) {
1189 pool_free(pl->pl_mempool, pp->value);
1190 pp->value = pool_strdup(pl->pl_mempool, value);
1191 }
else {
1192 pblock_nvinsert(name, value, pb);
1193 }
1194 }
1195
1196
1197
1198
1199 NSAPI_PUBLIC void pblock_kvreplace(
const pb_key *key,
const char *value,
int valuelen, pblock *pb)
1200 {
1201 PListStruct_t *pl =
PBTOPL(pb);
1202
1203
1204 pb_param *pp = pblock_findkey(key, pb);
1205 if (pp) {
1206 pool_free(pl->pl_mempool, pp->value);
1207 pp->value = (
char*)pool_malloc(pl->pl_mempool, valuelen +
1);
1208 memcpy(pp->value, value, valuelen +
1);
1209 }
else {
1210 pblock_kvinsert(key, value, valuelen, pb);
1211 }
1212 }
1213