示例#1
0
void read_from(ReadSource in, Level& level) {
    read(in, level.netRaceFlags);
    read(in, level.playerNum);
    read(in, level.player, kMaxPlayerNum);
    read(in, level.scoreStringResID);
    read(in, level.initialFirst);
    read(in, level.prologueID);
    read(in, level.initialNum);
    read(in, level.songID);
    read(in, level.conditionFirst);
    read(in, level.epilogueID);
    read(in, level.conditionNum);
    read(in, level.starMapH);
    read(in, level.briefPointFirst);
    read(in, level.starMapV);
    read(in, level.briefPointNum);
    level.parTime = game_ticks(secs(read<int16_t>(in)));
    in.shift(2);
    read(in, level.parKills);
    read(in, level.levelNameStrNum);
    read(in, level.parKillRatio);
    read(in, level.parLosses);
    int16_t start_time = read<int16_t>(in);
    level.startTime    = secs(start_time & kLevel_StartTimeMask);
    level.is_training  = start_time & kLevel_IsTraining_Bit;
}
示例#2
0
static unsigned long reportingduration(time_t eventstart, time_t eventduration)
{
	struct tm start, end;
	time_t eventend;
	unsigned long result;

	memcpy(&start, localtime(&eventstart), sizeof(start));
	eventend = eventstart + eventduration;
	memcpy(&end, localtime(&eventend), sizeof(end));

	if ((start.tm_mday == end.tm_mday) && (start.tm_mon == end.tm_mon) && (start.tm_year == end.tm_year))
		result = reportduration_oneday(start.tm_wday, secs(start.tm_hour, start.tm_min, start.tm_sec), secs(end.tm_hour, end.tm_min, end.tm_sec));
	else {
		int fulldays = (eventduration - (86400-secs(start.tm_hour, start.tm_min, start.tm_sec))) / 86400;
		int curdow = (start.tm_wday  == 6) ? 0 : (start.tm_wday+1);

		result = reportduration_oneday(start.tm_wday, secs(start.tm_hour, start.tm_min, start.tm_sec), 86400);
		while (fulldays) {
			result += reportduration_oneday(curdow, 0, 86400);
			curdow = (curdow  == 6) ? 0 : (curdow+1);
			fulldays--;
		}
		result += reportduration_oneday(curdow, 0, secs(end.tm_hour, end.tm_min, end.tm_sec));
	}

	return result;
}
示例#3
0
void Timeval::operator+=(const DelayInterval& arg2) {
  secs() += arg2.seconds(); usecs() += arg2.useconds();
  if (useconds() >= MILLION) {
    usecs() -= MILLION;
    ++secs();
  }
}
示例#4
0
void Timeval::operator-=(const DelayInterval& arg2) {
  secs() -= arg2.seconds(); usecs() -= arg2.useconds();
  if (usecs() < 0) {
    usecs() += MILLION;
    --secs();
  }
  if (secs() < 0)
    secs() = usecs() = 0;
}
示例#5
0
ProcessTime ProcessTime::operator-(const ProcessTime& t) {
  ProcessTime &tt= (ProcessTime&)t;
  ProcessTime res;
  if (tt.nano_secs() > nano_secs()) {
    res._secs      = secs()      - tt.secs() - 1;
    res._nano_secs = one_billion - tt.nano_secs() + nano_secs();
  } else {
    res._secs      = secs()      - tt.secs();
    res._nano_secs = nano_secs() - tt.nano_secs();
  }
  return res;
}
示例#6
0
 struct timeval timeval() const
 {
   struct timeval t;
   t.tv_sec = secs();
   t.tv_usec = us() - (t.tv_sec * MILLISECONDS);
   return t;
 }
int client(int argc, char* argv[])
{
  cxxtools::Arg<unsigned short> port(argc, argv, 'p', 1234);
  cxxtools::Arg<const char*> ip(argc, argv, 'i', "127.0.0.1");
  cxxtools::Arg<unsigned> secs(argc, argv, 't', 1);
  cxxtools::Arg<unsigned> bufsize(argc, argv, 't', BUFSIZE);
  cxxtools::Arg<unsigned> B(argc, argv, 'B', 0);

  cxxtools::net::Stream conn(ip.getValue(), port);

  cxxtools::Dynbuffer<char> buffer(bufsize);
  std::generate(buffer.begin(), buffer.end(), rand);

  std::cout << "test" << std::endl;

  if (B.isSet())
    run_test(conn, B, buffer.data(), secs);
  else
  {
    for (unsigned bs=256; bs <= bufsize.getValue(); bs <<= 1)
      run_test(conn, bs, buffer.data(), secs);
  }

  return 0;
}
示例#8
0
int client(int argc, char* argv[])
{
  cxxtools::Arg<unsigned short> port(argc, argv, 'p', 1234);
  cxxtools::Arg<const char*> ip(argc, argv, 'i');
  cxxtools::Arg<unsigned> secs(argc, argv, 't', 1);
  cxxtools::Arg<unsigned> bufsize(argc, argv, 't', BUFSIZE);
  cxxtools::Arg<unsigned> B(argc, argv, 'B', 0);

  cxxtools::net::TcpSocket conn(ip.getValue(), port);

  std::vector<char> buffer(bufsize);
  std::generate(&buffer[0], &buffer[bufsize], rand);

  std::cout << "test" << std::endl;

  if (B.isSet())
    run_test(conn, B, &buffer[0], secs);
  else
  {
    for (unsigned bs=256; bs <= bufsize.getValue(); bs <<= 1)
      run_test(conn, bs, &buffer[0], secs);
  }

  return 0;
}
示例#9
0
void SelectLevelScreen::handle_button(Button& button) {
    switch (button.id) {
        case OK:
            _state      = FADING_OUT;
            *_cancelled = false;
            stack()->push(
                    new ColorFade(ColorFade::TO_COLOR, RgbColor::black(), secs(1), false, NULL));
            break;

        case CANCEL:
            *_cancelled = true;
            stack()->pop(this);
            break;

        case PREVIOUS:
            if (_index > 0) {
                --_index;
                *_level = Handle<Level>(_chapters[_index] - 1);
            }
            adjust_interface();
            break;

        case NEXT:
            if (_index < _chapters.size() - 1) {
                ++_index;
                *_level = Handle<Level>(_chapters[_index] - 1);
            }
            adjust_interface();
            break;

        default: throw Exception(format("Got unknown button {0}.", button.id));
    }
}
示例#10
0
void ntpdtest::settime(int y, int m, int d, int H, int M, int S)
{

    time_t days(ntpcal_edate_to_eradays(y-1, m-1, d-1) + 1 - DAY_UNIX_STARTS);
    time_t secs(ntpcal_etime_to_seconds(H, M, S));

    nowtime = days * SECSPERDAY + secs;
}
示例#11
0
/**
 * web100clt currently (as of 2015-12-21) requires that its output queue be
 * drained at the end of the c2s test and hangs if it is not. We don't want to
 * break it, but that extra second or so should not be part of our measured
 * transmitted data, because the spec says that it's a 10 second upload from
 * client to server, not a "10 seconds or a little bit more depending on when
 * the client starts counting" upload.  Therefore, here we read from the
 * sockets for just a little longer, but ignore the resulting data, so that old
 * clients don't hang, but newer clients are not penalized for quitting after
 * 10 seconds, just like the spec says they can.
 *
 * TODO: Fix web100clt to eliminate the need for this function.
 * TODO: Make this function happen in a separate thread (but not a forked
 *       subprocess due to SSL issues). That way old clients being dumb doesn't
 *       slow down new clients' tests.  Currently it wastes 1 second per test,
 *       which at 150k tests per day is a waste of 40+ hours of peoples' lives
 *       every day.
 *
 * @param c2s_conns The connections to drain
 * @param streamsNum The number of connections
 * @param buff The buffer into which we should read data
 * @param buff_size The size of said buffer
 */
void drain_old_clients(Connection* c2s_conns, int streamsNum, char* buff, size_t buff_size) {
  int activeStreams;
  double trash = 0;  // A byte count we ignore.
  fd_set rfd;
  int max_fd;
  double start_time;
  int msgretvalue, read_error;
  struct timeval sel_tv;

  start_time = secs();
  activeStreams = connections_to_fd_set(c2s_conns, streamsNum, &rfd, &max_fd);
  while (activeStreams > 0 && (secs() - start_time) < DRAIN_TIME) {
    sel_tv.tv_sec = DRAIN_TIME;
    sel_tv.tv_usec = 0;
    msgretvalue = select(max_fd + 1, &rfd, NULL, NULL, &sel_tv);
    if (msgretvalue == -1) {
      if (errno == EINTR) {
        // select interrupted. Continue waiting for activity on socket
        continue;
      } else {
        log_println(5,
                    "Socket error while draining the client's send queue: %s. This is likely ok.",
                    strerror(errno));
        return;
      }
    } else if (msgretvalue == 0) {
      log_println(5, "Done draining the client's send queue.");
      return;
    } else if (msgretvalue > 0) {
      read_error = read_ready_streams(&rfd, c2s_conns, streamsNum, buff, buff_size, &trash);
      if (read_error != 0 && read_error != EINTR) {
        // EINTR is expected, but all other errors are actually errors
        log_println(5, "Error while trying to drain client's send queue: %s. This is likely ok.",
                    strerror(read_error));
        return;
      }
    } else {
      // This should never happen. select() returns -1, 0, or a positive number says POSIX.
      log_println(0, "Unhandled return value from select: %d.", msgretvalue);
      return;
    }
    // Set up the FD_SET and activeStreams for the next select.
    activeStreams = connections_to_fd_set(c2s_conns, streamsNum, &rfd, &max_fd);
  }
}
示例#12
0
ProcessTime ProcessTime::operator+(const ProcessTime& t) {
  ProcessTime &tt= (ProcessTime&)t;
  ProcessTime res;
  res._secs      = secs()      + tt.secs();
  res._nano_secs = nano_secs() + tt.nano_secs();
  if (res.nano_secs() >= one_billion) {
    res._nano_secs -= one_billion;
    res._secs      += 1;
  }
  return res;
}
示例#13
0
static void build_reportspecs(char *reporttime)
{
	/* Timespec:  W:HHMM:HHMM */

	char *spec, *timespec;
	int dow, start, end;
	int found;

	reptimecnt = 0;
	spec = strchr(reporttime, '=');
	timespec = strdup(spec ? (spec+1) : reporttime); 
	
	spec = strtok(timespec, ",");
	while (spec) {
		if (*spec == '*') {
			dow = -1;
			found = sscanf(spec+1, ":%d:%d", &start, &end);
		}
		else if ((*spec == 'W') || (*spec == 'w')) {
			dow = -2;
			found = sscanf(spec+1, ":%d:%d", &start, &end);
		}
		else {
			found = sscanf(spec, "%d:%d:%d", &dow, &start, &end);
		}

		if (found < 2) {
			errprintf("build_reportspecs: Found too few items in %s\n", spec);
		}

		reptimes[reptimecnt].dow = dow;
		reptimes[reptimecnt].start = secs((start / 100), (start % 100), 0);
		reptimes[reptimecnt].end = secs((end / 100), (end % 100), 0);
		reptimecnt++;
		spec = strtok(NULL, ",");
	}

	xfree(timespec);
}
示例#14
0
/***********************************************************************//**
 * @brief Time constructor
 *
 * @param[in] time Time value (seconds or days).
 * @param[in] unit Time unit (default: "secs").
 *
 * @exception GException::time_invalid_unit
 *            Invalid time unit specified.
 *
 * Constructs a GTime object by setting the time in the native reference
 * in units of seconds (default) or days.
 ***************************************************************************/
GTime::GTime(const double& time, const std::string& unit)
{
    // Initialise private members
    init_members();

    // Set time according to timeunit string
    std::string timeunit = tolower(unit);
    if (timeunit == "d" || timeunit == "day" || timeunit == "days") {
        days(time);
    }
    else if (timeunit == "s" || timeunit == "sec" || timeunit == "secs") {
        secs(time);
    }
    else {
        throw GException::time_invalid_unit(G_CONSTRUCT, unit,
              "Valid timeunit values are: \"d\", \"day\", \"days\","
              " \"s\", \"sec\" or \"secs\"");
    }

    // Return
    return;
}
示例#15
0
void Period::changePart(int s)
{
	if(!type) { addSecs(s*secs()); return; }
	uint np = type->parts.size();
	if(np)
	{
		uint p = (part + np + s)%np;
		if(part == 0 && s < 0) add(t1, type->base, -1);
		if(part == np - 1 && s > 0) add(t1, type->base, 1);
		part = p;
		QDateTime dt = set(from(), type->base, type->parts[part]);
		setFrom(dt); setTo(dt);
		p = (part + 1)%np;
                if(part == np - 1) add(t2, type->base, 1);
		setTo(set(to(), type->base, type->parts[p]));
	}
	else
	{
		setFrom(set(from(), type->base));
		add(t1, type->base, s);
		t2 = t1;
		add(t2, type->base, 1);
	}
}
示例#16
0
/**
 * Perform the client part of the middleBox testing. The middlebox test
 * is a 5.0 second throughput test from the Server to the Client to
 * check for duplex mismatch conditions. It determines if routers or
 * switches in the path may be making changes to some TCP parameters.
 * @param ctlSocket server control socket descriptor
 * @param tests set of tests to perform
 * @param host hostname of the server
 * @param conn_options connection options
 * @param buf_size TCP send/receive buffer size
 * @param testresult_str result obtained from server (containing server ip,
 * 						client ip, currentMSS, WinSCaleSent, WinScaleRcvd)
 * @param jsonSupport Indicates if messages should be sent using JSON format
 * @return  integer
 *     => 0 on success
 *     < 0 if error
 *     Return codes used:
 *     0 = (the test has been finalized)
 *     > 0 if protocol interactions were not as expected:
 *     		1: Unable to receive protocol message successfully
 * 			2: Wrong message type received
 *			3: Protocol message received was of invalid length
 *			4: Protocol payload data received was invalid
 *			5: Protocol message received was invalid
 *     < 0 if generic error:
 *			-3: Unable to resolve server address
 *			-10: creating connection to server failed
 *
 */
int test_mid_clt(int ctlSocket, char tests, char* host, int conn_options,
                 int buf_size, char* testresult_str, int jsonSupport) {
  char buff[BUFFSIZE + 1];
  int msgLen, msgType;
  int midport = atoi(PORT3);
  I2Addr sec_addr = NULL;
  int retcode, inlth;
  int in2Socket;
  double t, spdin;
  uint32_t bytes;
  struct timeval sel_tv;
  fd_set rfd;
  char* jsonMsgValue;

  enum TEST_STATUS_INT teststatuses = TEST_NOT_STARTED;
  enum TEST_ID testids = MIDDLEBOX;

  if (tests & TEST_MID) {  // middlebox test has to be performed
    log_println(1, " <-- Middlebox test -->");
    setCurrentTest(TEST_MID);
    // protocol logs
    teststatuses = TEST_STARTED;
    protolog_status(getpid(), testids, teststatuses, ctlSocket);


    //  Initially, expecting a TEST_PREPARE message. Any other message
    // ..type is unexpected at this stage.

    msgLen = sizeof(buff);
    if (recv_msg(ctlSocket, &msgType, buff, &msgLen)) {
      log_println(0, "Protocol error - missed prepare message!");
      return 1;
    }
    if (check_msg_type(MIDBOX_TEST_LOG, TEST_PREPARE, msgType, buff, msgLen)) {
      return 2;
    }

    // The server is expected to send a message with a valid payload that
    // contains the port number that server wants client to bind to for this
    // test
    buff[msgLen] = 0;
    if (jsonSupport) {
      jsonMsgValue = json_read_map_value(buff, DEFAULT_KEY);
      strlcpy(buff, jsonMsgValue, sizeof(buff));
      msgLen = strlen(buff);
      free(jsonMsgValue);
    }
    if (msgLen <= 0) {
      log_println(0, "Improper message");
      return 3;
    }
    if (check_int(buff, &midport)) {  // obtained message does not contain
                                      // integer port#
      log_println(0, "Invalid port number");
      return 4;
    }

    // get server address and set port
    log_println(1, "  -- port: %d", midport);
    if ((sec_addr = I2AddrByNode(get_errhandle(), host)) == NULL) {
      log_println(0, "Unable to resolve server address: %s", strerror(errno));
      return -3;
    }
    I2AddrSetPort(sec_addr, midport);

    // debug to check if correct port was set in addr struct
    if (get_debuglvl() > 4) {
      char tmpbuff[200];
      size_t tmpBufLen = 199;
      memset(tmpbuff, 0, 200);
      I2AddrNodeName(sec_addr, tmpbuff, &tmpBufLen);
      log_println(5, "connecting to %s:%d", tmpbuff, I2AddrPort(sec_addr));
    }

    // connect to server using port obtained above
    if ((retcode = CreateConnectSocket(&in2Socket, NULL, sec_addr,
                                       conn_options, buf_size))) {
      log_println(0, "Connect() for middlebox failed: %s", strerror(errno));
      return -10;
    }

    // start reading throughput test data from server using the connection
    // created above
    printf("Checking for Middleboxes . . . . . . . . . . . . . . . . . .  ");
    fflush(stdout);
    testresult_str[0] = '\0';
    bytes = 0;
    t = secs() + 5.0;  // set timer for 5 seconds, and read for 5 seconds
    sel_tv.tv_sec = 6;  // Time out the socket after 6.5 seconds
    sel_tv.tv_usec = 5;  // 500?
    FD_ZERO(&rfd);
    FD_SET(in2Socket, &rfd);
    for (;;) {
      if (secs() > t)
        break;
      retcode = select(in2Socket+1, &rfd, NULL, NULL, &sel_tv);
      if (retcode > 0) {
        inlth = read(in2Socket, buff, sizeof(buff));
        if (inlth == 0)
          break;
        bytes += inlth;
        continue;
      }
      if (retcode < 0) {
        printf("nothing to read, exiting read loop\n");
        break;
      }
      if (retcode == 0) {
        printf("timer expired, exiting read loop\n");
        break;
      }
    }
    // get actual time for which test was run
    t = secs() - t + 5.0;

    // calculate throughput in Kbps
    spdin = ((BITS_8_FLOAT * bytes) / KILO) / t;

    // Test is complete. Now, get results from server (includes CurrentMSS,
    // WinScaleSent, WinScaleRcvd..).
    // The results are sent from server in the form of a TEST_MSG object
    msgLen = sizeof(buff);
    if (recv_msg(ctlSocket, &msgType, buff, &msgLen)) {
      log_println(0, "Protocol error - missed text message!");
      return 1;
    }
    if (check_msg_type(MIDBOX_TEST_LOG " results", TEST_MSG, msgType, buff,
                       msgLen)) {
      return 2;
    }
    buff[msgLen] = 0;

    strlcat(testresult_str, buff, MIDBOX_TEST_RES_SIZE);

    memset(buff, 0, sizeof(buff));
    // this should work since the throughput results from the server should
    //  ...fit well within BUFFSIZE
    snprintf(buff, sizeof(buff), "%0.0f", spdin);
    log_println(4, "CWND limited speed = %0.2f kbps", spdin);

    // client now sends throughput it calculated above to server, as a TEST_MSG
    send_json_message(ctlSocket, TEST_MSG, buff, strlen(buff), jsonSupport, JSON_SINGLE_VALUE);
    printf("Done\n");

    I2AddrFree(sec_addr);

    // Expect an empty TEST_FINALIZE message from server
    msgLen = sizeof(buff);
    if (recv_msg(ctlSocket, &msgType, buff, &msgLen)) {
      log_println(0, "Protocol error - missed finalize message!");
      return 1;
    }
    if (check_msg_type(MIDBOX_TEST_LOG, TEST_FINALIZE, msgType, buff, msgLen)) {
      return 2;
    }
    log_println(1, " <-------------------->");
    // log protocol test ending
    teststatuses = TEST_ENDED;
    protolog_status(getpid(), testids, teststatuses, ctlSocket);
    setCurrentTest(TEST_NONE);
  }
  return 0;
}
示例#17
0
RideFile *CsvFileReader::openRideFile(QFile &file, QStringList &errors, QList<RideFile*>*) const
{
    CsvType csvType = generic;

    QRegExp metricUnits("(km|kph|km/h)", Qt::CaseInsensitive);
    QRegExp englishUnits("(miles|mph|mp/h)", Qt::CaseInsensitive);
    QRegExp degCUnits("Temperature .*C", Qt::CaseInsensitive);
    QRegExp degFUnits("Temperature .*F", Qt::CaseInsensitive);
    bool metric = true;
    enum temperature { degF, degC, degNone };
    typedef enum temperature Temperature;
    static Temperature tempType = degNone;
    QDateTime startTime;

    // Minutes,Torq (N-m),Km/h,Watts,Km,Cadence,Hrate,ID
    // Minutes, Torq (N-m),Km/h,Watts,Km,Cadence,Hrate,ID
    // Minutes,Torq (N-m),Km/h,Watts,Km,Cadence,Hrate,ID,Altitude (m)
    QRegExp powertapCSV("Minutes,[ ]?Torq \\(N-m\\),(Km/h|MPH),Watts,(Km|Miles),Cadence,Hrate,ID", Qt::CaseInsensitive);

    // TODO: a more robust regex for ergomo files
    // i don't have an example with english headers
    // the ergomo CSV has two rows of headers. units are on the second row.
    /*
    ZEIT,STRECKE,POWER,RPM,SPEED,PULS,HÖHE,TEMP,INTERVAL,PAUSE
    L_SEC,KM,WATT,RPM,KM/H,BPM,METER,°C,NUM,SEC
    */
    QRegExp ergomoCSV("(ZEIT|STRECKE)", Qt::CaseInsensitive);

    QRegExp motoActvCSV("activity_id", Qt::CaseInsensitive);
    bool epoch_set = false;
    quint64 epoch_offset=0;
    QChar ergomo_separator;
    int unitsHeader = 1;
    int total_pause = 0;
    int currentInterval = 0;
    int prevInterval = 0;
    double lastKM=0; // when deriving distance from speed

    /* Joule 1.0
    Version,Date/Time,Km,Minutes,RPE,Tags,"Weight, kg","Work, kJ",FTP,"Sample Rate, s",Device Type,Firmware Version,Last Updated,Category 1,Category 2
    6,2012-11-27 13:40:41,0,0,0,,55.8,788,227,1,Joule,18.018,,0,
    User Name,Power Zone 1,Power Zone 2,Power Zone 3,Power Zone 4,Power Zone 5,Power Zone 6,HR Zone 1,HR Zone 2,HR Zone 3,HR Zone 4,HR Zone 5,Calc Power A,Calc Power B,Calc Power 
    ,0,0,0,0,0,0,150,160,170,180,250,0,-0,
    Minutes, Torq (N-m),Km/h,Watts,Km,Cadence,Hrate,ID,Altitude (m),Temperature (�C),"Grade, %",Latitude,Longitude,Power Calc'd,Calc Power,Right Pedal,Pedal Power %,Cad. Smoot
    0,0,0,45,0,0,69,0,62,16.7,0,0,0,0,0,0,0,
    */
    QRegExp jouleCSV("Device Type,Firmware Version", Qt::CaseInsensitive);
    QRegExp jouleMetriCSV(",Km,", Qt::CaseInsensitive);

    // TODO: with all these formats, should the logic change to a switch/case structure?
    // The iBike format CSV file has five lines of headers (data begins on line 6)
    // starting with:
    /*
    iBike,8,english
    2008,8,8,6,32,52

    {Various configuration data, recording interval at line[4][4]}
    Speed (mph),Wind Speed (mph),Power (W),Distance (miles),Cadence (RPM),Heartrate (BPM),Elevation (feet),Hill slope (%),Internal,Internal,Internal,DFPM Power,Latitude,Longitude
    */

    QRegExp iBikeCSV("iBike,\\d\\d?,[a-z]+", Qt::CaseInsensitive);
    QRegExp moxyCSV("FW Part Number:", Qt::CaseInsensitive);
    QRegExp gcCSV("secs, cad, hr, km, kph, nm, watts, alt, lon, lat, headwind, slope, temp, interval, lrbalance, lte, rte, lps, rps, smo2, thb, o2hb, hhb");
    QRegExp periCSV("mm-dd,hh:mm:ss,SmO2 Live,SmO2 Averaged,THb,Target Power,Heart Rate,Speed,Power,Cadence");
    QRegExp freemotionCSV("Stages Data", Qt::CaseInsensitive);
    QRegExp cpexportCSV("seconds, value,[ model,]* date", Qt::CaseInsensitive);


    int recInterval = 1;

    if (!file.open(QFile::ReadOnly)) {
        errors << ("Could not open ride file: \""
                   + file.fileName() + "\"");
        return NULL;
    }
    int lineno = 1;
    QTextStream is(&file);
    RideFile *rideFile = new RideFile();
    int iBikeInterval = 0;
    bool dfpmExists   = false;
    int iBikeVersion  = 0;

    int secsIndex, minutesIndex = -1;

    double precWork=0.0;

    bool eof = false;
    while (!is.atEnd() && !eof) {
        // the readLine() method doesn't handle old Macintosh CR line endings
        // this workaround will load the the entire file if it has CR endings
        // then split and loop through each line
        // otherwise, there will be nothing to split and it will read each line as expected.
        QString linesIn = is.readLine();
        QStringList lines = linesIn.split('\r');
        // workaround for empty lines
        if(lines.isEmpty()) {
            lineno++;
            continue;
        }
        for (int li = 0; li < lines.size(); ++li) {
            QString line = lines[li];

            if (line.length()==0) {
                continue;
            }

            if (lineno == 1) {
                if (ergomoCSV.indexIn(line) != -1) {
                    csvType = ergomo;
                    rideFile->setDeviceType("Ergomo");
                    rideFile->setFileFormat("Ergomo CSV (csv)");
                    unitsHeader = 2;

                    QStringList headers = line.split(';');

                    if (headers.size()>1)
                        ergomo_separator = ';';
                    else
                        ergomo_separator = ',';

                    ++lineno;
                    continue;
                }
                else if(iBikeCSV.indexIn(line) != -1) {
                    csvType = ibike;
                    rideFile->setDeviceType("iBike");
                    rideFile->setFileFormat("iBike CSV (csv)");
                    unitsHeader = 5;
                    iBikeVersion = line.section( ',', 1, 1 ).toInt();
                    ++lineno;
                    continue;
                }
                else if(motoActvCSV.indexIn(line) != -1) {
                    csvType = motoactv;
                    rideFile->setDeviceType("MotoACTV");
                    rideFile->setFileFormat("MotoACTV CSV (csv)");
                    unitsHeader = -1;
                    /* MotoACTV files are always metric */
                    metric = true;
                    ++lineno;
                    continue;
                 }
                 else if(jouleCSV.indexIn(line) != -1) {
                    csvType = joule;
                    rideFile->setDeviceType("Joule");
                    rideFile->setFileFormat("Joule CSV (csv)");
                    if(jouleMetriCSV.indexIn(line) != -1) {
                        unitsHeader = 5;
                        metric = true;
                    }
                    else { /* ? */ }
                    ++lineno;
                    continue;
                 }
                 else if(moxyCSV.indexIn(line) != -1) {
                    csvType = moxy;
                    rideFile->setDeviceType("Moxy");
                    rideFile->setFileFormat("Moxy CSV (csv)");
                    unitsHeader = 4;
                    recInterval = 1;
                    ++lineno;
                    continue;
                }
                else if(gcCSV.indexIn(line) != -1) {
                    csvType = gc;
                    rideFile->setDeviceType("GoldenCheetah");
                    rideFile->setFileFormat("GoldenCheetah CSV (csv)");
                    unitsHeader = 1;
                    recInterval = 1;
                    ++lineno;
                    continue;
               }
                else if(periCSV.indexIn(line) != -1) {
                    csvType = peripedal;
                    rideFile->setDeviceType("Peripedal");
                    rideFile->setFileFormat("Peripedal CSV (csv)");
                    unitsHeader = 1;
                    recInterval = 1;
                    ++lineno;
                    continue;
               }
               else if(powertapCSV.indexIn(line) != -1) {
                    csvType = powertap;
                    rideFile->setDeviceType("PowerTap");
                    rideFile->setFileFormat("PowerTap CSV (csv)");
                    unitsHeader = 1;
                    ++lineno;
                    continue;
               }
               else if(freemotionCSV.indexIn(line) != -1) {
                    csvType = freemotion;
                    rideFile->setDeviceType("Freemotion Bike");
                    rideFile->setFileFormat("Stages Data (csv)");
                    unitsHeader = 3;
                    ++lineno;
                    continue;
               }
               else if(cpexportCSV.indexIn(line) != -1) {
                    csvType = cpexport;
                    rideFile->setDeviceType("CP Plot Export");
                    rideFile->setFileFormat("CP Plot Export (csv)");
                    unitsHeader = 1;
                    ++lineno;
                    continue;
               }
               else {  // default
                    csvType = generic;
                    rideFile->setDeviceType("Unknow");
                    rideFile->setFileFormat("Generic CSV (csv)");
               }
            }
            if (csvType == ibike) {
                if (lineno == 2) {
                    QStringList f = line.split(",");
                    if (f.size() == 6) {
                        startTime = QDateTime(
                            QDate(f[0].toInt(), f[1].toInt(), f[2].toInt()),
                            QTime(f[3].toInt(), f[4].toInt(), f[5].toInt()));
                    }
                }
                else if (lineno == 4) {
                    // this is the line with the iBike configuration data
                    // recording interval is in the [4] location (zero-based array)
                    // the trailing zeroes in the configuration area seem to be causing an error
                    // the number is in the format 5.000000
                    recInterval = (int)line.section(',',4,4).toDouble();
                }
            }

            if (csvType == freemotion) {
                if (lineno == 2) {
                    if (line == "English")
                        metric = false;
                }
            }



            if (csvType == joule && lineno == 2) {
                // 6,2012-11-27 13:40:41,0,0,0,,55.8,788,227,1,Joule,18.018,,0,
                QStringList f = line.split(",");
                if (f.size() >= 2) {
                    int f0l;
                    QStringList f0 = f[1].split("|");
                    // new format? due to new PowerAgent version (7.5.7.34)?
                    // 6,2011-01-02 21:22:20|2011-01-02 21:22|01/02/2011 21:22|2011-01-02 21-22-20,0,0, ...

                    f0l = f0.size();
                    if (f0l >= 2) {
                       startTime = QDateTime::fromString(f0[0], "yyyy-MM-dd H:mm:ss");
                    } else {
                       startTime = QDateTime::fromString(f[1], "yyyy-MM-dd H:mm:ss");
                    }
                }
            }
            if (lineno == unitsHeader && csvType == generic) {
                QRegExp timeHeaderSecs("( )*(secs|sec|time)( )*", Qt::CaseInsensitive);
                QRegExp timeHeaderMins("( )*(min|minutes)( )*", Qt::CaseInsensitive);
                QStringList headers = line.split(",");

                QStringListIterator i(headers);

                while (i.hasNext()) {
                    QString header = i.next();
                    if (timeHeaderSecs.indexIn(header) != -1)  {
                        secsIndex = headers.indexOf(header);
                    } else if (timeHeaderMins.indexIn(header) != -1)  {
                        minutesIndex = headers.indexOf(header);
                    }
                }
            }
            else if (lineno == unitsHeader && csvType != moxy && csvType != peripedal) {
                if (metricUnits.indexIn(line) != -1)
                    metric = true;
                else if (englishUnits.indexIn(line) != -1)
                    metric = false;
                else {
                    errors << "Can't find units in first line: \"" + line + "\" of file \"" + file.fileName() + "\".";
                    delete rideFile;
                    file.close();
                    return NULL;
                }

                if (degCUnits.indexIn(line) != -1)
                    tempType = degC;
                else if (degFUnits.indexIn(line) != -1)
                    tempType = degF;

            } else if (lineno > unitsHeader) {
                double minutes=0,nm=0,kph=0,watts=0,km=0,cad=0,alt=0,hr=0,dfpm=0, seconds=0.0;
                double temp=RideFile::NoTemp;
                double slope=0.0;
                bool ok;
                double lat = 0.0, lon = 0.0;
                double headwind = 0.0;
                double lrbalance = 0.0;
                double lte = 0.0, rte = 0.0;
                double lps = 0.0, rps = 0.0;
                double smo2 = 0.0, thb = 0.0;
                double o2hb = 0.0, hhb = 0.0;
                int interval=0;
                int pause=0;


                quint64 ms;

                if (csvType == powertap || csvType == joule) {
                     minutes = line.section(',', 0, 0).toDouble();
                     nm = line.section(',', 1, 1).toDouble();
                     kph = line.section(',', 2, 2).toDouble();
                     watts = line.section(',', 3, 3).toDouble();
                     km = line.section(',', 4, 4).toDouble();
                     cad = line.section(',', 5, 5).toDouble();
                     hr = line.section(',', 6, 6).toDouble();
                     interval = line.section(',', 7, 7).toInt();
                     alt = line.section(',', 8, 8).toDouble();
                    if (csvType == joule && tempType != degNone) {
                        // is the position always the same?
                        // should we read the header and assign positions
                        // to each item instead?
                        temp = line.section(',', 9, 9).toDouble();
                        if (tempType == degF) {
                           // convert to deg C
                           temp *= FAHRENHEIT_PER_CENTIGRADE + FAHRENHEIT_ADD_CENTIGRADE;
                        }
                    }
                    if (!metric) {
                        km *= KM_PER_MILE;
                        kph *= KM_PER_MILE;
                        alt *= METERS_PER_FOOT;
                    }

                } else if (csvType == gc) {
                    // GoldenCheetah CVS Format "secs, cad, hr, km, kph, nm, watts, alt, lon, lat, headwind, slope, temp, interval, lrbalance, lte, rte, lps, rps, smo2, thb, o2hb, hhb\n";

                    seconds = line.section(',', 0, 0).toDouble();
                    minutes = seconds / 60.0f;
                    cad = line.section(',', 1, 1).toDouble();
                    hr = line.section(',', 2, 2).toDouble();
                    km = line.section(',', 3, 3).toDouble();
                    kph = line.section(',', 4, 4).toDouble();
                    nm = line.section(',', 5, 5).toDouble();
                    watts = line.section(',', 6, 6).toDouble();
                    alt = line.section(',', 7, 7).toDouble();
                    lon = line.section(',', 8, 8).toDouble();
                    lat = line.section(',', 9, 9).toDouble();
                    headwind = line.section(',', 10, 10).toDouble();
                    slope = line.section(',', 11, 11).toDouble();
                    temp = line.section(',', 12, 12).toDouble();
                    interval = line.section(',', 13, 13).toInt();
                    lrbalance = line.section(',', 14, 14).toInt();
                    lte = line.section(',', 15, 15).toInt();
                    rte = line.section(',', 16, 16).toInt();
                    lps = line.section(',', 17, 17).toInt();
                    rps = line.section(',', 18, 18).toInt();
                    smo2 = line.section(',', 19, 19).toInt();
                    thb = line.section(',', 20, 20).toInt();
                    o2hb = line.section(',', 21, 21).toInt();
                    hhb = line.section(',', 22, 22).toInt();

                } else if (csvType == peripedal) {

                    //mm-dd,hh:mm:ss,SmO2 Live,SmO2 Averaged,THb,Target Power,Heart Rate,Speed,Power,Cadence
                    // ignore lines with wrong number of entries
                    if (line.split(",").count() != 10) continue;

                    seconds = moxySeconds(line.section(',',1,1));
                    minutes = seconds / 60.0f;

                    if (startTime == QDateTime()) {
                        QDate date = periDate(line.section(',',0,0));
                        QTime time = QTime(0,0,0).addSecs(seconds);
                        startTime = QDateTime(date,time);
                    }

                    double aSmo2 = line.section(',', 3, 3).toDouble();
                    smo2 = line.section(',', 2, 2).toDouble();

                    // use average if live not available
                    if (aSmo2 && !smo2) smo2 = aSmo2;

                    thb = line.section(',', 4, 4).toDouble();
                    hr = line.section(',', 6, 6).toDouble();
                    kph = line.section(',', 7, 7).toDouble();
                    watts = line.section(',', 8, 8).toDouble();
                    cad = line.section(',', 10, 10).toDouble();

                    // dervice distance from speed
                    km = lastKM + (kph/3600.0f);
                    lastKM = km;

                    nm = 0;
                    alt = 0;
                    lon = 0;
                    lat = 0;
                    headwind = 0;
                    slope = 0;
                    temp = 0;
                    interval = 0;
                    lrbalance = 0;
                    lte = 0;
                    rte = 0;
                    lps = 0;
                    rps = 0;
                    o2hb = 0;
                    hhb = 0;

                } else if (csvType == freemotion) {
                    if (line == "Ride_Totals") {
                        eof = true;
                        continue;
                    }
                    // Time,Miles,MPH,Watts,HR,RPM

                    seconds = QTime::fromString(line.section(',', 0, 0), "m:s").second();
                    minutes = QTime::fromString(line.section(',', 0, 0), "m:s").minute() + seconds / 60.0f;
                    cad = line.section(',', 5, 5).toDouble();
                    hr = line.section(',', 4, 4).toDouble();
                    km = line.section(',', 1, 1).toDouble();
                    kph = line.section(',', 2, 2).toDouble();
                    watts = line.section(',', 3, 3).toDouble();

                    if (!metric) {
                        km *= KM_PER_MILE;
                        kph *= KM_PER_MILE;
                    }

               } else if (csvType == ibike) {
                    // this must be iBike
                    // can't find time as a column.
                    // will we have to extrapolate based on the recording interval?
                    // reading recording interval from config data in ibike csv file
                    //
                    // For iBike software version 11 or higher:
                    // use "power" field until a the "dfpm" field becomes non-zero.
                     minutes = (recInterval * lineno - unitsHeader)/60.0;
                     nm = 0; //no torque
                     kph = line.section(',', 0, 0).toDouble();
                     dfpm = line.section( ',', 11, 11).toDouble();
                     headwind = line.section(',', 1, 1).toDouble();
                     if( iBikeVersion >= 11 && ( dfpm > 0.0 || dfpmExists ) ) {
                         dfpmExists = true;
                         watts = dfpm;
                     }
                     else {
                         watts = line.section(',', 2, 2).toDouble();
                     }
                     km = line.section(',', 3, 3).toDouble();
                     cad = line.section(',', 4, 4).toDouble();
                     hr = line.section(',', 5, 5).toDouble();
                     alt = line.section(',', 6, 6).toDouble();
                     slope = line.section(',', 7, 7).toDouble();
                     temp = line.section(',', 8, 8).toDouble();
                     lat = line.section(',', 12, 12).toDouble();
                     lon = line.section(',', 13, 13).toDouble();


                     int lap = line.section(',', 9, 9).toInt();
                     if (lap > 0) {
                         iBikeInterval += 1;
                         interval = iBikeInterval;
                     }
                    if (!metric) {
                        km *= KM_PER_MILE;
                        kph *= KM_PER_MILE;
                        alt *= METERS_PER_FOOT;
                        headwind *= KM_PER_MILE;
                    }

                } else if (csvType == moxy)  {

                    // we get crappy lines with no data so ignore them
                    // I think they're supposed to be delimiters for the file
                    // content, but are just noise to us !
                    if (line == (" ,,,,,") || line == ",,,,," ||
                        line == "" || line == " ") continue;

                    // need to get time from second column and note that
                    // there will be gaps when recording drops so shouldn't
                    // assume it is a continuous stream
                    double seconds = moxySeconds(line.section(',',1,1));

                    if (startTime == QDateTime()) {
                        QDate date = moxyDate(line.section(',',0,0));
                        QTime time = QTime(0,0,0).addSecs(seconds);
                        startTime = QDateTime(date,time);
                    }

                    if (seconds >0) {
                        minutes = seconds / 60.0f;
                        smo2 = line.section(',', 2, 2).remove("\"").toDouble();
                        thb = line.section(',', 4, 4).remove("\"").toDouble();
                    }
                }
               else if(csvType == motoactv) {
                    /* MotoActv saves it all as kind of SI (m, ms, m/s, NM etc)
                     *  "double","double",.. so we need to filter out "
                     */

                    km = line.section(',', 0,0).remove("\"").toDouble()/1000;
                    hr = line.section(',', 2, 2).remove("\"").toDouble();
                    kph = line.section(',', 3, 3).remove("\"").toDouble()*3.6;

                    lat = line.section(',', 5, 5).remove("\"").toDouble();
                    /* Item 8 is crank torque, 13 is wheel torque */
                    nm = line.section(',', 8, 8).remove("\"").toDouble();

                    /* Ok there's no crank torque, try the wheel */
                    if(nm == 0.0) {
                         nm = line.section(',', 13, 13).remove("\"").toDouble();
                    }
                    if(epoch_set == false) {
                         epoch_set = true;
                         epoch_offset = line.section(',', 9,9).remove("\"").toULongLong(&ok, 10);

                         /* We use this first value as the start time */
                         startTime = QDateTime();
                         startTime.setMSecsSinceEpoch(epoch_offset);
                         rideFile->setStartTime(startTime);
                    }

                    ms = line.section(',', 9,9).remove("\"").toULongLong(&ok, 10);
                    ms -= epoch_offset;
                    seconds = ms/1000;

                    alt = line.section(',', 10, 10).remove("\"").toDouble();
                    watts = line.section(',', 11, 11).remove("\"").toDouble();
                    lon = line.section(',', 15, 15).remove("\"").toDouble();
                    cad = line.section(',', 16, 16).remove("\"").toDouble();
               }
                else if (csvType == ergomo) {
                     // for ergomo formatted CSV files
                     minutes     = line.section(ergomo_separator, 0, 0).toDouble() + total_pause;
                     QString km_string = line.section(ergomo_separator, 1, 1);
                     km_string.replace(",",".");
                     km = km_string.toDouble();
                     watts = line.section(ergomo_separator, 2, 2).toDouble();
                     cad = line.section(ergomo_separator, 3, 3).toDouble();
                     QString kph_string = line.section(ergomo_separator, 4, 4);
                     kph_string.replace(",",".");
                     kph = kph_string.toDouble();
                     hr = line.section(ergomo_separator, 5, 5).toDouble();
                     alt = line.section(ergomo_separator, 6, 6).toDouble();
                     interval = line.section(',', 8, 8).toInt();
                     if (interval != prevInterval) {
                         prevInterval = interval;
                         if (interval != 0) currentInterval++;
                     }
                     if (interval != 0) interval = currentInterval;
                     pause = line.section(ergomo_separator, 9, 9).toInt();
                     total_pause += pause;
                     nm = 0; // torque is not provided in the Ergomo file

                     // the ergomo records the time in whole seconds
                     // RECORDING INT. 1, 2, 5, 10, 15 or 30 per sec
                     // Time is *always* perfectly sequential.  To find pauses,
                     // you need to read the PAUSE column.
                     minutes = minutes/60.0;

                     if (!metric) {
                         km *= KM_PER_MILE;
                         kph *= KM_PER_MILE;
                         alt *= METERS_PER_FOOT;
                     }
                } else if (csvType == cpexport) {
                    // seconds, value, (model), date
                    seconds = line.section(',',0,0).toDouble();
                    minutes = seconds / 60.0f;

                    seconds = lineno -1 ;
                    double avgwatts = line.section(',', 1, 1).toDouble();

                    watts = avgwatts * seconds - precWork; // 1000 * 1 - 700

                    precWork = avgwatts * seconds;
               } else {
                    if (secsIndex > -1) {
                        seconds = line.section(',', secsIndex, secsIndex).toDouble();
                        minutes = seconds / 60.0f;
                     }
                }

                // PT reports no data as watts == -1.
                if (watts == -1)
                    watts = 0;

               if(csvType == motoactv)
                    rideFile->appendPoint(seconds, cad, hr, km,
                                          kph, nm, watts, alt, lon, lat, 0.0,
                                          0.0, temp, 0.0, 0.0, 0.0, 0.0, 0.0,
                                          0.0, 0.0, 0.0, 0.0,
                                          0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
                                          0.0, 0.0, 0.0, 0.0, 0.0, interval);
               else if (csvType == moxy) {

                    // hack it in for now
                    // XXX IT COULD BE RECORDED WITH DIFFERENT INTERVALS XXX
                    rideFile->appendPoint(minutes * 60.0, cad, hr, km,
                                          kph, nm, watts, alt, lon, lat,
                                          headwind, slope, temp, 0.0,
                                          0.0, 0.0, 0.0, 0.0,
                                          0.0, 0.0,
                                          0.0, 0.0, 0.0, 0.0,
                                          0.0, 0.0, 0.0, 0.0,
                                          smo2, thb, 0.0, 0.0, 0.0, interval);
                    rideFile->appendPoint((minutes * 60.0)+1, cad, hr, km, // dupe it so we have 1s recording easier to merge
                                          kph, nm, watts, alt, lon, lat,
                                          headwind, slope, temp, 0.0,
                                          0.0, 0.0, 0.0, 0.0,
                                          0.0, 0.0,
                                          0.0, 0.0, 0.0, 0.0,
                                          0.0, 0.0, 0.0, 0.0,
                                          smo2, thb, 0.0, 0.0, 0.0, interval);

               } else {
                    rideFile->appendPoint(minutes * 60.0, cad, hr, km,
                                          kph, nm, watts, alt, lon, lat,
                                          headwind, slope, temp, lrbalance,
                                          lte, rte, lps, rps,
                                          0.0, 0.0,
                                          0.0, 0.0, 0.0, 0.0,
                                          0.0, 0.0, 0.0, 0.0,
                                          smo2, thb, 0.0, 0.0, 0.0, interval);
               }
            }
            ++lineno;
        }
    }
    file.close();

    // To estimate the recording interval, take the median of the
    // first 1000 samples and round to nearest millisecond.
    int n = rideFile->dataPoints().size();
    n = qMin(n, 1000);
    if (n >= 2) {
        QVector<double> secs(n-1);
        for (int i = 0; i < n-1; ++i) {
            double now = rideFile->dataPoints()[i]->secs;
            double then = rideFile->dataPoints()[i+1]->secs;
            secs[i] = then - now;
        }
        std::sort(secs.begin(), secs.end());
        int mid = n / 2 - 1;
        double recint = round(secs[mid] * 1000.0) / 1000.0;
        rideFile->setRecIntSecs(recint);
    }
    // less than 2 data points is not a valid ride file
    else {
        errors << "Insufficient valid data in file \"" + file.fileName() + "\".";
        delete rideFile;
        file.close();
        return NULL;
    }

    QRegExp rideTime("^.*/(\\d\\d\\d\\d)_(\\d\\d)_(\\d\\d)_"
                     "(\\d\\d)_(\\d\\d)_(\\d\\d)\\.csv$");
    rideTime.setCaseSensitivity(Qt::CaseInsensitive);

    if (startTime != QDateTime()) {

        // Start time was already set above?
        rideFile->setStartTime(startTime);

    } else if (rideTime.indexIn(file.fileName()) >= 0) {

        // It matches the GC naming convention?
        QDateTime datetime(QDate(rideTime.cap(1).toInt(),
                                 rideTime.cap(2).toInt(),
                                 rideTime.cap(3).toInt()),
                           QTime(rideTime.cap(4).toInt(),
                                 rideTime.cap(5).toInt(),
                                 rideTime.cap(6).toInt()));
        rideFile->setStartTime(datetime);

    } else {

        // Could be yyyyddmm_hhmmss_NAME.csv (case insensitive)
        rideTime.setPattern("(\\d\\d\\d\\d)(\\d\\d)(\\d\\d)_(\\d\\d)(\\d\\d)(\\d\\d)[^\\.]*\\.csv$");
        if (rideTime.indexIn(file.fileName()) >= 0) {
            QDateTime datetime(QDate(rideTime.cap(1).toInt(),
                                     rideTime.cap(2).toInt(),
                                     rideTime.cap(3).toInt()),
                               QTime(rideTime.cap(4).toInt(),
                                     rideTime.cap(5).toInt(),
                                     rideTime.cap(6).toInt()));
            rideFile->setStartTime(datetime);
        } else {

            // is it in poweragent format "name yyyy-mm-dd hh-mm-ss.csv"
            rideTime.setPattern("(\\d\\d\\d\\d)-(\\d\\d)-(\\d\\d) (\\d\\d)-(\\d\\d)-(\\d\\d)\\.csv$");
            if (rideTime.indexIn(file.fileName()) >=0) {

                QDateTime datetime(QDate(rideTime.cap(1).toInt(),
                                        rideTime.cap(2).toInt(),
                                        rideTime.cap(3).toInt()),
                                QTime(rideTime.cap(4).toInt(),
                                        rideTime.cap(5).toInt(),
                                        rideTime.cap(6).toInt()));
                rideFile->setStartTime(datetime);

            } else {

                // NO DICE

                // Note: qWarning("Failed to set start time");
                // console messages are no use, so commented out
                // this problem will ONLY occur during the import
                // process which traps these and corrects them
                // so no need to do anything here

            }
        }
    }

    // did we actually read any samples?
    if (rideFile->dataPoints().count() > 0) {
        return rideFile;
    } else {
        errors << "No samples present.";
        delete rideFile;
        return NULL;
    }
}
示例#18
0
int confOption::setValueFromFile(QString line)
{
  // Used to set values in confOptions from a file line
  
  QString rval = line.section("=",1).trimmed();

  qDebug() << "setting " << realName << " to " << rval << " (from file)";
    
  if (type == BOOL)
  {
    if (rval == "true" || rval == "on" || rval == "yes")
    {
      value = true;
      return 0;
    }
    else if (rval == "false" || rval == "off" || rval == "no")
    {
      value = false;
      return 0;
    }
    qDebug() << rval << "is not a valid value for setting" << realName << ". Ignoring...";
    return -1;
  }

  else if (type == INTEGER)
  {
    bool ok;
    qlonglong rvalToNmbr = rval.toLongLong(&ok);
    if (ok && rvalToNmbr >= minVal && rvalToNmbr <= maxVal)
    {
      value = rvalToNmbr;
      return 0;
    }
    qDebug() << rval << "is not a valid value for setting" << realName << ". Ignoring...";
    return -1;
  }

  else if (type == STRING)
  {
    value = rval;
    return 0;
  }  
  
  else if (type == LIST)
  {
    if (realName == "ShowStatus") // ShowStatus needs special treatment
    {
      if (rval.toLower() == "true" || rval.toLower() == "on")
        rval = "yes";
      else if (rval.toLower() == "false" || rval.toLower() == "off")
        rval = "no";
    }
    if (possibleVals.contains(rval))
    {
      value = rval.toLower();
      return 0;
    }
    qDebug() << rval << "is not a valid value for setting" << realName << ". Ignoring...";
    value = defVal;
    return -1;
  }

  else if (type == MULTILIST)
  {
    QVariantMap map;

    QStringList readList = rval.split(" ", QString::SkipEmptyParts);
    for (int i = 0; i < readList.size(); ++i)
    {
      if (!possibleVals.contains(readList.at(i)))
      {
        qDebug() << rval << "is not a valid value for setting" << realName << ". Ignoring...";
        return -1;
      }
    }
    
    for (int i = 0; i < possibleVals.size(); ++i)
    {
      if (readList.contains(possibleVals.at(i)))
        map[possibleVals.at(i)] = true;
      else
        map[possibleVals.at(i)] = false;
    }

    value = map;
    return 0;

  }  
  
  else if (type == TIME)
  {
    int pos = 0;
    QRegExp rxValid;

    // These regex check whether rval is a valid time interval
    if (hasNsec)
      rxValid = QRegExp("^(?:\\d*\\.?\\d *(ns|nsec|us|usec|ms|msec|s|sec|second|seconds|m|min|minute|minutes|h|hr|hour|hours|d|day|days|w|week|weeks|month|months|y|year|years)? *)+$");
    else
      rxValid = QRegExp("^(?:\\d*\\.?\\d *(us|usec|ms|msec|s|sec|second|seconds|m|min|minute|minutes|h|hr|hour|hours|d|day|days|w|week|weeks|month|months|y|year|years)? *)+$");

    pos = rxValid.indexIn(rval);

    if (pos > -1)
    {
      pos = 0;
      seconds secs(0);

      // This regex parses individual elements of the time interval
      QRegExp rxTimeParse = QRegExp("(\\d*\\.?\\d+) *([a-z]*)");

      while ((pos = rxTimeParse.indexIn(rval, pos)) != -1)
      {
        if (rxTimeParse.cap(2) == "ns" ||
            rxTimeParse.cap(2) == "nsec" )
        {
          nanoseconds ns(rxTimeParse.cap(1).trimmed().toDouble());
          secs += ns;
        }
        else if (rxTimeParse.cap(2) == "us" ||
            rxTimeParse.cap(2) == "usec" )
        {
          microseconds us(rxTimeParse.cap(1).trimmed().toDouble());
          secs += us;
        }
        else if (rxTimeParse.cap(2) == "ms" ||
            rxTimeParse.cap(2) == "msec" )
        {
          milliseconds ms(rxTimeParse.cap(1).trimmed().toDouble());
          secs += ms;
        }
        else if (rxTimeParse.cap(2) == "s" ||
                 rxTimeParse.cap(2) == "sec" ||
                 rxTimeParse.cap(2) == "second" ||
                 rxTimeParse.cap(2) == "seconds" )
        {
          seconds s(rxTimeParse.cap(1).trimmed().toDouble());
          secs += s;
        }
        else if (rxTimeParse.cap(2) == "m" ||
                 rxTimeParse.cap(2) == "min" ||
                 rxTimeParse.cap(2) == "minute" ||
                 rxTimeParse.cap(2) == "minutes" )
        {
          minutes min(rxTimeParse.cap(1).trimmed().toDouble());
          secs += min;
        }
        else if (rxTimeParse.cap(2) == "h" ||
                 rxTimeParse.cap(2) == "hr" ||
                 rxTimeParse.cap(2) == "hour" ||
                 rxTimeParse.cap(2) == "hours" )
        {
          hours hr(rxTimeParse.cap(1).trimmed().toDouble());
          secs += hr;
        }
        else if (rxTimeParse.cap(2) == "d" ||
                 rxTimeParse.cap(2) == "day" ||
                 rxTimeParse.cap(2) == "days")
        {
          days dy(rxTimeParse.cap(1).trimmed().toDouble());
          secs += dy;
        }
        else if (rxTimeParse.cap(2) == "w" ||
                 rxTimeParse.cap(2) == "week" ||
                 rxTimeParse.cap(2) == "weeks")
        {
          weeks w(rxTimeParse.cap(1).trimmed().toDouble());
          secs += w;
        }
        else if (rxTimeParse.cap(2) == "month" ||
                 rxTimeParse.cap(2) == "months")
        {
          months m(rxTimeParse.cap(1).trimmed().toDouble());
          secs += m;
        }
        else if (rxTimeParse.cap(2) == "y" ||
                 rxTimeParse.cap(2) == "year" ||
                 rxTimeParse.cap(2) == "years")
        {
          years y(rxTimeParse.cap(1).trimmed().toDouble());
          secs += y;
        }

        else if (rxTimeParse.cap(2).isEmpty())
        {
          // unitless number, convert it from defReadUnit to seconds
          seconds tmpSeconds(convertTimeUnit(rxTimeParse.cap(1).trimmed().toDouble(), defReadUnit, timeUnit::s).toDouble());
          secs += tmpSeconds;
        }

        pos += rxTimeParse.matchedLength();
      }

      // Convert the read value in seconds to defUnit
      if (defUnit == ns)
        value = nanoseconds(secs).count();
      else if (defUnit == us)
        value = microseconds(secs).count();
      else if (defUnit == ms)
        value = milliseconds(secs).count();
      else if (defUnit == s)
        value = secs.count();
      else if (defUnit == min)
        value = minutes(secs).count();
      else if (defUnit == h)
        value = hours(secs).count();
      else if (defUnit == d)
        value = days(secs).count();
      else if (defUnit == w)
        value = weeks(secs).count();
      else if (defUnit == month)
        value = months(secs).count();
      else if (defUnit == year)
        value = years(secs).count();

      value = value.toULongLong(); // Convert to ulonglong (we don't support float in ui)
      return 0;

    }
    else
    {
      qDebug() << rval << "is not a valid value for setting" << realName << ". Ignoring...";
      return -1;
    }
  }
  
  else if (type == RESLIMIT)
  {
    bool ok;
    int nmbr = rval.toUInt(&ok);
    if (ok)
    {
      value = nmbr;
      return 0;
    }
    else if (rval.toLower().trimmed() == "infinity" || rval.trimmed().isEmpty())
    {
      value = -1;
      return 0;
    }
    qDebug() << rval << "is not a valid value for setting" << realName << ". Ignoring...";
    return -1;
    
  }
  
  else if (type == SIZE)
  {
    // RegExp to match a number (possibly with decimals) followed by a size unit (or no unit for byte)
    QRegExp rxSize = QRegExp("(\\b\\d+\\.?\\d*(K|M|G|T|P|E)?\\b)");
    
    int pos = 0;
    pos = rxSize.indexIn(rval);
    if (pos > -1 && rxSize.cap(0) == rval.trimmed())
    {
      // convert the specified size unit to megabytes
      if (rxSize.cap(0).contains("K"))
        value = rxSize.cap(0).remove("K").toDouble() / 1024;
      else if (rxSize.cap(0).contains("M"))
        value = rxSize.cap(0).remove("M").toDouble();
      else if (rxSize.cap(0).contains("G"))
        value = rxSize.cap(0).remove("G").toDouble() * 1024;
      else if (rxSize.cap(0).contains("T"))
        value = rxSize.cap(0).remove("T").toDouble() * 1024 * 1024;
      else if (rxSize.cap(0).contains("P"))
        value = rxSize.cap(0).remove("P").toDouble() * 1024 * 1024 * 1024;
      else if (rxSize.cap(0).contains("E"))
        value = rxSize.cap(0).remove("E").toDouble() * 1024 * 1024 * 1024 * 1024;
      else
        value = rxSize.cap(0).toDouble() / 1024 / 1024;
      
      // Convert from double to ulonglong (we don't support float in ui)
      value = value.toULongLong();
      return 0;
    }
    else
    {
      qDebug() << rval << "is not a valid value for setting" << realName << ". Ignoring...";
      return -1;
    }
   
  }
  return -1;
}
RideFile *Computrainer3dpFileReader::openRideFile(QFile & file,
                                                  QStringList & errors)
    const
{
    if (!file.open(QFile::ReadOnly)) {
        errors << ("Could not open ride file: \"" + file.fileName() +
                   "\"");
        return NULL;
    }

    RideFile *rideFile = new RideFile();
    QDataStream is(&file);

    is.setByteOrder(QDataStream::LittleEndian);

    // looks like the first part is a header... ignore it.
    is.skipRawData(4);
    char perfStr[5];

    is.readRawData(perfStr, 4);
    perfStr[4] = NULL;
    is.skipRawData(0x8);
    char userName[65];
    is.readRawData(userName, 65);
    ubyte age;
    is >> age;
    is.skipRawData(6);
    float weight;
    is >> weight;
    int upperHR;
    is >> upperHR;
    int lowerHR;
    is >> lowerHR;
    int year;
    is >> year;
    ubyte month;
    is >> month;
    ubyte day;
    is >> day;
    ubyte hour;
    is >> hour;
    ubyte minute;
    is >> minute;
    int numberSamples;
    is >> numberSamples;
    // go back to the start, and go to the start of the data samples
    file.seek(0);
    is.skipRawData(0xf8);
    for (; numberSamples; numberSamples--) {
        ubyte hr;
        is >> hr;
        ubyte cad;
        is >> cad;
        unsigned short watts;
        is >> watts;
        float speed;
        is >> speed;
        speed = speed * KM_PER_MILE * 100;
        int ms;
        is >> ms;
        is.skipRawData(4);
        float miles;
        is >> miles;
        float km = miles * KM_PER_MILE;
        is.skipRawData(0x1c);
        rideFile->appendPoint((double) ms / 1000, (double) cad,
                              (double) hr, km, speed, 0.0, watts, 0, 0, 0);

    }
    QDateTime dateTime;
    QDate date;
    QTime time;
    date.setDate(year, month, day);
    time.setHMS(hour, minute, 0, 0);
    dateTime.setDate(date);
    dateTime.setTime(time);

    rideFile->setStartTime(dateTime);

    int n = rideFile->dataPoints().size();
    n = qMin(n, 1000);
    if (n >= 2) {
        QVector < double >secs(n - 1);
        for (int i = 0; i < n - 1; ++i) {
            double now = rideFile->dataPoints()[i]->secs;
            double then = rideFile->dataPoints()[i + 1]->secs;
            secs[i] = then - now;
        }
        std::sort(secs.begin(), secs.end());
        int mid = n / 2 - 1;
        double recint = round(secs[mid] * 1000.0) / 1000.0;
        rideFile->setRecIntSecs(recint);
    }
    rideFile->setDeviceType("Computrainer 3DP");
    file.close();
    return rideFile;
}
示例#20
0
int
test_mid_clt(int ctlSocket, char tests, char* host, int conn_options, int buf_size, char* tmpstr2)
{
  char buff[BUFFSIZE+1];
  int msgLen, msgType;
  int midport = 3003;
  I2Addr sec_addr = NULL;
  int ret, one=1, i, inlth;
  int in2Socket;
  double t, spdin;
  uint32_t bytes;
  struct timeval sel_tv;
  fd_set rfd;

  if (tests & TEST_MID) {
    log_println(1, " <-- Middlebox test -->");
    msgLen = sizeof(buff);
    if (recv_msg(ctlSocket, &msgType, buff, &msgLen)) {
      log_println(0, "Protocol error - missed prepare message!");
      return 1;
    }
    if (check_msg_type("Middlebox test", TEST_PREPARE, msgType, buff, msgLen)) {
      return 2;
    }
    if (msgLen <= 0) {
      log_println(0, "Improper message");
      return 3;
    }
    buff[msgLen] = 0;
    if (check_int(buff, &midport)) {
      log_println(0, "Invalid port number");
      return 4;
    }
    log_println(1, "  -- port: %d", midport);
    if ((sec_addr = I2AddrByNode(get_errhandle(), host)) == NULL) {
      log_println(0, "Unable to resolve server address: %s", strerror(errno));
      return -3;
    }
    I2AddrSetPort(sec_addr, midport);

    if (get_debuglvl() > 4) {
      char tmpbuff[200];
      size_t tmpBufLen = 199;
      memset(tmpbuff, 0, 200);
      I2AddrNodeName(sec_addr, tmpbuff, &tmpBufLen);
      log_println(5, "connecting to %s:%d", tmpbuff, I2AddrPort(sec_addr));
    }

    if ((ret = CreateConnectSocket(&in2Socket, NULL, sec_addr, conn_options, buf_size))) {
      log_println(0, "Connect() for middlebox failed: %s", strerror(errno));
      return -10;
    }

    printf("Checking for Middleboxes . . . . . . . . . . . . . . . . . .  ");
    fflush(stdout);
    tmpstr2[0] = '\0';
    i = 0;
    bytes = 0;
    t = secs() + 5.0;
    sel_tv.tv_sec = 6;
    sel_tv.tv_usec = 5;
    FD_ZERO(&rfd);
    FD_SET(in2Socket, &rfd);
    for (;;) {
      if (secs() > t)
        break;
      ret = select(in2Socket+1, &rfd, NULL, NULL, &sel_tv);
      if (ret > 0) {
        inlth = read(in2Socket, buff, sizeof(buff));
        if (inlth == 0)
          break;
        bytes += inlth;
        continue;
      }
      if (ret < 0) {
        printf("nothing to read, exiting read loop\n");
        break;
      }
      if (ret == 0) {
        printf("timer expired, exiting read loop\n");
        break;
      }
    }
    t =  secs() - t + 5.0;
    spdin = ((8.0 * bytes) / 1000) / t;

    msgLen = sizeof(buff);
    if (recv_msg(ctlSocket, &msgType, buff, &msgLen)) {
      log_println(0, "Protocol error - missed text message!");
      return 1;
    }
    if (check_msg_type("Middlebox test results", TEST_MSG, msgType, buff, msgLen)) {
      return 2;
    }
    strncat(tmpstr2, buff, msgLen);

    memset(buff, 0, 128);
    sprintf(buff, "%0.0f", spdin);
    log_println(4, "CWND limited speed = %0.2f kbps", spdin);
    send_msg(ctlSocket, TEST_MSG, buff, strlen(buff));
    printf("Done\n");

    I2AddrFree(sec_addr);

    msgLen = sizeof(buff);
    if (recv_msg(ctlSocket, &msgType, buff, &msgLen)) {
      log_println(0, "Protocol error - missed finalize message!");
      return 1;
    }
    if (check_msg_type("Middlebox test", TEST_FINALIZE, msgType, buff, msgLen)) {
      return 2;
    }
    log_println(1, " <-------------------->");
  }
  return 0;
}
示例#21
0
 void
 coverQuantisationCornerCases()
   {
     // origin at lower end of the time range
     FixedFrameQuantiser case1 (1, Time::MIN);
     CHECK (secs(0)            == case1.gridAlign(Time::MIN  ));
     CHECK (secs(0)            == case1.gridAlign(Time::MIN +TimeValue(1) ));
     CHECK (secs(1)            == case1.gridAlign(Time::MIN +secs(1) ));
     CHECK (Time::MAX -secs(1) >  case1.gridAlign( secs(-1)  ));
     CHECK (Time::MAX -secs(1) <= case1.gridAlign( secs (0)  ));
     CHECK (Time::MAX          >  case1.gridAlign( secs (0)  ));
     CHECK (Time::MAX          == case1.gridAlign( secs(+1)  ));
     CHECK (Time::MAX          == case1.gridAlign( secs(+2)  ));
     
     // origin at upper end of the time range
     FixedFrameQuantiser case2 (1, Time::MAX);
     CHECK (secs( 0)           == case2.gridAlign(Time::MAX  ));
     CHECK (secs(-1)           == case2.gridAlign(Time::MAX -TimeValue(1) ));  // note: next lower frame
     CHECK (secs(-1)           == case2.gridAlign(Time::MAX -secs(1) ));      //        i.e. the same as a whole frame down
     CHECK (Time::MIN +secs(1) <  case2.gridAlign( secs(+2)  ));
     CHECK (Time::MIN +secs(1) >= case2.gridAlign( secs(+1)  ));
     CHECK (Time::MIN          <  case2.gridAlign( secs(+1)  ));
     CHECK (Time::MIN          == case2.gridAlign( secs( 0)  ));          //      note: because of downward truncating,
     CHECK (Time::MIN          == case2.gridAlign( secs(-1)  ));         //             resulting values will already exceed
     CHECK (Time::MIN          == case2.gridAlign( secs(-2)  ));        //              allowed range and thus will be clipped
     
     // maximum frame size is half the time range
     Duration hugeFrame(Time::MAX);
     FixedFrameQuantiser case3 (hugeFrame);
     CHECK (Time::MIN          == case3.gridAlign(Time::MIN  ));
     CHECK (Time::MIN          == case3.gridAlign(Time::MIN +TimeValue(1) ));
     CHECK (Time::MIN          == case3.gridAlign( secs(-1)  ));
     CHECK (TimeValue(0)       == case3.gridAlign( secs( 0)  ));
     CHECK (TimeValue(0)       == case3.gridAlign( secs(+1)  ));
     CHECK (TimeValue(0)       == case3.gridAlign(Time::MAX -TimeValue(1) ));
     CHECK (Time::MAX          == case3.gridAlign(Time::MAX  ));
     
     // now displacing this grid by +1sec....
     FixedFrameQuantiser case4 (hugeFrame, secs(1));
     CHECK (Time::MIN          == case4.gridAlign(Time::MIN  ));
     CHECK (Time::MIN          == case4.gridAlign(Time::MIN +TimeValue(1) ));  // clipped...
     CHECK (Time::MIN          == case4.gridAlign(Time::MIN +secs(1) ));      //  but now exact (unclipped)
     CHECK (Time::MIN          == case4.gridAlign( secs(-1)  ));
     CHECK (Time::MIN          == case4.gridAlign( secs( 0)  ));
     CHECK (TimeValue(0)       == case4.gridAlign( secs(+1)  ));           //.....now exactly the frame number zero
     CHECK (TimeValue(0)       == case4.gridAlign(Time::MAX -TimeValue(1) ));
     CHECK (TimeValue(0)       == case4.gridAlign(Time::MAX  ));         //.......still truncated down to frame #0
     
     // larger frames aren't possible
     Duration not_really_larger(secs(10000) + hugeFrame);
     CHECK (hugeFrame == not_really_larger);
     
     // frame sizes below the time micro grid get trapped
     long subAtomic = 2*GAVL_TIME_SCALE;                           // too small for this universe...
     VERIFY_ERROR (BOTTOM_VALUE, FixedFrameQuantiser quark(subAtomic) );
     VERIFY_ERROR (BOTTOM_VALUE, FixedFrameQuantiser quark(Duration (FSecs (1,subAtomic))) );
   }
示例#22
0
bool
ServerAgent::ParseENums (const char *data, const char *sWord)
{
	int num (atoi (sWord));

	switch (num)
	{
		case ZERO:								 // 0
			{
				// wasn't a numeric, or the server is playing tricks on us
			}
			return false;

		case ERR_UNKNOWNCOMMAND:	 // 421
			{
				BString tempString (RestOfString (data, 4)),
								badCmd (GetWord (data, 4));

				if (badCmd == "VISION_LAG_CHECK")
				{
					int32 difference (system_time() - fLagCheck);
					if (difference > 0)
					{
						int32 secs (difference / 1000000);
						int32 milli (difference / 1000 - secs * 1000);
						char lag[15] = "";
						sprintf (lag, "%0" B_PRId32 ".%03" B_PRId32, secs, milli);
						fMyLag = lag;
						fLagCount = 0;
						fCheckingLag = false;
						fMsgr.SendMessage (M_LAG_CHANGED);
					}
				}
				else
				{
					tempString.RemoveFirst (":");
					tempString.Append ("\n");
					Display (tempString.String());
				}
			}
			return true;


		case RPL_WELCOME:					// 001
		case RPL_YOURHOST:				 // 002
		case RPL_CREATED:					// 003
		case RPL_MYINFO:					 // 004
			{
				fConnected = true;
				fIsConnecting = false;
				fInitialMotd = true;
				fRetry = 0;

				if (num == RPL_WELCOME)
				{
					BString message = B_TRANSLATE("Established");
					message.Prepend("[@] ").Append("\n");
					Display(message.String(), C_ERROR, C_BACKGROUND, F_SERVER);
				}

				if (fNetworkData.FindBool ("lagCheck"))
				{
					fMyLag = "0.000";
					fMsgr.SendMessage (M_LAG_CHANGED);
				}
				BString theNick (GetWord (data, 3));
				fMyNick = theNick;

				if (!IsHidden())
					vision_app->pClientWin()->pStatusView()->SetItemValue (STATUS_NICK,
						theNick.String());

				BString theMsg (RestOfString (data, 4));
				theMsg.RemoveFirst (":");
				theMsg.Prepend ("* ");
				theMsg.Append ("\n");
				Display (theMsg.String());


				if (num == RPL_MYINFO)
				{
					// set "real" hostname
					fServerHostName = (GetWord (data, 1));
					fServerHostName.RemoveFirst (":");
					BString hostName (fId.String());
					hostName += " - [";
					hostName += fServerHostName.String();
					hostName += "]";
					fAgentWinItem->SetName (hostName.String());

					// detect IRCd
					fIrcdtype = IRCD_STANDARD;

					if (theMsg.FindFirst("hybrid") > 0)
						fIrcdtype = IRCD_HYBRID;
					// ultimate and unreal share the same numerics, so treat them with the same
					// identifier for now
					else if ((theMsg.FindFirst("UltimateIRCd") > 0) || (theMsg.FindFirst("Unreal") > 0))
						fIrcdtype = IRCD_ULTIMATE;
					else if (theMsg.FindFirst("comstud") > 0)
						fIrcdtype = IRCD_COMSTUD;
					else if (theMsg.FindFirst("u2.") > 0)
						fIrcdtype = IRCD_UNDERNET;
					else if (theMsg.FindFirst("PTlink") > 0)
						fIrcdtype = IRCD_PTLINK;
					else if (theMsg.FindFirst ("CR") > 0)
						fIrcdtype = IRCD_CONFERENCEROOM;
					else if (theMsg.FindFirst ("nn-") > 0)
						fIrcdtype = IRCD_NEWNET;
				}
			}
			return true;


		case RPL_PROTOCTL:				 // 005
			{
				// this numeric also serves as RPL_NNMAP on Newnet

				BString theMsg (RestOfString (data, 4));
				theMsg.RemoveFirst (":");
				theMsg.Append ("\n");

				switch (fIrcdtype)
				{
					case IRCD_NEWNET:
						{
							// RPL_NNMAP
							Display (theMsg.String());
						}
						break;

					default:
						{
							// RPL_PROTOCTL
							theMsg.Prepend ("* ");
							Display (theMsg.String());
						}
				}
			}
			return true;



		case RPL_LUSERHIGHESTCONN: // 250
		case RPL_LUSERCLIENT:			// 251
		case RPL_LUSEROP:					// 252
		case RPL_LUSERUNKNOWN:		 // 253
		case RPL_LUSERCHANNELS:		// 254
		case RPL_LUSERME:					// 255
		case RPL_LUSERLOCAL:			 // 265
		case RPL_LUSERGLOBAL:			// 266
			{
				BString theMsg (RestOfString (data, 4));
				theMsg.RemoveFirst (":");
				theMsg.Prepend ("* ");
				theMsg.Append ("\n");
				Display (theMsg.String());
			}
			return true;


		/// strip and send to server agent	///
		case RPL_ULMAP:						 // 006
		case RPL_ULMAPEND:					// 007
		case RPL_U2MAP:						 // 015
		case RPL_U2MAPEND:					// 017
		case RPL_TRACELINK:				 // 200
		case RPL_TRACECONNECTING:	 // 201
		case RPL_TRACEHANDSHAKE:		// 202
		case RPL_TRACEUNKNOWN:			// 203
		case RPL_TRACEOPERATOR:		 // 204
		case RPL_TRACEUSER:				 // 205
		case RPL_TRACESERVER:			 // 206
		case RPL_TRACENEWTYPE:			// 208
		case RPL_TRACECLASS:				// 209
		case RPL_STATSLINKINFO:		 // 211
		case RPL_STATSCOMMANDS:		 // 212
		case RPL_STATSCLINE:				// 213
		case RPL_STATSNLINE:				// 214
		case RPL_STATSILINE:				// 215
		case RPL_STATSKLINE:				// 216
		case RPL_STATSQLINE:				// 217
		case RPL_STATSYLINE:				// 218
		case RPL_ENDOFSTATS:				// 219
		case RPL_STATSBLINE:				// 220
		case RPL_DALSTATSE:				 // 223
		case RPL_DALSTATSF:				 // 224
		case RPL_DALSTATSZ:				 // 225
		case RPL_DALSTATSN:				 // 226
		case RPL_DALSTATSG:				 // 227
		case RPL_STATSLLINE:				// 241
		case RPL_STATSUPTIME:			 // 242
		case RPL_STATSOLINE:				// 243
		case RPL_STATSHLINE:				// 244
		case RPL_STATSSLINE:				// 245
		case RPL_DALSTATSX:				 // 246
		case RPL_STATSXLINE:				// 247
		case RPL_STATSPLINE:				// 249
		case RPL_ADMINME:					 // 256
		case RPL_ADMINLOC1:				 // 257
		case RPL_ADMINLOC2:				 // 258
		case RPL_ADMINEMAIL:				// 259
		case RPL_TRACELOG:					// 261
		case RPL_ENDOFTRACE:				// 262
		case RPL_SILELIST:					// 271
		case RPL_ENDOFSILELIST:		 // 272
		case RPL_ENDOFWHO:					// 315
		case RPL_CHANSERVURL:			 // 328
		case RPL_COMMANDSYNTAX:		 // 334
		case RPL_VERSION:					 // 351
		case RPL_WHOREPLY:					// 352
		case RPL_BANLIST:					 // 367
		case RPL_ENDOFBANLIST:			// 368
		case RPL_INFO:							// 371
		case RPL_ENDOFINFO:				 // 374
		case RPL_YOUREOPER:				 // 381
		case RPL_REHASHING:				 // 382
		case RPL_TIME:							// 391
		case ERR_NOORIGIN:					// 409
		case ERR_NOTEXTTOSEND:			// 412
		case ERR_TOOMANYAWAY:			 // 429
		case ERR_NICKCHANGETOOFAST: // 438
		case ERR_TARGETCHANGETOOFAST: // 439
		case ERR_SUMMONDISABLED:		// 445
		case ERR_USERSDISABLED:		 // 446
		case ERR_NOTREGISTERED:		 // 451
		case ERR_NEEDMOREPARMS:		 // 461
		case ERR_PASSWDMISMATCH:		// 464
		case ERR_YOUREBANNEDCREEP:	// 465
		case ERR_NOPRIVILEGES:			// 481
		case ERR_NOOPERHOST:				// 491
		case ERR_USERSDONTMATCH:		// 502
		case ERR_SILELISTFULL:			// 511
		case ERR_TOOMANYWATCH:			// 512
		case ERR_TOOMANYDCC:				// 514
		case ERR_CANTINVITE:				// 518
		case ERR_LISTSYNTAX:				// 521
		case ERR_WHOSYNTAX:				 // 522
		case ERR_WHOLIMEXCEED:			// 523
		case RPL_LOGON:						 // 600
		case RPL_LOGOFF:						// 601
		case RPL_WATCHOFF:					// 602
		case RPL_WATCHSTAT:				 // 603
		case RPL_NOWON:						 // 604
		case RPL_NOWOFF:						// 605
		case RPL_WATCHLIST:				 // 606
		case RPL_ENDOFWATCHLIST:		// 607
		case RPL_DCCALLOWLIST:			// 618
		case RPL_DCCALLOWEND:			 // 619
		case RPL_DCCALLOW:					// 620
			{
				BString tempString (RestOfString (data, 4));
				tempString.RemoveFirst (":");
				tempString.Append ("\n");
				Display (tempString.String());
			}
			return true;

		case RPL_UMODEIS:					 // 221
			{
				BString theMode (GetWord (data, 4));

				BString tempString = B_TRANSLATE("Your current mode is %1");
				tempString.ReplaceFirst("%1", theMode);
				tempString += '\n';

				BMessage msg (M_DISPLAY);
				PackDisplay (&msg, tempString.String(), C_WHOIS);
				PostActive (&msg);
			}
			return true;

		/// strip and send to active agent	///
		case RPL_TRYAGAIN:					// 263
		case RPL_UNAWAY:						// 305
		case RPL_NOWAWAY:					 // 306
		case ERR_NOSUCHNICK:				// 401
		case ERR_NOSUCHSERVER:			// 402
		case ERR_NOSUCHCHANNEL:		 // 403
		case ERR_CANNOTSENDTOCHAN:	// 404
		case ERR_TOOMANYCHANNELS:	 // 405
		case ERR_WASNOSUCHNICK:		 // 406
		case ERR_TOOMANYTARGETS:		// 407
		case ERR_NOCOLORSONCHAN:		// 408
		case ERR_YOUCANTDOTHAT:		 // 460
		case ERR_CHANOPRIVSNEEDED:	// 482
			{
				BString tempString ("[x] ");
				if (num == ERR_CHANOPRIVSNEEDED)
					tempString += RestOfString (data, 5);
				else
					tempString += RestOfString (data, 4);
				tempString.RemoveFirst (":");
				tempString.Append ("\n");

				BMessage msg (M_DISPLAY);
				PackDisplay (&msg, tempString.String(), C_WHOIS, C_BACKGROUND, F_SERVER);
				PostActive (&msg);
			}
			return true;

		case RPL_AWAY:						 // 301
			{
				BString theNick (GetWord(data, 4));
				BString tempString ("[x] "),
							theReason (RestOfString(data, 5));
				theReason.RemoveFirst(":");
				tempString += "Away: ";
				tempString += theReason;
				tempString += '\n';

				if (fRemoteAwayMessages.find(theNick) != fRemoteAwayMessages.end())
				{
					if (fRemoteAwayMessages[theNick] == theReason)
					{
						return true;
					}
				}
				fRemoteAwayMessages[theNick] = theReason;
				BMessage msg (M_DISPLAY);
				PackDisplay (&msg, tempString.String(), C_WHOIS, C_BACKGROUND, F_SERVER);
				PostActive (&msg);
			}
			return true;

		case RPL_USERHOST:				// 302
			{
				BString theHost (GetWord (data, 4)),
								theHostname (GetAddress (theHost.String()));
				theHost.RemoveFirst (":");

				BString tempString (RestOfString (data, 4));
				tempString.RemoveFirst (":");
				tempString.Append ("\n");
				Display (tempString.String());

				if (fGetLocalIP && (tempString.IFindFirst (fMyNick.String()) == 0))
				{
					fGetLocalIP = false;
					struct addrinfo *info;
					struct addrinfo hints;
					memset(&hints, 0, sizeof(addrinfo));
					hints.ai_family = AF_UNSPEC;
					hints.ai_socktype = SOCK_STREAM;
					hints.ai_protocol = IPPROTO_TCP;
					int result = getaddrinfo(theHostname.String(), NULL, &hints, &info);
					if (result == 0)
					{
						char addr_buf[INET6_ADDRSTRLEN];
						getnameinfo(info->ai_addr, info->ai_addrlen, addr_buf, sizeof(addr_buf),
						NULL, 0, NI_NUMERICHOST);
						fLocalip = addr_buf;
						printf("Got address: %s\n", fLocalip.String());
						freeaddrinfo(info);
						return true;
					}
				}
			}
			return true;

		case RPL_ISON:					 // 303
			{
				BString nicks (RestOfString (data, 4));
				BString onlined, offlined;

				nicks.RemoveFirst (":");

				int hasChanged (0);

				BMessage msg (M_NOTIFYLIST_UPDATE);

				for (int32 i = 0; i < fNotifyNicks.CountItems(); i++)
				{
					NotifyListItem *item (((NotifyListItem *)fNotifyNicks.ItemAt(i)));

					int32 nickidx (nicks.IFindFirst(item->Text()));

					// make sure that the nick isn't a partial match.
					if ((nickidx >= 0) &&
						((nicks[nickidx + strlen(item->Text())] == ' ') || (nicks[nickidx + strlen(item->Text())] == '\0')))
					{
						if (item->GetState() != true)
						{
							item->SetState (true);
							hasChanged = 1;

							if (onlined.Length())
								onlined << ", ";
							onlined << item->Text();
#ifdef USE_INFOPOPPER
							if (be_roster->IsRunning(InfoPopperAppSig) == true) {
								entry_ref ref = vision_app->AppRef();
								BMessage infoMsg(InfoPopper::AddMessage);
								infoMsg.AddString("appTitle", S_INFOPOPPER_TITLE);
								infoMsg.AddString("title", fId.String());
								infoMsg.AddInt8("type", (int8)InfoPopper::Information);

								infoMsg.AddInt32("iconType", InfoPopper::Attribute);
								infoMsg.AddRef("iconRef", &ref);

								BString content;
								content << item->Text() << " is online";
								infoMsg.AddString("content", content);

								BMessenger(InfoPopperAppSig).SendMessage(&infoMsg);
							};
#endif

						}
					}
					else
					{
						if (item->GetState() == true)
						{
							item->SetState (false);
							hasChanged = 2;

							if (offlined.Length())
								offlined << ", ";
							offlined << item->Text();
#ifdef USE_INFOPOPPER
							if (be_roster->IsRunning(InfoPopperAppSig) == true) {
				entry_ref ref = vision_app->AppRef();
								BMessage infoMsg(InfoPopper::AddMessage);
								infoMsg.AddString("appTitle", S_INFOPOPPER_TITLE);
								infoMsg.AddString("title", fId.String());
								infoMsg.AddInt8("type", (int8)InfoPopper::Information);

								infoMsg.AddInt32("iconType", InfoPopper::Attribute);
								infoMsg.AddRef("iconRef", &ref);

								BString content;
								content << item->Text() << " is offline";
								infoMsg.AddString("content", content);

								BMessenger(InfoPopperAppSig).SendMessage(&infoMsg);
							};
#endif

						}
					}
#ifdef __HAIKU__
					if (offlined.Length())
					{
						BNotification notification(B_INFORMATION_NOTIFICATION);
						notification.SetGroup(BString("Vision"));
						entry_ref ref = vision_app->AppRef();
						notification.SetOnClickFile(&ref);
						notification.SetTitle(fServerName.String());
						BString content;
						content << offlined;
						if (offlined.FindFirst(' ') > -1)
							content << " are offline";
						else
							content << " is offline";


						notification.SetContent(content);
						notification.Send();
					}
					if (onlined.Length())
					{
						BNotification notification(B_INFORMATION_NOTIFICATION);
						notification.SetGroup(BString("Vision"));
						entry_ref ref = vision_app->AppRef();
						notification.SetOnClickFile(&ref);
						notification.SetTitle(fServerName.String());
						BString content;
						content << onlined;
						if (onlined.FindFirst(' ') > -1)
							content << " are online";
						else
							content << " is online";


						notification.SetContent(content);
						notification.Send();
					}
#endif
				}
				fNotifyNicks.SortItems(SortNotifyItems);
				msg.AddPointer ("list", &fNotifyNicks);
				msg.AddPointer ("source", this);
				msg.AddInt32 ("change", hasChanged);
				Window()->PostMessage (&msg);
			}
			return true;

		case RPL_WHOISIDENTIFIED:	 // 307
			{
				BString theInfo (RestOfString (data, 5));
				theInfo.RemoveFirst (":");

				if (theInfo == "-9z99")
				{
					// USERIP reply? (RPL_U2USERIP)
					BString tempString (RestOfString (data, 4));
					tempString.RemoveFirst (":");
					tempString.Append ("\n");
					Display (tempString.String());
					return true;
				}

				BMessage display (M_DISPLAY);
				BString buffer;

				buffer += "[x] ";
				buffer += theInfo;
				buffer += "\n";
				PackDisplay (&display, buffer.String(), C_WHOIS, C_BACKGROUND, F_SERVER);
				PostActive (&display);
			}
			return true;

		case RPL_WHOISADMIN:					// 308
		case RPL_WHOISSERVICESADMIN:	// 309
		case RPL_WHOISHELPOP:				 // 310
		case RPL_WHOISOPERATOR:			 // 313
		case RPL_WHOISREGNICK:				// 320
		case RPL_WHOISACTUALLY:			 // 338
		case RPL_WHOISMASK:					 // 550
		case RPL_WHOWASIP:						// 612
		case RPL_WHOISUSERMODESALT:	 // 614
		case RPL_WHOISUSERMODES:			// 615
		case RPL_WHOISREALHOSTNAME:	 // 616
			{
				BString theInfo (RestOfString (data, 5));
				theInfo.RemoveFirst (":");

				BMessage display (M_DISPLAY);
				BString buffer;

				buffer += "[x] ";
				buffer += theInfo;
				buffer += "\n";
				PackDisplay (&display, buffer.String(), C_WHOIS, C_BACKGROUND, F_SERVER);
				PostActive (&display);
			}
			return true;

		case RPL_WHOISUSER:				// 311
			{
				BString theNick (GetWord (data, 4)),
								theIdent (GetWord (data, 5)),
								theAddress (GetWord (data, 6)),
								theName (RestOfString (data, 8));
				theName.RemoveFirst (":");

				BMessage display (M_DISPLAY);
				BString buffer;

				buffer += "[x] ";
				buffer += theNick;
				buffer += " (";
				buffer += theIdent;
				buffer += "@";
				buffer += theAddress;
				buffer += ")\n";
				buffer += "[x] ";
				buffer += theName;
				buffer += "\n";

				PackDisplay (&display, buffer.String(), C_WHOIS, C_BACKGROUND, F_SERVER);
				PostActive (&display);
			}
		return true;

		case RPL_WHOISSERVER:	 // 312
			{
				BString theNick (GetWord (data, 4)),
								theServer (GetWord (data, 5)),
								theInfo (RestOfString (data, 6));
				theInfo.RemoveFirst (":");

				BMessage display (M_DISPLAY);
				BString buffer;

				buffer += "[x] Server: ";
				buffer += theServer;
				buffer += " (";
				buffer += theInfo;
				buffer += ")\n";
				PackDisplay (&display, buffer.String(), C_WHOIS, C_BACKGROUND, F_SERVER);
				PostActive (&display);
			}
			return true;

		case RPL_WHOWASUSER:		 // 314
			{
				BString theNick (GetWord (data, 4)),
								theIdent (GetWord (data, 5)),
								theAddress (GetWord (data, 6)),
								theName (RestOfString (data, 8)),
								tempString ("[x] ");
				theName.RemoveFirst (":");
				tempString += B_TRANSLATE("%1 was (%2)");
				tempString.ReplaceFirst("%1", theNick);
				BString nickString = theIdent << "@" << theAddress;
				tempString.ReplaceFirst("%2", nickString.String());
				tempString += "\n";

				BMessage msg (M_DISPLAY);
				PackDisplay (&msg, tempString.String(), C_WHOIS, C_BACKGROUND, F_SERVER);
				PostActive (&msg);
			}
			return true;

		case RPL_WHOISIDLE:			 // 317
			{
				BString theNick (GetWord (data, 4)),
								tempString ("[x] "),
								tempString2 ("[x] "),
								theTime (GetWord (data, 5)),
								signOnTime (GetWord (data, 6));

				int64 idleTime (strtoul(theTime.String(), NULL, 0));
				tempString += B_TRANSLATE("Idle");
				tempString += ": ";
				tempString += DurationString(idleTime * 1000 * 1000);
				tempString += "\n";

				int32 serverTime = strtoul(signOnTime.String(), NULL, 0);
				struct tm ptr;
				time_t st;
				char str[80];
				st = serverTime;
				localtime_r (&st, &ptr);
				strftime (str,80,"%A %b %d %Y %I:%M %p %Z", &ptr);
				BString signOnTimeParsed (str);
				signOnTimeParsed.RemoveAll ("\n");

				tempString2 += B_TRANSLATE("Signon");
				tempString2 += ": ";
				tempString2 += signOnTimeParsed;
				tempString2 += "\n";

				BMessage msg (M_DISPLAY);
				PackDisplay (&msg, tempString.String(), C_WHOIS, C_BACKGROUND, F_SERVER);
				PostActive (&msg);
				PackDisplay (&msg, tempString2.String(), C_WHOIS, C_BACKGROUND, F_SERVER);
				PostActive (&msg);
			}
			return true;

		case RPL_ENDOFWHOIS:	 // 318
		case RPL_ENDOFNAMES:	 // 366
		case RPL_ENDOFWHOWAS:	// 369
			{
				// nothing
			}
			return true;

		case RPL_WHOISCHANNELS:	 // 319
			{
				BString theChannels (RestOfString (data, 5));
				theChannels.RemoveFirst(":");

				BMessage display (M_DISPLAY);
				BString buffer = "[x] ";

				buffer += B_TRANSLATE("Channels");
				buffer += ": ";
				buffer += theChannels;
				buffer += "\n";
				PackDisplay (&display, buffer.String(), C_WHOIS, C_BACKGROUND, F_SERVER);
				PostActive (&display);
			}
			return true;

		case RPL_LISTSTART:			 // 321
			{
				BMessage msg (M_LIST_BEGIN);
				if (fListAgent)
					vision_app->pClientWin()->DispatchMessage(&msg, (BView *)fListAgent);
			}
			return true;

		case RPL_LIST:						// 322
			{
				BMessage msg (M_LIST_EVENT);
				BString channel (GetWord (data, 4)),
								users (GetWord (data, 5)),
								topic (RestOfString (data, 6));
				topic.RemoveFirst (":");

				msg.AddString ("channel", channel.String());
				msg.AddString ("users", users.String());
				msg.AddString ("topic", topic.String());

				if (fListAgent)
					vision_app->pClientWin()->DispatchMessage(&msg, (BView *)fListAgent);
			}
			return true;

		case RPL_LISTEND:				 // 323
			{
				BMessage msg (M_LIST_DONE);

				if (fListAgent)
					vision_app->pClientWin()->DispatchMessage(&msg, (BView *)fListAgent);
			}
			return true;

		case RPL_CHANNELMODEIS:	 // 324
			{
				BString theChan (GetWord (data, 4)),
								theMode (GetWord (data, 5)),
								tempStuff (RestOfString (data, 6));

				if (tempStuff != "-9z99")
				{
					theMode.Append(" ");
					theMode.Append(tempStuff); // avoid extra space w/o params
				}

				ClientAgent *aClient (ActiveClient()),
										*theClient (Client (theChan.String()));

				BString tempString("*** ");
				tempString += B_TRANSLATE("Channel mode for %1: %2");
				tempString.ReplaceFirst("%1", theChan.String());
				tempString.ReplaceFirst("%2", theMode.String());
				tempString += '\n';

				BMessage msg (M_CHANNEL_MODES);

				msg.AddString ("msgz", tempString.String());
				msg.AddString ("chan", theChan.String());
				msg.AddString ("mode", theMode.String());

				if (theClient)
					theClient->fMsgr.SendMessage (&msg);
				else if (aClient)
					aClient->fMsgr.SendMessage (&msg);
				else
					Display (tempString.String(), C_OP);
			}
			return true;

		case RPL_CHANNELMLOCK:		// 325
			{
				BString theChan (GetWord (data, 4)),
								mLock (GetWord (data, 8)),
								lockMessage ("*** ");
				lockMessage += B_TRANSLATE("Channel mode lock for %1: %2");
				lockMessage.ReplaceFirst("%1", theChan);
				lockMessage.ReplaceFirst("%2", mLock);
				lockMessage += "\n";

				BMessage display (M_DISPLAY);

				PackDisplay (&display, lockMessage.String(), C_OP, C_BACKGROUND, F_TEXT);
				ClientAgent *theClient (Client (theChan.String()));
				if (theClient)
					theClient->fMsgr.SendMessage (&display);
				else
					fMsgr.SendMessage (&display);
			}
			return true;

		case RPL_CHANNELCREATED:			 // 329
			{
				BString theChan (GetWord (data, 4)),
								theTime (GetWord (data, 5)),
								tempString;

				int32 serverTime (strtoul(theTime.String(), NULL, 0));
				struct tm ptr;
				time_t st;
				char str[80];
				st = serverTime;
				localtime_r (&st, &ptr);
				strftime (str,80,"%a %b %d %Y %I:%M %p %Z",&ptr);
				BString theTimeParsed (str);
				theTimeParsed.RemoveAll ("\n");

			tempString = B_TRANSLATE("Channel %1 was created at %2");
			tempString.ReplaceFirst("%1", theChan);
			tempString.ReplaceFirst("%2", theTimeParsed);
				tempString += '\n';
				Display (tempString.String());
			}
			return true;

		case RPL_NOTOPIC:						 // 331
			{
				BString theChan (GetWord (data, 4)),
								tempString ("[x] ");
				tempString += B_TRANSLATE("No topic set in %1");
				tempString.ReplaceFirst("%1", theChan);
				tempString += '\n';

				BMessage msg (M_DISPLAY);
				PackDisplay (&msg, tempString.String(), C_ERROR);
				PostActive (&msg);
			}
			return true;

		case RPL_TOPIC:							 // 332
			{
				BString theChannel (GetWord (data, 4)),
								theTopic (RestOfString (data, 5));
				ClientAgent *client (Client (theChannel.String()));

				theTopic.RemoveFirst (":");

				if (client)
				{
					BMessage display (M_DISPLAY);
					BString buffer;

					buffer += "*** ";
					buffer += B_TRANSLATE("Topic: %1");
					buffer.ReplaceFirst("%1", theTopic);
					buffer += '\n';
					PackDisplay (&display, buffer.String(), C_WHOIS);

					BMessage msg (M_CHANNEL_TOPIC);
					msg.AddString ("topic", theTopic.String());
					msg.AddMessage ("display", &display);

					if (client->fMsgr.IsValid())
						client->fMsgr.SendMessage (&msg);
				}
			}
			return true;

		case RPL_TOPICSET:						// 333
			{
				BString channel (GetWord (data, 4)),
								user (GetWord (data, 5)),
								theTime (GetWord (data, 6));

				int32 serverTime (strtoul(theTime.String(), NULL, 0));
				struct tm ptr;
				time_t st;
				char str[80];
				st = serverTime;
				localtime_r (&st, &ptr);
				strftime (str,80,"%A %b %d %Y %I:%M %p %Z",&ptr);
				BString theTimeParsed (str);
				theTimeParsed.RemoveAll ("\n");

				ClientAgent *client (Client (channel.String()));

				if (client)
				{
					BMessage display (M_DISPLAY);
					BString buffer = "*** ";

					buffer += B_TRANSLATE("Topic set by %1 at %2");
					buffer.ReplaceFirst("%1", user);
					buffer.ReplaceFirst("%2", theTimeParsed);
					buffer += '\n';
					PackDisplay (&display, buffer.String(), C_WHOIS);
					if (client->fMsgr.IsValid())
						client->fMsgr.SendMessage (&display);
				}
			}
			return true;

		case RPL_INVITING:						 // 341
			{
				BString channel (GetWord (data, 5)),
								theNick (GetWord (data, 4)),
								tempString;

				tempString += "*** ";
				tempString += B_TRANSLATE("%1 has been invited to %2.");
				tempString.ReplaceFirst("%1", theNick);
				tempString.ReplaceFirst("%2", channel);
				tempString += "\n";

				BMessage display (M_DISPLAY);

				PackDisplay (&display, tempString.String(), C_WHOIS);
				PostActive (&display);
			}
			return true;


		case RPL_NAMEREPLY:						 // 353
			{
				BString channel (GetWord (data, 5)),
								names (RestOfString (data, 6));
				ClientAgent *client (Client (channel.String()));
				names.RemoveFirst (":");

					BString tempString ("*** ");
					tempString += B_TRANSLATE("Users in %1: %2");
					tempString.ReplaceFirst("%1", channel);
					tempString.ReplaceFirst("%2", names);
					tempString += '\n';
					Display (tempString.String(), C_TEXT);

				if (client) // in the channel
				{
					BMessage msg (M_CHANNEL_NAMES);
					BString nick;
					int32 place (1);

					while ((nick = GetWord (names.String(), place)) != "-9z99")
					{
						const char *sNick (nick.String());
						bool founder (false),
								 protect (false),
								 op (false),
								 voice (false),
								 helper (false),
							 ignored;

						if (nick[0] == '*')
						{
							++sNick;
							founder = true;
						}
						else if (nick[0] == '!')
						{
							++sNick;
							protect = true;
						}
						else if (nick[0] == '@')
						{
							++sNick;
							op = true;
						}
						else if (nick[0] == '+')
						{
							++sNick;
							voice = true;
						}
						else if (nick[0] == '%')
						{
							++sNick;
							helper = true;
						}

						ignored = false;
						// BMessage aMsg (M_IS_IGNORED), reply;
						// aMsg.AddString ("server", fServerName.String());
						// aMsg.AddString ("nick", sNick);

						// be_app_messenger.SendMessage (&aMsg, &reply);
						// reply.FindBool ("ignored", &ignored);

						msg.AddString ("nick", nick.String());
						msg.AddBool ("founder", founder);
						msg.AddBool ("protect", protect);
						msg.AddBool ("op", op);
						msg.AddBool ("voice", voice);
						msg.AddBool ("helper", helper);
						msg.AddBool ("ignored", ignored);
						++place;
					}

					if (client->fMsgr.IsValid())
						client->fMsgr.SendMessage (&msg);
				}
			}
			return true;

		case RPL_MOTD:						// 372
		case RPL_MOTDALT:				 // 378
		case RPL_OPERMOTDSTART:	 // 609
		case RPL_OPERMOTD:				// 610
		case RPL_OPERENDOFMOTD:	 // 611
			{
				BString tempString (RestOfString(data, 4));
				tempString.RemoveFirst (":");
				tempString.Append ("\n");
				Display (tempString.String(), C_SERVER, C_BACKGROUND, F_SERVER);
			}
			return true;

		case RPL_MOTDSTART:				// 375
			{

				BString tempString ("- ");
				tempString += B_TRANSLATE("Server Message Of the Day");
				tempString += ":\n";
				Display (tempString.String(), C_SERVER, C_BACKGROUND, F_SERVER);
			}
			return true;

		case RPL_ENDOFMOTD:				// 376
		case ERR_NOMOTD:					 // 422
			{
				BString tempString (RestOfString (data, 4));
			tempString.RemoveFirst (":");
			tempString.Append ("\n");

				Display (tempString.String(), C_SERVER, C_BACKGROUND, F_SERVER);

				if (fInitialMotd && fCmds.Length())
				{
					BMessage msg (M_SUBMIT_INPUT);
					const char *place (fCmds.String()), *eol;

					msg.AddInt32 ("which", PASTE_MULTI_NODELAY);

					while ((eol = strchr (place, '\n')) != 0)
					{
						BString line;

						line.Append (place, eol - place);
						msg.AddString ("data", line.String());
						ParseAutoexecChans (line);
						place = eol + 1;
					}

					if (*place)
					{
						// check in case this was the only line
						ParseAutoexecChans (BString(place));
						msg.AddString ("data", place);
					}

					msg.AddInt32 ("which", 3);
					msg.AddBool ("autoexec", true);
					fMsgr.SendMessage (&msg);
				}

				BString IPCommand ("/userhost ");
				IPCommand += fMyNick;
				ParseCmd (IPCommand.String());

				if (fReconnecting)
				{
					BString reString = "[@] ";
					reString += B_TRANSLATE("Successful reconnect");
					reString += "\n";
					Display (reString.String(), C_ERROR);
					DisplayAll (reString.String(), C_ERROR, C_BACKGROUND, F_SERVER);
					fMsgr.SendMessage (M_REJOIN_ALL);
					fReconnecting = false;
				}

				fInitialMotd = false;
			}
			return true;

		case RPL_USERSSTART:			 // 392
			{
				// empty for now
		}
			return true;

		case RPL_USERS:						// 393
			{
				// empty for now
			}
			return true;

		case ERR_ERRONEOUSNICKNAME:		// 432
		case ERR_NICKNAMEINUSE:				// 433
		case ERR_RESOURCEUNAVAILABLE:	// 437
			{
				BString theNick (GetWord (data, 4));

				if (fIsConnecting)
				{
					BString nextNick (GetNextNick());
					if (nextNick != "")
					{
						BString tempString = "* ";
						tempString += B_TRANSLATE("Nickname \"%1\" in use or unavailable, trying \"%2\"");
						tempString.ReplaceFirst("%1", theNick.String());
						tempString.ReplaceFirst("%2", nextNick.String());
						tempString += "\n";
						Display (tempString.String());

						tempString = "NICK ";
						tempString += nextNick;
						SendData (tempString.String());
						return true;
					}
					else
					{
						BString tempString = "* ";
						tempString += B_TRANSLATE("All your pre-selected nicknames are in use.");
						tempString += "\n";
						Display (tempString.String());
						tempString = "* ";
						tempString += B_TRANSLATE("Please type /NICK <NEWNICK> to try another.");
						tempString += "\n";
						Display (tempString.String());
						return true;
					}
				}
				BString tempString = "[x] ";
				tempString += B_TRANSLATE("Nickname/Channel \"%1\" is already in use or unavailable.");
				tempString.ReplaceFirst("%1", theNick);
				tempString += "\n";

				BMessage display (M_DISPLAY);
				PackDisplay (&display, tempString.String(), C_NICK);
				PostActive (&display);
			}
			return true;

		case ERR_USERNOTINCHANNEL:		// 441
			{
				BString theChannel (GetWord (data, 5)),
								theNick (GetWord (data, 4)),
								tempString ("[x] ");
				tempString += B_TRANSLATE("%1 not in %2.");
				tempString.ReplaceFirst("%1", theNick);
				tempString.ReplaceFirst("%2", theChannel);
				tempString += "\n";

				BMessage msg (M_DISPLAY);
				PackDisplay (&msg, tempString.String(), C_ERROR);
				PostActive (&msg);
			}
			return true;

		case ERR_NOTONCHANNEL:			 // 442
			{
				BString theChannel (GetWord (data, 4)),
								tempString ("[x] ");
				tempString += B_TRANSLATE("You're not in %1.");
				tempString.ReplaceFirst("%1", theChannel);
				tempString += "\n";

				BMessage msg (M_DISPLAY);
				PackDisplay (&msg, tempString.String(), C_ERROR);
				PostActive (&msg);
			}
			return true;

		case ERR_USERONCHANNEL:		 // 443
			{
				BString theChannel (GetWord (data, 5)),
								theNick (GetWord (data, 4)),
				tempString ("[x] ");
				tempString += B_TRANSLATE("%1 is already in %2.");
				tempString.ReplaceFirst("%1", theNick);
				tempString.ReplaceFirst("%2", theChannel);
				tempString += "\n";

				BMessage msg (M_DISPLAY);
				PackDisplay (&msg, tempString.String(), C_ERROR);
				PostActive (&msg);
			}
			return true;

		case ERR_KEYSET:						// 467
			{
				BString theChannel (GetWord (data, 4)),
								tempString ("[x] ");
				tempString += B_TRANSLATE("Channel key already set in %1.");
				tempString.ReplaceFirst("%1", theChannel);
				tempString += "\n";

				BMessage msg (M_DISPLAY);
				PackDisplay (&msg, tempString.String(), C_ERROR);
				PostActive (&msg);
			}
			return true;

		case ERR_UNKNOWNMODE:				// 472
			{
				BString theMode (GetWord (data, 4)),
								tempString ("[x] ");
				tempString += B_TRANSLATE("Unknown channel mode: '%1'.");
				tempString.ReplaceFirst("%1", theMode);
				tempString += "\n";

				BMessage msg (M_DISPLAY);
				PackDisplay (&msg, tempString.String(), C_QUIT);
				PostActive (&msg);
			}
			return true;

		case ERR_INVITEONLYCHAN:		 // 473
			{
				BString theChan (GetWord (data, 4)),
								tempString ("[x] "),
								theReason (RestOfString (data, 5));
				theReason.RemoveFirst(":");
				theReason.ReplaceLast("channel", theChan.String());
				tempString << theReason < " ";
				tempString += B_TRANSLATE("(invite only)");
				tempString += "\n";

				BMessage msg (M_DISPLAY);
				PackDisplay (&msg, tempString.String(), C_QUIT, C_BACKGROUND, F_SERVER);
				PostActive (&msg);
				RemoveAutoexecChan (theChan);
			}
			return true;

		case ERR_BANNEDFROMCHAN:		 // 474
			{
				BString theChan (GetWord (data, 4)),
								tempString ("[x] "),
								theReason (RestOfString (data, 5));
				theReason.RemoveFirst(":");
				theReason.ReplaceLast("channel", theChan.String());

				tempString << theReason < " ";
				tempString += B_TRANSLATE("(you're banned)");
				tempString += "\n";

				BMessage msg (M_DISPLAY);
				PackDisplay (&msg, tempString.String(), C_QUIT, C_BACKGROUND, F_SERVER);
				PostActive (&msg);
				RemoveAutoexecChan (theChan);
			}
			return true;

		case ERR_BADCHANNELKEY:			// 475
			{
				BString theChan (GetWord(data, 4)),
								theReason (RestOfString(data, 5)),
								tempString("[x] ");
				theReason.RemoveFirst(":");
				theReason.ReplaceLast("channel", theChan.String());
				tempString << theReason << " ";
				tempString += B_TRANSLATE("(bad channel key)");
				tempString += "\n";

				BMessage msg (M_DISPLAY);
				PackDisplay (&msg, tempString.String(), C_QUIT, C_BACKGROUND, F_SERVER);
				PostActive (&msg);
				RemoveAutoexecChan (theChan);
			}
			return true;

		case ERR_UMODEUNKNOWNFLAG:		// 501
			{
				BMessage msg (M_DISPLAY);
				BString buffer = "[x] ";

		buffer += B_TRANSLATE("Unknown mode flag.");
				buffer += "\n";
				PackDisplay (&msg, buffer.String(), C_QUIT);
				PostActive (&msg);
			}
			return true;

		// not sure what these numerics are,
		// but they are usually on-connect messages
		case RPL_290:								 // 290
		case RPL_291:								 // 291
		case RPL_292:								 // 292
			{
				BString tempString (RestOfString(data, 4));
				tempString.RemoveFirst (":");
				tempString.Append ("\n");
				tempString.Prepend ("- ");
				Display (tempString.String());
			}
			return true;

		case RPL_WHOISREGISTEREDBOT:	// 617
			{
				// conflicts with RPL_DCCALLOWCHANGE
				BString theNick (GetWord (data, 4)),
								theMessage (RestOfString (data, 5)),
								tempString;
				theNick.RemoveFirst (":");
				theMessage.RemoveFirst (":");
				theMessage.Append ("\n");

				switch (fIrcdtype)
				{
					case IRCD_ULTIMATE:
						{
							tempString += "[@] ";
							tempString += theMessage;
							BMessage msg (M_DISPLAY);
							PackDisplay (&msg, tempString.String(), C_WHOIS, C_BACKGROUND, F_SERVER);
							PostActive (&msg);
						}
						break;

					default:
						{
							tempString += theNick;
							tempString += " ";
							tempString += theMessage;
							Display (tempString.String());
						}
				}
			}
			return true;

		default:
			break;
	}

	return false;
}
示例#23
0
文件: tickval.hpp 项目: kziemski/fix8
 /*! Get tickval as struct timespec
   \return result */
 struct timespec as_ts() const
 {
     const timespec ts = { secs(), static_cast<long>(nsecs()) };
     return ts;
 }
示例#24
0
RideFile *CsvFileReader::openRideFile(QFile &file, QStringList &errors) const
{
    QRegExp metricUnits("(km|kph|km/h)", Qt::CaseInsensitive);
    QRegExp englishUnits("(miles|mph|mp/h)", Qt::CaseInsensitive);
    bool metric;
    QDateTime startTime;

    // TODO: a more robust regex for ergomo files
    // i don't have an example with english headers
    // the ergomo CSV has two rows of headers. units are on the second row.
    /*
    ZEIT,STRECKE,POWER,RPM,SPEED,PULS,HÖHE,TEMP,INTERVAL,PAUSE
    L_SEC,KM,WATT,RPM,KM/H,BPM,METER,°C,NUM,SEC
    */
    QRegExp ergomoCSV("(ZEIT|STRECKE)", Qt::CaseInsensitive);
    bool ergomo = false;
    int unitsHeader = 1;
    int total_pause = 0;
    int currentInterval = 0;
    int prevInterval = 0;

    // TODO: with all these formats, should the logic change to a switch/case structure?
    // The iBike format CSV file has five lines of headers (data begins on line 6)
    // starting with:
    /*
    iBike,8,english
    2008,8,8,6,32,52

    {Various configuration data, recording interval at line[4][4]}
    Speed (mph),Wind Speed (mph),Power (W),Distance (miles),Cadence (RPM),Heartrate (BPM),Elevation (feet),Hill slope (%),Internal,Internal,Internal,DFPM Power,Latitude,Longitude
    */
    //  Modified the regExp string to allow for 2-digit version numbers - 23 Mar 2009, thm
    QRegExp iBikeCSV("iBike,\\d\\d?,[a-z]+", Qt::CaseInsensitive);
    bool iBike = false;
    int recInterval;

    if (!file.open(QFile::ReadOnly)) {
        errors << ("Could not open ride file: \""
                   + file.fileName() + "\"");
        return NULL;
    }
    int lineno = 1;
    QTextStream is(&file);
    RideFile *rideFile = new RideFile();
    int iBikeInterval = 0;
    bool dfpmExists   = false;
    int iBikeVersion  = 0;
    while (!is.atEnd()) {
        // the readLine() method doesn't handle old Macintosh CR line endings
        // this workaround will load the the entire file if it has CR endings
        // then split and loop through each line
        // otherwise, there will be nothing to split and it will read each line as expected.
        QString linesIn = is.readLine();
        QStringList lines = linesIn.split('\r');
        // workaround for empty lines
        if(lines.isEmpty()) {
            lineno++;
            continue;
        }
        for (int li = 0; li < lines.size(); ++li) {
            QString line = lines[li];

            if (lineno == 1) {
                if (ergomoCSV.indexIn(line) != -1) {
                    ergomo = true;
                    rideFile->setDeviceType("Ergomo CSV");
                    unitsHeader = 2;
                    ++lineno;
                    continue;
                }
                else {
                    if(iBikeCSV.indexIn(line) != -1) {
                        iBike = true;
                        rideFile->setDeviceType("iBike CSV");
                        unitsHeader = 5;
                        iBikeVersion = line.section( ',', 1, 1 ).toInt();
                        ++lineno;
                        continue;
                    }
                    rideFile->setDeviceType("PowerTap CSV");
                }
            }
            if (iBike && lineno == 2) {
                QStringList f = line.split(",");
                if (f.size() == 6) {
                    startTime = QDateTime(
                                    QDate(f[0].toInt(), f[1].toInt(), f[2].toInt()),
                                    QTime(f[3].toInt(), f[4].toInt(), f[5].toInt()));
                }
            }
            if (iBike && lineno == 4) {
                // this is the line with the iBike configuration data
                // recording interval is in the [4] location (zero-based array)
                // the trailing zeroes in the configuration area seem to be causing an error
                // the number is in the format 5.000000
                recInterval = (int)line.section(',',4,4).toDouble();
            }
            if (lineno == unitsHeader) {
                if (metricUnits.indexIn(line) != -1)
                    metric = true;
                else if (englishUnits.indexIn(line) != -1)
                    metric = false;
                else {
                    errors << "Can't find units in first line: \"" + line + "\" of file \"" + file.fileName() + "\".";
                    delete rideFile;
                    file.close();
                    return NULL;
                }
            }
            else if (lineno > unitsHeader) {
                double minutes,nm,kph,watts,km,cad,alt,hr,dfpm;
                double lat = 0.0, lon = 0.0;
                double headwind = 0.0;
                int interval;
                int pause;
                if (!ergomo && !iBike) {
                    minutes = line.section(',', 0, 0).toDouble();
                    nm = line.section(',', 1, 1).toDouble();
                    kph = line.section(',', 2, 2).toDouble();
                    watts = line.section(',', 3, 3).toDouble();
                    km = line.section(',', 4, 4).toDouble();
                    cad = line.section(',', 5, 5).toDouble();
                    hr = line.section(',', 6, 6).toDouble();
                    interval = line.section(',', 7, 7).toInt();
                    alt = line.section(',', 8, 8).toDouble();
                    if (!metric) {
                        km *= KM_PER_MILE;
                        kph *= KM_PER_MILE;
                        alt *= METERS_PER_FOOT;
                    }
                }
                else if (iBike) {
                    // this must be iBike
                    // can't find time as a column.
                    // will we have to extrapolate based on the recording interval?
                    // reading recording interval from config data in ibike csv file
                    //
                    // For iBike software version 11 or higher:
                    // use "power" field until a the "dfpm" field becomes non-zero.
                    minutes = (recInterval * lineno - unitsHeader)/60.0;
                    nm = NULL; //no torque
                    kph = line.section(',', 0, 0).toDouble();
                    dfpm = line.section( ',', 11, 11).toDouble();
                    if( iBikeVersion >= 11 && ( dfpm > 0.0 || dfpmExists ) ) {
                        dfpmExists = true;
                        watts = dfpm;
                        headwind = line.section(',', 1, 1).toDouble();
                    }
                    else {
                        watts = line.section(',', 2, 2).toDouble();
                    }
                    km = line.section(',', 3, 3).toDouble();
                    cad = line.section(',', 4, 4).toDouble();
                    hr = line.section(',', 5, 5).toDouble();
                    alt = line.section(',', 6, 6).toDouble();
                    lat = line.section(',', 12, 12).toDouble();
                    lon = line.section(',', 13, 13).toDouble();
                    int lap = line.section(',', 9, 9).toInt();
                    if (lap > 0) {
                        iBikeInterval += 1;
                        interval = iBikeInterval;
                    }
                    if (!metric) {
                        km *= KM_PER_MILE;
                        kph *= KM_PER_MILE;
                        alt *= METERS_PER_FOOT;
                        headwind *= KM_PER_MILE;
                    }
                }
                else {
                    // for ergomo formatted CSV files
                    minutes     = line.section(',', 0, 0).toDouble() + total_pause;
                    km = line.section(',', 1, 1).toDouble();
                    watts = line.section(',', 2, 2).toDouble();
                    cad = line.section(',', 3, 3).toDouble();
                    kph = line.section(',', 4, 4).toDouble();
                    hr = line.section(',', 5, 5).toDouble();
                    alt = line.section(',', 6, 6).toDouble();
                    interval = line.section(',', 8, 8).toInt();
                    if (interval != prevInterval) {
                        prevInterval = interval;
                        if (interval != 0) currentInterval++;
                    }
                    if (interval != 0) interval = currentInterval;
                    pause = line.section(',', 9, 9).toInt();
                    total_pause += pause;
                    nm = NULL; // torque is not provided in the Ergomo file

                    // the ergomo records the time in whole seconds
                    // RECORDING INT. 1, 2, 5, 10, 15 or 30 per sec
                    // Time is *always* perfectly sequential.  To find pauses,
                    // you need to read the PAUSE column.
                    minutes = minutes/60.0;

                    if (!metric) {
                        km *= KM_PER_MILE;
                        kph *= KM_PER_MILE;
                        alt *= METERS_PER_FOOT;
                    }
                }

                // PT reports no data as watts == -1.
                if (watts == -1)
                    watts = 0;

                rideFile->appendPoint(minutes * 60.0, cad, hr, km,
                                      kph, nm, watts, alt, lat, lon, headwind, interval);
            }
            ++lineno;
        }
    }
    file.close();

    // To estimate the recording interval, take the median of the
    // first 1000 samples and round to nearest millisecond.
    int n = rideFile->dataPoints().size();
    n = qMin(n, 1000);
    if (n >= 2) {
        QVector<double> secs(n-1);
        for (int i = 0; i < n-1; ++i) {
            double now = rideFile->dataPoints()[i]->secs;
            double then = rideFile->dataPoints()[i+1]->secs;
            secs[i] = then - now;
        }
        std::sort(secs.begin(), secs.end());
        int mid = n / 2 - 1;
        double recint = round(secs[mid] * 1000.0) / 1000.0;
        rideFile->setRecIntSecs(recint);
    }
    // less than 2 data points is not a valid ride file
    else {
        errors << "Insufficient valid data in file \"" + file.fileName() + "\".";
        delete rideFile;
        file.close();
        return NULL;
    }

    QRegExp rideTime("^.*/(\\d\\d\\d\\d)_(\\d\\d)_(\\d\\d)_"
                     "(\\d\\d)_(\\d\\d)_(\\d\\d)\\.csv$");
    rideTime.setCaseSensitivity(Qt::CaseInsensitive);
    if (startTime != QDateTime()) {
        rideFile->setStartTime(startTime);
    }
    else if (rideTime.indexIn(file.fileName()) >= 0) {
        QDateTime datetime(QDate(rideTime.cap(1).toInt(),
                                 rideTime.cap(2).toInt(),
                                 rideTime.cap(3).toInt()),
                           QTime(rideTime.cap(4).toInt(),
                                 rideTime.cap(5).toInt(),
                                 rideTime.cap(6).toInt()));
        rideFile->setStartTime(datetime);
    } else {
        // Could be yyyyddmm_hhmmss_NAME.csv (case insensitive)
        rideTime.setPattern("(\\d\\d\\d\\d)(\\d\\d)(\\d\\d)_(\\d\\d)(\\d\\d)(\\d\\d)[^\\.]*\\.csv$");
        if (rideTime.indexIn(file.fileName()) >= 0) {
            QDateTime datetime(QDate(rideTime.cap(1).toInt(),
                                     rideTime.cap(2).toInt(),
                                     rideTime.cap(3).toInt()),
                               QTime(rideTime.cap(4).toInt(),
                                     rideTime.cap(5).toInt(),
                                     rideTime.cap(6).toInt()));
            rideFile->setStartTime(datetime);
        } else {
            qWarning("Failed to set start time");
        }
    }
    return rideFile;
}
示例#25
0
/**
 * Perform the C2S Throughput test. This test intends to measure throughput
 * from the client to the server by performing a 10 seconds memory-to-memory
 * data transfer.
 *
 * Protocol messages are exchanged between the Client and the Server using the
 * same connection and message format as the NDTP-Control protocol.Throughput
 * packets are sent on the new connection and do not follow the NDTP-Control
 * protocol message format.
 *
 * When the Client stops streaming the test data (or the server test routine
 * times out), the Server sends the Client its calculated throughput value.
 *
 * @param ctl Client control Connection
 * @param agent Web100 agent used to track the connection
 * @param testOptions Test options
 * @param conn_options connection options
 * @param c2sspd In-out parameter to store C2S throughput value
 * @param set_buff enable setting TCP send/recv buffer size to be used (seems
 *                 unused in file)
 * @param window value of TCP send/rcv buffer size intended to be used.
 * @param autotune autotuning option. Deprecated.
 * @param device string device name inout parameter
 * @param options Test Option variables
 * @param record_reverse integer indicating whether receiver-side statistics
 *                       have to be logged
 * @param count_vars count of web100 variables
 * @param spds[] [] speed check array
 * @param spd_index  index used for speed check array
 * @param conn_options Connection options
 * @param ctx The SSL context (possibly NULL)
 * @param c2s_ThroughputSnapshots Variable used to set c2s throughput snapshots
 * @param extended indicates if extended c2s test should be performed
 * @return 0 on success, an error code otherwise
 *         Error codes:
 *           -1 - Listener socket creation failed
 *           -100 - Timeout while waiting for client to connect to server's
 *                  ephemeral port
 *           -101 - Retries exceeded while waiting for client to connect
 *           -102 - Retries exceeded while waiting for data from connected
 *                  client
 *           -errno - Other specific socket error numbers
 */
int test_c2s(Connection *ctl, tcp_stat_agent *agent, TestOptions *testOptions,
             int conn_options, double *c2sspd, int set_buff, int window,
             int autotune, char *device, Options *options, int record_reverse,
             int count_vars, char spds[4][256], int *spd_index, SSL_CTX *ctx,
             struct throughputSnapshot **c2s_ThroughputSnapshots,
             int extended) {
  tcp_stat_connection conn;
  tcp_stat_group *group = NULL;
  /* The pipe that will return packet pair results */
  int mon_pipe[2];
  int packet_trace_running = 0;
  pid_t c2s_childpid = 0;       // child process pids
  int msgretvalue, read_error;  // used during the "read"/"write" process
  int i;                  // used as loop iterator
  int conn_index, attempts;
  int retvalue = 0;
  int streamsNum = 1;
  int activeStreams = 1;
  int local_errno;

  struct sockaddr_storage cli_addr[MAX_STREAMS];
  Connection c2s_conns[MAX_STREAMS];
  struct throughputSnapshot *lastThroughputSnapshot;

  socklen_t clilen;
  char tmpstr[256];  // string array used for all sorts of temp storage purposes
  double start_time, measured_test_duration;
  double throughputSnapshotTime;  // specify the next snapshot time
  double testDuration = 10;       // default test duration
  double bytes_read = 0;    // number of bytes read during the throughput tests
  struct timeval sel_tv;    // time
  fd_set rfd;       // receive file descriptors
  int max_fd;
  char buff[BUFFSIZE + 1];  // message "payload" buffer
  PortPair pair;            // socket ports
  I2Addr c2ssrv_addr = NULL;  // c2s test's server address
  // I2Addr src_addr=NULL;  // c2s test source address
  char listenc2sport[10];  // listening port
  pthread_t workerThreadId;

  // snap related variables
  SnapArgs snapArgs;
  snapArgs.snap = NULL;
#if USE_WEB100
  snapArgs.log = NULL;
#endif
  snapArgs.delay = options->snapDelay;

  // Test ID and status descriptors
  enum TEST_ID testids = extended ? C2S_EXT : C2S;
  enum TEST_STATUS_INT teststatuses = TEST_NOT_STARTED;
  char namesuffix[256] = "c2s_snaplog";

  for (i = 0; i < MAX_STREAMS; i++) {
    c2s_conns[i].socket = 0;
    c2s_conns[i].ssl = NULL;
  }

  if (!extended && testOptions->c2sopt) {
    setCurrentTest(TEST_C2S);
  } else if (extended && testOptions->c2sextopt) {
    setCurrentTest(TEST_C2S_EXT);
  } else {
    return 0;
  }
  log_println(1, " <-- %d - C2S throughput test -->", testOptions->child0);
  strlcpy(listenc2sport, PORT2, sizeof(listenc2sport));

  // log protocol validation logs
  teststatuses = TEST_STARTED;
  protolog_status(testOptions->child0, testids, teststatuses, ctl->socket);

  // Determine port to be used. Compute based on options set earlier
  // by reading from config file, or use default port2 (3002).
  if (testOptions->c2ssockport) {
    snprintf(listenc2sport, sizeof(listenc2sport), "%d",
             testOptions->c2ssockport);
  } else if (testOptions->mainport) {
    snprintf(listenc2sport, sizeof(listenc2sport), "%d",
             testOptions->mainport + 1);
  }

  if (testOptions->multiple) {
    strlcpy(listenc2sport, "0", sizeof(listenc2sport));
  }

  // attempt to bind to a new port and obtain address structure with details
  // of listening port
  while (c2ssrv_addr == NULL) {
    c2ssrv_addr = CreateListenSocket(
        NULL, (testOptions->multiple
                   ? mrange_next(listenc2sport, sizeof(listenc2sport))
                   : listenc2sport),
        conn_options, 0);
    if (strcmp(listenc2sport, "0") == 0) {
      log_println(1, "WARNING: ephemeral port number was bound");
      break;
    }
    if (testOptions->multiple == 0) {
      break;
    }
  }
  if (c2ssrv_addr == NULL) {
    log_println(0,
                "Server (C2S throughput test): CreateListenSocket failed: %s",
                strerror(errno));
    snprintf(buff, sizeof(buff),
             "Server (C2S throughput test): CreateListenSocket failed: %s",
             strerror(errno));
    send_json_message_any(ctl, MSG_ERROR, buff, strlen(buff),
                          testOptions->connection_flags, JSON_SINGLE_VALUE);
    return -1;
  }

  // get socket FD and the ephemeral port number that client will connect to
  // run tests
  testOptions->c2ssockfd = I2AddrFD(c2ssrv_addr);
  testOptions->c2ssockport = I2AddrPort(c2ssrv_addr);
  log_println(1, "  -- c2s %d port: %d", testOptions->child0,
              testOptions->c2ssockport);
  if (extended) {
    log_println(1, "  -- c2s ext -- duration = %d", options->c2s_duration);
    log_println(1,
                "  -- c2s ext -- throughput snapshots: enabled = %s, "
                "delay = %d, offset = %d",
                options->c2s_throughputsnaps ? "true" : "false",
                options->c2s_snapsdelay, options->c2s_snapsoffset);
    log_println(1, "  -- c2s ext -- number of streams: %d",
                options->c2s_streamsnum);
  }
  pair.port1 = testOptions->c2ssockport;
  pair.port2 = -1;

  log_println(
      1, "listening for Inet connection on testOptions->c2ssockfd, fd=%d",
      testOptions->c2ssockfd);

  log_println(
      1, "Sending 'GO' signal, to tell client %d to head for the next test",
      testOptions->child0);
  snprintf(buff, sizeof(buff), "%d", testOptions->c2ssockport);
  if (extended) {
    snprintf(buff, sizeof(buff), "%d %d %d %d %d %d",
             testOptions->c2ssockport, options->c2s_duration,
             options->c2s_throughputsnaps, options->c2s_snapsdelay,
             options->c2s_snapsoffset, options->c2s_streamsnum);
    lastThroughputSnapshot = NULL;
  }

  // send TEST_PREPARE message with ephemeral port detail, indicating start
  // of tests
  if ((msgretvalue = send_json_message_any(
           ctl, TEST_PREPARE, buff, strlen(buff),
           testOptions->connection_flags, JSON_SINGLE_VALUE)) < 0) {
    log_println(2, "Child %d could not send details about ephemeral port",
                getpid());
    return msgretvalue;
  }

  // Wait on listening socket and read data once ready.
  // Retry 5 times,  waiting for activity on the socket
  clilen = sizeof(cli_addr);
  log_println(6, "child %d - sent c2s prepare to client",
              testOptions->child0);
  FD_ZERO(&rfd);
  FD_SET(testOptions->c2ssockfd, &rfd);
  sel_tv.tv_sec = 5;
  sel_tv.tv_usec = 0;
  if (extended) {
    streamsNum = options->c2s_streamsnum;
    testDuration = options->c2s_duration / 1000.0;
  }

  conn_index = 0;
  for (attempts = 0;
       attempts < RETRY_COUNT * streamsNum && conn_index < streamsNum;
       attempts++) {
    msgretvalue = select((testOptions->c2ssockfd) + 1, &rfd, NULL, NULL,
                         &sel_tv);  // TODO
    // socket interrupted. continue waiting for activity on socket
    if ((msgretvalue == -1) && (errno == EINTR)) {
      continue;
    }
    if (msgretvalue == 0)  // timeout
      retvalue = -SOCKET_CONNECT_TIMEOUT;
    if (msgretvalue < 0)  // other socket errors. exit
      retvalue = -errno;
    if (!retvalue) {
      // If a valid connection request is received, client has connected.
      // Proceed.
      c2s_conns[conn_index].socket = accept(
          testOptions->c2ssockfd,
          (struct sockaddr *)&cli_addr[conn_index],
          &clilen);
      // socket interrupted, wait some more
      if ((c2s_conns[conn_index].socket == -1) && (errno == EINTR)) {
        log_println(
            6,
            "Child %d interrupted while waiting for accept() to complete",
            testOptions->child0);
        continue;
      }
      if (c2s_conns[conn_index].socket <= 0) {
        continue;
      }
      log_println(6, "accept(%d/%d) for %d completed", conn_index + 1,
                  streamsNum, testOptions->child0);

      // log protocol validation indicating client accept
      protolog_procstatus(testOptions->child0, testids, CONNECT_TYPE,
                          PROCESS_STARTED, c2s_conns[conn_index].socket);
      if (testOptions->connection_flags & TLS_SUPPORT) {
        errno = setup_SSL_connection(&c2s_conns[conn_index], ctx);
        if (errno != 0) return -errno;
      }

      // To preserve user privacy, make sure that the HTTP header
      // processing is done prior to the start of packet capture, as many
      // browsers have headers that uniquely identify a single user.
      if (testOptions->connection_flags & WEBSOCKET_SUPPORT) {
        if (initialize_websocket_connection(&c2s_conns[conn_index], 0, "c2s") !=
            0) {
          close_all_connections(c2s_conns, streamsNum);
          return -EIO;
        }
      }

      conn_index++;
    }

    if (retvalue) {
      log_println(
          6,
          "-------     C2S connection setup for %d returned because (%d)",
          testOptions->child0, retvalue);
      close_all_connections(c2s_conns, streamsNum);
      return retvalue;
    }
  }
  // If we haven't created enough streams after the loop is over, quit.
  if (conn_index != streamsNum) {
    log_println(
        6,
        "c2s child %d, unable to open connection, return from test",
        testOptions->child0);
     close_all_connections(c2s_conns, streamsNum);
     return RETRY_EXCEEDED_WAITING_DATA;
  }

  // Get address associated with the throughput test. Used for packet tracing
  log_println(6, "child %d - c2s ready for test with fd=%d",
              testOptions->child0, c2s_conns[0].socket);

  // commenting out below to move to init_pkttrace function
  I2Addr src_addr = I2AddrByLocalSockFD(get_errhandle(), c2s_conns[0].socket, 0);

  // Get tcp_stat connection. Used to collect tcp_stat variable statistics
  conn = tcp_stat_connection_from_socket(agent, c2s_conns[0].socket);

  // set up packet tracing. Collected data is used for bottleneck link
  // calculations
  if (getuid() == 0) {
    if (pipe(mon_pipe) != 0) {
      log_println(0, "C2S test error: can't create pipe.");
    } else {
      if ((c2s_childpid = fork()) == 0) {
        close(testOptions->c2ssockfd);
        close_all_connections(c2s_conns, streamsNum);
        // Don't capture more than 14 seconds of packet traces:
        //   2 seconds of sleep + 10 seconds of test + 2 seconds of slop
        alarm(testDuration + RACE_CONDITION_WAIT_TIME + 2);
        log_println(
            5,
            "C2S test Child %d thinks pipe() returned fd0=%d, fd1=%d",
            testOptions->child0, mon_pipe[0], mon_pipe[1]);
        log_println(2, "C2S test calling init_pkttrace() with pd=%p",
                    &cli_addr[0]);
        init_pkttrace(src_addr, cli_addr, streamsNum, clilen,
                      mon_pipe, device, &pair, "c2s", options->c2s_duration / 1000.0);
        log_println(1, "c2s is exiting gracefully");
        /* Close the pipe */
        close(mon_pipe[0]);
        close(mon_pipe[1]);
        exit(0); /* Packet trace finished, terminate gracefully */
      } else if (c2s_childpid < 0) {
        log_println(0, "C2S test error: can't create child process.");
      }
    }

    packet_trace_running = wait_for_readable_fd(mon_pipe[0]);

    if (packet_trace_running) {
      // Get data collected from packet tracing into the C2S "ndttrace" file
      memset(tmpstr, 0, 256);
      for (i = 0; i < 5; i++) {
        msgretvalue = read(mon_pipe[0], tmpstr, 128);
        if ((msgretvalue == -1) && (errno == EINTR))
          continue;
        break;
      }

      if (strlen(tmpstr) > 5)
        memcpy(meta.c2s_ndttrace, tmpstr, strlen(tmpstr));
      // name of nettrace file passed back from pcap child
      log_println(3, "--tracefile after packet_trace %s",
                  meta.c2s_ndttrace);
    } else {
      log_println(0, "Packet trace was unable to be created");
      packet_trace_emergency_shutdown(mon_pipe);
    }
  }

  log_println(5, "C2S test Parent thinks pipe() returned fd0=%d, fd1=%d",
              mon_pipe[0], mon_pipe[1]);

  // experimental code, delete when finished
  setCwndlimit(conn, group, agent, options);

  // Create C->S snaplog directories, and perform some initialization based on
  // options
  create_client_logdir((struct sockaddr *) &cli_addr[0], clilen,
                       options->c2s_logname, sizeof(options->c2s_logname),
                       namesuffix, sizeof(namesuffix));
  sleep(RACE_CONDITION_WAIT_TIME);
  // Reset alarm() again. This 10 sec test should finish before this signal is
  // generated, but sleep() can render existing alarm()s invalid, and alarm() is
  // our watchdog timer.
  alarm(30);

  // send empty TEST_START indicating start of the test
  send_json_message_any(ctl, TEST_START, "", 0, testOptions->connection_flags,
                        JSON_SINGLE_VALUE);

  // If snaplog recording is enabled, update meta file to indicate the same
  // and proceed to get snapshot and log it.
  // This block is needed here since the meta file stores names without the
  // full directory but fopen needs full path. Else, it could have gone into
  // the "start_snap_worker" method
  if (options->snapshots && options->snaplog) {
    memcpy(meta.c2s_snaplog, namesuffix, strlen(namesuffix));
    /*start_snap_worker(&snapArgs, agent, options->snaplog, &workerLoop,
      &workerThreadId, meta.c2s_snaplog, options->c2s_logname,
      conn, group); */
  }
  if (options->snapshots)
    start_snap_worker(&snapArgs, agent, NULL, options->snaplog, &workerThreadId,
                      options->c2s_logname, conn, group);
  // Wait on listening socket and read data once ready.
  start_time = secs();
  throughputSnapshotTime = start_time + (options->c2s_snapsoffset / 1000.0);

  activeStreams = connections_to_fd_set(c2s_conns, streamsNum, &rfd, &max_fd);

  while (activeStreams > 0 && (secs() - start_time) < testDuration) {
    // POSIX says "Upon successful completion, the select() function may
    // modify the object pointed to by the timeout argument."
    // Therefore sel_tv is undefined afterwards and we must set it every time.
    sel_tv.tv_sec = testDuration + 1;  // time out after test duration + 1sec
    sel_tv.tv_usec = 0;
    msgretvalue = select(max_fd + 1, &rfd, NULL, NULL, &sel_tv);
    if (msgretvalue == -1) {
      if (errno == EINTR) {
        // select interrupted. Continue waiting for activity on socket
        continue;
      } else {
        log_println(1,
                    "Error while trying to wait for incoming data in c2s: %s",
                    strerror(errno));
        break;
      }
    }
    if (extended && options->c2s_throughputsnaps && secs() > throughputSnapshotTime) {
      if (lastThroughputSnapshot != NULL) {
        lastThroughputSnapshot->next = (struct throughputSnapshot*) malloc(sizeof(struct throughputSnapshot));
        lastThroughputSnapshot = lastThroughputSnapshot->next;
      } else {
        *c2s_ThroughputSnapshots = lastThroughputSnapshot = (struct throughputSnapshot*) malloc(sizeof(struct throughputSnapshot));
      }
      lastThroughputSnapshot->next = NULL;
      lastThroughputSnapshot->time = secs() - start_time;
      lastThroughputSnapshot->throughput = (8.e-3 * bytes_read) / (lastThroughputSnapshot->time);  // kbps
      log_println(6, " ---C->S: Throughput at %0.2f secs: Received %0.0f bytes, Spdin= %f",
                     lastThroughputSnapshot->time, bytes_read, lastThroughputSnapshot->throughput);
      throughputSnapshotTime += options->c2s_snapsdelay / 1000.0;
    }

    if (msgretvalue > 0) {
      read_error = read_ready_streams(&rfd, c2s_conns, streamsNum, buff, sizeof(buff), &bytes_read);
      if (read_error != 0 && read_error != EINTR) {
        // EINTR is expected, but all other errors are actually errors
        log_println(1, "Error while trying to read incoming data in c2s: %s",
                    strerror(read_error));
        break;
      }
    }

    // Set up the FD_SET and activeStreams for the next select.
    activeStreams = connections_to_fd_set(c2s_conns, streamsNum, &rfd, &max_fd);
  }
  measured_test_duration = secs() - start_time;
  // From the NDT spec:
  //  throughput in kilo bits per sec =
  //  (transmitted_byte_count * 8) / (time_duration)*(1000)
  *c2sspd = (8.0e-3 * bytes_read) / measured_test_duration;

  // As a kindness to old clients, drain their queues for a second or two.
  // TODO: Fix web100clt code to eliminate the need for this.  In general,
  //       clients that need this line should be removed from their respective
  //       gene pools and this code should be deleted.
  drain_old_clients(c2s_conns, streamsNum, buff, sizeof(buff));

  // c->s throuput value calculated and assigned ! Release resources, conclude
  // snap writing.
  if (options->snapshots)
    stop_snap_worker(&workerThreadId, options->snaplog, &snapArgs);

  // send the server calculated value of C->S throughput as result to client
  snprintf(buff, sizeof(buff), "%6.0f kbps outbound for child %d", *c2sspd,
           testOptions->child0);
  log_println(1, "%s", buff);
  snprintf(buff, sizeof(buff), "%0.0f", *c2sspd);
  if (extended && options->c2s_throughputsnaps && *c2s_ThroughputSnapshots != NULL) {
    struct throughputSnapshot *snapshotsPtr = *c2s_ThroughputSnapshots;
    while (snapshotsPtr != NULL) {
      int currBuffLength = strlen(buff);
      snprintf(&buff[currBuffLength], sizeof(buff)-currBuffLength, " %0.2f %0.2f", snapshotsPtr->time, snapshotsPtr->throughput);
      snapshotsPtr = snapshotsPtr->next;
    }
  }
  send_json_message_any(ctl, TEST_MSG, buff, strlen(buff),
                        testOptions->connection_flags, JSON_SINGLE_VALUE);

  // get receiver side Web100 stats and write them to the log file. close
  // sockets
  if (record_reverse == 1)
    tcp_stat_get_data_recv(c2s_conns[0].socket, agent, conn, count_vars);


  close_all_connections(c2s_conns, streamsNum);
  close(testOptions->c2ssockfd);

  if (packet_trace_running) {
    log_println(1, "Signal USR1(%d) sent to child [%d]", SIGUSR1,
                c2s_childpid);
    testOptions->child1 = c2s_childpid;
    kill(c2s_childpid, SIGUSR1);
    i = 0;

    for (;;) {
      FD_ZERO(&rfd);
      FD_SET(mon_pipe[0], &rfd);
      sel_tv.tv_sec = 1;
      sel_tv.tv_usec = 100000;
      msgretvalue = select(mon_pipe[0] + 1, &rfd, NULL, NULL, &sel_tv);
      if (msgretvalue <= 0) {
        local_errno = (msgretvalue == -1) ? errno : 0;
        if (local_errno == EINTR) continue;
        // Either a timeout or an error that wasn't EINTR...
        log_println(4, "Failed to read pkt-pair data from C2S flow, "
                    "retcode=%d, reason=%d", msgretvalue, local_errno);
        snprintf(spds[(*spd_index)++],
                 sizeof(spds[*spd_index]),
                 " -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0.0 0 0 0 0 0 -1");
        snprintf(spds[(*spd_index)++],
                 sizeof(spds[*spd_index]),
                 " -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0.0 0 0 0 0 0 -1");
        break;
      } else {
        /* There is something to read, so get it from the pktpair child.  If an
         * interrupt occurs, just skip the read and go on
         * RAC 2/8/10
         */
        if ((msgretvalue = read(mon_pipe[0], spds[*spd_index],
                                sizeof(spds[*spd_index]))) < 0) {
          snprintf(
              spds[*spd_index],
              sizeof(spds[*spd_index]),
              " -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0.0 0 0 0 0 0 -1");
        }
        log_println(1, "%d bytes read '%s' from C2S monitor pipe",
                    msgretvalue, spds[*spd_index]);
        (*spd_index)++;
        if (i++ == 1) break;
      }
    }
  }

  // An empty TEST_FINALIZE message is sent to conclude the test
  send_json_message_any(ctl, TEST_FINALIZE, "", 0,
                        testOptions->connection_flags, JSON_SINGLE_VALUE);

  //  Close opened resources for packet capture
  if (packet_trace_running) {
    // TODO: Determine whether this shutdown can be performed in a non-blocking
    // manner, and if so then refactor packet_trace_emergency_shutdown to have
    // better error handling and use that refactored and renamed function here.
    stop_packet_trace(mon_pipe);
    packet_trace_running = 0;
  }

  // log end of C->S test
  log_println(1, " <----------- %d -------------->", testOptions->child0);
  // protocol logs
  teststatuses = TEST_ENDED;
  protolog_status(testOptions->child0, testids, teststatuses, ctl->socket);

  // set current test status and free address
  setCurrentTest(TEST_NONE);


  return 0;
}
示例#26
0
int
test_s2c_clt(int ctlSocket, char tests, char* host, int conn_options, int buf_size, char* tmpstr)
{
  char buff[BUFFSIZE+1];
  int msgLen, msgType;
  int s2cport = 3003;
  I2Addr sec_addr = NULL;
  int inlth, ret, one=1, set_size;
  int inSocket;
  socklen_t optlen;
  uint32_t bytes;
  double t;
  struct timeval sel_tv;
  fd_set rfd;
  char* ptr;
  
  if (tests & TEST_S2C) {
    log_println(1, " <-- S2C throughput test -->");
    msgLen = sizeof(buff);
    if (recv_msg(ctlSocket, &msgType, buff, &msgLen)) {
      log_println(0, "Protocol error - missed prepare message!");
      return 1;
    }
    if (check_msg_type("S2C throughput test", TEST_PREPARE, msgType, buff, msgLen)) {
      return 2;
    }
    if (msgLen <= 0) {
      log_println(0, "Improper message");
      return 3;
    }
    buff[msgLen] = 0;
    if (check_int(buff, &s2cport)) {
      log_println(0, "Invalid port number");
      return 4;
    }
    log_println(1, "  -- port: %d", s2cport);

    /* Cygwin seems to want/need this extra getsockopt() function
     * call.  It certainly doesn't do anything, but the S2C test fails
     * at the connect() call if it's not there.  4/14/05 RAC
     */
    optlen = sizeof(set_size);
    getsockopt(ctlSocket, SOL_SOCKET, SO_SNDBUF, &set_size, &optlen);

    if ((sec_addr = I2AddrByNode(get_errhandle(), host)) == NULL) {
      log_println(0, "Unable to resolve server address: %s", strerror(errno));
      return -3;
    }
    I2AddrSetPort(sec_addr, s2cport);

    if ((ret = CreateConnectSocket(&inSocket, NULL, sec_addr, conn_options, buf_size))) {
      log_println(0, "Connect() for Server to Client failed", strerror(errno));
      return -15;
    }

    setsockopt(inSocket, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));

    /* Linux updates the sel_tv time values everytime select returns.  This
     * means that eventually the timer will reach 0 seconds and select will
     * exit with a timeout signal.  Other OS's don't do that so they need
     * another method for detecting a long-running process.  The check below
     * will cause the loop to terminate if select says there is something
     * to read and the loop has been active for over 14 seconds.  This usually
     * happens when there is a problem (duplex mismatch) and there is data
     * queued up on the server.
     */
    
    msgLen = sizeof(buff);
    if (recv_msg(ctlSocket, &msgType, buff, &msgLen)) {
      log_println(0, "Protocol error - missed start message!");
      return 1;
    }
    if (check_msg_type("S2C throughput test", TEST_START, msgType, buff, msgLen)) {
      return 2;
    }

    printf("running 10s inbound test (server to client) . . . . . . ");
    fflush(stdout);

    bytes = 0;
    t = secs() + 15.0;
    sel_tv.tv_sec = 15;
    sel_tv.tv_usec = 5;
    FD_ZERO(&rfd);
    FD_SET(inSocket, &rfd);
    for (;;) {
      ret = select(inSocket+1, &rfd, NULL, NULL, &sel_tv);
      if (secs() > t) {
        log_println(5, "Receive test running long, break out of read loop");
        break;
      }
      if (ret > 0) {
        inlth = read(inSocket, buff, sizeof(buff));
        if (inlth == 0)
          break;
        bytes += inlth;
        continue;
      }
      if (get_debuglvl() > 5) {
        log_println(0, "s2c read loop exiting:", strerror(errno));
      }
      break;
    }
    t = secs() - t + 15.0;
    spdin = ((8.0 * bytes) / 1000) / t;

    /* receive the s2cspd from the server */
    msgLen = sizeof(buff);
    if (recv_msg(ctlSocket, &msgType, buff, &msgLen)) {
      log_println(0, "Protocol error - missed text message!");
      return 1;
    }
    if (check_msg_type("S2C throughput test", TEST_MSG, msgType, buff, msgLen)) {
      return 2;
    }
    if (msgLen <= 0) { 
      log_println(0, "Improper message");
      return 3;
    }
    buff[msgLen] = 0; 
    ptr = strtok(buff, " ");
    if (ptr == NULL) {
      log_println(0, "S2C: Improper message");
      return 4;
    }
    s2cspd = atoi(ptr);
    ptr = strtok(NULL, " ");
    if (ptr == NULL) {
      log_println(0, "S2C: Improper message");
      return 4;
    }
    ssndqueue = atoi(ptr);
    ptr = strtok(NULL, " ");
    if (ptr == NULL) {
      log_println(0, "S2C: Improper message");
      return 4;
    }
    sbytes = atoi(ptr);
    
    if (spdin < 1000)
      printf("%0.2f kb/s\n", spdin);
    else
      printf("%0.2f Mb/s\n", spdin/1000);

    I2AddrFree(sec_addr);

    sprintf(buff, "%0.0f", spdin);
    send_msg(ctlSocket, TEST_MSG, buff, strlen(buff));
    
    /* get web100 variables from server */
    tmpstr[0] = '\0';
    for (;;) {
      msgLen = sizeof(buff);
      if (recv_msg(ctlSocket, &msgType, buff, &msgLen)) {
        log_println(0, "Protocol error - missed text/finalize message!");
        return 1;
      }
      if (msgType == TEST_FINALIZE) {
        break;
      }
      if (check_msg_type("S2C throughput test", TEST_MSG, msgType, buff, msgLen)) {
        return 2;
      }
      strncat(tmpstr, buff, msgLen);
      log_println(6, "tmpstr = '%s'", tmpstr);
    }
    log_println(1, " <------------------------->");
  }


  return 0;
}
示例#27
0
// ------------------------------------------------------------------------
// CDRMConsume:: ActivateL
//
// Calculate the smallest end time based on interval, end time,
// accumulated time & timed count.
// ------------------------------------------------------------------------
//
void CDRMConsume::ActivateL( TBool aSecureTime,
                             const TTime& aTrustedTime  )
{
    DRMLOG( _L( "CDRMConsume::ActivateL" ) );

    __ASSERT_DEBUG( iChild && iCombined, User::Invariant() );
    TTime endTime( Time::MaxTTime() );
    TTimeIntervalSeconds timed( KMaxTInt32 );
    TBool timeUsed( EFalse );
    TBool endTimeUsed( EFalse );

    iCurrentDelay = 0;

    if ( iCombined->iActiveConstraints & EConstraintTimedCounter )
    {
        // Take this, even if timed counts have been updated.
        // This might cause unnecessary RunL's to be called, but it
        // ensures both child & parent will be consumed when needed.
        // If e.g. it would be checked that iTimedCounts == 0xf,
        // either one (child or parent) might not get updated in case of
        // "Child expired, but parent didn't -> find new child".
        PickSmaller( timed, iCombined->iTimedInterval );
        timeUsed = ETrue;
    }

    if ( iCombined->iActiveConstraints & EConstraintAccumulated )
    {
        PickSmaller( timed, iCombined->iAccumulatedTime );
        timeUsed = ETrue;
    }

    if ( iCombined->iActiveConstraints & EConstraintInterval )
    {
        if ( iCombined->iIntervalStart != Time::NullTTime() )
        {
            endTime = iCombined->iIntervalStart;
            endTime += iCombined->iInterval;
            endTimeUsed = ETrue;
        }
        else
        {
            TInt64 tmp( iCombined->iInterval.Int() );

            PickSmaller( timed, tmp );
            timeUsed = ETrue;
        }
    }

    if ( iCombined->iActiveConstraints & EConstraintEndTime )
    {
        PickSmaller( endTime, iCombined->iEndTime );
        endTimeUsed = ETrue;
    }

    // Put the "smallest time" information to "endTime".
    if ( timeUsed )
    {
        TTime current( aTrustedTime );

        current += timed;

        PickSmaller( endTime, current );
        endTimeUsed = ETrue;
    }

    // Interval gets initialised immediately, and so do count constraints.
    // Timed/accumulated won't: those are consumed after the
    // interval if secure time exists.
    Consume( ETrue, ETrue, EFalse, 0,
             aSecureTime,
             aTrustedTime );

    // In case something was modified, update the db also.
    UpdateDBL();

    if ( endTimeUsed )
    {
        // Something exists.
        TTimeIntervalSeconds secs( 0 );
        TTime current( aTrustedTime );
        TInt err( KErrNone );

        // SecondsFrom returns an error if the difference is too great.
        err = endTime.SecondsFrom( current, secs );
        if ( err )
        {
            iCurrentDelay = KConsumeDefaultTimer;
        }
        else if ( secs.Int() < 0 )
        {
            iCurrentDelay = 0; // Already expired.
        }
        else if ( secs.Int() < KConsumeDefaultTimer )
        {
            iCurrentDelay = secs.Int();
        }
        else
        {
            iCurrentDelay = KConsumeDefaultTimer;
        }

        if ( !IsAdded() )
        {
            CActiveScheduler::Add( this );
        }

        DRMLOG2( _L( "CDRMConsume::ActivateL: using interval %d" ),
                 ( TInt )iCurrentDelay );

        // secs -> microsecs. The method sets the AO active.
        After( TTimeIntervalMicroSeconds32( iCurrentDelay * 1000000 ) );

        iTime = current;

        // If we see timed things here, we also have secure time.
        //SETBIT( iMask, KConsumeHasSecureTime );
    }
    else    // For metering we always need to have this:
    {
        iCurrentDelay = KConsumeDefaultTimer;
        iTime = aTrustedTime;

        if ( !IsAdded() )
        {
            CActiveScheduler::Add( this );
        }

        DRMLOG2( _L( "CDRMConsume::ActivateL: using interval %d" ),
                 ( TInt )iCurrentDelay );

        // secs -> microsecs. The method sets the AO active.
        After( TTimeIntervalMicroSeconds32( iCurrentDelay * 1000000 ) );
    }

    // If we see timed things here, we also have secure time.
    if( aTrustedTime != Time::NullTTime())
    {
        SETBIT( iMask, KConsumeHasSecureTime );
    }
    DRMLOG( _L( "CDRMConsume::ActivateL ok" ) );
}
示例#28
0
namespace antares {

static const int kCursorBoundsSize = 16;
static const usecs kTimeout = secs(1);

Cursor::Cursor(): _sprite(500, GRAY) { }

void Cursor::draw() const {
    draw_at(sys.video->get_mouse());
}

void Cursor::draw_at(Point where) const {
    if (world().contains(where)) {
        where.offset(-_sprite.at(0).center().h, -_sprite.at(0).center().v);
        _sprite.at(0).texture().draw(where.h, where.v);
    }
}

GameCursor::GameCursor():
        show(true),
        _show_crosshairs_until(now() + kTimeout) { }

bool GameCursor::active() const {
    return show && (_show_crosshairs_until > now());
}

Point GameCursor::clamped_location() {
    return clamp(sys.video->get_mouse());
}

Point GameCursor::clamp(Point p) {
    // Do the cursor, too, unless this is a replay.
    if (p.h > (viewport().right - kCursorBoundsSize - 1)) {
        p.h = viewport().right - kCursorBoundsSize - 1;
    }
    if (p.v < (viewport().top + kCursorBoundsSize)) {
        p.v = viewport().top + kCursorBoundsSize;
    } else if (p.v > (play_screen().bottom - kCursorBoundsSize - 1)) {
        p.v = play_screen().bottom - kCursorBoundsSize - 1;
    }
    return p;
}

void GameCursor::mouse_down(const MouseDownEvent& event) {
    if (event.where().h >= viewport().left) {
        wake();
    }
}

void GameCursor::mouse_up(const MouseUpEvent& event) {
    if (event.where().h >= viewport().left) {
        wake();
    }
}

void GameCursor::mouse_move(const MouseMoveEvent& event) {
    if (event.where().h >= viewport().left) {
        wake();
    }
}

void GameCursor::wake() {
    _show_crosshairs_until = now() + kTimeout;
}

ANTARES_GLOBAL bool HintLine::show_hint_line = false;
ANTARES_GLOBAL Point HintLine::hint_line_start;
ANTARES_GLOBAL Point HintLine::hint_line_end;
ANTARES_GLOBAL RgbColor HintLine::hint_line_color;
ANTARES_GLOBAL RgbColor HintLine::hint_line_color_dark;

void HintLine::show(Point fromWhere, Point toWhere, uint8_t color, uint8_t brightness) {
    hint_line_start = fromWhere;
    hint_line_end = toWhere;
    show_hint_line = true;

    hint_line_color = GetRGBTranslateColorShade(color, brightness);
    hint_line_color_dark = GetRGBTranslateColorShade(color, VERY_DARK);
}

void HintLine::hide() {
    show_hint_line = false;
}

void HintLine::reset() {
    show_hint_line = false;
    hint_line_start.h = hint_line_start.v = -1;
    hint_line_end.h = hint_line_end.v = -1;
    hint_line_color = hint_line_color_dark = RgbColor::black();
}

void GameCursor::draw() const {
    if (!show) {
        return;
    }

    Point where = sys.video->get_mouse();

    where = clamp(where);
    if (active()) {
        const Rect clip_rect = viewport();
        const RgbColor color = GetRGBTranslateColorShade(SKY_BLUE, MEDIUM);

        Point top_a = Point(where.h, clip_rect.top);
        Point top_b = Point(where.h, (where.v - kCursorBoundsSize));
        Point bottom_a = Point(where.h, (where.v + kCursorBoundsSize));
        Point bottom_b = Point(where.h, clip_rect.bottom - 1);
        Point left_a = Point(clip_rect.left, where.v);
        Point left_b = Point((where.h - kCursorBoundsSize), where.v);
        Point right_a = Point(std::max(viewport().left, where.h + kCursorBoundsSize), where.v);
        Point right_b = Point(clip_rect.right - 1, where.v);

        Rects rects;
        if (top_a.h >= viewport().left) {
            rects.fill({top_a.h, top_a.v, top_b.h + 1, top_b.v + 1}, color);
            rects.fill({bottom_a.h, bottom_a.v, bottom_b.h + 1, bottom_b.v + 1}, color);
        }
        rects.fill({right_a.h, right_a.v, right_b.h + 1, right_b.v + 1}, color);
        if (left_b.h >= viewport().left) {
            rects.fill({left_a.h, left_a.v, left_b.h + 1, left_b.v + 1}, color);
        }
    }

    if (where.h < viewport().left) {
        draw_at(where);
    }
}

void HintLine::draw() {
    if (show_hint_line) {
        Lines lines;
        Point start = hint_line_start;
        Point end = hint_line_end;

        start.offset(0, 2);
        end.offset(0, 2);
        lines.draw(start, end, hint_line_color_dark);

        start.offset(0, -1);
        end.offset(0, -1);
        lines.draw(start, end, hint_line_color);

        start.offset(0, -1);
        end.offset(0, -1);
        lines.draw(start, end, hint_line_color);
    }
}

}  // namespace antares
void RunKMedoids(const leveldb::Slice& begin,
                 const leveldb::Slice& end,
                 int K, leveldb::DB* db,
                 leveldb::DB* work_db, int concurrency,
                 std::ostream& ivar_out, std::ostream& cent_out) {
  auto very_start = std::chrono::system_clock::now();
  auto key_centroids = uniform_init(begin, end, K);
  std::vector<GDELTMini> val_centroids(K);
  {
    auto it = iter(db);
    for (int i = 0; i < K; ++i) {
      it->Seek(key_centroids[i]);
      CHECK(it->Valid());
      read(it->value(), val_centroids[i]);
    }
  }

  std::cout << "Divying up range among threads... " << std::flush;
  auto parvec = get_par_ranges(uniform_init(begin, end, concurrency), db, end);
  std::cout << "DONE" << std::endl;

  int i = 0;
  bool centers_changed = true;
  vuad totals(K);
  vuai cluster_sizes(K);
  for (int i = 0; i < K; ++i) {
    cluster_sizes[i].reset(new std::atomic<int>);
    totals[i].reset(new std::atomic<double>);
  }

  while (centers_changed) {
    auto start = std::chrono::system_clock::now();
    assign_closest(parvec, totals, K, work_db, val_centroids, concurrency,
                   cluster_sizes);
    auto tot = std::accumulate(totals.begin(), totals.end(), 0.0,
                               [](double sum, typename vuad::value_type& d) {
                                 return sum + d->load();
                               });
    auto end = std::chrono::system_clock::now();
    std::cout << "Iteration " << ++i << " total intravariance " << tot;
    std::cout << "\n    Assigning medoids took " << secs(start, end)
              << "s" << std::endl;

    start = std::chrono::system_clock::now();
    for (auto& d : totals) {
      ivar_out << d->load() << " ";
    }
    ivar_out << std::endl;
    cent_out << key_centroids << std::endl;
    end = std::chrono::system_clock::now();
    std::cout << "    Saving medoids took " << secs(start, end)
              << " s" << std::endl;

    start = std::chrono::system_clock::now();
    centers_changed = update_medoids(concurrency, K, db, work_db,
                                     val_centroids, key_centroids,
                                     totals, cluster_sizes);
    end = std::chrono::system_clock::now();
    std::cout << "    Medoid update took " << secs(start, end)
              << " s" << std::endl;
    start = end;
  }
  auto very_end = std::chrono::system_clock::now();
  std::cout << "K-medoid clustering COMPLETE in "
            << secs(very_start, very_end) << " s" << std::endl;
}