TEST_F(WiredTigerRecoveryUnitTestFixture, CommitTimestampAfterSetTimestampOnAbort) {
    boost::optional<Timestamp> commitTs = boost::none;
    auto opCtx = clientAndCtx1.second.get();
    Timestamp ts1(5, 5);
    Timestamp ts2(6, 6);

    {
        WriteUnitOfWork wuow(opCtx);
        opCtx->recoveryUnit()->onCommit(
            [&](boost::optional<Timestamp> commitTime) { commitTs = commitTime; });
        ASSERT(!commitTs);
        ASSERT_OK(opCtx->recoveryUnit()->setTimestamp(ts2));
        ASSERT(!commitTs);
    }
    ASSERT(!commitTs);

    opCtx->recoveryUnit()->setCommitTimestamp(ts1);
    ASSERT(!commitTs);

    {
        WriteUnitOfWork wuow(opCtx);
        opCtx->recoveryUnit()->onCommit(
            [&](boost::optional<Timestamp> commitTime) { commitTs = commitTime; });
        ASSERT(!commitTs);
    }
    ASSERT(!commitTs);
}
Пример #2
0
    void setDatePartTest()
    {
        csvsqldb::Timestamp ts1(1970, csvsqldb::Date::September, 23, 8, 9, 11, 115);

        ts1.day(17);
        ts1.month(csvsqldb::Date::August);
        ts1.year(2015);
        ts1.hour(16);
        ts1.minute(33);
        ts1.second(47);
        ts1.millisecond(899);

        MPF_TEST_ASSERTEQUAL(17, ts1.day());
        MPF_TEST_ASSERTEQUAL(8, ts1.month());
        MPF_TEST_ASSERTEQUAL(2015, ts1.year());
        MPF_TEST_ASSERTEQUAL(16, ts1.hour());
        MPF_TEST_ASSERTEQUAL(33, ts1.minute());
        MPF_TEST_ASSERTEQUAL(47, ts1.second());
        MPF_TEST_ASSERTEQUAL(899, ts1.millisecond());

        ts1.ymdhmsm(1963, csvsqldb::Date::March, 6, 10, 5, 59, 1);

        MPF_TEST_ASSERTEQUAL(6, ts1.day());
        MPF_TEST_ASSERTEQUAL(3, ts1.month());
        MPF_TEST_ASSERTEQUAL(1963, ts1.year());
        MPF_TEST_ASSERTEQUAL(10, ts1.hour());
        MPF_TEST_ASSERTEQUAL(5, ts1.minute());
        MPF_TEST_ASSERTEQUAL(59, ts1.second());
        MPF_TEST_ASSERTEQUAL(1, ts1.millisecond());
    }
Пример #3
0
    void constructionTest()
    {
        csvsqldb::Timestamp ts1(1970, csvsqldb::Date::September, 23, 8, 9, 11, 115);
        MPF_TEST_ASSERTEQUAL(23, ts1.day());
        MPF_TEST_ASSERTEQUAL(9, ts1.month());
        MPF_TEST_ASSERTEQUAL(1970, ts1.year());
        MPF_TEST_ASSERTEQUAL(8, ts1.hour());
        MPF_TEST_ASSERTEQUAL(9, ts1.minute());
        MPF_TEST_ASSERTEQUAL(11, ts1.second());
        MPF_TEST_ASSERTEQUAL(115, ts1.millisecond());

        csvsqldb::Timestamp ts2;
        MPF_TEST_ASSERT(ts2.isInfinite());

        csvsqldb::Timestamp ts3(0, csvsqldb::Date::January, 1, 0, 0, 0, 0);
        MPF_TEST_ASSERTEQUAL(1, ts3.day());
        MPF_TEST_ASSERTEQUAL(1, ts3.month());
        MPF_TEST_ASSERTEQUAL(0, ts3.year());
        MPF_TEST_ASSERTEQUAL(0, ts3.hour());
        MPF_TEST_ASSERTEQUAL(0, ts3.minute());
        MPF_TEST_ASSERTEQUAL(0, ts3.second());
        MPF_TEST_ASSERTEQUAL(0, ts3.millisecond());

        csvsqldb::Timestamp ts4(9999, csvsqldb::Date::December, 31, 23, 59, 59, 999);
        MPF_TEST_ASSERTEQUAL(31, ts4.day());
        MPF_TEST_ASSERTEQUAL(12, ts4.month());
        MPF_TEST_ASSERTEQUAL(9999, ts4.year());
        MPF_TEST_ASSERTEQUAL(23, ts4.hour());
        MPF_TEST_ASSERTEQUAL(59, ts4.minute());
        MPF_TEST_ASSERTEQUAL(59, ts4.second());
        MPF_TEST_ASSERTEQUAL(999, ts4.millisecond());
    }
Пример #4
0
TEST_F(TimeStampTests, testArithmetics)
{
  OpenAB::TimeStamp ts1(5, 900000);
  OpenAB::TimeStamp ts2(1, 200000);

  OpenAB::TimeStamp result;

  result = ts1 + ts2;
  ASSERT_EQ(7100, result.toMs());

  result = ts1 - ts2;
  ASSERT_EQ(4700, result.toMs());

  ts1 += ts2;
  ASSERT_EQ(7100, ts1.toMs());

  ts1 = OpenAB::TimeStamp(5, 900000);
  ts1 -= ts2;
  ASSERT_EQ(4700, ts1.toMs());

  ASSERT_TRUE(ts1 > ts2);
  ASSERT_TRUE(ts1 >= ts2);

  ASSERT_FALSE(ts2 > ts1);
  ASSERT_FALSE(ts2 >= ts1);


  ASSERT_FALSE(ts1 < ts2);
  ASSERT_FALSE(ts1 <= ts2);

  ASSERT_TRUE(ts2 < ts1);
  ASSERT_TRUE(ts2 <= ts1);
}
Пример #5
0
    void copyTest()
    {
        csvsqldb::Timestamp ts1(1970, csvsqldb::Date::September, 23, 8, 9, 11, 115);
        csvsqldb::Timestamp ts2(ts1);

        MPF_TEST_ASSERTEQUAL(23, ts2.day());
        MPF_TEST_ASSERTEQUAL(9, ts2.month());
        MPF_TEST_ASSERTEQUAL(1970, ts2.year());
        MPF_TEST_ASSERTEQUAL(8, ts2.hour());
        MPF_TEST_ASSERTEQUAL(9, ts2.minute());
        MPF_TEST_ASSERTEQUAL(11, ts2.second());
        MPF_TEST_ASSERTEQUAL(115, ts2.millisecond());

        csvsqldb::Timestamp ts3(2014, csvsqldb::Date::December, 30, 9, 5, 8);
        MPF_TEST_ASSERTEQUAL(30, ts3.day());
        MPF_TEST_ASSERTEQUAL(12, ts3.month());
        MPF_TEST_ASSERTEQUAL(2014, ts3.year());
        MPF_TEST_ASSERTEQUAL(9, ts3.hour());
        MPF_TEST_ASSERTEQUAL(5, ts3.minute());
        MPF_TEST_ASSERTEQUAL(8, ts3.second());
        MPF_TEST_ASSERTEQUAL(0, ts3.millisecond());

        ts3 = ts2;
        MPF_TEST_ASSERTEQUAL(23, ts3.day());
        MPF_TEST_ASSERTEQUAL(9, ts3.month());
        MPF_TEST_ASSERTEQUAL(1970, ts3.year());
        MPF_TEST_ASSERTEQUAL(8, ts3.hour());
        MPF_TEST_ASSERTEQUAL(9, ts3.minute());
        MPF_TEST_ASSERTEQUAL(11, ts3.second());
        MPF_TEST_ASSERTEQUAL(115, ts3.millisecond());
    }
Пример #6
0
    void operatorTest()
    {
        csvsqldb::Timestamp ts1(1970, csvsqldb::Date::September, 23, 8, 9, 11, 115);
        csvsqldb::Timestamp ts2(2015, csvsqldb::Date::January, 1, 0, 0, 0);

        MPF_TEST_ASSERTEQUAL(1397145049, ts2 - ts1);

        csvsqldb::Timestamp ts3(2035, csvsqldb::Date::September, 23, 8, 9, 11, 115);
        MPF_TEST_ASSERTEQUAL(65, (ts3 - ts1) / (365 * 24 * 60 * 60));
    }
Пример #7
0
void TestQ5()
{
	//int _a[4];
	//TwoStack<int> ts1(_a,4);
	TwoStack<int> ts1(4);
	ts1.push(2,1);
	ts1.push(2,2);
	ts1.push(2,3);
	ts1.push(2,4);
}
TEST_F(WiredTigerRecoveryUnitTestFixture, CommitWithoutDurableTimestamp) {
    auto opCtx = clientAndCtx1.second.get();
    Timestamp ts1(5, 5);
    opCtx->recoveryUnit()->setCommitTimestamp(ts1);

    {
        WriteUnitOfWork wuow(opCtx);
        wuow.commit();
    }
}
Пример #9
0
void pirdev::start(const QString proxy,const QString port){

    if ( proxy != ""  && port != "" ) {
    QString pip,pport;

    pip = proxy;
    pport = port;
    qDebug() << pip + ":" + pport ;
    QString http = "Acquire::http::Proxy \"http://" + pip + ":" + pport + "/\";";
    QString https = "Acquire::https::Proxy \"https://" + pip + ":" + pport + "/\";";

    qDebug() << http << "\n" << https;

    QFile f("/tmp/ir-dev.sh");
    if (!f.open(QFile::WriteOnly|QFile::Truncate)) {
        qDebug() << "[0]Error: File cannot be created" << "";
        exit(1);
    }

    QTextStream ts(&f) ;
    ts << "#!/bin/sh\n" << "cp -Rf /tmp/01proxy /etc/apt/apt.conf.d/";
    f.close();
      /////

    QFile f1("/tmp/01proxy");
    if (!f1.open(QFile::WriteOnly|QFile::Truncate)) {
        qDebug() << "[1]Error: File cannot be created" << "";
        exit(1);
    }
    QTextStream ts1(&f1);
    ts1 << http + "\n" + https;
    f1.close();

    ////
    QStringList args;

    QFile f2("/tmp/ir-dev2.sh");
    if (!f2.open(QFile::WriteOnly|QFile::Truncate)){
        qDebug() << "[2]Error: File cannot be created" << "";
        exit(1);
    }
    QTextStream ts2(&f2);
    ts2 << "#!/bin/sh\n\n" <<  "export _SBOX_DIR=xxx\n\n" << "/usr/lib/package-manager/pm-notification-tool.sh perl -e \'$<=0;$>=0;exec(\"sh\",\"/tmp/ir-dev.sh\")\' ";

    f2.close();
    args << "/tmp/ir-dev2.sh";
    QProcess::startDetached("/bin/sh",args);
    }
    else
    {
        qDebug() << "Error";
        //exit(1);
    }
}
Пример #10
0
    void specialGetterTest()
    {
        csvsqldb::Timestamp ts1(1970, csvsqldb::Date::September, 23, 8, 9, 11, 115);
        MPF_TEST_ASSERTEQUAL(csvsqldb::Date::Wednesday, ts1.dayOfWeek());
        MPF_TEST_ASSERTEQUAL(266, ts1.dayOfYear());
        MPF_TEST_ASSERTEQUAL(39, ts1.weekOfYear());

        csvsqldb::Timestamp ts2(1963, csvsqldb::Date::March, 6, 10, 5, 59, 1);
        MPF_TEST_ASSERTEQUAL(csvsqldb::Date::Wednesday, ts2.dayOfWeek());
        MPF_TEST_ASSERTEQUAL(65, ts2.dayOfYear());
        MPF_TEST_ASSERTEQUAL(10, ts2.weekOfYear());
    }
Пример #11
0
    void addDurationTest()
    {
        csvsqldb::Timestamp ts1(1970, csvsqldb::Date::September, 23, 8, 9, 11, 115);
        csvsqldb::Duration d(45, 2, 7, 3, 57, 999);
        ts1.addDuration(d);

        MPF_TEST_ASSERTEQUAL(2015, ts1.year());
        MPF_TEST_ASSERTEQUAL(csvsqldb::Date::November, ts1.month());
        MPF_TEST_ASSERTEQUAL(30, ts1.day());
        MPF_TEST_ASSERTEQUAL(12, ts1.hour());
        MPF_TEST_ASSERTEQUAL(22, ts1.minute());
        MPF_TEST_ASSERTEQUAL(50, ts1.second());
    }
Пример #12
0
        /**
          *   Generate 2 blocks of open info and create secret key.
         **/
        void generate_key_infos( const std::string &key,
                                 std::string &s1, std::string &s2,
                                 std::string &result )
        {
            random_device rd( false );

            std::string ts1( rd.generate_block( 256 ) );
            std::string ts2( rd.generate_block( 256 ) );

            create_key( key, ts1, ts2, result );

            s1.swap( ts1 );
            s2.swap( ts2 );
        }
TEST_F(WiredTigerRecoveryUnitTestFixture, CommitWithDurableTimestamp) {
    auto opCtx = clientAndCtx1.second.get();
    Timestamp ts1(3, 3);
    Timestamp ts2(5, 5);

    opCtx->recoveryUnit()->setCommitTimestamp(ts1);
    opCtx->recoveryUnit()->setDurableTimestamp(ts2);
    auto durableTs = opCtx->recoveryUnit()->getDurableTimestamp();
    ASSERT_EQ(ts2, durableTs);

    {
        WriteUnitOfWork wuow(opCtx);
        wuow.commit();
    }
}
Пример #14
0
    void formatTest()
    {
        csvsqldb::Timestamp ts1(1970, csvsqldb::Date::September, 23, 8, 9, 11, 115);

        MPF_TEST_ASSERTEQUAL("1970-09-23T08:09:11", ts1.format("%F"));
        MPF_TEST_ASSERTEQUAL("1970-09-23T08:09:11.115", ts1.format("%Y-%m-%dT%H:%M:%S.%s"));

        csvsqldb::Timestamp ts2(2015, csvsqldb::Date::July, 2, 14, 20, 30, 0);

        MPF_TEST_ASSERTEQUAL("2015-07-02T14:20:30", ts2.format("%F"));

        MPF_TEST_ASSERTEQUAL("23.09.1970 266 39 3", ts1.format("%d.%m.%Y %j %U %w"));
        MPF_TEST_ASSERTEQUAL("02.07.2015 183 27 4", ts2.format("%d.%m.%Y %j %U %w"));

        csvsqldb::Timestamp ts3(0, csvsqldb::Date::January, 1, 0, 0, 0, 0);
        MPF_TEST_ASSERTEQUAL("0000-01-01T00:00:00", ts3.format("%F"));
    }
Пример #15
0
    void compareTest()
    {
        csvsqldb::Timestamp ts1(1970, csvsqldb::Date::September, 23, 8, 9, 11, 115);
        csvsqldb::Timestamp ts2(1963, csvsqldb::Date::March, 6, 10, 5, 59, 1);

        MPF_TEST_ASSERT(ts1 != ts2);
        MPF_TEST_ASSERT(!(ts1 == ts2));
        MPF_TEST_ASSERT(ts2 < ts1);
        MPF_TEST_ASSERT(ts1 > ts2);
        MPF_TEST_ASSERT(ts2 <= ts1);
        MPF_TEST_ASSERT(ts1 >= ts2);

        csvsqldb::Timestamp ts3(ts2);
        MPF_TEST_ASSERT(ts2 == ts3);
        MPF_TEST_ASSERT(!(ts2 != ts3));
        MPF_TEST_ASSERT(ts2 >= ts3);
        MPF_TEST_ASSERT(ts2 <= ts3);
    }
TEST_F(WiredTigerRecoveryUnitTestFixture, ChangeIsPassedCommitTimestamp) {
    boost::optional<Timestamp> commitTs = boost::none;
    auto opCtx = clientAndCtx1.second.get();
    Timestamp ts1(5, 5);

    opCtx->recoveryUnit()->setCommitTimestamp(ts1);
    ASSERT(!commitTs);

    {
        WriteUnitOfWork wuow(opCtx);
        opCtx->recoveryUnit()->onCommit(
            [&](boost::optional<Timestamp> commitTime) { commitTs = commitTime; });
        ASSERT(!commitTs);
        wuow.commit();
        ASSERT_EQ(*commitTs, ts1);
    }
    ASSERT_EQ(*commitTs, ts1);
}
Пример #17
0
        /**
          *   keys for basic authentication;
          *   result is: sha256( s2 + sha256( s1 + key ) );
          *   s1 and s2 are open information
         **/
        void create_key( const std::string &key,
                         const std::string &s1, const std::string &s2,
                               std::string &result )
        {
            std::string tkey(key);
            std::string ts1 (s1 );
            std::string ts2 (s2 );

            vtrc::unique_ptr<hash_iface> sha256( hash::sha2::create256( ) );

            ts1.append( tkey.begin( ), tkey.end( ) );
            ts1.assign( sha256->get_data_hash( ts1.c_str( ), ts1.size( ) ) );

            ts2.append( ts1.begin( ), ts1.end( ) );
            ts2.assign( sha256->get_data_hash( ts2.c_str( ), ts2.size( ) ) );

            result.swap( ts2 );

        }
Пример #18
0
void drawTimeDifference (TDirectory* directory, TH1* refHisto, const char* fname=0)
{
  TGraphErrors* graphX = (TGraphErrors*)directory->Get("x");
  if ( graphX==0 )  return;
  TH1I* hFirst = (TH1I*)directory->Get("firstTime");
  TH1I* hLast = (TH1I*)directory->Get("lastTime");
  if ( hFirst==0 || hLast==0 )  return;

  std::string fullName("cDeltaT");
  if ( fname )  fullName += fname;
  else  fullName += directory->GetName();
  TCanvas* c = new TCanvas(fullName.c_str(),fullName.c_str());
  TH1* h = refHisto->Clone("DeltaT");
  h->Reset();
  h->SetTitle("DeltaT");

  TGraph* graph = new TGraph();
  graph->SetName("gDeltaT");

  double xg,yg;
  for ( unsigned int i=1; i<=hFirst->GetNbinsX(); ++i ) {
    std::time_t t1 = hFirst->GetAt(i);
    std::time_t t2 = hLast->GetAt(i);
    TTimeStamp ts1(hFirst->GetAt(i));
    std::cout << "Fit started at " << ts1.AsString() << std::endl;
    graphX->GetPoint(i-1,xg,yg);
    graph->SetPoint(i-1,xg,difftime(t2,t1));
  }

  double xmin,xmax,ymin,ymax;
  graph->ComputeRange(xmin,ymin,xmax,ymax);
  h->SetMinimum(0.);
  h->SetMaximum((ymax+ymin)/2.+2.*(ymax-ymin)/2.);
  h->Draw();
  graph->SetMarkerStyle(20);
//   graph->SetMarkerColor(2);
//   graph->SetLineColor(2);
  graph->Draw("P");
}
int SourceClick(points places[20])
{
	
	
	
	while(true)
	{
		
		Text ts(200,400,"Please click on the source position (on the green nodes only.)");
		int pos = getClick();//position of the first click is recorded
		ts.hide();
		int X = pos/65536;
		int Y = pos%65536;int t=100;
		
		for(int i=0; i<20; i++)
		{
			if((X<=places[i].x+4&&X>=places[i].x-4)&&(Y<=places[i].y+4&&Y>=places[i].y-4))
			t =i;
			
		}
		if(t!=100)
		{
			
			return t;
			break;
		}
		else
		{
			Text ts1(200,400,"Invalid Position. Reloading... ");
			ts1.show();
			wait(2);
			ts1.hide();
		}
	}
	
	
	
}
Пример #20
0
void __android_log_btwrite_multiple__helper(int count) {
    log_time ts(CLOCK_MONOTONIC);

    struct logger_list *logger_list;
    ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
        LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, 0)));

    log_time ts1(CLOCK_MONOTONIC);

    pid_t pid = fork();

    if (pid == 0) {
        // child
        for (int i = count; i; --i) {
            ASSERT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)));
            usleep(100);
        }
        ASSERT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts1, sizeof(ts1)));
        usleep(1000000);

        _exit(0);
    }

    siginfo_t info{};
    ASSERT_EQ(0, TEMP_FAILURE_RETRY(waitid(P_PID, pid, &info, WEXITED)));

    int expected_count = (count < 2) ? count : 2;
    int expected_chatty_count = (count <= 2) ? 0 : 1;
    int expected_expire_count = (count < 2) ? 0 : (count - 2);

    count = 0;
    int second_count = 0;
    int chatty_count = 0;
    int expire_count = 0;

    for (;;) {
        log_msg log_msg;
        if (android_logger_list_read(logger_list, &log_msg) <= 0) break;

        if ((log_msg.entry.pid != pid) ||
            (log_msg.entry.len < (4 + 1 + 8)) ||
            (log_msg.id() != LOG_ID_EVENTS)) continue;

        char *eventData = log_msg.msg();
        if (!eventData) continue;

        uint32_t tag = get4LE(eventData);

        if ((eventData[4] == EVENT_TYPE_LONG) && (log_msg.entry.len == (4 + 1 + 8))) {
            if (tag != 0) continue;

            log_time tx(eventData + 4 + 1);
            if (ts == tx) {
                ++count;
            } else if (ts1 == tx) {
                ++second_count;
            }
        } else if (eventData[4] == EVENT_TYPE_STRING) {
            // chatty
            if (tag != 1004) continue;
            ++chatty_count;
            // int len = get4LE(eventData + 4 + 1);
            const char *cp = strstr(eventData + 4 + 1 + 4, " expire ");
            if (!cp) continue;
            unsigned val = 0;
            sscanf(cp, " expire %u lines", &val);
            expire_count += val;
        }
    }

    EXPECT_EQ(expected_count, count);
    EXPECT_EQ(1, second_count);
    EXPECT_EQ(expected_chatty_count, chatty_count);
    EXPECT_EQ(expected_expire_count, expire_count);

    android_logger_list_close(logger_list);
}
Пример #21
0
void CTimerDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);

  if(!pDX->m_bSaveAndValidate)
    {
    if (m_current_timer && m_current_timer->bIncluded)
      m_strIncluded = "(included)";
    else 
      m_strIncluded.Empty ();
    }

	//{{AFX_DATA_MAP(CTimerDlg)
	DDX_Control(pDX, IDC_SEND_TO, m_ctlSendTo);
	DDX_Control(pDX, IDC_SCRIPT_NAME, m_ctlProcedure);
	DDX_Control(pDX, IDC_TIMER_CONTENTS, m_ctlContents);
	DDX_Control(pDX, IDC_BUTTON_AT, m_ctlButtonAt);
	DDX_Check(pDX, IDC_ENABLED, m_bEnabled);
	DDX_Text(pDX, IDC_TIMER_LABEL, m_strLabel);
	DDX_Text(pDX, IDC_AT_HOUR, m_iAtHour);
	DDV_MinMaxInt(pDX, m_iAtHour, 0, 23);
	DDX_Text(pDX, IDC_AT_MINUTE, m_iAtMinute);
	DDV_MinMaxInt(pDX, m_iAtMinute, 0, 59);
	DDX_Text(pDX, IDC_INTERVAL_HOUR, m_iEveryHour);
	DDV_MinMaxInt(pDX, m_iEveryHour, 0, 23);
	DDX_Text(pDX, IDC_INTERVAL_MINUTE, m_iEveryMinute);
	DDV_MinMaxInt(pDX, m_iEveryMinute, 0, 59);
	DDX_Text(pDX, IDC_OFFSET_HOUR, m_iOffsetHour);
	DDV_MinMaxInt(pDX, m_iOffsetHour, 0, 23);
	DDX_Text(pDX, IDC_OFFSET_MINUTE, m_iOffsetMinute);
	DDV_MinMaxInt(pDX, m_iOffsetMinute, 0, 59);
	DDX_MinMaxString(pDX, IDC_TIMER_CONTENTS, m_strContents);
	DDV_MinMaxString(pDX, m_strContents, 0, 32000);
	DDX_Radio(pDX, IDC_BUTTON_EVERY, m_iType);
	DDX_Text(pDX, IDC_SCRIPT_NAME, m_strProcedure);
	DDX_Check(pDX, IDC_ONE_SHOT_TIMER, m_bOneShot);
	DDX_Check(pDX, IDC_TEMPORARY, m_bTemporary);
	DDX_Check(pDX, IDC_ACTIVE_WHEN_CLOSED, m_bActiveWhenClosed);
	DDX_Text(pDX, IDC_GROUP, m_strGroup);
	DDX_CBIndex(pDX, IDC_SEND_TO, m_iSendTo);
	DDX_Text(pDX, IDC_VARIABLE, m_strVariable);
	DDX_Text(pDX, IDC_INCLUDED, m_strIncluded);
	DDX_Check(pDX, IDC_OMIT_FROM_OUTPUT, m_bOmitFromOutput);
	DDX_Check(pDX, IDC_OMIT_FROM_LOG, m_bOmitFromLog);
	DDX_Text(pDX, IDC_AT_SECOND, m_fAtSecond);
	DDV_MinMaxDouble(pDX, m_fAtSecond, 0., 59.99999);
	DDX_Text(pDX, IDC_INTERVAL_SECOND, m_fEverySecond);
	DDV_MinMaxDouble(pDX, m_fEverySecond, 0., 59.99999);
	DDX_Text(pDX, IDC_OFFSET_SECOND, m_fOffsetSecond);
	DDV_MinMaxDouble(pDX, m_fOffsetSecond, 0., 59.99999);
	//}}AFX_DATA_MAP

  if(pDX->m_bSaveAndValidate)
    {

    
    m_strLabel.TrimLeft ();
    m_strLabel.TrimRight ();

    m_strProcedure.TrimLeft ();
    m_strProcedure.TrimRight ();

    m_strGroup.TrimLeft ();
    m_strGroup.TrimRight ();

    if (m_iType == CTimer::eInterval)
      {
      CmcDateTimeSpan ts1 (0, m_iEveryHour, m_iEveryMinute, m_fEverySecond);
      CmcDateTimeSpan ts2 (0, m_iOffsetHour, m_iOffsetMinute, m_fOffsetSecond);

      if (ts1 <= CmcDateTimeSpan (0, 0, 0, 0))
          {
          ::TMessageBox("The timer interval must be greater than zero.");
          DDX_Text(pDX, IDC_INTERVAL_HOUR, m_iEveryHour);
          pDX->Fail();
          }     // end of interval <= 0

      if(ts2 >= ts1)
          {
          ::TMessageBox("The timer offset must be less than the timer period.");
          DDX_Text(pDX, IDC_OFFSET_HOUR, m_iOffsetHour);
          pDX->Fail();
          }     // end of offset >= period
        }   // end of doing a periodical timer


    CString strTimerName;
    CTimer * timer_item;
    POSITION pos;

    for (pos = m_pTimerMap->GetStartPosition (); pos; )
      {
      m_pTimerMap->GetNextAssoc (pos, strTimerName, timer_item);

// don't compare against itself

      if (timer_item == m_current_timer)
        continue;

// now check the label for duplicates

      if (!m_strLabel.IsEmpty ())    // we can have duplicate blank names
        if (m_strLabel.CompareNoCase (timer_item->strLabel) == 0)
          {
          CString strMsg;
          strMsg = TFormat ("The timer label \"%s\" is already in the list of timers.",
                          (LPCTSTR) m_strLabel);
          ::UMessageBox(strMsg);
          DDX_Text(pDX, IDC_TIMER_LABEL, m_strLabel);
          pDX->Fail();
          }

      }   // end of checking each Timer

    if (!m_strLabel.IsEmpty ())    // we can have blank labels
      {

// check label is valid

      if (CheckLabel (m_strLabel))
        {
        ::TMessageBox ("The label must start with a letter and consist of letters"
                        ", numbers or the underscore character.");
        DDX_Text(pDX, IDC_TIMER_LABEL, m_strLabel);
        pDX->Fail();
        }

      }   // end of having non-blank label


    if (m_strVariable.IsEmpty ())    // we can have blank variables
      {
      if (m_iSendTo == eSendToVariable)
        {
        ::TMessageBox("When sending to a variable you must specify a variable name. ",
                        MB_ICONSTOP);
        DDX_Text(pDX, IDC_VARIABLE, m_strVariable);
        pDX->Fail();
        }
      }
    else
      {

// check variable name is valid

      if (CheckLabel (m_strVariable))
        {
        ::TMessageBox("The variable name must start with a letter and consist of letters"
                        ", numbers or the underscore character.");
        DDX_Text(pDX, IDC_VARIABLE, m_strVariable);
        pDX->Fail();
        }

      }   // end of having non-blank variable


    // check for speed walking OK, unless they are substituting

    if (m_iSendTo == eSendToSpeedwalk)
      {

      CString strResult = m_pDoc->DoEvaluateSpeedwalk (m_strContents);

      if (!strResult.IsEmpty ())
        {
        if (strResult [0] == '*')    // error in speedwalk string?
          {
          ::UMessageBox (strResult.Mid (1));  // already translated, I think
          DDX_Text(pDX, IDC_TIMER_CONTENTS, m_strContents);
          pDX->Fail();
          }   // end of error message
        } // end of non-empty speedwalk          
      }   // end of speed walking wanted

    if(m_strContents.IsEmpty () && m_strProcedure.IsEmpty ())
        {
        ::TMessageBox("The timer contents cannot be blank unless you specify a script subroutine.");
        DDX_Text(pDX, IDC_TIMER_CONTENTS, m_strContents);
        pDX->Fail();
        }     // end of contents being blank


    if (!m_strProcedure.IsEmpty ())    // blank procedure is OK
      {

// check procedure is valid

      if (CheckLabel (m_strProcedure, true))
        {
        ::TMessageBox("The script subroutine name must start with a letter and consist of letters"
                        ", numbers or the underscore character.");
        DDX_Text(pDX, IDC_SCRIPT_NAME, m_strProcedure);
        pDX->Fail();
        }

      }   // end of having non-blank procedure

    }   // end of saving and validating

}
    // Utility to test the replace method. 
    void utlTestReplace(bool replaceAllofTarget)
    {
        struct TestReplaceSelectedDataStructure
        {
            const char* testDescription ; 
            const char* input ; 
            int startPosition ; 
            int replaceLength ; 
            int inputLength ; 
            int charactersToCopy ; 
            const char* expectedForCopyAll ;
            const char* expectedForCopyLimited ; 
        }; 
    
        const char* prefix = "test replace(start, end, char*, len), where char* = " ;
        const char* suffix1 ;
        const char* suffix2 ;
        if (replaceAllofTarget)
        {
            suffix1 = "size = len(targetString) :- verify if replaced" ;
            suffix2 = "size = len(targetString) :- verify return value";
        }
        else
        {
            suffix1 = "size < len(targetString) -2 :- verify if replaced" ;
            suffix2 = "size < len(targetString) -2 :- verify return value";
        }
        string Message ; 

        const char* baseString = "string rep" ;
        TestReplaceSelectedDataStructure testData[] = { \
               { "an empty string. start = 0; last = 0 ", \
                     "", 0, 10, 0, 0, "", "" }, \
               { "a regular string. start > 0; last < len(baseString) ", \
                     "Test Str", 2, 4, 8, 4, "stTest Str rep", "stTest rep" }, \
               { "a alpha-num string. start > 0; last < len(baseString) ", \
                     "Te12 $tr", 2, 4, 8, 4, "stTe12 $tr rep", "stTe12 rep" }, \
               { "a regular string. start > 0; last = total no. of remaining characters", \
                     "Test Str", 2, 8, 8, 4, "stTest Str", "stTest" }, \
               { "a alpha-num string. start > 0 ; last > len(baseString) ", \
                     "Te12 $tr", 2, 11, 8, 4, "stTe12 $tr", "stTe12" } \
         } ;

        const int testCount = sizeof(testData)/sizeof(testData[0]) ;
        
        // Using all the data that was created above, run the actual tests. 
        for(int i = 0 ; i < testCount ; i++)
        {
            UtlString ts1(baseString) ;
            UtlString ts2;
            const char* expected ;
            if (replaceAllofTarget)
            {
                ts2 = ts1.replace(testData[i].startPosition, testData[i].replaceLength, \
                                     testData[i].input, testData[i].inputLength) ;
                expected = testData[i].expectedForCopyAll ;
            }
            else
            {
                ts2 = ts1.replace(testData[i].startPosition, testData[i].replaceLength, \
                                     testData[i].input, testData[i].charactersToCopy) ;
                expected = testData[i].expectedForCopyLimited ;
            }
            
            // Verify if the selected text was replaced. 
            TestUtilities::createMessage(3, &Message, prefix, testData[i].testDescription, \
                                        suffix1) ; 
            CPPUNIT_ASSERT_EQUAL_MESSAGE(Message.data(), string(expected), string(ts1.data())) ;
 
            // Verify return value
            TestUtilities::createMessage(3, &Message, prefix, testData[i].testDescription, \
                                        suffix2) ; 
            CPPUNIT_ASSERT_EQUAL_MESSAGE(Message.data(), string(expected), string(ts2.data())) ;
        }
   } //utlTestReplace