00001 #ifndef ADDRESS_IMPLEMENTATION_FILE
00002 #define ADDRESS_IMPLEMENTATION_FILE
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "address.h"
00019 #include "imp_sockets.h"
00020 #include "machine_uid.h"
00021
00022 #include <basis/byte_array.h>
00023 #include <basis/function.h>
00024 #include <basis/istring.h>
00025 #include <basis/mutex.h>
00026 #include <data_struct/configurator.h>
00027 #include <data_struct/static_memory_gremlin.h>
00028 #include <data_struct/string_table.h>
00029 #include <textual/parser_bits.h>
00030 #include <textual/tokenizer.h>
00031
00032 #include <stdio.h>
00033 #include <string.h>
00034
00035 using namespace basis;
00036
00037
00038
00039
00041
00042 #undef LOG
00043 #define LOG(to_print) CLASS_EMERGENCY_LOG(program_wide_logger(), to_print)
00044
00046
00047 network_address::network_address()
00048 : _type(UNINITIALIZED_ADDRESS),
00049 _addr(NIL)
00050 {}
00051
00052 network_address::network_address(const network_address &to_copy)
00053 : packable(),
00054 _type(to_copy._type),
00055 _addr(to_copy._addr? to_copy._addr->create_copy() : NIL)
00056 {}
00057
00058 network_address::network_address(const internet_address &address)
00059 : _type(INTERNET_ADDRESS),
00060 _addr(address.create_copy())
00061 {}
00062
00063 #ifndef EMBEDDED_BUILD
00064
00065 network_address::network_address(const serial_port_address &address)
00066 : _type(SERIAL_PORT_ADDRESS),
00067 _addr(address.create_copy())
00068 {}
00069
00070 network_address::network_address(const ipc_address &address)
00071 : _type(IPC_ADDRESS),
00072 _addr(address.create_copy())
00073 {}
00074
00075 #endif
00076
00077 network_address::~network_address()
00078 {
00079 _type = UNINITIALIZED_ADDRESS;
00080 WHACK(_addr);
00081 }
00082
00083 network_address &network_address::operator =(const network_address &to_copy)
00084 {
00085 if (this == &to_copy) return *this;
00086 WHACK(_addr);
00087 _type = to_copy._type;
00088 if (to_copy._addr)
00089 _addr = to_copy._addr->create_copy();
00090 return *this;
00091 }
00092
00093 bool network_address::valid() const
00094 { return (_type > ADDRESS_SENTINEL_BEGIN) && (_type < ADDRESS_SENTINEL_END); }
00095
00096 internet_address *network_address::internet()
00097 { return dynamic_cast<internet_address *>(_addr); }
00098
00099 #ifndef EMBEDDED_BUILD
00100 serial_port_address *network_address::serial()
00101 { return dynamic_cast<serial_port_address *>(_addr); }
00102
00103 ipc_address *network_address::ipc()
00104 { return dynamic_cast<ipc_address *>(_addr); }
00105 #endif
00106
00107 const internet_address *network_address::internet() const
00108 { return dynamic_cast<const internet_address *>(_addr); }
00109
00110 #ifndef EMBEDDED_BUILD
00111 const serial_port_address *network_address::serial() const
00112 { return dynamic_cast<const serial_port_address *>(_addr); }
00113
00114 const ipc_address *network_address::ipc() const
00115 { return dynamic_cast<const ipc_address *>(_addr); }
00116 #endif
00117
00118 bool network_address::comparable(address_type a, address_type b) const
00119 {
00120 return (a == b);
00121
00122
00123 }
00124
00125 int network_address::packed_size() const
00126 {
00127 if (!_addr) return 0;
00128 return _addr->packed_size();
00129 }
00130
00131 bool network_address::same_host(const network_address &to_compare) const
00132 {
00133 FUNCDEF("same_host");
00134 if (!comparable(address_type(_type), address_type(to_compare._type)))
00135 return false;
00136 if (!_addr) return true;
00137 return _addr->same_host(*to_compare._addr);
00138 }
00139
00140 bool network_address::same_port(const network_address &to_compare) const
00141 {
00142 FUNCDEF("same_port");
00143 if (!comparable(address_type(_type), address_type(to_compare._type)))
00144 return false;
00145 if (!_addr) return true;
00146 return _addr->same_port(*to_compare._addr);
00147 }
00148
00149 bool network_address::shareable(const network_address &to_compare) const
00150 {
00151 if (! operator == (to_compare)) return false;
00152
00153
00154 if (!_addr) return false;
00155 return _addr->shareable(*to_compare._addr);
00156 }
00157
00158 bool network_address::operator == (const network_address &to_compare) const
00159 { return same_host(to_compare) && same_port(to_compare); }
00160
00161 istring network_address::text_for_type(address_type type)
00162 {
00163 istring to_return;
00164 switch (type) {
00165 case UNINITIALIZED_ADDRESS: return "Uninitialized";
00166 case IPC_ADDRESS: return "IPC";
00167 case INTERNET_ADDRESS: return "TCP/IP";
00168 case SERIAL_PORT_ADDRESS: return "Serial_Port";
00169 default:
00170 return isprintf("unknown address type %d", type);
00171 }
00172 }
00173
00174 #define APPROX(t) (t.lower()).substring(0, 2)
00175
00176 network_address::address_type network_address::type_from_text
00177 (const istring &text)
00178 {
00179 if (APPROX(text) == APPROX(text_for_type(IPC_ADDRESS)))
00180 return IPC_ADDRESS;
00181 if (APPROX(text) == APPROX(text_for_type(INTERNET_ADDRESS)))
00182 return INTERNET_ADDRESS;
00183 if (APPROX(text) == APPROX(text_for_type(SERIAL_PORT_ADDRESS)))
00184 return SERIAL_PORT_ADDRESS;
00185 return UNINITIALIZED_ADDRESS;
00186 }
00187
00188 istring network_address::text_form(bool show_type) const
00189 {
00190 istring to_return;
00191 if (show_type) {
00192 istring type_to_print(text_for_type(type()));
00193 if (_addr) type_to_print += " ";
00194
00195 to_return += type_to_print;
00196 }
00197 if (_addr) to_return += _addr->text_form();
00198 return to_return;
00199 }
00200
00201 istring network_address::unified_hostname() const
00202 {
00203 istring to_return;
00204 if (type() == network_address::INTERNET_ADDRESS) {
00205 to_return = internet()->normalize_host();
00206 } else if (type() == network_address::IPC_ADDRESS) {
00207 to_return = "local";
00208 } else {
00209 to_return = "n/a";
00210 }
00211 return to_return;
00212 }
00213
00214 istring network_address::tokenize() const
00215 {
00216 istring to_return("type");
00217 to_return += TOKEN_ASSIGN();
00218 to_return += text_for_type(type());
00219
00220 if (_addr) {
00221 to_return += TOKEN_SEPARATOR();
00222 to_return += ' ';
00223 to_return += _addr->tokenize();
00224 }
00225 return to_return;
00226 }
00227
00228
00229 #define FILL(addr_type) { \
00230 addr_type *low = new addr_type; \
00231 worked = low->detokenize(info); \
00232 if (worked) _addr = low; \
00233 else WHACK(low); \
00234 break; \
00235 }
00236
00237 bool network_address::detokenize(const istring &info)
00238 {
00239 FUNCDEF("detokenize");
00240
00241 _type = UNINITIALIZED_ADDRESS;
00242 WHACK(_addr);
00243
00244 int first_sep = info.find(TOKEN_SEPARATOR());
00245 if (negative(first_sep))
00246 first_sep = info.length();
00247
00248 int first_assign = info.find(TOKEN_ASSIGN());
00249 if (negative(first_assign)) return false;
00250
00251
00252
00253 istring type_tag = info.substring(0, first_assign - 1);
00254 type_tag.strip_spaces();
00255 if (type_tag.lower() != istring("type")) return false;
00256
00257
00258 istring type_name = info.substring(first_assign + 1, first_sep - 1);
00259 type_name.strip_spaces();
00260
00261 bool worked = false;
00262
00263 _type = type_from_text(type_name);
00264 switch (_type) {
00265 case UNINITIALIZED_ADDRESS: worked = true; break;
00266 case INTERNET_ADDRESS: FILL(internet_address);
00267 #ifndef EMBEDDED_BUILD
00268 case SERIAL_PORT_ADDRESS: FILL(serial_port_address);
00269 case IPC_ADDRESS: FILL(ipc_address);
00270 #endif
00271 default: {
00272 LOG(isprintf("unknown type %d.", _type));
00273 break;
00274 }
00275 }
00276 return worked;
00277 }
00278
00279
00280
00281 network_address network_address::load(configurator &config,
00282 const istring §ion, const istring &name, const network_address &def)
00283 {
00284 istring token_list;
00285 if (!config.get(section, name, token_list)) {
00286
00287 config.put(section, name, def.tokenize());
00288 return def;
00289 }
00290 network_address to_return;
00291
00292 if (to_return.detokenize(token_list)) return to_return;
00293
00294
00295
00296
00297 return network_address();
00298 }
00299
00300 bool network_address::store(configurator &config, const istring §ion,
00301 const istring &name, const network_address &to_store)
00302 {
00303 istring text = to_store.tokenize();
00304 return config.put(section, name, text);
00305 }
00306
00307 void network_address::parse_pack(byte_array &packed_form) const
00308 { tokenize().pack(packed_form); }
00309
00310 bool network_address::parse_unpack(byte_array &packed_form)
00311 {
00312 istring tokenized;
00313 if (!tokenized.unpack(packed_form)) return false;
00314 if (!detokenize(tokenized)) return false;
00315 return true;
00316 }
00317
00318 machine_uid network_address::convert() const
00319 {
00320 if (!_addr) return machine_uid();
00321 return _addr->convert();
00322 }
00323
00324 void network_address::pack(byte_array &packed_form) const
00325 {
00326 attach(packed_form, int(_type));
00327 if (_addr) _addr->pack(packed_form);
00328 }
00329
00330 bool network_address::unpack(byte_array &packed_form)
00331 {
00332 FUNCDEF("unpack");
00333
00334 WHACK(_addr);
00335 _type = UNINITIALIZED_ADDRESS;
00336 int type;
00337 if (!detach(packed_form, type)) return false;
00338 _type = type;
00339 switch (_type) {
00340 case UNINITIALIZED_ADDRESS: return true;
00341 case INTERNET_ADDRESS: _addr = new internet_address(); break;
00342 #ifndef EMBEDDED_BUILD
00343 case SERIAL_PORT_ADDRESS: _addr = new serial_port_address(); break;
00344 case IPC_ADDRESS: _addr = new ipc_address(); break;
00345 #endif
00346 default: {
00347 LOG(isprintf("unknown type %d.", _type));
00348 return false;
00349 }
00350 }
00351 bool to_return = _addr->unpack(packed_form);
00352 if (!to_return) {
00353 _type = UNINITIALIZED_ADDRESS;
00354 WHACK(_addr);
00355 }
00356 return to_return;
00357 }
00358
00360
00361
00362
00363 #define CAST_UP(type) \
00364 const type *temp = dynamic_cast<const type *>(&compare_in); \
00365 if (!temp) return false; \
00366 const type &to_compare = *temp;
00367
00369
00370 internet_address::internet_address() { fill(byte_array(), "", 0); }
00371
00372 internet_address::internet_address(const byte_array &ip,
00373 const istring &host, int port_in)
00374 { fill(ip, host, port_in); }
00375
00376
00377
00378
00379
00380 machine_uid internet_address::convert() const
00381 { return internet_machine_uid(hostname, byte_array(ADDRESS_SIZE, ip_address)); }
00382
00383 bool internet_address::ip_appropriate_number(const istring &to_check, int indy,
00384 istring &accum)
00385 {
00386 FUNCDEF("ip_appropriate_number");
00387 accum.reset();
00388 for (int i = indy; (i < indy + 3) && (i < to_check.length()); i++) {
00389
00390 if (!parser_bits::is_numeric(to_check[i]) || (to_check[i] == '-') ) {
00391
00392
00393 if (i == indy) return false;
00394 else break;
00395 }
00396 accum += to_check[i];
00397 }
00398 if (!accum.length()) return false;
00399 int convert = accum.convert(-1);
00400 return (convert >= 0) && (convert <= 255);
00401 }
00402
00403
00404
00405 bool internet_address::has_ip_address(const istring &to_check,
00406 istring &ip_found)
00407 {
00408 FUNCDEF("has_ip_address");
00409 int nums_seen = 0;
00410 ip_found.reset();
00411 for (int i = 0; i < to_check.length(); i++) {
00412 bool hosed = false;
00413 istring num_found;
00414
00415 if (!ip_appropriate_number(to_check, i, num_found)) {
00416
00417 hosed = true;
00418 } else {
00419
00420
00421 nums_seen++;
00422 if (nums_seen >= 4) {
00423 ip_found += num_found;
00424 return true;
00425 }
00426
00427 int period_indy = to_check.find('.', i);
00428 if (negative(period_indy) || (period_indy > i + 3) ) hosed = true;
00429 else {
00430 for (int x = i; x < period_indy; x++) {
00431 if (!parser_bits::is_numeric(to_check[x]) || (to_check[x] == '-')) {
00432
00433 hosed = true;
00434 }
00435 }
00436 if (!hosed) {
00437 ip_found += to_check.substring(i, period_indy);
00438 i = period_indy;
00439 }
00440 }
00441 }
00442 if (hosed) {
00443 nums_seen = 0;
00444 ip_found.reset();
00445 }
00446 }
00447 return false;
00448 }
00449
00450 const byte localhosts_bytes[] = { 127, 0, 0, 1 };
00451 SAFE_STATIC_CONST(byte_array, internet_address::localhost,
00452 (ADDRESS_SIZE, localhosts_bytes))
00453
00454 bool internet_address::is_localhost() const
00455 {
00456
00457 istring host = hostname;
00458 host.to_lower();
00459 if ( (host == "local") || (host == "localhost") )
00460 return true;
00461
00462
00463 for (int i = 0; i < ADDRESS_SIZE; i++) {
00464 if (ip_address[i] != localhost().get(i))
00465 return false;
00466 }
00467
00468 return true;
00469 }
00470
00471 istring internet_address::normalize_host() const
00472 {
00473
00474 istring remote = hostname;
00475 if (remote.t()) return remote;
00476
00477 byte_array ip_form(ADDRESS_SIZE, ip_address);
00478 remote = ip_address_text_form(ip_form);
00479 return remote;
00480 }
00481
00482 int internet_address::packed_size() const
00483 {
00484 return sizeof(port) +
00485 + sizeof(int) + ADDRESS_SIZE
00486 + sizeof(int) + MAXIMUM_HOSTNAME_LENGTH;
00487 }
00488
00489 void internet_address::pack(byte_array &packed_form) const
00490 {
00491 attach(packed_form, port);
00492 packed_form += byte_array(ADDRESS_SIZE, ip_address);
00493 packed_form += byte_array(MAXIMUM_HOSTNAME_LENGTH, (byte *)hostname);
00494 }
00495
00496 bool internet_address::unpack(byte_array &packed_form)
00497 {
00498
00499 if (packed_form.length() < int(sizeof(port)) + ADDRESS_SIZE
00500 + MAXIMUM_HOSTNAME_LENGTH)
00501 return false;
00502 if (!detach(packed_form, port)) return false;
00503 packed_form.stuff(ADDRESS_SIZE, ip_address);
00504 packed_form.zap(0, ADDRESS_SIZE - 1);
00505 packed_form.stuff(MAXIMUM_HOSTNAME_LENGTH, (byte *)hostname);
00506 packed_form.zap(0, MAXIMUM_HOSTNAME_LENGTH - 1);
00507 return true;
00508 }
00509
00510 void internet_address::fill(const byte_array &ip, const istring &host,
00511 int port_in)
00512 {
00513 port = port_in;
00514 int mini = minimum(int(ADDRESS_SIZE), ip.length());
00515 for (int i = 0; i < mini; i++) ip_address[i] = ip[i];
00516 for (int j = mini; j < ADDRESS_SIZE; j++) ip_address[j] = 0;
00517 hostname[0] = '\0';
00518 host.stuff(hostname, MAXIMUM_HOSTNAME_LENGTH - 1);
00519 }
00520
00521 address_base *internet_address::create_copy() const
00522 {
00523 return new internet_address(byte_array(ADDRESS_SIZE, ip_address),
00524 hostname, port);
00525 }
00526
00527 istring internet_address::text_form() const
00528 {
00529 istring to_print("[");
00530 if (istring(hostname).t()) {
00531 to_print += "host=";
00532 to_print += hostname;
00533 to_print += ", ";
00534 }
00538 to_print += "ip_addr=";
00539 for (int i = 0; i < ADDRESS_SIZE; i++) {
00540 to_print += isprintf("%d", int(ip_address[i]));
00541 if (i != ADDRESS_SIZE - 1) to_print += ".";
00542 }
00543 to_print += ", ";
00545 to_print += isprintf("port=%u]", port);
00546 return to_print;
00547 }
00548
00549 bool internet_address::is_nil_address(const address_array &ip_address)
00550 {
00551 for (int i = 0; i < ADDRESS_SIZE; i++) if (ip_address[i]) return false;
00552 return true;
00553 }
00554
00555 const byte nil_address_bytes[] = { 0, 0, 0, 0 };
00556 SAFE_STATIC_CONST(byte_array, internet_address::nil_address,
00557 (ADDRESS_SIZE, nil_address_bytes))
00558
00559 bool internet_address::is_nil_address() const
00560 { return is_nil_address(ip_address); }
00561
00562 bool internet_address::same_host(const address_base &compare_in) const
00563 {
00564 CAST_UP(internet_address);
00565
00566
00567
00568
00569
00570 if ( (is_nil_address(ip_address) && is_nil_address(to_compare.ip_address))
00571 && !istring(hostname) && !istring(to_compare.hostname) )
00572 return true;
00573 if ( (is_nil_address(ip_address) && is_nil_address(to_compare.ip_address))
00574 && (istring(hostname).iequals(to_compare.hostname)) )
00575 return true;
00576 if (is_nil_address(ip_address)) return false;
00577 if (is_nil_address(to_compare.ip_address)) return false;
00578
00579
00580 for (int i = 0; i < ADDRESS_SIZE; i++)
00581 if (ip_address[i] != to_compare.ip_address[i])
00582 return false;
00583
00584
00585
00586 if (istring(hostname).t() && istring(to_compare.hostname).t()) {
00587
00588 if (istring(hostname).lower() != istring(to_compare.hostname).lower())
00589 return false;
00590 }
00591
00592 return true;
00593
00594 }
00595
00596 bool internet_address::same_port(const address_base &compare_in) const
00597 {
00598 CAST_UP(internet_address);
00599 return port == to_compare.port;
00600 }
00601
00602 bool internet_address::shareable(const address_base &) const
00603 { return true; }
00604
00605 bool internet_address::detokenize(const istring &info)
00606 {
00607 FUNCDEF("detokenize");
00608 LOADER_ENTRY;
00609
00610
00611 FIND("address", addr);
00612 #ifdef DEBUG_ADDRESS
00613 LOG(istring("info is ") + info + istring('.'));
00614 LOG(istring("addr is ") + addr);
00615 #endif
00616 byte_array ip_found;
00617 if (addr.t()) {
00618
00619
00620 for (int i = 0; i < ADDRESS_SIZE; i++) {
00621 #ifdef DEBUG_ADDRESS
00622 LOG(istring("ip curr: ") + addr);
00623 #endif
00624 int current_byte = addr.convert(int(0));
00625 ip_found += byte(current_byte);
00626 #ifdef DEBUG_ADDRESS
00627 LOG(isprintf("%d: %02x ", i, current_byte));
00628 #endif
00629 int indy = addr.find('.');
00630 addr.zap(0, indy);
00631 }
00632 }
00633
00634 FIND("host", host);
00635 GRAB("port", port_t);
00636 int port = port_t.convert(0);
00637 fill(ip_found, host, port);
00638 #ifdef DEBUG_ADDRESS
00639 LOG(istring("tcp/ip address found::: ") + text_form());
00640 #endif
00641 LOADER_EXIT;
00642 return true;
00643 }
00644
00645 istring internet_address::tokenize() const
00646 {
00647 FUNCDEF("tokenize");
00648 STORER_ENTRY;
00649 #ifdef DEBUG_ADDRESS
00650 LOG(istring(isprintf("host eval is %d for %s",
00651 istring(hostname).t(), hostname));
00652 #endif
00653 if (istring(hostname).t()) ADD("host", hostname);
00654 bool print_ip = false;
00655 for (int i = 0; i < ADDRESS_SIZE; i++) if (ip_address[i]) print_ip = true;
00656 if (print_ip) {
00657 istring ip_addr;
00658 for (int i = 0; i < ADDRESS_SIZE; i++)
00659 ip_addr += isprintf("%d", int(ip_address[i])) + istring(".");
00660 ip_addr.zap(ip_addr.end(), ip_addr.end());
00661 ADD("address", ip_addr);
00662 }
00663 ADD("port", isprintf("%d", int(port)));
00664 #ifdef DEBUG_ADDRESS
00665 LOG(istring("your toke's currently ") + fred.text_form());
00666 #endif
00667 DUMP_EXIT;
00668 }
00669
00670
00671
00672 bool internet_address::is_valid_internet_address(const istring &to_check,
00673 byte_array &ip_form, bool &all_zeros)
00674 {
00675 istring tmpstr = to_check;
00676 all_zeros = true;
00677 ip_form.reset();
00678
00679
00680 char *p = strtok(tmpstr.s(), ".");
00681
00682 int index = 0;
00683 while (p && (index < ADDRESS_SIZE)) {
00684 int nTemp = istring(p).convert(-1);
00685
00686
00687 if ( (nTemp < 0) || (nTemp > 255) ) return false;
00688
00689
00690 ip_form += (byte)nTemp;
00691
00692
00693 p = strtok(NIL, ".");
00694 }
00695
00696
00697 if (p) return false;
00698
00699 for (int i = 0; i < ip_form.length(); i++)
00700 if (ip_form[i]) { all_zeros = false; break; }
00701
00702 return ip_form.length() == ADDRESS_SIZE;
00703 }
00704
00705 bool internet_address::valid_address(const istring &to_check)
00706 {
00707 byte_array addr;
00708 bool all_zeros;
00709 return is_valid_internet_address(to_check, addr, all_zeros);
00710 }
00711
00712 istring internet_address::ip_address_text_form(const byte_array &ip_address)
00713 {
00714 return isprintf("%d.%d.%d.%d", int(ip_address[0]),
00715 int(ip_address[1]), int(ip_address[2]), int(ip_address[3]));
00716 }
00717
00718 #ifndef EMBEDDED_BUILD
00719
00721
00722 serial_port_address::serial_port_address() { fill(1, 9600, 8, 'N', 1); }
00723
00724 serial_port_address::serial_port_address(int port_in, int baud_rate_in,
00725 byte data_bits_in, char parity_in, byte stop_bits_in)
00726 { fill(port_in, baud_rate_in, data_bits_in, parity_in, stop_bits_in); }
00727
00728 address_base *serial_port_address::create_copy() const
00729 {
00730 return new serial_port_address(port, baud_rate, data_bits, parity, stop_bits);
00731 }
00732
00733 machine_uid serial_port_address::convert() const { return machine_uid(); }
00734
00735 istring serial_port_address::GET_DSR() { return "get_dsr"; }
00736
00737 istring serial_port_address::GET_CTS() { return "get_cts"; }
00738
00739 istring serial_port_address::SET_DTR() { return "set_dtr"; }
00740
00741 istring serial_port_address::SET_RTS() { return "set_rts"; }
00742
00743 istring serial_port_address::USE_MARK_SPACE() { return "mark_space"; }
00744
00745 istring serial_port_address::text_form() const
00746 {
00747 return isprintf("[port %d, baud %d, data %d, parity %c, stop %d]",
00748 port, baud_rate, int(data_bits), parity, int(stop_bits));
00749 }
00750
00751 bool serial_port_address::same_host(const address_base &) const
00752 { return true; }
00753
00754 bool serial_port_address::same_port(const address_base &compare_in) const
00755 {
00756 CAST_UP(serial_port_address);
00757 return port == to_compare.port;
00758 }
00759
00760 bool serial_port_address::shareable(const address_base &compare_in) const
00761 {
00762 CAST_UP(serial_port_address);
00763 if (baud_rate != to_compare.baud_rate) return false;
00764 if (data_bits != to_compare.data_bits) return false;
00765 if (parity != to_compare.parity) return false;
00766 if (stop_bits != to_compare.stop_bits) return false;
00767 return true;
00768 }
00769
00770 int serial_port_address::packed_size() const
00771 {
00772 return sizeof(port) + sizeof(baud_rate) + sizeof(data_bits)
00773 + sizeof(stop_bits)
00774 + 1;
00775 }
00776
00777 void serial_port_address::pack(byte_array &packed_form) const
00778 {
00779 attach(packed_form, port);
00780 attach(packed_form, baud_rate);
00781 attach(packed_form, data_bits);
00782 attach(packed_form, stop_bits);
00783 packed_form += byte_array(1, (byte *)&parity);
00784 }
00785
00786 bool serial_port_address::unpack(byte_array &packed_form)
00787 {
00788 if (u_int(packed_form.length()) < sizeof(port) + sizeof(baud_rate)
00789 + sizeof(data_bits) + sizeof(stop_bits) + 1)
00790 return false;
00791 if (!detach(packed_form, port)) return false;
00792 if (!detach(packed_form, baud_rate)) return false;
00793 if (!detach(packed_form, data_bits)) return false;
00794 if (!detach(packed_form, stop_bits)) return false;
00795 parity = packed_form[0];
00796 packed_form.zap(0, 0);
00797 return true;
00798 }
00799
00800 void serial_port_address::fill(int port_in, int baud_rate_in,
00801 byte data_bits_in, char parity_in, byte stop_bits_in)
00802 {
00803 port = port_in;
00804 baud_rate = baud_rate_in;
00805 data_bits = data_bits_in;
00806
00807 parity = (istring(parity_in, 1).upper())[0];
00808 stop_bits = stop_bits_in;
00809 }
00810
00811 bool serial_port_address::detokenize(const istring &info)
00812 {
00813 LOADER_ENTRY;
00814 GRAB("port", port);
00815 GRAB("baud", baud);
00816 FIND("parity", parity);
00817 FIND("data", data);
00818 FIND("stop", stop);
00819 fill(port.convert(0), baud.convert(0), byte(data.convert(8)),
00820 parity[0], byte(stop.convert(1)));
00821 LOADER_EXIT;
00822 return true;
00823 }
00824
00825 istring serial_port_address::tokenize() const
00826 {
00827 STORER_ENTRY;
00828 ADD("port", isprintf("%d", int(port)));
00829 ADD("baud", isprintf("%d", baud_rate));
00830 ADD("parity", istring(parity, 1));
00831 ADD("data", isprintf("%d", int(data_bits)));
00832 ADD("stop", isprintf("%d", int(stop_bits)));
00833 DUMP_EXIT;
00834 }
00835
00837
00838 ipc_address::ipc_address() { fill("", ""); }
00839
00840 ipc_address::ipc_address(const istring &service, const istring &topic)
00841 { fill(service, topic); }
00842
00843 machine_uid ipc_address::convert() const { return machine_uid(); }
00844
00845 void ipc_address::fill(const istring &service_in, const istring &topic_in)
00846 {
00847 service_in.stuff(service, MAXIMUM_IPC_NAME_LENGTH - 1);
00848 topic_in.stuff(topic, MAXIMUM_IPC_NAME_LENGTH - 1);
00849 }
00850
00851 int ipc_address::packed_size() const
00852 {
00853 return 2 * (sizeof(int) + MAXIMUM_IPC_NAME_LENGTH);
00854 }
00855
00856 void ipc_address::pack(byte_array &packed_form) const
00857 {
00858 packed_form += byte_array(MAXIMUM_IPC_NAME_LENGTH, (byte *)service);
00859 packed_form += byte_array(MAXIMUM_IPC_NAME_LENGTH, (byte *)topic);
00860 }
00861
00862 bool ipc_address::unpack(byte_array &packed_form)
00863 {
00864