Vidalia  0.2.21
Stream.cpp
Go to the documentation of this file.
1 /*
2 ** This file is part of Vidalia, and is subject to the license terms in the
3 ** LICENSE file, found in the top level directory of this distribution. If
4 ** you did not receive the LICENSE file with this file, you may obtain it
5 ** from the Vidalia source package distributed by the Vidalia Project at
6 ** http://www.torproject.org/projects/vidalia.html. No part of Vidalia,
7 ** including this file, may be copied, modified, propagated, or distributed
8 ** except according to the terms described in the LICENSE file.
9 */
10 
11 /*
12 ** \file Stream.cpp
13 ** \brief Object representing a Tor stream
14 */
15 
16 #include "Stream.h"
17 #include "Circuit.h"
18 
19 #include <QStringList>
20 
21 
22 /** Default constructor. */
24 {
25  _status = Unknown;
26  _port = 0;
27 }
28 
29 /** Constructor */
30 Stream::Stream(const StreamId &streamId, Status status,
31  const CircuitId &circuitId, const QString &address,
32  quint16 port)
33 {
34  _streamId = streamId;
35  _status = status;
37  _address = address;
38  _port = port;
39 }
40 
41 /** Constructor */
42 Stream::Stream(const StreamId &streamId, Status status,
43  const CircuitId &circuitId, const QString &target)
44 {
45  _streamId = streamId;
46  _status = status;
48  _port = 0;
49 
50  int i = target.indexOf(":");
51  if (i >= 0)
52  _address = target.mid(0, i);
53  if (i + 1 < target.length())
54  _port = target.mid(i+1).toUInt();
55 }
56 
57 /** Parses the given string for stream information, given in Tor control
58  * protocol format. The format is:
59  *
60  * StreamID SP StreamStatus SP CircID SP Target
61  */
62 Stream
63 Stream::fromString(const QString &stream)
64 {
65  QStringList parts = stream.split(" ", QString::SkipEmptyParts);
66  if (parts.size() >= 4) {
67  /* Get the stream ID */
68  StreamId streamId = parts.at(0);
69  /* Get the stream status value */
70  Stream::Status status = Stream::toStatus(parts.at(1));
71  /* Get the ID of the circuit on which this stream travels */
72  CircuitId circId = parts.at(2);
73  /* Get the target address for this stream */
74  QString target = parts.at(3);
75 
76  return Stream(streamId, status, circId, target);
77  }
78  return Stream();
79 }
80 
81 /** Returns true iff <b>streamId</b> consists of only between 1 and 16
82  * (inclusive) ASCII-encoded letters and numbers. */
83 bool
85 {
86  int length = streamId.length();
87  if (length < 1 || length > 16)
88  return false;
89 
90  for (int i = 0; i < length; i++) {
91  char c = streamId[i].toAscii();
92  if (c < '0' && c > '9' && c < 'A' && c > 'Z' && c < 'a' && c > 'z')
93  return false;
94  }
95  return true;
96 }
97 
98 /** Converts a string description of a stream's status to its enum value */
100 Stream::toStatus(const QString &strStatus)
101 {
102  if (!strStatus.compare("NEW", Qt::CaseInsensitive))
103  return New;
104  if (!strStatus.compare("NEWRESOLVE", Qt::CaseInsensitive))
105  return NewResolve;
106  if (!strStatus.compare("SENTCONNECT", Qt::CaseInsensitive))
107  return SentConnect;
108  if (!strStatus.compare("SENTRESOLVE", Qt::CaseInsensitive))
109  return SentResolve;
110  if (!strStatus.compare("SUCCEEDED", Qt::CaseInsensitive))
111  return Succeeded;
112  if (!strStatus.compare("FAILED", Qt::CaseInsensitive))
113  return Failed;
114  if (!strStatus.compare("CLOSED", Qt::CaseInsensitive))
115  return Closed;
116  if (!strStatus.compare("DETACHED", Qt::CaseInsensitive))
117  return Detached;
118  if (!strStatus.compare("REMAP", Qt::CaseInsensitive))
119  return Remap;
120  return Unknown;
121 }
122 
123 /** Returns a human-understandable string representation of this
124  * stream's status. */
125 QString
127 {
128  QString status;
129  switch (_status) {
130  case New: status = tr("New"); break;
131  case NewResolve:
132  case SentResolve: status = tr("Resolving"); break;
133  case SentConnect: status = tr("Connecting"); break;
134  case Succeeded: status = tr("Open"); break;
135  case Failed: status = tr("Failed"); break;
136  case Closed: status = tr("Closed"); break;
137  case Detached: status = tr("Retrying"); break;
138  case Remap: status = tr("Remapped"); break;
139  default: status = tr("Unknown"); break;
140  }
141  return status;
142 }
143 
144 /** Returns true if all fields in this Stream object are valid. */
145 bool
147 {
148  return (isValidStreamId(_streamId)
150  && (_status != Unknown)
151  && !_address.isEmpty());
152 }
153