00001 #include <stdlib.h>
00002 #include "memory.h"
00003 #include "nmd.h"
00004 #include "nmd_impl.h"
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #undef __FUNCT__
00020 #define __FUNCT__ "NMDAllocateComponent"
00021
00022
00023
00024 static NMDErrorCode NMDAllocateComponent(NMD_metadata_item *rcmp)
00025 {
00026 NMD_metadata_item cmp;
00027 NMD_MALLOC(cmp,1,struct NMD_metadata_item_,"component");
00028 cmp->cookie = NMDCOOKIE; cmp->set = NMDFalse;
00029 *rcmp = cmp;
00030 CHKMEMQ
00031 return 0;
00032 }
00033
00034 #undef __FUNCT__
00035 #define __FUNCT__ "NMDCategoryAllocateNewComponent"
00036
00037
00038
00039
00040 NMDErrorCode NMDCategoryAllocateNewComponent
00041 (NMD_metadata_category cat,const char *cmp,NMDDataType type,NMD_metadata_item *rcpt)
00042 {
00043 NMD_metadata_item cpt; int idx; NMDErrorCode ierr;
00044
00045
00046
00047
00048 if (cat->ncmp >= cat->alloc) {
00049 NMD_metadata_item* newcmps; int newalloc;
00050 newalloc = 2*cat->alloc;
00051 ierr = PetscMalloc
00052 (newalloc*sizeof(struct NMD_metadata_item_),&newcmps); CHKERRQ(ierr);
00053 for (idx=0; idx<cat->ncmp; idx++)
00054 newcmps[idx] = cat->cmps[idx];
00055 ierr = PetscFree(cat->cmps); CHKERRQ(ierr);
00056 cat->cmps = newcmps; cat->alloc = newalloc;
00057 }
00058
00059
00060
00061 idx = cat->ncmp++;
00062 ierr = NMDAllocateComponent(&cpt); NMD_ERR_RETURN(ierr);
00063 NMD_STRDUP(cmp,cpt->name); cpt->t = type; cpt->set = NMDFalse;
00064 cat->cmps[idx] = cpt;
00065 if (rcpt) *rcpt = cpt;
00066 CHKMEMQ
00067 return 0;
00068 }
00069
00070 #undef __FUNCT__
00071 #define __FUNCT__ "NMDComponentDestroy"
00072 NMDErrorCode NMDComponentDestroy(NMD_metadata_item cmp)
00073 {
00074 switch (cmp->t) {
00075 case NMDIntarray :
00076 if (cmp->ii) {
00077 struct NMD_intarray_struct *arraystruct =
00078 (struct NMD_intarray_struct *)(cmp->ii);
00079 if (arraystruct->length>0 && arraystruct->unique==1)
00080 NMD_FREE(arraystruct->data);
00081 NMD_FREE(cmp->ii);
00082 } ;
00083 break;
00084 case NMDRealarray :
00085 if (cmp->rr) {
00086 struct NMD_realarray_struct *arraystruct =
00087 (struct NMD_realarray_struct *)(cmp->rr);
00088 if (arraystruct->length>0 && arraystruct->unique==1)
00089 NMD_FREE(arraystruct->data);
00090 NMD_FREE(cmp->rr);
00091 } ;
00092 break;
00093 case NMDString : NMD_FREE(cmp->cc);
00094 break;
00095 default :
00096 break;
00097 }
00098 NMD_FREE(cmp->name);
00099 NMD_FREE(cmp);
00100 return 0;
00101 }
00102
00103 #undef __FUNCT__
00104 #define __FUNCT__ "NMDCategoryGetOrCreateComponent"
00105
00106
00107 NMDErrorCode NMDCategoryGetOrCreateComponent
00108 (NMD_metadata_category cat,char *cmp,NMDDataType type,NMD_metadata_item *cpt)
00109 {
00110 NMD_metadata_item cnew; NMDTruth flg; NMDErrorCode ierr;
00111 CHECKHASNMDCOOKIE(cat);
00112 ierr = NMDCategoryTryGetComponent(cat,cmp,&cnew,&flg); NMD_ERR_RETURN(ierr);
00113 if (flg) {
00114 if (type!=cnew->t)
00115 NMD_ERR_REPORTii
00116 ("Type incompatibility: old/new",(int)(cnew->t),(int)type);
00117 if (cpt) *cpt = cnew;
00118 } else {
00119 ierr = NMDCategoryAllocateNewComponent
00120 (cat,cmp,type,cpt); NMD_ERR_RETURN(ierr);
00121 }
00122 CHKMEMQ
00123 return 0;
00124 }
00125
00126 #undef __FUNCT__
00127 #define __FUNCT__ "NMDObjectEnsureCategoryComponent"
00128
00129
00130
00131
00132
00133 NMDErrorCode NMDObjectEnsureCategoryComponent
00134 (NMD_metadata obj,char *cat,char *cmp,NMDDataType type,NMDTruth *nnew)
00135 {
00136 NMD_metadata_category ctg; NMD_metadata_item cpt;
00137 NMDTruth flg; NMDErrorCode ierr;
00138 CHECKHASNMDCOOKIE(obj);
00139 ierr = NMDObjectTryGetCategory(obj,cat,&ctg,&flg); NMD_ERR_RETURN(ierr);
00140 if (!flg) {
00141 ierr = NMDObjectAllocateNewCategory(obj,cat,&ctg); NMD_ERR_RETURN(ierr);
00142 }
00143 ierr = NMDCategoryTryGetComponent(ctg,cmp,&cpt,&flg); NMD_ERR_RETURN(ierr);
00144 if (flg) {
00145 if (nnew) *nnew = NMDFalse;
00146 if (type!=cpt->t)
00147 NMD_ERR_REPORTii
00148 ("Type incompatibility: old/new",(int)(cpt->t),(int)type);
00149 } else {
00150 if (nnew) *nnew = NMDTrue;
00151 ierr = NMDCategoryAllocateNewComponent
00152 (ctg,cmp,type,NULL); NMD_ERR_RETURN(ierr);
00153 }
00154 CHKMEMQ
00155 return 0;
00156 }
00157
00158 #undef __FUNCT__
00159 #define __FUNCT__ "NMDObjectHasCategoryComponent"
00160 NMDErrorCode NMDObjectHasCategoryComponent
00161 (NMD_metadata obj,char *cat,char *cmp,NMDTruth *f)
00162 {
00163 NMD_metadata_category ctg; NMDErrorCode ierr;
00164 CHECKHASNMDCOOKIE(obj);
00165 ierr = NMDObjectTryGetCategory(obj,cat,&ctg,f); NMD_ERR_RETURN(ierr);
00166 if (*f) {
00167 ierr = NMDCategoryTryGetComponent(ctg,cmp,NULL,f); NMD_ERR_RETURN(ierr);
00168 }
00169 CHKMEMQ
00170 return 0;
00171 }
00172
00173 #undef __FUNCT__
00174 #define __FUNCT__ "NMDCategoryTryGetComponent"
00175
00176
00177 NMDErrorCode NMDCategoryTryGetComponent
00178 (NMD_metadata_category cat,const char *cmp, NMD_metadata_item *rcpt,NMDTruth *f)
00179 {
00180 int icmp;
00181 CHECKHASNMDCOOKIE(cat);
00182 *f = NMDFalse;
00183 for (icmp=0; icmp<cat->ncmp; icmp++) {
00184 NMD_metadata_item cpt = cat->cmps[icmp];
00185 CHECKHASNMDCOOKIE(cpt);
00186 if (strcmp(cmp,cpt->name)==0) {
00187 *f = NMDTrue;
00188 if (rcpt) *rcpt = cpt;
00189 break;
00190 }
00191 }
00192 CHKMEMQ
00193 return 0;
00194 }
00195
00196 #undef __FUNCT__
00197 #define __FUNCT__ "NMDCategoryGetComponents"
00198
00199
00200
00201
00202
00203
00204 NMDErrorCode NMDCategoryGetComponents
00205 (NMD_metadata obj,char* cat,int *ncmp,char ***cmps,NMDDataType **typs)
00206 {
00207 NMD_metadata_category catobj; int icmp;
00208 char **names; NMDDataType *types; NMDErrorCode ierr;
00209 CHECKHASNMDCOOKIE(obj);
00210 ierr = NMDObjectGetCategory(obj,cat,&catobj); CHKERRQ(ierr);
00211 if (ncmp) *ncmp = catobj->ncmp;
00212 if (cmps) {
00213 NMD_MALLOC(names,catobj->ncmp,char*,"name array");
00214 for (icmp=0; icmp<catobj->ncmp; icmp++)
00215 names[icmp] = catobj->cmps[icmp]->name;
00216 *cmps = names;
00217 }
00218 if (typs) {
00219 NMD_MALLOC(types,catobj->ncmp,NMDDataType,"type array");
00220 for (icmp=0; icmp<catobj->ncmp; icmp++)
00221 types[icmp] = catobj->cmps[icmp]->t;
00222 *typs = types;
00223 }
00224 CHKMEMQ
00225 return 0;
00226 }
00227
00228 #undef __FUNCT__
00229 #define __FUNCT__ "NMDCategoryGetComponent"
00230
00231
00232
00233 NMDErrorCode NMDCategoryGetComponent
00234 (NMD_metadata_category cat,char *cmp,NMD_metadata_item *cpt)
00235 {
00236 NMDTruth flg; NMDErrorCode ierr;
00237 CHECKHASNMDCOOKIE(cat);
00238 ierr = NMDCategoryTryGetComponent
00239 (cat,cmp,cpt,&flg); NMD_ERR_RETURN(ierr);
00240 if (!flg) NMD_ERR_REPORTss("Could not find component in category",cmp,cat->name);
00241 CHKMEMQ
00242 return 0;
00243 }
00244
00245 #undef __FUNCT__
00246 #define __FUNCT__ "NMDGetCategoryIGetComponents"
00247
00248
00249
00250
00251
00252
00253
00254 NMDErrorCode NMDGetCategoryIGetComponents
00255 (NMD_metadata obj,int icat,int *ncmp,char ***cmps,NMDDataType **typs)
00256 {
00257 NMD_metadata_category cat;
00258 CHECKHASNMDCOOKIE(obj);
00259 cat = obj->cats[icat];
00260 if (ncmp) *ncmp = cat->ncmp;
00261 if (cat->ncmp && (cmps || typs) ) {
00262 NMDDataType *types; char **names; int icmp;
00263 if (cmps)
00264 NMD_MALLOC(names,cat->ncmp,char*,"name array");
00265 if (typs)
00266 NMD_MALLOC(types,cat->ncmp,NMDDataType,"name array");
00267 for (icmp=0; icmp<cat->ncmp; icmp++) {
00268 if (cmps) names[icmp] = cat->cmps[icmp]->name;
00269 if (typs) types[icmp] = cat->cmps[icmp]->t;
00270 }
00271 if (cmps) *cmps = names; if (typs) *typs = types;
00272 }
00273 return 0;
00274 }
00275
00276 #undef __FUNCT__
00277 #define __FUNCT__ "NMDComponentSetValue"
00278 NMDErrorCode NMDComponentSetValue(NMD_metadata_item cpt,NMDDataType t,void *v)
00279 {
00280 CHECKHASNMDCOOKIE(cpt);
00281 if (t!=cpt->t) NMD_ERR_REPORT("Type conflict");
00282 switch (cpt->t) {
00283 case NMDInt : cpt->i = *(int*)v; break;
00284 case NMDReal : cpt->r = *(double*)v; break;
00285 case NMDString : NMD_STRDUP((char*)v,cpt->cc); break;
00286 case NMDIntarray :
00287 case NMDRealarray :
00288 NMD_ERR_REPORT("Please use NMDSetArrayValue"); break;
00289 default : NMD_ERR_REPORTi("Unknown type",(int)t); break;
00290 }
00291 cpt->set = NMDTrue;
00292 return 0;
00293 }
00294
00295 #undef __FUNCT__
00296 #define __FUNCT__ "NMDComponentUnsetValue"
00297 NMDErrorCode NMDComponentUnsetValue(NMD_metadata_item cpt)
00298 {
00299 CHECKHASNMDCOOKIE(cpt);
00300 switch (cpt->t) {
00301 case NMDInt :
00302 case NMDReal : break;
00303 case NMDString : NMD_FREE(cpt->cc); break;
00304 case NMDIntarray : {
00305 struct NMD_intarray_struct* iistruct = cpt->ii;
00306 NMD_FREE(iistruct->data);
00307 NMD_FREE(iistruct);
00308 break;}
00309 case NMDRealarray : {
00310 struct NMD_realarray_struct* rrstruct = cpt->rr;
00311 NMD_FREE(rrstruct->data);
00312 NMD_FREE(rrstruct);
00313 break;}
00314 default : NMD_ERR_REPORTi("Unknown type",cpt->t); break;
00315 }
00316 cpt->set = NMDFalse;
00317 return 0;
00318 }
00319
00320 #undef __FUNCT__
00321 #define __FUNCT__ "NMDComponentSetArrayValue"
00322 NMDErrorCode NMDComponentSetArrayValue
00323 (NMD_metadata_item cpt,NMDDataType t,void *v,int l)
00324 {
00325 NMDErrorCode ierr;
00326 CHECKHASNMDCOOKIE(cpt);
00327 switch (cpt->t) {
00328 case NMDInt :
00329 case NMDReal :
00330 case NMDString :
00331 ierr = NMDComponentSetValue(cpt,cpt->t,v); NMD_ERR_RETURN(ierr);
00332 break;
00333 case NMDIntarray : {
00334 struct NMD_intarray_struct* iistruct;
00335 NMD_MALLOC(iistruct,1,struct NMD_intarray_struct,"int array struct");
00336 iistruct->unique = 0; iistruct->length = l;
00337 iistruct->data = *(int**)v;
00338 cpt->ii = iistruct;
00339 break;}
00340 case NMDRealarray : {
00341 struct NMD_realarray_struct* rrstruct;
00342 NMD_MALLOC(rrstruct,1,struct NMD_realarray_struct,"real array struct");
00343 rrstruct->unique = 0; rrstruct->length = l;
00344 rrstruct->data = *(NMDRealtype**)v;
00345 cpt->rr = rrstruct;
00346 break;}
00347 default :
00348 NMD_ERR_REPORTi("Unknown type",(int)t)
00349 }
00350 cpt->set = NMDTrue;
00351 return 0;
00352 }
00353
00354 #undef __FUNCT__
00355 #define __FUNCT__ "NMDCopyItemValues"
00356
00357
00358
00359 PetscErrorCode NMDCopyItemValues(NMD_metadata_item src,NMD_metadata_item tar)
00360 {
00361 tar->set = src->set; if (!src->set) goto done;
00362 switch (src->t) {
00363 case NMDInt : tar->i = src->i; break;
00364 case NMDReal : tar->r = src->r ; break;
00365 case NMDString : NMD_STRDUP(src->cc,tar->cc); break;
00366 case NMDIntarray :
00367 {
00368 struct NMD_intarray_struct *tarstruct,*srcstruct = src->ii;
00369 int length=srcstruct->length;
00370 NMD_MALLOC(tarstruct,1,struct NMD_intarray_struct,"copied int array");
00371 tarstruct->length = length; tarstruct->unique = srcstruct->unique;
00372 if (srcstruct->unique) {
00373 int *a1=srcstruct->data,*a2; int i;
00374 NMD_MALLOC(a2,length,int,"int array data");
00375 for (i=0; i<length; i++) a2[i] = a1[i];
00376 tarstruct->data = a2;
00377 } else
00378 tarstruct->data = srcstruct->data;
00379 tar->ii = tarstruct;
00380 } ;
00381 break;
00382 case NMDRealarray :
00383 {
00384 struct NMD_realarray_struct *tarstruct,*srcstruct = src->rr;
00385 int length=srcstruct->length;
00386 NMD_MALLOC(tarstruct,1,struct NMD_realarray_struct,"copied real array");
00387 tarstruct->length = length; tarstruct->unique = srcstruct->unique;
00388 if (srcstruct->unique) {
00389 NMDRealtype *a1=srcstruct->data,*a2; int i;
00390 NMD_MALLOC(a2,length,NMDRealtype,"real array data");
00391 for (i=0; i<length; i++) a2[i] = a1[i];
00392 tarstruct->data = a2;
00393 } else
00394 tarstruct->data = srcstruct->data;
00395 tar->rr = tarstruct;
00396 } ;
00397 break;
00398 default : NMD_ERR_REPORTi("Can not copy items of type",(int)(src->t));
00399 break;
00400 }
00401 done:
00402 CHKMEMQ
00403 return 0;
00404 }
00405