geoip.cpp

Go to the documentation of this file.
00001 /*
00002 **  This file is part of Vidalia, and is subject to the license terms in the
00003 **  LICENSE file, found in the top level directory of this distribution. If you
00004 **  did not receive the LICENSE file with this file, you may obtain it from the
00005 **  Vidalia source package distributed by the Vidalia Project at
00006 **  http://www.vidalia-project.net/. No part of Vidalia, including this file,
00007 **  may be copied, modified, propagated, or distributed except according to the
00008 **  terms described in the LICENSE file.
00009 */
00010 
00011 /*
00012 ** \file geoip.cpp
00013 ** \version $Id: geoip.cpp 2362 2008-02-29 04:30:11Z edmanm $
00014 ** \brief Associates an IP with a geographic location
00015 */
00016 
00017 #include <QStringList>
00018 
00019 #include "geoip.h"
00020 
00021 /** Verifies a latitude is between -90.0 and 90.0 degrees. */
00022 #define IS_VALID_LATITUDE(x)    (((x) >= -90.0) && ((x) <= 90.0))
00023 /** Verifies a longitude is between -180.0 and 180.0 degrees. */
00024 #define IS_VALID_LONGITUDE(x)   (((x) >= -180.0) && ((x) <= 180.0))
00025 
00026 
00027 /** Constructor */
00028 GeoIp::GeoIp(QHostAddress ip)
00029 {
00030   _ip = ip;
00031   _latitude = _longitude = 0xFFFF;
00032 }
00033 
00034 /** Constructor. */
00035 GeoIp::GeoIp(QHostAddress ip, float latitude, float longitude, 
00036              QString city, QString state, QString country)
00037 {
00038   _ip        = ip;
00039   _latitude  = latitude;
00040   _longitude = longitude;
00041   _city      = city;
00042   _state     = state;
00043   _country   = country;
00044 }
00045 
00046 /** Parses the GeoIp information from a comma-delimited string. The format of
00047  * the string is as in the following example:
00048  *
00049  *      128.213.48.13,Troy,NY,US,42.7495,-73.5951,1138402852
00050  */
00051 GeoIp
00052 GeoIp::fromString(QString geoip)
00053 {
00054   /* Split comma-delimited data fields */
00055   QStringList data = geoip.split(",");
00056   
00057   if (data.size() == 2 && data.at(1).toLower() == "unknown") {
00058     return GeoIp(QHostAddress(data.at(0)));
00059   } else if (data.size() < 6) {
00060     return GeoIp();
00061   }
00062   
00063   /* Parse the data from the string */
00064   QHostAddress   ip(data.at(0));
00065   QString city    = data.at(1);
00066   QString state   = data.at(2);
00067   QString country = data.at(3);
00068   float latitude  = data.at(4).toFloat();
00069   float longitude = data.at(5).toFloat();
00070  
00071   /* Create a new GeoIp object with the parsed data. */
00072   return GeoIp(ip, latitude, longitude, city, state, country);
00073 }
00074 
00075 /** Formats the GeoIp information as a comma-delimited string. */
00076 QString
00077 GeoIp::toString() const
00078 {
00079   QString s;
00080   /* Assemble and comma-delimit the data fields */
00081   s.append(_ip.toString());
00082   s.append("," + _city);
00083   s.append("," + _state);
00084   s.append("," + _country);
00085   s.append("," + QString::number(_latitude,  'f', 4));
00086   s.append("," + QString::number(_longitude, 'f', 4));
00087   return s;
00088 }
00089 
00090 /** Returns true if the GeoIp object is invalid. */
00091 bool
00092 GeoIp::isEmpty() const
00093 {
00094   return (_ip.isNull() && 
00095           !IS_VALID_LATITUDE(_latitude) && 
00096           !IS_VALID_LONGITUDE(_longitude));
00097 }
00098 
00099 /** Returns true if the GeoIp object is valid, but no location information
00100  * is known for the associated IP address. */
00101 bool
00102 GeoIp::isUnknown() const
00103 {
00104   return (!_ip.isNull() && 
00105           !IS_VALID_LATITUDE(_latitude) && 
00106           !IS_VALID_LONGITUDE(_longitude));
00107 }
00108 
00109 /** Returns a human-readable string of GeoIp location information. */
00110 QString
00111 GeoIp::toLocation() const
00112 {
00113   QStringList location;
00114   
00115   /* Add the city name (if present) */
00116   if (!_city.isEmpty()) {
00117     location << _city;
00118   }
00119   /* Add the state or region name (if present) */
00120   if (!_state.isEmpty()) {
00121     /* Only display non-numeric region codes. */
00122     bool valid = true;
00123     for (int i = 0; i < _state.length(); i++) {
00124       if (_state[i].isDigit()) {
00125         valid = false;
00126         break;
00127       }
00128     }
00129     if (valid) {
00130       location << _state;
00131     }
00132   }
00133   /* Add the country code (if present) */
00134   if (!_country.isEmpty()) {
00135     location << _country;
00136   }
00137   return location.join(", ");
00138 }
00139 

Generated on Sat Aug 16 17:31:48 2008 for Vidalia by  doxygen 1.5.6