uves_propertylist.c

00001 /* $Id: uves_propertylist.c,v 1.9 2007/10/01 17:06:51 amodigli Exp $
00002  *
00003  * This file is part of the ESO Common Pipeline Library
00004  * Copyright (C) 2001-2005 European Southern Observatory
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  */
00020 
00021 /*
00022  * $Author: amodigli $
00023  * $Date: 2007/10/01 17:06:51 $
00024  * $Revision: 1.9 $
00025  * $Name: uves-4_2_2 $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #  include <config.h>
00030 #endif
00031 #include <uves_msg.h>
00032 
00033 #include <uves_propertylist.h>
00034 #include <uves_utils_wrappers.h>
00035 #include <uves_error.h>
00036 
00037 #ifdef USE_CPL
00038 #else
00039 
00040 #include <uves_utils_wrappers.h>
00041 #include <uves_deque.h>
00042 #include <uves_dump.h>
00043 
00044 #include <cpl.h>
00045 
00046 //#include <cxmacros.h>
00047 #include <cxmemory.h>
00048 #include <cxmessages.h>
00049 #include <cxstrutils.h>
00050 #include <cxutils.h>
00051 //#include "cpl_error_impl.h"
00052 //#include "cpl_propertylist_impl.h"
00053 #include <qfits.h>
00054 
00055 #include <stdio.h>
00056 #include <string.h>
00057 #include <sys/types.h>
00058 #include <regex.h>
00059 
00076 enum {
00077     FITS_STDKEY_MAX = 8,
00078     FITS_SVALUE_MAX = 68
00079 };
00080 
00081 
00082 /*
00083  * The property list type.
00084  */
00085 
00086 struct _uves_propertylist_ {
00087     uves_deque *properties;
00088 };
00089 
00090 
00091 /*
00092  * Regular expresion filter type
00093  */
00094 
00095 struct _uves_regexp_ {
00096     regex_t re;
00097     cxbool invert;
00098 };
00099 
00100 typedef struct _uves_regexp_ uves_regexp;
00101 
00102 
00103 static void
00104 propertylist_append_property(uves_propertylist *plist, const cpl_property *p)
00105 {
00106     switch(cpl_property_get_type(p)) {
00107     case CPL_TYPE_CHAR:
00108         uves_propertylist_append_char(plist, cpl_property_get_name(p), cpl_property_get_char(p));
00109         break;
00110     case CPL_TYPE_BOOL:
00111         uves_propertylist_append_bool(plist, cpl_property_get_name(p), cpl_property_get_bool(p));
00112         break;
00113     case CPL_TYPE_INT:
00114         uves_propertylist_append_int(plist, cpl_property_get_name(p), cpl_property_get_int(p));
00115         break;
00116     case CPL_TYPE_LONG:
00117         uves_propertylist_append_long(plist, cpl_property_get_name(p), cpl_property_get_long(p));
00118         break;
00119     case CPL_TYPE_FLOAT:
00120         uves_propertylist_append_float(plist, cpl_property_get_name(p), cpl_property_get_float(p));
00121         break;
00122     case CPL_TYPE_DOUBLE:
00123         uves_propertylist_append_double(plist, cpl_property_get_name(p), cpl_property_get_double(p));
00124         break;
00125     case CPL_TYPE_STRING:
00126         uves_propertylist_append_string(plist, cpl_property_get_name(p), cpl_property_get_string(p));
00127         break;
00128     default:
00129         cpl_msg_error("Unknown property type: %s", uves_tostring_cpl_type(cpl_property_get_type(p)));
00130         cpl_error_set(__func__, CPL_ERROR_UNSUPPORTED_MODE);
00131         break;
00132     }
00133     /* This is constant time!! */
00134     cpl_property_set_comment(uves_propertylist_get(plist, uves_propertylist_get_size(plist) - 1),
00135                              cpl_property_get_comment(p));
00136     return;
00137 }
00138 
00139 static void
00140 propertylist_prepend_property_cpl(cpl_propertylist *plist, const cpl_property *p)
00141 {
00142     switch(cpl_property_get_type(p)) {
00143     case CPL_TYPE_CHAR:
00144         cpl_propertylist_prepend_char(plist, cpl_property_get_name(p), cpl_property_get_char(p));
00145         break;
00146     case CPL_TYPE_BOOL:
00147         cpl_propertylist_prepend_bool(plist, cpl_property_get_name(p), cpl_property_get_bool(p));
00148         break;
00149     case CPL_TYPE_INT:
00150         cpl_propertylist_prepend_int(plist, cpl_property_get_name(p), cpl_property_get_int(p));
00151         break;
00152     case CPL_TYPE_LONG:
00153         cpl_propertylist_prepend_long(plist, cpl_property_get_name(p), cpl_property_get_long(p));
00154         break;
00155     case CPL_TYPE_FLOAT:
00156         cpl_propertylist_prepend_float(plist, cpl_property_get_name(p), cpl_property_get_float(p));
00157         break;
00158     case CPL_TYPE_DOUBLE:
00159         cpl_propertylist_prepend_double(plist, cpl_property_get_name(p), cpl_property_get_double(p));
00160         break;
00161     case CPL_TYPE_STRING:
00162         cpl_propertylist_prepend_string(plist, cpl_property_get_name(p), cpl_property_get_string(p));
00163         break;
00164     default:
00165         cpl_msg_error("Unknown property type: %s", uves_tostring_cpl_type(cpl_property_get_type(p)));
00166         cpl_error_set(__func__, CPL_ERROR_UNSUPPORTED_MODE);
00167         break;
00168     }
00169     cpl_propertylist_set_comment(plist, cpl_property_get_name(p), cpl_property_get_comment(p));
00170     return;
00171 }
00172 
00173 static cpl_propertylist *
00174 uves_propertylist_to_cpl(const uves_propertylist *self)
00175 {
00176     cpl_propertylist *result;
00177     long i;
00178 
00179     if (self == NULL) {
00180         result = NULL;
00181     }
00182     else {
00183         result = cpl_propertylist_new();
00184         
00185         for (i = uves_propertylist_get_size(self)-1; i >= 0; i--) {
00186             propertylist_prepend_property_cpl(
00187                 result, 
00188                 uves_propertylist_get_const(self, i));
00189         }
00190     }
00191     return result;
00192 }
00193 
00194 static void
00195 uves_propertylist_from_cpl(uves_propertylist *self, const cpl_propertylist *list_cpl)
00196 {
00197     long N = cpl_propertylist_get_size(list_cpl); /* O(n) */
00198     cpl_propertylist *copy = cpl_propertylist_duplicate(list_cpl); /* O(n) */
00199     long i;
00200 
00201     assert( uves_propertylist_is_empty(self));
00202 
00203     for (i = 0; i < N; i++) {
00204         const cpl_property *p = cpl_propertylist_get(copy, 0); /* O(1) */
00205         propertylist_append_property(self, p); /* O(1) */
00206         cpl_propertylist_erase(copy, cpl_property_get_name(p)); /* O(1),
00207                                                                  erases only first match */
00208     }
00209     assert( cpl_propertylist_is_empty(copy));
00210     cpl_propertylist_delete(copy);
00211 
00212     return;
00213 }
00214 
00215 /* Wrappers for often used functions which have cpl_propertylists in their interface */
00216 cpl_error_code uves_vector_save(const cpl_vector *v, const char *f, cpl_type_bpp bpp,
00217                                 const uves_propertylist *header, unsigned mode)
00218 {
00219     cpl_propertylist *header_cpl = uves_propertylist_to_cpl(header);
00220     cpl_vector_save(v, f, bpp, header_cpl, mode);
00221     cpl_propertylist_delete(header_cpl);
00222 
00223     return cpl_error_get_code();
00224 }
00225 cpl_error_code 
00226 uves_image_save(const cpl_image *image, const char *f, cpl_type_bpp bpp,
00227                                const uves_propertylist *header, unsigned mode)
00228 {
00229   cpl_propertylist *header_cpl = NULL;
00230   check_nomsg(header_cpl=uves_propertylist_to_cpl(header));
00231   check_nomsg(cpl_image_save(image, f, bpp, header_cpl, mode));
00232  cleanup:
00233     cpl_propertylist_delete(header_cpl);
00234 
00235     return cpl_error_get_code();
00236 }
00237 cpl_error_code uves_imagelist_save(const cpl_imagelist *imagelist, const char *f, cpl_type_bpp bpp,
00238                                const uves_propertylist *header, unsigned mode)
00239 {
00240     cpl_propertylist *header_cpl = uves_propertylist_to_cpl(header);
00241     cpl_imagelist_save(imagelist, f, bpp, header_cpl, mode);
00242     cpl_propertylist_delete(header_cpl);
00243 
00244     return cpl_error_get_code();
00245 }
00246 cpl_error_code uves_table_save(const cpl_table *table, const uves_propertylist *header,
00247                                const uves_propertylist *ext_header, const char *filename,
00248                                unsigned mode)
00249 {
00250     cpl_propertylist *header_cpl = uves_propertylist_to_cpl(header);
00251     cpl_propertylist *ext_header_cpl = uves_propertylist_to_cpl(ext_header);
00252     cpl_table_save(table, header_cpl, ext_header_cpl, filename, mode);
00253     cpl_propertylist_delete(header_cpl);
00254     cpl_propertylist_delete(ext_header_cpl);
00255 
00256     return cpl_error_get_code();
00257 }
00258 
00259 cpl_error_code uves_dfs_setup_product_header(uves_propertylist *header,
00260                                              const cpl_frame *product_frame,
00261                                              const cpl_frameset *framelist,
00262                                              const cpl_parameterlist *parlist,
00263                                              const char *recid,
00264                                              const char *pipeline_id,
00265                                              const char *dictionary_id)
00266 {
00267     cpl_propertylist *header_cpl = uves_propertylist_to_cpl(header);
00268     cpl_dfs_setup_product_header(header_cpl,
00269                                  product_frame,
00270                                  framelist,
00271                                  parlist,
00272                                  recid,
00273                                  pipeline_id,
00274                                  dictionary_id);
00275 
00276     uves_propertylist_empty(header);
00277     uves_propertylist_from_cpl(header, header_cpl);
00278     cpl_propertylist_delete(header_cpl);
00279 
00280     return cpl_error_get_code();
00281 }
00282 
00283 cpl_error_code uves_table_sort(cpl_table *t, const uves_propertylist *list)
00284 {
00285     /* Just use this workaround ... */
00286     uves_table_sort_dfsxxxx(t, list);
00287     
00288     /* ... instead of this one */
00289 #if 0
00290     cpl_propertylist *list_cpl = uves_propertylist_to_cpl(list);
00291     cpl_table_sort(t, list_cpl);
00292     cpl_propertylist_delete(list_cpl);
00293 #endif    
00294     return cpl_error_get_code();
00295 }
00296 
00297 
00298 /*
00299  * Private methods
00300  */
00301 
00302 
00303 /* Workarounds for cpl_error_push/pop which are not exported */
00304 static cpl_error_code push_pop_error;
00305 
00306 static void error_push(void)
00307 {
00308     push_pop_error = cpl_error_get_code();
00309     /* Don't track location */
00310     cpl_error_reset();
00311     return;
00312 }
00313 static void error_pop(void)
00314 {
00315     if (push_pop_error != CPL_ERROR_NONE)
00316         {
00317             cpl_error_set(__func__, push_pop_error);
00318         }
00319     return;
00320 }
00321 
00322 
00323 
00324 
00325 
00326 
00327 
00328 
00329 inline static cxint
00330 _uves_propertylist_filter_regexp(cxcptr key, cxcptr filter)
00331 {
00332 
00333     const uves_regexp *_filter = (const uves_regexp *)filter;
00334 
00335     if (regexec(&_filter->re, key, (size_t)0, NULL, 0) == REG_NOMATCH)
00336         return _filter->invert == TRUE ? TRUE : FALSE;
00337 
00338     return _filter->invert == TRUE ? FALSE : TRUE;
00339 
00340 }
00341 
00342 
00343 inline static cxbool
00344 _uves_propertylist_compare(const cpl_property *property, const char *name)
00345 {
00346     const cxchar *key = cpl_property_get_name(property);
00347 
00348     return strcmp(key, name) == 0 ? TRUE : FALSE;
00349 
00350 }
00351 
00352 
00353 inline static cxbool
00354 _uves_propertylist_compare_start(const cpl_property *property,
00355                                 const char *part_name)
00356 {
00357 
00358     const cxchar *key = cpl_property_get_name(property);
00359 
00360     if (strstr(key, part_name) == key)
00361         return TRUE;
00362 
00363     return FALSE;
00364 
00365 }
00366 
00367 
00368 inline static cxbool
00369 _uves_propertylist_compare_regexp(const cpl_property *property, uves_regexp *re)
00370 {
00371 
00372     const cxchar *key = cpl_property_get_name(property);
00373 
00374     return _uves_propertylist_filter_regexp(key, re);
00375 
00376 }
00377 
00378 
00379 inline static uves_deque_iterator
00380 _uves_propertylist_find(const uves_propertylist *self, const char *name)
00381 {
00382 
00383     uves_deque_iterator first, last;
00384     cpl_property *p;
00385 
00386     first = uves_deque_begin(self->properties);
00387     last = uves_deque_end(self->properties);
00388 
00389     while (first != last) {
00390         p = uves_deque_get(self->properties, first);
00391 
00392         if (_uves_propertylist_compare(p, name))
00393             break;
00394 
00395         first = uves_deque_next(self->properties, first);
00396     }
00397 
00398     return first;
00399 
00400 }
00401 
00402 inline static cpl_property *
00403 _uves_propertylist_get(const uves_propertylist *self, const char *name)
00404 {
00405     uves_deque_iterator pos = _uves_propertylist_find(self, name);
00406 
00407     if (pos == uves_deque_end(self->properties))
00408         return NULL;
00409 
00410     return uves_deque_get(self->properties, pos);
00411 
00412 }
00413 
00414 
00415 inline static int
00416 _uves_propertylist_insert(uves_propertylist *self, const cxchar *where,
00417                          cxbool after, const cxchar *name, cpl_type type,
00418                          cxptr value)
00419 {
00420 
00421     uves_deque_iterator pos;
00422     cpl_property *property;
00423 
00424 
00425     /*
00426      * Find the position where value should be inserted.
00427      */
00428 
00429     pos = _uves_propertylist_find(self, where);
00430 
00431     if (pos == uves_deque_end(self->properties)) {
00432         return 1;
00433     }
00434 
00435     if (after) {
00436         pos = uves_deque_next(self->properties, pos);
00437     }
00438 
00439 
00440     /*
00441      * Create the property for value and fill it.
00442      */
00443 
00444     property = cpl_property_new(name, type);
00445     if (!property) {
00446         return 1;
00447     }
00448 
00449 
00450     /*
00451      * Map property type to the driver function's argument type.
00452      */
00453 
00454     switch (type) {
00455         case CPL_TYPE_CHAR:
00456             cpl_property_set_char(property, *((cxchar *)value));
00457             break;
00458 
00459         case CPL_TYPE_BOOL:
00460             cpl_property_set_bool(property, *((cxint *)value));
00461             break;
00462 
00463         case CPL_TYPE_INT:
00464             cpl_property_set_int(property, *((cxint *)value));
00465             break;
00466 
00467         case CPL_TYPE_LONG:
00468             cpl_property_set_long(property, *((cxlong *)value));
00469             break;
00470 
00471         case CPL_TYPE_FLOAT:
00472             cpl_property_set_float(property, *((cxfloat *)value));
00473             break;
00474 
00475         case CPL_TYPE_DOUBLE:
00476             cpl_property_set_double(property, *((cxdouble *)value));
00477             break;
00478 
00479         case CPL_TYPE_STRING:
00480             cpl_property_set_string(property, ((const cxchar *)value));
00481             break;
00482 
00483         default:
00484             return 1;
00485             break;
00486     }
00487 
00488 
00489     /*
00490      * Insert it into the list
00491      */
00492 
00493     uves_deque_insert(self->properties, pos, property);
00494 
00495     return 0;
00496 
00497 }
00498 
00499 
00500 /*
00501  * Parser for FITS cards. Returns 0 if the card was successfully parsed
00502  * into its components, 1 if the card should be ignored and a negative
00503  * number if an error occurred. If the parsing was successful the function
00504  * fills the buffers pointed to by key, value, comment and type.
00505  *
00506  * The buffers key, value and comment must, at least, have the size
00507  * FITS_LINESZ + 1!
00508  *
00509  * Errors:
00510  *  -1  Invalid pointer to the input FITS header.
00511  *  -2  Invalid keyword name detected (cf. qfits_header_getitem())
00512  */
00513 
00514 inline static cxint
00515 _uves_propertylist_decode_fits(const qfits_header *header, cxint i,
00516                               cxchar *key, cxint *type, cxchar *value,
00517                               cxchar *comment)
00518 {
00519 
00520     cxchar _key[FITS_LINESZ + 1];
00521     cxchar _value[FITS_LINESZ + 1];
00522     cxchar _comment[FITS_LINESZ + 1];
00523     cxchar *s;
00524 
00525     if (!header)
00526         return -1;
00527 
00528     /*
00529      * Get a FITS card, decode it into its components and determine
00530      * its type.
00531      */
00532 
00533     if (qfits_header_getitem((qfits_header *)header, i, _key, _value,
00534                              _comment, NULL) != 0) {
00535         return -2;
00536     }
00537 
00538 
00539     /*
00540      * Skip the END record. Qfits ignores empty header cards. Therefore
00541      * we do not need to take care of them here, but who knows.
00542      */
00543 
00544     s = _key;
00545 
00546     if (strncmp(s, "END", 3) == 0 || strncmp(s, "        ", 8) == 0 ||
00547         strlen(s) == 0) {
00548         return 1;
00549     }
00550 
00551 
00552     /*
00553      * strip the HIERARCH prefix from the keyword name if it
00554      * is present.
00555      */
00556 
00557     if (strncmp(s, "HIERARCH ", 9) == 0)
00558         s += 9;
00559 
00560     strncpy(key, s, FITS_LINESZ);
00561     key[FITS_LINESZ] = '\0';
00562 
00563 
00564     /*
00565      * Parse the value string and determine its type. Comment and
00566      * history records are forced to be strings. The type check
00567      * has to be done before cleaning the value, so that strings
00568      * like '1.0' are still recognized as such.
00569      */
00570 
00571     s = _value;
00572 
00573     if (strncmp(_key, "COMMENT", 7) == 0 || strncmp(_key, "HISTORY", 7) == 0) {
00574         *type = QFITS_STRING;
00575 
00576         /*
00577          * qfits returns an empty string if there is no value for a keyword
00578          */
00579 
00580         if (strlen(s) == 0) {
00581             value[0] = '\0';
00582         }
00583         else {
00584             strncpy(value, s, FITS_LINESZ);
00585         }
00586     }
00587     else {
00588         *type = qfits_get_type(s);
00589         strncpy(value, qfits_pretty_string(s), FITS_LINESZ);
00590         value[FITS_LINESZ] = '\0';
00591     }
00592 
00593 
00594     /*
00595      * Parse the comment
00596      */
00597 
00598     s = _comment;
00599 
00600     /*
00601      * qfits returns an empty string if there is no value for a keyword
00602      */
00603 
00604     if (strlen(s) == 0)
00605         comment[0] = '\0';
00606     else {
00607         strncpy(comment, s, FITS_LINESZ);
00608         comment[FITS_LINESZ] = '\0';
00609     }
00610 
00611     return 0;
00612 
00613 }
00614 
00615 
00616 /*
00617  * The function converts a FITS header to a property list ignoring
00618  * keywords for which _uves_propertylist_decode_fits() returns 1. If
00619  * parsing a FITS keyword fails the function returns the status from
00620  * _uves_propertylist_decode_fits(). If the type of a FITS keyword is not
00621  * supported -1 is returned.
00622  */
00623 
00624 inline static cxint
00625 _uves_propertylist_from_fits(uves_propertylist *self,
00626                             const qfits_header *header,
00627                             cx_compare_func filter,
00628                             cxcptr data)
00629 {
00630 
00631     register cxint i;
00632 
00633 
00634     cx_assert(self != NULL);
00635     cx_assert(header != NULL);
00636 
00637 
00638     /*
00639      * Build the property list from the header.
00640      */
00641 
00642     for (i = 0; i < header->n; i++) {
00643         register cxint status;
00644 
00645         cxint type;
00646         cxint ival;
00647 
00648         cxdouble dval;
00649 
00650         cxchar key[FITS_LINESZ + 1];
00651         cxchar value[FITS_LINESZ + 1];
00652         cxchar comment[FITS_LINESZ + 1];
00653 
00654         cpl_property *property;
00655 
00656 
00657         status = _uves_propertylist_decode_fits(header, i, key, &type,
00658                                                value, comment);
00659 
00660         if (status) {
00661             switch (status) {
00662             case 1:
00663                 continue;
00664                 break;
00665 
00666             default:
00667                 return status;
00668                 break;
00669             }
00670         }
00671 
00672 
00673         if (filter != NULL && filter(key, data) == FALSE) {
00674             continue;
00675         }
00676 
00677 
00678         /*
00679          * Create the property from the parsed FITS card.
00680          */
00681 
00682         switch (type) {
00683             case QFITS_BOOLEAN:
00684                 property = cpl_property_new(key, CPL_TYPE_BOOL);
00685 
00686                 ival = *value == 'T' ? 1 : 0;
00687                 cpl_property_set_bool(property, ival);
00688                 cpl_property_set_comment(property, comment);
00689                 break;
00690 
00691             case QFITS_INT:
00692                 property = cpl_property_new(key, CPL_TYPE_INT);
00693 
00694                 sscanf(value, "%d", &ival);
00695                 cpl_property_set_int(property, ival);
00696                 cpl_property_set_comment(property, comment);
00697                 break;
00698 
00699             case QFITS_FLOAT:
00700                 property = cpl_property_new(key, CPL_TYPE_DOUBLE);
00701 
00702                 sscanf(value, "%lf", &dval);
00703                 cpl_property_set_double(property, dval);
00704                 cpl_property_set_comment(property, comment);
00705                 break;
00706 
00707                 /* FIXME: qfits does not correctly report the type for
00708                  *        string values if the single quotes have been
00709                  *        stripped. In this case it reports QFITS_UNKNOWN
00710                  *        for the value's type. As a temporary (!) work
00711                  *        around we accept everything unknown as a string.
00712                  */
00713 
00714             case QFITS_UNKNOWN:
00715             case QFITS_STRING:
00716                 property = cpl_property_new(key, CPL_TYPE_STRING);
00717 
00718                 cpl_property_set_string(property, value);
00719                 cpl_property_set_comment(property, comment);
00720                 break;
00721 
00722             case QFITS_COMPLEX:
00723 
00724                 /* FIXME: Add support for complex keywords. */
00725 
00726             default:
00727                 return 1;
00728                 break;
00729         }
00730 
00731         uves_deque_push_back(self->properties, property);
00732     }
00733 
00734     return 0;
00735 
00736 }
00737 
00738 
00739 
00740 /*
00741  * Public methods
00742  */
00743 
00758 uves_propertylist *
00759 uves_propertylist_new(void)
00760 {
00761 
00762     uves_propertylist *self = cx_malloc(sizeof *self);
00763 
00764     self->properties = uves_deque_new();
00765     return self;
00766 
00767 }
00768 
00769 
00795 uves_propertylist *
00796 uves_propertylist_duplicate(const uves_propertylist *self)
00797 {
00798 
00799     const cxchar *const _id = "uves_propertylist_duplicate";
00800 
00801     uves_deque_iterator first, last;
00802 
00803     uves_propertylist *copy = NULL;
00804 
00805 
00806     if (self == NULL) {
00807         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
00808         return NULL;
00809     }
00810 
00811     cx_assert(self->properties != NULL);
00812 
00813 
00814     copy = uves_propertylist_new();
00815 
00816     first = uves_deque_begin(self->properties);
00817     last = uves_deque_end(self->properties);
00818 
00819     while (first != last) {
00820         cpl_property *tmp = uves_deque_get(self->properties, first);
00821 
00822         uves_deque_push_back(copy->properties, cpl_property_duplicate(tmp));
00823         first = uves_deque_next(self->properties, first);
00824     }
00825 
00826     return copy;
00827 
00828 }
00829 
00830 
00844 void
00845 uves_propertylist_delete(const uves_propertylist *self)
00846 {
00847 
00848     if (self) {
00849         uves_deque_destroy(self->properties, (cx_free_func)cpl_property_delete);
00850         cx_free((void *)self);
00851     }
00852 
00853     return;
00854 
00855 }
00856 
00857 
00884 long
00885 uves_propertylist_get_size(const uves_propertylist *self)
00886 {
00887 
00888     const cxchar *const _id = "uves_propertylist_get_size";
00889 
00890 
00891     if (self == NULL) {
00892         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
00893         return 0L;
00894     }
00895 
00896     return (long) uves_deque_size(self->properties);
00897 
00898 }
00899 
00900 
00926 int
00927 uves_propertylist_is_empty(const uves_propertylist *self)
00928 {
00929 
00930     const cxchar *const _id = "uves_propertylist_is_empty";
00931 
00932 
00933     if (self == NULL) {
00934         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
00935         return -1;
00936     }
00937 
00938     return uves_deque_empty(self->properties);
00939 
00940 }
00941 
00942 
00977 cpl_type
00978 uves_propertylist_get_type(const uves_propertylist *self, const char *name)
00979 {
00980 
00981     const cxchar *const _id = "uves_propertylist_get_type";
00982 
00983     cpl_property *property;
00984 
00985 
00986     if (self == NULL || name == NULL) {
00987         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
00988         return CPL_TYPE_INVALID;
00989     }
00990 
00991     property = _uves_propertylist_get(self, name);
00992 
00993     if (property == NULL) {
00994         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
00995         return CPL_TYPE_INVALID;
00996     }
00997 
00998     return cpl_property_get_type(property);
00999 
01000 }
01001 
01002 
01031 int
01032 uves_propertylist_contains(const uves_propertylist *self, const char *name)
01033 {
01034 
01035     const cxchar *const _id = "uves_propertylist_contains";
01036 
01037 
01038     if (self == NULL || name == NULL) {
01039         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01040         return 0;
01041     }
01042 
01043     return _uves_propertylist_get(self, name) != NULL ? 1 : 0;
01044 
01045 }
01046 
01047 
01085 cpl_error_code
01086 uves_propertylist_set_comment(uves_propertylist *self, const char *name,
01087                              const char *comment)
01088 {
01089 
01090     const cxchar *const _id = "uves_propertylist_set_comment";
01091 
01092     cpl_property *property;
01093 
01094 
01095     if (self == NULL || name == NULL) {
01096         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01097         return CPL_ERROR_NULL_INPUT;
01098     }
01099 
01100     property = _uves_propertylist_get(self, name);
01101 
01102     if (property == NULL) {
01103         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
01104         return CPL_ERROR_DATA_NOT_FOUND;
01105     }
01106 
01107     cpl_property_set_comment(property, comment);
01108 
01109     return CPL_ERROR_NONE;
01110 
01111 }
01112 
01113 
01150 cpl_error_code
01151 uves_propertylist_set_char(uves_propertylist *self, const char *name,
01152                           char value)
01153 {
01154 
01155     const cxchar *const _id = "uves_propertylist_set_char";
01156 
01157     cpl_property *property;
01158 
01159 
01160     if (self == NULL || name == NULL) {
01161         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01162         return CPL_ERROR_NULL_INPUT;
01163     }
01164 
01165     property = _uves_propertylist_get(self, name);
01166 
01167     if (property == NULL) {
01168         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
01169         return CPL_ERROR_DATA_NOT_FOUND;
01170     }
01171 
01172     return cpl_property_set_char(property, value);
01173 
01174 }
01175 
01176 
01213 cpl_error_code
01214 uves_propertylist_set_bool(uves_propertylist *self, const char *name, int value)
01215 {
01216 
01217     const cxchar *const _id = "uves_propertylist_set_bool";
01218 
01219     cpl_property *property;
01220 
01221 
01222     if (self == NULL || name == NULL) {
01223         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01224         return CPL_ERROR_NULL_INPUT;
01225     }
01226 
01227     property = _uves_propertylist_get(self, name);
01228 
01229     if (property == NULL) {
01230         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
01231         return CPL_ERROR_DATA_NOT_FOUND;
01232     }
01233 
01234     return cpl_property_set_bool(property, value);
01235 
01236 }
01237 
01238 
01275 cpl_error_code
01276 uves_propertylist_set_int(uves_propertylist *self, const char *name, int value)
01277 {
01278 
01279     const cxchar *const _id = "uves_propertylist_set_int";
01280 
01281     cpl_property *property;
01282 
01283 
01284     if (self == NULL || name == NULL) {
01285         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01286         return CPL_ERROR_NULL_INPUT;
01287     }
01288 
01289     property = _uves_propertylist_get(self, name);
01290 
01291     if (property == NULL) {
01292         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
01293         return CPL_ERROR_DATA_NOT_FOUND;
01294     }
01295 
01296     return cpl_property_set_int(property, value);
01297 
01298 }
01299 
01300 
01337 cpl_error_code
01338 uves_propertylist_set_long(uves_propertylist *self, const char *name,
01339                           long value)
01340 {
01341 
01342     const cxchar *const _id = "uves_propertylist_set_long";
01343 
01344     cpl_property *property;
01345 
01346 
01347     if (self == NULL || name == NULL) {
01348         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01349         return CPL_ERROR_NULL_INPUT;
01350     }
01351 
01352     property = _uves_propertylist_get(self, name);
01353 
01354     if (property == NULL) {
01355         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
01356         return CPL_ERROR_DATA_NOT_FOUND;
01357     }
01358 
01359     return cpl_property_set_long(property, value);
01360 
01361 }
01362 
01363 
01400 cpl_error_code
01401 uves_propertylist_set_float(uves_propertylist *self, const char *name,
01402                            float value)
01403 {
01404 
01405     const cxchar *const _id = "uves_propertylist_set_float";
01406 
01407     cpl_property *property;
01408 
01409 
01410     if (self == NULL || name == NULL) {
01411         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01412         return CPL_ERROR_NULL_INPUT;
01413     }
01414 
01415     property = _uves_propertylist_get(self, name);
01416 
01417     if (property == NULL) {
01418         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
01419         return CPL_ERROR_DATA_NOT_FOUND;
01420     }
01421 
01422     return cpl_property_set_float(property, value);
01423 
01424 }
01425 
01426 
01463 cpl_error_code
01464 uves_propertylist_set_double(uves_propertylist *self, const char *name,
01465                             double value)
01466 {
01467 
01468     const cxchar *const _id = "uves_propertylist_set_double";
01469 
01470     cpl_property *property;
01471 
01472 
01473     if (self == NULL || name == NULL) {
01474         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01475         return CPL_ERROR_NULL_INPUT;
01476     }
01477 
01478     property = _uves_propertylist_get(self, name);
01479 
01480     if (property == NULL) {
01481         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
01482         return CPL_ERROR_DATA_NOT_FOUND;
01483     }
01484 
01485     return cpl_property_set_double(property, value);
01486 
01487 }
01488 
01489 
01526 cpl_error_code
01527 uves_propertylist_set_string(uves_propertylist *self, const char *name,
01528                             const char *value)
01529 {
01530 
01531     const cxchar *const _id = "uves_propertylist_set_string";
01532 
01533     cpl_property *property;
01534 
01535 
01536     if (self == NULL || name == NULL) {
01537         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01538         return CPL_ERROR_NULL_INPUT;
01539     }
01540 
01541     property = _uves_propertylist_get(self, name);
01542 
01543     if (property == NULL) {
01544         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
01545         return CPL_ERROR_DATA_NOT_FOUND;
01546     }
01547 
01548     return cpl_property_set_string(property, value);
01549 
01550 }
01551 
01552 
01582 const cpl_property *
01583 uves_propertylist_get_const(const uves_propertylist *self, long position)
01584 {
01585 
01586     const cxchar *const _id = "uves_propertylist_get";
01587 
01588 //    register cxsize i = 0;
01589 
01590     uves_deque_iterator first, last;
01591 
01592 
01593     if (self == NULL) {
01594         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01595         return NULL;
01596     }
01597 
01598     if (position < 0) {
01599         return NULL;
01600     }
01601 
01602     first = uves_deque_begin(self->properties);
01603     last = uves_deque_end(self->properties);
01604 
01605 //    while (i < (cxsize)position && first != last) {
01606 //        first = uves_deque_next(self->properties, first);
01607 //        i++;
01608 //    }
01609 
01610     if (first == last) {
01611         return NULL;
01612     }
01613 
01614 //    return uves_deque_get(self->properties, first);
01615     return uves_deque_get(self->properties, position);
01616 
01617 }
01618 
01619 cpl_property *
01620 uves_propertylist_get(uves_propertylist *self, long position)
01621 {
01622     return (cpl_property *)uves_propertylist_get_const(self, position);
01623 }
01624 
01625 
01661 const char *
01662 uves_propertylist_get_comment(const uves_propertylist *self, const char *name)
01663 {
01664 
01665     const cxchar *const _id = "uves_propertylist_get_comment";
01666 
01667     cpl_property *property;
01668 
01669 
01670     if (self == NULL || name == NULL) {
01671         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01672         return NULL;
01673     }
01674 
01675     property = _uves_propertylist_get(self, name);
01676 
01677     if (!property) {
01678         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
01679         return NULL;
01680     }
01681 
01682     return cpl_property_get_comment(property);
01683 
01684 }
01685 
01686 
01728 char
01729 uves_propertylist_get_char(const uves_propertylist *self, const char *name)
01730 {
01731 
01732     const cxchar *const _id = "uves_propertylist_get_char";
01733 
01734     cxchar result;
01735 
01736     cpl_property *property;
01737 
01738 
01739     if (self == NULL || name == NULL) {
01740         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01741         return '\0';
01742     }
01743 
01744     property = _uves_propertylist_get(self, name);
01745 
01746     if (!property) {
01747         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
01748         return '\0';
01749     }
01750 
01751     error_push();
01752 //jmlarsen: this is not exported    cpl_error_push();
01753 
01754     result = cpl_property_get_char(property);
01755 
01756     /*
01757      * If an error occurred change any possibly set location to this
01758      * function.
01759      */
01760 
01761     if (cpl_error_get_code() != CPL_ERROR_NONE) {
01762         cpl_error_set_where(_id);
01763         return '\0';
01764     }
01765 
01766 //jmlarsen: this is not exported    cpl_error_pop();
01767     error_pop();
01768 
01769     return result;
01770 
01771 }
01772 
01773 
01817 int
01818 uves_propertylist_get_bool(const uves_propertylist *self, const char *name)
01819 {
01820 
01821     const cxchar *const _id = "uves_propertylist_get_bool";
01822 
01823     cxbool result;
01824 
01825     cpl_property *property;
01826 
01827 
01828     if (self == NULL || name == NULL) {
01829         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01830         return 0;
01831     }
01832 
01833     property = _uves_propertylist_get(self, name);
01834 
01835     if (!property) {
01836         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
01837         return 0;
01838     }
01839 
01840     error_push();
01841 //jmlarsen: this is not exported    cpl_error_push();
01842 
01843     result = cpl_property_get_bool(property);
01844 
01845     /*
01846      * If an error occurred change any possibly set location to this
01847      * function.
01848      */
01849 
01850     if (cpl_error_get_code() != CPL_ERROR_NONE) {
01851         cpl_error_set_where(_id);
01852         return 0;
01853     }
01854 
01855 //jmlarsen: this is not exported    cpl_error_pop();
01856     error_pop();
01857 
01858     return result == TRUE ? 1 : 0;
01859 
01860 }
01861 
01862 
01904 int
01905 uves_propertylist_get_int(const uves_propertylist *self, const char *name)
01906 {
01907 
01908     const cxchar *const _id = "uves_propertylist_get_int";
01909 
01910     cxint result;
01911 
01912     cpl_property *property;
01913 
01914 
01915     if (self == NULL || name == NULL) {
01916         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01917         return 0;
01918     }
01919 
01920     property = _uves_propertylist_get(self, name);
01921 
01922     if (!property) {
01923         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
01924         return 0;
01925     }
01926 
01927     error_push();
01928 //jmlarsen: this is not exported    cpl_error_push();
01929 
01930     result = cpl_property_get_int(property);
01931 
01932     /*
01933      * If an error occurred change any possibly set location to this
01934      * function.
01935      */
01936 
01937     if (cpl_error_get_code() != CPL_ERROR_NONE) {
01938         cpl_error_set_where(_id);
01939         return 0;
01940     }
01941 
01942 //jmlarsen: this is not exported    cpl_error_pop();
01943     error_pop();
01944 
01945     return result;
01946 
01947 }
01948 
01949 
01991 long
01992 uves_propertylist_get_long(const uves_propertylist *self, const char *name)
01993 {
01994 
01995     const cxchar *const _id = "uves_propertylist_get_long";
01996 
01997     cxlong result;
01998 
01999     cpl_property *property;
02000 
02001 
02002     if (self == NULL || name == NULL) {
02003         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02004         return 0;
02005     }
02006 
02007     property = _uves_propertylist_get(self, name);
02008 
02009     if (!property) {
02010         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
02011         return 0;
02012     }
02013 
02014     error_push();
02015 //jmlarsen: this is not exported    cpl_error_push();
02016 
02017     result = cpl_property_get_long(property);
02018 
02019     /*
02020      * If an error occurred change any possibly set location to this
02021      * function.
02022      */
02023 
02024     if (cpl_error_get_code() != CPL_ERROR_NONE) {
02025         cpl_error_set_where(_id);
02026         return 0;
02027     }
02028 
02029 //jmlarsen: this is not exported    cpl_error_pop();
02030     error_pop();
02031 
02032     return result;
02033 
02034 }
02035 
02036 
02078 float
02079 uves_propertylist_get_float(const uves_propertylist *self, const char *name)
02080 {
02081 
02082     const cxchar *const _id = "uves_propertylist_get_float";
02083 
02084     cxfloat result;
02085 
02086     cpl_property *property;
02087 
02088 
02089     if (self == NULL || name == NULL) {
02090         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02091         return 0;
02092     }
02093 
02094     property = _uves_propertylist_get(self, name);
02095 
02096     if (!property) {
02097         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
02098         return 0;
02099     }
02100 
02101     error_push();
02102 //jmlarsen: this is not exported    cpl_error_push();
02103 
02104     result = cpl_property_get_float(property);
02105 
02106     /*
02107      * If an error occurred change any possibly set location to this
02108      * function.
02109      */
02110 
02111     if (cpl_error_get_code() != CPL_ERROR_NONE) {
02112         cpl_error_set_where(_id);
02113         return 0;
02114     }
02115 
02116 //jmlarsen: this is not exported    cpl_error_pop();
02117     error_pop();
02118 
02119     return result;
02120 
02121 }
02122 
02123 
02165 double
02166 uves_propertylist_get_double(const uves_propertylist *self, const char *name)
02167 {
02168 
02169     const cxchar *const _id = "uves_propertylist_get_double";
02170 
02171     cxdouble result;
02172 
02173     cpl_property *property;
02174 
02175 
02176     if (self == NULL || name == NULL) {
02177         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02178         return 0;
02179     }
02180 
02181     property = _uves_propertylist_get(self, name);
02182 
02183     if (!property) {
02184         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
02185         return 0;
02186     }
02187 
02188     error_push();
02189 //jmlarsen: this is not exported    cpl_error_push();
02190 
02191     result = cpl_property_get_double(property);
02192 
02193     /*
02194      * If an error occurred change any possibly set location to this
02195      * function.
02196      */
02197 
02198     if (cpl_error_get_code() != CPL_ERROR_NONE) {
02199         cpl_error_set_where(_id);
02200         return 0;
02201     }
02202 
02203 //jmlarsen: this is not exported    cpl_error_pop();
02204     error_pop();
02205 
02206     return result;
02207 
02208 }
02209 
02210 
02254 const char *
02255 uves_propertylist_get_string(const uves_propertylist *self, const char *name)
02256 {
02257 
02258     const cxchar *const _id = "uves_propertylist_get_string";
02259 
02260     const cxchar *result;
02261 
02262     cpl_property *property;
02263 
02264 
02265     if (self == NULL || name == NULL) {
02266         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02267         return NULL;
02268     }
02269 
02270     property = _uves_propertylist_get(self, name);
02271 
02272     if (!property) {
02273         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
02274         return NULL;
02275     }
02276 
02277     error_push();
02278 //jmlarsen: this is not exported    cpl_error_push();
02279 
02280     result = cpl_property_get_string(property);
02281 
02282     /*
02283      * If an error occurred change any possibly set location to this
02284      * function.
02285      */
02286 
02287     if (cpl_error_get_code() != CPL_ERROR_NONE) {
02288         cpl_error_set_where(_id);
02289         return NULL;
02290     }
02291 
02292 //jmlarsen: this is not exported    cpl_error_pop();
02293     error_pop();
02294 
02295     return result;
02296 
02297 }
02298 
02299 
02337 cpl_error_code
02338 uves_propertylist_insert_char(uves_propertylist *self, const char *here,
02339                              const char *name, char value)
02340 {
02341 
02342     const cxchar *const _id = "uves_propertylist_insert_char";
02343 
02344     cxint status = 0;
02345 
02346 
02347     if (self == NULL || here == NULL || name == NULL) {
02348         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02349         return CPL_ERROR_NULL_INPUT;
02350     }
02351 
02352     status = _uves_propertylist_insert(self, here, FALSE, name,
02353                                       CPL_TYPE_CHAR, &value);
02354 
02355     if (status) {
02356         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
02357         return CPL_ERROR_UNSPECIFIED;
02358     }
02359 
02360     return CPL_ERROR_NONE;
02361 
02362 }
02363 
02364 
02402 cpl_error_code
02403 uves_propertylist_insert_bool(uves_propertylist *self, const char *here,
02404                              const char *name, int value)
02405 {
02406 
02407     const cxchar *const _id = "uves_propertylist_insert_bool";
02408 
02409     cxint status = 0;
02410 
02411 
02412     if (self == NULL || here == NULL || name == NULL) {
02413         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02414         return CPL_ERROR_NULL_INPUT;
02415     }
02416 
02417     status =  _uves_propertylist_insert(self, here, FALSE, name,
02418                                        CPL_TYPE_BOOL, &value);
02419 
02420     if (status) {
02421         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
02422         return CPL_ERROR_UNSPECIFIED;
02423     }
02424 
02425     return CPL_ERROR_NONE;
02426 
02427 }
02428 
02429 
02467 cpl_error_code
02468 uves_propertylist_insert_int(uves_propertylist *self, const char *here,
02469                             const char *name, int value)
02470 {
02471 
02472     const cxchar *const _id = "uves_propertylist_insert_int";
02473 
02474     cxint status = 0;
02475 
02476 
02477     if (self == NULL || here == NULL || name == NULL) {
02478         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02479         return CPL_ERROR_NULL_INPUT;
02480     }
02481 
02482     status = _uves_propertylist_insert(self, here, FALSE, name,
02483                                       CPL_TYPE_INT, &value);
02484 
02485     if (status) {
02486         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
02487         return CPL_ERROR_UNSPECIFIED;
02488     }
02489 
02490     return CPL_ERROR_NONE;
02491 
02492 }
02521 int
02522 uves_propertylist_has(const uves_propertylist *self, const char *name)
02523 {
02524 
02525     const cxchar *const _id = "cpl_propertylist_has";
02526 
02527 
02528     if (self == NULL || name == NULL) {
02529         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02530         return 0;
02531     }
02532 
02533     return _uves_propertylist_get(self, name) != NULL ? 1 : 0;
02534 
02535 }
02536 
02537 
02575 cpl_error_code
02576 uves_propertylist_insert_long(uves_propertylist *self, const char *here,
02577                              const char *name, long value)
02578 {
02579 
02580     const cxchar *const _id = "uves_propertylist_insert_long";
02581 
02582     cxint status = 0;
02583 
02584 
02585     if (self == NULL || here == NULL || name == NULL) {
02586         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02587         return CPL_ERROR_NULL_INPUT;
02588     }
02589 
02590     status = _uves_propertylist_insert(self, here, FALSE, name,
02591                                       CPL_TYPE_LONG, &value);
02592 
02593     if (status) {
02594         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
02595         return CPL_ERROR_UNSPECIFIED;
02596     }
02597 
02598     return CPL_ERROR_NONE;
02599 
02600 }
02601 
02602 
02640 cpl_error_code
02641 uves_propertylist_insert_float(uves_propertylist *self, const char *here,
02642                               const char *name, float value)
02643 {
02644 
02645     const cxchar *const _id = "uves_propertylist_insert_float";
02646 
02647     cxint status = 0;
02648 
02649 
02650     if (self == NULL || here == NULL || name == NULL) {
02651         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02652         return CPL_ERROR_NULL_INPUT;
02653     }
02654 
02655     status = _uves_propertylist_insert(self, here, FALSE, name,
02656                                       CPL_TYPE_FLOAT, &value);
02657 
02658     if (status) {
02659         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
02660         return CPL_ERROR_UNSPECIFIED;
02661     }
02662 
02663     return CPL_ERROR_NONE;
02664 
02665 }
02666 
02667 
02705 cpl_error_code
02706 uves_propertylist_insert_double(uves_propertylist *self, const char *here,
02707                                const char *name, double value)
02708 {
02709 
02710     const cxchar *const _id = "uves_propertylist_insert_char";
02711 
02712     cxint status = 0;
02713 
02714 
02715     if (self == NULL || here == NULL || name == NULL) {
02716         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02717         return CPL_ERROR_NULL_INPUT;
02718     }
02719 
02720     status = _uves_propertylist_insert(self, here, FALSE, name,
02721                                       CPL_TYPE_DOUBLE, &value);
02722 
02723     if (status) {
02724         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
02725         return CPL_ERROR_UNSPECIFIED;
02726     }
02727 
02728     return CPL_ERROR_NONE;
02729 
02730 }
02731 
02732 
02770 cpl_error_code
02771 uves_propertylist_insert_string(uves_propertylist *self, const char *here,
02772                                const char *name, const char *value)
02773 {
02774 
02775     const cxchar *const _id = "uves_propertylist_insert_string";
02776 
02777     cxint status = 0;
02778 
02779 
02780     if (self == NULL || here == NULL || name == NULL) {
02781         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02782         return CPL_ERROR_NULL_INPUT;
02783     }
02784 
02785     status = _uves_propertylist_insert(self, here, FALSE, name,
02786                                       CPL_TYPE_STRING, (cxptr)value);
02787 
02788     if (status) {
02789         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
02790         return CPL_ERROR_UNSPECIFIED;
02791     }
02792 
02793     return CPL_ERROR_NONE;
02794 
02795 }
02796 
02797 
02835 cpl_error_code
02836 uves_propertylist_insert_after_char(uves_propertylist *self, const char *after,
02837                                    const char *name, char value)
02838 {
02839 
02840     const cxchar *const _id = "uves_propertylist_insert_after_char";
02841 
02842     cxint status = 0;
02843 
02844 
02845     if (self == NULL || after == NULL || name == NULL) {
02846         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02847         return CPL_ERROR_NULL_INPUT;
02848     }
02849 
02850     status = _uves_propertylist_insert(self, after, TRUE, name,
02851                                       CPL_TYPE_CHAR, &value);
02852 
02853     if (status) {
02854         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
02855         return CPL_ERROR_UNSPECIFIED;
02856     }
02857 
02858     return CPL_ERROR_NONE;
02859 
02860 }
02861 
02862 
02900 cpl_error_code
02901 uves_propertylist_insert_after_bool(uves_propertylist *self, const char *after,
02902                                    const char *name, int value)
02903 {
02904 
02905     const cxchar *const _id = "uves_propertylist_insert_after_bool";
02906 
02907     cxint status = 0;
02908 
02909 
02910     if (self == NULL || after == NULL || name == NULL) {
02911         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02912         return CPL_ERROR_NULL_INPUT;
02913     }
02914 
02915     status = _uves_propertylist_insert(self, after, TRUE, name,
02916                                       CPL_TYPE_BOOL, &value);
02917 
02918     if (status) {
02919         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
02920         return CPL_ERROR_UNSPECIFIED;
02921     }
02922 
02923     return CPL_ERROR_NONE;
02924 
02925 }
02926 
02927 
02965 cpl_error_code
02966 uves_propertylist_insert_after_int(uves_propertylist *self, const char *after,
02967                                   const char *name, int value)
02968 {
02969 
02970     const cxchar *const _id = "uves_propertylist_insert_after_int";
02971 
02972     cxint status = 0;
02973 
02974 
02975     if (self == NULL || after == NULL || name == NULL) {
02976         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02977         return CPL_ERROR_NULL_INPUT;
02978     }
02979 
02980     status = _uves_propertylist_insert(self, after, TRUE, name,
02981                                       CPL_TYPE_INT, &value);
02982 
02983     if (status) {
02984         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
02985         return CPL_ERROR_UNSPECIFIED;
02986     }
02987 
02988     return CPL_ERROR_NONE;
02989 
02990 }
02991 
02992 
03030 cpl_error_code
03031 uves_propertylist_insert_after_long(uves_propertylist *self, const char *after,
03032                                    const char *name, long value)
03033 {
03034 
03035     const cxchar *const _id = "uves_propertylist_insert_after_long";
03036 
03037     cxint status = 0;
03038 
03039 
03040     if (self == NULL || after == NULL || name == NULL) {
03041         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03042         return CPL_ERROR_NULL_INPUT;
03043     }
03044 
03045     status = _uves_propertylist_insert(self, after, TRUE, name,
03046                                       CPL_TYPE_LONG, &value);
03047 
03048     if (status) {
03049         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
03050         return CPL_ERROR_UNSPECIFIED;
03051     }
03052 
03053     return CPL_ERROR_NONE;
03054 
03055 }
03056 
03057 
03095 cpl_error_code
03096 uves_propertylist_insert_after_float(uves_propertylist *self, const char *after,
03097                                     const char *name, float value)
03098 {
03099 
03100     const cxchar *const _id = "uves_propertylist_insert_after_float";
03101 
03102     cxint status = 0;
03103 
03104 
03105     if (self == NULL || after == NULL || name == NULL) {
03106         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03107         return CPL_ERROR_NULL_INPUT;
03108     }
03109 
03110     status = _uves_propertylist_insert(self, after, TRUE, name,
03111                                       CPL_TYPE_FLOAT, &value);
03112 
03113     if (status) {
03114         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
03115         return CPL_ERROR_UNSPECIFIED;
03116     }
03117 
03118     return CPL_ERROR_NONE;
03119 
03120 }
03121 
03122 
03160 cpl_error_code
03161 uves_propertylist_insert_after_double(uves_propertylist *self,
03162                                      const char *after, const char *name,
03163                                      double value)
03164 {
03165 
03166     const cxchar *const _id = "uves_propertylist_insert_after_double";
03167 
03168     cxint status = 0;
03169 
03170 
03171     if (self == NULL || after == NULL || name == NULL) {
03172         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03173         return CPL_ERROR_NULL_INPUT;
03174     }
03175 
03176     status = _uves_propertylist_insert(self, after, TRUE, name,
03177                                       CPL_TYPE_DOUBLE, &value);
03178 
03179     if (status) {
03180         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
03181         return CPL_ERROR_UNSPECIFIED;
03182     }
03183 
03184     return CPL_ERROR_NONE;
03185 
03186 }
03187 
03188 
03226 cpl_error_code
03227 uves_propertylist_insert_after_string(uves_propertylist *self,
03228                                      const char *after, const char *name,
03229                                      const char *value)
03230 {
03231 
03232     const cxchar *const _id = "uves_propertylist_insert_after_string";
03233 
03234     cxint status = 0;
03235 
03236 
03237     if (self == NULL || after == NULL || name == NULL) {
03238         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03239         return CPL_ERROR_NULL_INPUT;
03240     }
03241 
03242     status =  _uves_propertylist_insert(self, after, TRUE, name,
03243                                        CPL_TYPE_STRING, (cxptr)value);
03244 
03245     if (status) {
03246         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
03247         return CPL_ERROR_UNSPECIFIED;
03248     }
03249 
03250     return CPL_ERROR_NONE;
03251 
03252 }
03253 
03254 
03283 cpl_error_code
03284 uves_propertylist_prepend_char(uves_propertylist *self, const char *name,
03285                               char value)
03286 {
03287 
03288     const cxchar *const _id = "uves_propertylist_prepend_char";
03289 
03290     cpl_property *property = NULL;
03291 
03292 
03293     if (self == NULL || name == NULL) {
03294         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03295         return CPL_ERROR_NULL_INPUT;
03296     }
03297 
03298     property = cpl_property_new(name, CPL_TYPE_CHAR);
03299     cx_assert(property != NULL);
03300 
03301     cpl_property_set_char(property, value);
03302     uves_deque_push_front(self->properties, property);
03303 
03304     return CPL_ERROR_NONE;
03305 
03306 }
03307 
03308 
03337 cpl_error_code
03338 uves_propertylist_prepend_bool(uves_propertylist *self, const char *name,
03339                               int value)
03340 {
03341 
03342     const cxchar *const _id = "uves_propertylist_prepend_bool";
03343 
03344     cpl_property *property = NULL;
03345 
03346 
03347     if (self == NULL || name == NULL) {
03348         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03349         return CPL_ERROR_NULL_INPUT;
03350     }
03351 
03352     property = cpl_property_new(name, CPL_TYPE_BOOL);
03353     cx_assert(property != NULL);
03354 
03355     cpl_property_set_bool(property, value);
03356     uves_deque_push_front(self->properties, property);
03357 
03358     return CPL_ERROR_NONE;
03359 
03360 }
03361 
03362 
03391 cpl_error_code
03392 uves_propertylist_prepend_int(uves_propertylist *self, const char *name,
03393                              int value)
03394 {
03395 
03396     const cxchar *const _id = "uves_propertylist_prepend_int";
03397 
03398     cpl_property *property = NULL;
03399 
03400 
03401     if (self == NULL || name == NULL) {
03402         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03403         return CPL_ERROR_NULL_INPUT;
03404     }
03405 
03406     property = cpl_property_new(name, CPL_TYPE_INT);
03407     cx_assert(property != NULL);
03408 
03409     cpl_property_set_int(property, value);
03410     uves_deque_push_front(self->properties, property);
03411 
03412     return CPL_ERROR_NONE;
03413 
03414 }
03415 
03416 
03445 cpl_error_code
03446 uves_propertylist_prepend_long(uves_propertylist *self, const char *name,
03447                               long value)
03448 {
03449 
03450     const cxchar *const _id = "uves_propertylist_prepend_long";
03451 
03452     cpl_property *property = NULL;
03453 
03454 
03455     if (self == NULL || name == NULL) {
03456         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03457         return CPL_ERROR_NULL_INPUT;
03458     }
03459 
03460     property = cpl_property_new(name, CPL_TYPE_LONG);
03461     cx_assert(property != NULL);
03462 
03463     cpl_property_set_long(property, value);
03464     uves_deque_push_front(self->properties, property);
03465 
03466     return CPL_ERROR_NONE;
03467 
03468 }
03469 
03470 
03499 cpl_error_code
03500 uves_propertylist_prepend_float(uves_propertylist *self, const char *name,
03501                                float value)
03502 {
03503 
03504     const cxchar *const _id = "uves_propertylist_prepend_float";
03505 
03506     cpl_property *property = NULL;
03507 
03508 
03509     if (self == NULL || name == NULL) {
03510         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03511         return CPL_ERROR_NULL_INPUT;
03512     }
03513 
03514     property = cpl_property_new(name, CPL_TYPE_FLOAT);
03515     cx_assert(property != NULL);
03516 
03517     cpl_property_set_float(property, value);
03518     uves_deque_push_front(self->properties, property);
03519 
03520     return CPL_ERROR_NONE;
03521 
03522 }
03523 
03524 
03553 cpl_error_code
03554 uves_propertylist_prepend_double(uves_propertylist *self, const char *name,
03555                                 double value)
03556 {
03557 
03558     const cxchar *const _id = "uves_propertylist_prepend_double";
03559 
03560     cpl_property *property = NULL;
03561 
03562 
03563     if (self == NULL || name == NULL) {
03564         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03565         return CPL_ERROR_NULL_INPUT;
03566     }
03567 
03568     property = cpl_property_new(name, CPL_TYPE_DOUBLE);
03569     cx_assert(property != NULL);
03570 
03571     cpl_property_set_double(property, value);
03572     uves_deque_push_front(self->properties, property);
03573 
03574     return CPL_ERROR_NONE;
03575 
03576 }
03577 
03578 
03607 cpl_error_code
03608 uves_propertylist_prepend_string(uves_propertylist *self, const char *name,
03609                                 const char *value)
03610 {
03611 
03612     const cxchar *const _id = "uves_propertylist_prepend_string";
03613 
03614     cpl_property *property = NULL;
03615 
03616 
03617     if (self == NULL || name == NULL) {
03618         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03619         return CPL_ERROR_NULL_INPUT;
03620     }
03621 
03622     property = cpl_property_new(name, CPL_TYPE_STRING);
03623     cx_assert(property != NULL);
03624 
03625     cpl_property_set_string(property, value);
03626     uves_deque_push_front(self->properties, property);
03627 
03628     return CPL_ERROR_NONE;
03629 
03630 }
03631 
03632 
03633 
03634 cpl_error_code
03635 uves_propertylist_append_char(uves_propertylist *self, const char *name,
03636                              char value)
03637 {
03638     return uves_propertylist_append_c_char(self, name, value, NULL);
03639 }
03640 cpl_error_code
03641 uves_propertylist_append_bool(uves_propertylist *self, const char *name,
03642                              int value)
03643 {
03644     return uves_propertylist_append_c_bool(self, name, value, NULL);
03645 }
03646 
03647 cpl_error_code
03648 uves_propertylist_append_int(uves_propertylist *self, const char *name,
03649                             int value)
03650 {
03651     return uves_propertylist_append_c_int(self, name, value, NULL);
03652 }
03653 
03654 cpl_error_code
03655 uves_propertylist_append_long(uves_propertylist *self, const char *name,
03656                              long value)
03657 {
03658     return uves_propertylist_append_c_long(self, name, value, NULL);
03659 }
03660 
03661 cpl_error_code
03662 uves_propertylist_append_float(uves_propertylist *self, const char *name,
03663                               float value)
03664 {
03665     return uves_propertylist_append_c_float(self, name, value, NULL);
03666 }
03667 
03668 cpl_error_code
03669 uves_propertylist_append_double(uves_propertylist *self, const char *name,
03670                                double value)
03671 {
03672     return uves_propertylist_append_c_double(self, name, value, NULL);
03673 }
03674 
03675 cpl_error_code
03676 uves_propertylist_append_string(uves_propertylist *self, const char *name,
03677                                const char *value)
03678 {
03679     return uves_propertylist_append_c_string(self, name, value, NULL);
03680 }
03681 
03682 
03683 
03684 
03685 
03686 
03687 
03688 
03689 
03690 
03691 
03692 
03693 
03694 
03695 
03696 
03697 
03698 
03727 cpl_error_code
03728 uves_propertylist_append_c_char(uves_propertylist *self, const char *name,
03729                              char value, const char *comment)
03730 {
03731 
03732     const cxchar *const _id = "uves_propertylist_append_char";
03733 
03734     cpl_property *property = NULL;
03735 
03736 
03737     if (self == NULL || name == NULL) {
03738         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03739         return CPL_ERROR_NULL_INPUT;
03740     }
03741 
03742     property = cpl_property_new(name, CPL_TYPE_CHAR);
03743     cx_assert(property != NULL);
03744 
03745     if (comment != NULL) cpl_property_set_comment(property, comment);
03746 
03747     cpl_property_set_char(property, value);
03748     uves_deque_push_back(self->properties, property);
03749 
03750     return CPL_ERROR_NONE;
03751 
03752 }
03753 
03754 
03783 cpl_error_code
03784 uves_propertylist_append_c_bool(uves_propertylist *self, const char *name,
03785                              int value, const char *comment)
03786 {
03787 
03788     const cxchar *const _id = "uves_propertylist_append_bool";
03789 
03790     cpl_property *property = NULL;
03791 
03792 
03793     if (self == NULL || name == NULL) {
03794         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03795         return CPL_ERROR_NULL_INPUT;
03796     }
03797 
03798     property = cpl_property_new(name, CPL_TYPE_BOOL);
03799     cx_assert(property != NULL);
03800 
03801     if (comment != NULL) cpl_property_set_comment(property, comment);
03802 
03803     cpl_property_set_bool(property, value);
03804     uves_deque_push_back(self->properties, property);
03805 
03806     return CPL_ERROR_NONE;
03807 
03808 }
03809 
03810 
03839 cpl_error_code
03840 uves_propertylist_append_c_int(uves_propertylist *self, const char *name,
03841                             int value, const char *comment)
03842 {
03843 
03844     const cxchar *const _id = "uves_propertylist_append_int";
03845 
03846     cpl_property *property = NULL;
03847 
03848 
03849     if (self == NULL || name == NULL) {
03850         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03851         return CPL_ERROR_NULL_INPUT;
03852     }
03853 
03854     property = cpl_property_new(name, CPL_TYPE_INT);
03855     cx_assert(property != NULL);
03856 
03857     if (comment != NULL) cpl_property_set_comment(property, comment);
03858 
03859     cpl_property_set_int(property, value);
03860     uves_deque_push_back(self->properties, property);
03861 
03862     return CPL_ERROR_NONE;
03863 
03864 }
03865 
03866 
03895 cpl_error_code
03896 uves_propertylist_append_c_long(uves_propertylist *self, const char *name,
03897                              long value, const char *comment)
03898 {
03899 
03900     const cxchar *const _id = "uves_propertylist_append_long";
03901 
03902     cpl_property *property = NULL;
03903 
03904 
03905     if (self == NULL || name == NULL) {
03906         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03907         return CPL_ERROR_NULL_INPUT;
03908     }
03909 
03910     property = cpl_property_new(name, CPL_TYPE_LONG);
03911     cx_assert(property != NULL);
03912 
03913     if (comment != NULL) cpl_property_set_comment(property, comment);
03914 
03915     cpl_property_set_long(property, value);
03916     uves_deque_push_back(self->properties, property);
03917 
03918     return CPL_ERROR_NONE;
03919 
03920 }
03921 
03922 
03951 cpl_error_code
03952 uves_propertylist_append_c_float(uves_propertylist *self, const char *name,
03953                               float value, const char *comment)
03954 {
03955 
03956     const cxchar *const _id = "uves_propertylist_append_float";
03957 
03958     cpl_property *property = NULL;
03959 
03960 
03961     if (self == NULL || name == NULL) {
03962         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03963         return CPL_ERROR_NULL_INPUT;
03964     }
03965 
03966     property = cpl_property_new(name, CPL_TYPE_FLOAT);
03967     cx_assert(property != NULL);
03968 
03969     if (comment != NULL) cpl_property_set_comment(property, comment);
03970 
03971     cpl_property_set_float(property, value);
03972     uves_deque_push_back(self->properties, property);
03973 
03974     return CPL_ERROR_NONE;
03975 
03976 }
03977 
03978 
04007 cpl_error_code
04008 uves_propertylist_append_c_double(uves_propertylist *self, const char *name,
04009                                double value, const char *comment)
04010 {
04011 
04012     const cxchar *const _id = "uves_propertylist_append_double";
04013 
04014     cpl_property *property = NULL;
04015 
04016 
04017     if (self == NULL || name == NULL) {
04018         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
04019         return CPL_ERROR_NULL_INPUT;
04020     }
04021 
04022     property = cpl_property_new(name, CPL_TYPE_DOUBLE);
04023     cx_assert(property != NULL);
04024 
04025     if (comment != NULL) cpl_property_set_comment(property, comment);
04026 
04027     cpl_property_set_double(property, value);
04028     uves_deque_push_back(self->properties, property);
04029 
04030     return CPL_ERROR_NONE;
04031 
04032 }
04033 
04034 
04063 cpl_error_code
04064 uves_propertylist_append_c_string(uves_propertylist *self, const char *name,
04065                                const char *value, const char *comment)
04066 {
04067 
04068     const cxchar *const _id = "uves_propertylist_append_string";
04069 
04070     cpl_property *property = NULL;
04071 
04072 
04073     if (self == NULL || name == NULL) {
04074         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
04075         return CPL_ERROR_NULL_INPUT;
04076     }
04077 
04078     property = cpl_property_new(name, CPL_TYPE_STRING);
04079     cx_assert(property != NULL);
04080 
04081     if (comment != NULL) cpl_property_set_comment(property, comment);
04082 
04083     cpl_property_set_string(property, value);
04084     uves_deque_push_back(self->properties, property);
04085 
04086     return CPL_ERROR_NONE;
04087 
04088 }
04089 
04090 
04117 cpl_error_code
04118 uves_propertylist_append(uves_propertylist *self,
04119                         const uves_propertylist *other)
04120 {
04121 
04122     const cxchar *const _id = "uves_propertylist_append";
04123 
04124     if (self == NULL) {
04125         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
04126         return CPL_ERROR_NULL_INPUT;
04127     }
04128 
04129     if (other != NULL) {
04130 
04131         uves_deque_const_iterator pos = uves_deque_begin(other->properties);
04132 
04133         while (pos != uves_deque_end(other->properties)) {
04134 
04135             const cpl_property *p = uves_deque_get(other->properties, pos);
04136 
04137             uves_deque_push_back(self->properties, cpl_property_duplicate(p));
04138             pos = uves_deque_next(other->properties, pos);
04139 
04140         }
04141 
04142     }
04143 
04144     return CPL_ERROR_NONE;
04145 
04146 }
04147 
04148 
04179 int
04180 uves_propertylist_erase(uves_propertylist *self, const char *name)
04181 {
04182 
04183     const cxchar *const _id = "uves_propertylist_erase";
04184 
04185     uves_deque_iterator pos;
04186 
04187 
04188     if (self == NULL || name == NULL) {
04189         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
04190         return 0;
04191     }
04192 
04193     pos = _uves_propertylist_find(self, name);
04194     if (pos == uves_deque_end(self->properties)) {
04195         return 0;
04196     }
04197 //        fprintf(stderr, "%d\n", __LINE__);
04198 
04199     uves_deque_erase(self->properties, pos, (cx_free_func)cpl_property_delete);
04200 
04201     return 1;
04202 
04203 }
04204 
04240 int
04241 uves_propertylist_erase_regexp(uves_propertylist *self, const char *regexp,
04242                               int invert)
04243 {
04244 
04245     const cxchar *const _id = "uves_propertylist_erase_regexp";
04246 
04247     cxint status = 0;
04248     cxint count = 0;
04249 
04250     uves_deque_iterator first, last, pos;
04251 
04252     cpl_property    *p;
04253 
04254     uves_regexp filter;
04255 
04256 
04257     if (self == NULL || regexp == NULL) {
04258         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
04259         return 0;
04260     }
04261 
04262 
04263     status = regcomp(&filter.re, regexp, REG_EXTENDED | REG_NOSUB);
04264     if (status) {
04265         cpl_error_set(_id, CPL_ERROR_ILLEGAL_INPUT);
04266         return 0;
04267     }
04268 
04269     filter.invert = invert == 0 ? FALSE : TRUE;
04270 
04271     first = uves_deque_begin(self->properties);
04272     last  = uves_deque_end(self->properties);
04273 
04274     while (first < uves_deque_end(self->properties)) {
04275         pos = first;
04276 //        first = uves_deque_next(self->properties, first);
04277 
04278         p = uves_deque_get(self->properties, pos);
04279         if (_uves_propertylist_compare_regexp(p, &filter) == TRUE) {
04280 
04281 //            fprintf(stderr, "%d\n", __LINE__);
04282 
04283             uves_deque_erase(self->properties, pos,
04284                           (cx_free_func)cpl_property_delete);
04285             count++;
04286         }
04287         else
04288             first = uves_deque_next(self->properties, first);
04289     }
04290 
04291     regfree(&filter.re);
04292 
04293     return count;
04294 
04295 }
04296 
04297 
04322 void
04323 uves_propertylist_empty(uves_propertylist *self)
04324 {
04325 
04326     const cxchar *const _id = "uves_propertylist_empty";
04327 
04328     uves_deque_iterator first, last;
04329 
04330 
04331     if (self == NULL) {
04332         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
04333         return;
04334     }
04335 
04336     first = uves_deque_begin(self->properties);
04337     last = uves_deque_end(self->properties);
04338 
04339     while (first < uves_deque_end(self->properties)) {
04340         uves_deque_iterator pos = first;
04341         
04342 //        first = uves_deque_next(self->properties, first);
04343 //        fprintf(stderr, "%d  %d %d %d\n", __LINE__, first, last, pos);
04344         uves_deque_erase(self->properties, pos,
04345                       (cx_free_func)cpl_property_delete);
04346 
04347 //        first = uves_deque_next(self->properties, first);
04348     }
04349 
04350     return;
04351 
04352 }
04353 
04354 
04393 cpl_error_code
04394 uves_propertylist_update_char(uves_propertylist *self, const char *name,
04395                              char value)
04396 {
04397 
04398     const cxchar *const _id = "uves_propertylist_update_char";
04399 
04400     uves_deque_iterator pos;
04401 
04402 
04403     if (self == NULL || name == NULL) {
04404         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
04405         return CPL_ERROR_NULL_INPUT;
04406     }
04407 
04408     pos = _uves_propertylist_find(self, name);
04409 
04410     if (pos == uves_deque_end(self->properties)) {
04411 
04412         cpl_property *property = cpl_property_new(name, CPL_TYPE_CHAR);
04413 
04414 
04415         cx_assert(property != NULL);
04416 
04417         cpl_property_set_char(property, value);
04418         uves_deque_push_back(self->properties, property);
04419     }
04420     else {
04421 
04422         cpl_property *property = uves_deque_get(self->properties, pos);
04423 
04424 
04425         cx_assert(property != NULL);
04426 
04427         if (cpl_property_get_type(property) != CPL_TYPE_CHAR) {
04428             cpl_error_set(_id, CPL_ERROR_TYPE_MISMATCH);
04429             return CPL_ERROR_TYPE_MISMATCH;
04430         }
04431 
04432         cpl_property_set_char(property, value);
04433 
04434     }
04435 
04436     return CPL_ERROR_NONE;
04437 
04438 }
04439 
04440 
04479 cpl_error_code
04480 uves_propertylist_update_bool(uves_propertylist *self, const char *name,
04481                              int value)
04482 {
04483 
04484     const cxchar *const _id = "uves_propertylist_update_bool";
04485 
04486     uves_deque_iterator pos;
04487 
04488 
04489     if (self == NULL || name == NULL) {
04490         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
04491         return CPL_ERROR_NULL_INPUT;
04492     }
04493 
04494     pos = _uves_propertylist_find(self, name);
04495 
04496     if (pos == uves_deque_end(self->properties)) {
04497 
04498         cpl_property *property = cpl_property_new(name, CPL_TYPE_BOOL);
04499 
04500 
04501         cx_assert(property != NULL);
04502 
04503         cpl_property_set_bool(property, value);
04504         uves_deque_push_back(self->properties, property);
04505     }
04506     else {
04507 
04508         cpl_property *property = uves_deque_get(self->properties, pos);
04509 
04510 
04511         cx_assert(property != NULL);
04512 
04513         if (cpl_property_get_type(property) != CPL_TYPE_BOOL) {
04514             cpl_error_set(_id, CPL_ERROR_TYPE_MISMATCH);
04515             return CPL_ERROR_TYPE_MISMATCH;
04516         }
04517 
04518         cpl_property_set_bool(property, value);
04519 
04520     }
04521 
04522     return CPL_ERROR_NONE;
04523 
04524 }
04525 
04526 
04565 cpl_error_code
04566 uves_propertylist_update_int(uves_propertylist *self, const char *name,
04567                             int value)
04568 {
04569 
04570     const cxchar *const _id = "uves_propertylist_update_int";
04571 
04572     uves_deque_iterator pos;
04573 
04574 
04575     if (self == NULL || name == NULL) {
04576         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
04577         return CPL_ERROR_NULL_INPUT;
04578     }
04579 
04580     pos = _uves_propertylist_find(self, name);
04581 
04582     if (pos == uves_deque_end(self->properties)) {
04583 
04584         cpl_property *property = cpl_property_new(name, CPL_TYPE_INT);
04585 
04586 
04587         cx_assert(property != NULL);
04588 
04589         cpl_property_set_int(property, value);
04590         uves_deque_push_back(self->properties, property);
04591     }
04592     else {
04593 
04594         cpl_property *property = uves_deque_get(self->properties, pos);
04595 
04596 
04597         cx_assert(property != NULL);
04598 
04599         if (cpl_property_get_type(property) != CPL_TYPE_INT) {
04600             cpl_error_set(_id, CPL_ERROR_TYPE_MISMATCH);
04601             return CPL_ERROR_TYPE_MISMATCH;
04602         }
04603 
04604         cpl_property_set_int(property, value);
04605 
04606     }
04607 
04608     return CPL_ERROR_NONE;
04609 
04610 }
04611 
04612 
04651 cpl_error_code
04652 uves_propertylist_update_long(uves_propertylist *self, const char *name,
04653                              long value)
04654 {
04655 
04656     const cxchar *const _id = "uves_propertylist_update_long";
04657 
04658     uves_deque_iterator pos;
04659 
04660 
04661     if (self == NULL || name == NULL) {
04662         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
04663         return CPL_ERROR_NULL_INPUT;
04664     }
04665 
04666     pos = _uves_propertylist_find(self, name);
04667 
04668     if (pos == uves_deque_end(self->properties)) {
04669 
04670         cpl_property *property = cpl_property_new(name, CPL_TYPE_LONG);
04671 
04672 
04673         cx_assert(property != NULL);
04674 
04675         cpl_property_set_long(property, value);
04676         uves_deque_push_back(self->properties, property);
04677     }
04678     else {
04679 
04680         cpl_property *property = uves_deque_get(self->properties, pos);
04681 
04682 
04683         cx_assert(property != NULL);
04684 
04685         if (cpl_property_get_type(property) != CPL_TYPE_LONG) {
04686             cpl_error_set(_id, CPL_ERROR_TYPE_MISMATCH);
04687             return CPL_ERROR_TYPE_MISMATCH;
04688         }
04689 
04690         cpl_property_set_long(property, value);
04691 
04692     }
04693 
04694     return CPL_ERROR_NONE;
04695 
04696 }
04697 
04698 
04737 cpl_error_code
04738 uves_propertylist_update_float(uves_propertylist *self, const char *name,
04739                               float value)
04740 {
04741 
04742     const cxchar *const _id = "uves_propertylist_update_float";
04743 
04744     uves_deque_iterator pos;
04745 
04746 
04747     if (self == NULL || name == NULL) {
04748         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
04749         return CPL_ERROR_NULL_INPUT;
04750     }
04751 
04752     pos = _uves_propertylist_find(self, name);
04753 
04754     if (pos == uves_deque_end(self->properties)) {
04755 
04756         cpl_property *property = cpl_property_new(name, CPL_TYPE_FLOAT);
04757 
04758 
04759         cx_assert(property != NULL);
04760 
04761         cpl_property_set_float(property, value);
04762         uves_deque_push_back(self->properties, property);
04763     }
04764     else {
04765 
04766         cpl_property *property = uves_deque_get(self->properties, pos);
04767 
04768 
04769         cx_assert(property != NULL);
04770 
04771         if (cpl_property_get_type(property) != CPL_TYPE_FLOAT) {
04772             cpl_error_set(_id, CPL_ERROR_TYPE_MISMATCH);
04773             return CPL_ERROR_TYPE_MISMATCH;
04774         }
04775 
04776         cpl_property_set_float(property, value);
04777 
04778     }
04779 
04780     return CPL_ERROR_NONE;
04781 
04782 }
04783 
04784 
04823 cpl_error_code
04824 uves_propertylist_update_double(uves_propertylist *self, const char *name,
04825                                double value)
04826 {
04827 
04828     const cxchar *const _id = "uves_propertylist_update_double";
04829 
04830     uves_deque_iterator pos;
04831 
04832 
04833     if (self == NULL || name == NULL) {
04834         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
04835         return CPL_ERROR_NULL_INPUT;
04836     }
04837 
04838     pos = _uves_propertylist_find(self, name);
04839 
04840     if (pos == uves_deque_end(self->properties)) {
04841 
04842         cpl_property *property = cpl_property_new(name, CPL_TYPE_DOUBLE);
04843 
04844 
04845         cx_assert(property != NULL);
04846 
04847         cpl_property_set_double(property, value);
04848         uves_deque_push_back(self->properties, property);
04849     }
04850     else {
04851 
04852         cpl_property *property = uves_deque_get(self->properties, pos);
04853 
04854 
04855         cx_assert(property != NULL);
04856 
04857         if (cpl_property_get_type(property) != CPL_TYPE_DOUBLE) {
04858             cpl_error_set(_id, CPL_ERROR_TYPE_MISMATCH);
04859             return CPL_ERROR_TYPE_MISMATCH;
04860         }
04861 
04862         cpl_property_set_double(property, value);
04863 
04864     }
04865 
04866     return CPL_ERROR_NONE;
04867 
04868 }
04869 
04870 
04909 cpl_error_code
04910 uves_propertylist_update_string(uves_propertylist *self, const char *name,
04911                                const char *value)
04912 {
04913 
04914     const cxchar *const _id = "uves_propertylist_update_string";
04915 
04916     uves_deque_iterator pos;
04917 
04918 
04919     if (self == NULL || name == NULL) {
04920         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
04921         return CPL_ERROR_NULL_INPUT;
04922     }
04923 
04924     pos = _uves_propertylist_find(self, name);
04925 
04926     if (pos == uves_deque_end(self->properties)) {
04927 
04928         cpl_property *property = cpl_property_new(name, CPL_TYPE_STRING);
04929 
04930 
04931         cx_assert(property != NULL);
04932 
04933         cpl_property_set_string(property, value);
04934         uves_deque_push_back(self->properties, property);
04935     }
04936     else {
04937 
04938         cpl_property *property = uves_deque_get(self->properties, pos);
04939 
04940 
04941         cx_assert(property != NULL);
04942 
04943         if (cpl_property_get_type(property) != CPL_TYPE_STRING) {
04944             cpl_error_set(_id, CPL_ERROR_TYPE_MISMATCH);
04945             return CPL_ERROR_TYPE_MISMATCH;
04946         }
04947 
04948         cpl_property_set_string(property, value);
04949 
04950     }
04951 
04952     return CPL_ERROR_NONE;
04953 
04954 }
04955 
04956 
05004 cpl_error_code
05005 uves_propertylist_copy_property(uves_propertylist *self,
05006                                const uves_propertylist *other,
05007                                const char *name)
05008 {
05009 
05010     const cxchar *const _id = "uves_propertylist_copy_property";
05011 
05012     uves_deque_iterator spos;
05013     uves_deque_iterator tpos;
05014 
05015 
05016     if (self == NULL || other == NULL || name == NULL) {
05017         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
05018         return CPL_ERROR_NULL_INPUT;
05019     }
05020 
05021     spos = _uves_propertylist_find(other, name);
05022 
05023     if (spos == uves_deque_end(other->properties)) {
05024         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
05025         return CPL_ERROR_DATA_NOT_FOUND;
05026     }
05027 
05028     tpos = _uves_propertylist_find(self, name);
05029 
05030     if (tpos == uves_deque_end(self->properties)) {
05031 
05032         cpl_property *p = cpl_property_duplicate(uves_deque_get(other->properties,
05033                                                              spos));
05034         uves_deque_push_back(self->properties, p);
05035 
05036     }
05037     else {
05038 
05039         cpl_property *p = uves_deque_get(self->properties, tpos);
05040         cpl_property *_p = uves_deque_get(self->properties, spos);
05041 
05042 
05043         if (cpl_property_get_type(p) != cpl_property_get_type(_p)) {
05044             cpl_error_set(_id, CPL_ERROR_TYPE_MISMATCH);
05045             return CPL_ERROR_TYPE_MISMATCH;
05046         }
05047 
05048         switch (cpl_property_get_type(_p)) {
05049 
05050         case CPL_TYPE_CHAR:
05051             cpl_property_set_char(p, cpl_property_get_char(_p));
05052             break;
05053 
05054         case CPL_TYPE_BOOL:
05055             cpl_property_set_bool(p, cpl_property_get_bool(_p));
05056             break;
05057 
05058         case CPL_TYPE_INT:
05059             cpl_property_set_int(p, cpl_property_get_int(_p));
05060             break;
05061 
05062         case CPL_TYPE_LONG:
05063             cpl_property_set_long(p, cpl_property_get_long(_p));
05064             break;
05065 
05066         case CPL_TYPE_FLOAT:
05067             cpl_property_set_float(p, cpl_property_get_float(_p));
05068             break;
05069 
05070         case CPL_TYPE_DOUBLE:
05071             cpl_property_set_double(p, cpl_property_get_double(_p));
05072             break;
05073 
05074         case CPL_TYPE_STRING:
05075             cpl_property_set_string(p, cpl_property_get_string(_p));
05076             break;
05077 
05078         default:
05079             /* This point should never be reached */
05080             cx_error("%s: Unsupported type encountered!", CX_CODE_POS);
05081             break;
05082 
05083         }
05084 
05085         cpl_property_set_comment(p, cpl_property_get_comment(_p));
05086 
05087     }
05088 
05089     return CPL_ERROR_NONE;
05090 
05091 }
05092 
05093 
05153 cpl_error_code
05154 uves_propertylist_copy_property_regexp(uves_propertylist *self,
05155                                       const uves_propertylist *other,
05156                                       const char *regexp,
05157                                       int invert)
05158 {
05159 
05160     const cxchar *const _id = "uves_propertylist_copy_property_regexp";
05161 
05162     cxint status;
05163 
05164     cxsize i;
05165     cxsize count = 0;
05166 
05167     uves_deque_const_iterator first, last;
05168 
05169     typedef struct _property_pair_ {
05170         cpl_property *s;
05171         cpl_property *t;
05172     } property_pair;
05173 
05174     property_pair *pairs = NULL;
05175 
05176     uves_regexp filter;
05177 
05178 
05179     if (self == NULL || other == NULL || regexp == NULL) {
05180         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
05181         return CPL_ERROR_NULL_INPUT;
05182     }
05183 
05184     status = regcomp(&filter.re, regexp, REG_EXTENDED | REG_NOSUB);
05185     if (status) {
05186         cpl_error_set(_id, CPL_ERROR_ILLEGAL_INPUT);
05187         return CPL_ERROR_ILLEGAL_INPUT;
05188     }
05189 
05190     filter.invert = invert == 0 ? FALSE : TRUE;
05191 
05192 
05193     count = uves_deque_size(other->properties);
05194 
05195     if (count == 0) {
05196         regfree(&filter.re);
05197         return CPL_ERROR_NONE;
05198     }
05199 
05200     pairs = cx_malloc(count * sizeof(property_pair));
05201     cx_assert(pairs != NULL);
05202 
05203     count = 0;
05204 
05205 
05206     first = uves_deque_begin(other->properties);
05207     last  = uves_deque_end(other->properties);
05208 
05209     while (first != last) {
05210 
05211         cpl_property *p = uves_deque_get(other->properties, first);
05212 
05213 
05214         if (_uves_propertylist_compare_regexp(p, &filter) == TRUE) {
05215 
05216             const cxchar *name = cpl_property_get_name(p);
05217 
05218             uves_deque_const_iterator pos = _uves_propertylist_find(self, name);
05219 
05220             cpl_property *_p = NULL;
05221 
05222 
05223             if (pos != uves_deque_end(self->properties)) {
05224 
05225                 _p = uves_deque_get(self->properties, pos);
05226 
05227                 if (cpl_property_get_type(p) != cpl_property_get_type(_p)) {
05228 
05229                     regfree(&filter.re);
05230 
05231                     cx_free(pairs);
05232                     pairs = NULL;
05233 
05234                     cpl_error_set(_id, CPL_ERROR_TYPE_MISMATCH);
05235 
05236                     return CPL_ERROR_TYPE_MISMATCH;
05237 
05238                 }
05239 
05240             }
05241 
05242             pairs[count].s = p;
05243             pairs[count].t = _p;
05244             ++count;
05245 
05246         }
05247 
05248         first = uves_deque_next(other->properties, first);
05249 
05250     }
05251 
05252     regfree(&filter.re);
05253 
05254 
05255     for (i = 0; i < count; i++) {
05256 
05257         if (pairs[i].t == NULL) {
05258 
05259             cpl_property *p = cpl_property_duplicate(pairs[i].s);
05260             uves_deque_push_back(self->properties, p);
05261 
05262         }
05263         else {
05264 
05265             switch (cpl_property_get_type(pairs[i].s)) {
05266 
05267             case CPL_TYPE_CHAR:
05268                 cpl_property_set_char(pairs[i].t,
05269                                       cpl_property_get_char(pairs[i].s));
05270                 break;
05271 
05272             case CPL_TYPE_BOOL:
05273                 cpl_property_set_bool(pairs[i].t,
05274                                       cpl_property_get_bool(pairs[i].s));
05275                 break;
05276 
05277             case CPL_TYPE_INT:
05278                 cpl_property_set_int(pairs[i].t,
05279                                      cpl_property_get_int(pairs[i].s));
05280                 break;
05281 
05282             case CPL_TYPE_LONG:
05283                 cpl_property_set_long(pairs[i].t,
05284                                       cpl_property_get_long(pairs[i].s));
05285                 break;
05286 
05287             case CPL_TYPE_FLOAT:
05288                 cpl_property_set_float(pairs[i].t,
05289                                        cpl_property_get_float(pairs[i].s));
05290                 break;
05291 
05292             case CPL_TYPE_DOUBLE:
05293                 cpl_property_set_double(pairs[i].t,
05294                                         cpl_property_get_double(pairs[i].s));
05295                 break;
05296 
05297             case CPL_TYPE_STRING:
05298                 cpl_property_set_string(pairs[i].t,
05299                                         cpl_property_get_string(pairs[i].s));
05300                 break;
05301 
05302             default:
05303                 /* This point should never be reached */
05304                 cx_free(pairs);
05305                 cx_error("%s: Unsupported type encountered!", CX_CODE_POS);
05306                 break;
05307 
05308             }
05309 
05310         }
05311 
05312     }
05313 
05314     cx_free(pairs);
05315 
05316     return CPL_ERROR_NONE;
05317 
05318 }
05319 
05320 
05381 uves_propertylist *
05382 uves_propertylist_load(const char *name, int position)
05383 {
05384 
05385     const cxchar *const _id = "uves_propertylist_load";
05386 
05387     register cxint n, status;
05388 
05389     qfits_header *header;
05390 
05391     uves_propertylist *self;
05392 
05393 
05394     if (name == NULL) {
05395         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
05396         return NULL;
05397     }
05398 
05399     if (position < 0) {
05400         cpl_error_set(_id, CPL_ERROR_ILLEGAL_INPUT);
05401         return NULL;
05402     }
05403 
05404     status = qfits_is_fits((cxchar *)name);
05405     if (status == -1) {
05406         cpl_error_set(_id, CPL_ERROR_FILE_IO);
05407         return NULL;
05408     }
05409     else {
05410         if (status == 0) {
05411             cpl_error_set(_id, CPL_ERROR_BAD_FILE_FORMAT);
05412             return NULL;
05413         }
05414     }
05415 
05416     /*
05417      * qfits_query_n_ext() only counts true extensions, i.e. it does not
05418      * count the primary FITS unit. But since we passed the qfits_is_fits()
05419      * check we can safely assume that there is one.
05420      */
05421 
05422     n = qfits_query_n_ext((cxchar *)name);
05423 
05424     if (n < position) {
05425         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
05426         return NULL;
05427     }
05428 
05429 
05430     header = qfits_header_readext((cxchar *)name, position);
05431 
05432     if (header == NULL) {
05433         cpl_error_set(_id, CPL_ERROR_ILLEGAL_INPUT);
05434         return NULL;
05435     }
05436 
05437     self = uves_propertylist_new();
05438     cx_assert(self);
05439 
05440     status = _uves_propertylist_from_fits(self, header, NULL, NULL);
05441 
05442     if (status) {
05443         uves_propertylist_delete(self);
05444         qfits_header_destroy(header);
05445 
05446         cpl_error_set(_id, CPL_ERROR_ILLEGAL_INPUT);
05447         return NULL;
05448     }
05449 
05450     qfits_header_destroy(header);
05451 
05452     return self;
05453 
05454 }
05455 
05456 
05528 uves_propertylist *
05529 uves_propertylist_load_regexp(const char *name, int position,
05530                              const char *regexp, int invert)
05531 {
05532 
05533     const cxchar *const _id = "uves_propertylist_load_regexp";
05534 
05535     register cxint n, status;
05536 
05537     qfits_header *header;
05538 
05539     uves_propertylist *self;
05540 
05541     uves_regexp filter;
05542 
05543 
05544     if (name == NULL || regexp == NULL) {
05545         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
05546         return NULL;
05547     }
05548 
05549     if (position < 0) {
05550         cpl_error_set(_id, CPL_ERROR_ILLEGAL_INPUT);
05551         return NULL;
05552     }
05553 
05554     status = regcomp(&filter.re, regexp, REG_EXTENDED | REG_NOSUB);
05555     if (status) {
05556         cpl_error_set(_id, CPL_ERROR_ILLEGAL_INPUT);
05557         return NULL;
05558     }
05559 
05560     filter.invert = invert == 0 ? FALSE : TRUE;
05561 
05562 
05563     status = qfits_is_fits((cxchar *)name);
05564     if (status == -1) {
05565         cpl_error_set(_id, CPL_ERROR_FILE_IO);
05566         return NULL;
05567     }
05568     else {
05569         if (status == 0) {
05570             cpl_error_set(_id, CPL_ERROR_BAD_FILE_FORMAT);
05571             return NULL;
05572         }
05573     }
05574 
05575     /*
05576      * qfits_query_n_ext() only counts true extensions, i.e. it does not
05577      * count the primary FITS unit. But since we passed the qfits_is_fits()
05578      * check we can safely assume that there is one.
05579      */
05580 
05581     n = qfits_query_n_ext((cxchar *)name);
05582 
05583     if (n < position) {
05584         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
05585         return NULL;
05586     }
05587 
05588 
05589     header = qfits_header_readext((cxchar *)name, position);
05590 
05591     if (header == NULL) {
05592         cpl_error_set(_id, CPL_ERROR_ILLEGAL_INPUT);
05593         return NULL;
05594     }
05595 
05596     self = uves_propertylist_new();
05597     cx_assert(self);
05598 
05599     status = _uves_propertylist_from_fits(self, header,
05600                                          _uves_propertylist_filter_regexp,
05601                                          &filter);
05602 
05603     if (status) {
05604         uves_propertylist_delete(self);
05605         qfits_header_destroy(header);
05606 
05607         regfree(&filter.re);
05608 
05609         cpl_error_set(_id, CPL_ERROR_ILLEGAL_INPUT);
05610         return NULL;
05611     }
05612 
05613     qfits_header_destroy(header);
05614     regfree(&filter.re);
05615 
05616     return self;
05617 
05618 }
05619 
05620 
05638 qfits_header *
05639 uves_propertylist_to_fits(const uves_propertylist *self)
05640 {
05641     const cxchar *const _id = "uves_propertylist_to_fits";
05642 
05643     qfits_header *header;
05644 
05645 
05646     cx_assert(self != NULL);
05647 
05648     header = qfits_header_new();
05649 
05650     if (!uves_deque_empty(self->properties)) {
05651         uves_deque_iterator i = uves_deque_begin(self->properties);
05652         uves_deque_iterator last = uves_deque_end(self->properties);
05653 
05654         while (i != last) {
05655             cxchar tmp[FITS_LINESZ + 1];
05656             cxchar key[FITS_LINESZ + 1];
05657             cxchar value[FITS_LINESZ + 1];
05658             cxfloat fval;
05659             cxdouble dval;
05660             cpl_property *property;
05661 
05662             property = uves_deque_get(self->properties, i);
05663 
05664             /*
05665              * Convert each property into a FITS keyword an error is
05666              * triggered for unsupported types. Also, since the FITS
05667              * format does not support array keywords, apart from strings,
05668              * i.e. character arrays, an error is triggered in this case too.
05669              *
05670              * A possible solution for the array case would be to create
05671              * a sequence of indexed keywords. But this must be checked.
05672              */
05673 
05674             strncpy(tmp, cpl_property_get_name(property), FITS_LINESZ);
05675             tmp[FITS_LINESZ] = '\0';
05676 
05677             if (!cx_strupper(tmp)) {
05678 //                cpl_error_set_code(CPL_ERROR_INCOMPATIBLE_INPUT);
05679 //                cpl_error_set_where(_id);
05680                 cpl_error_set(_id, CPL_ERROR_INCOMPATIBLE_INPUT);
05681 
05682                 qfits_header_destroy(header);
05683 
05684                 return NULL;
05685             }
05686 
05687             key[0] = '\0';
05688 
05689             if (strlen(tmp) > FITS_STDKEY_MAX &&
05690                 strncmp(tmp, "HIERARCH ", 9)) {
05691                 strncat(key, "HIERARCH ", 9);
05692             }
05693             strncat(key, tmp, FITS_LINESZ - strlen(key));
05694 
05695             switch (cpl_property_get_type(property)) {
05696                 case CPL_TYPE_CHAR:
05697                     cx_snprintf(value, FITS_LINESZ, "'%c'",
05698                                 cpl_property_get_char(property));
05699                     break;
05700 
05701                 case CPL_TYPE_BOOL:
05702                 {
05703                     cxint pvalue = cpl_property_get_bool(property);
05704 
05705                     cx_snprintf(value, FITS_LINESZ, "%c",
05706                                 pvalue == 1 ? 'T' : 'F');
05707                     break;
05708                 }
05709 
05710                 case CPL_TYPE_INT:
05711                     cx_snprintf(value, FITS_LINESZ, "%d",
05712                                 cpl_property_get_int(property));
05713                     break;
05714 
05715                 case CPL_TYPE_LONG:
05716                     cx_snprintf(value, FITS_LINESZ, "%ld",
05717                                 cpl_property_get_long(property));
05718                     break;
05719 
05720                 case CPL_TYPE_FLOAT:
05721                     fval = cpl_property_get_float(property);
05722                     cx_snprintf(value, FITS_LINESZ, "%.7G", fval);
05723 
05724                     if (!strchr(value, '.')) {
05725                         if (strchr(value, 'E'))
05726                             cx_snprintf(value, FITS_LINESZ, "%.1E", fval);
05727                         else
05728                             strcat(value, ".");
05729                     }
05730                     break;
05731 
05732                 case CPL_TYPE_DOUBLE:
05733                     dval = cpl_property_get_double(property);
05734                     cx_snprintf(value, FITS_LINESZ, "%.15G", dval);
05735 
05736                     if (!strchr(value, '.')) {
05737                         if (strchr(value, 'E'))
05738                             cx_snprintf(value, FITS_LINESZ, "%.1E", dval);
05739                         else
05740                             strcat(value, ".");
05741                     }
05742                     break;
05743 
05744                 case CPL_TYPE_STRING:
05745                     if (!strcmp(key, "COMMENT") || !strcmp(key, "HISTORY")) {
05746                         cx_snprintf(value, FITS_LINESZ, "%s",
05747                                     cpl_property_get_string(property));
05748                     }
05749                     else {
05750 
05751                         cxint n = 0;
05752 
05753                         n = cx_snprintf(value, FITS_SVALUE_MAX + 1, "'%s'",
05754                                         cpl_property_get_string(property));
05755 
05756                         if (n > FITS_SVALUE_MAX) {
05757                             value[FITS_SVALUE_MAX - 1] = '\'';
05758                             value[FITS_SVALUE_MAX] = '\0';
05759                         }
05760 
05761                     }
05762                     break;
05763 
05764                 default:
05765 //                    cpl_error_set_code(CPL_ERROR_INCOMPATIBLE_INPUT);
05766 //                    cpl_error_set_where(_id);
05767                     cpl_error_set(_id, CPL_ERROR_INCOMPATIBLE_INPUT);
05768 
05769                     qfits_header_destroy(header);
05770 
05771                     return NULL;
05772                     break;
05773             }
05774 
05775             qfits_header_append(header, key, value,
05776                                 (cxchar *)cpl_property_get_comment(property),
05777                                 NULL);
05778 
05779             i = uves_deque_next(self->properties, i);
05780         }
05781     }
05782 
05783 
05784     /*
05785      * Add the END keyword as last entry.
05786      */
05787 
05788     /* FIXME: Maybe better to check if end is already present */
05789 
05790     qfits_header_append(header, "END", NULL, NULL, NULL);
05791 
05792 
05793     /*
05794      * Sort the header according to ESO's DICB standard
05795      */
05796 
05797     if (qfits_header_sort(&header) != 0) {
05798 //        cpl_error_set_code(CPL_ERROR_INCOMPATIBLE_INPUT);
05799 //        cpl_error_set_where(_id);
05800         cpl_error_set(_id, CPL_ERROR_INCOMPATIBLE_INPUT);
05801 
05802         qfits_header_destroy(header);
05803 
05804         return NULL;
05805     }
05806 
05807     return header;
05808 
05809 }
05810 
05834 uves_propertylist *
05835 uves_propertylist_from_fits(const qfits_header *header)
05836 {
05837 
05838     const cxchar *const _id = "uves_propertylist_from_fits";
05839 
05840     register cxint status;
05841 
05842     uves_propertylist *self;
05843 
05844 
05845     if (!header) {
05846         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
05847         return NULL;
05848     }
05849 
05850     self = uves_propertylist_new();
05851     cx_assert(self != NULL);
05852 
05853     status = _uves_propertylist_from_fits(self, header, NULL, NULL);
05854 
05855     if (status) {
05856         uves_propertylist_delete(self);
05857 
05858 //        cpl_error_set_where(_id);
05859 
05860         switch (status) {
05861         case -2:
05862         case -1:
05863 //            cpl_error_set_code(CPL_ERROR_ILLEGAL_INPUT);
05864             cpl_error_set(_id, CPL_ERROR_ILLEGAL_INPUT);
05865             break;
05866 
05867         case 1:
05868 //            cpl_error_set_code(CPL_ERROR_INVALID_TYPE);
05869             cpl_error_set(_id, CPL_ERROR_INVALID_TYPE);
05870             break;
05871 
05872         default:
05873             /* This should never be reached */
05874             break;
05875         }
05876 
05877         return NULL;
05878     }
05879 
05880     return self;
05881 
05882 }
05883 
05884 #endif /* USE_CPL */
05885 

Generated on Mon Apr 21 10:56:56 2008 for UVES Pipeline Reference Manual by  doxygen 1.5.1