machine_uid.cpp

Go to the documentation of this file.
00001 #ifndef MACHINE_UID_IMPLEMENTATION_FILE
00002 #define MACHINE_UID_IMPLEMENTATION_FILE
00003 
00004 /*****************************************************************************\
00005 *                                                                             *
00006 *  Name   : machine_uid                                                       *
00007 *  Author : Chris Koeritz                                                     *
00008 *                                                                             *
00009 *******************************************************************************
00010 * Copyright (c) 2000-$now By Author.  This program is free software; you can  *
00011 * redistribute it and/or modify it under the terms of the GNU General Public  *
00012 * License as published by the Free Software Foundation; either version 2 of   *
00013 * the License or (at your option) any later version.  This is online at:      *
00014 *     http://www.fsf.org/copyleft/gpl.html                                    *
00015 * Please send any updates to: fred@gruntose.com                               *
00016 \*****************************************************************************/
00017 
00018 #include "address.h"
00019 #include "machine_uid.h"
00020 
00021 #include <basis/byte_array.h>
00022 #include <basis/function.h>
00023 #include <basis/istring.h>
00024 #include <basis/mutex.h>
00025 #include <basis/utility.h>
00026 #include <data_struct/static_memory_gremlin.h>
00027 #include <textual/byte_format.h>
00028 
00029 machine_uid::machine_uid()
00030 : _contents(new byte_array)
00031 { *_contents += byte(INVALID_LOCATION); }
00032 
00033 machine_uid::machine_uid(known_location_types type,
00034     const byte_array &address)
00035 : _contents(new byte_array)
00036 {
00037   *_contents += byte(type); 
00038   *_contents += address;
00039 }
00040 
00041 machine_uid::machine_uid(const machine_uid &to_copy)
00042 : packable(),
00043   _contents(new byte_array)
00044 { *this = to_copy; }
00045 
00046 machine_uid::~machine_uid() { WHACK(_contents); }
00047 
00048 void machine_uid::reset(known_location_types type, const byte_array &address)
00049 {
00050   _contents->reset();
00051   *_contents += byte(type); 
00052   *_contents += address;
00053 }
00054 
00055 const byte_array &machine_uid::raw() const { return *_contents; }
00056 
00057 const istring &machine_uid::type_name(known_location_types type)
00058 {
00059   static istring TCPIP_NAME = "TCPIP";
00060   static istring IPX_NAME = "IPX";
00061   static istring NETBIOS_NAME = "NETBIOS";
00062   static istring UNKNOWN_NAME = "INVALID";
00063 
00064   switch (type) {
00065     case TCPIP_LOCATION: return TCPIP_NAME;
00066     case IPX_LOCATION: return IPX_NAME;
00067     case NETBIOS_LOCATION: return NETBIOS_NAME;
00068     default: return UNKNOWN_NAME;
00069   }
00070 }
00071 
00072 machine_uid &machine_uid::operator = (const machine_uid &to_copy)
00073 {
00074   if (this == &to_copy) return *this;
00075   *_contents = *to_copy._contents;
00076   return *this;
00077 }
00078 
00079 istring machine_uid::text_form() const
00080 {
00081   istring to_return;
00082   to_return += type_name(type()) + "[";
00083   for (int i = 1; i < _contents->length(); i++) {
00084     if (type() == TCPIP_LOCATION)
00085       to_return += isprintf("%d", int(_contents->get(i)));
00086     else
00087       to_return += isprintf("%02x", int(_contents->get(i)));
00088     if (i < _contents->length() - 1)
00089       to_return += ".";
00090   }
00091   to_return += "]";
00092   return to_return;
00093 }
00094 
00095 istring machine_uid::compact_form() const
00096 {
00097   istring to_return;
00098   byte_format::bytes_to_shifted_string(*_contents, to_return);
00099   return to_return;
00100 }
00101 
00102 machine_uid machine_uid::expand(const istring &compacted)
00103 {
00104   machine_uid to_return;
00105   to_return._contents->reset();
00106   byte_format::shifted_string_to_bytes(compacted, *to_return._contents);
00107   return to_return;
00108 }
00109 
00110 bool machine_uid::operator == (const machine_uid &to_compare) const
00111 {
00112   // an empty id is only equal to another empty id.
00113   if (!_contents->length() || !to_compare._contents->length())
00114     return !_contents->length() && !to_compare._contents->length();
00115   if (_contents->length() != to_compare._contents->length()) return false;
00116   for (int i = 0; i < _contents->length(); i++)
00117     if (_contents->get(i) != to_compare._contents->get(i)) return false;
00118   return true;
00119 }
00120 
00121 machine_uid::known_location_types machine_uid::type() const
00122 {
00123   if (!_contents->length()) return INVALID_LOCATION;
00124   return known_location_types(_contents->get(0));
00125 }
00126 
00127 void machine_uid::pack(byte_array &packed_form) const
00128 {
00129   basis::attach(packed_form, _contents->length());
00130   packed_form += *_contents;
00131 }
00132 
00133 bool machine_uid::unpack(byte_array &packed_form)
00134 {
00135   int len = 0;
00136   if (!basis::detach(packed_form, len)) return false;
00137     // there's no length even?
00138   if (packed_form.length() < len) return false;
00139     // not enough size left for the length specified.
00140   *_contents = packed_form.subarray(0, len - 1);
00141   packed_form.zap(0, len - 1);
00142   return true;
00143 }
00144 
00145 byte_array machine_uid::native() const
00146 {
00147   if (_contents->length() <= 1) return byte_array();  // invalid.
00148   return _contents->subarray(1, _contents->last());
00149 }
00150 
00152 
00153 class internal_machine_uid_array : public array<machine_uid> {};
00154 
00155 machine_uid_array::machine_uid_array()
00156 : _uids(new internal_machine_uid_array)
00157 {}
00158 
00159 machine_uid_array::machine_uid_array(const machine_uid_array &to_copy)
00160 : object_base(),
00161   _uids(new internal_machine_uid_array(*to_copy._uids))
00162 {
00163 }
00164 
00165 machine_uid_array::~machine_uid_array()
00166 {
00167   WHACK(_uids);
00168 }
00169 
00170 SAFE_STATIC_CONST(machine_uid_array, machine_uid_array::blank_array, )
00171 
00172 machine_uid_array &machine_uid_array::operator =
00173     (const machine_uid_array &to_copy)
00174 {
00175   if (this != &to_copy) {
00176     *_uids = *to_copy._uids;
00177   }
00178   return *this;
00179 }
00180 
00181 bool machine_uid_array::operator += (const machine_uid &to_add)
00182 {
00183   if (member(to_add)) return false;
00184   _uids->concatenate(to_add);
00185   return true;
00186 }
00187 
00188 int machine_uid_array::elements() const { return _uids->length(); }
00189 
00190 istring machine_uid_array::text_form() const
00191 {
00192   istring to_return;
00193   for (int i = 0; i < _uids->length(); i++) {
00194     to_return += _uids->get(i).text_form() + " ";
00195   }
00196   return to_return;
00197 }
00198 
00199 machine_uid &machine_uid_array::operator [] (int index)
00200 { return _uids->use(index); }
00201 
00202 const machine_uid &machine_uid_array::operator [] (int index) const
00203 { return _uids->get(index); }
00204 
00205 void machine_uid_array::reset() { _uids->reset(); }
00206 
00207 bool machine_uid_array::member(const machine_uid &to_test) const
00208 {
00209   const int test_len = to_test.raw().length();
00210   for (int i = 0; i < _uids->length(); i++) {
00211     const machine_uid &curr = _uids->get(i);
00212     // test for the length first since that's cheaper.
00213     if ( (test_len == curr.raw().length()) && (curr == to_test) ) {
00214       return true;
00215     } else if (!to_test.valid() && !curr.valid()) return true;
00216       // both are invalid, so the item to find is present.
00217 
00218 /*
00219       if (!to_test.valid() || !curr.valid()) continue;
00220         // one is invalid but the other is not; not a match.
00221 all bogus!
00222 //hmmm: weird partial matching being allowed here.
00223       bool to_return = true;  // assume it's good until told otherwise.
00224       // if the first parts of the addresses agree, then assume we're
00225       for (int j = 0; j < minimum(test_len, curr.raw().length()); j++) {
00226         if (curr.raw().get(j) != to_test.raw().get(j)) {
00227           to_return = false;
00228         }
00229       }
00230       if (to_return)
00231         return true;
00232     }
00233 */
00234   }
00235   return false;
00236 }
00237 
00239 
00240 internet_machine_uid::internet_machine_uid(const istring &hostname,
00241     const byte_array &ip_address)
00242 {
00243   byte_array addr(ip_address);
00244   u_short fletch = utility::fletcher_checksum((const byte *)hostname.observe(),
00245       hostname.length());
00246   basis::attach(addr, fletch);
00247   reset(machine_uid::TCPIP_LOCATION, addr);
00248 }
00249 
00250 
00251 #endif //MACHINE_UID_IMPLEMENTATION_FILE
00252 

Generated on Fri Nov 28 04:28:56 2008 for HOOPLE Libraries by  doxygen 1.5.1