00001
00002
00003 #include "ace/Configuration_Import_Export.h"
00004 #include "ace/OS_Errno.h"
00005 #include "ace/OS_NS_stdio.h"
00006 #include "ace/OS_NS_ctype.h"
00007 #include "ace/OS_NS_string.h"
00008
00009 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00010
00011 ACE_Config_ImpExp_Base::ACE_Config_ImpExp_Base (ACE_Configuration& config)
00012 : config_ (config)
00013 {
00014 }
00015
00016 ACE_Config_ImpExp_Base::~ACE_Config_ImpExp_Base (void)
00017 {
00018 }
00019
00020 ACE_Registry_ImpExp::ACE_Registry_ImpExp (ACE_Configuration& config)
00021 : ACE_Config_ImpExp_Base (config)
00022 {
00023 }
00024
00025 ACE_Registry_ImpExp::~ACE_Registry_ImpExp (void)
00026 {
00027 }
00028
00029
00030
00031 int
00032 ACE_Registry_ImpExp::import_config (const ACE_TCHAR* filename)
00033 {
00034 if (0 == filename)
00035 {
00036 errno = EINVAL;
00037 return -1;
00038 }
00039 FILE* in = ACE_OS::fopen (filename, ACE_TEXT ("r"));
00040 if (!in)
00041 return -1;
00042
00043 u_int buffer_size = 4096;
00044 u_int read_pos = 0;
00045 ACE_TCHAR *buffer = 0;
00046 ACE_NEW_NORETURN (buffer, ACE_TCHAR[buffer_size]);
00047 if (!buffer)
00048 {
00049 ACE_Errno_Guard guard (errno);
00050 (void) ACE_OS::fclose (in);
00051 return -1;
00052 }
00053 ACE_Configuration_Section_Key section;
00054 ACE_TCHAR *end = 0;
00055
00056 while (ACE_OS::fgets (buffer+read_pos, buffer_size - read_pos, in))
00057 {
00058
00059 end = ACE_OS::strrchr (buffer + read_pos,
00060 ACE_TEXT ('\n'));
00061 if (!end)
00062 {
00063
00064 ACE_TCHAR *temp_buffer;
00065 ACE_NEW_NORETURN (temp_buffer, ACE_TCHAR[buffer_size * 2]);
00066 if (!temp_buffer)
00067 {
00068 ACE_Errno_Guard guard (errno);
00069 delete [] buffer;
00070 (void) ACE_OS::fclose (in);
00071 return -1;
00072 }
00073
00074
00075 ACE_OS::memcpy (temp_buffer, buffer, buffer_size);
00076 read_pos = buffer_size - 1;
00077 buffer_size *= 2;
00078 delete [] buffer;
00079 buffer = temp_buffer;
00080 continue;
00081 }
00082 read_pos = 0;
00083
00084
00085 if (buffer[0] == ACE_TEXT (';') || buffer[0] == ACE_TEXT ('#'))
00086 continue;
00087
00088 if (buffer[0] == ACE_TEXT ('['))
00089 {
00090
00091 end = ACE_OS::strrchr (buffer, ACE_TEXT (']'));
00092 if (!end)
00093 {
00094 ACE_OS::fclose (in);
00095 delete [] buffer;
00096 return -3;
00097 }
00098 *end = 0;
00099
00100 if (config_.expand_path (config_.root_section (), buffer + 1, section, 1))
00101 {
00102 ACE_OS::fclose (in);
00103 delete [] buffer;
00104 return -3;
00105 }
00106 continue;
00107 }
00108
00109 if (buffer[0] == ACE_TEXT ('"'))
00110 {
00111
00112 end = ACE_OS::strchr (buffer+1, '"');
00113 if (!end)
00114 continue;
00115
00116
00117 *end = 0;
00118 ACE_TCHAR* name = buffer + 1;
00119 end+=2;
00120
00121 if (*end == '\"')
00122 {
00123
00124
00125 ++end;
00126 ACE_TCHAR* trailing = ACE_OS::strrchr (end, '"');
00127 if (trailing)
00128 *trailing = 0;
00129 if (config_.set_string_value (section, name, end))
00130 {
00131 ACE_OS::fclose (in);
00132 delete [] buffer;
00133 return -4;
00134 }
00135 }
00136 else if (ACE_OS::strncmp (end, ACE_TEXT ("dword:"), 6) == 0)
00137 {
00138
00139 ACE_TCHAR* endptr = 0;
00140 unsigned long value = ACE_OS::strtoul (end + 6, &endptr, 16);
00141 if (config_.set_integer_value (section, name, value))
00142 {
00143 ACE_OS::fclose (in);
00144 delete [] buffer;
00145 return -4;
00146 }
00147 }
00148 else if (ACE_OS::strncmp (end, ACE_TEXT ("hex:"), 4) == 0)
00149 {
00150
00151 size_t string_length = ACE_OS::strlen (end + 4);
00152
00153 size_t length = string_length / 3;
00154 size_t remaining = length;
00155 u_char* data = 0;
00156 ACE_NEW_RETURN (data,
00157 u_char[length],
00158 -1);
00159 u_char* out = data;
00160 ACE_TCHAR* inb = end + 4;
00161 ACE_TCHAR* endptr = 0;
00162 while (remaining)
00163 {
00164 u_char charin = (u_char) ACE_OS::strtoul (inb, &endptr, 16);
00165 *out = charin;
00166 ++out;
00167 --remaining;
00168 inb += 3;
00169 }
00170 if (config_.set_binary_value (section, name, data, length))
00171 {
00172 ACE_OS::fclose (in);
00173 delete [] data;
00174 delete [] buffer;
00175 return -4;
00176 }
00177 else
00178 delete [] data;
00179 }
00180 else
00181 {
00182
00183 continue;
00184 }
00185 }
00186 else
00187 {
00188
00189
00190
00191
00192 int rc = process_previous_line_format (buffer, section);
00193 if (rc != 0)
00194 {
00195 ACE_OS::fclose (in);
00196 delete [] buffer;
00197 return rc;
00198 }
00199 }
00200 }
00201
00202 if (ferror (in))
00203 {
00204 ACE_OS::fclose (in);
00205 delete [] buffer;
00206 return -1;
00207 }
00208
00209 ACE_OS::fclose (in);
00210 delete [] buffer;
00211 return 0;
00212 }
00213
00214
00215
00216
00217 int
00218 ACE_Registry_ImpExp::export_config (const ACE_TCHAR* filename)
00219 {
00220 if (0 == filename)
00221 {
00222 errno = EINVAL;
00223 return -1;
00224 }
00225 int result = -1;
00226
00227 FILE* out = ACE_OS::fopen (filename, ACE_TEXT ("w"));
00228 if (out)
00229 {
00230 result = this->export_section (config_.root_section (),
00231 ACE_TEXT (""),
00232 out);
00233
00234
00235 if (ACE_OS::fclose (out) < 0)
00236 result = -7;
00237 }
00238 return result;
00239 }
00240
00241
00242
00243
00244
00245 int
00246 ACE_Registry_ImpExp::export_section (const ACE_Configuration_Section_Key& section,
00247 const ACE_TString& path,
00248 FILE* out)
00249 {
00250
00251 if (path.length ())
00252 {
00253
00254 ACE_TString header = ACE_TEXT ("[");
00255 header += path;
00256 header += ACE_TEXT ("]");
00257 header += ACE_TEXT (" \n");
00258 if (ACE_OS::fputs (header.fast_rep (), out) < 0)
00259 return -1;
00260
00261 int index = 0;
00262 ACE_TString name;
00263 ACE_Configuration::VALUETYPE type;
00264 ACE_TString line;
00265 ACE_TCHAR int_value[32];
00266 ACE_TCHAR bin_value[3];
00267 void* binary_data;
00268 size_t binary_length;
00269 ACE_TString string_value;
00270 while (!config_.enumerate_values (section, index, name, type))
00271 {
00272 line = ACE_TEXT ("\"") + name + ACE_TEXT ("\"=");
00273 switch (type)
00274 {
00275 case ACE_Configuration::INTEGER:
00276 {
00277 u_int value;
00278 if (config_.get_integer_value (section, name.fast_rep (), value))
00279 return -2;
00280 ACE_OS::sprintf (int_value, ACE_TEXT ("%08x"), value);
00281 line += ACE_TEXT ("dword:");
00282 line += int_value;
00283 break;
00284 }
00285 case ACE_Configuration::STRING:
00286 {
00287 if (config_.get_string_value (section,
00288 name.fast_rep (),
00289 string_value))
00290 return -2;
00291 line += ACE_TEXT ("\"");
00292 line += string_value + ACE_TEXT ("\"");
00293 break;
00294 }
00295 #ifdef _WIN32
00296 case ACE_Configuration::INVALID:
00297 break;
00298
00299
00300 #endif
00301 case ACE_Configuration::BINARY:
00302 {
00303
00304 if (config_.get_binary_value (section,
00305 name.fast_rep (),
00306 binary_data,
00307 binary_length))
00308 return -2;
00309 line += ACE_TEXT ("hex:");
00310 unsigned char* ptr = (unsigned char*)binary_data;
00311 while (binary_length)
00312 {
00313 if (ptr != binary_data)
00314 {
00315 line += ACE_TEXT (",");
00316 }
00317 ACE_OS::sprintf (bin_value, ACE_TEXT ("%02x"), *ptr);
00318 line += bin_value;
00319 --binary_length;
00320 ++ptr;
00321 }
00322 delete [] (char*) binary_data;
00323 break;
00324 }
00325 default:
00326 return -3;
00327 }
00328 line += ACE_TEXT ("\n");
00329 if (ACE_OS::fputs (line.fast_rep (), out) < 0)
00330 return -4;
00331 ++index;
00332 }
00333 }
00334
00335 int index = 0;
00336 ACE_TString name;
00337 ACE_Configuration_Section_Key sub_key;
00338 ACE_TString sub_section;
00339 while (!config_.enumerate_sections (section, index, name))
00340 {
00341 ACE_TString sub_section (path);
00342 if (path.length ())
00343 sub_section += ACE_TEXT ("\\");
00344 sub_section += name;
00345 if (config_.open_section (section, name.fast_rep (), 0, sub_key))
00346 return -5;
00347 if (export_section (sub_key, sub_section.fast_rep (), out))
00348 return -6;
00349 ++index;
00350 }
00351 return 0;
00352 }
00353
00354
00355
00356
00357 int
00358 ACE_Registry_ImpExp::process_previous_line_format (ACE_TCHAR* buffer,
00359 ACE_Configuration_Section_Key& section)
00360 {
00361
00362 ACE_TCHAR *endp = ACE_OS::strpbrk (buffer, ACE_TEXT ("\r\n"));
00363 if (endp != 0)
00364 *endp = '\0';
00365
00366
00367 ACE_TCHAR* end = ACE_OS::strchr (buffer, '=');
00368 if (end)
00369 {
00370
00371 *end = 0;
00372 ++end;
00373
00374 if (*end == '\"')
00375 {
00376
00377 if(config_.set_string_value (section, buffer, end + 1))
00378 return -4;
00379 }
00380 else if (*end == '#')
00381 {
00382
00383 u_int value = ACE_OS::atoi (end + 1);
00384 if (config_.set_integer_value (section, buffer, value))
00385 return -4;
00386 }
00387 }
00388 return 0;
00389 }
00390
00391
00392 ACE_Ini_ImpExp::ACE_Ini_ImpExp (ACE_Configuration& config)
00393 : ACE_Config_ImpExp_Base (config)
00394 {
00395 }
00396
00397 ACE_Ini_ImpExp::~ACE_Ini_ImpExp (void)
00398 {
00399 }
00400
00401
00402 int
00403 ACE_Ini_ImpExp::import_config (const ACE_TCHAR* filename)
00404 {
00405 if (0 == filename)
00406 {
00407 errno = EINVAL;
00408 return -1;
00409 }
00410 FILE* in = ACE_OS::fopen (filename, ACE_TEXT ("r"));
00411 if (!in)
00412 return -1;
00413
00414
00415 ACE_TCHAR buffer[4096];
00416 ACE_Configuration_Section_Key section;
00417 while (ACE_OS::fgets (buffer, sizeof buffer, in))
00418 {
00419 ACE_TCHAR *line = this->squish (buffer);
00420
00421 if (line[0] == ACE_TEXT (';') ||
00422 line[0] == ACE_TEXT ('#') ||
00423 line[0] == '\0')
00424 continue;
00425
00426 if (line[0] == ACE_TEXT ('['))
00427 {
00428
00429 ACE_TCHAR* end = ACE_OS::strrchr (line, ACE_TEXT (']'));
00430 if (!end)
00431 {
00432 ACE_OS::fclose (in);
00433 return -3;
00434 }
00435 *end = 0;
00436
00437 if (config_.expand_path (config_.root_section (),
00438 line + 1,
00439 section,
00440 1))
00441 {
00442 ACE_OS::fclose (in);
00443 return -3;
00444 }
00445
00446 continue;
00447 }
00448
00449
00450 ACE_TCHAR *end = ACE_OS::strchr (line, ACE_TEXT ('='));
00451 if (end == 0)
00452 {
00453 ACE_OS::fclose (in);
00454 return -3;
00455 }
00456 *end++ = '\0';
00457 ACE_TCHAR *name = this->squish (line);
00458 #if 0
00459 if (ACE_OS::strlen (name) == 0)
00460 {
00461 ACE_OS::fclose (in);
00462 return -3;
00463 }
00464 #endif
00465
00466 ACE_TCHAR *value = this->squish (end);
00467 size_t value_len = ACE_OS::strlen (value);
00468 if (value_len > 0)
00469 {
00470
00471
00472
00473 if (value[0] == ACE_TEXT ('"') &&
00474 value[value_len - 1] == ACE_TEXT ('"'))
00475 {
00476
00477 value[value_len - 1] = '\0';
00478 ++value;
00479 }
00480 }
00481
00482 if (config_.set_string_value (section, name, value))
00483 {
00484 ACE_OS::fclose (in);
00485 return -4;
00486 }
00487 }
00488
00489 if (ferror (in))
00490 {
00491 ACE_OS::fclose (in);
00492 return -1;
00493 }
00494
00495 ACE_OS::fclose (in);
00496 return 0;
00497 }
00498
00499
00500
00501
00502 int
00503 ACE_Ini_ImpExp::export_config (const ACE_TCHAR* filename)
00504 {
00505 if (0 == filename)
00506 {
00507 errno = EINVAL;
00508 return -1;
00509 }
00510 int result = -1;
00511
00512 FILE* out = ACE_OS::fopen (filename, ACE_TEXT ("w"));
00513 if (out)
00514 {
00515 result = this->export_section (config_.root_section (),
00516 ACE_TEXT (""),
00517 out);
00518
00519
00520 if (ACE_OS::fclose (out) < 0)
00521 result = -7;
00522 }
00523 return result;
00524 }
00525
00526
00527
00528
00529
00530 int
00531 ACE_Ini_ImpExp::export_section (const ACE_Configuration_Section_Key& section,
00532 const ACE_TString& path,
00533 FILE* out)
00534 {
00535
00536 if (path.length ())
00537 {
00538
00539 ACE_TString header = ACE_TEXT ("[");
00540 header += path;
00541 header += ACE_TEXT ("]\n");
00542 if (ACE_OS::fputs (header.fast_rep (), out) < 0)
00543 return -1;
00544
00545 int index = 0;
00546 ACE_TString name;
00547 ACE_Configuration::VALUETYPE type;
00548 ACE_TString line;
00549 ACE_TCHAR int_value[32];
00550 ACE_TCHAR bin_value[3];
00551 void* binary_data;
00552 size_t binary_length;
00553 ACE_TString string_value;
00554 while (!config_.enumerate_values (section, index, name, type))
00555 {
00556 line = name + ACE_TEXT ("=");
00557 switch (type)
00558 {
00559 case ACE_Configuration::INTEGER:
00560 {
00561 u_int value;
00562 if (config_.get_integer_value (section, name.fast_rep (), value))
00563 return -2;
00564 ACE_OS::sprintf (int_value, ACE_TEXT ("%08x"), value);
00565 line += int_value;
00566 break;
00567 }
00568 case ACE_Configuration::STRING:
00569 {
00570 if (config_.get_string_value (section,
00571 name.fast_rep (),
00572 string_value))
00573 return -2;
00574 line += string_value;
00575 break;
00576 }
00577 #ifdef _WIN32
00578 case ACE_Configuration::INVALID:
00579 break;
00580
00581
00582 #endif
00583 case ACE_Configuration::BINARY:
00584 {
00585
00586 if (config_.get_binary_value (section,
00587 name.fast_rep (),
00588 binary_data,
00589 binary_length))
00590 return -2;
00591 line += ACE_TEXT ("\"");
00592 unsigned char* ptr = (unsigned char*)binary_data;
00593 while (binary_length)
00594 {
00595 if (ptr != binary_data)
00596 {
00597 line += ACE_TEXT (",");
00598 }
00599 ACE_OS::sprintf (bin_value, ACE_TEXT ("%02x"), *ptr);
00600 line += bin_value;
00601 --binary_length;
00602 ++ptr;
00603 }
00604 line += ACE_TEXT ("\"");
00605 delete [] (char *) binary_data;
00606 break;
00607 }
00608 default:
00609 return -3;
00610
00611 }
00612
00613 line += ACE_TEXT ("\n");
00614 if (ACE_OS::fputs (line.fast_rep (), out) < 0)
00615 return -4;
00616 ++index;
00617 }
00618 }
00619
00620 int index = 0;
00621 ACE_TString name;
00622 ACE_Configuration_Section_Key sub_key;
00623 ACE_TString sub_section;
00624 while (!config_.enumerate_sections (section, index, name))
00625 {
00626 ACE_TString sub_section (path);
00627 if (path.length ())
00628 sub_section += ACE_TEXT ("\\");
00629 sub_section += name;
00630 if (config_.open_section (section, name.fast_rep (), 0, sub_key))
00631 return -5;
00632 if (export_section (sub_key, sub_section.fast_rep (), out))
00633 return -6;
00634 ++index;
00635 }
00636 return 0;
00637
00638 }
00639
00640
00641
00642
00643
00644
00645
00646
00647 ACE_TCHAR *
00648 ACE_Ini_ImpExp::squish (ACE_TCHAR *src)
00649 {
00650 ACE_TCHAR *cp = 0;
00651
00652 if (src == 0)
00653 return 0;
00654
00655
00656 for (cp = src + ACE_OS::strlen (src) - 1;
00657 cp != src;
00658 --cp)
00659 if (!ACE_OS::ace_isspace (*cp))
00660 break;
00661 cp[1] = '\0';
00662
00663
00664 for (cp = src; ACE_OS::ace_isspace (*cp); ++cp)
00665 continue;
00666
00667 return cp;
00668 }
00669
00670 ACE_END_VERSIONED_NAMESPACE_DECL