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", filename));
00601 return cpl_error_get_code();
00602 }
00603
00604 return CPL_ERROR_NONE;
00605
00606 }
00607
00608
00609
00623
00624 cpl_error_code irplib_framelist_load_propertylist_all(irplib_framelist * self,
00625 int ind,
00626 const char * regexp,
00627 cpl_boolean invert)
00628 {
00629
00630 int nprops = 0;
00631 int nfiles = 0;
00632 int i;
00633
00634 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00635 cpl_ensure_code(regexp != NULL, CPL_ERROR_NULL_INPUT);
00636
00637 for (i=0; i < self->size; i++) {
00638 if (self->propertylist[i] == NULL)
00639 cpl_ensure_code(!irplib_framelist_load_propertylist(self, i,
00640 ind,
00641 regexp,
00642 invert),
00643 cpl_error_get_code());
00644
00645
00646 nprops += cpl_propertylist_get_size(self->propertylist[i]);
00647 nfiles++;
00648 }
00649
00650 cpl_msg_info(cpl_func, "List of %d frames has %d properties", nfiles,
00651 nprops);
00652
00653 return CPL_ERROR_NONE;
00654
00655 }
00656
00657
00658
00659
00667
00668 cpl_error_code irplib_framelist_set_tag_all(irplib_framelist * self,
00669 const char * tag)
00670 {
00671
00672 int i;
00673
00674 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00675 cpl_ensure_code(tag != NULL, CPL_ERROR_NULL_INPUT);
00676
00677 for (i=0; i < self->size; i++)
00678 cpl_ensure_code(!cpl_frame_set_tag(self->frame[i], tag),
00679 cpl_error_get_code());
00680
00681 return CPL_ERROR_NONE;
00682 }
00683
00684
00685
00699
00700 cpl_error_code irplib_framelist_set(irplib_framelist * self, cpl_frame * frame,
00701 int pos)
00702 {
00703
00704 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00705 cpl_ensure_code(frame != NULL, CPL_ERROR_NULL_INPUT);
00706 cpl_ensure_code(pos >= 0, CPL_ERROR_ILLEGAL_INPUT);
00707
00708 if (pos == self->size) {
00709
00710 self->size++;
00711
00712 irplib_framelist_set_size(self);
00713
00714 } else {
00715
00716 cpl_ensure_code(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00717
00718 cpl_frame_delete(self->frame[pos]);
00719 cpl_propertylist_delete(self->propertylist[pos]);
00720 }
00721
00722 self->frame[pos] = frame;
00723 self->propertylist[pos] = NULL;
00724
00725 return CPL_ERROR_NONE;
00726
00727 }
00728
00729
00738
00739 cpl_error_code irplib_framelist_erase(irplib_framelist * self, int pos)
00740 {
00741
00742 int i;
00743
00744 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00745 cpl_ensure_code(pos >= 0, CPL_ERROR_ILLEGAL_INPUT);
00746 cpl_ensure_code(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00747
00748
00749
00750 cpl_frame_delete(self->frame[pos]);
00751 cpl_propertylist_delete(self->propertylist[pos]);
00752
00753
00754 for (i = pos+1; i < self->size; i++) {
00755
00756 self->frame[i-1] = self->frame[i];
00757
00758 self->propertylist[i-1] = self->propertylist[i];
00759
00760 }
00761
00762 self->size--;
00763
00764 irplib_framelist_set_size(self);
00765
00766 return CPL_ERROR_NONE;
00767
00768 }
00769
00770
00771
00772
00788
00789 cpl_frame * irplib_framelist_unset(irplib_framelist * self, int pos,
00790 cpl_propertylist ** plist)
00791
00792 {
00793 cpl_frame * frame;
00794 int i;
00795
00796
00797 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
00798 cpl_ensure(pos >= 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
00799 cpl_ensure(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
00800
00801
00802 frame = self->frame[pos];
00803
00804 if (plist != NULL)
00805 *plist = self->propertylist[pos];
00806 else
00807 cpl_propertylist_delete(self->propertylist[pos]);
00808
00809
00810
00811 for (i = pos+1; i < self->size; i++) {
00812
00813 self->frame[i-1] = self->frame[i];
00814
00815 self->propertylist[i-1] = self->propertylist[i];
00816
00817 }
00818
00819 self->size--;
00820
00821 irplib_framelist_set_size(self);
00822
00823 return frame;
00824
00825 }
00826
00827
00834
00835 void irplib_framelist_empty(irplib_framelist * self)
00836 {
00837
00838 if (self != NULL) {
00839
00840
00841 while (self->size > 0) {
00842 self->size--;
00843 cpl_frame_delete(self->frame[self->size]);
00844 cpl_propertylist_delete(self->propertylist[self->size]);
00845
00846 }
00847
00848
00849 irplib_framelist_set_size(self);
00850
00851 }
00852 }
00853
00854
00855
00856
00894
00895 cpl_error_code irplib_framelist_contains(const irplib_framelist * self,
00896 const char * key, cpl_type type,
00897 cpl_boolean is_equal, double fp_tol)
00898 {
00899
00900 char * value_0;
00901 char * value_i;
00902 cpl_type type_0 = CPL_TYPE_INVALID;
00903 int i;
00904
00905
00906 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00907 cpl_ensure_code(key != NULL, CPL_ERROR_NULL_INPUT);
00908 cpl_ensure_code(fp_tol >= 0.0, CPL_ERROR_ILLEGAL_INPUT);
00909
00910 for (i=0; i < self->size; i++) {
00911 cpl_type type_i;
00912
00913
00914 if (self->propertylist[i] == NULL) continue;
00915
00916 type_i = cpl_propertylist_get_type(self->propertylist[i], key);
00917
00918 if (type_i == CPL_TYPE_INVALID) {
00919 if (type == CPL_TYPE_INVALID)
00920 irplib_error_push(cpl_error_get_code(),
00921 ("FITS key '%s' is missing from file %s", key,
00922 cpl_frame_get_filename(self->frame[i])));
00923 else
00924 irplib_error_push(cpl_error_get_code(),
00925 ("FITS key '%s' [%s] is missing from "
00926 "file %s", key, irplib_type_as_string(type),
00927 cpl_frame_get_filename(self->frame[i])));
00928 return cpl_error_get_code();
00929 }
00930
00931 if (type != CPL_TYPE_INVALID && type_i != type) {
00932 irplib_error_push(CPL_ERROR_INVALID_TYPE,
00933 ("FITS key '%s' has type %s instead of %s in "
00934 "file %s", key, irplib_type_as_string(type_i),
00935 irplib_type_as_string(type),
00936 cpl_frame_get_filename(self->frame[i])));
00937 return cpl_error_get_code();
00938 }
00939
00940 if (!is_equal) continue;
00941
00942 if (type_0 == CPL_TYPE_INVALID) {
00943 type_0 = type_i;
00944 continue;
00945 }
00946
00947 if (type_i != type_0) {
00948 assert( type == CPL_TYPE_INVALID );
00949 irplib_error_push(CPL_ERROR_TYPE_MISMATCH,
00950 ("FITS key '%s' has different types "
00951 "(%s <=> %s) in files %s and %s", key,
00952 irplib_type_as_string(type_0),
00953 irplib_type_as_string(type_i),
00954 cpl_frame_get_filename(self->frame[0]),
00955 cpl_frame_get_filename(self->frame[i])));
00956 return cpl_error_get_code();
00957 }
00958
00959 if (irplib_property_equal(self->propertylist[0], self->propertylist[i],
00960 key, type_0, fp_tol, &value_0, &value_i))
00961 continue;
00962
00963 if ((type_0 == CPL_TYPE_FLOAT || type_0 == CPL_TYPE_DOUBLE)
00964 && fp_tol > 0.0) {
00965 irplib_error_push(CPL_ERROR_INCOMPATIBLE_INPUT,
00966 ("FITS key '%s' [%s] has values that differ by "
00967 "more than %g (%s <=> %s) in files %s and %s",
00968 key, irplib_type_as_string(type_0), fp_tol,
00969 value_0, value_i,
00970 cpl_frame_get_filename(self->frame[0]),
00971 cpl_frame_get_filename(self->frame[i])));
00972 } else {
00973 irplib_error_push(CPL_ERROR_INCOMPATIBLE_INPUT,
00974 ("FITS key '%s' [%s] has different "
00975 "values (%s <=> %s) in files %s and %s", key,
00976 irplib_type_as_string(type_0),
00977 value_0, value_i,
00978 cpl_frame_get_filename(self->frame[0]),
00979 cpl_frame_get_filename(self->frame[i])));
00980 }
00981 cpl_free(value_0);
00982 cpl_free(value_i);
00983
00984 return cpl_error_get_code();
00985 }
00986
00987 return CPL_ERROR_NONE;
00988
00989 }
00990
00991
00992
01005
01006 cpl_imagelist * irplib_imagelist_load_framelist(const irplib_framelist * self,
01007 cpl_type pixeltype,
01008 int planenum,
01009 int extnum)
01010 {
01011
01012 cpl_imagelist * list = NULL;
01013 cpl_image * image = NULL;
01014 int i;
01015
01016
01017 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
01018 cpl_ensure(extnum >= 0, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
01019 cpl_ensure(planenum >= 0, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
01020
01021 list = cpl_imagelist_new();
01022
01023 for (i=0; i < self->size; i++, image = NULL) {
01024 const char * filename = cpl_frame_get_filename(self->frame[i]);
01025 cpl_error_code error;
01026
01027 if (filename == NULL) break;
01028
01029 image = cpl_image_load(filename, pixeltype, planenum, extnum);
01030 if (image == NULL) {
01031 irplib_error_push(cpl_error_get_code(),
01032 ("Could not load FITS-image from plane %d "
01033 "in extension %d in file %s", planenum, extnum,
01034 filename));
01035 break;
01036 }
01037
01038 error = cpl_imagelist_set(list, image, i);
01039 assert(error == CPL_ERROR_NONE);
01040 }
01041
01042 cpl_image_delete(image);
01043
01044 if (cpl_imagelist_get_size(list) != self->size) {
01045 cpl_imagelist_delete(list);
01046 list = NULL;
01047 assert(cpl_error_get_code() != CPL_ERROR_NONE);
01048 }
01049
01050 return list;
01051
01052 }
01053
01054
01058
01070
01071 static void irplib_framelist_set_size(irplib_framelist * self)
01072 {
01073
01074
01075 assert( self != NULL);
01076
01077 if (self->size == 0) {
01078
01079 cpl_free(self->frame);
01080 cpl_free(self->propertylist);
01081 self->frame = NULL;
01082 self->propertylist = NULL;
01083 } else {
01084
01085
01086 self->frame = cpl_realloc(self->frame, self->size * sizeof(cpl_frame*));
01087 self->propertylist =
01088 cpl_realloc(self->propertylist,
01089 self->size * sizeof(cpl_propertylist*));
01090 }
01091
01092 }
01093
01094
01118
01119 static cpl_boolean irplib_property_equal(const cpl_propertylist * self,
01120 const cpl_propertylist * other,
01121 const char * key, cpl_type type,
01122 double fp_tol,
01123 char ** sstring, char ** ostring)
01124 {
01125
01126 cpl_boolean equal;
01127
01128
01129 assert(self != NULL);
01130 assert(other != NULL);
01131 assert(key != NULL);
01132 assert(sstring != NULL);
01133 assert(ostring != NULL);
01134
01135
01136 assert(cpl_propertylist_get_type(other, key) == type);
01137 assert(fp_tol >= 0.0);
01138
01139 switch (type) {
01140
01141 case CPL_TYPE_CHAR: {
01142 const char svalue = cpl_propertylist_get_char(self, key);
01143 const char ovalue = cpl_propertylist_get_char(other, key);
01144
01145 equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
01146 if (!equal) {
01147 *sstring = irplib_sprintf("%c", svalue);
01148 *ostring = irplib_sprintf("%c", ovalue);
01149 }
01150 break;
01151 }
01152
01153 case CPL_TYPE_BOOL: {
01154 const int svalue = cpl_propertylist_get_bool(self, key);
01155 const int ovalue = cpl_propertylist_get_bool(other, key);
01156
01157 equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
01158 if (!equal) {
01159 *sstring = cpl_strdup(svalue == 0 ? "F" : "T");
01160 *ostring = cpl_strdup(ovalue == 0 ? "F" : "T");
01161 }
01162 break;
01163 }
01164
01165 case CPL_TYPE_INT: {
01166 const int svalue = cpl_propertylist_get_int(self, key);
01167 const int ovalue = cpl_propertylist_get_int(other, key);
01168
01169 equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
01170 if (!equal) {
01171 *sstring = irplib_sprintf("%d", svalue);
01172 *ostring = irplib_sprintf("%d", ovalue);
01173 }
01174 break;
01175 }
01176
01177 case CPL_TYPE_LONG: {
01178 const long svalue = cpl_propertylist_get_long(self, key);
01179 const long ovalue = cpl_propertylist_get_long(other, key);
01180
01181 equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
01182 if (!equal) {
01183 *sstring = irplib_sprintf("%ld", svalue);
01184 *ostring = irplib_sprintf("%ld", ovalue);
01185 }
01186 break;
01187 }
01188
01189 case CPL_TYPE_FLOAT: {
01190 const double svalue = (double)cpl_propertylist_get_float(self, key);
01191 const double ovalue = (double)cpl_propertylist_get_float(other, key);
01192
01193 equal = (fabs(svalue - ovalue) <= fp_tol) ? CPL_TRUE : CPL_FALSE;
01194 if (!equal) {
01195 *sstring = irplib_sprintf("%f", svalue);
01196 *ostring = irplib_sprintf("%f", ovalue);
01197 }
01198 break;
01199 }
01200
01201 case CPL_TYPE_DOUBLE: {
01202 const double svalue = cpl_propertylist_get_double(self, key);
01203 const double ovalue = cpl_propertylist_get_double(other, key);
01204
01205 equal = (fabs(svalue - ovalue) <= fp_tol) ? CPL_TRUE : CPL_FALSE;
01206 if (!equal) {
01207 *sstring = irplib_sprintf("%g", svalue);
01208 *ostring = irplib_sprintf("%g", ovalue);
01209 }
01210 break;
01211 }
01212 case CPL_TYPE_STRING: {
01213 const char * svalue = cpl_propertylist_get_string(self, key);
01214 const char * ovalue = cpl_propertylist_get_string(other, key);
01215
01216 equal = strcmp(svalue, ovalue) == 0 ? CPL_TRUE : CPL_FALSE;
01217 if (!equal) {
01218 *sstring = cpl_strdup(svalue);
01219 *ostring = cpl_strdup(ovalue);
01220 }
01221 break;
01222 }
01223 default:
01224
01225 assert( 0 );
01226
01227 equal = CPL_FALSE;
01228
01229 }
01230
01231 if (!equal) {
01232 assert( *sstring != NULL );
01233 assert( *ostring != NULL );
01234 }
01235
01236 return equal;
01237
01238 }
01239
01240
01241
01242
01251
01252 static const char * irplib_type_as_string(cpl_type type)
01253 {
01254
01255 const char * self;
01256
01257
01258 switch (type) {
01259
01260 case CPL_TYPE_CHAR:
01261 self = "char";
01262 break;
01263
01264 case CPL_TYPE_BOOL:
01265 self = "boolean";
01266 break;
01267
01268 case CPL_TYPE_INT:
01269 self = "int";
01270 break;
01271
01272 case CPL_TYPE_LONG:
01273 self = "long";
01274 break;
01275
01276 case CPL_TYPE_FLOAT:
01277 self = "float";
01278 break;
01279
01280 case CPL_TYPE_DOUBLE:
01281 self = "double";
01282 break;
01283
01284 case CPL_TYPE_STRING:
01285 self = "string";
01286 break;
01287
01288 default:
01289
01290 cpl_ensure(0, CPL_ERROR_UNSUPPORTED_MODE, "");
01291
01292 }
01293
01294 return self;
01295
01296 }