uves_propertylist.c

00001 /* $Id: uves_propertylist.c,v 1.7 2007/06/06 06:28:06 jmlarsen 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: jmlarsen $
00023  * $Date: 2007/06/06 06:28:06 $
00024  * $Revision: 1.7 $
00025  * $Name: uves-3_3_1 $
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 
00035 #ifdef USE_CPL
00036 #else
00037 
00038 #include <uves_utils_wrappers.h>
00039 #include <uves_deque.h>
00040 #include <uves_dump.h>
00041 #include <irplib_access.h>
00042 
00043 #include <cpl.h>
00044 
00045 //#include <cxmacros.h>
00046 #include <cxmemory.h>
00047 #include <cxmessages.h>
00048 #include <cxstrutils.h>
00049 #include <cxutils.h>
00050 //#include "cpl_error_impl.h"
00051 //#include "cpl_propertylist_impl.h"
00052 #include <qfits.h>
00053 
00054 #include <stdio.h>
00055 #include <string.h>
00056 #include <sys/types.h>
00057 #include <regex.h>
00058 
00075 enum {
00076     FITS_STDKEY_MAX = 8,
00077     FITS_SVALUE_MAX = 68
00078 };
00079 
00080 
00081 /*
00082  * The property list type.
00083  */
00084 
00085 struct _uves_propertylist_ {
00086     uves_deque *properties;
00087 };
00088 
00089 
00090 /*
00091  * Regular expresion filter type
00092  */
00093 
00094 struct _uves_regexp_ {
00095     regex_t re;
00096     cxbool invert;
00097 };
00098 
00099 typedef struct _uves_regexp_ uves_regexp;
00100 
00101 
00102 static void
00103 propertylist_append_property(uves_propertylist *plist, const cpl_property *p)
00104 {
00105     switch(cpl_property_get_type(p)) {
00106     case CPL_TYPE_CHAR:
00107         uves_propertylist_append_char(plist, cpl_property_get_name(p), cpl_property_get_char(p));
00108         break;
00109     case CPL_TYPE_BOOL:
00110         uves_propertylist_append_bool(plist, cpl_property_get_name(p), cpl_property_get_bool(p));
00111         break;
00112     case CPL_TYPE_INT:
00113         uves_propertylist_append_int(plist, cpl_property_get_name(p), cpl_property_get_int(p));
00114         break;
00115     case CPL_TYPE_LONG:
00116         uves_propertylist_append_long(plist, cpl_property_get_name(p), cpl_property_get_long(p));
00117         break;
00118     case CPL_TYPE_FLOAT:
00119         uves_propertylist_append_float(plist, cpl_property_get_name(p), cpl_property_get_float(p));
00120         break;
00121     case CPL_TYPE_DOUBLE:
00122         uves_propertylist_append_double(plist, cpl_property_get_name(p), cpl_property_get_double(p));
00123         break;
00124     case CPL_TYPE_STRING:
00125         uves_propertylist_append_string(plist, cpl_property_get_name(p), cpl_property_get_string(p));
00126         break;
00127     default:
00128         cpl_msg_error("Unknown property type: %s", uves_tostring_cpl_type(cpl_property_get_type(p)));
00129         cpl_error_set(__func__, CPL_ERROR_UNSUPPORTED_MODE);
00130         break;
00131     }
00132     /* This is constant time!! */
00133     cpl_property_set_comment(uves_propertylist_get(plist, uves_propertylist_get_size(plist) - 1),
00134                              cpl_property_get_comment(p));
00135     return;
00136 }
00137 
00138 static void
00139 propertylist_prepend_property_cpl(cpl_propertylist *plist, const cpl_property *p)
00140 {
00141     switch(cpl_property_get_type(p)) {
00142     case CPL_TYPE_CHAR:
00143         cpl_propertylist_prepend_char(plist, cpl_property_get_name(p), cpl_property_get_char(p));
00144         break;
00145     case CPL_TYPE_BOOL:
00146         cpl_propertylist_prepend_bool(plist, cpl_property_get_name(p), cpl_property_get_bool(p));
00147         break;
00148     case CPL_TYPE_INT:
00149         cpl_propertylist_prepend_int(plist, cpl_property_get_name(p), cpl_property_get_int(p));
00150         break;
00151     case CPL_TYPE_LONG:
00152         cpl_propertylist_prepend_long(plist, cpl_property_get_name(p), cpl_property_get_long(p));
00153         break;
00154     case CPL_TYPE_FLOAT:
00155         cpl_propertylist_prepend_float(plist, cpl_property_get_name(p), cpl_property_get_float(p));
00156         break;
00157     case CPL_TYPE_DOUBLE:
00158         cpl_propertylist_prepend_double(plist, cpl_property_get_name(p), cpl_property_get_double(p));
00159         break;
00160     case CPL_TYPE_STRING:
00161         cpl_propertylist_prepend_string(plist, cpl_property_get_name(p), cpl_property_get_string(p));
00162         break;
00163     default:
00164         cpl_msg_error("Unknown property type: %s", uves_tostring_cpl_type(cpl_property_get_type(p)));
00165         cpl_error_set(__func__, CPL_ERROR_UNSUPPORTED_MODE);
00166         break;
00167     }
00168     cpl_propertylist_set_comment(plist, cpl_property_get_name(p), cpl_property_get_comment(p));
00169     return;
00170 }
00171 
00172 static cpl_propertylist *
00173 uves_propertylist_to_cpl(const uves_propertylist *self)
00174 {
00175     cpl_propertylist *result;
00176     long i;
00177 
00178     if (self == NULL) {
00179         result = NULL;
00180     }
00181     else {
00182         result = cpl_propertylist_new();
00183         
00184         for (i = uves_propertylist_get_size(self)-1; i >= 0; i--) {
00185             propertylist_prepend_property_cpl(
00186                 result, 
00187                 uves_propertylist_get_const(self, i));
00188         }
00189     }
00190     return result;
00191 }
00192 
00193 static void
00194 uves_propertylist_from_cpl(uves_propertylist *self, const cpl_propertylist *list_cpl)
00195 {
00196     long N = cpl_propertylist_get_size(list_cpl); /* O(n) */
00197     cpl_propertylist *copy = cpl_propertylist_duplicate(list_cpl); /* O(n) */
00198     long i;
00199 
00200     assert( uves_propertylist_is_empty(self));
00201 
00202     for (i = 0; i < N; i++) {
00203         const cpl_property *p = irplib_propertylist_get_const(copy, 0); /* O(1) */
00204         propertylist_append_property(self, p); /* O(1) */
00205         cpl_propertylist_erase(copy, cpl_property_get_name(p)); /* O(1),
00206                                                                  erases only first match */
00207     }
00208     assert( cpl_propertylist_is_empty(copy));
00209     cpl_propertylist_delete(copy);
00210 
00211     return;
00212 }
00213 
00214 /* Wrappers for often used functions which have cpl_propertylists in their interface */
00215 cpl_error_code uves_vector_save(const cpl_vector *v, const char *f, cpl_type_bpp bpp,
00216                                 const uves_propertylist *header, unsigned mode)
00217 {
00218     cpl_propertylist *header_cpl = uves_propertylist_to_cpl(header);
00219     cpl_vector_save(v, f, bpp, header_cpl, mode);
00220     cpl_propertylist_delete(header_cpl);
00221 
00222     return cpl_error_get_code();
00223 }
00224 cpl_error_code uves_image_save(const cpl_image *image, const char *f, cpl_type_bpp bpp,
00225                                const uves_propertylist *header, unsigned mode)
00226 {
00227     cpl_propertylist *header_cpl = uves_propertylist_to_cpl(header);
00228     cpl_image_save(image, f, bpp, header_cpl, mode);
00229     cpl_propertylist_delete(header_cpl);
00230 
00231     return cpl_error_get_code();
00232 }
00233 cpl_error_code uves_imagelist_save(const cpl_imagelist *imagelist, const char *f, cpl_type_bpp bpp,
00234                                const uves_propertylist *header, unsigned mode)
00235 {
00236     cpl_propertylist *header_cpl = uves_propertylist_to_cpl(header);
00237     cpl_imagelist_save(imagelist, f, bpp, header_cpl, mode);
00238     cpl_propertylist_delete(header_cpl);
00239 
00240     return cpl_error_get_code();
00241 }
00242 cpl_error_code uves_table_save(const cpl_table *table, const uves_propertylist *header,
00243                                const uves_propertylist *ext_header, const char *filename,
00244                                unsigned mode)
00245 {
00246     cpl_propertylist *header_cpl = uves_propertylist_to_cpl(header);
00247     cpl_propertylist *ext_header_cpl = uves_propertylist_to_cpl(ext_header);
00248     cpl_table_save(table, header_cpl, ext_header_cpl, filename, mode);
00249     cpl_propertylist_delete(header_cpl);
00250     cpl_propertylist_delete(ext_header_cpl);
00251 
00252     return cpl_error_get_code();
00253 }
00254 
00255 cpl_error_code uves_dfs_setup_product_header(uves_propertylist *header,
00256                                              const cpl_frame *product_frame,
00257                                              const cpl_frameset *framelist,
00258                                              const cpl_parameterlist *parlist,
00259                                              const char *recid,
00260                                              const char *pipeline_id,
00261                                              const char *dictionary_id)
00262 {
00263     cpl_propertylist *header_cpl = uves_propertylist_to_cpl(header);
00264     cpl_dfs_setup_product_header(header_cpl,
00265                                  product_frame,
00266                                  framelist,
00267                                  parlist,
00268                                  recid,
00269                                  pipeline_id,
00270                                  dictionary_id);
00271 
00272     uves_propertylist_empty(header);
00273     uves_propertylist_from_cpl(header, header_cpl);
00274     cpl_propertylist_delete(header_cpl);
00275 
00276     return cpl_error_get_code();
00277 }
00278 
00279 cpl_error_code uves_table_sort(cpl_table *t, const uves_propertylist *list)
00280 {
00281     /* Just use this workaround ... */
00282     uves_table_sort_dfsxxxx(t, list);
00283     
00284     /* ... instead of this one */
00285 #if 0
00286     cpl_propertylist *list_cpl = uves_propertylist_to_cpl(list);
00287     cpl_table_sort(t, list_cpl);
00288     cpl_propertylist_delete(list_cpl);
00289 #endif    
00290     return cpl_error_get_code();
00291 }
00292 
00293 
00294 /*
00295  * Private methods
00296  */
00297 
00298 
00299 /* Workarounds for cpl_error_push/pop which are not exported */
00300 static cpl_error_code push_pop_error;
00301 
00302 static void error_push(void)
00303 {
00304     push_pop_error = cpl_error_get_code();
00305     /* Don't track location */
00306     cpl_error_reset();
00307     return;
00308 }
00309 static void error_pop(void)
00310 {
00311     if (push_pop_error != CPL_ERROR_NONE)
00312         {
00313             cpl_error_set(__func__, push_pop_error);
00314         }
00315     return;
00316 }
00317 
00318 
00319 
00320 
00321 
00322 
00323 
00324 
00325 inline static cxint
00326 _uves_propertylist_filter_regexp(cxcptr key, cxcptr filter)
00327 {
00328 
00329     const uves_regexp *_filter = (const uves_regexp *)filter;
00330 
00331     if (regexec(&_filter->re, key, (size_t)0, NULL, 0) == REG_NOMATCH)
00332         return _filter->invert == TRUE ? TRUE : FALSE;
00333 
00334     return _filter->invert == TRUE ? FALSE : TRUE;
00335 
00336 }
00337 
00338 
00339 inline static cxbool
00340 _uves_propertylist_compare(const cpl_property *property, const char *name)
00341 {
00342     const cxchar *key = cpl_property_get_name(property);
00343 
00344     return strcmp(key, name) == 0 ? TRUE : FALSE;
00345 
00346 }
00347 
00348 
00349 inline static cxbool
00350 _uves_propertylist_compare_start(const cpl_property *property,
00351                                 const char *part_name)
00352 {
00353 
00354     const cxchar *key = cpl_property_get_name(property);
00355 
00356     if (strstr(key, part_name) == key)
00357         return TRUE;
00358 
00359     return FALSE;
00360 
00361 }
00362 
00363 
00364 inline static cxbool
00365 _uves_propertylist_compare_regexp(const cpl_property *property, uves_regexp *re)
00366 {
00367 
00368     const cxchar *key = cpl_property_get_name(property);
00369 
00370     return _uves_propertylist_filter_regexp(key, re);
00371 
00372 }
00373 
00374 
00375 inline static uves_deque_iterator
00376 _uves_propertylist_find(const uves_propertylist *self, const char *name)
00377 {
00378 
00379     uves_deque_iterator first, last;
00380     cpl_property *p;
00381 
00382     first = uves_deque_begin(self->properties);
00383     last = uves_deque_end(self->properties);
00384 
00385     while (first != last) {
00386         p = uves_deque_get(self->properties, first);
00387 
00388         if (_uves_propertylist_compare(p, name))
00389             break;
00390 
00391         first = uves_deque_next(self->properties, first);
00392     }
00393 
00394     return first;
00395 
00396 }
00397 
00398 inline static cpl_property *
00399 _uves_propertylist_get(const uves_propertylist *self, const char *name)
00400 {
00401     uves_deque_iterator pos = _uves_propertylist_find(self, name);
00402 
00403     if (pos == uves_deque_end(self->properties))
00404         return NULL;
00405 
00406     return uves_deque_get(self->properties, pos);
00407 
00408 }
00409 
00410 
00411 inline static int
00412 _uves_propertylist_insert(uves_propertylist *self, const cxchar *where,
00413                          cxbool after, const cxchar *name, cpl_type type,
00414                          cxptr value)
00415 {
00416 
00417     uves_deque_iterator pos;
00418     cpl_property *property;
00419 
00420 
00421     /*
00422      * Find the position where value should be inserted.
00423      */
00424 
00425     pos = _uves_propertylist_find(self, where);
00426 
00427     if (pos == uves_deque_end(self->properties)) {
00428         return 1;
00429     }
00430 
00431     if (after) {
00432         pos = uves_deque_next(self->properties, pos);
00433     }
00434 
00435 
00436     /*
00437      * Create the property for value and fill it.
00438      */
00439 
00440     property = cpl_property_new(name, type);
00441     if (!property) {
00442         return 1;
00443     }
00444 
00445 
00446     /*
00447      * Map property type to the driver function's argument type.
00448      */
00449 
00450     switch (type) {
00451         case CPL_TYPE_CHAR:
00452             cpl_property_set_char(property, *((cxchar *)value));
00453             break;
00454 
00455         case CPL_TYPE_BOOL:
00456             cpl_property_set_bool(property, *((cxint *)value));
00457             break;
00458 
00459         case CPL_TYPE_INT:
00460             cpl_property_set_int(property, *((cxint *)value));
00461             break;
00462 
00463         case CPL_TYPE_LONG:
00464             cpl_property_set_long(property, *((cxlong *)value));
00465             break;
00466 
00467         case CPL_TYPE_FLOAT:
00468             cpl_property_set_float(property, *((cxfloat *)value));
00469             break;
00470 
00471         case CPL_TYPE_DOUBLE:
00472             cpl_property_set_double(property, *((cxdouble *)value));
00473             break;
00474 
00475         case CPL_TYPE_STRING:
00476             cpl_property_set_string(property, ((const cxchar *)value));
00477             break;
00478 
00479         default:
00480             return 1;
00481             break;
00482     }
00483 
00484 
00485     /*
00486      * Insert it into the list
00487      */
00488 
00489     uves_deque_insert(self->properties, pos, property);
00490 
00491     return 0;
00492 
00493 }
00494 
00495 
00496 /*
00497  * Parser for FITS cards. Returns 0 if the card was successfully parsed
00498  * into its components, 1 if the card should be ignored and a negative
00499  * number if an error occurred. If the parsing was successful the function
00500  * fills the buffers pointed to by key, value, comment and type.
00501  *
00502  * The buffers key, value and comment must, at least, have the size
00503  * FITS_LINESZ + 1!
00504  *
00505  * Errors:
00506  *  -1  Invalid pointer to the input FITS header.
00507  *  -2  Invalid keyword name detected (cf. qfits_header_getitem())
00508  */
00509 
00510 inline static cxint
00511 _uves_propertylist_decode_fits(const qfits_header *header, cxint i,
00512                               cxchar *key, cxint *type, cxchar *value,
00513                               cxchar *comment)
00514 {
00515 
00516     cxchar _key[FITS_LINESZ + 1];
00517     cxchar _value[FITS_LINESZ + 1];
00518     cxchar _comment[FITS_LINESZ + 1];
00519     cxchar *s;
00520 
00521     if (!header)
00522         return -1;
00523 
00524     /*
00525      * Get a FITS card, decode it into its components and determine
00526      * its type.
00527      */
00528 
00529     if (qfits_header_getitem((qfits_header *)header, i, _key, _value,
00530                              _comment, NULL) != 0) {
00531         return -2;
00532     }
00533 
00534 
00535     /*
00536      * Skip the END record. Qfits ignores empty header cards. Therefore
00537      * we do not need to take care of them here, but who knows.
00538      */
00539 
00540     s = _key;
00541 
00542     if (strncmp(s, "END", 3) == 0 || strncmp(s, "        ", 8) == 0 ||
00543         strlen(s) == 0) {
00544         return 1;
00545     }
00546 
00547 
00548     /*
00549      * strip the HIERARCH prefix from the keyword name if it
00550      * is present.
00551      */
00552 
00553     if (strncmp(s, "HIERARCH ", 9) == 0)
00554         s += 9;
00555 
00556     strncpy(key, s, FITS_LINESZ);
00557     key[FITS_LINESZ] = '\0';
00558 
00559 
00560     /*
00561      * Parse the value string and determine its type. Comment and
00562      * history records are forced to be strings. The type check
00563      * has to be done before cleaning the value, so that strings
00564      * like '1.0' are still recognized as such.
00565      */
00566 
00567     s = _value;
00568 
00569     if (strncmp(_key, "COMMENT", 7) == 0 || strncmp(_key, "HISTORY", 7) == 0) {
00570         *type = QFITS_STRING;
00571 
00572         /*
00573          * qfits returns an empty string if there is no value for a keyword
00574          */
00575 
00576         if (strlen(s) == 0) {
00577             value[0] = '\0';
00578         }
00579         else {
00580             strncpy(value, s, FITS_LINESZ);
00581         }
00582     }
00583     else {
00584         *type = qfits_get_type(s);
00585         strncpy(value, qfits_pretty_string(s), FITS_LINESZ);
00586         value[FITS_LINESZ] = '\0';
00587     }
00588 
00589 
00590     /*
00591      * Parse the comment
00592      */
00593 
00594     s = _comment;
00595 
00596     /*
00597      * qfits returns an empty string if there is no value for a keyword
00598      */
00599 
00600     if (strlen(s) == 0)
00601         comment[0] = '\0';
00602     else {
00603         strncpy(comment, s, FITS_LINESZ);
00604         comment[FITS_LINESZ] = '\0';
00605     }
00606 
00607     return 0;
00608 
00609 }
00610 
00611 
00612 /*
00613  * The function converts a FITS header to a property list ignoring
00614  * keywords for which _uves_propertylist_decode_fits() returns 1. If
00615  * parsing a FITS keyword fails the function returns the status from
00616  * _uves_propertylist_decode_fits(). If the type of a FITS keyword is not
00617  * supported -1 is returned.
00618  */
00619 
00620 inline static cxint
00621 _uves_propertylist_from_fits(uves_propertylist *self,
00622                             const qfits_header *header,
00623                             cx_compare_func filter,
00624                             cxcptr data)
00625 {
00626 
00627     register cxint i;
00628 
00629 
00630     cx_assert(self != NULL);
00631     cx_assert(header != NULL);
00632 
00633 
00634     /*
00635      * Build the property list from the header.
00636      */
00637 
00638     for (i = 0; i < header->n; i++) {
00639         register cxint status;
00640 
00641         cxint type;
00642         cxint ival;
00643 
00644         cxdouble dval;
00645 
00646         cxchar key[FITS_LINESZ + 1];
00647         cxchar value[FITS_LINESZ + 1];
00648         cxchar comment[FITS_LINESZ + 1];
00649 
00650         cpl_property *property;
00651 
00652 
00653         status = _uves_propertylist_decode_fits(header, i, key, &type,
00654                                                value, comment);
00655 
00656         if (status) {
00657             switch (status) {
00658             case 1:
00659                 continue;
00660                 break;
00661 
00662             default:
00663                 return status;
00664                 break;
00665             }
00666         }
00667 
00668 
00669         if (filter != NULL && filter(key, data) == FALSE) {
00670             continue;
00671         }
00672 
00673 
00674         /*
00675          * Create the property from the parsed FITS card.
00676          */
00677 
00678         switch (type) {
00679             case QFITS_BOOLEAN:
00680                 property = cpl_property_new(key, CPL_TYPE_BOOL);
00681 
00682                 ival = *value == 'T' ? 1 : 0;
00683                 cpl_property_set_bool(property, ival);
00684                 cpl_property_set_comment(property, comment);
00685                 break;
00686 
00687             case QFITS_INT:
00688                 property = cpl_property_new(key, CPL_TYPE_INT);
00689 
00690                 sscanf(value, "%d", &ival);
00691                 cpl_property_set_int(property, ival);
00692                 cpl_property_set_comment(property, comment);
00693                 break;
00694 
00695             case QFITS_FLOAT:
00696                 property = cpl_property_new(key, CPL_TYPE_DOUBLE);
00697 
00698                 sscanf(value, "%lf", &dval);
00699                 cpl_property_set_double(property, dval);
00700                 cpl_property_set_comment(property, comment);
00701                 break;
00702 
00703                 /* FIXME: qfits does not correctly report the type for
00704                  *        string values if the single quotes have been
00705                  *        stripped. In this case it reports QFITS_UNKNOWN
00706                  *        for the value's type. As a temporary (!) work
00707                  *        around we accept everything unknown as a string.
00708                  */
00709 
00710             case QFITS_UNKNOWN:
00711             case QFITS_STRING:
00712                 property = cpl_property_new(key, CPL_TYPE_STRING);
00713 
00714                 cpl_property_set_string(property, value);
00715                 cpl_property_set_comment(property, comment);
00716                 break;
00717 
00718             case QFITS_COMPLEX:
00719 
00720                 /* FIXME: Add support for complex keywords. */
00721 
00722             default:
00723                 return 1;
00724                 break;
00725         }
00726 
00727         uves_deque_push_back(self->properties, property);
00728     }
00729 
00730     return 0;
00731 
00732 }
00733 
00734 
00735 
00736 /*
00737  * Public methods
00738  */
00739 
00754 uves_propertylist *
00755 uves_propertylist_new(void)
00756 {
00757 
00758     uves_propertylist *self = cx_malloc(sizeof *self);
00759 
00760     self->properties = uves_deque_new();
00761     return self;
00762 
00763 }
00764 
00765 
00791 uves_propertylist *
00792 uves_propertylist_duplicate(const uves_propertylist *self)
00793 {
00794 
00795     const cxchar *const _id = "uves_propertylist_duplicate";
00796 
00797     uves_deque_iterator first, last;
00798 
00799     uves_propertylist *copy = NULL;
00800 
00801 
00802     if (self == NULL) {
00803         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
00804         return NULL;
00805     }
00806 
00807     cx_assert(self->properties != NULL);
00808 
00809 
00810     copy = uves_propertylist_new();
00811 
00812     first = uves_deque_begin(self->properties);
00813     last = uves_deque_end(self->properties);
00814 
00815     while (first != last) {
00816         cpl_property *tmp = uves_deque_get(self->properties, first);
00817 
00818         uves_deque_push_back(copy->properties, cpl_property_duplicate(tmp));
00819         first = uves_deque_next(self->properties, first);
00820     }
00821 
00822     return copy;
00823 
00824 }
00825 
00826 
00840 void
00841 uves_propertylist_delete(const uves_propertylist *self)
00842 {
00843 
00844     if (self) {
00845         uves_deque_destroy(self->properties, (cx_free_func)cpl_property_delete);
00846         cx_free((void *)self);
00847     }
00848 
00849     return;
00850 
00851 }
00852 
00853 
00880 long
00881 uves_propertylist_get_size(const uves_propertylist *self)
00882 {
00883 
00884     const cxchar *const _id = "uves_propertylist_get_size";
00885 
00886 
00887     if (self == NULL) {
00888         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
00889         return 0L;
00890     }
00891 
00892     return (long) uves_deque_size(self->properties);
00893 
00894 }
00895 
00896 
00922 int
00923 uves_propertylist_is_empty(const uves_propertylist *self)
00924 {
00925 
00926     const cxchar *const _id = "uves_propertylist_is_empty";
00927 
00928 
00929     if (self == NULL) {
00930         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
00931         return -1;
00932     }
00933 
00934     return uves_deque_empty(self->properties);
00935 
00936 }
00937 
00938 
00973 cpl_type
00974 uves_propertylist_get_type(const uves_propertylist *self, const char *name)
00975 {
00976 
00977     const cxchar *const _id = "uves_propertylist_get_type";
00978 
00979     cpl_property *property;
00980 
00981 
00982     if (self == NULL || name == NULL) {
00983         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
00984         return CPL_TYPE_INVALID;
00985     }
00986 
00987     property = _uves_propertylist_get(self, name);
00988 
00989     if (property == NULL) {
00990         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
00991         return CPL_TYPE_INVALID;
00992     }
00993 
00994     return cpl_property_get_type(property);
00995 
00996 }
00997 
00998 
01027 int
01028 uves_propertylist_contains(const uves_propertylist *self, const char *name)
01029 {
01030 
01031     const cxchar *const _id = "uves_propertylist_contains";
01032 
01033 
01034     if (self == NULL || name == NULL) {
01035         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01036         return 0;
01037     }
01038 
01039     return _uves_propertylist_get(self, name) != NULL ? 1 : 0;
01040 
01041 }
01042 
01043 
01081 cpl_error_code
01082 uves_propertylist_set_comment(uves_propertylist *self, const char *name,
01083                              const char *comment)
01084 {
01085 
01086     const cxchar *const _id = "uves_propertylist_set_comment";
01087 
01088     cpl_property *property;
01089 
01090 
01091     if (self == NULL || name == NULL) {
01092         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01093         return CPL_ERROR_NULL_INPUT;
01094     }
01095 
01096     property = _uves_propertylist_get(self, name);
01097 
01098     if (property == NULL) {
01099         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
01100         return CPL_ERROR_DATA_NOT_FOUND;
01101     }
01102 
01103     cpl_property_set_comment(property, comment);
01104 
01105     return CPL_ERROR_NONE;
01106 
01107 }
01108 
01109 
01146 cpl_error_code
01147 uves_propertylist_set_char(uves_propertylist *self, const char *name,
01148                           char value)
01149 {
01150 
01151     const cxchar *const _id = "uves_propertylist_set_char";
01152 
01153     cpl_property *property;
01154 
01155 
01156     if (self == NULL || name == NULL) {
01157         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01158         return CPL_ERROR_NULL_INPUT;
01159     }
01160 
01161     property = _uves_propertylist_get(self, name);
01162 
01163     if (property == NULL) {
01164         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
01165         return CPL_ERROR_DATA_NOT_FOUND;
01166     }
01167 
01168     return cpl_property_set_char(property, value);
01169 
01170 }
01171 
01172 
01209 cpl_error_code
01210 uves_propertylist_set_bool(uves_propertylist *self, const char *name, int value)
01211 {
01212 
01213     const cxchar *const _id = "uves_propertylist_set_bool";
01214 
01215     cpl_property *property;
01216 
01217 
01218     if (self == NULL || name == NULL) {
01219         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01220         return CPL_ERROR_NULL_INPUT;
01221     }
01222 
01223     property = _uves_propertylist_get(self, name);
01224 
01225     if (property == NULL) {
01226         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
01227         return CPL_ERROR_DATA_NOT_FOUND;
01228     }
01229 
01230     return cpl_property_set_bool(property, value);
01231 
01232 }
01233 
01234 
01271 cpl_error_code
01272 uves_propertylist_set_int(uves_propertylist *self, const char *name, int value)
01273 {
01274 
01275     const cxchar *const _id = "uves_propertylist_set_int";
01276 
01277     cpl_property *property;
01278 
01279 
01280     if (self == NULL || name == NULL) {
01281         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01282         return CPL_ERROR_NULL_INPUT;
01283     }
01284 
01285     property = _uves_propertylist_get(self, name);
01286 
01287     if (property == NULL) {
01288         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
01289         return CPL_ERROR_DATA_NOT_FOUND;
01290     }
01291 
01292     return cpl_property_set_int(property, value);
01293 
01294 }
01295 
01296 
01333 cpl_error_code
01334 uves_propertylist_set_long(uves_propertylist *self, const char *name,
01335                           long value)
01336 {
01337 
01338     const cxchar *const _id = "uves_propertylist_set_long";
01339 
01340     cpl_property *property;
01341 
01342 
01343     if (self == NULL || name == NULL) {
01344         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01345         return CPL_ERROR_NULL_INPUT;
01346     }
01347 
01348     property = _uves_propertylist_get(self, name);
01349 
01350     if (property == NULL) {
01351         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
01352         return CPL_ERROR_DATA_NOT_FOUND;
01353     }
01354 
01355     return cpl_property_set_long(property, value);
01356 
01357 }
01358 
01359 
01396 cpl_error_code
01397 uves_propertylist_set_float(uves_propertylist *self, const char *name,
01398                            float value)
01399 {
01400 
01401     const cxchar *const _id = "uves_propertylist_set_float";
01402 
01403     cpl_property *property;
01404 
01405 
01406     if (self == NULL || name == NULL) {
01407         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01408         return CPL_ERROR_NULL_INPUT;
01409     }
01410 
01411     property = _uves_propertylist_get(self, name);
01412 
01413     if (property == NULL) {
01414         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
01415         return CPL_ERROR_DATA_NOT_FOUND;
01416     }
01417 
01418     return cpl_property_set_float(property, value);
01419 
01420 }
01421 
01422 
01459 cpl_error_code
01460 uves_propertylist_set_double(uves_propertylist *self, const char *name,
01461                             double value)
01462 {
01463 
01464     const cxchar *const _id = "uves_propertylist_set_double";
01465 
01466     cpl_property *property;
01467 
01468 
01469     if (self == NULL || name == NULL) {
01470         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01471         return CPL_ERROR_NULL_INPUT;
01472     }
01473 
01474     property = _uves_propertylist_get(self, name);
01475 
01476     if (property == NULL) {
01477         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
01478         return CPL_ERROR_DATA_NOT_FOUND;
01479     }
01480 
01481     return cpl_property_set_double(property, value);
01482 
01483 }
01484 
01485 
01522 cpl_error_code
01523 uves_propertylist_set_string(uves_propertylist *self, const char *name,
01524                             const char *value)
01525 {
01526 
01527     const cxchar *const _id = "uves_propertylist_set_string";
01528 
01529     cpl_property *property;
01530 
01531 
01532     if (self == NULL || name == NULL) {
01533         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01534         return CPL_ERROR_NULL_INPUT;
01535     }
01536 
01537     property = _uves_propertylist_get(self, name);
01538 
01539     if (property == NULL) {
01540         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
01541         return CPL_ERROR_DATA_NOT_FOUND;
01542     }
01543 
01544     return cpl_property_set_string(property, value);
01545 
01546 }
01547 
01548 
01578 const cpl_property *
01579 uves_propertylist_get_const(const uves_propertylist *self, long position)
01580 {
01581 
01582     const cxchar *const _id = "uves_propertylist_get";
01583 
01584 //    register cxsize i = 0;
01585 
01586     uves_deque_iterator first, last;
01587 
01588 
01589     if (self == NULL) {
01590         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01591         return NULL;
01592     }
01593 
01594     if (position < 0) {
01595         return NULL;
01596     }
01597 
01598     first = uves_deque_begin(self->properties);
01599     last = uves_deque_end(self->properties);
01600 
01601 //    while (i < (cxsize)position && first != last) {
01602 //        first = uves_deque_next(self->properties, first);
01603 //        i++;
01604 //    }
01605 
01606     if (first == last) {
01607         return NULL;
01608     }
01609 
01610 //    return uves_deque_get(self->properties, first);
01611     return uves_deque_get(self->properties, position);
01612 
01613 }
01614 
01615 cpl_property *
01616 uves_propertylist_get(uves_propertylist *self, long position)
01617 {
01618     return (cpl_property *)uves_propertylist_get_const(self, position);
01619 }
01620 
01621 
01657 const char *
01658 uves_propertylist_get_comment(const uves_propertylist *self, const char *name)
01659 {
01660 
01661     const cxchar *const _id = "uves_propertylist_get_comment";
01662 
01663     cpl_property *property;
01664 
01665 
01666     if (self == NULL || name == NULL) {
01667         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01668         return NULL;
01669     }
01670 
01671     property = _uves_propertylist_get(self, name);
01672 
01673     if (!property) {
01674         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
01675         return NULL;
01676     }
01677 
01678     return cpl_property_get_comment(property);
01679 
01680 }
01681 
01682 
01724 char
01725 uves_propertylist_get_char(const uves_propertylist *self, const char *name)
01726 {
01727 
01728     const cxchar *const _id = "uves_propertylist_get_char";
01729 
01730     cxchar result;
01731 
01732     cpl_property *property;
01733 
01734 
01735     if (self == NULL || name == NULL) {
01736         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01737         return '\0';
01738     }
01739 
01740     property = _uves_propertylist_get(self, name);
01741 
01742     if (!property) {
01743         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
01744         return '\0';
01745     }
01746 
01747     error_push();
01748 //jmlarsen: this is not exported    cpl_error_push();
01749 
01750     result = cpl_property_get_char(property);
01751 
01752     /*
01753      * If an error occurred change any possibly set location to this
01754      * function.
01755      */
01756 
01757     if (cpl_error_get_code() != CPL_ERROR_NONE) {
01758         cpl_error_set_where(_id);
01759         return '\0';
01760     }
01761 
01762 //jmlarsen: this is not exported    cpl_error_pop();
01763     error_pop();
01764 
01765     return result;
01766 
01767 }
01768 
01769 
01813 int
01814 uves_propertylist_get_bool(const uves_propertylist *self, const char *name)
01815 {
01816 
01817     const cxchar *const _id = "uves_propertylist_get_bool";
01818 
01819     cxbool result;
01820 
01821     cpl_property *property;
01822 
01823 
01824     if (self == NULL || name == NULL) {
01825         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01826         return 0;
01827     }
01828 
01829     property = _uves_propertylist_get(self, name);
01830 
01831     if (!property) {
01832         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
01833         return 0;
01834     }
01835 
01836     error_push();
01837 //jmlarsen: this is not exported    cpl_error_push();
01838 
01839     result = cpl_property_get_bool(property);
01840 
01841     /*
01842      * If an error occurred change any possibly set location to this
01843      * function.
01844      */
01845 
01846     if (cpl_error_get_code() != CPL_ERROR_NONE) {
01847         cpl_error_set_where(_id);
01848         return 0;
01849     }
01850 
01851 //jmlarsen: this is not exported    cpl_error_pop();
01852     error_pop();
01853 
01854     return result == TRUE ? 1 : 0;
01855 
01856 }
01857 
01858 
01900 int
01901 uves_propertylist_get_int(const uves_propertylist *self, const char *name)
01902 {
01903 
01904     const cxchar *const _id = "uves_propertylist_get_int";
01905 
01906     cxint result;
01907 
01908     cpl_property *property;
01909 
01910 
01911     if (self == NULL || name == NULL) {
01912         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01913         return 0;
01914     }
01915 
01916     property = _uves_propertylist_get(self, name);
01917 
01918     if (!property) {
01919         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
01920         return 0;
01921     }
01922 
01923     error_push();
01924 //jmlarsen: this is not exported    cpl_error_push();
01925 
01926     result = cpl_property_get_int(property);
01927 
01928     /*
01929      * If an error occurred change any possibly set location to this
01930      * function.
01931      */
01932 
01933     if (cpl_error_get_code() != CPL_ERROR_NONE) {
01934         cpl_error_set_where(_id);
01935         return 0;
01936     }
01937 
01938 //jmlarsen: this is not exported    cpl_error_pop();
01939     error_pop();
01940 
01941     return result;
01942 
01943 }
01944 
01945 
01987 long
01988 uves_propertylist_get_long(const uves_propertylist *self, const char *name)
01989 {
01990 
01991     const cxchar *const _id = "uves_propertylist_get_long";
01992 
01993     cxlong result;
01994 
01995     cpl_property *property;
01996 
01997 
01998     if (self == NULL || name == NULL) {
01999         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02000         return 0;
02001     }
02002 
02003     property = _uves_propertylist_get(self, name);
02004 
02005     if (!property) {
02006         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
02007         return 0;
02008     }
02009 
02010     error_push();
02011 //jmlarsen: this is not exported    cpl_error_push();
02012 
02013     result = cpl_property_get_long(property);
02014 
02015     /*
02016      * If an error occurred change any possibly set location to this
02017      * function.
02018      */
02019 
02020     if (cpl_error_get_code() != CPL_ERROR_NONE) {
02021         cpl_error_set_where(_id);
02022         return 0;
02023     }
02024 
02025 //jmlarsen: this is not exported    cpl_error_pop();
02026     error_pop();
02027 
02028     return result;
02029 
02030 }
02031 
02032 
02074 float
02075 uves_propertylist_get_float(const uves_propertylist *self, const char *name)
02076 {
02077 
02078     const cxchar *const _id = "uves_propertylist_get_float";
02079 
02080     cxfloat result;
02081 
02082     cpl_property *property;
02083 
02084 
02085     if (self == NULL || name == NULL) {
02086         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02087         return 0;
02088     }
02089 
02090     property = _uves_propertylist_get(self, name);
02091 
02092     if (!property) {
02093         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
02094         return 0;
02095     }
02096 
02097     error_push();
02098 //jmlarsen: this is not exported    cpl_error_push();
02099 
02100     result = cpl_property_get_float(property);
02101 
02102     /*
02103      * If an error occurred change any possibly set location to this
02104      * function.
02105      */
02106 
02107     if (cpl_error_get_code() != CPL_ERROR_NONE) {
02108         cpl_error_set_where(_id);
02109         return 0;
02110     }
02111 
02112 //jmlarsen: this is not exported    cpl_error_pop();
02113     error_pop();
02114 
02115     return result;
02116 
02117 }
02118 
02119 
02161 double
02162 uves_propertylist_get_double(const uves_propertylist *self, const char *name)
02163 {
02164 
02165     const cxchar *const _id = "uves_propertylist_get_double";
02166 
02167     cxdouble result;
02168 
02169     cpl_property *property;
02170 
02171 
02172     if (self == NULL || name == NULL) {
02173         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02174         return 0;
02175     }
02176 
02177     property = _uves_propertylist_get(self, name);
02178 
02179     if (!property) {
02180         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
02181         return 0;
02182     }
02183 
02184     error_push();
02185 //jmlarsen: this is not exported    cpl_error_push();
02186 
02187     result = cpl_property_get_double(property);
02188 
02189     /*
02190      * If an error occurred change any possibly set location to this
02191      * function.
02192      */
02193 
02194     if (cpl_error_get_code() != CPL_ERROR_NONE) {
02195         cpl_error_set_where(_id);
02196         return 0;
02197     }
02198 
02199 //jmlarsen: this is not exported    cpl_error_pop();
02200     error_pop();
02201 
02202     return result;
02203 
02204 }
02205 
02206 
02250 const char *
02251 uves_propertylist_get_string(const uves_propertylist *self, const char *name)
02252 {
02253 
02254     const cxchar *const _id = "uves_propertylist_get_string";
02255 
02256     const cxchar *result;
02257 
02258     cpl_property *property;
02259 
02260 
02261     if (self == NULL || name == NULL) {
02262         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02263         return NULL;
02264     }
02265 
02266     property = _uves_propertylist_get(self, name);
02267 
02268     if (!property) {
02269         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
02270         return NULL;
02271     }
02272 
02273     error_push();
02274 //jmlarsen: this is not exported    cpl_error_push();
02275 
02276     result = cpl_property_get_string(property);
02277 
02278     /*
02279      * If an error occurred change any possibly set location to this
02280      * function.
02281      */
02282 
02283     if (cpl_error_get_code() != CPL_ERROR_NONE) {
02284         cpl_error_set_where(_id);
02285         return NULL;
02286     }
02287 
02288 //jmlarsen: this is not exported    cpl_error_pop();
02289     error_pop();
02290 
02291     return result;
02292 
02293 }
02294 
02295 
02333 cpl_error_code
02334 uves_propertylist_insert_char(uves_propertylist *self, const char *here,
02335                              const char *name, char value)
02336 {
02337 
02338     const cxchar *const _id = "uves_propertylist_insert_char";
02339 
02340     cxint status = 0;
02341 
02342 
02343     if (self == NULL || here == NULL || name == NULL) {
02344         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02345         return CPL_ERROR_NULL_INPUT;
02346     }
02347 
02348     status = _uves_propertylist_insert(self, here, FALSE, name,
02349                                       CPL_TYPE_CHAR, &value);
02350 
02351     if (status) {
02352         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
02353         return CPL_ERROR_UNSPECIFIED;
02354     }
02355 
02356     return CPL_ERROR_NONE;
02357 
02358 }
02359 
02360 
02398 cpl_error_code
02399 uves_propertylist_insert_bool(uves_propertylist *self, const char *here,
02400                              const char *name, int value)
02401 {
02402 
02403     const cxchar *const _id = "uves_propertylist_insert_bool";
02404 
02405     cxint status = 0;
02406 
02407 
02408     if (self == NULL || here == NULL || name == NULL) {
02409         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02410         return CPL_ERROR_NULL_INPUT;
02411     }
02412 
02413     status =  _uves_propertylist_insert(self, here, FALSE, name,
02414                                        CPL_TYPE_BOOL, &value);
02415 
02416     if (status) {
02417         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
02418         return CPL_ERROR_UNSPECIFIED;
02419     }
02420 
02421     return CPL_ERROR_NONE;
02422 
02423 }
02424 
02425 
02463 cpl_error_code
02464 uves_propertylist_insert_int(uves_propertylist *self, const char *here,
02465                             const char *name, int value)
02466 {
02467 
02468     const cxchar *const _id = "uves_propertylist_insert_int";
02469 
02470     cxint status = 0;
02471 
02472 
02473     if (self == NULL || here == NULL || name == NULL) {
02474         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02475         return CPL_ERROR_NULL_INPUT;
02476     }
02477 
02478     status = _uves_propertylist_insert(self, here, FALSE, name,
02479                                       CPL_TYPE_INT, &value);
02480 
02481     if (status) {
02482         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
02483         return CPL_ERROR_UNSPECIFIED;
02484     }
02485 
02486     return CPL_ERROR_NONE;
02487 
02488 }
02489 
02490 
02528 cpl_error_code
02529 uves_propertylist_insert_long(uves_propertylist *self, const char *here,
02530                              const char *name, long value)
02531 {
02532 
02533     const cxchar *const _id = "uves_propertylist_insert_long";
02534 
02535     cxint status = 0;
02536 
02537 
02538     if (self == NULL || here == NULL || name == NULL) {
02539         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02540         return CPL_ERROR_NULL_INPUT;
02541     }
02542 
02543     status = _uves_propertylist_insert(self, here, FALSE, name,
02544                                       CPL_TYPE_LONG, &value);
02545 
02546     if (status) {
02547         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
02548         return CPL_ERROR_UNSPECIFIED;
02549     }
02550 
02551     return CPL_ERROR_NONE;
02552 
02553 }
02554 
02555 
02593 cpl_error_code
02594 uves_propertylist_insert_float(uves_propertylist *self, const char *here,
02595                               const char *name, float value)
02596 {
02597 
02598     const cxchar *const _id = "uves_propertylist_insert_float";
02599 
02600     cxint status = 0;
02601 
02602 
02603     if (self == NULL || here == NULL || name == NULL) {
02604         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02605         return CPL_ERROR_NULL_INPUT;
02606     }
02607 
02608     status = _uves_propertylist_insert(self, here, FALSE, name,
02609                                       CPL_TYPE_FLOAT, &value);
02610 
02611     if (status) {
02612         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
02613         return CPL_ERROR_UNSPECIFIED;
02614     }
02615 
02616     return CPL_ERROR_NONE;
02617 
02618 }
02619 
02620 
02658 cpl_error_code
02659 uves_propertylist_insert_double(uves_propertylist *self, const char *here,
02660                                const char *name, double value)
02661 {
02662 
02663     const cxchar *const _id = "uves_propertylist_insert_char";
02664 
02665     cxint status = 0;
02666 
02667 
02668     if (self == NULL || here == NULL || name == NULL) {
02669         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02670         return CPL_ERROR_NULL_INPUT;
02671     }
02672 
02673     status = _uves_propertylist_insert(self, here, FALSE, name,
02674                                       CPL_TYPE_DOUBLE, &value);
02675 
02676     if (status) {
02677         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
02678         return CPL_ERROR_UNSPECIFIED;
02679     }
02680 
02681     return CPL_ERROR_NONE;
02682 
02683 }
02684 
02685 
02723 cpl_error_code
02724 uves_propertylist_insert_string(uves_propertylist *self, const char *here,
02725                                const char *name, const char *value)
02726 {
02727 
02728     const cxchar *const _id = "uves_propertylist_insert_string";
02729 
02730     cxint status = 0;
02731 
02732 
02733     if (self == NULL || here == NULL || name == NULL) {
02734         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02735         return CPL_ERROR_NULL_INPUT;
02736     }
02737 
02738     status = _uves_propertylist_insert(self, here, FALSE, name,
02739                                       CPL_TYPE_STRING, (cxptr)value);
02740 
02741     if (status) {
02742         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
02743         return CPL_ERROR_UNSPECIFIED;
02744     }
02745 
02746     return CPL_ERROR_NONE;
02747 
02748 }
02749 
02750 
02788 cpl_error_code
02789 uves_propertylist_insert_after_char(uves_propertylist *self, const char *after,
02790                                    const char *name, char value)
02791 {
02792 
02793     const cxchar *const _id = "uves_propertylist_insert_after_char";
02794 
02795     cxint status = 0;
02796 
02797 
02798     if (self == NULL || after == NULL || name == NULL) {
02799         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02800         return CPL_ERROR_NULL_INPUT;
02801     }
02802 
02803     status = _uves_propertylist_insert(self, after, TRUE, name,
02804                                       CPL_TYPE_CHAR, &value);
02805 
02806     if (status) {
02807         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
02808         return CPL_ERROR_UNSPECIFIED;
02809     }
02810 
02811     return CPL_ERROR_NONE;
02812 
02813 }
02814 
02815 
02853 cpl_error_code
02854 uves_propertylist_insert_after_bool(uves_propertylist *self, const char *after,
02855                                    const char *name, int value)
02856 {
02857 
02858     const cxchar *const _id = "uves_propertylist_insert_after_bool";
02859 
02860     cxint status = 0;
02861 
02862 
02863     if (self == NULL || after == NULL || name == NULL) {
02864         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02865         return CPL_ERROR_NULL_INPUT;
02866     }
02867 
02868     status = _uves_propertylist_insert(self, after, TRUE, name,
02869                                       CPL_TYPE_BOOL, &value);
02870 
02871     if (status) {
02872         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
02873         return CPL_ERROR_UNSPECIFIED;
02874     }
02875 
02876     return CPL_ERROR_NONE;
02877 
02878 }
02879 
02880 
02918 cpl_error_code
02919 uves_propertylist_insert_after_int(uves_propertylist *self, const char *after,
02920                                   const char *name, int value)
02921 {
02922 
02923     const cxchar *const _id = "uves_propertylist_insert_after_int";
02924 
02925     cxint status = 0;
02926 
02927 
02928     if (self == NULL || after == NULL || name == NULL) {
02929         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02930         return CPL_ERROR_NULL_INPUT;
02931     }
02932 
02933     status = _uves_propertylist_insert(self, after, TRUE, name,
02934                                       CPL_TYPE_INT, &value);
02935 
02936     if (status) {
02937         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
02938         return CPL_ERROR_UNSPECIFIED;
02939     }
02940 
02941     return CPL_ERROR_NONE;
02942 
02943 }
02944 
02945 
02983 cpl_error_code
02984 uves_propertylist_insert_after_long(uves_propertylist *self, const char *after,
02985                                    const char *name, long value)
02986 {
02987 
02988     const cxchar *const _id = "uves_propertylist_insert_after_long";
02989 
02990     cxint status = 0;
02991 
02992 
02993     if (self == NULL || after == NULL || name == NULL) {
02994         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02995         return CPL_ERROR_NULL_INPUT;
02996     }
02997 
02998     status = _uves_propertylist_insert(self, after, TRUE, name,
02999                                       CPL_TYPE_LONG, &value);
03000 
03001     if (status) {
03002         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
03003         return CPL_ERROR_UNSPECIFIED;
03004     }
03005 
03006     return CPL_ERROR_NONE;
03007 
03008 }
03009 
03010 
03048 cpl_error_code
03049 uves_propertylist_insert_after_float(uves_propertylist *self, const char *after,
03050                                     const char *name, float value)
03051 {
03052 
03053     const cxchar *const _id = "uves_propertylist_insert_after_float";
03054 
03055     cxint status = 0;
03056 
03057 
03058     if (self == NULL || after == NULL || name == NULL) {
03059         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03060         return CPL_ERROR_NULL_INPUT;
03061     }
03062 
03063     status = _uves_propertylist_insert(self, after, TRUE, name,
03064                                       CPL_TYPE_FLOAT, &value);
03065 
03066     if (status) {
03067         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
03068         return CPL_ERROR_UNSPECIFIED;
03069     }
03070 
03071     return CPL_ERROR_NONE;
03072 
03073 }
03074 
03075 
03113 cpl_error_code
03114 uves_propertylist_insert_after_double(uves_propertylist *self,
03115                                      const char *after, const char *name,
03116                                      double value)
03117 {
03118 
03119     const cxchar *const _id = "uves_propertylist_insert_after_double";
03120 
03121     cxint status = 0;
03122 
03123 
03124     if (self == NULL || after == NULL || name == NULL) {
03125         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03126         return CPL_ERROR_NULL_INPUT;
03127     }
03128 
03129     status = _uves_propertylist_insert(self, after, TRUE, name,
03130                                       CPL_TYPE_DOUBLE, &value);
03131 
03132     if (status) {
03133         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
03134         return CPL_ERROR_UNSPECIFIED;
03135     }
03136 
03137     return CPL_ERROR_NONE;
03138 
03139 }
03140 
03141 
03179 cpl_error_code
03180 uves_propertylist_insert_after_string(uves_propertylist *self,
03181                                      const char *after, const char *name,
03182                                      const char *value)
03183 {
03184 
03185     const cxchar *const _id = "uves_propertylist_insert_after_string";
03186 
03187     cxint status = 0;
03188 
03189 
03190     if (self == NULL || after == NULL || name == NULL) {
03191         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03192         return CPL_ERROR_NULL_INPUT;
03193     }
03194 
03195     status =  _uves_propertylist_insert(self, after, TRUE, name,
03196                                        CPL_TYPE_STRING, (cxptr)value);
03197 
03198     if (status) {
03199         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
03200         return CPL_ERROR_UNSPECIFIED;
03201     }
03202 
03203     return CPL_ERROR_NONE;
03204 
03205 }
03206 
03207 
03236 cpl_error_code
03237 uves_propertylist_prepend_char(uves_propertylist *self, const char *name,
03238                               char value)
03239 {
03240 
03241     const cxchar *const _id = "uves_propertylist_prepend_char";
03242 
03243     cpl_property *property = NULL;
03244 
03245 
03246     if (self == NULL || name == NULL) {
03247         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03248         return CPL_ERROR_NULL_INPUT;
03249     }
03250 
03251     property = cpl_property_new(name, CPL_TYPE_CHAR);
03252     cx_assert(property != NULL);
03253 
03254     cpl_property_set_char(property, value);
03255     uves_deque_push_front(self->properties, property);
03256 
03257     return CPL_ERROR_NONE;
03258 
03259 }
03260 
03261 
03290 cpl_error_code
03291 uves_propertylist_prepend_bool(uves_propertylist *self, const char *name,
03292                               int value)
03293 {
03294 
03295     const cxchar *const _id = "uves_propertylist_prepend_bool";
03296 
03297     cpl_property *property = NULL;
03298 
03299 
03300     if (self == NULL || name == NULL) {
03301         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03302         return CPL_ERROR_NULL_INPUT;
03303     }
03304 
03305     property = cpl_property_new(name, CPL_TYPE_BOOL);
03306     cx_assert(property != NULL);
03307 
03308     cpl_property_set_bool(property, value);
03309     uves_deque_push_front(self->properties, property);
03310 
03311     return CPL_ERROR_NONE;
03312 
03313 }
03314 
03315 
03344 cpl_error_code
03345 uves_propertylist_prepend_int(uves_propertylist *self, const char *name,
03346                              int value)
03347 {
03348 
03349     const cxchar *const _id = "uves_propertylist_prepend_int";
03350 
03351     cpl_property *property = NULL;
03352 
03353 
03354     if (self == NULL || name == NULL) {
03355         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03356         return CPL_ERROR_NULL_INPUT;
03357     }
03358 
03359     property = cpl_property_new(name, CPL_TYPE_INT);
03360     cx_assert(property != NULL);
03361 
03362     cpl_property_set_int(property, value);
03363     uves_deque_push_front(self->properties, property);
03364 
03365     return CPL_ERROR_NONE;
03366 
03367 }
03368 
03369 
03398 cpl_error_code
03399 uves_propertylist_prepend_long(uves_propertylist *self, const char *name,
03400                               long value)
03401 {
03402 
03403     const cxchar *const _id = "uves_propertylist_prepend_long";
03404 
03405     cpl_property *property = NULL;
03406 
03407 
03408     if (self == NULL || name == NULL) {
03409         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03410         return CPL_ERROR_NULL_INPUT;
03411     }
03412 
03413     property = cpl_property_new(name, CPL_TYPE_LONG);
03414     cx_assert(property != NULL);
03415 
03416     cpl_property_set_long(property, value);
03417     uves_deque_push_front(self->properties, property);
03418 
03419     return CPL_ERROR_NONE;
03420 
03421 }
03422 
03423 
03452 cpl_error_code
03453 uves_propertylist_prepend_float(uves_propertylist *self, const char *name,
03454                                float value)
03455 {
03456 
03457     const cxchar *const _id = "uves_propertylist_prepend_float";
03458 
03459     cpl_property *property = NULL;
03460 
03461 
03462     if (self == NULL || name == NULL) {
03463         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03464         return CPL_ERROR_NULL_INPUT;
03465     }
03466 
03467     property = cpl_property_new(name, CPL_TYPE_FLOAT);
03468     cx_assert(property != NULL);
03469 
03470     cpl_property_set_float(property, value);
03471     uves_deque_push_front(self->properties, property);
03472 
03473     return CPL_ERROR_NONE;
03474 
03475 }
03476 
03477 
03506 cpl_error_code
03507 uves_propertylist_prepend_double(uves_propertylist *self, const char *name,
03508                                 double value)
03509 {
03510 
03511     const cxchar *const _id = "uves_propertylist_prepend_double";
03512 
03513     cpl_property *property = NULL;
03514 
03515 
03516     if (self == NULL || name == NULL) {
03517         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03518         return CPL_ERROR_NULL_INPUT;
03519     }
03520 
03521     property = cpl_property_new(name, CPL_TYPE_DOUBLE);
03522     cx_assert(property != NULL);
03523 
03524     cpl_property_set_double(property, value);
03525     uves_deque_push_front(self->properties, property);
03526 
03527     return CPL_ERROR_NONE;
03528 
03529 }
03530 
03531 
03560 cpl_error_code
03561 uves_propertylist_prepend_string(uves_propertylist *self, const char *name,
03562                                 const char *value)
03563 {
03564 
03565     const cxchar *const _id = "uves_propertylist_prepend_string";
03566 
03567     cpl_property *property = NULL;
03568 
03569 
03570     if (self == NULL || name == NULL) {
03571         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03572         return CPL_ERROR_NULL_INPUT;
03573     }
03574 
03575     property = cpl_property_new(name, CPL_TYPE_STRING);
03576     cx_assert(property != NULL);
03577 
03578     cpl_property_set_string(property, value);
03579     uves_deque_push_front(self->properties, property);
03580 
03581     return CPL_ERROR_NONE;
03582 
03583 }
03584 
03585 
03586 
03587 cpl_error_code
03588 uves_propertylist_append_char(uves_propertylist *self, const char *name,
03589                              char value)
03590 {
03591     return uves_propertylist_append_c_char(self, name, value, NULL);
03592 }
03593 cpl_error_code
03594 uves_propertylist_append_bool(uves_propertylist *self, const char *name,
03595                              int value)
03596 {
03597     return uves_propertylist_append_c_bool(self, name, value, NULL);
03598 }
03599 
03600 cpl_error_code
03601 uves_propertylist_append_int(uves_propertylist *self, const char *name,
03602                             int value)
03603 {
03604     return uves_propertylist_append_c_int(self, name, value, NULL);
03605 }
03606 
03607 cpl_error_code
03608 uves_propertylist_append_long(uves_propertylist *self, const char *name,
03609                              long value)
03610 {
03611     return uves_propertylist_append_c_long(self, name, value, NULL);
03612 }
03613 
03614 cpl_error_code
03615 uves_propertylist_append_float(uves_propertylist *self, const char *name,
03616                               float value)
03617 {
03618     return uves_propertylist_append_c_float(self, name, value, NULL);
03619 }
03620 
03621 cpl_error_code
03622 uves_propertylist_append_double(uves_propertylist *self, const char *name,
03623                                double value)
03624 {
03625     return uves_propertylist_append_c_double(self, name, value, NULL);
03626 }
03627 
03628 cpl_error_code
03629 uves_propertylist_append_string(uves_propertylist *self, const char *name,
03630                                const char *value)
03631 {
03632     return uves_propertylist_append_c_string(self, name, value, NULL);
03633 }
03634 
03635 
03636 
03637 
03638 
03639 
03640 
03641 
03642 
03643 
03644 
03645 
03646 
03647 
03648 
03649 
03650 
03651 
03680 cpl_error_code
03681 uves_propertylist_append_c_char(uves_propertylist *self, const char *name,
03682                              char value, const char *comment)
03683 {
03684 
03685     const cxchar *const _id = "uves_propertylist_append_char";
03686 
03687     cpl_property *property = NULL;
03688 
03689 
03690     if (self == NULL || name == NULL) {
03691         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03692         return CPL_ERROR_NULL_INPUT;
03693     }
03694 
03695     property = cpl_property_new(name, CPL_TYPE_CHAR);
03696     cx_assert(property != NULL);
03697 
03698     if (comment != NULL) cpl_property_set_comment(property, comment);
03699 
03700     cpl_property_set_char(property, value);
03701     uves_deque_push_back(self->properties, property);
03702 
03703     return CPL_ERROR_NONE;
03704 
03705 }
03706 
03707 
03736 cpl_error_code
03737 uves_propertylist_append_c_bool(uves_propertylist *self, const char *name,
03738                              int value, const char *comment)
03739 {
03740 
03741     const cxchar *const _id = "uves_propertylist_append_bool";
03742 
03743     cpl_property *property = NULL;
03744 
03745 
03746     if (self == NULL || name == NULL) {
03747         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03748         return CPL_ERROR_NULL_INPUT;
03749     }
03750 
03751     property = cpl_property_new(name, CPL_TYPE_BOOL);
03752     cx_assert(property != NULL);
03753 
03754     if (comment != NULL) cpl_property_set_comment(property, comment);
03755 
03756     cpl_property_set_bool(property, value);
03757     uves_deque_push_back(self->properties, property);
03758 
03759     return CPL_ERROR_NONE;
03760 
03761 }
03762 
03763 
03792 cpl_error_code
03793 uves_propertylist_append_c_int(uves_propertylist *self, const char *name,
03794                             int value, const char *comment)
03795 {
03796 
03797     const cxchar *const _id = "uves_propertylist_append_int";
03798 
03799     cpl_property *property = NULL;
03800 
03801 
03802     if (self == NULL || name == NULL) {
03803         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03804         return CPL_ERROR_NULL_INPUT;
03805     }
03806 
03807     property = cpl_property_new(name, CPL_TYPE_INT);
03808     cx_assert(property != NULL);
03809 
03810     if (comment != NULL) cpl_property_set_comment(property, comment);
03811 
03812     cpl_property_set_int(property, value);
03813     uves_deque_push_back(self->properties, property);
03814 
03815     return CPL_ERROR_NONE;
03816 
03817 }
03818 
03819 
03848 cpl_error_code
03849 uves_propertylist_append_c_long(uves_propertylist *self, const char *name,
03850                              long value, const char *comment)
03851 {
03852 
03853     const cxchar *const _id = "uves_propertylist_append_long";
03854 
03855     cpl_property *property = NULL;
03856 
03857 
03858     if (self == NULL || name == NULL) {
03859         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03860         return CPL_ERROR_NULL_INPUT;
03861     }
03862 
03863     property = cpl_property_new(name, CPL_TYPE_LONG);
03864     cx_assert(property != NULL);
03865 
03866     if (comment != NULL) cpl_property_set_comment(property, comment);
03867 
03868     cpl_property_set_long(property, value);
03869     uves_deque_push_back(self->properties, property);
03870 
03871     return CPL_ERROR_NONE;
03872 
03873 }
03874 
03875 
03904 cpl_error_code
03905 uves_propertylist_append_c_float(uves_propertylist *self, const char *name,
03906                               float value, const char *comment)
03907 {
03908 
03909     const cxchar *const _id = "uves_propertylist_append_float";
03910 
03911     cpl_property *property = NULL;
03912 
03913 
03914     if (self == NULL || name == NULL) {
03915         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03916         return CPL_ERROR_NULL_INPUT;
03917     }
03918 
03919     property = cpl_property_new(name, CPL_TYPE_FLOAT);
03920     cx_assert(property != NULL);
03921 
03922     if (comment != NULL) cpl_property_set_comment(property, comment);
03923 
03924     cpl_property_set_float(property, value);
03925     uves_deque_push_back(self->properties, property);
03926 
03927     return CPL_ERROR_NONE;
03928 
03929 }
03930 
03931 
03960 cpl_error_code
03961 uves_propertylist_append_c_double(uves_propertylist *self, const char *name,
03962                                double value, const char *comment)
03963 {
03964 
03965     const cxchar *const _id = "uves_propertylist_append_double";
03966 
03967     cpl_property *property = NULL;
03968 
03969 
03970     if (self == NULL || name == NULL) {
03971         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03972         return CPL_ERROR_NULL_INPUT;
03973     }
03974 
03975     property = cpl_property_new(name, CPL_TYPE_DOUBLE);
03976     cx_assert(property != NULL);
03977 
03978     if (comment != NULL) cpl_property_set_comment(property, comment);
03979 
03980     cpl_property_set_double(property, value);
03981     uves_deque_push_back(self->properties, property);
03982 
03983     return CPL_ERROR_NONE;
03984 
03985 }
03986 
03987 
04016 cpl_error_code
04017 uves_propertylist_append_c_string(uves_propertylist *self, const char *name,
04018                                const char *value, const char *comment)
04019 {
04020 
04021     const cxchar *const _id = "uves_propertylist_append_string";
04022 
04023     cpl_property *property = NULL;
04024 
04025 
04026     if (self == NULL || name == NULL) {
04027         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
04028         return CPL_ERROR_NULL_INPUT;
04029     }
04030 
04031     property = cpl_property_new(name, CPL_TYPE_STRING);
04032     cx_assert(property != NULL);
04033 
04034     if (comment != NULL) cpl_property_set_comment(property, comment);
04035 
04036     cpl_property_set_string(property, value);
04037     uves_deque_push_back(self->properties, property);
04038 
04039     return CPL_ERROR_NONE;
04040 
04041 }
04042 
04043 
04070 cpl_error_code
04071 uves_propertylist_append(uves_propertylist *self,
04072                         const uves_propertylist *other)
04073 {
04074 
04075     const cxchar *const _id = "uves_propertylist_append";
04076 
04077     if (self == NULL) {
04078         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
04079         return CPL_ERROR_NULL_INPUT;
04080     }
04081 
04082     if (other != NULL) {
04083 
04084         uves_deque_const_iterator pos = uves_deque_begin(other->properties);
04085 
04086         while (pos != uves_deque_end(other->properties)) {
04087 
04088             const cpl_property *p = uves_deque_get(other->properties, pos);
04089 
04090             uves_deque_push_back(self->properties, cpl_property_duplicate(p));
04091             pos = uves_deque_next(other->properties, pos);
04092 
04093         }
04094 
04095     }
04096 
04097     return CPL_ERROR_NONE;
04098 
04099 }
04100 
04101 
04132 int
04133 uves_propertylist_erase(uves_propertylist *self, const char *name)
04134 {
04135 
04136     const cxchar *const _id = "uves_propertylist_erase";
04137 
04138     uves_deque_iterator pos;
04139 
04140 
04141     if (self == NULL || name == NULL) {
04142         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
04143         return 0;
04144     }
04145 
04146     pos = _uves_propertylist_find(self, name);
04147     if (pos == uves_deque_end(self->properties)) {
04148         return 0;
04149     }
04150 //        fprintf(stderr, "%d\n", __LINE__);
04151 
04152     uves_deque_erase(self->properties, pos, (cx_free_func)cpl_property_delete);
04153 
04154     return 1;
04155 
04156 }
04157 
04193 int
04194 uves_propertylist_erase_regexp(uves_propertylist *self, const char *regexp,
04195                               int invert)
04196 {
04197 
04198     const cxchar *const _id = "uves_propertylist_erase_regexp";
04199 
04200     cxint status = 0;
04201     cxint count = 0;
04202 
04203     uves_deque_iterator first, last, pos;
04204 
04205     cpl_property    *p;
04206 
04207     uves_regexp filter;
04208 
04209 
04210     if (self == NULL || regexp == NULL) {
04211         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
04212         return 0;
04213     }
04214 
04215 
04216     status = regcomp(&filter.re, regexp, REG_EXTENDED | REG_NOSUB);
04217     if (status) {
04218         cpl_error_set(_id, CPL_ERROR_ILLEGAL_INPUT);
04219         return 0;
04220     }
04221 
04222     filter.invert = invert == 0 ? FALSE : TRUE;
04223 
04224     first = uves_deque_begin(self->properties);
04225     last  = uves_deque_end(self->properties);
04226 
04227     while (first < uves_deque_end(self->properties)) {
04228         pos = first;
04229 //        first = uves_deque_next(self->properties, first);
04230 
04231         p = uves_deque_get(self->properties, pos);
04232         if (_uves_propertylist_compare_regexp(p, &filter) == TRUE) {
04233 
04234 //            fprintf(stderr, "%d\n", __LINE__);
04235 
04236             uves_deque_erase(self->properties, pos,
04237                           (cx_free_func)cpl_property_delete);
04238             count++;
04239         }
04240         else
04241             first = uves_deque_next(self->properties, first);
04242     }
04243 
04244     regfree(&filter.re);
04245 
04246     return count;
04247 
04248 }
04249 
04250 
04275 void
04276 uves_propertylist_empty(uves_propertylist *self)
04277 {
04278 
04279     const cxchar *const _id = "uves_propertylist_empty";
04280 
04281     uves_deque_iterator first, last;
04282 
04283 
04284     if (self == NULL) {
04285         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
04286         return;
04287     }
04288 
04289     first = uves_deque_begin(self->properties);
04290     last = uves_deque_end(self->properties);
04291 
04292     while (first < uves_deque_end(self->properties)) {
04293         uves_deque_iterator pos = first;
04294         
04295 //        first = uves_deque_next(self->properties, first);
04296 //        fprintf(stderr, "%d  %d %d %d\n", __LINE__, first, last, pos);
04297         uves_deque_erase(self->properties, pos,
04298                       (cx_free_func)cpl_property_delete);
04299 
04300 //        first = uves_deque_next(self->properties, first);
04301     }
04302 
04303     return;
04304 
04305 }
04306 
04307 
04346 cpl_error_code
04347 uves_propertylist_update_char(uves_propertylist *self, const char *name,
04348                              char value)
04349 {
04350 
04351     const cxchar *const _id = "uves_propertylist_update_char";
04352 
04353     uves_deque_iterator pos;
04354 
04355 
04356     if (self == NULL || name == NULL) {
04357         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
04358         return CPL_ERROR_NULL_INPUT;
04359     }
04360 
04361     pos = _uves_propertylist_find(self, name);
04362 
04363     if (pos == uves_deque_end(self->properties)) {
04364 
04365         cpl_property *property = cpl_property_new(name, CPL_TYPE_CHAR);
04366 
04367 
04368         cx_assert(property != NULL);
04369 
04370         cpl_property_set_char(property, value);
04371         uves_deque_push_back(self->properties, property);
04372     }
04373     else {
04374 
04375         cpl_property *property = uves_deque_get(self->properties, pos);
04376 
04377 
04378         cx_assert(property != NULL);
04379 
04380         if (cpl_property_get_type(property) != CPL_TYPE_CHAR) {
04381             cpl_error_set(_id, CPL_ERROR_TYPE_MISMATCH);
04382             return CPL_ERROR_TYPE_MISMATCH;
04383         }
04384 
04385         cpl_property_set_char(property, value);
04386 
04387     }
04388 
04389     return CPL_ERROR_NONE;
04390 
04391 }
04392 
04393 
04432 cpl_error_code
04433 uves_propertylist_update_bool(uves_propertylist *self, const char *name,
04434                              int value)
04435 {
04436 
04437     const cxchar *const _id = "uves_propertylist_update_bool";
04438 
04439     uves_deque_iterator pos;
04440 
04441 
04442     if (self == NULL || name == NULL) {
04443         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
04444         return CPL_ERROR_NULL_INPUT;
04445     }
04446 
04447     pos = _uves_propertylist_find(self, name);
04448 
04449     if (pos == uves_deque_end(self->properties)) {
04450 
04451         cpl_property *property = cpl_property_new(name, CPL_TYPE_BOOL);
04452 
04453 
04454         cx_assert(property != NULL);
04455 
04456         cpl_property_set_bool(property, value);
04457         uves_deque_push_back(self->properties, property);
04458     }
04459     else {
04460 
04461         cpl_property *property = uves_deque_get(self->properties, pos);
04462 
04463 
04464         cx_assert(property != NULL);
04465 
04466         if (cpl_property_get_type(property) != CPL_TYPE_BOOL) {
04467             cpl_error_set(_id, CPL_ERROR_TYPE_MISMATCH);
04468             return CPL_ERROR_TYPE_MISMATCH;
04469         }
04470 
04471         cpl_property_set_bool(property, value);
04472 
04473     }
04474 
04475     return CPL_ERROR_NONE;
04476 
04477 }
04478 
04479 
04518 cpl_error_code
04519 uves_propertylist_update_int(uves_propertylist *self, const char *name,
04520                             int value)
04521 {
04522 
04523     const cxchar *const _id = "uves_propertylist_update_int";
04524 
04525     uves_deque_iterator pos;
04526 
04527 
04528     if (self == NULL || name == NULL) {
04529         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
04530         return CPL_ERROR_NULL_INPUT;
04531     }
04532 
04533     pos = _uves_propertylist_find(self, name);
04534 
04535     if (pos == uves_deque_end(self->properties)) {
04536 
04537         cpl_property *property = cpl_property_new(name, CPL_TYPE_INT);
04538 
04539 
04540         cx_assert(property != NULL);
04541 
04542         cpl_property_set_int(property, value);
04543         uves_deque_push_back(self->properties, property);
04544     }
04545     else {
04546 
04547         cpl_property *property = uves_deque_get(self->properties, pos);
04548 
04549 
04550         cx_assert(property != NULL);
04551 
04552         if (cpl_property_get_type(property) != CPL_TYPE_INT) {
04553             cpl_error_set(_id, CPL_ERROR_TYPE_MISMATCH);
04554             return CPL_ERROR_TYPE_MISMATCH;
04555         }
04556 
04557         cpl_property_set_int(property, value);
04558 
04559     }
04560 
04561     return CPL_ERROR_NONE;
04562 
04563 }
04564 
04565 
04604 cpl_error_code
04605 uves_propertylist_update_long(uves_propertylist *self, const char *name,
04606                              long value)
04607 {
04608 
04609     const cxchar *const _id = "uves_propertylist_update_long";
04610 
04611     uves_deque_iterator pos;
04612 
04613 
04614     if (self == NULL || name == NULL) {
04615         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
04616         return CPL_ERROR_NULL_INPUT;
04617     }
04618 
04619     pos = _uves_propertylist_find(self, name);
04620 
04621     if (pos == uves_deque_end(self->properties)) {
04622 
04623         cpl_property *property = cpl_property_new(name, CPL_TYPE_LONG);
04624 
04625 
04626         cx_assert(property != NULL);
04627 
04628         cpl_property_set_long(property, value);
04629         uves_deque_push_back(self->properties, property);
04630     }
04631     else {
04632 
04633         cpl_property *property = uves_deque_get(self->properties, pos);
04634 
04635 
04636         cx_assert(property != NULL);
04637 
04638         if (cpl_property_get_type(property) != CPL_TYPE_LONG) {
04639             cpl_error_set(_id, CPL_ERROR_TYPE_MISMATCH);
04640             return CPL_ERROR_TYPE_MISMATCH;
04641         }
04642 
04643         cpl_property_set_long(property, value);
04644 
04645     }
04646 
04647     return CPL_ERROR_NONE;
04648 
04649 }
04650 
04651 
04690 cpl_error_code
04691 uves_propertylist_update_float(uves_propertylist *self, const char *name,
04692                               float value)
04693 {
04694 
04695     const cxchar *const _id = "uves_propertylist_update_float";
04696 
04697     uves_deque_iterator pos;
04698 
04699 
04700     if (self == NULL || name == NULL) {
04701         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
04702         return CPL_ERROR_NULL_INPUT;
04703     }
04704 
04705     pos = _uves_propertylist_find(self, name);
04706 
04707     if (pos == uves_deque_end(self->properties)) {
04708 
04709         cpl_property *property = cpl_property_new(name, CPL_TYPE_FLOAT);
04710 
04711 
04712         cx_assert(property != NULL);
04713 
04714         cpl_property_set_float(property, value);
04715         uves_deque_push_back(self->properties, property);
04716     }
04717     else {
04718 
04719         cpl_property *property = uves_deque_get(self->properties, pos);
04720 
04721 
04722         cx_assert(property != NULL);
04723 
04724         if (cpl_property_get_type(property) != CPL_TYPE_FLOAT) {
04725             cpl_error_set(_id, CPL_ERROR_TYPE_MISMATCH);
04726             return CPL_ERROR_TYPE_MISMATCH;
04727         }
04728 
04729         cpl_property_set_float(property, value);
04730 
04731     }
04732 
04733     return CPL_ERROR_NONE;
04734 
04735 }
04736 
04737 
04776 cpl_error_code
04777 uves_propertylist_update_double(uves_propertylist *self, const char *name,
04778                                double value)
04779 {
04780 
04781     const cxchar *const _id = "uves_propertylist_update_double";
04782 
04783     uves_deque_iterator pos;
04784 
04785 
04786     if (self == NULL || name == NULL) {
04787         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
04788         return CPL_ERROR_NULL_INPUT;
04789     }
04790 
04791     pos = _uves_propertylist_find(self, name);
04792 
04793     if (pos == uves_deque_end(self->properties)) {
04794 
04795         cpl_property *property = cpl_property_new(name, CPL_TYPE_DOUBLE);
04796 
04797 
04798         cx_assert(property != NULL);
04799 
04800         cpl_property_set_double(property, value);
04801         uves_deque_push_back(self->properties, property);
04802     }
04803     else {
04804 
04805         cpl_property *property = uves_deque_get(self->properties, pos);
04806 
04807 
04808         cx_assert(property != NULL);
04809 
04810         if (cpl_property_get_type(property) != CPL_TYPE_DOUBLE) {
04811             cpl_error_set(_id, CPL_ERROR_TYPE_MISMATCH);
04812             return CPL_ERROR_TYPE_MISMATCH;
04813         }
04814 
04815         cpl_property_set_double(property, value);
04816 
04817     }
04818 
04819     return CPL_ERROR_NONE;
04820 
04821 }
04822 
04823 
04862 cpl_error_code
04863 uves_propertylist_update_string(uves_propertylist *self, const char *name,
04864                                const char *value)
04865 {
04866 
04867     const cxchar *const _id = "uves_propertylist_update_string";
04868 
04869     uves_deque_iterator pos;
04870 
04871 
04872     if (self == NULL || name == NULL) {
04873         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
04874         return CPL_ERROR_NULL_INPUT;
04875     }
04876 
04877     pos = _uves_propertylist_find(self, name);
04878 
04879     if (pos == uves_deque_end(self->properties)) {
04880 
04881         cpl_property *property = cpl_property_new(name, CPL_TYPE_STRING);
04882 
04883 
04884         cx_assert(property != NULL);
04885 
04886         cpl_property_set_string(property, value);
04887         uves_deque_push_back(self->properties, property);
04888     }
04889     else {
04890 
04891         cpl_property *property = uves_deque_get(self->properties, pos);
04892 
04893 
04894         cx_assert(property != NULL);
04895 
04896         if (cpl_property_get_type(property) != CPL_TYPE_STRING) {
04897             cpl_error_set(_id, CPL_ERROR_TYPE_MISMATCH);
04898             return CPL_ERROR_TYPE_MISMATCH;
04899         }
04900 
04901         cpl_property_set_string(property, value);
04902 
04903     }
04904 
04905     return CPL_ERROR_NONE;
04906 
04907 }
04908 
04909 
04957 cpl_error_code
04958 uves_propertylist_copy_property(uves_propertylist *self,
04959                                const uves_propertylist *other,
04960                                const char *name)
04961 {
04962 
04963     const cxchar *const _id = "uves_propertylist_copy_property";
04964 
04965     uves_deque_iterator spos;
04966     uves_deque_iterator tpos;
04967 
04968 
04969     if (self == NULL || other == NULL || name == NULL) {
04970         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
04971         return CPL_ERROR_NULL_INPUT;
04972     }
04973 
04974     spos = _uves_propertylist_find(other, name);
04975 
04976     if (spos == uves_deque_end(other->properties)) {
04977         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
04978         return CPL_ERROR_DATA_NOT_FOUND;
04979     }
04980 
04981     tpos = _uves_propertylist_find(self, name);
04982 
04983     if (tpos == uves_deque_end(self->properties)) {
04984 
04985         cpl_property *p = cpl_property_duplicate(uves_deque_get(other->properties,
04986                                                              spos));
04987         uves_deque_push_back(self->properties, p);
04988 
04989     }
04990     else {
04991 
04992         cpl_property *p = uves_deque_get(self->properties, tpos);
04993         cpl_property *_p = uves_deque_get(self->properties, spos);
04994 
04995 
04996         if (cpl_property_get_type(p) != cpl_property_get_type(_p)) {
04997             cpl_error_set(_id, CPL_ERROR_TYPE_MISMATCH);
04998             return CPL_ERROR_TYPE_MISMATCH;
04999         }
05000 
05001         switch (cpl_property_get_type(_p)) {
05002 
05003         case CPL_TYPE_CHAR:
05004             cpl_property_set_char(p, cpl_property_get_char(_p));
05005             break;
05006 
05007         case CPL_TYPE_BOOL:
05008             cpl_property_set_bool(p, cpl_property_get_bool(_p));
05009             break;
05010 
05011         case CPL_TYPE_INT:
05012             cpl_property_set_int(p, cpl_property_get_int(_p));
05013             break;
05014 
05015         case CPL_TYPE_LONG:
05016             cpl_property_set_long(p, cpl_property_get_long(_p));
05017             break;
05018 
05019         case CPL_TYPE_FLOAT:
05020             cpl_property_set_float(p, cpl_property_get_float(_p));
05021             break;
05022 
05023         case CPL_TYPE_DOUBLE:
05024             cpl_property_set_double(p, cpl_property_get_double(_p));
05025             break;
05026 
05027         case CPL_TYPE_STRING:
05028             cpl_property_set_string(p, cpl_property_get_string(_p));
05029             break;
05030 
05031         default:
05032             /* This point should never be reached */
05033             cx_error("%s: Unsupported type encountered!", CX_CODE_POS);
05034             break;
05035 
05036         }
05037 
05038         cpl_property_set_comment(p, cpl_property_get_comment(_p));
05039 
05040     }
05041 
05042     return CPL_ERROR_NONE;
05043 
05044 }
05045 
05046 
05106 cpl_error_code
05107 uves_propertylist_copy_property_regexp(uves_propertylist *self,
05108                                       const uves_propertylist *other,
05109                                       const char *regexp,
05110                                       int invert)
05111 {
05112 
05113     const cxchar *const _id = "uves_propertylist_copy_property_regexp";
05114 
05115     cxint status;
05116 
05117     cxsize i;
05118     cxsize count = 0;
05119 
05120     uves_deque_const_iterator first, last;
05121 
05122     typedef struct _property_pair_ {
05123         cpl_property *s;
05124         cpl_property *t;
05125     } property_pair;
05126 
05127     property_pair *pairs = NULL;
05128 
05129     uves_regexp filter;
05130 
05131 
05132     if (self == NULL || other == NULL || regexp == NULL) {
05133         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
05134         return CPL_ERROR_NULL_INPUT;
05135     }
05136 
05137     status = regcomp(&filter.re, regexp, REG_EXTENDED | REG_NOSUB);
05138     if (status) {
05139         cpl_error_set(_id, CPL_ERROR_ILLEGAL_INPUT);
05140         return CPL_ERROR_ILLEGAL_INPUT;
05141     }
05142 
05143     filter.invert = invert == 0 ? FALSE : TRUE;
05144 
05145 
05146     count = uves_deque_size(other->properties);
05147 
05148     if (count == 0) {
05149         regfree(&filter.re);
05150         return CPL_ERROR_NONE;
05151     }
05152 
05153     pairs = cx_malloc(count * sizeof(property_pair));
05154     cx_assert(pairs != NULL);
05155 
05156     count = 0;
05157 
05158 
05159     first = uves_deque_begin(other->properties);
05160     last  = uves_deque_end(other->properties);
05161 
05162     while (first != last) {
05163 
05164         cpl_property *p = uves_deque_get(other->properties, first);
05165 
05166 
05167         if (_uves_propertylist_compare_regexp(p, &filter) == TRUE) {
05168 
05169             const cxchar *name = cpl_property_get_name(p);
05170 
05171             uves_deque_const_iterator pos = _uves_propertylist_find(self, name);
05172 
05173             cpl_property *_p = NULL;
05174 
05175 
05176             if (pos != uves_deque_end(self->properties)) {
05177 
05178                 _p = uves_deque_get(self->properties, pos);
05179 
05180                 if (cpl_property_get_type(p) != cpl_property_get_type(_p)) {
05181 
05182                     regfree(&filter.re);
05183 
05184                     cx_free(pairs);
05185                     pairs = NULL;
05186 
05187                     cpl_error_set(_id, CPL_ERROR_TYPE_MISMATCH);
05188 
05189                     return CPL_ERROR_TYPE_MISMATCH;
05190 
05191                 }
05192 
05193             }
05194 
05195             pairs[count].s = p;
05196             pairs[count].t = _p;
05197             ++count;
05198 
05199         }
05200 
05201         first = uves_deque_next(other->properties, first);
05202 
05203     }
05204 
05205     regfree(&filter.re);
05206 
05207 
05208     for (i = 0; i < count; i++) {
05209 
05210         if (pairs[i].t == NULL) {
05211 
05212             cpl_property *p = cpl_property_duplicate(pairs[i].s);
05213             uves_deque_push_back(self->properties, p);
05214 
05215         }
05216         else {
05217 
05218             switch (cpl_property_get_type(pairs[i].s)) {
05219 
05220             case CPL_TYPE_CHAR:
05221                 cpl_property_set_char(pairs[i].t,
05222                                       cpl_property_get_char(pairs[i].s));
05223                 break;
05224 
05225             case CPL_TYPE_BOOL:
05226                 cpl_property_set_bool(pairs[i].t,
05227                                       cpl_property_get_bool(pairs[i].s));
05228                 break;
05229 
05230             case CPL_TYPE_INT:
05231                 cpl_property_set_int(pairs[i].t,
05232                                      cpl_property_get_int(pairs[i].s));
05233                 break;
05234 
05235             case CPL_TYPE_LONG:
05236                 cpl_property_set_long(pairs[i].t,
05237                                       cpl_property_get_long(pairs[i].s));
05238                 break;
05239 
05240             case CPL_TYPE_FLOAT:
05241                 cpl_property_set_float(pairs[i].t,
05242                                        cpl_property_get_float(pairs[i].s));
05243                 break;
05244 
05245             case CPL_TYPE_DOUBLE:
05246                 cpl_property_set_double(pairs[i].t,
05247                                         cpl_property_get_double(pairs[i].s));
05248                 break;
05249 
05250             case CPL_TYPE_STRING:
05251                 cpl_property_set_string(pairs[i].t,
05252                                         cpl_property_get_string(pairs[i].s));
05253                 break;
05254 
05255             default:
05256                 /* This point should never be reached */
05257                 cx_free(pairs);
05258                 cx_error("%s: Unsupported type encountered!", CX_CODE_POS);
05259                 break;
05260 
05261             }
05262 
05263         }
05264 
05265     }
05266 
05267     cx_free(pairs);
05268 
05269     return CPL_ERROR_NONE;
05270 
05271 }
05272 
05273 
05334 uves_propertylist *
05335 uves_propertylist_load(const char *name, int position)
05336 {
05337 
05338     const cxchar *const _id = "uves_propertylist_load";
05339 
05340     register cxint n, status;
05341 
05342     qfits_header *header;
05343 
05344     uves_propertylist *self;
05345 
05346 
05347     if (name == NULL) {
05348         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
05349         return NULL;
05350     }
05351 
05352     if (position < 0) {
05353         cpl_error_set(_id, CPL_ERROR_ILLEGAL_INPUT);
05354         return NULL;
05355     }
05356 
05357     status = qfits_is_fits((cxchar *)name);
05358     if (status == -1) {
05359         cpl_error_set(_id, CPL_ERROR_FILE_IO);
05360         return NULL;
05361     }
05362     else {
05363         if (status == 0) {
05364             cpl_error_set(_id, CPL_ERROR_BAD_FILE_FORMAT);
05365             return NULL;
05366         }
05367     }
05368 
05369     /*
05370      * qfits_query_n_ext() only counts true extensions, i.e. it does not
05371      * count the primary FITS unit. But since we passed the qfits_is_fits()
05372      * check we can safely assume that there is one.
05373      */
05374 
05375     n = qfits_query_n_ext((cxchar *)name);
05376 
05377     if (n < position) {
05378         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
05379         return NULL;
05380     }
05381 
05382 
05383     header = qfits_header_readext((cxchar *)name, position);
05384 
05385     if (header == NULL) {
05386         cpl_error_set(_id, CPL_ERROR_ILLEGAL_INPUT);
05387         return NULL;
05388     }
05389 
05390     self = uves_propertylist_new();
05391     cx_assert(self);
05392 
05393     status = _uves_propertylist_from_fits(self, header, NULL, NULL);
05394 
05395     if (status) {
05396         uves_propertylist_delete(self);
05397         qfits_header_destroy(header);
05398 
05399         cpl_error_set(_id, CPL_ERROR_ILLEGAL_INPUT);
05400         return NULL;
05401     }
05402 
05403     qfits_header_destroy(header);
05404 
05405     return self;
05406 
05407 }
05408 
05409 
05481 uves_propertylist *
05482 uves_propertylist_load_regexp(const char *name, int position,
05483                              const char *regexp, int invert)
05484 {
05485 
05486     const cxchar *const _id = "uves_propertylist_load_regexp";
05487 
05488     register cxint n, status;
05489 
05490     qfits_header *header;
05491 
05492     uves_propertylist *self;
05493 
05494     uves_regexp filter;
05495 
05496 
05497     if (name == NULL || regexp == NULL) {
05498         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
05499         return NULL;
05500     }
05501 
05502     if (position < 0) {
05503         cpl_error_set(_id, CPL_ERROR_ILLEGAL_INPUT);
05504         return NULL;
05505     }
05506 
05507     status = regcomp(&filter.re, regexp, REG_EXTENDED | REG_NOSUB);
05508     if (status) {
05509         cpl_error_set(_id, CPL_ERROR_ILLEGAL_INPUT);
05510         return NULL;
05511     }
05512 
05513     filter.invert = invert == 0 ? FALSE : TRUE;
05514 
05515 
05516     status = qfits_is_fits((cxchar *)name);
05517     if (status == -1) {
05518         cpl_error_set(_id, CPL_ERROR_FILE_IO);
05519         return NULL;
05520     }
05521     else {
05522         if (status == 0) {
05523             cpl_error_set(_id, CPL_ERROR_BAD_FILE_FORMAT);
05524             return NULL;
05525         }
05526     }
05527 
05528     /*
05529      * qfits_query_n_ext() only counts true extensions, i.e. it does not
05530      * count the primary FITS unit. But since we passed the qfits_is_fits()
05531      * check we can safely assume that there is one.
05532      */
05533 
05534     n = qfits_query_n_ext((cxchar *)name);
05535 
05536     if (n < position) {
05537         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
05538         return NULL;
05539     }
05540 
05541 
05542     header = qfits_header_readext((cxchar *)name, position);
05543 
05544     if (header == NULL) {
05545         cpl_error_set(_id, CPL_ERROR_ILLEGAL_INPUT);
05546         return NULL;
05547     }
05548 
05549     self = uves_propertylist_new();
05550     cx_assert(self);
05551 
05552     status = _uves_propertylist_from_fits(self, header,
05553                                          _uves_propertylist_filter_regexp,
05554                                          &filter);
05555 
05556     if (status) {
05557         uves_propertylist_delete(self);
05558         qfits_header_destroy(header);
05559 
05560         regfree(&filter.re);
05561 
05562         cpl_error_set(_id, CPL_ERROR_ILLEGAL_INPUT);
05563         return NULL;
05564     }
05565 
05566     qfits_header_destroy(header);
05567     regfree(&filter.re);
05568 
05569     return self;
05570 
05571 }
05572 
05573 
05591 qfits_header *
05592 uves_propertylist_to_fits(const uves_propertylist *self)
05593 {
05594     const cxchar *const _id = "uves_propertylist_to_fits";
05595 
05596     qfits_header *header;
05597 
05598 
05599     cx_assert(self != NULL);
05600 
05601     header = qfits_header_new();
05602 
05603     if (!uves_deque_empty(self->properties)) {
05604         uves_deque_iterator i = uves_deque_begin(self->properties);
05605         uves_deque_iterator last = uves_deque_end(self->properties);
05606 
05607         while (i != last) {
05608             cxchar tmp[FITS_LINESZ + 1];
05609             cxchar key[FITS_LINESZ + 1];
05610             cxchar value[FITS_LINESZ + 1];
05611             cxfloat fval;
05612             cxdouble dval;
05613             cpl_property *property;
05614 
05615             property = uves_deque_get(self->properties, i);
05616 
05617             /*
05618              * Convert each property into a FITS keyword an error is
05619              * triggered for unsupported types. Also, since the FITS
05620              * format does not support array keywords, apart from strings,
05621              * i.e. character arrays, an error is triggered in this case too.
05622              *
05623              * A possible solution for the array case would be to create
05624              * a sequence of indexed keywords. But this must be checked.
05625              */
05626 
05627             strncpy(tmp, cpl_property_get_name(property), FITS_LINESZ);
05628             tmp[FITS_LINESZ] = '\0';
05629 
05630             if (!cx_strupper(tmp)) {
05631 //                cpl_error_set_code(CPL_ERROR_INCOMPATIBLE_INPUT);
05632 //                cpl_error_set_where(_id);
05633                 cpl_error_set(_id, CPL_ERROR_INCOMPATIBLE_INPUT);
05634 
05635                 qfits_header_destroy(header);
05636 
05637                 return NULL;
05638             }
05639 
05640             key[0] = '\0';
05641 
05642             if (strlen(tmp) > FITS_STDKEY_MAX &&
05643                 strncmp(tmp, "HIERARCH ", 9)) {
05644                 strncat(key, "HIERARCH ", 9);
05645             }
05646             strncat(key, tmp, FITS_LINESZ - strlen(key));
05647 
05648             switch (cpl_property_get_type(property)) {
05649                 case CPL_TYPE_CHAR:
05650                     cx_snprintf(value, FITS_LINESZ, "'%c'",
05651                                 cpl_property_get_char(property));
05652                     break;
05653 
05654                 case CPL_TYPE_BOOL:
05655                 {
05656                     cxint pvalue = cpl_property_get_bool(property);
05657 
05658                     cx_snprintf(value, FITS_LINESZ, "%c",
05659                                 pvalue == 1 ? 'T' : 'F');
05660                     break;
05661                 }
05662 
05663                 case CPL_TYPE_INT:
05664                     cx_snprintf(value, FITS_LINESZ, "%d",
05665                                 cpl_property_get_int(property));
05666                     break;
05667 
05668                 case CPL_TYPE_LONG:
05669                     cx_snprintf(value, FITS_LINESZ, "%ld",
05670                                 cpl_property_get_long(property));
05671                     break;
05672 
05673                 case CPL_TYPE_FLOAT:
05674                     fval = cpl_property_get_float(property);
05675                     cx_snprintf(value, FITS_LINESZ, "%.7G", fval);
05676 
05677                     if (!strchr(value, '.')) {
05678                         if (strchr(value, 'E'))
05679                             cx_snprintf(value, FITS_LINESZ, "%.1E", fval);
05680                         else
05681                             strcat(value, ".");
05682                     }
05683                     break;
05684 
05685                 case CPL_TYPE_DOUBLE:
05686                     dval = cpl_property_get_double(property);
05687                     cx_snprintf(value, FITS_LINESZ, "%.15G", dval);
05688 
05689                     if (!strchr(value, '.')) {
05690                         if (strchr(value, 'E'))
05691                             cx_snprintf(value, FITS_LINESZ, "%.1E", dval);
05692                         else
05693                             strcat(value, ".");
05694                     }
05695                     break;
05696 
05697                 case CPL_TYPE_STRING:
05698                     if (!strcmp(key, "COMMENT") || !strcmp(key, "HISTORY")) {
05699                         cx_snprintf(value, FITS_LINESZ, "%s",
05700                                     cpl_property_get_string(property));
05701                     }
05702                     else {
05703 
05704                         cxint n = 0;
05705 
05706                         n = cx_snprintf(value, FITS_SVALUE_MAX + 1, "'%s'",
05707                                         cpl_property_get_string(property));
05708 
05709                         if (n > FITS_SVALUE_MAX) {
05710                             value[FITS_SVALUE_MAX - 1] = '\'';
05711                             value[FITS_SVALUE_MAX] = '\0';
05712                         }
05713 
05714                     }
05715                     break;
05716 
05717                 default:
05718 //                    cpl_error_set_code(CPL_ERROR_INCOMPATIBLE_INPUT);
05719 //                    cpl_error_set_where(_id);
05720                     cpl_error_set(_id, CPL_ERROR_INCOMPATIBLE_INPUT);
05721 
05722                     qfits_header_destroy(header);
05723 
05724                     return NULL;
05725                     break;
05726             }
05727 
05728             qfits_header_append(header, key, value,
05729                                 (cxchar *)cpl_property_get_comment(property),
05730                                 NULL);
05731 
05732             i = uves_deque_next(self->properties, i);
05733         }
05734     }
05735 
05736 
05737     /*
05738      * Add the END keyword as last entry.
05739      */
05740 
05741     /* FIXME: Maybe better to check if end is already present */
05742 
05743     qfits_header_append(header, "END", NULL, NULL, NULL);
05744 
05745 
05746     /*
05747      * Sort the header according to ESO's DICB standard
05748      */
05749 
05750     if (qfits_header_sort(&header) != 0) {
05751 //        cpl_error_set_code(CPL_ERROR_INCOMPATIBLE_INPUT);
05752 //        cpl_error_set_where(_id);
05753         cpl_error_set(_id, CPL_ERROR_INCOMPATIBLE_INPUT);
05754 
05755         qfits_header_destroy(header);
05756 
05757         return NULL;
05758     }
05759 
05760     return header;
05761 
05762 }
05763 
05787 uves_propertylist *
05788 uves_propertylist_from_fits(const qfits_header *header)
05789 {
05790 
05791     const cxchar *const _id = "uves_propertylist_from_fits";
05792 
05793     register cxint status;
05794 
05795     uves_propertylist *self;
05796 
05797 
05798     if (!header) {
05799         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
05800         return NULL;
05801     }
05802 
05803     self = uves_propertylist_new();
05804     cx_assert(self != NULL);
05805 
05806     status = _uves_propertylist_from_fits(self, header, NULL, NULL);
05807 
05808     if (status) {
05809         uves_propertylist_delete(self);
05810 
05811 //        cpl_error_set_where(_id);
05812 
05813         switch (status) {
05814         case -2:
05815         case -1:
05816 //            cpl_error_set_code(CPL_ERROR_ILLEGAL_INPUT);
05817             cpl_error_set(_id, CPL_ERROR_ILLEGAL_INPUT);
05818             break;
05819 
05820         case 1:
05821 //            cpl_error_set_code(CPL_ERROR_INVALID_TYPE);
05822             cpl_error_set(_id, CPL_ERROR_INVALID_TYPE);
05823             break;
05824 
05825         default:
05826             /* This should never be reached */
05827             break;
05828         }
05829 
05830         return NULL;
05831     }
05832 
05833     return self;
05834 
05835 }
05836 
05837 #endif /* USE_CPL */
05838 

Generated on Tue Jun 19 14:39:17 2007 for UVES Pipeline Reference Manual by  doxygen 1.4.6