205 *error = DAVQL_UNKNOWN_FORMATCHAR; |
217 *error = DAVQL_UNKNOWN_FORMATCHAR; |
206 err = 1; |
218 err = 1; |
207 } |
219 } |
208 } |
220 } |
209 if(err) { |
221 if(err) { |
210 ucx_buffer_free(buf); |
222 cxBufferDestroy(&buf); |
211 sstr_t n; |
223 return (cxmutstr){NULL,0}; |
212 n.ptr = NULL; |
|
213 n.length = 0; |
|
214 return n; |
|
215 } |
224 } |
216 } |
225 } |
217 placeholder = 0; |
226 placeholder = 0; |
218 } else { |
227 } else { |
219 if(c == '%') { |
228 if(c == '%') { |
220 placeholder = 1; |
229 placeholder = 1; |
221 } else { |
230 } else { |
222 ucx_buffer_putc(buf, c); |
231 cxBufferPut(&buf, c); |
223 } |
232 } |
224 } |
233 } |
|
234 } |
|
235 if(cxBufferPut(&buf, '\0')) { |
|
236 *error = DAVQL_OOM; |
|
237 cxBufferDestroy(&buf); |
|
238 return (cxmutstr){NULL, 0}; |
225 } |
239 } |
226 *error = DAVQL_OK; |
240 *error = DAVQL_OK; |
227 |
241 |
228 sstr_t ret = sstrdup_a(a, sstrn(buf->space, buf->size)); |
242 return cx_mutstrn(buf.space, buf.size-1); |
229 ucx_buffer_free(buf); |
243 } |
230 return ret; |
244 |
231 } |
245 static int fl_add_properties(DavSession *sn, const CxAllocator *a, CxMap *map, DavQLExpression *expression) { |
232 |
|
233 static int fl_add_properties(DavSession *sn, UcxMempool *mp, UcxMap *map, DavQLExpression *expression) { |
|
234 if(!expression) { |
246 if(!expression) { |
235 return 0; |
247 return 0; |
236 } |
248 } |
237 |
249 |
238 if(expression->type == DAVQL_IDENTIFIER) { |
250 if(expression->type == DAVQL_IDENTIFIER) { |
239 DavProperty *property = ucx_mempool_malloc(mp, sizeof(DavProperty)); |
251 DavProperty *property = cxMalloc(a, sizeof(DavProperty)); |
240 |
252 |
241 char *name; |
253 char *name; |
242 DavNamespace *ns = dav_get_property_namespace( |
254 DavNamespace *ns = dav_get_property_namespace( |
243 sn->context, |
255 sn->context, |
244 sstrdup_a(mp->allocator, expression->srctext).ptr, |
256 cx_strdup_a(a, expression->srctext).ptr, |
245 &name); |
257 &name); |
246 if(!ns) { |
258 if(!ns) { |
247 return -1; |
259 return -1; |
248 } |
260 } |
249 |
261 |
250 property->ns = ns; |
262 property->ns = ns; |
251 property->name = name; |
263 property->name = name; |
252 property->value = NULL; |
264 property->value = NULL; |
253 |
265 |
254 ucx_map_sstr_put(map, expression->srctext, property); |
266 cxMapPut(map, cx_hash_key(expression->srctext.ptr, expression->srctext.length), property); |
255 } |
267 } |
256 |
268 |
257 if(expression->left) { |
269 if(expression->left) { |
258 if(fl_add_properties(sn, mp, map, expression->left)) { |
270 if(fl_add_properties(sn, a, map, expression->left)) { |
259 return -1; |
271 return -1; |
260 } |
272 } |
261 } |
273 } |
262 if(expression->right) { |
274 if(expression->right) { |
263 if(fl_add_properties(sn, mp, map, expression->right)) { |
275 if(fl_add_properties(sn, a, map, expression->right)) { |
264 return -1; |
276 return -1; |
265 } |
277 } |
266 } |
278 } |
267 |
279 |
268 return 0; |
280 return 0; |
269 } |
281 } |
270 |
282 |
271 static UcxBuffer* fieldlist2propfindrequest(DavSession *sn, UcxMempool *mp, UcxList *fields, int *isallprop) { |
283 static CxBuffer* fieldlist2propfindrequest(DavSession *sn, const CxAllocator *a, CxList *fields, int *isallprop) { |
272 UcxMap *properties = ucx_map_new(32); |
284 CxMap *properties = cxHashMapCreate(cxDefaultAllocator, CX_STORE_POINTERS, 32); |
273 *isallprop = 0; |
285 *isallprop = 0; |
274 |
286 |
275 UCX_FOREACH(elm, fields) { |
287 CxIterator i = cxListIterator(fields); |
276 DavQLField *field = elm->data; |
288 cx_foreach(DavQLField*, field, i) { |
277 if(!sstrcmp(field->name, S("*"))) { |
289 if(!cx_strcmp(field->name, CX_STR("*"))) { |
278 ucx_map_free(properties); |
290 cxMapDestroy(properties); |
279 *isallprop = 1; |
291 *isallprop = 1; |
280 return create_allprop_propfind_request(); |
292 return create_allprop_propfind_request(); |
281 } else if(!sstrcmp(field->name, S("-"))) { |
293 } else if(!cx_strcmp(field->name, CX_STR("-"))) { |
282 ucx_map_free(properties); |
294 cxMapDestroy(properties); |
283 return create_propfind_request(sn, NULL, "propfind", 0); |
295 return create_propfind_request(sn, NULL, "propfind", 0); |
284 } else { |
296 } else { |
285 if(fl_add_properties(sn, mp, properties, field->expr)) { |
297 if(fl_add_properties(sn, a, properties, field->expr)) { |
286 // TODO: set error |
298 // TODO: set error |
287 ucx_map_free(properties); |
299 cxMapDestroy(properties); |
288 return NULL; |
300 return NULL; |
289 } |
301 } |
290 } |
302 } |
291 } |
303 } |
292 |
304 |
293 UcxMapIterator i = ucx_map_iterator(properties); |
305 i = cxMapIteratorValues(properties); |
294 UcxKey key; |
306 CxList *list = cxLinkedListCreateSimple(CX_STORE_POINTERS); |
295 DavProperty *value; |
307 cx_foreach(DavProperty*, value, i) { |
296 UcxList *list = NULL; |
308 cxListAdd(list, value); |
297 UCX_MAP_FOREACH(key, value, i) { |
309 } |
298 list = ucx_list_append(list, value); |
310 |
299 } |
311 CxBuffer *reqbuf = create_propfind_request(sn, list, "propfind", 0); |
300 |
312 cxListDestroy(list); |
301 UcxBuffer *reqbuf = create_propfind_request(sn, list, "propfind", 0); |
313 cxMapDestroy(properties); |
302 ucx_list_free(list); |
|
303 ucx_map_free(properties); |
|
304 return reqbuf; |
314 return reqbuf; |
305 } |
315 } |
306 |
316 |
307 static int reset_properties(DavSession *sn, DavResult *result, DavResource *res, UcxList *fields) { |
317 static int reset_properties(DavSession *sn, DavResult *result, DavResource *res, CxList *fields) { |
308 UcxMap *new_properties = ucx_map_new_a(sn->mp->allocator, 32); |
318 CxMap *new_properties = cxHashMapCreate(sn->mp->allocator, CX_STORE_POINTERS, 32); |
309 DavResourceData *data = (DavResourceData*)res->data; |
319 DavResourceData *data = (DavResourceData*)res->data; |
310 |
320 |
311 // add basic properties |
321 // add basic properties |
312 void *value; |
322 void *value; |
313 |
323 |
314 sstr_t cl_keystr = dav_property_key("DAV:", "getcontentlength"); |
324 cxmutstr cl_keystr = dav_property_key("DAV:", "getcontentlength"); |
315 UcxKey cl_key = ucx_key(cl_keystr.ptr, cl_keystr.length); |
325 CxHashKey cl_key = cx_hash_key(cl_keystr.ptr, cl_keystr.length); |
316 value = ucx_map_get(data->properties, cl_key); |
326 value = cxMapGet(data->properties, cl_key); |
317 if(value) { |
327 if(value) { |
318 ucx_map_put(new_properties, cl_key, value); |
328 cxMapPut(new_properties, cl_key, value); |
319 } |
329 } |
320 |
330 |
321 sstr_t cd_keystr = dav_property_key("DAV:", "creationdate"); |
331 cxmutstr cd_keystr = dav_property_key("DAV:", "creationdate"); |
322 UcxKey cd_key = ucx_key(cd_keystr.ptr, cd_keystr.length); |
332 CxHashKey cd_key = cx_hash_key(cd_keystr.ptr, cd_keystr.length); |
323 value = ucx_map_get(data->properties, cd_key); |
333 value = cxMapGet(data->properties, cd_key); |
324 if(value) { |
334 if(value) { |
325 ucx_map_put(new_properties, cd_key, value); |
335 cxMapPut(new_properties, cd_key, value); |
326 } |
336 } |
327 |
337 |
328 sstr_t lm_keystr = dav_property_key("DAV:", "getlastmodified"); |
338 cxmutstr lm_keystr = dav_property_key("DAV:", "getlastmodified"); |
329 UcxKey lm_key = ucx_key(lm_keystr.ptr, lm_keystr.length); |
339 CxHashKey lm_key = cx_hash_key(lm_keystr.ptr, lm_keystr.length); |
330 value = ucx_map_get(data->properties, lm_key); |
340 value = cxMapGet(data->properties, lm_key); |
331 if(value) { |
341 if(value) { |
332 ucx_map_put(new_properties, lm_key, value); |
342 cxMapPut(new_properties, lm_key, value); |
333 } |
343 } |
334 |
344 |
335 sstr_t ct_keystr = dav_property_key("DAV:", "getcontenttype"); |
345 cxmutstr ct_keystr = dav_property_key("DAV:", "getcontenttype"); |
336 UcxKey ct_key = ucx_key(ct_keystr.ptr, ct_keystr.length); |
346 CxHashKey ct_key = cx_hash_key(ct_keystr.ptr, ct_keystr.length); |
337 value = ucx_map_get(data->properties, ct_key); |
347 value = cxMapGet(data->properties, ct_key); |
338 if(value) { |
348 if(value) { |
339 ucx_map_put(new_properties, ct_key, value); |
349 cxMapPut(new_properties, ct_key, value); |
340 } |
350 } |
341 |
351 |
342 sstr_t rt_keystr = dav_property_key("DAV:", "resourcetype"); |
352 cxmutstr rt_keystr = dav_property_key("DAV:", "resourcetype"); |
343 UcxKey rt_key = ucx_key(rt_keystr.ptr, rt_keystr.length); |
353 CxHashKey rt_key = cx_hash_key(rt_keystr.ptr, rt_keystr.length); |
344 value = ucx_map_get(data->properties, rt_key); |
354 value = cxMapGet(data->properties, rt_key); |
345 if(value) { |
355 if(value) { |
346 ucx_map_put(new_properties, rt_key, value); |
356 cxMapPut(new_properties, rt_key, value); |
347 } |
357 } |
348 |
358 |
349 sstr_t cn_keystr = dav_property_key(DAV_NS, "crypto-name"); |
359 cxmutstr cn_keystr = dav_property_key(DAV_NS, "crypto-name"); |
350 UcxKey cn_key = ucx_key(cn_keystr.ptr, cn_keystr.length); |
360 CxHashKey cn_key = cx_hash_key(cn_keystr.ptr, cn_keystr.length); |
351 value = ucx_map_get(data->properties, cn_key); |
361 value = cxMapGet(data->properties, cn_key); |
352 if(value) { |
362 if(value) { |
353 ucx_map_put(new_properties, cn_key, value); |
363 cxMapPut(new_properties, cn_key, value); |
354 } |
364 } |
355 |
365 |
356 sstr_t ck_keystr = dav_property_key(DAV_NS, "crypto-key"); |
366 cxmutstr ck_keystr = dav_property_key(DAV_NS, "crypto-key"); |
357 UcxKey ck_key = ucx_key(ck_keystr.ptr, ck_keystr.length); |
367 CxHashKey ck_key = cx_hash_key(ck_keystr.ptr, ck_keystr.length); |
358 value = ucx_map_get(data->properties, ck_key); |
368 value = cxMapGet(data->properties, ck_key); |
359 if(value) { |
369 if(value) { |
360 ucx_map_put(new_properties, ck_key, value); |
370 cxMapPut(new_properties, ck_key, value); |
361 } |
371 } |
362 |
372 |
363 sstr_t ch_keystr = dav_property_key(DAV_NS, "crypto-hash"); |
373 cxmutstr ch_keystr = dav_property_key(DAV_NS, "crypto-hash"); |
364 UcxKey ch_key = ucx_key(ch_keystr.ptr, ch_keystr.length); |
374 CxHashKey ch_key = cx_hash_key(ch_keystr.ptr, ch_keystr.length); |
365 value = ucx_map_get(data->properties, ch_key); |
375 value = cxMapGet(data->properties, ch_key); |
366 if(value) { |
376 if(value) { |
367 ucx_map_put(new_properties, ch_key, value); |
377 cxMapPut(new_properties, ch_key, value); |
368 } |
378 } |
369 |
379 |
370 // add properties from field list |
380 // add properties from field list |
371 UCX_FOREACH(elm, fields) { |
381 if(fields) { |
372 DavCompiledField *field = elm->data; |
382 CxIterator i = cxListIterator(fields); |
373 DavQLStackObj field_result; |
383 cx_foreach(DavCompiledField*, field, i) { |
374 if(!dav_exec_expr(field->code, res, &field_result)) { |
384 DavQLStackObj field_result; |
375 sstr_t str; |
385 if(!dav_exec_expr(field->code, res, &field_result)) { |
376 str.ptr = NULL; |
386 cxmutstr str; |
377 str.length = 0; |
387 str.ptr = NULL; |
378 DavXmlNode *node = NULL; |
388 str.length = 0; |
379 if(field_result.type == 0) { |
389 DavXmlNode *node = NULL; |
380 str = ucx_asprintf( |
390 if(field_result.type == 0) { |
381 sn->mp->allocator, |
391 str = cx_asprintf_a( |
382 "%d", |
392 sn->mp->allocator, |
383 field_result.data.integer); |
393 "%" PRId64, |
384 } else if(field_result.type == 1) { |
394 field_result.data.integer); |
385 if(field_result.data.string) { |
395 } else if(field_result.type == 1) { |
386 str = sstrdup_a(sn->mp->allocator, sstrn( |
396 if(field_result.data.string) { |
387 field_result.data.string, |
397 str = cx_strdup_a(sn->mp->allocator, cx_strn( |
388 field_result.length)); |
398 field_result.data.string, |
389 } |
399 field_result.length)); |
390 } else if(field_result.type == 2) { |
400 } |
391 node = dav_copy_node(field_result.data.node); |
401 } else if(field_result.type == 2) { |
|
402 node = dav_copy_node(field_result.data.node); |
|
403 } else { |
|
404 // unknown type |
|
405 // TODO: error |
|
406 resource_free_properties(sn, new_properties); |
|
407 return -1; |
|
408 } |
|
409 if(str.ptr) { |
|
410 node = dav_session_malloc(sn, sizeof(DavXmlNode)); |
|
411 memset(node, 0, sizeof(DavXmlNode)); |
|
412 node->type = DAV_XML_TEXT; |
|
413 node->content = str.ptr; |
|
414 node->contentlength = str.length; |
|
415 } |
|
416 if(node) { |
|
417 cxmutstr key = dav_property_key(field->ns, field->name); |
|
418 |
|
419 DavNamespace *namespace = dav_session_malloc(sn, sizeof(DavNamespace)); |
|
420 namespace->prefix = NULL; |
|
421 namespace->name = dav_session_strdup(sn, field->ns); |
|
422 |
|
423 DavProperty *prop = dav_session_malloc(sn, sizeof(DavProperty)); |
|
424 prop->name = dav_session_strdup(sn, field->name); |
|
425 prop->ns = namespace; |
|
426 prop->value = node; |
|
427 |
|
428 cxMapPut(new_properties, cx_hash_key(key.ptr, key.length), prop); |
|
429 free(key.ptr); |
|
430 } |
392 } else { |
431 } else { |
393 // unknown type |
|
394 // TODO: error |
432 // TODO: error |
395 resource_free_properties(sn, new_properties); |
433 resource_free_properties(sn, new_properties); |
396 return -1; |
434 return -1; |
397 } |
435 } |
398 if(str.ptr) { |
436 } |
399 node = dav_session_malloc(sn, sizeof(DavXmlNode)); |
437 } |
400 memset(node, 0, sizeof(DavXmlNode)); |
438 |
401 node->type = DAV_XML_TEXT; |
439 cxMapRemove(data->properties, cl_key); |
402 node->content = str.ptr; |
440 cxMapRemove(data->properties, cd_key); |
403 node->contentlength = str.length; |
441 cxMapRemove(data->properties, lm_key); |
404 } |
442 cxMapRemove(data->properties, ct_key); |
405 if(node) { |
443 cxMapRemove(data->properties, rt_key); |
406 sstr_t key = dav_property_key(field->ns, field->name); |
444 cxMapRemove(data->properties, cn_key); |
407 |
445 cxMapRemove(data->properties, ck_key); |
408 DavNamespace *namespace = dav_session_malloc(sn, sizeof(DavNamespace)); |
446 cxMapRemove(data->properties, ch_key); |
409 namespace->prefix = NULL; |
|
410 namespace->name = dav_session_strdup(sn, field->ns); |
|
411 |
|
412 DavProperty *prop = dav_session_malloc(sn, sizeof(DavProperty)); |
|
413 prop->name = dav_session_strdup(sn, field->name); |
|
414 prop->ns = namespace; |
|
415 prop->value = node; |
|
416 |
|
417 ucx_map_sstr_put(new_properties, key, prop); |
|
418 free(key.ptr); |
|
419 } |
|
420 } else { |
|
421 // TODO: error |
|
422 resource_free_properties(sn, new_properties); |
|
423 return -1; |
|
424 } |
|
425 } |
|
426 |
|
427 ucx_map_remove(data->properties, cl_key); |
|
428 ucx_map_remove(data->properties, cd_key); |
|
429 ucx_map_remove(data->properties, lm_key); |
|
430 ucx_map_remove(data->properties, ct_key); |
|
431 ucx_map_remove(data->properties, rt_key); |
|
432 ucx_map_remove(data->properties, cn_key); |
|
433 ucx_map_remove(data->properties, ck_key); |
|
434 ucx_map_remove(data->properties, ch_key); |
|
435 |
447 |
436 resource_free_properties(sn, data->properties); |
448 resource_free_properties(sn, data->properties); |
437 data->properties = new_properties; |
449 data->properties = new_properties; |
438 |
450 |
439 free(cl_keystr.ptr); |
451 free(cl_keystr.ptr); |
450 |
462 |
451 /* |
463 /* |
452 * execute a davql select statement |
464 * execute a davql select statement |
453 */ |
465 */ |
454 DavResult dav_exec_select(DavSession *sn, DavQLStatement *st, va_list ap) { |
466 DavResult dav_exec_select(DavSession *sn, DavQLStatement *st, va_list ap) { |
455 UcxMempool *mp = ucx_mempool_new(128); |
467 CxMempool *mp = cxBasicMempoolCreate(128); |
456 DavResult result; |
468 DavResult result; |
457 result.result = NULL; |
469 result.result = NULL; |
458 result.status = 1; |
470 result.status = 1; |
459 |
471 |
460 DavQLArgList *args = dav_ql_get_args(st, ap); |
472 DavQLArgList *args = dav_ql_get_args(st, ap); |
461 if(!args) { |
473 if(!args) { |
462 return result; |
474 return result; |
463 } |
475 } |
464 ucx_mempool_reg_destr(mp, args, (ucx_destructor)dav_ql_free_arglist); |
476 util_regdestr(mp, args, (cx_destructor_func)dav_ql_free_arglist); |
465 |
477 |
466 int isallprop; |
478 int isallprop; |
467 UcxBuffer *rqbuf = fieldlist2propfindrequest(sn, mp, st->fields, &isallprop); |
479 CxBuffer *rqbuf = fieldlist2propfindrequest(sn, mp->allocator, st->fields, &isallprop); |
468 if(!rqbuf) { |
480 if(!rqbuf) { |
469 ucx_mempool_destroy(mp); |
481 cxMempoolDestroy(mp); |
470 return result; |
482 return result; |
471 } |
483 } |
472 ucx_mempool_reg_destr(mp, rqbuf, (ucx_destructor)ucx_buffer_free); |
484 util_regdestr(mp, rqbuf, (cx_destructor_func)cxBufferFree); |
473 |
485 |
474 // compile field list |
486 // compile field list |
475 UcxList *cfieldlist = NULL; |
487 CxList *cfieldlist = cxLinkedListCreate(mp->allocator, NULL, CX_STORE_POINTERS); |
476 UCX_FOREACH(elm, st->fields) { |
488 if(st->fields) { |
477 DavQLField *field = elm->data; |
489 CxIterator i = cxListIterator(st->fields); |
478 if(sstrcmp(field->name, S("*")) && sstrcmp(field->name, S("-"))) { |
490 cx_foreach(DavQLField*, field, i) { |
479 // compile field expression |
491 if(cx_strcmp(field->name, CX_STR("*")) && cx_strcmp(field->name, CX_STR("-"))) { |
480 UcxBuffer *code = dav_compile_expr( |
492 // compile field expression |
481 sn->context, |
493 CxBuffer *code = dav_compile_expr( |
482 mp->allocator, |
494 sn->context, |
483 field->expr, |
495 mp->allocator, |
484 args); |
496 field->expr, |
485 if(!code) { |
497 args); |
486 // TODO: set error string |
498 if(!code) { |
487 return result; |
499 // TODO: set error string |
488 } |
500 return result; |
489 ucx_mempool_reg_destr(mp, code, (ucx_destructor)ucx_buffer_free); |
501 } |
490 DavCompiledField *cfield = ucx_mempool_malloc( |
502 DavCompiledField *cfield = cxMalloc( |
491 mp, |
503 mp->allocator, |
492 sizeof(DavCompiledField)); |
504 sizeof(DavCompiledField)); |
493 |
505 |
494 char *ns; |
|
495 char *name; |
|
496 dav_get_property_namespace_str( |
|
497 sn->context, |
|
498 sstrdup_a(mp->allocator, field->name).ptr, |
|
499 &ns, |
|
500 &name); |
|
501 if(!ns || !name) { |
|
502 // TODO: set error string |
|
503 return result; |
|
504 } |
|
505 cfield->ns = ns; |
|
506 cfield->name = name; |
|
507 cfield->code = code; |
|
508 cfieldlist = ucx_list_append_a(mp->allocator, cfieldlist, cfield); |
|
509 } |
|
510 } |
|
511 |
|
512 // get path string |
|
513 davqlerror_t error; |
|
514 sstr_t path = dav_format_string(mp->allocator, st->path, args, &error); |
|
515 if(error) { |
|
516 // TODO: cleanup |
|
517 ucx_mempool_destroy(mp); |
|
518 return result; |
|
519 } |
|
520 |
|
521 int depth = st->depth == DAV_DEPTH_PLACEHOLDER ? |
|
522 dav_ql_getarg_int(args) : st->depth; |
|
523 |
|
524 UcxBuffer *where = dav_compile_expr(sn->context, mp->allocator, st->where, args); |
|
525 if(st->where && !where) { |
|
526 // TODO: cleanup |
|
527 ucx_mempool_destroy(mp); |
|
528 return result; |
|
529 } |
|
530 if(where) { |
|
531 ucx_mempool_reg_destr(mp, where, (ucx_destructor)ucx_buffer_free); |
|
532 } |
|
533 |
|
534 // compile order criterion |
|
535 UcxList *ordercr = NULL; |
|
536 UCX_FOREACH(elm, st->orderby) { |
|
537 DavQLOrderCriterion *oc = elm->data; |
|
538 DavQLExpression *column = oc->column; |
|
539 //printf("%.*s %s\n", column->srctext.length, column->srctext.ptr, oc->descending ? "desc" : "asc"); |
|
540 if(column->type == DAVQL_IDENTIFIER) { |
|
541 // TODO: remove code duplication (add_cmd) |
|
542 davqlresprop_t resprop; |
|
543 sstr_t propertyname = sstrchr(column->srctext, ':'); |
|
544 if(propertyname.length > 0) { |
|
545 char *ns; |
506 char *ns; |
546 char *name; |
507 char *name; |
547 dav_get_property_namespace_str( |
508 dav_get_property_namespace_str( |
548 sn->context, |
509 sn->context, |
549 sstrdup_a(mp->allocator, column->srctext).ptr, |
510 cx_strdup_a(mp->allocator, field->name).ptr, |
550 &ns, |
511 &ns, |
551 &name); |
512 &name); |
552 if(ns && name) { |
513 if(!ns || !name) { |
553 DavOrderCriterion *cr = ucx_mempool_malloc(mp, sizeof(DavOrderCriterion)); |
514 // TODO: set error string |
554 cr->type = 1; |
515 return result; |
555 sstr_t keystr = dav_property_key_a(mp->allocator, ns, name); |
516 } |
556 cr->column.property = ucx_key(keystr.ptr, keystr.length); |
517 cfield->ns = ns; |
557 cr->descending = oc->descending; |
518 cfield->name = name; |
558 ordercr = ucx_list_append_a(mp->allocator, ordercr, cr); |
519 cfield->code = code; |
|
520 cxListAdd(cfieldlist, cfield); |
|
521 } |
|
522 } |
|
523 } |
|
524 |
|
525 // get path string |
|
526 davqlerror_t error; |
|
527 cxmutstr path = dav_format_string(mp->allocator, st->path, args, &error); |
|
528 if(error) { |
|
529 // TODO: cleanup |
|
530 cxMempoolDestroy(mp); |
|
531 return result; |
|
532 } |
|
533 |
|
534 int depth = st->depth == DAV_DEPTH_PLACEHOLDER ? |
|
535 dav_ql_getarg_int(args) : st->depth; |
|
536 |
|
537 CxBuffer *where = dav_compile_expr(sn->context, mp->allocator, st->where, args); |
|
538 if(st->where && !where) { |
|
539 // TODO: cleanup |
|
540 cxMempoolDestroy(mp); |
|
541 return result; |
|
542 } |
|
543 |
|
544 // compile order criterion |
|
545 CxList *ordercr = NULL; |
|
546 if(st->orderby) { |
|
547 ordercr = cxLinkedListCreate(mp->allocator, NULL, sizeof(DavOrderCriterion)); |
|
548 CxIterator i = cxListIterator(st->orderby); |
|
549 cx_foreach(DavQLOrderCriterion*, oc, i) { |
|
550 DavQLExpression *column = oc->column; |
|
551 //printf("%.*s %s\n", column->srctext.length, column->srctext.ptr, oc->descending ? "desc" : "asc"); |
|
552 if(column->type == DAVQL_IDENTIFIER) { |
|
553 // TODO: remove code duplication (add_cmd) |
|
554 davqlresprop_t resprop; |
|
555 cxstring propertyname = cx_strchr(column->srctext, ':'); |
|
556 if(propertyname.length > 0) { |
|
557 char *ns; |
|
558 char *name; |
|
559 dav_get_property_namespace_str( |
|
560 sn->context, |
|
561 cx_strdup_a(mp->allocator, column->srctext).ptr, |
|
562 &ns, |
|
563 &name); |
|
564 if(ns && name) { |
|
565 DavOrderCriterion cr; |
|
566 cr.type = 1; |
|
567 cxmutstr keystr = dav_property_key_a(mp->allocator, ns, name); |
|
568 cr.column.property = cx_hash_key(keystr.ptr, keystr.length); |
|
569 cr.descending = oc->descending; |
|
570 cxListAdd(ordercr, &cr); |
|
571 } else { |
|
572 // error |
|
573 // TODO: cleanup |
|
574 cxMempoolDestroy(mp); |
|
575 return result; |
|
576 } |
|
577 } else if(dav_identifier2resprop(column->srctext, &resprop)) { |
|
578 DavOrderCriterion cr; |
|
579 cr.type = 0; |
|
580 cr.column.resprop = resprop; |
|
581 cr.descending = oc->descending; |
|
582 cxListAdd(ordercr, &cr); |
559 } else { |
583 } else { |
560 // error |
584 // error |
561 // TODO: cleanup |
585 // TODO: cleanup |
562 ucx_mempool_destroy(mp); |
586 cxMempoolDestroy(mp); |
563 return result; |
587 return result; |
564 } |
588 } |
565 } else if(dav_identifier2resprop(column->srctext, &resprop)) { |
589 |
566 DavOrderCriterion *cr = ucx_mempool_malloc(mp, sizeof(DavOrderCriterion)); |
590 } else if(column->type == DAVQL_NUMBER) { |
567 cr->type = 0; |
591 // TODO: implement |
568 cr->column.resprop = resprop; |
592 fprintf(stderr, "order by number not supported\n"); |
569 cr->descending = oc->descending; |
593 return result; |
570 ordercr = ucx_list_append_a(mp->allocator, ordercr, cr); |
|
571 } else { |
594 } else { |
572 // error |
595 // something is broken |
573 // TODO: cleanup |
596 // TODO: cleanup |
574 ucx_mempool_destroy(mp); |
597 cxMempoolDestroy(mp); |
575 return result; |
598 return result; |
576 } |
599 } |
577 |
|
578 } else if(column->type == DAVQL_NUMBER) { |
|
579 // TODO: implement |
|
580 fprintf(stderr, "order by number not supported\n"); |
|
581 return result; |
|
582 } else { |
|
583 // something is broken |
|
584 // TODO: cleanup |
|
585 ucx_mempool_destroy(mp); |
|
586 return result; |
|
587 } |
600 } |
588 } |
601 } |
589 |
602 |
590 DavResource *selroot = dav_resource_new(sn, path.ptr); |
603 DavResource *selroot = dav_resource_new(sn, path.ptr); |
591 |
604 |
592 UcxList *stack = NULL; // stack with DavResource* elements |
605 CxList *stack = cxLinkedListCreateSimple(sizeof(DavQLRes)); |
593 // initialize the stack with the requested resource |
606 // initialize the stack with the requested resource |
594 DavQLRes *res = ucx_mempool_malloc(mp, sizeof(DavQLRes)); |
607 DavQLRes res; |
595 res->resource = selroot; |
608 res.resource = selroot; |
596 res->depth = 0; |
609 res.depth = 0; |
597 stack = ucx_list_prepend(stack, res); |
610 cxListInsert(stack, 0, &res); |
598 |
611 |
599 // reuseable response buffer |
612 // reuseable response buffer |
600 UcxBuffer *rpbuf = ucx_buffer_new(NULL, 4096, UCX_BUFFER_AUTOEXTEND); |
613 CxBuffer *rpbuf = cxBufferCreate(NULL, 4096, mp->allocator, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND); |
601 if(!rpbuf) { |
614 if(!rpbuf) { |
602 // TODO: cleanup |
615 // TODO: cleanup |
603 ucx_mempool_destroy(mp); |
616 cxMempoolDestroy(mp); |
604 return result; |
617 return result; |
605 } |
618 } |
606 ucx_mempool_reg_destr(mp, rpbuf, (ucx_destructor)ucx_buffer_free); |
|
607 |
619 |
608 result.result = selroot; |
620 result.result = selroot; |
609 result.status = 0; |
621 result.status = 0; |
610 |
622 |
611 // do a propfind request for each resource on the stack |
623 // do a propfind request for each resource on the stack |
612 while(stack) { |
624 while(stack->size > 0) { |
613 DavQLRes *sr = stack->data; // get first element from the stack |
625 DavQLRes *sr = cxListAt(stack, 0); // get first element from the stack |
614 stack = ucx_list_remove(stack, stack); // remove first element |
626 cxListRemove(stack, 0); |
|
627 cxListRemove(stack, 0); // remove first element |
615 DavResource *root = sr->resource; |
628 DavResource *root = sr->resource; |
616 |
629 |
617 util_set_url(sn, dav_resource_get_href(sr->resource)); |
630 util_set_url(sn, dav_resource_get_href(sr->resource)); |
618 CURLcode ret = do_propfind_request(sn, rqbuf, rpbuf); |
631 CURLcode ret = do_propfind_request(sn, rqbuf, rpbuf); |
619 long http_status = 0; |
632 long http_status = 0; |
736 } |
747 } |
737 } |
748 } |
738 return count; |
749 return count; |
739 } |
750 } |
740 |
751 |
741 int dav_identifier2resprop(sstr_t src, davqlresprop_t *prop) { |
752 int dav_identifier2resprop(cxstring src, davqlresprop_t *prop) { |
742 if(!sstrcmp(src, S("name"))) { |
753 if(!cx_strcmp(src, CX_STR("name"))) { |
743 *prop = DAVQL_RES_NAME; |
754 *prop = DAVQL_RES_NAME; |
744 } else if(!sstrcmp(src, S("path"))) { |
755 } else if(!cx_strcmp(src, CX_STR("path"))) { |
745 *prop = DAVQL_RES_PATH; |
756 *prop = DAVQL_RES_PATH; |
746 } else if(!sstrcmp(src, S("href"))) { |
757 } else if(!cx_strcmp(src, CX_STR("href"))) { |
747 *prop = DAVQL_RES_HREF; |
758 *prop = DAVQL_RES_HREF; |
748 } else if(!sstrcmp(src, S("contentlength"))) { |
759 } else if(!cx_strcmp(src, CX_STR("contentlength"))) { |
749 *prop = DAVQL_RES_CONTENTLENGTH; |
760 *prop = DAVQL_RES_CONTENTLENGTH; |
750 } else if(!sstrcmp(src, S("contenttype"))) { |
761 } else if(!cx_strcmp(src, CX_STR("contenttype"))) { |
751 *prop = DAVQL_RES_CONTENTTYPE; |
762 *prop = DAVQL_RES_CONTENTTYPE; |
752 } else if(!sstrcmp(src, S("creationdate"))) { |
763 } else if(!cx_strcmp(src, CX_STR("creationdate"))) { |
753 *prop = DAVQL_RES_CREATIONDATE; |
764 *prop = DAVQL_RES_CREATIONDATE; |
754 } else if(!sstrcmp(src, S("lastmodified"))) { |
765 } else if(!cx_strcmp(src, CX_STR("lastmodified"))) { |
755 *prop = DAVQL_RES_LASTMODIFIED; |
766 *prop = DAVQL_RES_LASTMODIFIED; |
756 } else if(!sstrcmp(src, S("iscollection"))) { |
767 } else if(!cx_strcmp(src, CX_STR("iscollection"))) { |
757 *prop = DAVQL_RES_ISCOLLECTION; |
768 *prop = DAVQL_RES_ISCOLLECTION; |
758 } else { |
769 } else { |
759 return 0; |
770 return 0; |
760 } |
771 } |
761 return 1; |
772 return 1; |
762 } |
773 } |
763 |
774 |
764 static int add_cmd(DavContext *ctx, UcxAllocator *a, UcxBuffer *bcode, DavQLExpression *expr, DavQLArgList *ap) { |
775 static int add_cmd(DavContext *ctx, const CxAllocator *a, CxBuffer *bcode, DavQLExpression *expr, DavQLArgList *ap) { |
765 if(!expr) { |
776 if(!expr) { |
766 return 0; |
777 return 0; |
767 } |
778 } |
768 |
779 |
769 int numcmd = 1; |
780 int numcmd = 1; |
770 DavQLCmd cmd; |
781 DavQLCmd cmd; |
771 memset(&cmd, 0, sizeof(DavQLCmd)); |
782 memset(&cmd, 0, sizeof(DavQLCmd)); |
772 davqlerror_t error; |
783 davqlerror_t error; |
773 |
784 |
774 sstr_t src = expr->srctext; |
785 cxstring src = expr->srctext; |
775 switch(expr->type) { |
786 switch(expr->type) { |
776 default: break; |
787 default: break; |
777 case DAVQL_NUMBER: { |
788 case DAVQL_NUMBER: { |
778 cmd.type = DAVQL_CMD_INT; |
789 cmd.type = DAVQL_CMD_INT; |
779 if(src.ptr[0] == '%') { |
790 if(src.ptr[0] == '%') { |
780 cmd.data.integer = dav_ql_getarg_int(ap); |
791 cmd.data.integer = dav_ql_getarg_int(ap); |
781 } else if(util_strtoint(src.ptr, &cmd.data.integer)) { |
792 } else if(util_strtoint(src.ptr, &cmd.data.integer)) { |
782 ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode); |
793 cxBufferWrite(&cmd, sizeof(cmd), 1, bcode); |
783 } else { |
794 } else { |
784 // error |
795 // error |
785 return -1; |
796 return -1; |
786 } |
797 } |
787 |
798 |
788 break; |
799 break; |
789 } |
800 } |
790 case DAVQL_STRING: { |
801 case DAVQL_STRING: { |
791 cmd.type = DAVQL_CMD_STRING; |
802 cmd.type = DAVQL_CMD_STRING; |
792 cmd.data.string = dav_format_string(a, src, ap, &error); |
803 cmd.data.string = dav_format_string(a, src, ap, &error); |
793 ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode); |
804 cxBufferWrite(&cmd, sizeof(cmd), 1, bcode); |
794 break; |
805 break; |
795 } |
806 } |
796 case DAVQL_TIMESTAMP: { |
807 case DAVQL_TIMESTAMP: { |
797 if(src.ptr[0] == '%') { |
808 if(src.ptr[0] == '%') { |
798 cmd.type = DAVQL_CMD_TIMESTAMP; |
809 cmd.type = DAVQL_CMD_TIMESTAMP; |
799 cmd.data.timestamp = dav_ql_getarg_time(ap); |
810 cmd.data.timestamp = dav_ql_getarg_time(ap); |
800 ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode); |
811 cxBufferWrite(&cmd, sizeof(cmd), 1, bcode); |
801 } else { |
812 } else { |
802 // error |
813 // error |
803 return -1; |
814 return -1; |
804 } |
815 } |
805 break; |
816 break; |
806 } |
817 } |
807 case DAVQL_IDENTIFIER: { |
818 case DAVQL_IDENTIFIER: { |
808 sstr_t propertyname = sstrchr(src, ':'); |
819 cxstring propertyname = cx_strchr(src, ':'); |
809 cmd.type = DAVQL_CMD_RES_IDENTIFIER; |
820 cmd.type = DAVQL_CMD_RES_IDENTIFIER; |
810 if(propertyname.length > 0) { |
821 if(propertyname.length > 0) { |
811 cmd.type = DAVQL_CMD_PROP_IDENTIFIER; |
822 cmd.type = DAVQL_CMD_PROP_IDENTIFIER; |
812 char *ns; |
823 char *ns; |
813 char *name; |
824 char *name; |
814 dav_get_property_namespace_str( |
825 dav_get_property_namespace_str( |
815 ctx, |
826 ctx, |
816 sstrdup_a(a, src).ptr, |
827 cx_strdup_a(a, src).ptr, |
817 &ns, |
828 &ns, |
818 &name); |
829 &name); |
819 if(ns && name) { |
830 if(ns && name) { |
820 cmd.data.property.ns = ns; |
831 cmd.data.property.ns = ns; |
821 cmd.data.property.name = name; |
832 cmd.data.property.name = name; |
822 } else { |
833 } else { |
823 // error |
834 // error |
824 return -1; |
835 return -1; |
825 } |
836 } |
826 } else if(!dav_identifier2resprop(src, &cmd.data.resprop)) { |
837 } else if(!dav_identifier2resprop(src, &cmd.data.resprop)) { |
827 if(!sstrcmp(src, S("true"))) { |
838 if(!cx_strcmp(src, CX_STR("true"))) { |
828 cmd.type = DAVQL_CMD_INT; |
839 cmd.type = DAVQL_CMD_INT; |
829 cmd.data.integer = 1; |
840 cmd.data.integer = 1; |
830 } else if(!sstrcmp(src, S("false"))) { |
841 } else if(!cx_strcmp(src, CX_STR("false"))) { |
831 cmd.type = DAVQL_CMD_INT; |
842 cmd.type = DAVQL_CMD_INT; |
832 cmd.data.integer = 0; |
843 cmd.data.integer = 0; |
833 } else { |
844 } else { |
834 // error, unknown identifier |
845 // error, unknown identifier |
835 return -1; |
846 return -1; |
836 } |
847 } |
837 } |
848 } |
838 ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode); |
849 cxBufferWrite(&cmd, sizeof(cmd), 1, bcode); |
839 break; |
850 break; |
840 } |
851 } |
841 case DAVQL_UNARY: { |
852 case DAVQL_UNARY: { |
842 numcmd += add_cmd(ctx, a, bcode, expr->left, ap); |
853 numcmd += add_cmd(ctx, a, bcode, expr->left, ap); |
843 switch(expr->op) { |
854 switch(expr->op) { |
905 |
916 |
906 switch(expr->op) { |
917 switch(expr->op) { |
907 case DAVQL_NOT: { |
918 case DAVQL_NOT: { |
908 numcmd += add_cmd(ctx, a, bcode, expr->left, ap); |
919 numcmd += add_cmd(ctx, a, bcode, expr->left, ap); |
909 cmd.type = DAVQL_CMD_OP_LOGICAL_NOT; |
920 cmd.type = DAVQL_CMD_OP_LOGICAL_NOT; |
910 ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode); |
921 cxBufferWrite(&cmd, sizeof(cmd), 1, bcode); |
911 break; |
922 break; |
912 } |
923 } |
913 case DAVQL_LAND: { |
924 case DAVQL_LAND: { |
914 cmd.type = DAVQL_CMD_OP_LOGICAL_AND; |
925 cmd.type = DAVQL_CMD_OP_LOGICAL_AND; |
915 ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode); |
926 cxBufferWrite(&cmd, sizeof(cmd), 1, bcode); |
916 break; |
927 break; |
917 } |
928 } |
918 case DAVQL_LOR: { |
929 case DAVQL_LOR: { |
919 int nleft = add_cmd(ctx, a, bcode, expr->left, ap); |
930 int nleft = add_cmd(ctx, a, bcode, expr->left, ap); |
920 |
931 |
921 cmd.type = DAVQL_CMD_OP_LOGICAL_OR_L; |
932 cmd.type = DAVQL_CMD_OP_LOGICAL_OR_L; |
922 DavQLCmd *or_l = (DavQLCmd*)(bcode->space + bcode->pos); |
933 DavQLCmd *or_l = (DavQLCmd*)(bcode->space + bcode->pos); |
923 ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode); |
934 cxBufferWrite(&cmd, sizeof(cmd), 1, bcode); |
924 |
935 |
925 int nright = add_cmd(ctx, a, bcode, expr->right, ap); |
936 int nright = add_cmd(ctx, a, bcode, expr->right, ap); |
926 or_l->data.integer = nright + 1; |
937 or_l->data.integer = nright + 1; |
927 |
938 |
928 cmd.type = DAVQL_CMD_OP_LOGICAL_OR; |
939 cmd.type = DAVQL_CMD_OP_LOGICAL_OR; |
929 cmd.data.integer = 0; |
940 cmd.data.integer = 0; |
930 ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode); |
941 cxBufferWrite(&cmd, sizeof(cmd), 1, bcode); |
931 |
942 |
932 numcmd += nleft + nright; |
943 numcmd += nleft + nright; |
933 break; |
944 break; |
934 } |
945 } |
935 case DAVQL_LXOR: { |
946 case DAVQL_LXOR: { |
936 cmd.type = DAVQL_CMD_OP_LOGICAL_XOR; |
947 cmd.type = DAVQL_CMD_OP_LOGICAL_XOR; |
937 ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode); |
948 cxBufferWrite(&cmd, sizeof(cmd), 1, bcode); |
938 break; |
949 break; |
939 } |
950 } |
940 case DAVQL_EQ: { |
951 case DAVQL_EQ: { |
941 cmd.type = DAVQL_CMD_OP_EQ; |
952 cmd.type = DAVQL_CMD_OP_EQ; |
942 ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode); |
953 cxBufferWrite(&cmd, sizeof(cmd), 1, bcode); |
943 break; |
954 break; |
944 } |
955 } |
945 case DAVQL_NEQ: { |
956 case DAVQL_NEQ: { |
946 cmd.type = DAVQL_CMD_OP_NEQ; |
957 cmd.type = DAVQL_CMD_OP_NEQ; |
947 ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode); |
958 cxBufferWrite(&cmd, sizeof(cmd), 1, bcode); |
948 break; |
959 break; |
949 } |
960 } |
950 case DAVQL_LT: { |
961 case DAVQL_LT: { |
951 cmd.type = DAVQL_CMD_OP_LT; |
962 cmd.type = DAVQL_CMD_OP_LT; |
952 ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode); |
963 cxBufferWrite(&cmd, sizeof(cmd), 1, bcode); |
953 break; |
964 break; |
954 } |
965 } |
955 case DAVQL_GT: { |
966 case DAVQL_GT: { |
956 cmd.type = DAVQL_CMD_OP_GT; |
967 cmd.type = DAVQL_CMD_OP_GT; |
957 ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode); |
968 cxBufferWrite(&cmd, sizeof(cmd), 1, bcode); |
958 break; |
969 break; |
959 } |
970 } |
960 case DAVQL_LE: { |
971 case DAVQL_LE: { |
961 cmd.type = DAVQL_CMD_OP_LE; |
972 cmd.type = DAVQL_CMD_OP_LE; |
962 ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode); |
973 cxBufferWrite(&cmd, sizeof(cmd), 1, bcode); |
963 break; |
974 break; |
964 } |
975 } |
965 case DAVQL_GE: { |
976 case DAVQL_GE: { |
966 cmd.type = DAVQL_CMD_OP_GE; |
977 cmd.type = DAVQL_CMD_OP_GE; |
967 ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode); |
978 cxBufferWrite(&cmd, sizeof(cmd), 1, bcode); |
968 break; |
979 break; |
969 } |
980 } |
970 case DAVQL_LIKE: { |
981 case DAVQL_LIKE: { |
971 cmd.type = DAVQL_CMD_OP_LIKE; |
982 cmd.type = DAVQL_CMD_OP_LIKE; |
972 ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode); |
983 cxBufferWrite(&cmd, sizeof(cmd), 1, bcode); |
973 break; |
984 break; |
974 } |
985 } |
975 case DAVQL_UNLIKE: { |
986 case DAVQL_UNLIKE: { |
976 cmd.type = DAVQL_CMD_OP_UNLIKE; |
987 cmd.type = DAVQL_CMD_OP_UNLIKE; |
977 ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode); |
988 cxBufferWrite(&cmd, sizeof(cmd), 1, bcode); |
978 break; |
989 break; |
979 } |
990 } |
980 default: break; |
991 default: break; |
981 } |
992 } |
982 break; |
993 break; |
1018 } |
1029 } |
1019 } |
1030 } |
1020 return numcmd; |
1031 return numcmd; |
1021 } |
1032 } |
1022 |
1033 |
1023 UcxBuffer* dav_compile_expr(DavContext *ctx, UcxAllocator *a, DavQLExpression *lexpr, DavQLArgList *ap) { |
1034 CxBuffer* dav_compile_expr(DavContext *ctx, const CxAllocator *a, DavQLExpression *lexpr, DavQLArgList *ap) { |
1024 UcxBuffer *bcode = ucx_buffer_new(NULL, 512, UCX_BUFFER_AUTOEXTEND); |
1035 CxBuffer *bcode = cxBufferCreate(NULL, 512, a, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND); |
1025 if(!bcode) { |
1036 if(!bcode) { |
1026 return NULL; |
1037 return NULL; |
1027 } |
1038 } |
1028 |
1039 |
1029 if(add_cmd(ctx, a, bcode, lexpr, ap) <= 0) { |
1040 if(add_cmd(ctx, a, bcode, lexpr, ap) <= 0) { |
1030 ucx_buffer_free(bcode); |
1041 cxBufferFree(bcode); |
1031 return NULL; |
1042 return NULL; |
1032 } |
1043 } |
1033 |
1044 |
1034 return bcode; |
1045 return bcode; |
1035 } |
1046 } |
1036 |
1047 |
1037 static int cmd_str_cmp(DavQLStackObj obj1, DavQLStackObj obj2, davqlcmdtype_t cmd) { |
1048 static int cmd_str_cmp(DavQLStackObj obj1, DavQLStackObj obj2, davqlcmdtype_t cmd) { |
1038 sstr_t s1 = obj1.type == 1 ? |
1049 cxmutstr s1m = obj1.type == 1 ? |
1039 sstrn(obj1.data.string, obj1.length) : |
1050 cx_mutstrn(obj1.data.string, obj1.length) : |
1040 ucx_sprintf("%" PRId64, obj1.data.integer); |
1051 cx_asprintf("%" PRId64, obj1.data.integer); |
1041 sstr_t s2 = obj1.type == 1 ? |
1052 cxmutstr s2m = obj1.type == 1 ? |
1042 sstrn(obj2.data.string, obj2.length) : |
1053 cx_mutstrn(obj2.data.string, obj2.length) : |
1043 ucx_sprintf("%" PRId64, obj2.data.integer); |
1054 cx_asprintf("%" PRId64, obj2.data.integer); |
|
1055 |
|
1056 cxstring s1 = cx_strcast(s1m); |
|
1057 cxstring s2 = cx_strcast(s2m); |
1044 |
1058 |
1045 int res = 0; |
1059 int res = 0; |
1046 switch(cmd) { |
1060 switch(cmd) { |
1047 case DAVQL_CMD_OP_EQ: { |
1061 case DAVQL_CMD_OP_EQ: { |
1048 res = sstrcmp(s1, s2) == 0; |
1062 res = cx_strcmp(s1, s2) == 0; |
1049 break; |
1063 break; |
1050 } |
1064 } |
1051 case DAVQL_CMD_OP_NEQ: { |
1065 case DAVQL_CMD_OP_NEQ: { |
1052 res = sstrcmp(s1, s2) != 0; |
1066 res = cx_strcmp(s1, s2) != 0; |
1053 break; |
1067 break; |
1054 } |
1068 } |
1055 case DAVQL_CMD_OP_LT: { |
1069 case DAVQL_CMD_OP_LT: { |
1056 res = sstrcmp(s1, s2) < 0; |
1070 res = cx_strcmp(s1, s2) < 0; |
1057 break; |
1071 break; |
1058 } |
1072 } |
1059 case DAVQL_CMD_OP_GT: { |
1073 case DAVQL_CMD_OP_GT: { |
1060 res = sstrcmp(s1, s2) > 0; |
1074 res = cx_strcmp(s1, s2) > 0; |
1061 break; |
1075 break; |
1062 } |
1076 } |
1063 case DAVQL_CMD_OP_LE: { |
1077 case DAVQL_CMD_OP_LE: { |
1064 res = sstrcmp(s1, s2) <= 0; |
1078 res = cx_strcmp(s1, s2) <= 0; |
1065 break; |
1079 break; |
1066 } |
1080 } |
1067 case DAVQL_CMD_OP_GE: { |
1081 case DAVQL_CMD_OP_GE: { |
1068 res = sstrcmp(s1, s2) >= 0; |
1082 res = cx_strcmp(s1, s2) >= 0; |
1069 break; |
1083 break; |
1070 } |
1084 } |
1071 default: break; |
1085 default: break; |
1072 } |
1086 } |
1073 |
1087 |
1074 if(obj1.type == 0) { |
1088 if(obj1.type == 0) { |
1075 free(s1.ptr); |
1089 free(s1m.ptr); |
1076 } |
1090 } |
1077 if(obj2.type == 0) { |
1091 if(obj2.type == 0) { |
1078 free(s2.ptr); |
1092 free(s2m.ptr); |
1079 } |
1093 } |
1080 |
1094 |
1081 return res; |
1095 return res; |
1082 } |
1096 } |
1083 |
1097 |
1084 int dav_exec_expr(UcxBuffer *bcode, DavResource *res, DavQLStackObj *result) { |
1098 int dav_exec_expr(CxBuffer *bcode, DavResource *res, DavQLStackObj *result) { |
1085 if(!bcode) { |
1099 if(!bcode) { |
1086 result->type = 0; |
1100 result->type = 0; |
1087 result->length = 0; |
1101 result->length = 0; |
1088 result->data.integer = 1; |
1102 result->data.integer = 1; |
1089 return 0; |
1103 return 0; |