stream.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 
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 2977 2008-08-17 01:28:25Z edmanm $
00014 ** \brief Object representing a Tor stream
00015 */
00016 
00017 #include <QStringList>
00018 
00019 #include "circuit.h" 
00020 #include "stream.h"
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 

Generated on Wed Nov 26 21:03:58 2008 for Vidalia by  doxygen 1.5.6