Vidalia 0.2.10
|
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 00004 ** you did not receive the LICENSE file with this file, you may obtain it 00005 ** from the 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 00008 ** the terms described in the LICENSE file. 00009 */ 00010 00011 /* 00012 ** \file Stream.cpp 00013 ** \version $Id: Stream.cpp 3735 2009-04-28 20:28:01Z edmanm $ 00014 ** \brief Object representing a Tor stream 00015 */ 00016 00017 #include "Stream.h" 00018 #include "Circuit.h" 00019 00020 #include <QStringList> 00021 00022 00023 /** Default constructor. */ 00024 Stream::Stream() 00025 { 00026 _status = Unknown; 00027 _port = 0; 00028 } 00029 00030 /** Constructor */ 00031 Stream::Stream(const StreamId &streamId, Status status, 00032 const CircuitId &circuitId, const QString &address, 00033 quint16 port) 00034 { 00035 _streamId = streamId; 00036 _status = status; 00037 _circuitId = circuitId; 00038 _address = address; 00039 _port = port; 00040 } 00041 00042 /** Constructor */ 00043 Stream::Stream(const StreamId &streamId, Status status, 00044 const CircuitId &circuitId, const QString &target) 00045 { 00046 _streamId = streamId; 00047 _status = status; 00048 _circuitId = circuitId; 00049 _port = 0; 00050 00051 int i = target.indexOf(":"); 00052 if (i >= 0) 00053 _address = target.mid(0, i); 00054 if (i + 1 < target.length()) 00055 _port = target.mid(i+1).toUInt(); 00056 } 00057 00058 /** Parses the given string for stream information, given in Tor control 00059 * protocol format. The format is: 00060 * 00061 * StreamID SP StreamStatus SP CircID SP Target 00062 */ 00063 Stream 00064 Stream::fromString(const QString &stream) 00065 { 00066 QStringList parts = stream.split(" ", QString::SkipEmptyParts); 00067 if (parts.size() >= 4) { 00068 /* Get the stream ID */ 00069 StreamId streamId = parts.at(0); 00070 /* Get the stream status value */ 00071 Stream::Status status = Stream::toStatus(parts.at(1)); 00072 /* Get the ID of the circuit on which this stream travels */ 00073 CircuitId circId = parts.at(2); 00074 /* Get the target address for this stream */ 00075 QString target = parts.at(3); 00076 00077 return Stream(streamId, status, circId, target); 00078 } 00079 return Stream(); 00080 } 00081 00082 /** Returns true iff <b>streamId</b> consists of only between 1 and 16 00083 * (inclusive) ASCII-encoded letters and numbers. */ 00084 bool 00085 Stream::isValidStreamId(const StreamId &streamId) 00086 { 00087 int length = streamId.length(); 00088 if (length < 1 || length > 16) 00089 return false; 00090 00091 for (int i = 0; i < length; i++) { 00092 char c = streamId[i].toAscii(); 00093 if (c < '0' && c > '9' && c < 'A' && c > 'Z' && c < 'a' && c > 'z') 00094 return false; 00095 } 00096 return true; 00097 } 00098 00099 /** Converts a string description of a stream's status to its enum value */ 00100 Stream::Status 00101 Stream::toStatus(const QString &strStatus) 00102 { 00103 if (!strStatus.compare("NEW", Qt::CaseInsensitive)) 00104 return New; 00105 if (!strStatus.compare("NEWRESOLVE", Qt::CaseInsensitive)) 00106 return NewResolve; 00107 if (!strStatus.compare("SENTCONNECT", Qt::CaseInsensitive)) 00108 return SentConnect; 00109 if (!strStatus.compare("SENTRESOLVE", Qt::CaseInsensitive)) 00110 return SentResolve; 00111 if (!strStatus.compare("SUCCEEDED", Qt::CaseInsensitive)) 00112 return Succeeded; 00113 if (!strStatus.compare("FAILED", Qt::CaseInsensitive)) 00114 return Failed; 00115 if (!strStatus.compare("CLOSED", Qt::CaseInsensitive)) 00116 return Closed; 00117 if (!strStatus.compare("DETACHED", Qt::CaseInsensitive)) 00118 return Detached; 00119 if (!strStatus.compare("REMAP", Qt::CaseInsensitive)) 00120 return Remap; 00121 return Unknown; 00122 } 00123 00124 /** Returns a human-understandable string representation of this 00125 * stream's status. */ 00126 QString 00127 Stream::statusString() const 00128 { 00129 QString status; 00130 switch (_status) { 00131 case New: status = tr("New"); break; 00132 case NewResolve: 00133 case SentResolve: status = tr("Resolving"); break; 00134 case SentConnect: status = tr("Connecting"); break; 00135 case Succeeded: status = tr("Open"); break; 00136 case Failed: status = tr("Failed"); break; 00137 case Closed: status = tr("Closed"); break; 00138 case Detached: status = tr("Retrying"); break; 00139 case Remap: status = tr("Remapped"); break; 00140 default: status = tr("Unknown"); break; 00141 } 00142 return status; 00143 } 00144 00145 /** Returns true if all fields in this Stream object are valid. */ 00146 bool 00147 Stream::isValid() const 00148 { 00149 return (isValidStreamId(_streamId) 00150 && Circuit::isValidCircuitId(_circuitId) 00151 && (_status != Unknown) 00152 && !_address.isEmpty()); 00153 } 00154