00001 #include "Shared/Config.h"
00002 #include "Behaviors/Mon/RawCamBehavior.h"
00003 #include "Vision/RawCameraGenerator.h"
00004 #include <stdio.h>
00005 #include <string>
00006 #include <cstring>
00007 #include <ctype.h>
00008 #include "Wireless/Socket.h"
00009 #ifdef PLATFORM_APERIOS
00010 # include <OPENR/OPrimitiveControl.h>
00011 # include <OPENR/OPENRAPI.h>
00012 #else
00013 typedef unsigned int OSpeakerVolume;
00014 const OSpeakerVolume ospkvolinfdB = 0x8000;
00015 const OSpeakerVolume ospkvol25dB = 0xe700;
00016 const OSpeakerVolume ospkvol18dB = 0xee00;
00017 const OSpeakerVolume ospkvol10dB = 0xf600;
00018 #endif
00019
00020 Config* config=NULL;
00021
00022 void* Config::setValue(section_t section, const char *key, const char *value,
00023 bool ) {
00024 switch (section) {
00025 case sec_wireless:
00026 if (strncasecmp(key,"id",29)==0) {
00027 wireless.id=atoi(value);
00028 return &wireless.id;
00029 }
00030 break;
00031 case sec_vision:
00032 if (strncasecmp(key,"white_balance",29)==0) {
00033 if (strncasecmp(value,"indoor",49)==0) {
00034 vision.white_balance=1;
00035 } else if (strncasecmp(value,"flourescent",49)==0) {
00036 vision.white_balance=3;
00037 } else if (strncasecmp(value,"outdoor",49)==0) {
00038 vision.white_balance=2;
00039 }
00040 #ifdef PLATFORM_APERIOS
00041
00042 OPrimitiveID fbkID = 0;
00043 if(OPENR::OpenPrimitive(CameraLocator, &fbkID) != oSUCCESS){
00044 std::cout << "Open FbkImageSensor failure." << std::endl;
00045 } else {
00046 OPrimitiveControl_CameraParam owb(vision.white_balance);
00047 if(OPENR::ControlPrimitive(fbkID, oprmreqCAM_SET_WHITE_BALANCE, &owb, sizeof(owb), 0, 0) != oSUCCESS){
00048 std::cout << "CAM_SET_WHITE_BALANCE : Failed!" << std::endl;
00049 }
00050 OPENR::ClosePrimitive(fbkID);
00051 }
00052 #endif
00053 return &vision.white_balance;
00054 } else if (strncasecmp(key,"gain",29)==0) {
00055 if (strncasecmp(value,"low",49)==0) {
00056 vision.gain=1;
00057 } else if (strncasecmp(value,"mid",49)==0) {
00058 vision.gain=2;
00059 } else if (strncasecmp(value,"high",49)==0) {
00060 vision.gain=3;
00061 }
00062 #ifdef PLATFORM_APERIOS
00063
00064 OPrimitiveID fbkID = 0;
00065 if(OPENR::OpenPrimitive(CameraLocator, &fbkID) != oSUCCESS){
00066 std::cout << "Open FbkImageSensor failure." << std::endl;
00067 } else {
00068 OPrimitiveControl_CameraParam ogain(vision.gain);
00069 if(OPENR::ControlPrimitive(fbkID, oprmreqCAM_SET_GAIN, &ogain, sizeof(ogain), 0, 0) != oSUCCESS)
00070 std::cout << "CAM_SET_GAIN : Failed!" << std::endl;
00071 OPENR::ClosePrimitive(fbkID);
00072 }
00073 #endif
00074 return &vision.gain;
00075 } else if (strncasecmp(key,"shutter_speed",29)==0) {
00076 if (strncasecmp(value,"slow",49)==0) {
00077 vision.shutter_speed=1;
00078 } else if (strncasecmp(value,"mid",49)==0) {
00079 vision.shutter_speed=2;
00080 } else if (strncasecmp(value,"fast",49)==0) {
00081 vision.shutter_speed=3;
00082 }
00083 #ifdef PLATFORM_APERIOS
00084
00085 OPrimitiveID fbkID = 0;
00086 if(OPENR::OpenPrimitive(CameraLocator, &fbkID) != oSUCCESS){
00087 std::cout << "Open FbkImageSensor failure." << std::endl;
00088 } else {
00089 OPrimitiveControl_CameraParam oshutter(vision.shutter_speed);
00090 if(OPENR::ControlPrimitive(fbkID,oprmreqCAM_SET_SHUTTER_SPEED, &oshutter, sizeof(oshutter), 0, 0) != oSUCCESS)
00091 std::cout << "CAM_SET_SHUTTER_SPEED : Failed!" << std::endl;
00092 OPENR::ClosePrimitive(fbkID);
00093 }
00094 #endif
00095 return &vision.shutter_speed;
00096 } else if (strncasecmp(key,"resolution",29)==0) {
00097 if (strncasecmp(value,"full",49)==0) {
00098 vision.resolution=1;
00099 } else if (strncasecmp(value,"half",49)==0) {
00100 vision.resolution=2;
00101 } else if (strncasecmp(value,"quarter",49)==0) {
00102 vision.resolution=3;
00103 }
00104 return &vision.resolution;
00105 } else if (strncasecmp(key,"horizFOV",29)==0) {
00106 vision.horizFOV=atof(value)*M_PI/180;
00107 return &vision.horizFOV;
00108 } else if (strncasecmp(key,"vertFOV",29)==0) {
00109 vision.vertFOV=atof(value)*M_PI/180;
00110 return &vision.vertFOV;
00111 } else if (strncasecmp(key,"focal_length",29)==0) {
00112 vision.focal_length=atof(value);
00113 return &vision.focal_length;
00114 } else if (strncasecmp(key,"thresh",29)==0) {
00115 vision.thresh.push_back(value);
00116 return &vision.thresh;
00117 } else if (strncasecmp(key,"colors",29)==0) {
00118 strncpy(vision.colors,value,49);
00119 return &vision.colors;
00120 } else if (strncasecmp(key,"raw_port",29)==0) {
00121 vision.rawcam_port=atoi(value);
00122 return &vision.rawcam_port;
00123 } else if (strncasecmp(key,"raw_transport",29)==0) {
00124 if (strncasecmp(value,"udp",49)==0)
00125 vision.rawcam_transport=0;
00126 else if (strncasecmp(value,"tcp",49)==0)
00127 vision.rawcam_transport=1;
00128 return &vision.rawcam_transport;
00129 } else if (strncasecmp(key,"rle_port",29)==0) {
00130 vision.rle_port=atoi(value);
00131 return &vision.rle_port;
00132 } else if (strncasecmp(key,"rle_transport",29)==0) {
00133 if (strncasecmp(value,"udp",49)==0)
00134 vision.rle_transport=0;
00135 else if (strncasecmp(value,"tcp",49)==0)
00136 vision.rle_transport=1;
00137 return &vision.rle_transport;
00138 } else if (strncasecmp(key,"obj_port",29)==0) {
00139 vision.obj_port=atoi(value);
00140 return &vision.obj_port;
00141 } else if (strncasecmp(key,"restore_image",29)==0) {
00142 vision.restore_image=atoi(value);
00143 return &vision.obj_port;
00144 } else if (strncasecmp(key,"jpeg_dct_method",29)==0) {
00145 if (strncasecmp(value,"islow",49)==0) {
00146 vision.jpeg_dct_method=JDCT_ISLOW;
00147 } else if (strncasecmp(value,"ifast",49)==0) {
00148 vision.jpeg_dct_method=JDCT_IFAST;
00149 } else if (strncasecmp(value,"float",49)==0) {
00150 vision.jpeg_dct_method=JDCT_FLOAT;
00151 }
00152 return &vision.jpeg_dct_method;
00153 } else if (strncasecmp(key,"rawcam_encoding",29)==0) {
00154 if (strncasecmp(value,"color",49)==0) {
00155 vision.rawcam_encoding=vision_config::ENCODE_COLOR;
00156 vision.rawcam_channel=RawCameraGenerator::CHAN_Y;
00157 } else if (strncasecmp(value,"y_only",49)==0) {
00158 vision.rawcam_encoding=vision_config::ENCODE_SINGLE_CHANNEL;
00159 vision.rawcam_channel=RawCameraGenerator::CHAN_Y;
00160 } else if (strncasecmp(value,"uv_only",49)==0) {
00161 vision.rawcam_encoding=vision_config::ENCODE_COLOR;
00162 vision.rawcam_channel=-1;
00163 } else if (strncasecmp(value,"u_only",49)==0) {
00164 vision.rawcam_encoding=vision_config::ENCODE_SINGLE_CHANNEL;
00165 vision.rawcam_channel=RawCameraGenerator::CHAN_U;
00166 } else if (strncasecmp(value,"v_only",49)==0) {
00167 vision.rawcam_encoding=vision_config::ENCODE_SINGLE_CHANNEL;
00168 vision.rawcam_channel=RawCameraGenerator::CHAN_V;
00169 } else if (strncasecmp(value,"y_dx_only",49)==0) {
00170 vision.rawcam_encoding=vision_config::ENCODE_SINGLE_CHANNEL;
00171 vision.rawcam_channel=RawCameraGenerator::CHAN_Y_DX;
00172 } else if (strncasecmp(value,"y_dy_only",49)==0) {
00173 vision.rawcam_encoding=vision_config::ENCODE_SINGLE_CHANNEL;
00174 vision.rawcam_channel=RawCameraGenerator::CHAN_Y_DY;
00175 } else if (strncasecmp(value,"y_dxdy_only",49)==0) {
00176 vision.rawcam_encoding=vision_config::ENCODE_SINGLE_CHANNEL;
00177 vision.rawcam_channel=RawCameraGenerator::CHAN_Y_DXDY;
00178 }
00179 return &vision.rawcam_encoding;
00180 } else if (strncasecmp(key,"rawcam_compression",29)==0) {
00181 if (strncasecmp(value,"none",49)==0) {
00182 vision.rawcam_compression=vision_config::COMPRESS_NONE;
00183 } else if (strncasecmp(value,"jpeg",49)==0) {
00184 vision.rawcam_compression=vision_config::COMPRESS_JPEG;
00185 }
00186 return &vision.rawcam_compression;
00187 } else if (strncasecmp(key,"rawcam_compress_quality",29)==0) {
00188 vision.rawcam_compress_quality=atoi(value);
00189 return &vision.rawcam_compress_quality;
00190 } else if (strncasecmp(key,"rawcam_y_skip",29)==0) {
00191 vision.rawcam_y_skip=atoi(value);
00192 return &vision.rawcam_y_skip;
00193 } else if (strncasecmp(key,"rawcam_uv_skip",29)==0) {
00194 vision.rawcam_uv_skip=atoi(value);
00195 return &vision.rawcam_uv_skip;
00196 } else if (strncasecmp(key,"rlecam_skip",29)==0) {
00197 vision.rlecam_skip=atoi(value);
00198 return &vision.rlecam_skip;
00199 } else if (strncasecmp(key,"rlecam_channel",29)==0) {
00200 vision.rlecam_channel=atoi(value);
00201 return &vision.rlecam_channel;
00202 } else if (strncasecmp(key,"rlecam_compression",29)==0) {
00203 if (strncasecmp(value,"none",49)==0) {
00204 vision.rlecam_compression=vision_config::COMPRESS_NONE;
00205 } else if (strncasecmp(value,"rle",49)==0) {
00206 vision.rlecam_compression=vision_config::COMPRESS_RLE;
00207 }
00208 return &vision.rlecam_compression;
00209 }
00210 break;
00211 case sec_main:
00212 if (strncasecmp(key,"console_port",29)==0) {
00213 main.console_port=atoi(value);
00214 return &main.console_port;
00215 } else if (strncasecmp(key,"stderr_port",29)==0) {
00216 main.stderr_port=atoi(value);
00217 return &main.stderr_port;
00218 } else if (strncasecmp(key,"error_level",29)==0) {
00219 main.error_level=atoi(value);
00220 return &main.error_level;
00221 } else if (strncasecmp(key,"debug_level",29)==0) {
00222 main.debug_level=atoi(value);
00223 return &main.debug_level;
00224 } else if (strncasecmp(key,"verbose_level",29)==0) {
00225 main.verbose_level=atoi(value);
00226 return &main.verbose_level;
00227 } else if (strncasecmp(key,"wsjoints_port",29)==0) {
00228 main.wsjoints_port=atoi(value);
00229 return &main.wsjoints_port;
00230 } else if (strncasecmp(key,"wspids_port",29)==0) {
00231 main.wspids_port=atoi(value);
00232 return &main.wspids_port;
00233 } else if (strncasecmp(key,"headControl_port",29)==0) {
00234 main.headControl_port=atoi(value);
00235 return &main.headControl_port;
00236 } else if (strncasecmp(key,"walkControl_port",29)==0) {
00237 main.walkControl_port=atoi(value);
00238 return &main.walkControl_port;
00239 } else if (strncasecmp(key,"estopControl_port",29)==0) {
00240 main.estopControl_port=atoi(value);
00241 return &main.estopControl_port;
00242 } else if (strncasecmp(key,"aibo3d_port",29)==0) {
00243 main.aibo3d_port=atoi(value);
00244 return &main.aibo3d_port;
00245 } else if (strncasecmp(key,"wmmonitor_port",29)==0) {
00246 main.wmmonitor_port=atoi(value);
00247 return &main.wmmonitor_port;
00248 } else if (strncasecmp(key,"use_VT100",29)==0) {
00249 main.use_VT100=extractBool(value);
00250 return &main.use_VT100;
00251 }
00252 break;
00253 case sec_behaviors:
00254 break;
00255 case sec_controller:
00256 if (strncasecmp(key,"gui_port",29)==0) {
00257 controller.gui_port = atoi(value);
00258 return &controller.gui_port ;
00259 } else if (strncasecmp(key,"select_snd",29)==0) {
00260 strncpy(controller.select_snd,value,49);
00261 return &controller.select_snd;
00262 } else if (strncasecmp(key,"next_snd",29)==0) {
00263 strncpy(controller.next_snd,value,49);
00264 return &controller.next_snd;
00265 } else if (strncasecmp(key,"prev_snd",29)==0) {
00266 strncpy(controller.prev_snd,value,49);
00267 return &controller.prev_snd;
00268 } else if (strncasecmp(key,"read_snd",29)==0) {
00269 strncpy(controller.read_snd,value,49);
00270 return &controller.read_snd;
00271 } else if (strncasecmp(key,"cancel_snd",29)==0) {
00272 strncpy(controller.cancel_snd,value,49);
00273 return &controller.cancel_snd;
00274 } else if (strncasecmp(key,"error_snd",29)==0) {
00275 strncpy(controller.error_snd,value,49);
00276 return &controller.error_snd;
00277 }
00278 break;
00279 case sec_motion:
00280 if (strncasecmp(key,"root",29)==0) {
00281 motion.root=value;
00282 return &motion.root;
00283 } else if (strncasecmp(key,"walk",29)==0) {
00284 motion.walk=value;
00285 return &motion.walk;
00286 } else if (strncasecmp(key,"kinematics",29)==0) {
00287 motion.kinematics=value;
00288 return &motion.walk;
00289 } else if (strncasecmp(key,"kinematic_chains",29)==0) {
00290 motion.kinematic_chains.push_back(value);
00291 return &motion.kinematic_chains;
00292 } else if (strncasecmp(key,"calibrate:",10)==0) {
00293 for(unsigned int i=PIDJointOffset; i<PIDJointOffset+NumPIDJoints; i++)
00294 if(strncasecmp(&key[10],outputNames[i],outputNameLen+1)==0) {
00295 motion.calibration[i-PIDJointOffset] = atof(value);
00296 return &motion.calibration[i];
00297 }
00298 std::cout << "WARNING: Could not match '" << (strlen(key)>10?&key[10]:key) << "' as calibration parameter" << std::endl;
00299 return NULL;
00300 } else if (strncasecmp(key,"estop_on_snd",29)==0) {
00301 strncpy(motion.estop_on_snd,value,49);
00302 return &motion.estop_on_snd;
00303 } else if (strncasecmp(key,"estop_off_snd",29)==0) {
00304 strncpy(motion.estop_off_snd,value,49);
00305 return &motion.estop_off_snd;
00306 } else if (strncasecmp(key,"max_head_tilt_speed",29)==0) {
00307 motion.max_head_tilt_speed=atof(value);
00308 return &motion.max_head_tilt_speed;
00309 } else if (strncasecmp(key,"max_head_pan_speed",29)==0) {
00310 motion.max_head_pan_speed=atof(value);
00311 return &motion.max_head_pan_speed;
00312 } else if (strncasecmp(key,"max_head_roll_speed",29)==0) {
00313 motion.max_head_roll_speed=atof(value);
00314 return &motion.max_head_roll_speed;
00315 } else if (strncasecmp(key,"console_port",29)==0) {
00316 motion.console_port = atoi(value);
00317 return &motion.console_port;
00318 } else if (strncasecmp(key,"stderr_port",29)==0) {
00319 motion.stderr_port = atoi(value);
00320 return &motion.stderr_port ;
00321 }
00322 break;
00323 case sec_sound:
00324 if (strncasecmp(key,"root",29)==0) {
00325 sound.root=value;
00326 return &sound.root;
00327 } else if (strncasecmp(key,"volume",29)==0) {
00328 if(strncasecmp(value,"mute",49)==0)
00329 sound.volume=ospkvolinfdB;
00330 else if(strncasecmp(value,"level_1",49)==0)
00331 sound.volume=ospkvol25dB;
00332 else if(strncasecmp(value,"level_2",49)==0)
00333 sound.volume=ospkvol18dB;
00334 else if(strncasecmp(value,"level_3",49)==0)
00335 sound.volume=ospkvol10dB;
00336 else
00337 sound.volume=strtol(value,NULL,0);
00338 return &sound.volume;
00339 } else if (strncasecmp(key,"sample_rate",29)==0) {
00340 sound.sample_rate = atoi(value);
00341 return &sound.sample_rate ;
00342 } else if (strncasecmp(key,"sample_bits",29)==0) {
00343 sound.sample_bits = atoi(value);
00344 return &sound.sample_bits ;
00345 } else if (strncasecmp(key,"preload",29)==0) {
00346 sound.preload.push_back(value);
00347 return &sound.preload ;
00348 } else if (strncasecmp(key,"streaming.mic_port",29)==0) {
00349 sound.streaming.mic_port = atoi(value);
00350 return &sound.streaming.mic_port;
00351 } else if (strncasecmp(key,"streaming.mic_sample_rate",29)==0) {
00352 sound.streaming.mic_sample_rate = atoi(value);
00353 return &sound.streaming.mic_sample_rate;
00354 } else if (strncasecmp(key,"streaming.mic_sample_bits",29)==0) {
00355 sound.streaming.mic_sample_bits = atoi(value);
00356 return &sound.streaming.mic_sample_bits;
00357 } else if (strncasecmp(key,"streaming.mic_stereo",29)==0) {
00358 sound.streaming.mic_stereo = extractBool(value);
00359 return &sound.streaming.mic_stereo;
00360 } else if (strncasecmp(key,"streaming.speaker_port",29)==0) {
00361 sound.streaming.speaker_port = atoi(value);
00362 return &sound.streaming.speaker_port;
00363 } else if (strncasecmp(key,"streaming.speaker_frame_length",30)==0) {
00364 sound.streaming.speaker_frame_length = atoi(value);
00365 return &sound.streaming.speaker_frame_length;
00366 } else if (strncasecmp(key,"streaming.speaker_max_delay",29)==0) {
00367 sound.streaming.speaker_max_delay = atoi(value);
00368 return &sound.streaming.speaker_max_delay;
00369 }
00370 break;
00371 default:
00372 break;
00373 }
00374 return NULL;
00375 }
00376
00377 Config::section_t Config::parseSection(const char* key) {
00378 if (strncasecmp(key,"wireless",29)==0) {
00379 return sec_wireless;
00380 } else if (strncasecmp(key,"vision",29)==0) {
00381 return sec_vision;
00382 } else if (strncasecmp(key,"main",29)==0) {
00383 return sec_main;
00384 } else if (strncasecmp(key,"behaviors",29)==0) {
00385 return sec_behaviors;
00386 } else if (strncasecmp(key,"controller",29)==0) {
00387 return sec_controller;
00388 } else if (strncasecmp(key,"motion",29)==0) {
00389 return sec_motion;
00390 } else if (strncasecmp(key,"sound",29)==0) {
00391 return sec_sound;
00392 } else {
00393 return sec_invalid;
00394 }
00395 }
00396
00397 void Config::readConfig(const char* filename) {
00398 FILE* fp = fopen(filename, "r");
00399 char buf[80], key[30], value[50];
00400 section_t section=sec_invalid;
00401 if (fp==NULL) return;
00402
00403 bool ignoring=false;
00404 std::vector<std::string> curmodel;
00405 #ifdef PLATFORM_APERIOS
00406 char rdStr[orobotdesignNAME_MAX + 1];
00407 memset(rdStr, 0, sizeof(rdStr));
00408 if (OPENR::GetRobotDesign(rdStr) != oSUCCESS) {
00409 printf("OPENR::GetRobotDesign() failed.\n");
00410 rdStr[0]='\0';
00411 }
00412 #else
00413 # if TGT_ERS7
00414 char rdStr[]="ERS-7";
00415 # elif TGT_ERS210
00416 char rdStr[]="ERS-210";
00417 # elif TGT_ERS220
00418 char rdStr[]="ERS-220";
00419 # elif TGT_ERS2xx
00420 # warning "TGT_2xx is not specific for simulation purposes - defaulting to ERS210"
00421 char rdStr[]="ERS-210";
00422 # else
00423 # warning "TGT_<model> undefined - defaulting to ERS210"
00424 char rdStr[]="ERS-210";
00425 # endif
00426 #endif
00427
00428
00429 unsigned int lineno=0;
00430 while (fscanf(fp,"%79[^\n]\n", buf)!=EOF) {
00431 lineno++;
00432 if (sscanf(buf,"<%29[^>]>",key)>0) {
00433 if(key[0]=='/') {
00434 if(curmodel.size()==0) {
00435 printf("WARNING: not in a model specific section, line %d\n",lineno);
00436 continue;
00437 }
00438 bool subset=matchNoCase(&key[1],curmodel.back());
00439 bool superset=matchNoCase(curmodel.back(),&key[1]);
00440 if(subset && superset) {
00441
00442 curmodel.pop_back();
00443 } else if(superset) {
00444 while(curmodel.size()>0) {
00445
00446 curmodel.pop_back();
00447 if(!matchNoCase(curmodel.back(),&key[1]))
00448 break;
00449 }
00450 } else
00451 printf("WARNING: config model mismatch, line %d\n",lineno);
00452
00453 ignoring=false;
00454 for(unsigned int i=0; i<curmodel.size(); i++)
00455 if(!matchNoCase(rdStr,curmodel[i])) {
00456 ignoring=true;
00457 break;
00458 }
00459
00460
00461 } else {
00462 curmodel.push_back(key);
00463
00464 ignoring=ignoring || !matchNoCase(rdStr,key);
00465
00466 }
00467 } else if(!ignoring) {
00468 if (sscanf(buf,"[%29[^]]]",key)>0) {
00469 section=parseSection(key);
00470
00471 } else if (sscanf(buf,"%29[^=]=%49s",key,value)>1) {
00472
00473 setValue(section, key, value);
00474 }
00475 }
00476 }
00477 fclose(fp);
00478 }
00479
00480 bool Config::matchNoCase(const std::string& model, const std::string& pattern) {
00481 unsigned int i=0;
00482 if(i==pattern.size() && i==model.size())
00483 return true;
00484 if(i==pattern.size() || i==model.size())
00485 return false;
00486 while(pattern[i]!='*') {
00487 if(toupper(pattern[i])!=toupper(model[i]))
00488 return false;
00489 i++;
00490 if(i==pattern.size() && i==model.size())
00491 return true;
00492 if(i==pattern.size() || i==model.size())
00493 return false;
00494 }
00495 i=pattern.size()-1;
00496 unsigned int j=model.size()-1;
00497 while(pattern[i]!='*') {
00498 if(toupper(pattern[i])!=toupper(model[j]))
00499 return false;
00500 i--; j--;
00501 }
00502 return true;
00503 }
00504
00505 bool Config::extractBool(const char * value) {
00506 int i=0;
00507 while(isspace(value[i])) i++;
00508 if(strncasecmp(&value[i],"t",29)==0)
00509 return true;
00510 else if(strncasecmp(&value[i],"f",29)==0)
00511 return false;
00512 else if(strncasecmp(&value[i],"true",29)==0)
00513 return true;
00514 else if(strncasecmp(&value[i],"false",29)==0)
00515 return false;
00516 else if(strncasecmp(&value[i],"y",29)==0)
00517 return true;
00518 else if(strncasecmp(&value[i],"n",29)==0)
00519 return false;
00520 else if(strncasecmp(&value[i],"yes",29)==0)
00521 return true;
00522 else if(strncasecmp(&value[i],"no",29)==0)
00523 return false;
00524 else
00525 return atoi(value);
00526 }
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538