00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifdef HAVE_CONFIG_H
00030 #include <config.h>
00031 #endif
00032
00033
00034
00035
00036
00037
00038 #include <stdio.h>
00039 #include <string.h>
00040 #include <sys/types.h>
00041 #include <regex.h>
00042 #include <math.h>
00043 #include <assert.h>
00044
00045 #include <cpl.h>
00046
00047
00048 #include "irplib_utils.h"
00049 #include "irplib_error.h"
00050 #include "irplib_framelist.h"
00051
00052
00053
00054
00055
00056
00057
00058 struct _irplib_framelist_ {
00059 int size;
00060 cpl_frame ** frame;
00061 cpl_propertylist ** propertylist;
00062
00063 };
00064
00065
00066
00067
00068
00069
00070 static void irplib_framelist_set_size(irplib_framelist *)
00071 #if defined __GNUC__ && __GNUC__ >= 4
00072 __attribute__((nonnull))
00073 #endif
00074 ;
00075
00076 static cpl_boolean irplib_property_equal(const cpl_propertylist *,
00077 const cpl_propertylist *,
00078 const char *, cpl_type, double,
00079 char **, char **)
00080 #if defined __GNUC__ && __GNUC__ >= 4
00081 __attribute__((nonnull))
00082 #endif
00083 ;
00084
00085 static const char * irplib_type_as_string(cpl_type);
00086
00087
00166
00167
00170
00171
00172
00173
00174
00182
00183 irplib_framelist * irplib_framelist_new(void)
00184 {
00185
00186 return (irplib_framelist *) cpl_calloc(1, sizeof(irplib_framelist));
00187
00188 }
00189
00190
00195
00196 void irplib_framelist_delete(irplib_framelist * self)
00197 {
00198
00199 irplib_framelist_empty(self);
00200 cpl_free(self);
00201 }
00202
00203
00204
00213
00214 irplib_framelist * irplib_framelist_cast(const cpl_frameset * frameset)
00215 {
00216
00217 irplib_framelist * self;
00218 const cpl_frame * frame;
00219 int i;
00220
00221
00222 cpl_ensure(frameset != NULL, CPL_ERROR_NULL_INPUT, NULL);
00223
00224
00225 self = irplib_framelist_new();
00226
00227 for (i = 0, frame = cpl_frameset_get_first(frameset);
00228 frame != NULL;
00229 i++, frame = cpl_frameset_get_next(frameset)) {
00230
00231 cpl_frame * copy = cpl_frame_duplicate(frame);
00232
00233 const cpl_error_code error = irplib_framelist_set(self, copy, i);
00234
00235 assert(error == CPL_ERROR_NONE);
00236
00237 }
00238
00239 assert(self->size == cpl_frameset_get_size(frameset));
00240
00241 return self;
00242
00243 }
00244
00245
00246
00255
00256 cpl_frameset * irplib_frameset_cast(const irplib_framelist * self)
00257 {
00258
00259 cpl_frameset * new;
00260 int i;
00261
00262 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
00263
00264
00265 new = cpl_frameset_new();
00266
00267 for (i = 0; i < self->size; i++) {
00268 cpl_frame * frame = cpl_frame_duplicate(self->frame[i]);
00269 const cpl_error_code error = cpl_frameset_insert(new, frame);
00270
00271 assert(error == CPL_ERROR_NONE);
00272
00273 }
00274
00275 assert(self->size == cpl_frameset_get_size(new));
00276
00277 return new;
00278
00279 }
00280
00281
00282
00294
00295 irplib_framelist * irplib_framelist_extract(const irplib_framelist * self,
00296 const char * tag)
00297 {
00298
00299 irplib_framelist * new;
00300 int i, newsize;
00301
00302
00303 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
00304 cpl_ensure(tag != NULL, CPL_ERROR_NULL_INPUT, NULL);
00305
00306 new = irplib_framelist_new();
00307 newsize = 0;
00308
00309 for (i = 0; i < self->size; i++) {
00310 const cpl_frame * frame = self->frame[i];
00311 const char * ftag = cpl_frame_get_tag(frame);
00312 cpl_frame * copy;
00313 cpl_error_code error;
00314
00315 if (ftag == NULL) {
00316
00317 irplib_framelist_delete(new);
00318 cpl_ensure(0, CPL_ERROR_ILLEGAL_INPUT, NULL);
00319 }
00320
00321 if (strcmp(tag, ftag)) continue;
00322
00323 copy = cpl_frame_duplicate(frame);
00324
00325 error = irplib_framelist_set(new, copy, newsize);
00326 assert(error == CPL_ERROR_NONE);
00327
00328 if (self->propertylist[i] != NULL) new->propertylist[newsize]
00329 = cpl_propertylist_duplicate(self->propertylist[i]);
00330
00331 newsize++;
00332 }
00333
00334 assert( newsize == new->size );
00335
00336 if (newsize == 0) {
00337 irplib_error_push(CPL_ERROR_DATA_NOT_FOUND,
00338 ("The list of %d frame(s) has no frames with "
00339 "tag: %s", self->size, tag));
00340 irplib_framelist_delete(new);
00341 new = NULL;
00342 }
00343
00344 return new;
00345
00346 }
00347
00348
00358
00359 irplib_framelist * irplib_framelist_extract_regexp(const irplib_framelist* self,
00360 const char * regexp,
00361 cpl_boolean invert)
00362 {
00363
00364 irplib_framelist * new;
00365 int error;
00366 int i, newsize;
00367 const int xor = invert == CPL_FALSE ? 0 : 1;
00368 regex_t re;
00369
00370
00371 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
00372 cpl_ensure(regexp != NULL, CPL_ERROR_NULL_INPUT, NULL);
00373
00374 error = regcomp(&re, regexp, REG_EXTENDED | REG_NOSUB);
00375 cpl_ensure(!error, CPL_ERROR_ILLEGAL_INPUT, NULL);
00376
00377 new = irplib_framelist_new();
00378 newsize = 0;
00379
00380 for (i = 0; i < self->size; i++) {
00381 const cpl_frame * frame = self->frame[i];
00382 const char * tag = cpl_frame_get_tag(frame);
00383 cpl_frame * copy;
00384
00385 if (tag == NULL) {
00386
00387 irplib_framelist_delete(new);
00388 regfree(&re);
00389 cpl_ensure(0, CPL_ERROR_ILLEGAL_INPUT, NULL);
00390 }
00391
00392 if ((regexec(&re, tag, (size_t)0, NULL, 0) == REG_NOMATCH ? 1 : 0)
00393 ^ xor) continue;
00394
00395 copy = cpl_frame_duplicate(frame);
00396
00397 error = (int)irplib_framelist_set(new, copy, newsize);
00398 assert(error == CPL_ERROR_NONE);
00399
00400 if (self->propertylist[i] != NULL) new->propertylist[newsize]
00401 = cpl_propertylist_duplicate(self->propertylist[i]);
00402
00403 newsize++;
00404
00405 }
00406
00407 regfree(&re);
00408
00409 assert( newsize == new->size );
00410
00411 if (newsize == 0) {
00412 irplib_error_push(CPL_ERROR_DATA_NOT_FOUND,
00413 ("The list of %d frame(s) has no frames that "
00414 "match: %s", self->size, regexp));
00415 irplib_framelist_delete(new);
00416 new = NULL;
00417 }
00418
00419 return new;
00420 }
00421
00422
00423
00430
00431 int irplib_framelist_get_size(const irplib_framelist * self)
00432 {
00433
00434 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, -1);
00435
00436 return self->size;
00437
00438 }
00439
00440
00448
00449 cpl_frame * irplib_framelist_get(irplib_framelist * self, int pos)
00450 {
00451 return (cpl_frame *)irplib_framelist_get_const(self, pos);
00452
00453 }
00454
00455
00456
00464
00465 const cpl_frame * irplib_framelist_get_const(const irplib_framelist * self,
00466 int pos)
00467 {
00468
00469 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
00470 cpl_ensure(pos >= 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
00471 cpl_ensure(pos <= self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
00472
00473 return self->frame[pos];
00474
00475 }
00476
00477
00478
00487
00488 cpl_error_code irplib_framelist_set_propertylist(irplib_framelist * self,
00489 int pos,
00490 const cpl_propertylist * list)
00491 {
00492
00493 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00494 cpl_ensure_code(list != NULL, CPL_ERROR_NULL_INPUT);
00495 cpl_ensure_code(pos >= 0, CPL_ERROR_ILLEGAL_INPUT);
00496 cpl_ensure_code(pos <= self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00497
00498 cpl_propertylist_delete(self->propertylist[pos]);
00499
00500 self->propertylist[pos] = cpl_propertylist_duplicate(list);
00501
00502 cpl_ensure_code(self->propertylist[pos] != NULL, cpl_error_get_code());
00503
00504 return CPL_ERROR_NONE;
00505
00506 }
00507
00508
00509
00520
00521 cpl_propertylist * irplib_framelist_get_propertylist(irplib_framelist * self,
00522 int pos)
00523 {
00524
00525 return (cpl_propertylist *)irplib_framelist_get_propertylist_const(self,
00526 pos);
00527
00528 }
00529
00530
00531
00542
00543 const cpl_propertylist * irplib_framelist_get_propertylist_const(
00544 const irplib_framelist * self,
00545 int pos)
00546 {
00547 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
00548 cpl_ensure(pos >= 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
00549 cpl_ensure(pos <= self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
00550
00551 cpl_ensure(self->propertylist[pos] != NULL,
00552 CPL_ERROR_DATA_NOT_FOUND, NULL);
00553
00554 return self->propertylist[pos];
00555
00556 }
00557
00558
00559
00573
00574 cpl_error_code irplib_framelist_load_propertylist(irplib_framelist * self,
00575 int pos, int ind,
00576 const char * regexp,
00577 cpl_boolean invert)
00578 {
00579
00580 const char * filename;
00581
00582
00583 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00584 cpl_ensure_code(regexp != NULL, CPL_ERROR_NULL_INPUT);
00585 cpl_ensure_code(pos >= 0, CPL_ERROR_ILLEGAL_INPUT);
00586 cpl_ensure_code(pos <= self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00587
00588 filename = cpl_frame_get_filename(self->frame[pos]);
00589
00590 cpl_ensure_code(filename != NULL, cpl_error_get_code());
00591
00592 cpl_propertylist_delete(self->propertylist[pos]);
00593
00594 self->propertylist[pos] = cpl_propertylist_load_regexp(filename, ind,
00595 regexp,
00596 invert ? 1 : 0);
00597
00598 if (self->propertylist[pos] == NULL) {
00599 irplib_error_push(cpl_error_get_code(),
00600 ("Could not load FITS header from '%s' using regexp "
00601 "'%s'", filename, regexp));
00602 return cpl_error_get_code();
00603 }
00604
00605 return CPL_ERROR_NONE;
00606
00607 }
00608
00609
00610
00624
00625 cpl_error_code irplib_framelist_load_propertylist_all(irplib_framelist * self,
00626 int ind,
00627 const char * regexp,
00628 cpl_boolean invert)
00629 {
00630
00631 int nprops = 0;
00632 int nfiles = 0;
00633 int i;
00634
00635 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00636 cpl_ensure_code(regexp != NULL, CPL_ERROR_NULL_INPUT);
00637
00638 for (i=0; i < self->size; i++) {
00639 if (self->propertylist[i] == NULL)
00640 cpl_ensure_code(!irplib_framelist_load_propertylist(self, i,
00641 ind,
00642 regexp,
00643 invert),
00644 cpl_error_get_code());
00645
00646
00647 nprops += cpl_propertylist_get_size(self->propertylist[i]);
00648 nfiles++;
00649 }
00650
00651 cpl_msg_info(cpl_func, "List of %d frames has %d properties", nfiles,
00652 nprops);
00653
00654 return CPL_ERROR_NONE;
00655
00656 }
00657
00658
00659
00660
00668
00669 cpl_error_code irplib_framelist_set_tag_all(irplib_framelist * self,
00670 const char * tag)
00671 {
00672
00673 int i;
00674
00675 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00676 cpl_ensure_code(tag != NULL, CPL_ERROR_NULL_INPUT);
00677
00678 for (i=0; i < self->size; i++)
00679 cpl_ensure_code(!cpl_frame_set_tag(self->frame[i], tag),
00680 cpl_error_get_code());
00681
00682 return CPL_ERROR_NONE;
00683 }
00684
00685
00686
00700
00701 cpl_error_code irplib_framelist_set(irplib_framelist * self, cpl_frame * frame,
00702 int pos)
00703 {
00704
00705 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00706 cpl_ensure_code(frame != NULL, CPL_ERROR_NULL_INPUT);
00707 cpl_ensure_code(pos >= 0, CPL_ERROR_ILLEGAL_INPUT);
00708
00709 if (pos == self->size) {
00710
00711 self->size++;
00712
00713 irplib_framelist_set_size(self);
00714
00715 } else {
00716
00717 cpl_ensure_code(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00718
00719 cpl_frame_delete(self->frame[pos]);
00720 cpl_propertylist_delete(self->propertylist[pos]);
00721 }
00722
00723 self->frame[pos] = frame;
00724 self->propertylist[pos] = NULL;
00725
00726 return CPL_ERROR_NONE;
00727
00728 }
00729
00730
00739
00740 cpl_error_code irplib_framelist_erase(irplib_framelist * self, int pos)
00741 {
00742
00743 int i;
00744
00745 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00746 cpl_ensure_code(pos >= 0, CPL_ERROR_ILLEGAL_INPUT);
00747 cpl_ensure_code(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00748
00749
00750
00751 cpl_frame_delete(self->frame[pos]);
00752 cpl_propertylist_delete(self->propertylist[pos]);
00753
00754
00755 for (i = pos+1; i < self->size; i++) {
00756
00757 self->frame[i-1] = self->frame[i];
00758
00759 self->propertylist[i-1] = self->propertylist[i];
00760
00761 }
00762
00763 self->size--;
00764
00765 irplib_framelist_set_size(self);
00766
00767 return CPL_ERROR_NONE;
00768
00769 }
00770
00771
00772
00773
00789
00790 cpl_frame * irplib_framelist_unset(irplib_framelist * self, int pos,
00791 cpl_propertylist ** plist)
00792
00793 {
00794 cpl_frame * frame;
00795 int i;
00796
00797
00798 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
00799 cpl_ensure(pos >= 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
00800 cpl_ensure(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
00801
00802
00803 frame = self->frame[pos];
00804
00805 if (plist != NULL)
00806 *plist = self->propertylist[pos];
00807 else
00808 cpl_propertylist_delete(self->propertylist[pos]);
00809
00810
00811
00812 for (i = pos+1; i < self->size; i++) {
00813
00814 self->frame[i-1] = self->frame[i];
00815
00816 self->propertylist[i-1] = self->propertylist[i];
00817
00818 }
00819
00820 self->size--;
00821
00822 irplib_framelist_set_size(self);
00823
00824 return frame;
00825
00826 }
00827
00828
00835
00836 void irplib_framelist_empty(irplib_framelist * self)
00837 {
00838
00839 if (self != NULL) {
00840
00841
00842 while (self->size > 0) {
00843 self->size--;
00844 cpl_frame_delete(self->frame[self->size]);
00845 cpl_propertylist_delete(self->propertylist[self->size]);
00846
00847 }
00848
00849
00850 irplib_framelist_set_size(self);
00851
00852 }
00853 }
00854
00855
00856
00857
00895
00896 cpl_error_code irplib_framelist_contains(const irplib_framelist * self,
00897 const char * key, cpl_type type,
00898 cpl_boolean is_equal, double fp_tol)
00899 {
00900
00901 char * value_0;
00902 char * value_i;
00903 cpl_type type_0 = CPL_TYPE_INVALID;
00904 int i;
00905
00906
00907 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00908 cpl_ensure_code(key != NULL, CPL_ERROR_NULL_INPUT);
00909 cpl_ensure_code(fp_tol >= 0.0, CPL_ERROR_ILLEGAL_INPUT);
00910
00911 for (i=0; i < self->size; i++) {
00912 cpl_type type_i;
00913
00914
00915 if (self->propertylist[i] == NULL) continue;
00916
00917 type_i = cpl_propertylist_get_type(self->propertylist[i], key);
00918
00919 if (type_i == CPL_TYPE_INVALID) {
00920 if (type == CPL_TYPE_INVALID)
00921 irplib_error_push(cpl_error_get_code(),
00922 ("FITS key '%s' is missing from file %s", key,
00923 cpl_frame_get_filename(self->frame[i])));
00924 else
00925 irplib_error_push(cpl_error_get_code(),
00926 ("FITS key '%s' [%s] is missing from "
00927 "file %s", key, irplib_type_as_string(type),
00928 cpl_frame_get_filename(self->frame[i])));
00929 return cpl_error_get_code();
00930 }
00931
00932 if (type != CPL_TYPE_INVALID && type_i != type) {
00933 irplib_error_push(CPL_ERROR_INVALID_TYPE,
00934 ("FITS key '%s' has type %s instead of %s in "
00935 "file %s", key, irplib_type_as_string(type_i),
00936 irplib_type_as_string(type),
00937 cpl_frame_get_filename(self->frame[i])));
00938 return cpl_error_get_code();
00939 }
00940
00941 if (!is_equal) continue;
00942
00943 if (type_0 == CPL_TYPE_INVALID) {
00944 type_0 = type_i;
00945 continue;
00946 }
00947
00948 if (type_i != type_0) {
00949 assert( type == CPL_TYPE_INVALID );
00950 irplib_error_push(CPL_ERROR_TYPE_MISMATCH,
00951 ("FITS key '%s' has different types "
00952 "(%s <=> %s) in files %s and %s", key,
00953 irplib_type_as_string(type_0),
00954 irplib_type_as_string(type_i),
00955 cpl_frame_get_filename(self->frame[0]),
00956 cpl_frame_get_filename(self->frame[i])));
00957 return cpl_error_get_code();
00958 }
00959
00960 if (irplib_property_equal(self->propertylist[0], self->propertylist[i],
00961 key, type_0, fp_tol, &value_0, &value_i))
00962 continue;
00963
00964 if ((type_0 == CPL_TYPE_FLOAT || type_0 == CPL_TYPE_DOUBLE)
00965 && fp_tol > 0.0) {
00966 irplib_error_push(CPL_ERROR_INCOMPATIBLE_INPUT,
00967 ("FITS key '%s' [%s] has values that differ by "
00968 "more than %g (%s <=> %s) in files %s and %s",
00969 key, irplib_type_as_string(type_0), fp_tol,
00970 value_0, value_i,
00971 cpl_frame_get_filename(self->frame[0]),
00972 cpl_frame_get_filename(self->frame[i])));
00973 } else {
00974 irplib_error_push(CPL_ERROR_INCOMPATIBLE_INPUT,
00975 ("FITS key '%s' [%s] has different "
00976 "values (%s <=> %s) in files %s and %s", key,
00977 irplib_type_as_string(type_0),
00978 value_0, value_i,
00979 cpl_frame_get_filename(self->frame[0]),
00980 cpl_frame_get_filename(self->frame[i])));
00981 }
00982 cpl_free(value_0);
00983 cpl_free(value_i);
00984
00985 return cpl_error_get_code();
00986 }
00987
00988 return CPL_ERROR_NONE;
00989
00990 }
00991
00992
00993
01006
01007 cpl_imagelist * irplib_imagelist_load_framelist(const irplib_framelist * self,
01008 cpl_type pixeltype,
01009 int planenum,
01010 int extnum)
01011 {
01012
01013 cpl_imagelist * list = NULL;
01014 cpl_image * image = NULL;
01015 int i;
01016
01017
01018 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
01019 cpl_ensure(extnum >= 0, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
01020 cpl_ensure(planenum >= 0, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
01021
01022 list = cpl_imagelist_new();
01023
01024 for (i=0; i < self->size; i++, image = NULL) {
01025 const char * filename = cpl_frame_get_filename(self->frame[i]);
01026 cpl_error_code error;
01027
01028 if (filename == NULL) break;
01029
01030 image = cpl_image_load(filename, pixeltype, planenum, extnum);
01031 if (image == NULL) {
01032 irplib_error_push(cpl_error_get_code(),
01033 ("Could not load FITS-image from plane %d "
01034 "in extension %d in file %s", planenum, extnum,
01035 filename));
01036 break;
01037 }
01038
01039 error = cpl_imagelist_set(list, image, i);
01040 assert(error == CPL_ERROR_NONE);
01041 }
01042
01043 cpl_image_delete(image);
01044
01045 if (cpl_imagelist_get_size(list) != self->size) {
01046 cpl_imagelist_delete(list);
01047 list = NULL;
01048 assert(cpl_error_get_code() != CPL_ERROR_NONE);
01049 }
01050
01051 return list;
01052
01053 }
01054
01055
01059
01071
01072 static void irplib_framelist_set_size(irplib_framelist * self)
01073 {
01074
01075
01076 assert( self != NULL);
01077
01078 if (self->size == 0) {
01079
01080 cpl_free(self->frame);
01081 cpl_free(self->propertylist);
01082 self->frame = NULL;
01083 self->propertylist = NULL;
01084 } else {
01085
01086
01087 self->frame = cpl_realloc(self->frame, self->size * sizeof(cpl_frame*));
01088 self->propertylist =
01089 cpl_realloc(self->propertylist,
01090 self->size * sizeof(cpl_propertylist*));
01091 }
01092
01093 }
01094
01095
01119
01120 static cpl_boolean irplib_property_equal(const cpl_propertylist * self,
01121 const cpl_propertylist * other,
01122 const char * key, cpl_type type,
01123 double fp_tol,
01124 char ** sstring, char ** ostring)
01125 {
01126
01127 cpl_boolean equal;
01128
01129
01130 assert(self != NULL);
01131 assert(other != NULL);
01132 assert(key != NULL);
01133 assert(sstring != NULL);
01134 assert(ostring != NULL);
01135
01136
01137 assert(cpl_propertylist_get_type(other, key) == type);
01138 assert(fp_tol >= 0.0);
01139
01140 switch (type) {
01141
01142 case CPL_TYPE_CHAR: {
01143 const char svalue = cpl_propertylist_get_char(self, key);
01144 const char ovalue = cpl_propertylist_get_char(other, key);
01145
01146 equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
01147 if (!equal) {
01148 *sstring = irplib_sprintf("%c", svalue);
01149 *ostring = irplib_sprintf("%c", ovalue);
01150 }
01151 break;
01152 }
01153
01154 case CPL_TYPE_BOOL: {
01155 const int svalue = cpl_propertylist_get_bool(self, key);
01156 const int ovalue = cpl_propertylist_get_bool(other, key);
01157
01158 equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
01159 if (!equal) {
01160 *sstring = cpl_strdup(svalue == 0 ? "F" : "T");
01161 *ostring = cpl_strdup(ovalue == 0 ? "F" : "T");
01162 }
01163 break;
01164 }
01165
01166 case CPL_TYPE_INT: {
01167 const int svalue = cpl_propertylist_get_int(self, key);
01168 const int ovalue = cpl_propertylist_get_int(other, key);
01169
01170 equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
01171 if (!equal) {
01172 *sstring = irplib_sprintf("%d", svalue);
01173 *ostring = irplib_sprintf("%d", ovalue);
01174 }
01175 break;
01176 }
01177
01178 case CPL_TYPE_LONG: {
01179 const long svalue = cpl_propertylist_get_long(self, key);
01180 const long ovalue = cpl_propertylist_get_long(other, key);
01181
01182 equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
01183 if (!equal) {
01184 *sstring = irplib_sprintf("%ld", svalue);
01185 *ostring = irplib_sprintf("%ld", ovalue);
01186 }
01187 break;
01188 }
01189
01190 case CPL_TYPE_FLOAT: {
01191 const double svalue = (double)cpl_propertylist_get_float(self, key);
01192 const double ovalue = (double)cpl_propertylist_get_float(other, key);
01193
01194 equal = (fabs(svalue - ovalue) <= fp_tol) ? CPL_TRUE : CPL_FALSE;
01195 if (!equal) {
01196 *sstring = irplib_sprintf("%f", svalue);
01197 *ostring = irplib_sprintf("%f", ovalue);
01198 }
01199 break;
01200 }
01201
01202 case CPL_TYPE_DOUBLE: {
01203 const double svalue = cpl_propertylist_get_double(self, key);
01204 const double ovalue = cpl_propertylist_get_double(other, key);
01205
01206 equal = (fabs(svalue - ovalue) <= fp_tol) ? CPL_TRUE : CPL_FALSE;
01207 if (!equal) {
01208 *sstring = irplib_sprintf("%g", svalue);
01209 *ostring = irplib_sprintf("%g", ovalue);
01210 }
01211 break;
01212 }
01213 case CPL_TYPE_STRING: {
01214 const char * svalue = cpl_propertylist_get_string(self, key);
01215 const char * ovalue = cpl_propertylist_get_string(other, key);
01216
01217 equal = strcmp(svalue, ovalue) == 0 ? CPL_TRUE : CPL_FALSE;
01218 if (!equal) {
01219 *sstring = cpl_strdup(svalue);
01220 *ostring = cpl_strdup(ovalue);
01221 }
01222 break;
01223 }
01224 default:
01225
01226 assert( 0 );
01227
01228 equal = CPL_FALSE;
01229
01230 }
01231
01232 if (!equal) {
01233 assert( *sstring != NULL );
01234 assert( *ostring != NULL );
01235 }
01236
01237 return equal;
01238
01239 }
01240
01241
01242
01243
01252
01253 static const char * irplib_type_as_string(cpl_type type)
01254 {
01255
01256 const char * self;
01257
01258
01259 switch (type) {
01260
01261 case CPL_TYPE_CHAR:
01262 self = "char";
01263 break;
01264
01265 case CPL_TYPE_BOOL:
01266 self = "boolean";
01267 break;
01268
01269 case CPL_TYPE_INT:
01270 self = "int";
01271 break;
01272
01273 case CPL_TYPE_LONG:
01274 self = "long";
01275 break;
01276
01277 case CPL_TYPE_FLOAT:
01278 self = "float";
01279 break;
01280
01281 case CPL_TYPE_DOUBLE:
01282 self = "double";
01283 break;
01284
01285 case CPL_TYPE_STRING:
01286 self = "string";
01287 break;
01288
01289 default:
01290
01291 cpl_ensure(0, CPL_ERROR_UNSUPPORTED_MODE, "");
01292
01293 }
01294
01295 return self;
01296
01297 }