📄 gaparameter.cpp
字号:
// $Header$/* ---------------------------------------------------------------------------- parameters.C mbwall 28jul94 Copyright (c) 1995 Massachusetts Institute of Technology all rights reserved DESCRIPTION: Definition of the parameter object and a container list for it. I did thisas a separate list implementation because I don't want all of the overhead ofa fullblown list. The parameter list is a special purpose, stripped down listimplementation.---------------------------------------------------------------------------- */#include <stdlib.h>#include <string.h>#include <ctype.h>#include "gaconfig.h"#include "gaerror.h"#include "GAParameter.h"#define PRM_CHUNKSIZE 10#define BUFSIZE 1024 // size of buffer for reading pairs#define MAX_PAIRS 5000 // max number of name-value pairs in stream#define NAMESIZE 128 // max length of name in name-value pairextern char _gaerrbuf1[];extern char _gaerrbuf2[];static int IsNumeric(const char*);GAParameter::GAParameter(const char* fn, const char* sn, Type tp, const void* v){ if(fn){ fname = new char[strlen(fn)+1]; strcpy(fname, fn); } else fname = (char*)0; if(sn){ sname = new char[strlen(sn)+1]; strcpy(sname, sn); } else sname = (char*)0; t = tp; memset(&val, 0, sizeof(Value)); setvalue(v);}GAParameter::GAParameter(const GAParameter& orig){ fname=sname = (char*)0; memset(&val, 0, sizeof(Value)); copy(orig);}voidGAParameter::copy(const GAParameter& orig){ if(&orig == this) return; delete [] fname; delete [] sname; if(orig.fname){ fname = new char[strlen(orig.fname)+1]; strcpy(fname, orig.fname); } else fname = (char *)0; if(orig.sname){ sname = new char[strlen(orig.sname)+1]; strcpy(sname, orig.sname); } else sname = (char *)0; t = orig.t; setvalue(orig.value()); // do this directly...} GAParameter::~GAParameter(){ delete [] fname; delete [] sname; if(t == STRING) delete [] val.sval;}voidGAParameter::setvalue(const void* v){ switch(t){ case BOOLEAN: case INT: val.ival = *((int*)v); break; case CHAR: val.cval = *((char*)v); break; case STRING: if(v != val.sval) { char* ptr=0; if(strlen((char*)v) > 0){ ptr = new char[strlen((char*)v)+1]; strcpy(ptr, (char*)v); } delete [] val.sval; val.sval = ptr; } break; case FLOAT: val.fval = *((float*)v); break; case DOUBLE: val.dval = *((double*)v); break; case POINTER: default: val.pval = v; break; }}// The default parameter list is empty. Allocate space for the pointers, but// don't allocate any parameters at this point.GAParameterList::GAParameterList(){ N = n = cur = 0; p = (GAParameter**)0;}GAParameterList::GAParameterList(const GAParameterList& list){ N = list.N; n = list.n; cur = list.cur; p = new GAParameter * [N]; for(unsigned int i=0; i<n; i++) p[i] = new GAParameter(*(list.p[i]));}// This is a rather stupid operator= implementation. Instead of doing a copy// we just nuke everything the reallocate new stuff. If this were called a lot// then we could end up with some fragmentation this way (rather than just // doing copies on already-allocated memory).GAParameterList&GAParameterList::operator=(const GAParameterList& list){ if(&list == this) return *this; unsigned int i; for(i=0; i<n; i++) delete p[i]; delete [] p; N = list.N; n = list.n; cur = list.cur; p = new GAParameter * [N]; for(i=0; i<n; i++) p[i] = new GAParameter(*(list.p[i])); return *this;}GAParameterList::~GAParameterList(){ for(unsigned int i=0; i<n; i++) delete p[i]; delete [] p;}// Set the specified parameter (if we have it). If we don't recognize the name// (ie it has not been added to the list) then we return the error code.intGAParameterList::set(const char* name, const void* v){ int found = 0; for(unsigned int i=0; i<n && !found; i++){ if(strcmp(name, p[i]->fullname()) == 0 || strcmp(name, p[i]->shrtname()) == 0){ p[i]->value(v); found = 1; } } return found ? 0 : -1;}// Must do a special case for double/float. Any floats that get passed to this// routine will be cast to doubles, but then we need to force them back to a// float if FLOAT is the type that is expected. Kind of sucks, eh?// We could check the parameter type against the type here, but we don't. // (could do it for all of the 'set' members). Maybe in a later release.intGAParameterList::set(const char* name, double v) { int found = 0; for(unsigned int i=0; i<n; i++){ if(strcmp(name, p[i]->fullname()) == 0 || strcmp(name, p[i]->shrtname()) == 0){ if(p[i]->type() == GAParameter::FLOAT){ float fval = (float)v; p[i]->value((void*)&fval); } else if(p[i]->type() == GAParameter::DOUBLE) p[i]->value((void*)&v); else GAErr(GA_LOC, "GAParameterList", "set", gaErrBadTypeIndicator); found = 1; } } return found ? 0 : -1;}// This allocates space for strings, so be sure to free it!intGAParameterList::get(const char* name, void* value) const { int status = 1; for(unsigned int i=0; i<n; i++){ if(strcmp(name, p[i]->fullname()) == 0 || strcmp(name, p[i]->shrtname()) == 0){ switch(p[i]->type()){ case GAParameter::BOOLEAN: case GAParameter::INT: *((int*)value) = *((int*)p[i]->value()); break; case GAParameter::CHAR: *((char*)value) = *((char*)p[i]->value()); break; case GAParameter::STRING: break; case GAParameter::FLOAT: *((float*)value) = *((float*)p[i]->value()); break; case GAParameter::DOUBLE: *((double*)value) = *((double*)p[i]->value()); break; case GAParameter::POINTER: default: break; } status = 0; } } return status;}// Add the item to the list if it does not already exist. Return 0 if the add// was OK, -1 if there was a problem.intGAParameterList::add(const char* fn, const char* sn, GAParameter::Type t, const void* v) { int status = -1; if(n == N){ N += PRM_CHUNKSIZE; GAParameter **tmp = p; p = new GAParameter* [N]; memcpy(p, tmp, n * sizeof(GAParameter*)); delete [] tmp; } int found = 0; for(unsigned int i=0; i<n && !found; i++){ if(strcmp(fn, p[i]->fullname()) == 0 && strcmp(sn, p[i]->shrtname()) == 0) found = 1; } if(!found){ cur = n; p[n++] = new GAParameter(fn, sn, t, v); } return status;}// When you remove a parameter from the list, the iterator is left pointing// at the same location. If the item was the last in the list, then the // iterator moves to the new last item in the list.// Return 0 if everything was OK, -1 if error.intGAParameterList::remove(){ int status = -1; if(cur > n) return status; delete p[cur]; memmove(&(p[cur]), &(p[cur+1]), (n-cur-1)*sizeof(GAParameter*)); n--; if(cur > n) cur = n; status = 0; return status;}GAParameter* GAParameterList::operator()(const char* name){ for(unsigned int i=0; i<n; i++) if(strcmp(name, p[i]->fullname())==0 || strcmp(name, p[i]->shrtname())==0) return p[i]; return (GAParameter*)0;}#ifdef GALIB_USE_STREAMS// Dump the parameters to the specified stream. Just name-value pairs with a// tab delimiter and newline separating pairs.// If there is an error, return 1, otherwise return 0.intGAParameterList::write(STD_OSTREAM& os) const { for(unsigned int i=0; i<n; i++){ int ival; float fval; double dval; char cval; char* sval; os << p[i]->fullname() << "\t"; switch(p[i]->type()){ case GAParameter::BOOLEAN: ival = *((int*)(p[i]->value())); if(ival) os << "1\n"; else os << "0\n"; break; case GAParameter::INT: ival = *((int*)(p[i]->value())); os << ival << "\n"; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -