uves_propertylist.c

00001 /* $Id: uves_propertylist.c,v 1.17 2010/09/24 09:32:07 amodigli Exp $
00002  *
00003  * This file is part of the ESO Common Pipeline Library
00004  * Copyright (C) 2001-2005 European Southern Observatory
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  */
00020 
00021 /*
00022  * $Author: amodigli $
00023  * $Date: 2010/09/24 09:32:07 $
00024  * $Revision: 1.17 $
00025  * $Name: uves-5_0_0 $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #  include <config.h>
00030 #endif
00031 #include <uves_msg.h>
00032 
00033 #include <uves_propertylist.h>
00034 #include <uves_utils_wrappers.h>
00035 #include <uves_error.h>
00036 
00037 #ifdef USE_CPL
00038 #else
00039 
00040 #include <uves_utils_wrappers.h>
00041 #include <uves_deque.h>
00042 #include <uves_dump.h>
00043 #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 
00059 
00060 
00061 #include <cxdeque.h>
00062 
00079 enum {
00080     FITS_STDKEY_MAX = 8,
00081     FITS_SVALUE_MAX = 68
00082 };
00083 
00084 
00085 /*
00086  * The property list type.
00087  */
00088 
00089 struct _uves_propertylist_ {
00090     uves_deque *properties;
00091 };
00092 
00093 
00094 /*
00095  * Regular expresion filter type
00096  */
00097 
00098 struct _uves_regexp_ {
00099     regex_t re;
00100     cxbool invert;
00101 };
00102 
00103 typedef struct _uves_regexp_ uves_regexp;
00104 
00105 
00106 static void
00107 propertylist_append_property(uves_propertylist *plist, const cpl_property *p)
00108 {
00109     switch(cpl_property_get_type(p)) {
00110     case CPL_TYPE_CHAR:
00111         uves_propertylist_append_char(plist, cpl_property_get_name(p), cpl_property_get_char(p));
00112         break;
00113     case CPL_TYPE_BOOL:
00114         uves_propertylist_append_bool(plist, cpl_property_get_name(p), cpl_property_get_bool(p));
00115         break;
00116     case CPL_TYPE_INT:
00117         uves_propertylist_append_int(plist, cpl_property_get_name(p), cpl_property_get_int(p));
00118         break;
00119     case CPL_TYPE_LONG:
00120         uves_propertylist_append_long(plist, cpl_property_get_name(p), cpl_property_get_long(p));
00121         break;
00122     case CPL_TYPE_FLOAT:
00123         uves_propertylist_append_float(plist, cpl_property_get_name(p), cpl_property_get_float(p));
00124         break;
00125     case CPL_TYPE_DOUBLE:
00126         uves_propertylist_append_double(plist, cpl_property_get_name(p), cpl_property_get_double(p));
00127         break;
00128     case CPL_TYPE_STRING:
00129         uves_propertylist_append_string(plist, cpl_property_get_name(p), cpl_property_get_string(p));
00130         break;
00131     default:
00132         cpl_msg_error("Unknown property type: %s", uves_tostring_cpl_type(cpl_property_get_type(p)));
00133         cpl_error_set(__func__, CPL_ERROR_UNSUPPORTED_MODE);
00134         break;
00135     }
00136     /* This is constant time!! */
00137     cpl_property_set_comment(uves_propertylist_get(plist, uves_propertylist_get_size(plist) - 1),
00138                              cpl_property_get_comment(p));
00139     return;
00140 }
00141 
00142 static void
00143 propertylist_prepend_property_cpl(cpl_propertylist *plist, const cpl_property *p)
00144 {
00145     switch(cpl_property_get_type(p)) {
00146     case CPL_TYPE_CHAR:
00147         cpl_propertylist_prepend_char(plist, cpl_property_get_name(p), cpl_property_get_char(p));
00148         break;
00149     case CPL_TYPE_BOOL:
00150         cpl_propertylist_prepend_bool(plist, cpl_property_get_name(p), cpl_property_get_bool(p));
00151         break;
00152     case CPL_TYPE_INT:
00153         cpl_propertylist_prepend_int(plist, cpl_property_get_name(p), cpl_property_get_int(p));
00154         break;
00155     case CPL_TYPE_LONG:
00156         cpl_propertylist_prepend_long(plist, cpl_property_get_name(p), cpl_property_get_long(p));
00157         break;
00158     case CPL_TYPE_FLOAT:
00159         cpl_propertylist_prepend_float(plist, cpl_property_get_name(p), cpl_property_get_float(p));
00160         break;
00161     case CPL_TYPE_DOUBLE:
00162         cpl_propertylist_prepend_double(plist, cpl_property_get_name(p), cpl_property_get_double(p));
00163         break;
00164     case CPL_TYPE_STRING:
00165         cpl_propertylist_prepend_string(plist, cpl_property_get_name(p), cpl_property_get_string(p));
00166         break;
00167     default:
00168         cpl_msg_error("Unknown property type: %s", uves_tostring_cpl_type(cpl_property_get_type(p)));
00169         cpl_error_set(__func__, CPL_ERROR_UNSUPPORTED_MODE);
00170         break;
00171     }
00172     cpl_propertylist_set_comment(plist, cpl_property_get_name(p), cpl_property_get_comment(p));
00173     return;
00174 }
00175 
00176 static cpl_propertylist *
00177 uves_propertylist_to_cpl(const uves_propertylist *self)
00178 {
00179     cpl_propertylist *result;
00180     long i;
00181 
00182     if (self == NULL) {
00183         result = NULL;
00184     }
00185     else {
00186         result = cpl_propertylist_new();
00187         
00188         for (i = uves_propertylist_get_size(self)-1; i >= 0; i--) {
00189             propertylist_prepend_property_cpl(
00190                 result, 
00191                 uves_propertylist_get_const(self, i));
00192         }
00193     }
00194     return result;
00195 }
00196 
00197 static void
00198 uves_propertylist_from_cpl(uves_propertylist *self, const cpl_propertylist *list_cpl)
00199 {
00200     long N = cpl_propertylist_get_size(list_cpl); /* O(n) */
00201     cpl_propertylist *copy = cpl_propertylist_duplicate(list_cpl); /* O(n) */
00202     long i;
00203 
00204     assert( uves_propertylist_is_empty(self));
00205 
00206     for (i = 0; i < N; i++) {
00207         const cpl_property *p = cpl_propertylist_get(copy, 0); /* O(1) */
00208         propertylist_append_property(self, p); /* O(1) */
00209         cpl_propertylist_erase(copy, cpl_property_get_name(p)); /* O(1),
00210                                                                  erases only first match */
00211     }
00212     assert( cpl_propertylist_is_empty(copy));
00213     cpl_propertylist_delete(copy);
00214 
00215     return;
00216 }
00217 
00218 /* Wrappers for often used functions which have cpl_propertylists in their interface */
00219 cpl_error_code uves_vector_save(const cpl_vector *v, const char *f, cpl_type_bpp bpp,
00220                                 const uves_propertylist *header, unsigned mode)
00221 {
00222     cpl_propertylist *header_cpl = uves_propertylist_to_cpl(header);
00223     cpl_vector_save(v, f, bpp, header_cpl, mode);
00224     cpl_propertylist_delete(header_cpl);
00225 
00226     return cpl_error_get_code();
00227 }
00228 cpl_error_code 
00229 uves_image_save(const cpl_image *image, const char *f, cpl_type_bpp bpp,
00230                                const uves_propertylist *header, unsigned mode)
00231 {
00232   cpl_propertylist *header_cpl = NULL;
00233   check_nomsg(header_cpl=uves_propertylist_to_cpl(header));
00234   check_nomsg(cpl_image_save(image, f, bpp, header_cpl, mode));
00235  cleanup:
00236     cpl_propertylist_delete(header_cpl);
00237 
00238     return cpl_error_get_code();
00239 }
00240 cpl_error_code uves_imagelist_save(const cpl_imagelist *imagelist, const char *f, cpl_type_bpp bpp,
00241                                const uves_propertylist *header, unsigned mode)
00242 {
00243     cpl_propertylist *header_cpl = uves_propertylist_to_cpl(header);
00244     cpl_imagelist_save(imagelist, f, bpp, header_cpl, mode);
00245     cpl_propertylist_delete(header_cpl);
00246 
00247     return cpl_error_get_code();
00248 }
00249 cpl_error_code uves_table_save(const cpl_table *table, const uves_propertylist *header,
00250                                const uves_propertylist *ext_header, const char *filename,
00251                                unsigned mode)
00252 {
00253     cpl_propertylist *header_cpl = uves_propertylist_to_cpl(header);
00254     cpl_propertylist *ext_header_cpl = uves_propertylist_to_cpl(ext_header);
00255     cpl_table_save(table, header_cpl, ext_header_cpl, filename, mode);
00256     cpl_propertylist_delete(header_cpl);
00257     cpl_propertylist_delete(ext_header_cpl);
00258 
00259     return cpl_error_get_code();
00260 }
00261 
00262 cpl_error_code uves_dfs_setup_product_header(uves_propertylist *header,
00263                                              const cpl_frame *product_frame,
00264                                              const cpl_frameset *framelist,
00265                                              const cpl_parameterlist *parlist,
00266                                              const char *recid,
00267                                              const char *pipeline_id,
00268                                              const char *dictionary_id)
00269 {
00270     cpl_propertylist *header_cpl = uves_propertylist_to_cpl(header);
00271 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0) 
00272     cpl_dfs_setup_product_header(header_cpl,
00273                                  product_frame,
00274                                  framelist,
00275                                  parlist,
00276                                  recid,
00277                                  pipeline_id,
00278                                  dictionary_id,NULL);
00279 #else 
00280     cpl_dfs_setup_product_header(header_cpl,
00281                                  product_frame,
00282                                  framelist,
00283                                  parlist,
00284                                  recid,
00285                                  pipeline_id,
00286                                  dictionary_id);
00287 #endif
00288     uves_propertylist_empty(header);
00289     uves_propertylist_from_cpl(header, header_cpl);
00290     cpl_propertylist_delete(header_cpl);
00291 
00292     return cpl_error_get_code();
00293 }
00294 
00295 cpl_error_code uves_table_sort(cpl_table *t, const uves_propertylist *list)
00296 {
00297     /* Just use this workaround ... */
00298    cpl_table_sort(t, (const cpl_propertylist*) list);
00299     
00300     /* ... instead of this one */
00301 #if 0
00302     cpl_propertylist *list_cpl = uves_propertylist_to_cpl(list);
00303     cpl_table_sort(t, list_cpl);
00304     cpl_propertylist_delete(list_cpl);
00305 #endif    
00306     return cpl_error_get_code();
00307 }
00308 
00309 
00310 /*
00311  * Private methods
00312  */
00313 
00314 
00315 /* Workarounds for cpl_error_push/pop which are not exported */
00316 static cpl_error_code push_pop_error;
00317 
00318 static void error_push(void)
00319 {
00320     push_pop_error = cpl_error_get_code();
00321     /* Don't track location */
00322     cpl_error_reset();
00323     return;
00324 }
00325 static void error_pop(void)
00326 {
00327     if (push_pop_error != CPL_ERROR_NONE)
00328         {
00329             cpl_error_set(__func__, push_pop_error);
00330         }
00331     return;
00332 }
00333 
00334 
00335 
00336 
00337 
00338 
00339 
00340 
00341 static cxint
00342 _uves_propertylist_filter_regexp(cxcptr key, cxcptr filter)
00343 {
00344 
00345     const uves_regexp *_filter = (const uves_regexp *)filter;
00346 
00347     if (regexec(&_filter->re, key, (size_t)0, NULL, 0) == REG_NOMATCH)
00348         return _filter->invert == TRUE ? TRUE : FALSE;
00349 
00350     return _filter->invert == TRUE ? FALSE : TRUE;
00351 
00352 }
00353 
00354 
00355 static cxbool
00356 _uves_propertylist_compare(const cpl_property *property, const char *name)
00357 {
00358     const cxchar *key = cpl_property_get_name(property);
00359 
00360     return strcmp(key, name) == 0 ? TRUE : FALSE;
00361 
00362 }
00363 
00364 /* The following function is not used
00365 static cxbool
00366 _uves_propertylist_compare_start(const cpl_property *property,
00367                                 const char *part_name)
00368 {
00369 
00370     const cxchar *key = cpl_property_get_name(property);
00371 
00372     if (strstr(key, part_name) == key)
00373         return TRUE;
00374 
00375     return FALSE;
00376 
00377 }
00378 */
00379 
00380 static cxbool
00381 _uves_propertylist_compare_regexp(const cpl_property *property, uves_regexp *re)
00382 {
00383 
00384     const cxchar *key = cpl_property_get_name(property);
00385 
00386     return _uves_propertylist_filter_regexp(key, re);
00387 
00388 }
00389 
00390 
00391 static uves_deque_iterator
00392 _uves_propertylist_find(const uves_propertylist *self, const char *name)
00393 {
00394 
00395     uves_deque_iterator first, last;
00396     cpl_property *p;
00397 
00398     first = uves_deque_begin(self->properties);
00399     last = uves_deque_end(self->properties);
00400 
00401     while (first != last) {
00402         p = uves_deque_get(self->properties, first);
00403 
00404         if (_uves_propertylist_compare(p, name))
00405             break;
00406 
00407         first = uves_deque_next(self->properties, first);
00408     }
00409 
00410     return first;
00411 
00412 }
00413 
00414 static cpl_property *
00415 _uves_propertylist_get(const uves_propertylist *self, const char *name)
00416 {
00417     uves_deque_iterator pos = _uves_propertylist_find(self, name);
00418 
00419     if (pos == uves_deque_end(self->properties))
00420         return NULL;
00421 
00422     return uves_deque_get(self->properties, pos);
00423 
00424 }
00425 
00426 
00427 static int
00428 _uves_propertylist_insert(uves_propertylist *self, const cxchar *where,
00429                          cxbool after, const cxchar *name, cpl_type type,
00430                          cxptr value)
00431 {
00432 
00433     uves_deque_iterator pos;
00434     cpl_property *property;
00435 
00436 
00437     /*
00438      * Find the position where value should be inserted.
00439      */
00440 
00441     pos = _uves_propertylist_find(self, where);
00442 
00443     if (pos == uves_deque_end(self->properties)) {
00444         return 1;
00445     }
00446 
00447     if (after) {
00448         pos = uves_deque_next(self->properties, pos);
00449     }
00450 
00451 
00452     /*
00453      * Create the property for value and fill it.
00454      */
00455 
00456     property = cpl_property_new(name, type);
00457     if (!property) {
00458         return 1;
00459     }
00460 
00461 
00462     /*
00463      * Map property type to the driver function's argument type.
00464      */
00465 
00466     switch (type) {
00467         case CPL_TYPE_CHAR:
00468             cpl_property_set_char(property, *((cxchar *)value));
00469             break;
00470 
00471         case CPL_TYPE_BOOL:
00472             cpl_property_set_bool(property, *((cxint *)value));
00473             break;
00474 
00475         case CPL_TYPE_INT:
00476             cpl_property_set_int(property, *((cxint *)value));
00477             break;
00478 
00479         case CPL_TYPE_LONG:
00480             cpl_property_set_long(property, *((cxlong *)value));
00481             break;
00482 
00483         case CPL_TYPE_FLOAT:
00484             cpl_property_set_float(property, *((cxfloat *)value));
00485             break;
00486 
00487         case CPL_TYPE_DOUBLE:
00488             cpl_property_set_double(property, *((cxdouble *)value));
00489             break;
00490 
00491         case CPL_TYPE_STRING:
00492             cpl_property_set_string(property, ((const cxchar *)value));
00493             break;
00494 
00495         default:
00496             return 1;
00497             break;
00498     }
00499 
00500 
00501     /*
00502      * Insert it into the list
00503      */
00504 
00505     uves_deque_insert(self->properties, pos, property);
00506 
00507     return 0;
00508 
00509 }
00510 
00511 /*
00512  * Parser for FITS cards. Returns 0 if the card was successfully parsed
00513  * into its components, 1 if the card should be ignored and a negative
00514  * number if an error occurred. If the parsing was successful the function
00515  * fills the buffers pointed to by key, value, comment and type.
00516  *
00517  * The buffers key, value and comment must, at least, have the size
00518  * FITS_LINESZ + 1!
00519  *
00520  * Errors:
00521  *  -1  Invalid pointer to the input FITS header.
00522  *  -2  Invalid keyword name detected (cf. qfits_header_getitem())
00523  */
00524 
00525 static cxint
00526 _uves_propertylist_decode_fits(const qfits_header *header, cxint i,
00527                               cxchar *key, cxint *type, cxchar *value,
00528                               cxchar *comment)
00529 {
00530 
00531     cxchar _key[FITS_LINESZ + 1];
00532     cxchar _value[FITS_LINESZ + 1];
00533     cxchar _comment[FITS_LINESZ + 1];
00534     cxchar *s;
00535 
00536     if (!header)
00537         return -1;
00538 
00539     /*
00540      * Get a FITS card, decode it into its components and determine
00541      * its type.
00542      */
00543 
00544     if (qfits_header_getitem((qfits_header *)header, i, _key, _value,
00545                              _comment, NULL) != 0) {
00546         return -2;
00547     }
00548 
00549 
00550     /*
00551      * Skip the END record. Qfits ignores empty header cards. Therefore
00552      * we do not need to take care of them here, but who knows.
00553      */
00554 
00555     s = _key;
00556 
00557     if (strncmp(s, "END", 3) == 0 || strncmp(s, "        ", 8) == 0 ||
00558         strlen(s) == 0) {
00559         return 1;
00560     }
00561 
00562 
00563     /*
00564      * strip the HIERARCH prefix from the keyword name if it
00565      * is present.
00566      */
00567 
00568     if (strncmp(s, "HIERARCH ", 9) == 0)
00569         s += 9;
00570 
00571     strncpy(key, s, FITS_LINESZ);
00572     key[FITS_LINESZ] = '\0';
00573 
00574 
00575     /*
00576      * Parse the value string and determine its type. Comment and
00577      * history records are forced to be strings. The type check
00578      * has to be done before cleaning the value, so that strings
00579      * like '1.0' are still recognized as such.
00580      */
00581 
00582     s = _value;
00583 
00584     if (strncmp(_key, "COMMENT", 7) == 0 || strncmp(_key, "HISTORY", 7) == 0) {
00585         *type = QFITS_STRING;
00586 
00587         /*
00588          * qfits returns an empty string if there is no value for a keyword
00589          */
00590 
00591         if (strlen(s) == 0) {
00592             value[0] = '\0';
00593         }
00594         else {
00595             strncpy(value, s, FITS_LINESZ);
00596         }
00597     }
00598     else {
00599         *type = qfits_get_type(s);
00600         strncpy(value, qfits_pretty_string(s), FITS_LINESZ);
00601         value[FITS_LINESZ] = '\0';
00602     }
00603 
00604 
00605     /*
00606      * Parse the comment
00607      */
00608 
00609     s = _comment;
00610 
00611     /*
00612      * qfits returns an empty string if there is no value for a keyword
00613      */
00614 
00615     if (strlen(s) == 0)
00616         comment[0] = '\0';
00617     else {
00618         strncpy(comment, s, FITS_LINESZ);
00619         comment[FITS_LINESZ] = '\0';
00620     }
00621 
00622     return 0;
00623 
00624 }
00625 
00626 
00627 
00628 
00629 /*
00630  * The function converts a FITS header to a property list ignoring
00631  * keywords for which _uves_propertylist_decode_fits() returns 1. If
00632  * parsing a FITS keyword fails the function returns the status from
00633  * _uves_propertylist_decode_fits(). If the type of a FITS keyword is not
00634  * supported -1 is returned.
00635  */
00636 
00637 static cxint
00638 _uves_propertylist_from_fits(uves_propertylist *self,
00639                             const qfits_header *header,
00640                             cx_compare_func filter,
00641                             cxcptr data)
00642 {
00643 
00644     register cxint i;
00645 
00646 
00647     cx_assert(self != NULL);
00648     cx_assert(header != NULL);
00649 
00650 
00651     /*
00652      * Build the property list from the header.
00653      */
00654 
00655     for (i = 0; i < header->n; i++) {
00656         register cxint status;
00657 
00658         cxint type;
00659         cxint ival;
00660 
00661         cxdouble dval;
00662 
00663         cxchar key[FITS_LINESZ + 1];
00664         cxchar value[FITS_LINESZ + 1];
00665         cxchar comment[FITS_LINESZ + 1];
00666 
00667         cpl_property *property;
00668 
00669 
00670         status = _uves_propertylist_decode_fits(header, i, key, &type,
00671                                                value, comment);
00672 
00673         if (status) {
00674             switch (status) {
00675             case 1:
00676                 continue;
00677                 break;
00678 
00679             default:
00680                 return status;
00681                 break;
00682             }
00683         }
00684 
00685 
00686         if (filter != NULL && filter(key, data) == FALSE) {
00687             continue;
00688         }
00689 
00690 
00691         /*
00692          * Create the property from the parsed FITS card.
00693          */
00694 
00695         switch (type) {
00696             case QFITS_BOOLEAN:
00697                 property = cpl_property_new(key, CPL_TYPE_BOOL);
00698 
00699                 ival = *value == 'T' ? 1 : 0;
00700                 cpl_property_set_bool(property, ival);
00701                 cpl_property_set_comment(property, comment);
00702                 break;
00703 
00704             case QFITS_INT:
00705                 property = cpl_property_new(key, CPL_TYPE_INT);
00706 
00707                 sscanf(value, "%d", &ival);
00708                 cpl_property_set_int(property, ival);
00709                 cpl_property_set_comment(property, comment);
00710                 break;
00711 
00712             case QFITS_FLOAT:
00713                 property = cpl_property_new(key, CPL_TYPE_DOUBLE);
00714 
00715                 sscanf(value, "%lf", &dval);
00716                 cpl_property_set_double(property, dval);
00717                 cpl_property_set_comment(property, comment);
00718                 break;
00719 
00720                 /* FIXME: qfits does not correctly report the type for
00721                  *        string values if the single quotes have been
00722                  *        stripped. In this case it reports QFITS_UNKNOWN
00723                  *        for the value's type. As a temporary (!) work
00724                  *        around we accept everything unknown as a string.
00725                  */
00726 
00727             case QFITS_UNKNOWN:
00728             case QFITS_STRING:
00729                 property = cpl_property_new(key, CPL_TYPE_STRING);
00730 
00731                 cpl_property_set_string(property, value);
00732                 cpl_property_set_comment(property, comment);
00733                 break;
00734 
00735             case QFITS_COMPLEX:
00736 
00737                 /* FIXME: Add support for complex keywords. */
00738 
00739             default:
00740                 return 1;
00741                 break;
00742         }
00743 
00744         uves_deque_push_back(self->properties, property);
00745     }
00746 
00747     return 0;
00748 
00749 }
00750 
00751 
00752 
00753 /*
00754  * Public methods
00755  */
00756 
00771 uves_propertylist *
00772 uves_propertylist_new(void)
00773 {
00774 
00775     uves_propertylist *self = cx_malloc(sizeof *self);
00776 
00777     self->properties = uves_deque_new();
00778     return self;
00779 
00780 }
00781 
00782 
00808 uves_propertylist *
00809 uves_propertylist_duplicate(const uves_propertylist *self)
00810 {
00811 
00812     const cxchar *const _id = "uves_propertylist_duplicate";
00813 
00814     uves_deque_iterator first, last;
00815 
00816     uves_propertylist *copy = NULL;
00817 
00818 
00819     if (self == NULL) {
00820         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
00821         return NULL;
00822     }
00823 
00824     cx_assert(self->properties != NULL);
00825 
00826 
00827     copy = uves_propertylist_new();
00828 
00829     first = uves_deque_begin(self->properties);
00830     last = uves_deque_end(self->properties);
00831 
00832     while (first != last) {
00833         cpl_property *tmp = uves_deque_get(self->properties, first);
00834 
00835         uves_deque_push_back(copy->properties, cpl_property_duplicate(tmp));
00836         first = uves_deque_next(self->properties, first);
00837     }
00838 
00839     return copy;
00840 
00841 }
00842 
00843 
00857 void
00858 uves_propertylist_delete(const uves_propertylist *self)
00859 {
00860 
00861     if (self) {
00862         uves_deque_destroy(self->properties, (cx_free_func)cpl_property_delete);
00863         cx_free((void *)self);
00864     }
00865 
00866     return;
00867 
00868 }
00869 
00870 
00897 long
00898 uves_propertylist_get_size(const uves_propertylist *self)
00899 {
00900 
00901     const cxchar *const _id = "uves_propertylist_get_size";
00902 
00903 
00904     if (self == NULL) {
00905         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
00906         return 0L;
00907     }
00908 
00909     return (long) uves_deque_size(self->properties);
00910 
00911 }
00912 
00913 
00939 int
00940 uves_propertylist_is_empty(const uves_propertylist *self)
00941 {
00942 
00943     const cxchar *const _id = "uves_propertylist_is_empty";
00944 
00945 
00946     if (self == NULL) {
00947         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
00948         return -1;
00949     }
00950 
00951     return uves_deque_empty(self->properties);
00952 
00953 }
00954 
00955 
00990 cpl_type
00991 uves_propertylist_get_type(const uves_propertylist *self, const char *name)
00992 {
00993 
00994     const cxchar *const _id = "uves_propertylist_get_type";
00995 
00996     cpl_property *property;
00997 
00998 
00999     if (self == NULL || name == NULL) {
01000         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01001         return CPL_TYPE_INVALID;
01002     }
01003 
01004     property = _uves_propertylist_get(self, name);
01005 
01006     if (property == NULL) {
01007         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
01008         return CPL_TYPE_INVALID;
01009     }
01010 
01011     return cpl_property_get_type(property);
01012 
01013 }
01014 
01015 
01044 int
01045 uves_propertylist_contains(const uves_propertylist *self, const char *name)
01046 {
01047 
01048     const cxchar *const _id = "uves_propertylist_contains";
01049 
01050 
01051     if (self == NULL || name == NULL) {
01052         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01053         return 0;
01054     }
01055 
01056     return _uves_propertylist_get(self, name) != NULL ? 1 : 0;
01057 
01058 }
01059 
01060 
01061 
01062 
01063 
01092 int
01093 my_uves_propertylist_contains(const cpl_propertylist *self, const char *name)
01094 {
01095 
01096     const cxchar *const _id = "my_uves_propertylist_contains";
01097 
01098 
01099     if (self == NULL || name == NULL) {
01100         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01101         return 0;
01102     }
01103 
01104     return cpl_propertylist_has(self, name);
01105 
01106 }
01107 
01108 
01109 
01110 
01111 
01112 
01113 
01114 
01152 cpl_error_code
01153 uves_propertylist_set_comment(uves_propertylist *self, const char *name,
01154                              const char *comment)
01155 {
01156 
01157     const cxchar *const _id = "uves_propertylist_set_comment";
01158 
01159     cpl_property *property;
01160 
01161 
01162     if (self == NULL || name == NULL) {
01163         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01164         return CPL_ERROR_NULL_INPUT;
01165     }
01166 
01167     property = _uves_propertylist_get(self, name);
01168 
01169     if (property == NULL) {
01170         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
01171         return CPL_ERROR_DATA_NOT_FOUND;
01172     }
01173 
01174     cpl_property_set_comment(property, comment);
01175 
01176     return CPL_ERROR_NONE;
01177 
01178 }
01179 
01180 
01217 cpl_error_code
01218 uves_propertylist_set_char(uves_propertylist *self, const char *name,
01219                           char value)
01220 {
01221 
01222     const cxchar *const _id = "uves_propertylist_set_char";
01223 
01224     cpl_property *property;
01225 
01226 
01227     if (self == NULL || name == NULL) {
01228         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01229         return CPL_ERROR_NULL_INPUT;
01230     }
01231 
01232     property = _uves_propertylist_get(self, name);
01233 
01234     if (property == NULL) {
01235         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
01236         return CPL_ERROR_DATA_NOT_FOUND;
01237     }
01238 
01239     return cpl_property_set_char(property, value);
01240 
01241 }
01242 
01243 
01280 cpl_error_code
01281 uves_propertylist_set_bool(uves_propertylist *self, const char *name, int value)
01282 {
01283 
01284     const cxchar *const _id = "uves_propertylist_set_bool";
01285 
01286     cpl_property *property;
01287 
01288 
01289     if (self == NULL || name == NULL) {
01290         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01291         return CPL_ERROR_NULL_INPUT;
01292     }
01293 
01294     property = _uves_propertylist_get(self, name);
01295 
01296     if (property == NULL) {
01297         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
01298         return CPL_ERROR_DATA_NOT_FOUND;
01299     }
01300 
01301     return cpl_property_set_bool(property, value);
01302 
01303 }
01304 
01305 
01342 cpl_error_code
01343 uves_propertylist_set_int(uves_propertylist *self, const char *name, int value)
01344 {
01345 
01346     const cxchar *const _id = "uves_propertylist_set_int";
01347 
01348     cpl_property *property;
01349 
01350 
01351     if (self == NULL || name == NULL) {
01352         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01353         return CPL_ERROR_NULL_INPUT;
01354     }
01355 
01356     property = _uves_propertylist_get(self, name);
01357 
01358     if (property == NULL) {
01359         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
01360         return CPL_ERROR_DATA_NOT_FOUND;
01361     }
01362 
01363     return cpl_property_set_int(property, value);
01364 
01365 }
01366 
01367 
01404 cpl_error_code
01405 uves_propertylist_set_long(uves_propertylist *self, const char *name,
01406                           long value)
01407 {
01408 
01409     const cxchar *const _id = "uves_propertylist_set_long";
01410 
01411     cpl_property *property;
01412 
01413 
01414     if (self == NULL || name == NULL) {
01415         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01416         return CPL_ERROR_NULL_INPUT;
01417     }
01418 
01419     property = _uves_propertylist_get(self, name);
01420 
01421     if (property == NULL) {
01422         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
01423         return CPL_ERROR_DATA_NOT_FOUND;
01424     }
01425 
01426     return cpl_property_set_long(property, value);
01427 
01428 }
01429 
01430 
01467 cpl_error_code
01468 uves_propertylist_set_float(uves_propertylist *self, const char *name,
01469                            float value)
01470 {
01471 
01472     const cxchar *const _id = "uves_propertylist_set_float";
01473 
01474     cpl_property *property;
01475 
01476 
01477     if (self == NULL || name == NULL) {
01478         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01479         return CPL_ERROR_NULL_INPUT;
01480     }
01481 
01482     property = _uves_propertylist_get(self, name);
01483 
01484     if (property == NULL) {
01485         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
01486         return CPL_ERROR_DATA_NOT_FOUND;
01487     }
01488 
01489     return cpl_property_set_float(property, value);
01490 
01491 }
01492 
01493 
01530 cpl_error_code
01531 uves_propertylist_set_double(uves_propertylist *self, const char *name,
01532                             double value)
01533 {
01534 
01535     const cxchar *const _id = "uves_propertylist_set_double";
01536 
01537     cpl_property *property;
01538 
01539 
01540     if (self == NULL || name == NULL) {
01541         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01542         return CPL_ERROR_NULL_INPUT;
01543     }
01544 
01545     property = _uves_propertylist_get(self, name);
01546 
01547     if (property == NULL) {
01548         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
01549         return CPL_ERROR_DATA_NOT_FOUND;
01550     }
01551 
01552     return cpl_property_set_double(property, value);
01553 
01554 }
01555 
01556 
01593 cpl_error_code
01594 uves_propertylist_set_string(uves_propertylist *self, const char *name,
01595                             const char *value)
01596 {
01597 
01598     const cxchar *const _id = "uves_propertylist_set_string";
01599 
01600     cpl_property *property;
01601 
01602 
01603     if (self == NULL || name == NULL) {
01604         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01605         return CPL_ERROR_NULL_INPUT;
01606     }
01607 
01608     property = _uves_propertylist_get(self, name);
01609 
01610     if (property == NULL) {
01611         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
01612         return CPL_ERROR_DATA_NOT_FOUND;
01613     }
01614 
01615     return cpl_property_set_string(property, value);
01616 
01617 }
01618 
01619 
01649 const cpl_property *
01650 uves_propertylist_get_const(const uves_propertylist *self, long position)
01651 {
01652 
01653     const cxchar *const _id = "uves_propertylist_get";
01654 
01655 //    register cxsize i = 0;
01656 
01657     uves_deque_iterator first, last;
01658 
01659 
01660     if (self == NULL) {
01661         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01662         return NULL;
01663     }
01664 
01665     if (position < 0) {
01666         return NULL;
01667     }
01668 
01669     first = uves_deque_begin(self->properties);
01670     last = uves_deque_end(self->properties);
01671 
01672 //    while (i < (cxsize)position && first != last) {
01673 //        first = uves_deque_next(self->properties, first);
01674 //        i++;
01675 //    }
01676 
01677     if (first == last) {
01678         return NULL;
01679     }
01680 
01681 //    return uves_deque_get(self->properties, first);
01682     return uves_deque_get(self->properties, position);
01683 
01684 }
01685 
01686 cpl_property *
01687 uves_propertylist_get(uves_propertylist *self, long position)
01688 {
01689     return (cpl_property *)uves_propertylist_get_const(self, position);
01690 }
01691 
01692 
01728 const char *
01729 uves_propertylist_get_comment(const uves_propertylist *self, const char *name)
01730 {
01731 
01732     const cxchar *const _id = "uves_propertylist_get_comment";
01733 
01734     cpl_property *property;
01735 
01736 
01737     if (self == NULL || name == NULL) {
01738         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01739         return NULL;
01740     }
01741 
01742     property = _uves_propertylist_get(self, name);
01743 
01744     if (!property) {
01745         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
01746         return NULL;
01747     }
01748 
01749     return cpl_property_get_comment(property);
01750 
01751 }
01752 
01753 
01795 char
01796 uves_propertylist_get_char(const uves_propertylist *self, const char *name)
01797 {
01798 
01799     const cxchar *const _id = "uves_propertylist_get_char";
01800 
01801     cxchar result;
01802 
01803     cpl_property *property;
01804 
01805 
01806     if (self == NULL || name == NULL) {
01807         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01808         return '\0';
01809     }
01810 
01811     property = _uves_propertylist_get(self, name);
01812 
01813     if (!property) {
01814         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
01815         return '\0';
01816     }
01817 
01818     error_push();
01819 //jmlarsen: this is not exported    cpl_error_push();
01820 
01821     result = cpl_property_get_char(property);
01822 
01823     /*
01824      * If an error occurred change any possibly set location to this
01825      * function.
01826      */
01827 
01828     if (cpl_error_get_code() != CPL_ERROR_NONE) {
01829         cpl_error_set_where(_id);
01830         return '\0';
01831     }
01832 
01833 //jmlarsen: this is not exported    cpl_error_pop();
01834     error_pop();
01835 
01836     return result;
01837 
01838 }
01839 
01840 
01884 int
01885 uves_propertylist_get_bool(const uves_propertylist *self, const char *name)
01886 {
01887 
01888     const cxchar *const _id = "uves_propertylist_get_bool";
01889 
01890     cxbool result;
01891 
01892     cpl_property *property;
01893 
01894 
01895     if (self == NULL || name == NULL) {
01896         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01897         return 0;
01898     }
01899 
01900     property = _uves_propertylist_get(self, name);
01901 
01902     if (!property) {
01903         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
01904         return 0;
01905     }
01906 
01907     error_push();
01908 //jmlarsen: this is not exported    cpl_error_push();
01909 
01910     result = cpl_property_get_bool(property);
01911 
01912     /*
01913      * If an error occurred change any possibly set location to this
01914      * function.
01915      */
01916 
01917     if (cpl_error_get_code() != CPL_ERROR_NONE) {
01918         cpl_error_set_where(_id);
01919         return 0;
01920     }
01921 
01922 //jmlarsen: this is not exported    cpl_error_pop();
01923     error_pop();
01924 
01925     return result == TRUE ? 1 : 0;
01926 
01927 }
01928 
01929 
01971 int
01972 uves_propertylist_get_int(const uves_propertylist *self, const char *name)
01973 {
01974 
01975     const cxchar *const _id = "uves_propertylist_get_int";
01976 
01977     cxint result;
01978 
01979     cpl_property *property;
01980 
01981 
01982     if (self == NULL || name == NULL) {
01983         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
01984         return 0;
01985     }
01986 
01987     property = _uves_propertylist_get(self, name);
01988 
01989     if (!property) {
01990         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
01991         return 0;
01992     }
01993 
01994     error_push();
01995 //jmlarsen: this is not exported    cpl_error_push();
01996 
01997     result = cpl_property_get_int(property);
01998 
01999     /*
02000      * If an error occurred change any possibly set location to this
02001      * function.
02002      */
02003 
02004     if (cpl_error_get_code() != CPL_ERROR_NONE) {
02005         cpl_error_set_where(_id);
02006         return 0;
02007     }
02008 
02009 //jmlarsen: this is not exported    cpl_error_pop();
02010     error_pop();
02011 
02012     return result;
02013 
02014 }
02015 
02016 
02058 long
02059 uves_propertylist_get_long(const uves_propertylist *self, const char *name)
02060 {
02061 
02062     const cxchar *const _id = "uves_propertylist_get_long";
02063 
02064     cxlong result;
02065 
02066     cpl_property *property;
02067 
02068 
02069     if (self == NULL || name == NULL) {
02070         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02071         return 0;
02072     }
02073 
02074     property = _uves_propertylist_get(self, name);
02075 
02076     if (!property) {
02077         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
02078         return 0;
02079     }
02080 
02081     error_push();
02082 //jmlarsen: this is not exported    cpl_error_push();
02083 
02084     result = cpl_property_get_long(property);
02085 
02086     /*
02087      * If an error occurred change any possibly set location to this
02088      * function.
02089      */
02090 
02091     if (cpl_error_get_code() != CPL_ERROR_NONE) {
02092         cpl_error_set_where(_id);
02093         return 0;
02094     }
02095 
02096 //jmlarsen: this is not exported    cpl_error_pop();
02097     error_pop();
02098 
02099     return result;
02100 
02101 }
02102 
02103 
02145 float
02146 uves_propertylist_get_float(const uves_propertylist *self, const char *name)
02147 {
02148 
02149     const cxchar *const _id = "uves_propertylist_get_float";
02150 
02151     cxfloat result;
02152 
02153     cpl_property *property;
02154 
02155 
02156     if (self == NULL || name == NULL) {
02157         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02158         return 0;
02159     }
02160 
02161     property = _uves_propertylist_get(self, name);
02162 
02163     if (!property) {
02164         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
02165         return 0;
02166     }
02167 
02168     error_push();
02169 //jmlarsen: this is not exported    cpl_error_push();
02170 
02171     result = cpl_property_get_float(property);
02172 
02173     /*
02174      * If an error occurred change any possibly set location to this
02175      * function.
02176      */
02177 
02178     if (cpl_error_get_code() != CPL_ERROR_NONE) {
02179         cpl_error_set_where(_id);
02180         return 0;
02181     }
02182 
02183 //jmlarsen: this is not exported    cpl_error_pop();
02184     error_pop();
02185 
02186     return result;
02187 
02188 }
02189 
02190 
02232 double
02233 uves_propertylist_get_double(const uves_propertylist *self, const char *name)
02234 {
02235 
02236     const cxchar *const _id = "uves_propertylist_get_double";
02237 
02238     cxdouble result;
02239 
02240     cpl_property *property;
02241 
02242 
02243     if (self == NULL || name == NULL) {
02244         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02245         return 0;
02246     }
02247 
02248     property = _uves_propertylist_get(self, name);
02249 
02250     if (!property) {
02251         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
02252         return 0;
02253     }
02254 
02255     error_push();
02256 //jmlarsen: this is not exported    cpl_error_push();
02257 
02258     result = cpl_property_get_double(property);
02259 
02260     /*
02261      * If an error occurred change any possibly set location to this
02262      * function.
02263      */
02264 
02265     if (cpl_error_get_code() != CPL_ERROR_NONE) {
02266         cpl_error_set_where(_id);
02267         return 0;
02268     }
02269 
02270 //jmlarsen: this is not exported    cpl_error_pop();
02271     error_pop();
02272 
02273     return result;
02274 
02275 }
02276 
02277 
02321 const char *
02322 uves_propertylist_get_string(const uves_propertylist *self, const char *name)
02323 {
02324 
02325     const cxchar *const _id = "uves_propertylist_get_string";
02326 
02327     const cxchar *result;
02328 
02329     cpl_property *property;
02330 
02331 
02332     if (self == NULL || name == NULL) {
02333         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02334         return NULL;
02335     }
02336 
02337     property = _uves_propertylist_get(self, name);
02338 
02339     if (!property) {
02340         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
02341         return NULL;
02342     }
02343 
02344     error_push();
02345 //jmlarsen: this is not exported    cpl_error_push();
02346 
02347     result = cpl_property_get_string(property);
02348 
02349     /*
02350      * If an error occurred change any possibly set location to this
02351      * function.
02352      */
02353 
02354     if (cpl_error_get_code() != CPL_ERROR_NONE) {
02355         cpl_error_set_where(_id);
02356         return NULL;
02357     }
02358 
02359 //jmlarsen: this is not exported    cpl_error_pop();
02360     error_pop();
02361 
02362     return result;
02363 
02364 }
02365 
02366 
02404 cpl_error_code
02405 uves_propertylist_insert_char(uves_propertylist *self, const char *here,
02406                              const char *name, char value)
02407 {
02408 
02409     const cxchar *const _id = "uves_propertylist_insert_char";
02410 
02411     cxint status = 0;
02412 
02413 
02414     if (self == NULL || here == NULL || name == NULL) {
02415         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02416         return CPL_ERROR_NULL_INPUT;
02417     }
02418 
02419     status = _uves_propertylist_insert(self, here, FALSE, name,
02420                                       CPL_TYPE_CHAR, &value);
02421 
02422     if (status) {
02423         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
02424         return CPL_ERROR_UNSPECIFIED;
02425     }
02426 
02427     return CPL_ERROR_NONE;
02428 
02429 }
02430 
02431 
02469 cpl_error_code
02470 uves_propertylist_insert_bool(uves_propertylist *self, const char *here,
02471                              const char *name, int value)
02472 {
02473 
02474     const cxchar *const _id = "uves_propertylist_insert_bool";
02475 
02476     cxint status = 0;
02477 
02478 
02479     if (self == NULL || here == NULL || name == NULL) {
02480         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02481         return CPL_ERROR_NULL_INPUT;
02482     }
02483 
02484     status =  _uves_propertylist_insert(self, here, FALSE, name,
02485                                        CPL_TYPE_BOOL, &value);
02486 
02487     if (status) {
02488         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
02489         return CPL_ERROR_UNSPECIFIED;
02490     }
02491 
02492     return CPL_ERROR_NONE;
02493 
02494 }
02495 
02496 
02534 cpl_error_code
02535 uves_propertylist_insert_int(uves_propertylist *self, const char *here,
02536                             const char *name, int value)
02537 {
02538 
02539     const cxchar *const _id = "uves_propertylist_insert_int";
02540 
02541     cxint status = 0;
02542 
02543 
02544     if (self == NULL || here == NULL || name == NULL) {
02545         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02546         return CPL_ERROR_NULL_INPUT;
02547     }
02548 
02549     status = _uves_propertylist_insert(self, here, FALSE, name,
02550                                       CPL_TYPE_INT, &value);
02551 
02552     if (status) {
02553         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
02554         return CPL_ERROR_UNSPECIFIED;
02555     }
02556 
02557     return CPL_ERROR_NONE;
02558 
02559 }
02588 int
02589 uves_propertylist_has(const uves_propertylist *self, const char *name)
02590 {
02591 
02592     const cxchar *const _id = "cpl_propertylist_has";
02593 
02594 
02595     if (self == NULL || name == NULL) {
02596         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02597         return 0;
02598     }
02599 
02600     return _uves_propertylist_get(self, name) != NULL ? 1 : 0;
02601 
02602 }
02603 
02604 
02642 cpl_error_code
02643 uves_propertylist_insert_long(uves_propertylist *self, const char *here,
02644                              const char *name, long value)
02645 {
02646 
02647     const cxchar *const _id = "uves_propertylist_insert_long";
02648 
02649     cxint status = 0;
02650 
02651 
02652     if (self == NULL || here == NULL || name == NULL) {
02653         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02654         return CPL_ERROR_NULL_INPUT;
02655     }
02656 
02657     status = _uves_propertylist_insert(self, here, FALSE, name,
02658                                       CPL_TYPE_LONG, &value);
02659 
02660     if (status) {
02661         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
02662         return CPL_ERROR_UNSPECIFIED;
02663     }
02664 
02665     return CPL_ERROR_NONE;
02666 
02667 }
02668 
02669 
02707 cpl_error_code
02708 uves_propertylist_insert_float(uves_propertylist *self, const char *here,
02709                               const char *name, float value)
02710 {
02711 
02712     const cxchar *const _id = "uves_propertylist_insert_float";
02713 
02714     cxint status = 0;
02715 
02716 
02717     if (self == NULL || here == NULL || name == NULL) {
02718         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02719         return CPL_ERROR_NULL_INPUT;
02720     }
02721 
02722     status = _uves_propertylist_insert(self, here, FALSE, name,
02723                                       CPL_TYPE_FLOAT, &value);
02724 
02725     if (status) {
02726         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
02727         return CPL_ERROR_UNSPECIFIED;
02728     }
02729 
02730     return CPL_ERROR_NONE;
02731 
02732 }
02733 
02734 
02772 cpl_error_code
02773 uves_propertylist_insert_double(uves_propertylist *self, const char *here,
02774                                const char *name, double value)
02775 {
02776 
02777     const cxchar *const _id = "uves_propertylist_insert_char";
02778 
02779     cxint status = 0;
02780 
02781 
02782     if (self == NULL || here == NULL || name == NULL) {
02783         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02784         return CPL_ERROR_NULL_INPUT;
02785     }
02786 
02787     status = _uves_propertylist_insert(self, here, FALSE, name,
02788                                       CPL_TYPE_DOUBLE, &value);
02789 
02790     if (status) {
02791         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
02792         return CPL_ERROR_UNSPECIFIED;
02793     }
02794 
02795     return CPL_ERROR_NONE;
02796 
02797 }
02798 
02799 
02837 cpl_error_code
02838 uves_propertylist_insert_string(uves_propertylist *self, const char *here,
02839                                const char *name, const char *value)
02840 {
02841 
02842     const cxchar *const _id = "uves_propertylist_insert_string";
02843 
02844     cxint status = 0;
02845 
02846 
02847     if (self == NULL || here == NULL || name == NULL) {
02848         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02849         return CPL_ERROR_NULL_INPUT;
02850     }
02851 
02852     status = _uves_propertylist_insert(self, here, FALSE, name,
02853                                       CPL_TYPE_STRING, (cxptr)value);
02854 
02855     if (status) {
02856         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
02857         return CPL_ERROR_UNSPECIFIED;
02858     }
02859 
02860     return CPL_ERROR_NONE;
02861 
02862 }
02863 
02864 
02902 cpl_error_code
02903 uves_propertylist_insert_after_char(uves_propertylist *self, const char *after,
02904                                    const char *name, char value)
02905 {
02906 
02907     const cxchar *const _id = "uves_propertylist_insert_after_char";
02908 
02909     cxint status = 0;
02910 
02911 
02912     if (self == NULL || after == NULL || name == NULL) {
02913         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02914         return CPL_ERROR_NULL_INPUT;
02915     }
02916 
02917     status = _uves_propertylist_insert(self, after, TRUE, name,
02918                                       CPL_TYPE_CHAR, &value);
02919 
02920     if (status) {
02921         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
02922         return CPL_ERROR_UNSPECIFIED;
02923     }
02924 
02925     return CPL_ERROR_NONE;
02926 
02927 }
02928 
02929 
02967 cpl_error_code
02968 uves_propertylist_insert_after_bool(uves_propertylist *self, const char *after,
02969                                    const char *name, int value)
02970 {
02971 
02972     const cxchar *const _id = "uves_propertylist_insert_after_bool";
02973 
02974     cxint status = 0;
02975 
02976 
02977     if (self == NULL || after == NULL || name == NULL) {
02978         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02979         return CPL_ERROR_NULL_INPUT;
02980     }
02981 
02982     status = _uves_propertylist_insert(self, after, TRUE, name,
02983                                       CPL_TYPE_BOOL, &value);
02984 
02985     if (status) {
02986         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
02987         return CPL_ERROR_UNSPECIFIED;
02988     }
02989 
02990     return CPL_ERROR_NONE;
02991 
02992 }
02993 
02994 
03032 cpl_error_code
03033 uves_propertylist_insert_after_int(uves_propertylist *self, const char *after,
03034                                   const char *name, int value)
03035 {
03036 
03037     const cxchar *const _id = "uves_propertylist_insert_after_int";
03038 
03039     cxint status = 0;
03040 
03041 
03042     if (self == NULL || after == NULL || name == NULL) {
03043         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03044         return CPL_ERROR_NULL_INPUT;
03045     }
03046 
03047     status = _uves_propertylist_insert(self, after, TRUE, name,
03048                                       CPL_TYPE_INT, &value);
03049 
03050     if (status) {
03051         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
03052         return CPL_ERROR_UNSPECIFIED;
03053     }
03054 
03055     return CPL_ERROR_NONE;
03056 
03057 }
03058 
03059 
03097 cpl_error_code
03098 uves_propertylist_insert_after_long(uves_propertylist *self, const char *after,
03099                                    const char *name, long value)
03100 {
03101 
03102     const cxchar *const _id = "uves_propertylist_insert_after_long";
03103 
03104     cxint status = 0;
03105 
03106 
03107     if (self == NULL || after == NULL || name == NULL) {
03108         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03109         return CPL_ERROR_NULL_INPUT;
03110     }
03111 
03112     status = _uves_propertylist_insert(self, after, TRUE, name,
03113                                       CPL_TYPE_LONG, &value);
03114 
03115     if (status) {
03116         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
03117         return CPL_ERROR_UNSPECIFIED;
03118     }
03119 
03120     return CPL_ERROR_NONE;
03121 
03122 }
03123 
03124 
03162 cpl_error_code
03163 uves_propertylist_insert_after_float(uves_propertylist *self, const char *after,
03164                                     const char *name, float value)
03165 {
03166 
03167     const cxchar *const _id = "uves_propertylist_insert_after_float";
03168 
03169     cxint status = 0;
03170 
03171 
03172     if (self == NULL || after == NULL || name == NULL) {
03173         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03174         return CPL_ERROR_NULL_INPUT;
03175     }
03176 
03177     status = _uves_propertylist_insert(self, after, TRUE, name,
03178                                       CPL_TYPE_FLOAT, &value);
03179 
03180     if (status) {
03181         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
03182         return CPL_ERROR_UNSPECIFIED;
03183     }
03184 
03185     return CPL_ERROR_NONE;
03186 
03187 }
03188 
03189 
03227 cpl_error_code
03228 uves_propertylist_insert_after_double(uves_propertylist *self,
03229                                      const char *after, const char *name,
03230                                      double value)
03231 {
03232 
03233     const cxchar *const _id = "uves_propertylist_insert_after_double";
03234 
03235     cxint status = 0;
03236 
03237 
03238     if (self == NULL || after == NULL || name == NULL) {
03239         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03240         return CPL_ERROR_NULL_INPUT;
03241     }
03242 
03243     status = _uves_propertylist_insert(self, after, TRUE, name,
03244                                       CPL_TYPE_DOUBLE, &value);
03245 
03246     if (status) {
03247         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
03248         return CPL_ERROR_UNSPECIFIED;
03249     }
03250 
03251     return CPL_ERROR_NONE;
03252 
03253 }
03254 
03255 
03293 cpl_error_code
03294 uves_propertylist_insert_after_string(uves_propertylist *self,
03295                                      const char *after, const char *name,
03296                                      const char *value)
03297 {
03298 
03299     const cxchar *const _id = "uves_propertylist_insert_after_string";
03300 
03301     cxint status = 0;
03302 
03303 
03304     if (self == NULL || after == NULL || name == NULL) {
03305         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03306         return CPL_ERROR_NULL_INPUT;
03307     }
03308 
03309     status =  _uves_propertylist_insert(self, after, TRUE, name,
03310                                        CPL_TYPE_STRING, (cxptr)value);
03311 
03312     if (status) {
03313         cpl_error_set(_id, CPL_ERROR_UNSPECIFIED);
03314         return CPL_ERROR_UNSPECIFIED;
03315     }
03316 
03317     return CPL_ERROR_NONE;
03318 
03319 }
03320 
03321 
03350 cpl_error_code
03351 uves_propertylist_prepend_char(uves_propertylist *self, const char *name,
03352                               char value)
03353 {
03354 
03355     const cxchar *const _id = "uves_propertylist_prepend_char";
03356 
03357     cpl_property *property = NULL;
03358 
03359 
03360     if (self == NULL || name == NULL) {
03361         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03362         return CPL_ERROR_NULL_INPUT;
03363     }
03364 
03365     property = cpl_property_new(name, CPL_TYPE_CHAR);
03366     cx_assert(property != NULL);
03367 
03368     cpl_property_set_char(property, value);
03369     uves_deque_push_front(self->properties, property);
03370 
03371     return CPL_ERROR_NONE;
03372 
03373 }
03374 
03375 
03404 cpl_error_code
03405 uves_propertylist_prepend_bool(uves_propertylist *self, const char *name,
03406                               int value)
03407 {
03408 
03409     const cxchar *const _id = "uves_propertylist_prepend_bool";
03410 
03411     cpl_property *property = NULL;
03412 
03413 
03414     if (self == NULL || name == NULL) {
03415         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03416         return CPL_ERROR_NULL_INPUT;
03417     }
03418 
03419     property = cpl_property_new(name, CPL_TYPE_BOOL);
03420     cx_assert(property != NULL);
03421 
03422     cpl_property_set_bool(property, value);
03423     uves_deque_push_front(self->properties, property);
03424 
03425     return CPL_ERROR_NONE;
03426 
03427 }
03428 
03429 
03458 cpl_error_code
03459 uves_propertylist_prepend_int(uves_propertylist *self, const char *name,
03460                              int value)
03461 {
03462 
03463     const cxchar *const _id = "uves_propertylist_prepend_int";
03464 
03465     cpl_property *property = NULL;
03466 
03467 
03468     if (self == NULL || name == NULL) {
03469         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03470         return CPL_ERROR_NULL_INPUT;
03471     }
03472 
03473     property = cpl_property_new(name, CPL_TYPE_INT);
03474     cx_assert(property != NULL);
03475 
03476     cpl_property_set_int(property, value);
03477     uves_deque_push_front(self->properties, property);
03478 
03479     return CPL_ERROR_NONE;
03480 
03481 }
03482 
03483 
03512 cpl_error_code
03513 uves_propertylist_prepend_long(uves_propertylist *self, const char *name,
03514                               long value)
03515 {
03516 
03517     const cxchar *const _id = "uves_propertylist_prepend_long";
03518 
03519     cpl_property *property = NULL;
03520 
03521 
03522     if (self == NULL || name == NULL) {
03523         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03524         return CPL_ERROR_NULL_INPUT;
03525     }
03526 
03527     property = cpl_property_new(name, CPL_TYPE_LONG);
03528     cx_assert(property != NULL);
03529 
03530     cpl_property_set_long(property, value);
03531     uves_deque_push_front(self->properties, property);
03532 
03533     return CPL_ERROR_NONE;
03534 
03535 }
03536 
03537 
03566 cpl_error_code
03567 uves_propertylist_prepend_float(uves_propertylist *self, const char *name,
03568                                float value)
03569 {
03570 
03571     const cxchar *const _id = "uves_propertylist_prepend_float";
03572 
03573     cpl_property *property = NULL;
03574 
03575 
03576     if (self == NULL || name == NULL) {
03577         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03578         return CPL_ERROR_NULL_INPUT;
03579     }
03580 
03581     property = cpl_property_new(name, CPL_TYPE_FLOAT);
03582     cx_assert(property != NULL);
03583 
03584     cpl_property_set_float(property, value);
03585     uves_deque_push_front(self->properties, property);
03586 
03587     return CPL_ERROR_NONE;
03588 
03589 }
03590 
03591 
03620 cpl_error_code
03621 uves_propertylist_prepend_double(uves_propertylist *self, const char *name,
03622                                 double value)
03623 {
03624 
03625     const cxchar *const _id = "uves_propertylist_prepend_double";
03626 
03627     cpl_property *property = NULL;
03628 
03629 
03630     if (self == NULL || name == NULL) {
03631         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03632         return CPL_ERROR_NULL_INPUT;
03633     }
03634 
03635     property = cpl_property_new(name, CPL_TYPE_DOUBLE);
03636     cx_assert(property != NULL);
03637 
03638     cpl_property_set_double(property, value);
03639     uves_deque_push_front(self->properties, property);
03640 
03641     return CPL_ERROR_NONE;
03642 
03643 }
03644 
03645 
03674 cpl_error_code
03675 uves_propertylist_prepend_string(uves_propertylist *self, const char *name,
03676                                 const char *value)
03677 {
03678 
03679     const cxchar *const _id = "uves_propertylist_prepend_string";
03680 
03681     cpl_property *property = NULL;
03682 
03683 
03684     if (self == NULL || name == NULL) {
03685         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03686         return CPL_ERROR_NULL_INPUT;
03687     }
03688 
03689     property = cpl_property_new(name, CPL_TYPE_STRING);
03690     cx_assert(property != NULL);
03691 
03692     cpl_property_set_string(property, value);
03693     uves_deque_push_front(self->properties, property);
03694 
03695     return CPL_ERROR_NONE;
03696 
03697 }
03698 
03699 
03700 
03701 cpl_error_code
03702 uves_propertylist_append_char(uves_propertylist *self, const char *name,
03703                              char value)
03704 {
03705     return uves_propertylist_append_c_char(self, name, value, NULL);
03706 }
03707 cpl_error_code
03708 uves_propertylist_append_bool(uves_propertylist *self, const char *name,
03709                              int value)
03710 {
03711     return uves_propertylist_append_c_bool(self, name, value, NULL);
03712 }
03713 
03714 cpl_error_code
03715 uves_propertylist_append_int(uves_propertylist *self, const char *name,
03716                             int value)
03717 {
03718     return uves_propertylist_append_c_int(self, name, value, NULL);
03719 }
03720 
03721 cpl_error_code
03722 uves_propertylist_append_long(uves_propertylist *self, const char *name,
03723                              long value)
03724 {
03725     return uves_propertylist_append_c_long(self, name, value, NULL);
03726 }
03727 
03728 cpl_error_code
03729 uves_propertylist_append_float(uves_propertylist *self, const char *name,
03730                               float value)
03731 {
03732     return uves_propertylist_append_c_float(self, name, value, NULL);
03733 }
03734 
03735 cpl_error_code
03736 uves_propertylist_append_double(uves_propertylist *self, const char *name,
03737                                double value)
03738 {
03739     return uves_propertylist_append_c_double(self, name, value, NULL);
03740 }
03741 
03742 cpl_error_code
03743 uves_propertylist_append_string(uves_propertylist *self, const char *name,
03744                                const char *value)
03745 {
03746     return uves_propertylist_append_c_string(self, name, value, NULL);
03747 }
03748 
03749 
03750 
03751 
03752 
03753 
03754 
03755 
03756 
03757 
03758 
03759 
03760 
03761 
03762 
03763 
03764 
03765 
03794 cpl_error_code
03795 uves_propertylist_append_c_char(uves_propertylist *self, const char *name,
03796                              char value, const char *comment)
03797 {
03798 
03799     const cxchar *const _id = "uves_propertylist_append_char";
03800 
03801     cpl_property *property = NULL;
03802 
03803 
03804     if (self == NULL || name == NULL) {
03805         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03806         return CPL_ERROR_NULL_INPUT;
03807     }
03808 
03809     property = cpl_property_new(name, CPL_TYPE_CHAR);
03810     cx_assert(property != NULL);
03811 
03812     if (comment != NULL) cpl_property_set_comment(property, comment);
03813 
03814     cpl_property_set_char(property, value);
03815     uves_deque_push_back(self->properties, property);
03816 
03817     return CPL_ERROR_NONE;
03818 
03819 }
03820 
03821 
03850 cpl_error_code
03851 uves_propertylist_append_c_bool(uves_propertylist *self, const char *name,
03852                              int value, const char *comment)
03853 {
03854 
03855     const cxchar *const _id = "uves_propertylist_append_bool";
03856 
03857     cpl_property *property = NULL;
03858 
03859 
03860     if (self == NULL || name == NULL) {
03861         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03862         return CPL_ERROR_NULL_INPUT;
03863     }
03864 
03865     property = cpl_property_new(name, CPL_TYPE_BOOL);
03866     cx_assert(property != NULL);
03867 
03868     if (comment != NULL) cpl_property_set_comment(property, comment);
03869 
03870     cpl_property_set_bool(property, value);
03871     uves_deque_push_back(self->properties, property);
03872 
03873     return CPL_ERROR_NONE;
03874 
03875 }
03876 
03877 
03906 cpl_error_code
03907 uves_propertylist_append_c_int(uves_propertylist *self, const char *name,
03908                             int value, const char *comment)
03909 {
03910 
03911     const cxchar *const _id = "uves_propertylist_append_int";
03912 
03913     cpl_property *property = NULL;
03914 
03915 
03916     if (self == NULL || name == NULL) {
03917         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03918         return CPL_ERROR_NULL_INPUT;
03919     }
03920 
03921     property = cpl_property_new(name, CPL_TYPE_INT);
03922     cx_assert(property != NULL);
03923 
03924     if (comment != NULL) cpl_property_set_comment(property, comment);
03925 
03926     cpl_property_set_int(property, value);
03927     uves_deque_push_back(self->properties, property);
03928 
03929     return CPL_ERROR_NONE;
03930 
03931 }
03932 
03933 
03962 cpl_error_code
03963 uves_propertylist_append_c_long(uves_propertylist *self, const char *name,
03964                              long value, const char *comment)
03965 {
03966 
03967     const cxchar *const _id = "uves_propertylist_append_long";
03968 
03969     cpl_property *property = NULL;
03970 
03971 
03972     if (self == NULL || name == NULL) {
03973         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
03974         return CPL_ERROR_NULL_INPUT;
03975     }
03976 
03977     property = cpl_property_new(name, CPL_TYPE_LONG);
03978     cx_assert(property != NULL);
03979 
03980     if (comment != NULL) cpl_property_set_comment(property, comment);
03981 
03982     cpl_property_set_long(property, value);
03983     uves_deque_push_back(self->properties, property);
03984 
03985     return CPL_ERROR_NONE;
03986 
03987 }
03988 
03989 
04018 cpl_error_code
04019 uves_propertylist_append_c_float(uves_propertylist *self, const char *name,
04020                               float value, const char *comment)
04021 {
04022 
04023     const cxchar *const _id = "uves_propertylist_append_float";
04024 
04025     cpl_property *property = NULL;
04026 
04027 
04028     if (self == NULL || name == NULL) {
04029         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
04030         return CPL_ERROR_NULL_INPUT;
04031     }
04032 
04033     property = cpl_property_new(name, CPL_TYPE_FLOAT);
04034     cx_assert(property != NULL);
04035 
04036     if (comment != NULL) cpl_property_set_comment(property, comment);
04037 
04038     cpl_property_set_float(property, value);
04039     uves_deque_push_back(self->properties, property);
04040 
04041     return CPL_ERROR_NONE;
04042 
04043 }
04044 
04045 
04074 cpl_error_code
04075 uves_propertylist_append_c_double(uves_propertylist *self, const char *name,
04076                                double value, const char *comment)
04077 {
04078 
04079     const cxchar *const _id = "uves_propertylist_append_double";
04080 
04081     cpl_property *property = NULL;
04082 
04083 
04084     if (self == NULL || name == NULL) {
04085         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
04086         return CPL_ERROR_NULL_INPUT;
04087     }
04088 
04089     property = cpl_property_new(name, CPL_TYPE_DOUBLE);
04090     cx_assert(property != NULL);
04091 
04092     if (comment != NULL) cpl_property_set_comment(property, comment);
04093 
04094     cpl_property_set_double(property, value);
04095     uves_deque_push_back(self->properties, property);
04096 
04097     return CPL_ERROR_NONE;
04098 
04099 }
04100 
04101 
04130 cpl_error_code
04131 uves_propertylist_append_c_string(uves_propertylist *self, const char *name,
04132                                const char *value, const char *comment)
04133 {
04134 
04135     const cxchar *const _id = "uves_propertylist_append_string";
04136 
04137     cpl_property *property = NULL;
04138 
04139 
04140     if (self == NULL || name == NULL) {
04141         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
04142         return CPL_ERROR_NULL_INPUT;
04143     }
04144 
04145     property = cpl_property_new(name, CPL_TYPE_STRING);
04146     cx_assert(property != NULL);
04147 
04148     if (comment != NULL) cpl_property_set_comment(property, comment);
04149 
04150     cpl_property_set_string(property, value);
04151     uves_deque_push_back(self->properties, property);
04152 
04153     return CPL_ERROR_NONE;
04154 
04155 }
04156 
04157 
04184 cpl_error_code
04185 uves_propertylist_append(uves_propertylist *self,
04186                         const uves_propertylist *other)
04187 {
04188 
04189     const cxchar *const _id = "uves_propertylist_append";
04190 
04191     if (self == NULL) {
04192         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
04193         return CPL_ERROR_NULL_INPUT;
04194     }
04195 
04196     if (other != NULL) {
04197 
04198         uves_deque_const_iterator pos = uves_deque_begin(other->properties);
04199 
04200         while (pos != uves_deque_end(other->properties)) {
04201 
04202             const cpl_property *p = uves_deque_get(other->properties, pos);
04203 
04204             uves_deque_push_back(self->properties, cpl_property_duplicate(p));
04205             pos = uves_deque_next(other->properties, pos);
04206 
04207         }
04208 
04209     }
04210 
04211     return CPL_ERROR_NONE;
04212 
04213 }
04214 
04215 
04246 int
04247 uves_propertylist_erase(uves_propertylist *self, const char *name)
04248 {
04249 
04250     const cxchar *const _id = "uves_propertylist_erase";
04251 
04252     uves_deque_iterator pos;
04253 
04254 
04255     if (self == NULL || name == NULL) {
04256         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
04257         return 0;
04258     }
04259 
04260     pos = _uves_propertylist_find(self, name);
04261     if (pos == uves_deque_end(self->properties)) {
04262         return 0;
04263     }
04264 //        fprintf(stderr, "%d\n", __LINE__);
04265 
04266     uves_deque_erase(self->properties, pos, (cx_free_func)cpl_property_delete);
04267 
04268     return 1;
04269 
04270 }
04271 
04307 int
04308 uves_propertylist_erase_regexp(uves_propertylist *self, const char *regexp,
04309                               int invert)
04310 {
04311 
04312     const cxchar *const _id = "uves_propertylist_erase_regexp";
04313 
04314     cxint status = 0;
04315     cxint count = 0;
04316 
04317     uves_deque_iterator first, last, pos;
04318 
04319     cpl_property    *p;
04320 
04321     uves_regexp filter;
04322 
04323 
04324     if (self == NULL || regexp == NULL) {
04325         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
04326         return 0;
04327     }
04328 
04329 
04330     status = regcomp(&filter.re, regexp, REG_EXTENDED | REG_NOSUB);
04331     if (status) {
04332         cpl_error_set(_id, CPL_ERROR_ILLEGAL_INPUT);
04333         return 0;
04334     }
04335 
04336     filter.invert = invert == 0 ? FALSE : TRUE;
04337 
04338     first = uves_deque_begin(self->properties);
04339     last  = uves_deque_end(self->properties);
04340 
04341     while (first < uves_deque_end(self->properties)) {
04342         pos = first;
04343 //        first = uves_deque_next(self->properties, first);
04344 
04345         p = uves_deque_get(self->properties, pos);
04346         if (_uves_propertylist_compare_regexp(p, &filter) == TRUE) {
04347 
04348 //            fprintf(stderr, "%d\n", __LINE__);
04349 
04350             uves_deque_erase(self->properties, pos,
04351                           (cx_free_func)cpl_property_delete);
04352             count++;
04353         }
04354         else
04355             first = uves_deque_next(self->properties, first);
04356     }
04357 
04358     regfree(&filter.re);
04359 
04360     return count;
04361 
04362 }
04363 
04364 
04389 void
04390 uves_propertylist_empty(uves_propertylist *self)
04391 {
04392 
04393     const cxchar *const _id = "uves_propertylist_empty";
04394 
04395     uves_deque_iterator first, last;
04396 
04397 
04398     if (self == NULL) {
04399         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
04400         return;
04401     }
04402 
04403     first = uves_deque_begin(self->properties);
04404     last = uves_deque_end(self->properties);
04405 
04406     while (first < uves_deque_end(self->properties)) {
04407         uves_deque_iterator pos = first;
04408         
04409 //        first = uves_deque_next(self->properties, first);
04410 //        fprintf(stderr, "%d  %d %d %d\n", __LINE__, first, last, pos);
04411         uves_deque_erase(self->properties, pos,
04412                       (cx_free_func)cpl_property_delete);
04413 
04414 //        first = uves_deque_next(self->properties, first);
04415     }
04416 
04417     return;
04418 
04419 }
04420 
04421 
04460 cpl_error_code
04461 uves_propertylist_update_char(uves_propertylist *self, const char *name,
04462                              char value)
04463 {
04464 
04465     const cxchar *const _id = "uves_propertylist_update_char";
04466 
04467     uves_deque_iterator pos;
04468 
04469 
04470     if (self == NULL || name == NULL) {
04471         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
04472         return CPL_ERROR_NULL_INPUT;
04473     }
04474 
04475     pos = _uves_propertylist_find(self, name);
04476 
04477     if (pos == uves_deque_end(self->properties)) {
04478 
04479         cpl_property *property = cpl_property_new(name, CPL_TYPE_CHAR);
04480 
04481 
04482         cx_assert(property != NULL);
04483 
04484         cpl_property_set_char(property, value);
04485         uves_deque_push_back(self->properties, property);
04486     }
04487     else {
04488 
04489         cpl_property *property = uves_deque_get(self->properties, pos);
04490 
04491 
04492         cx_assert(property != NULL);
04493 
04494         if (cpl_property_get_type(property) != CPL_TYPE_CHAR) {
04495             cpl_error_set(_id, CPL_ERROR_TYPE_MISMATCH);
04496             return CPL_ERROR_TYPE_MISMATCH;
04497         }
04498 
04499         cpl_property_set_char(property, value);
04500 
04501     }
04502 
04503     return CPL_ERROR_NONE;
04504 
04505 }
04506 
04507 
04546 cpl_error_code
04547 uves_propertylist_update_bool(uves_propertylist *self, const char *name,
04548                              int value)
04549 {
04550 
04551     const cxchar *const _id = "uves_propertylist_update_bool";
04552 
04553     uves_deque_iterator pos;
04554 
04555 
04556     if (self == NULL || name == NULL) {
04557         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
04558         return CPL_ERROR_NULL_INPUT;
04559     }
04560 
04561     pos = _uves_propertylist_find(self, name);
04562 
04563     if (pos == uves_deque_end(self->properties)) {
04564 
04565         cpl_property *property = cpl_property_new(name, CPL_TYPE_BOOL);
04566 
04567 
04568         cx_assert(property != NULL);
04569 
04570         cpl_property_set_bool(property, value);
04571         uves_deque_push_back(self->properties, property);
04572     }
04573     else {
04574 
04575         cpl_property *property = uves_deque_get(self->properties, pos);
04576 
04577 
04578         cx_assert(property != NULL);
04579 
04580         if (cpl_property_get_type(property) != CPL_TYPE_BOOL) {
04581             cpl_error_set(_id, CPL_ERROR_TYPE_MISMATCH);
04582             return CPL_ERROR_TYPE_MISMATCH;
04583         }
04584 
04585         cpl_property_set_bool(property, value);
04586 
04587     }
04588 
04589     return CPL_ERROR_NONE;
04590 
04591 }
04592 
04593 
04632 cpl_error_code
04633 uves_propertylist_update_int(uves_propertylist *self, const char *name,
04634                             int value)
04635 {
04636 
04637     const cxchar *const _id = "uves_propertylist_update_int";
04638 
04639     uves_deque_iterator pos;
04640 
04641 
04642     if (self == NULL || name == NULL) {
04643         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
04644         return CPL_ERROR_NULL_INPUT;
04645     }
04646 
04647     pos = _uves_propertylist_find(self, name);
04648 
04649     if (pos == uves_deque_end(self->properties)) {
04650 
04651         cpl_property *property = cpl_property_new(name, CPL_TYPE_INT);
04652 
04653 
04654         cx_assert(property != NULL);
04655 
04656         cpl_property_set_int(property, value);
04657         uves_deque_push_back(self->properties, property);
04658     }
04659     else {
04660 
04661         cpl_property *property = uves_deque_get(self->properties, pos);
04662 
04663 
04664         cx_assert(property != NULL);
04665 
04666         if (cpl_property_get_type(property) != CPL_TYPE_INT) {
04667             cpl_error_set(_id, CPL_ERROR_TYPE_MISMATCH);
04668             return CPL_ERROR_TYPE_MISMATCH;
04669         }
04670 
04671         cpl_property_set_int(property, value);
04672 
04673     }
04674 
04675     return CPL_ERROR_NONE;
04676 
04677 }
04678 
04679 
04718 cpl_error_code
04719 uves_propertylist_update_long(uves_propertylist *self, const char *name,
04720                              long value)
04721 {
04722 
04723     const cxchar *const _id = "uves_propertylist_update_long";
04724 
04725     uves_deque_iterator pos;
04726 
04727 
04728     if (self == NULL || name == NULL) {
04729         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
04730         return CPL_ERROR_NULL_INPUT;
04731     }
04732 
04733     pos = _uves_propertylist_find(self, name);
04734 
04735     if (pos == uves_deque_end(self->properties)) {
04736 
04737         cpl_property *property = cpl_property_new(name, CPL_TYPE_LONG);
04738 
04739 
04740         cx_assert(property != NULL);
04741 
04742         cpl_property_set_long(property, value);
04743         uves_deque_push_back(self->properties, property);
04744     }
04745     else {
04746 
04747         cpl_property *property = uves_deque_get(self->properties, pos);
04748 
04749 
04750         cx_assert(property != NULL);
04751 
04752         if (cpl_property_get_type(property) != CPL_TYPE_LONG) {
04753             cpl_error_set(_id, CPL_ERROR_TYPE_MISMATCH);
04754             return CPL_ERROR_TYPE_MISMATCH;
04755         }
04756 
04757         cpl_property_set_long(property, value);
04758 
04759     }
04760 
04761     return CPL_ERROR_NONE;
04762 
04763 }
04764 
04765 
04804 cpl_error_code
04805 uves_propertylist_update_float(uves_propertylist *self, const char *name,
04806                               float value)
04807 {
04808 
04809     const cxchar *const _id = "uves_propertylist_update_float";
04810 
04811     uves_deque_iterator pos;
04812 
04813 
04814     if (self == NULL || name == NULL) {
04815         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
04816         return CPL_ERROR_NULL_INPUT;
04817     }
04818 
04819     pos = _uves_propertylist_find(self, name);
04820 
04821     if (pos == uves_deque_end(self->properties)) {
04822 
04823         cpl_property *property = cpl_property_new(name, CPL_TYPE_FLOAT);
04824 
04825 
04826         cx_assert(property != NULL);
04827 
04828         cpl_property_set_float(property, value);
04829         uves_deque_push_back(self->properties, property);
04830     }
04831     else {
04832 
04833         cpl_property *property = uves_deque_get(self->properties, pos);
04834 
04835 
04836         cx_assert(property != NULL);
04837 
04838         if (cpl_property_get_type(property) != CPL_TYPE_FLOAT) {
04839             cpl_error_set(_id, CPL_ERROR_TYPE_MISMATCH);
04840             return CPL_ERROR_TYPE_MISMATCH;
04841         }
04842 
04843         cpl_property_set_float(property, value);
04844 
04845     }
04846 
04847     return CPL_ERROR_NONE;
04848 
04849 }
04850 
04851 
04890 cpl_error_code
04891 uves_propertylist_update_double(uves_propertylist *self, const char *name,
04892                                double value)
04893 {
04894 
04895     const cxchar *const _id = "uves_propertylist_update_double";
04896 
04897     uves_deque_iterator pos;
04898 
04899 
04900     if (self == NULL || name == NULL) {
04901         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
04902         return CPL_ERROR_NULL_INPUT;
04903     }
04904 
04905     pos = _uves_propertylist_find(self, name);
04906 
04907     if (pos == uves_deque_end(self->properties)) {
04908 
04909         cpl_property *property = cpl_property_new(name, CPL_TYPE_DOUBLE);
04910 
04911 
04912         cx_assert(property != NULL);
04913 
04914         cpl_property_set_double(property, value);
04915         uves_deque_push_back(self->properties, property);
04916     }
04917     else {
04918 
04919         cpl_property *property = uves_deque_get(self->properties, pos);
04920 
04921 
04922         cx_assert(property != NULL);
04923 
04924         if (cpl_property_get_type(property) != CPL_TYPE_DOUBLE) {
04925             cpl_error_set(_id, CPL_ERROR_TYPE_MISMATCH);
04926             return CPL_ERROR_TYPE_MISMATCH;
04927         }
04928 
04929         cpl_property_set_double(property, value);
04930 
04931     }
04932 
04933     return CPL_ERROR_NONE;
04934 
04935 }
04936 
04937 
04976 cpl_error_code
04977 uves_propertylist_update_string(uves_propertylist *self, const char *name,
04978                                const char *value)
04979 {
04980 
04981     const cxchar *const _id = "uves_propertylist_update_string";
04982 
04983     uves_deque_iterator pos;
04984 
04985 
04986     if (self == NULL || name == NULL) {
04987         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
04988         return CPL_ERROR_NULL_INPUT;
04989     }
04990 
04991     pos = _uves_propertylist_find(self, name);
04992 
04993     if (pos == uves_deque_end(self->properties)) {
04994 
04995         cpl_property *property = cpl_property_new(name, CPL_TYPE_STRING);
04996 
04997 
04998         cx_assert(property != NULL);
04999 
05000         cpl_property_set_string(property, value);
05001         uves_deque_push_back(self->properties, property);
05002     }
05003     else {
05004 
05005         cpl_property *property = uves_deque_get(self->properties, pos);
05006 
05007 
05008         cx_assert(property != NULL);
05009 
05010         if (cpl_property_get_type(property) != CPL_TYPE_STRING) {
05011             cpl_error_set(_id, CPL_ERROR_TYPE_MISMATCH);
05012             return CPL_ERROR_TYPE_MISMATCH;
05013         }
05014 
05015         cpl_property_set_string(property, value);
05016 
05017     }
05018 
05019     return CPL_ERROR_NONE;
05020 
05021 }
05022 
05023 
05071 cpl_error_code
05072 uves_propertylist_copy_property(uves_propertylist *self,
05073                                const uves_propertylist *other,
05074                                const char *name)
05075 {
05076 
05077     const cxchar *const _id = "uves_propertylist_copy_property";
05078 
05079     uves_deque_iterator spos;
05080     uves_deque_iterator tpos;
05081 
05082 
05083     if (self == NULL || other == NULL || name == NULL) {
05084         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
05085         return CPL_ERROR_NULL_INPUT;
05086     }
05087 
05088     spos = _uves_propertylist_find(other, name);
05089 
05090     if (spos == uves_deque_end(other->properties)) {
05091         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
05092         return CPL_ERROR_DATA_NOT_FOUND;
05093     }
05094 
05095     tpos = _uves_propertylist_find(self, name);
05096 
05097     if (tpos == uves_deque_end(self->properties)) {
05098 
05099         cpl_property *p = cpl_property_duplicate(uves_deque_get(other->properties,
05100                                                              spos));
05101         uves_deque_push_back(self->properties, p);
05102 
05103     }
05104     else {
05105 
05106         cpl_property *p = uves_deque_get(self->properties, tpos);
05107         cpl_property *_p = uves_deque_get(self->properties, spos);
05108 
05109 
05110         if (cpl_property_get_type(p) != cpl_property_get_type(_p)) {
05111             cpl_error_set(_id, CPL_ERROR_TYPE_MISMATCH);
05112             return CPL_ERROR_TYPE_MISMATCH;
05113         }
05114 
05115         switch (cpl_property_get_type(_p)) {
05116 
05117         case CPL_TYPE_CHAR:
05118             cpl_property_set_char(p, cpl_property_get_char(_p));
05119             break;
05120 
05121         case CPL_TYPE_BOOL:
05122             cpl_property_set_bool(p, cpl_property_get_bool(_p));
05123             break;
05124 
05125         case CPL_TYPE_INT:
05126             cpl_property_set_int(p, cpl_property_get_int(_p));
05127             break;
05128 
05129         case CPL_TYPE_LONG:
05130             cpl_property_set_long(p, cpl_property_get_long(_p));
05131             break;
05132 
05133         case CPL_TYPE_FLOAT:
05134             cpl_property_set_float(p, cpl_property_get_float(_p));
05135             break;
05136 
05137         case CPL_TYPE_DOUBLE:
05138             cpl_property_set_double(p, cpl_property_get_double(_p));
05139             break;
05140 
05141         case CPL_TYPE_STRING:
05142             cpl_property_set_string(p, cpl_property_get_string(_p));
05143             break;
05144 
05145         default:
05146             /* This point should never be reached */
05147             cx_error("%s: Unsupported type encountered!", CX_CODE_POS);
05148             break;
05149 
05150         }
05151 
05152         cpl_property_set_comment(p, cpl_property_get_comment(_p));
05153 
05154     }
05155 
05156     return CPL_ERROR_NONE;
05157 
05158 }
05159 
05160 
05220 cpl_error_code
05221 uves_propertylist_copy_property_regexp(uves_propertylist *self,
05222                                       const uves_propertylist *other,
05223                                       const char *regexp,
05224                                       int invert)
05225 {
05226 
05227     const cxchar *const _id = "uves_propertylist_copy_property_regexp";
05228 
05229     cxint status;
05230 
05231     cxsize i;
05232     cxsize count = 0;
05233 
05234     uves_deque_const_iterator first, last;
05235 
05236     typedef struct _property_pair_ {
05237         cpl_property *s;
05238         cpl_property *t;
05239     } property_pair;
05240 
05241     property_pair *pairs = NULL;
05242 
05243     uves_regexp filter;
05244 
05245 
05246     if (self == NULL || other == NULL || regexp == NULL) {
05247         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
05248         return CPL_ERROR_NULL_INPUT;
05249     }
05250 
05251     status = regcomp(&filter.re, regexp, REG_EXTENDED | REG_NOSUB);
05252     if (status) {
05253         cpl_error_set(_id, CPL_ERROR_ILLEGAL_INPUT);
05254         return CPL_ERROR_ILLEGAL_INPUT;
05255     }
05256 
05257     filter.invert = invert == 0 ? FALSE : TRUE;
05258 
05259 
05260     count = uves_deque_size(other->properties);
05261 
05262     if (count == 0) {
05263         regfree(&filter.re);
05264         return CPL_ERROR_NONE;
05265     }
05266 
05267     pairs = cx_malloc(count * sizeof(property_pair));
05268     cx_assert(pairs != NULL);
05269 
05270     count = 0;
05271 
05272 
05273     first = uves_deque_begin(other->properties);
05274     last  = uves_deque_end(other->properties);
05275 
05276     while (first != last) {
05277 
05278         cpl_property *p = uves_deque_get(other->properties, first);
05279 
05280 
05281         if (_uves_propertylist_compare_regexp(p, &filter) == TRUE) {
05282 
05283             const cxchar *name = cpl_property_get_name(p);
05284 
05285             uves_deque_const_iterator pos = _uves_propertylist_find(self, name);
05286 
05287             cpl_property *_p = NULL;
05288 
05289 
05290             if (pos != uves_deque_end(self->properties)) {
05291 
05292                 _p = uves_deque_get(self->properties, pos);
05293 
05294                 if (cpl_property_get_type(p) != cpl_property_get_type(_p)) {
05295 
05296                     regfree(&filter.re);
05297 
05298                     cx_free(pairs);
05299                     pairs = NULL;
05300 
05301                     cpl_error_set(_id, CPL_ERROR_TYPE_MISMATCH);
05302 
05303                     return CPL_ERROR_TYPE_MISMATCH;
05304 
05305                 }
05306 
05307             }
05308 
05309             pairs[count].s = p;
05310             pairs[count].t = _p;
05311             ++count;
05312 
05313         }
05314 
05315         first = uves_deque_next(other->properties, first);
05316 
05317     }
05318 
05319     regfree(&filter.re);
05320 
05321 
05322     for (i = 0; i < count; i++) {
05323 
05324         if (pairs[i].t == NULL) {
05325 
05326             cpl_property *p = cpl_property_duplicate(pairs[i].s);
05327             uves_deque_push_back(self->properties, p);
05328 
05329         }
05330         else {
05331 
05332             switch (cpl_property_get_type(pairs[i].s)) {
05333 
05334             case CPL_TYPE_CHAR:
05335                 cpl_property_set_char(pairs[i].t,
05336                                       cpl_property_get_char(pairs[i].s));
05337                 break;
05338 
05339             case CPL_TYPE_BOOL:
05340                 cpl_property_set_bool(pairs[i].t,
05341                                       cpl_property_get_bool(pairs[i].s));
05342                 break;
05343 
05344             case CPL_TYPE_INT:
05345                 cpl_property_set_int(pairs[i].t,
05346                                      cpl_property_get_int(pairs[i].s));
05347                 break;
05348 
05349             case CPL_TYPE_LONG:
05350                 cpl_property_set_long(pairs[i].t,
05351                                       cpl_property_get_long(pairs[i].s));
05352                 break;
05353 
05354             case CPL_TYPE_FLOAT:
05355                 cpl_property_set_float(pairs[i].t,
05356                                        cpl_property_get_float(pairs[i].s));
05357                 break;
05358 
05359             case CPL_TYPE_DOUBLE:
05360                 cpl_property_set_double(pairs[i].t,
05361                                         cpl_property_get_double(pairs[i].s));
05362                 break;
05363 
05364             case CPL_TYPE_STRING:
05365                 cpl_property_set_string(pairs[i].t,
05366                                         cpl_property_get_string(pairs[i].s));
05367                 break;
05368 
05369             default:
05370                 /* This point should never be reached */
05371                 cx_free(pairs);
05372                 cx_error("%s: Unsupported type encountered!", CX_CODE_POS);
05373                 break;
05374 
05375             }
05376 
05377         }
05378 
05379     }
05380 
05381     cx_free(pairs);
05382 
05383     return CPL_ERROR_NONE;
05384 
05385 }
05386 
05387 
05448 uves_propertylist *
05449 uves_propertylist_load(const char *name, int position)
05450 {
05451 
05452     const cxchar *const _id = "uves_propertylist_load";
05453 
05454     register cxint n, status;
05455 
05456     qfits_header *header;
05457 
05458     uves_propertylist *self;
05459 
05460 
05461     if (name == NULL) {
05462         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
05463         return NULL;
05464     }
05465 
05466     if (position < 0) {
05467         cpl_error_set(_id, CPL_ERROR_ILLEGAL_INPUT);
05468         return NULL;
05469     }
05470 
05471     status = qfits_is_fits((cxchar *)name);
05472     if (status == -1) {
05473         cpl_error_set(_id, CPL_ERROR_FILE_IO);
05474         return NULL;
05475     }
05476     else {
05477         if (status == 0) {
05478             cpl_error_set(_id, CPL_ERROR_BAD_FILE_FORMAT);
05479             return NULL;
05480         }
05481     }
05482 
05483     /*
05484      * qfits_query_n_ext() only counts true extensions, i.e. it does not
05485      * count the primary FITS unit. But since we passed the qfits_is_fits()
05486      * check we can safely assume that there is one.
05487      */
05488 
05489     n = qfits_query_n_ext((cxchar *)name);
05490 
05491     if (n < position) {
05492         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
05493         return NULL;
05494     }
05495 
05496 
05497     header = qfits_header_readext((cxchar *)name, position);
05498 
05499     if (header == NULL) {
05500         cpl_error_set(_id, CPL_ERROR_ILLEGAL_INPUT);
05501         return NULL;
05502     }
05503 
05504     self = uves_propertylist_new();
05505     cx_assert(self);
05506 
05507     status = _uves_propertylist_from_fits(self, header, NULL, NULL);
05508 
05509     if (status) {
05510         uves_propertylist_delete(self);
05511         qfits_header_destroy(header);
05512 
05513         cpl_error_set(_id, CPL_ERROR_ILLEGAL_INPUT);
05514         return NULL;
05515     }
05516 
05517     qfits_header_destroy(header);
05518 
05519     return self;
05520 
05521 }
05522 
05523 
05595 uves_propertylist *
05596 uves_propertylist_load_regexp(const char *name, int position,
05597                              const char *regexp, int invert)
05598 {
05599 
05600     const cxchar *const _id = "uves_propertylist_load_regexp";
05601 
05602     register cxint n, status;
05603 
05604     qfits_header *header;
05605 
05606     uves_propertylist *self;
05607 
05608     uves_regexp filter;
05609 
05610 
05611     if (name == NULL || regexp == NULL) {
05612         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
05613         return NULL;
05614     }
05615 
05616     if (position < 0) {
05617         cpl_error_set(_id, CPL_ERROR_ILLEGAL_INPUT);
05618         return NULL;
05619     }
05620 
05621     status = regcomp(&filter.re, regexp, REG_EXTENDED | REG_NOSUB);
05622     if (status) {
05623         cpl_error_set(_id, CPL_ERROR_ILLEGAL_INPUT);
05624         return NULL;
05625     }
05626 
05627     filter.invert = invert == 0 ? FALSE : TRUE;
05628 
05629 
05630     status = qfits_is_fits((cxchar *)name);
05631     if (status == -1) {
05632         cpl_error_set(_id, CPL_ERROR_FILE_IO);
05633         return NULL;
05634     }
05635     else {
05636         if (status == 0) {
05637             cpl_error_set(_id, CPL_ERROR_BAD_FILE_FORMAT);
05638             return NULL;
05639         }
05640     }
05641 
05642     /*
05643      * qfits_query_n_ext() only counts true extensions, i.e. it does not
05644      * count the primary FITS unit. But since we passed the qfits_is_fits()
05645      * check we can safely assume that there is one.
05646      */
05647 
05648     n = qfits_query_n_ext((cxchar *)name);
05649 
05650     if (n < position) {
05651         cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
05652         return NULL;
05653     }
05654 
05655 
05656     header = qfits_header_readext((cxchar *)name, position);
05657 
05658     if (header == NULL) {
05659         cpl_error_set(_id, CPL_ERROR_ILLEGAL_INPUT);
05660         return NULL;
05661     }
05662 
05663     self = uves_propertylist_new();
05664     cx_assert(self);
05665 
05666     status = _uves_propertylist_from_fits(self, header,
05667                                          _uves_propertylist_filter_regexp,
05668                                          &filter);
05669 
05670     if (status) {
05671         uves_propertylist_delete(self);
05672         qfits_header_destroy(header);
05673 
05674         regfree(&filter.re);
05675 
05676         cpl_error_set(_id, CPL_ERROR_ILLEGAL_INPUT);
05677         return NULL;
05678     }
05679 
05680     qfits_header_destroy(header);
05681     regfree(&filter.re);
05682 
05683     return self;
05684 
05685 }
05686 
05687 
05705 qfits_header *
05706 uves_propertylist_to_fits(const uves_propertylist *self)
05707 {
05708     const cxchar *const _id = "uves_propertylist_to_fits";
05709 
05710     qfits_header *header;
05711 
05712 
05713     cx_assert(self != NULL);
05714 
05715     header = qfits_header_new();
05716 
05717     if (!uves_deque_empty(self->properties)) {
05718         uves_deque_iterator i = uves_deque_begin(self->properties);
05719         uves_deque_iterator last = uves_deque_end(self->properties);
05720 
05721         while (i != last) {
05722             cxchar tmp[FITS_LINESZ + 1];
05723             cxchar key[FITS_LINESZ + 1];
05724             cxchar value[FITS_LINESZ + 1];
05725             cxfloat fval;
05726             cxdouble dval;
05727             cpl_property *property;
05728 
05729             property = uves_deque_get(self->properties, i);
05730 
05731             /*
05732              * Convert each property into a FITS keyword an error is
05733              * triggered for unsupported types. Also, since the FITS
05734              * format does not support array keywords, apart from strings,
05735              * i.e. character arrays, an error is triggered in this case too.
05736              *
05737              * A possible solution for the array case would be to create
05738              * a sequence of indexed keywords. But this must be checked.
05739              */
05740 
05741             strncpy(tmp, cpl_property_get_name(property), FITS_LINESZ);
05742             tmp[FITS_LINESZ] = '\0';
05743 
05744             if (!cx_strupper(tmp)) {
05745 //                cpl_error_set_code(CPL_ERROR_INCOMPATIBLE_INPUT);
05746 //                cpl_error_set_where(_id);
05747                 cpl_error_set(_id, CPL_ERROR_INCOMPATIBLE_INPUT);
05748 
05749                 qfits_header_destroy(header);
05750 
05751                 return NULL;
05752             }
05753 
05754             key[0] = '\0';
05755 
05756             if (strlen(tmp) > FITS_STDKEY_MAX &&
05757                 strncmp(tmp, "HIERARCH ", 9)) {
05758                 strncat(key, "HIERARCH ", 9);
05759             }
05760             strncat(key, tmp, FITS_LINESZ - strlen(key));
05761 
05762             switch (cpl_property_get_type(property)) {
05763                 case CPL_TYPE_CHAR:
05764                     cx_snprintf(value, FITS_LINESZ, "'%c'",
05765                                 cpl_property_get_char(property));
05766                     break;
05767 
05768                 case CPL_TYPE_BOOL:
05769                 {
05770                     cxint pvalue = cpl_property_get_bool(property);
05771 
05772                     cx_snprintf(value, FITS_LINESZ, "%c",
05773                                 pvalue == 1 ? 'T' : 'F');
05774                     break;
05775                 }
05776 
05777                 case CPL_TYPE_INT:
05778                     cx_snprintf(value, FITS_LINESZ, "%d",
05779                                 cpl_property_get_int(property));
05780                     break;
05781 
05782                 case CPL_TYPE_LONG:
05783                     cx_snprintf(value, FITS_LINESZ, "%ld",
05784                                 cpl_property_get_long(property));
05785                     break;
05786 
05787                 case CPL_TYPE_FLOAT:
05788                     fval = cpl_property_get_float(property);
05789                     cx_snprintf(value, FITS_LINESZ, "%.7G", fval);
05790 
05791                     if (!strchr(value, '.')) {
05792                         if (strchr(value, 'E'))
05793                             cx_snprintf(value, FITS_LINESZ, "%.1E", fval);
05794                         else
05795                             strcat(value, ".");
05796                     }
05797                     break;
05798 
05799                 case CPL_TYPE_DOUBLE:
05800                     dval = cpl_property_get_double(property);
05801                     cx_snprintf(value, FITS_LINESZ, "%.15G", dval);
05802 
05803                     if (!strchr(value, '.')) {
05804                         if (strchr(value, 'E'))
05805                             cx_snprintf(value, FITS_LINESZ, "%.1E", dval);
05806                         else
05807                             strcat(value, ".");
05808                     }
05809                     break;
05810 
05811                 case CPL_TYPE_STRING:
05812                     if (!strcmp(key, "COMMENT") || !strcmp(key, "HISTORY")) {
05813                         cx_snprintf(value, FITS_LINESZ, "%s",
05814                                     cpl_property_get_string(property));
05815                     }
05816                     else {
05817 
05818                         cxint n = 0;
05819 
05820                         n = cx_snprintf(value, FITS_SVALUE_MAX + 1, "'%s'",
05821                                         cpl_property_get_string(property));
05822 
05823                         if (n > FITS_SVALUE_MAX) {
05824                             value[FITS_SVALUE_MAX - 1] = '\'';
05825                             value[FITS_SVALUE_MAX] = '\0';
05826                         }
05827 
05828                     }
05829                     break;
05830 
05831                 default:
05832 //                    cpl_error_set_code(CPL_ERROR_INCOMPATIBLE_INPUT);
05833 //                    cpl_error_set_where(_id);
05834                     cpl_error_set(_id, CPL_ERROR_INCOMPATIBLE_INPUT);
05835 
05836                     qfits_header_destroy(header);
05837 
05838                     return NULL;
05839                     break;
05840             }
05841 
05842             qfits_header_append(header, key, value,
05843                                 (cxchar *)cpl_property_get_comment(property),
05844                                 NULL);
05845 
05846             i = uves_deque_next(self->properties, i);
05847         }
05848     }
05849 
05850 
05851     /*
05852      * Add the END keyword as last entry.
05853      */
05854 
05855     /* FIXME: Maybe better to check if end is already present */
05856 
05857     qfits_header_append(header, "END", NULL, NULL, NULL);
05858 
05859 
05860     /*
05861      * Sort the header according to ESO's DICB standard
05862      */
05863 
05864     if (qfits_header_sort(&header) != 0) {
05865 //        cpl_error_set_code(CPL_ERROR_INCOMPATIBLE_INPUT);
05866 //        cpl_error_set_where(_id);
05867         cpl_error_set(_id, CPL_ERROR_INCOMPATIBLE_INPUT);
05868 
05869         qfits_header_destroy(header);
05870 
05871         return NULL;
05872     }
05873 
05874     return header;
05875 
05876 }
05877 
05901 uves_propertylist *
05902 uves_propertylist_from_fits(const qfits_header *header)
05903 {
05904 
05905     const cxchar *const _id = "uves_propertylist_from_fits";
05906 
05907     register cxint status;
05908 
05909     uves_propertylist *self;
05910 
05911 
05912     if (!header) {
05913         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
05914         return NULL;
05915     }
05916 
05917     self = uves_propertylist_new();
05918     cx_assert(self != NULL);
05919 
05920     status = _uves_propertylist_from_fits(self, header, NULL, NULL);
05921 
05922     if (status) {
05923         uves_propertylist_delete(self);
05924 
05925 //        cpl_error_set_where(_id);
05926 
05927         switch (status) {
05928         case -2:
05929         case -1:
05930 //            cpl_error_set_code(CPL_ERROR_ILLEGAL_INPUT);
05931             cpl_error_set(_id, CPL_ERROR_ILLEGAL_INPUT);
05932             break;
05933 
05934         case 1:
05935 //            cpl_error_set_code(CPL_ERROR_INVALID_TYPE);
05936             cpl_error_set(_id, CPL_ERROR_INVALID_TYPE);
05937             break;
05938 
05939         default:
05940             /* This should never be reached */
05941             break;
05942         }
05943 
05944         return NULL;
05945     }
05946 
05947     return self;
05948 
05949 }
05950 
05951 #endif /* USE_CPL */
05952 

Generated on 9 Mar 2012 for UVES Pipeline Reference Manual by  doxygen 1.6.1