4 * PWLib application source file for pwtest
6 * Main program entry point.
8 * Copyright 98 Equivalence
11 * Revision 1.40 2003/12/14 10:00:04 rjongbloed
12 * Updated to new API due to plug-ins
14 * Revision 1.39 2002/12/10 04:47:18 robertj
15 * Added support in PTime for ISO 8601 format.
17 * Revision 1.38 2002/12/04 00:19:04 robertj
18 * Removed get document that just returns a content length as the chunked
19 * transfer encoding makes this very dangerous.
21 * Revision 1.37 2002/12/02 00:16:13 robertj
22 * Additional URL testing
24 * Revision 1.36 2002/11/19 10:37:32 robertj
25 * Added functions to set anf get "file:" URL. as PFilePath and do the right
26 * things with platform dependent directory components.
28 * Revision 1.35 2002/05/21 04:23:40 robertj
29 * Fixed problem with ASN encoding/decoding unsconstrained negative numbers,
31 * Revision 1.34 2002/03/18 05:03:03 robertj
32 * Fixed display of URL test so does not treat & as special in dialog.
34 * Revision 1.33 2001/12/06 04:06:03 robertj
35 * Removed "Win32 SSL xxx" build configurations in favour of system
36 * environment variables to select optional libraries.
38 * Revision 1.32 2001/11/08 00:31:27 robertj
39 * Reinstated URL test code and added "parameter" string dictionary display.
41 * Revision 1.31 2001/09/28 10:05:57 robertj
42 * Added check for "scientific" mode in PTimeInterval so does not print
43 * out hours and minutes, but just rounded seconds.
45 * Revision 1.30 2001/05/10 02:43:23 robertj
46 * Added SSL test code.
48 * Revision 1.29 2001/03/20 06:56:07 robertj
49 * Removed hard coded personal e-mail addreses from test.
51 * Revision 1.28 2001/03/05 04:18:27 robertj
52 * Added net mask to interface info returned by GetInterfaceTable()
54 * Revision 1.27 2001/03/03 05:06:31 robertj
55 * Major upgrade of video conversion and grabbing classes.
57 * Revision 1.26 2001/01/04 03:39:14 craigs
58 * Removed IP addresses that cause DNS reverse lookup hassles
60 * Revision 1.25 2000/11/12 23:32:21 craigs
61 * Added conditionals for functions not implemented in Motif/Qt libraries
63 * Revision 1.24 2000/11/10 01:08:11 robertj
64 * Added content transfer encoding and automatic base64 translation.
66 * Revision 1.23 2000/11/09 05:50:23 robertj
67 * Added RFC822 aware channel class for doing internet mail.
69 * Revision 1.22 2000/11/09 00:23:05 robertj
70 * Additional video testing.
72 * Revision 1.21 2000/08/30 03:17:00 robertj
73 * Improved multithreaded reliability of the timers under stress.
75 * Revision 1.20 2000/07/25 13:14:07 robertj
76 * Got the video capture stuff going!
78 * Revision 1.19 2000/07/15 09:47:35 robertj
79 * Added video I/O device classes.
81 * Revision 1.18 2000/04/29 08:11:06 robertj
82 * Fixed problem with stream output width in PTimeInterval
84 * Revision 1.17 2000/04/29 04:51:07 robertj
85 * Added microseconds to string output.
86 * Fixed uninitialised microseconds on some constructors.
88 * Revision 1.16 1999/09/10 04:35:43 robertj
89 * Added Windows version of PIPSocket::GetInterfaceTable() function.
91 * Revision 1.15 1999/08/07 07:11:14 robertj
92 * Added test for menu text change
94 * Revision 1.14 1999/08/07 01:47:18 robertj
95 * Fixed some trivial errors.
97 * Revision 1.13 1999/07/06 04:46:01 robertj
98 * Fixed being able to case an unsigned to a PTimeInterval.
99 * Improved resolution of PTimer::Tick() to be millisecond accurate.
101 * Revision 1.12 1999/07/03 03:12:59 robertj
102 * #ifdef'ed test code for stuff not in general distrubution.
104 * Revision 1.11 1999/06/30 08:57:20 robertj
105 * Fixed bug in encodeing sequence of constrained primitive type. Constraint not set.
106 * Fixed bug in not emitting namespace use clause.
107 * Added "normalisation" of separate sequence of <base type> to be single class.
109 * Revision 1.10 1999/06/24 14:00:09 robertj
110 * Added URL parse test
112 * Revision 1.9 1999/06/14 07:59:39 robertj
113 * Enhanced tracing again to add options to trace output (timestamps etc).
115 * Revision 1.8 1999/06/07 01:55:04 robertj
116 * Added test for default driver function in sound classes.
118 * Revision 1.7 1999/05/28 14:07:18 robertj
119 * Added function to get default audio device.
121 * Revision 1.6 1999/03/29 03:39:56 robertj
122 * Changed semantics of PTitledWindow::OnClose() function.
124 * Revision 1.5 1999/02/23 07:11:29 robertj
125 * Improved trace facility adding trace levels and #define to remove all trace code.
127 * Revision 1.4 1999/02/22 10:15:16 robertj
128 * Sound driver interface implementation to Linux OSS specification.
130 * Revision 1.3 1999/01/31 00:59:27 robertj
131 * Added IP Access Control List class to PTLib Components
133 * Revision 1.2 1998/12/23 01:17:29 robertj
139 #include <ptlib/videoio.h>
140 #include <ptclib/ipacl.h>
141 #include <ptclib/url.h>
142 #include <ptclib/asner.h>
143 #include <ptclib/random.h>
144 #include <ptclib/inetmail.h>
146 #include <ptclib/pssl.h>
147 #include <ptclib/http.h>
150 #include "resources.h"
153 class OpenSoundFileDialog
: public POpenFileDialog
155 PCLASSINFO(OpenSoundFileDialog
, POpenFileDialog
)
157 OpenSoundFileDialog(MainWindow
* parent
);
159 virtual void OnInit();
161 const PString
& GetDriver() const { return driver
; }
162 BOOL
GetWait() const { return waitFlag
; }
170 class SaveSoundFileDialog
: public PSaveFileDialog
172 PCLASSINFO(SaveSoundFileDialog
, PSaveFileDialog
)
174 SaveSoundFileDialog(MainWindow
* parent
);
176 virtual void OnInit();
178 const PString
& GetDriver() const { return driver
; }
185 PCREATE_PROCESS(Pwtest
);
191 : PApplication("Equivalence", "pwtest", 1, 0, AlphaCode
, 1)
194 PTrace::SetOptions(PTrace::Blocks
);
198 #define TEST_TIME(t) PTRACE(1, t << " => " << PTime(t))
202 PTRACE_BLOCK("Pwtest::Pwtest()");
203 PTRACE(2, GetName() << " v" << GetVersion(TRUE
));
206 PTRACE(1, "Time is now " << now
.AsString("h:m:s.u d/M/y"));
207 PTRACE(1, "Time is now " << now
.AsString("yyyy/MM/dd h:m:s.uuuu"));
208 PTRACE(1, "Time is now " << now
.AsString("MMM/d/yyyyy w h:m:sa"));
209 PTRACE(1, "Time is now " << now
.AsString("wwww d/M/yyy h:m:s.uu"));
210 PTRACE(1, "Time is now " << now
.AsString("www d/MMMM/yy h:m:s.uuu"));
212 TEST_TIME("20010203T1234Z");
213 TEST_TIME("20010203T1234");
214 TEST_TIME("20010203T0034");
215 TEST_TIME("20010203T10034");
216 TEST_TIME("20010203T123456+1100");
217 TEST_TIME("20010203T000056");
218 TEST_TIME("20010203T123456");
219 TEST_TIME("2001-02-03 T 12:34:56");
220 TEST_TIME("5/03/1999 12:34:56");
221 TEST_TIME("15/06/1999 12:34:56");
222 TEST_TIME("15/06/01 12:34:56 PST");
223 TEST_TIME("5/06/02 12:34:56");
224 TEST_TIME("5/23/1999 12:34am");
225 TEST_TIME("5/23/00 12:34am");
226 TEST_TIME("1999/23/04 12:34:56");
227 TEST_TIME("Mar 3, 1999 12:34pm");
228 TEST_TIME("3 Jul 2004 12:34pm");
229 TEST_TIME("12:34:56 5 December 1999");
230 TEST_TIME("10 minutes ago");
231 TEST_TIME("2 weeks");
233 PTRACE(1, "Testing timer resolution, reported as " << PTimer::Resolution() << "ms");
234 time_t oldSec
= time(NULL
); // Wait for second boundary
235 while (oldSec
== time(NULL
))
239 PTimeInterval newTick
= PTimer::Tick();
240 PTimeInterval oldTick
= newTick
;
243 while (oldSec
== time(NULL
)) { // For one full second
244 while (newTick
== oldTick
)
245 newTick
= PTimer::Tick();
247 count
++; // Count the changes in tick
250 PTRACE(1, "Actual resolution is " << 1000000/count
<< "us");
253 PTRACE(1, "TimeInterval output: \"" << setw(15) << newTick
<< '"');
254 PTRACE(1, "TimeInterval output: \"" << setw(15) << oldTick
<< '"');
256 for (p
= 3; p
< 10; p
++)
257 PTRACE(1, "TimeInterval output: " << p
<< " \""
258 << setiosflags(ios::scientific
)
259 << setw(p
) << setprecision(2) << oldTick
260 << resetiosflags(ios::scientific
) << '"');
261 for (p
= 3; p
< 20; p
++)
262 PTRACE(1, "TimeInterval output: " << p
<< " \""
263 << setw(p
) << setprecision(2) << oldTick
<< '"');
267 id
= "0.0.8.2250.0.2";
269 strm
.CompleteEncoding();
270 PTRACE(1, "OID " << id
<< " -> " << strm
);
272 PASN_Integer asn_int1
, asn_int2
;
273 asn_int1
= 123456789;
274 strm
.BeginEncoding();
275 asn_int1
.Encode(strm
);
276 strm
.CompleteEncoding();
278 asn_int2
.Decode(strm
);
279 PTRACE(1, "ASN +ve Integer " << asn_int1
<< " -> " << strm
<< " -> " << asn_int2
);
281 asn_int1
= (unsigned)-12345;
282 strm
.BeginEncoding();
283 asn_int1
.Encode(strm
);
284 strm
.CompleteEncoding();
286 asn_int2
.Decode(strm
);
287 PTRACE(1, "ASN -ve Integer " << asn_int1
<< " -> " << strm
<< " -> " << asn_int2
);
289 SetAboutDialogID(IDD_ABOUT
);
291 new MainWindow(GetArguments());
293 PApplication::Main();
297 MainWindow::MainWindow(PArgList
&)
299 PTRACE_BLOCK("Pwtest::Pwtest()");
301 SetTitle(PResourceString(IDS_TITLE
));
302 SetIcon(PIcon(IDI_MAIN_WINDOW
));
303 myMenu
= new MainMenu(this);
306 #if ! defined(P_MOTIF) && ! defined(P_LESSTIF) && ! defined(P_QT)
307 static const PButtonBar::ButtonID cmds
[] = {
308 { 1, "IP_ACL", IDM_TEST_ENABLED
, IDM_TEST_DISABLED
, IDS_TEST_BUTTON
}
310 buttonBar
= new PButtonBar(this, cmds
, PARRAYSIZE(cmds
));
313 statusBar
= new PStatusBar(this, 2);
314 statusBar
->SetSectionWidth(1, 20);
316 #if ! defined(P_MOTIF) && ! defined(P_LESSTIF) && ! defined(P_QT)
317 new PMDIDocWindow(this, "Test");
320 UpdateCommandSources();
325 void MainWindow::NewCmd(PMenuItem
&, INT
)
327 #if ! defined(P_MOTIF) && ! defined(P_LESSTIF) && ! defined(P_QT)
328 PMDIDocWindow
* child
= new PMDIDocWindow(this, "fred");
334 void MainWindow::OpenCmd(PMenuItem
&, INT
)
336 POpenFileDialog
dlg(this);
337 if (dlg
.RunModal()) {
339 if (file
.Open(dlg
.GetFile())) {
340 PString str
= file
.ReadString(file
.GetLength());
346 void MainWindow::CloseCmd(PMenuItem
&, INT
)
352 void MainWindow::SaveCmd(PMenuItem
& item
, INT
)
354 // Save current document
356 pos
= item
.GetPosition();
357 pos
= item
.GetMenu()->GetPosition();
361 void MainWindow::SaveAsCmd(PMenuItem
&, INT
)
363 PSaveFileDialog
dlg(this);
364 if (dlg
.RunModal()) {
365 // Save document to new name
370 void MainWindow::PrintCmd(PMenuItem
&, INT
)
372 PPrintJobDialog
dlg(this, printInfo
);
373 if (dlg
.RunModal()) {
374 printInfo
= dlg
.GetPrintInfo();
375 PPrintCanvas
canvas("pwtest", printInfo
);
377 // Add printing code here
382 void MainWindow::PrinterSetupCmd(PMenuItem
&, INT
)
384 PPrinterSetupDialog
dlg(this, printInfo
);
386 printInfo
= dlg
.GetPrintInfo();
390 void MainWindow::ExitCmd(PMenuItem
&, INT
)
391 // The Exit menu ... well ... exits.
397 void MainWindow::CopyCmd()
399 PClipboard
clip(this);
400 // Do something with the clipboard
404 BOOL
MainWindow::CanCopy()
406 // If want copy menu enabled
411 void MainWindow::PasteCmd()
413 PClipboard
clip(this);
414 // Do something with the clipboard
418 BOOL
MainWindow::CanPaste()
420 // If want paste menu enabled, ie clipboard has right format
425 void MainWindow::OnRedraw(PCanvas
& canvas
)
427 PPattern::Bits pat
= { 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 };
428 canvas
.SetFillPattern(PPattern(pat
));
429 canvas
.FillRect(100, 100, 100, 100);
430 canvas
.FillRect(150, 150, 100, 100);
434 void MainWindow::OnResize(const PDim
& newSize
, ResizeType type
)
436 if (type
!= Iconic
) {
437 PRect
bounds(newSize
);
438 #if ! defined(P_MOTIF) && ! defined(P_LESSTIF) && ! defined(P_QT)
439 buttonBar
->AutoAdjustBounds(bounds
, AdjustTop
);
441 statusBar
->AutoAdjustBounds(bounds
, AdjustBottom
);
442 #if ! defined(P_MOTIF) && ! defined(P_LESSTIF) && ! defined(P_QT)
443 SetDocumentArea(bounds
, PixelCoords
);
449 void MainWindow::OnClose()
451 PTopLevelWindow::OnClose();
456 void MainWindow::TestCmd()
458 myMenu
->menuTestItem
->SetString("Test Menu");
462 void MainWindow::IP_ACL_Cmd()
464 PIpAccessControlList list
;
466 list
.LoadHostsAccess("ipop3d");
467 list
.Add("10.0.2.0/24");
468 list
.Add("192.168.");
469 list
.Add(".nr.equival.net");
470 list
.Add("-hadron.nr.equival.net");
471 list
.Add("-10.0.2.1");
472 list
.Add("203.41.8.86/255.255.255.248");
477 for (i
= 0; i
< list
.GetSize(); i
++)
478 str
<< list
[i
] << '\n';
480 static const char * const addresses
[] = {
481 "10.0.1.1", "10.0.1.4", "10.0.2.4", "10.0.2.1",
482 //"129.168.1.1", "192.168.1.1",
483 //"203.41.8.86", "203.41.8.80", "203.41.8.88"
485 for (i
= 0; i
< PARRAYSIZE(addresses
); i
++) {
486 PIPSocket::Address
addr(addresses
[i
]);
487 str
<< '\n' << addr
<< ' ' << (list
.IsAllowed(addr
) ? "Allowed" : "Disallowed");
490 PSimpleDialog::Info(this, str
);
494 void MainWindow::ListInterfacesCmd(PMenuItem
&, INT
)
498 PIPSocket::InterfaceTable interfaces
;
499 if (PIPSocket::GetInterfaceTable(interfaces
)) {
500 str
<< "Interfaces:\n";
501 for (PINDEX i
= 0; i
< interfaces
.GetSize(); i
++)
503 << interfaces
[i
].GetName() << ' '
504 << interfaces
[i
].GetAddress() << ' '
505 << interfaces
[i
].GetNetMask() << ' '
506 << interfaces
[i
].GetMACAddress() << '\n';
509 str
<< "Error getting interfaces.";
511 PSimpleDialog::Info(this, str
);
515 void MainWindow::ParseURLCmd()
517 ParseURLDialog
dlg(this);
519 dlg
.filePath
= FALSE
;
527 PFilePath path
= dlg
.url
;
535 str
<< "URL: " << url
<< "\n"
536 "Scheme: " << url
.GetScheme() << "\n"
537 "Host: " << url
.GetHostName() << "\n"
538 "Port: " << url
.GetPort() << "\n"
539 "Username: " << url
.GetUserName() << "\n"
540 "Password: " << url
.GetPassword() << "\n"
541 "Fragment: " << url
.GetFragment() << "\n";
544 if (url
.GetPath().IsEmpty())
545 str
<< "Path: " << url
.GetPathStr() << '\n';
547 str
<< (url
.GetRelativePath() ? "Relative" : "Absolute") << '\n';
548 for (i
= 0; i
< url
.GetPath().GetSize(); i
++)
549 str
<< "Path[" << i
<< "]: " << url
.GetPath()[i
] << '\n';
552 for (i
= 0; i
< url
.GetParamVars().GetSize(); i
++)
553 str
<< "Param[" << i
<< "]: "
554 << url
.GetParamVars().GetKeyAt(i
) << " = "
555 << url
.GetParamVars().GetDataAt(i
) << '\n';
557 for (i
= 0; i
< url
.GetQueryVars().GetSize(); i
++)
558 str
<< "Query[" << i
<< "]: "
559 << url
.GetQueryVars().GetKeyAt(i
) << " = "
560 << url
.GetQueryVars().GetDataAt(i
) << '\n';
562 str
<< "FilePath: " << url
.AsFilePath() << '\n';
564 str
.Replace("&", "&&", TRUE
);
566 PSimpleDialog::Info(this, str
);
570 void MainWindow::PlaySoundCmd()
572 OpenSoundFileDialog
dlg(this);
576 PSoundChannel player
;
577 if (!player
.Open(dlg
.GetDriver(), PSoundChannel::Player
)) {
578 PSimpleDialog::Error(this, "Could not open driver: "+dlg
.GetDriver());
582 player
.SetBuffers(65536, 8);
584 if (!player
.PlayFile(dlg
.GetFile(), dlg
.GetWait()))
585 PSimpleDialog::Error(this, "Could not play file: "+dlg
.GetFile());
589 OpenSoundFileDialog::OpenSoundFileDialog(MainWindow
* parent
)
590 : POpenFileDialog(parent
)
597 void OpenSoundFileDialog::OnInit()
599 POpenFileDialog::OnInit();
601 PDim dim
= GetDimensions(LocalCoords
);
603 driver
= PSoundChannel::GetDefaultDevice(PSoundChannel::Player
);
604 PStringArray driverNames
= PSoundChannel::GetDeviceNames(PSoundChannel::Player
);
606 PComboBox
* drivers
= new PComboBox(this);
607 drivers
->SetValuePointer(&driver
);
608 for (PINDEX i
= 0; i
< driverNames
.GetSize(); i
++) {
609 drivers
->AddString(driverNames
[i
]);
610 if (driverNames
[i
] == driver
)
611 drivers
->SetCurrent(i
);
613 drivers
->SetPosition(20, dim
.Height());
614 drivers
->SetDimensions(120, 60, LocalCoords
);
618 if (dim
.Width() <= 160)
621 PCheckBox
* wait
= new PCheckBox(this, "Wait", waitFlag
);
622 wait
->SetValuePointer(&waitFlag
);
623 wait
->SetPosition(20, dim
.Height());
626 PDim ctlDim
= wait
->GetDimensions(LocalCoords
);
627 dim
.AddHeight(ctlDim
.Height() + 10);
628 if (dim
.Width() <= ctlDim
.Width()+40)
629 dim
.SetWidth(ctlDim
.Width()+41);
631 SetDimensions(dim
, LocalCoords
);
635 void MainWindow::RecordSoundCmd()
637 SaveSoundFileDialog
dlg(this);
641 PSoundChannel recorder
;
642 if (!recorder
.Open(dlg
.GetDriver(), PSoundChannel::Recorder
)) {
643 PSimpleDialog::Error(this, "Could not open driver: "+dlg
.GetDriver());
647 recorder
.SetBuffers(8*8000, 2); // 8 x 8 second buffers
649 if (!recorder
.RecordFile(dlg
.GetFile()))
650 PSimpleDialog::Error(this, "Could not record file: "+dlg
.GetFile());
654 SaveSoundFileDialog::SaveSoundFileDialog(MainWindow
* parent
)
655 : PSaveFileDialog(parent
)
657 SetDefaultFileType(".wav");
661 void SaveSoundFileDialog::OnInit()
663 PSaveFileDialog::OnInit();
665 PDim dim
= GetDimensions(LocalCoords
);
667 driver
= PSoundChannel::GetDefaultDevice(PSoundChannel::Recorder
);
668 PStringArray driverNames
= PSoundChannel::GetDeviceNames(PSoundChannel::Recorder
);
670 PComboBox
* drivers
= new PComboBox(this);
671 drivers
->SetValuePointer(&driver
);
672 for (PINDEX i
= 0; i
< driverNames
.GetSize(); i
++) {
673 drivers
->AddString(driverNames
[i
]);
674 if (driverNames
[i
] == driver
)
675 drivers
->SetCurrent(i
);
677 drivers
->SetPosition(20, dim
.Height());
678 drivers
->SetDimensions(120, 60, LocalCoords
);
682 if (dim
.Width() <= 160)
685 SetDimensions(dim
, LocalCoords
);
689 void MainWindow::VideoCaptureCmd()
691 PStringList drivers
= PVideoInputDevice::GetDriverNames();
692 if (drivers
.IsEmpty()) {
693 PSimpleDialog::Error(this, "No video grabber drivers.");
697 PVideoInputDevice
* grabber
= PVideoInputDevice::CreateDevice(drivers
[0]);
698 if (grabber
== NULL()) {
699 PSimpleDialog::Error(this, "Cannot create video input device for driver " + drivers
[0]);
703 PStringList devices
= grabber
->GetDeviceNames();
704 if (devices
.IsEmpty()) {
705 PSimpleDialog::Error(this, "No video grabber devices.");
709 if (!grabber
->Open(devices
[0], FALSE
)) {
710 PSimpleDialog::Error(this, "Could not open device " + devices
[0]);
714 grabber
->SetFrameRate(25);
715 grabber
->SetColourFormatConverter("RGB32");
719 PTimeInterval startTime
= PTimer::Tick();
720 PBYTEArray
buffer(grabber
->GetMaxFrameBytes());
722 for (i
= 0; i
< 100; i
++) {
723 if (!grabber
->GetFrameData(buffer
.GetPointer()))
730 PSimpleDialog::Error(this, "Error in grab.");
732 long time
= (long)(PTimer::Tick() - startTime
).GetMilliSeconds();
733 PSimpleDialog::Info(this, "Grabbed 100 frames in %lu ms (%u f/s).", time
, 100000/time
);
735 unsigned width
, height
;
736 grabber
->GetFrameSize(width
, height
);
737 PPixelImage
image(width
, height
, 32);
738 memcpy(image
->GetPixelDataPtr(), buffer
, buffer
.GetSize());
739 PFile
file("c:\\capture.bmp", PFile::WriteOnly
);
747 void MainWindow::StressTimeout(PTimer
& timer
, INT
)
749 TimerStressReport
<< PTimer::Tick().GetMilliSeconds() << "\tTimeout\t" << (void *)&timer
<< endl
;
750 timer
= PRandom::Number()%10000;
754 void MainWindow::TimerStressCmd()
756 if (!TimerStressReport
.Open("TimerStress.txt", PFile::WriteOnly
)) {
757 PSimpleDialog::Error(this, "Could not open \"TimerStress.txt\"!");
762 PTimer
* timers
[1000];
764 for (i
= 0; i
< PARRAYSIZE(timers
); i
++)
767 static const PINDEX numTests
= 100000;
768 PINDEX activeTimers
= 0;
769 PINDEX highWatermark
= 0;
771 for (i
= 0; i
< numTests
; i
++) {
772 PINDEX t
= PRandom::Number()%PARRAYSIZE(timers
);
773 if (timers
[t
] != NULL
) {
774 TimerStressReport
<< PTimer::Tick().GetMilliSeconds() << "\tDestroy\t" << (void *)timers
[t
] << endl
;
780 timers
[t
] = new PTimer(PRandom::Number()%10000);
781 timers
[t
]->SetNotifier(PCREATE_NOTIFIER(StressTimeout
));
782 TimerStressReport
<< PTimer::Tick().GetMilliSeconds() << "\tCreate\t" << (void *)timers
[t
] << endl
;
784 if (activeTimers
> highWatermark
)
785 highWatermark
= activeTimers
;
787 PThread::Current()->Sleep(PRandom::Number()%100);
789 if ((i
%(numTests
/100)) == 0) {
790 PTRACE(1, "Timer stress tested " << (i
*100/numTests
) << '%');
794 PTRACE(1, "Timer stress tested 100% (" << numTests
795 << " iterations), max simultaneous timers: " << highWatermark
);
797 for (i
= 0; i
< PARRAYSIZE(timers
); i
++)
800 TimerStressReport
.Close();
804 void MainWindow::MailTestCmd()
807 PRFC822Channel
simple(PRFC822Channel::Sending
);
808 simple
.SetFromAddress("postmaster");
809 simple
.SetToAddress(PProcess::Current().GetUserName());
810 simple
.SetSubject("Test of RFC822 class.");
812 if (!simple
.SendWithSMTP("mail"))
813 PSimpleDialog::Error(this, "Error in sending message.");
815 simple
<< "This is a simple test.\n\n";
816 for (PINDEX i
= 1; i
< 10; i
++)
817 simple
<< " Line number " << i
<< "\n";
818 simple
<< "\nEnd of test.\n";
821 PRFC822Channel
complex(PRFC822Channel::Sending
);
822 complex.SetFromAddress("postmaster");
823 complex.SetToAddress(PProcess::Current().GetUserName());
824 complex.SetSubject("Test of RFC822 class.");
826 if (!complex.SendWithSMTP("mail"))
827 PSimpleDialog::Error(this, "Error in sending message.");
829 PString boundary
= complex.MultipartMessage();
831 complex << "\nThis is the first part of a multipart message.\n";
832 complex.NextPart(boundary
);
834 complex << "\n\nThis is the second part of a multipart message.\n";
835 complex.NextPart(boundary
);
837 complex.SetContentType("text/html");
838 complex << "<HTML><BODY>\n"
839 "<H1>Third Page</H1>\n"
840 "This is the third part of a multipart message.\n"
843 complex.NextPart(boundary
);
844 complex.SetContentAttachment("plushot.gif");
845 complex.SetTransferEncoding("base64");
846 static BYTE binaryStuff
[] = {
847 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x09, 0x00,
848 0x09, 0x00, 0xA2, 0x00, 0x00, 0x00, 0x00, 0xFF,
849 0x5F, 0x8A, 0xC5, 0xFF, 0xFF, 0xFF, 0xCC, 0xCC,
850 0xCC, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
851 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00,
852 0x00, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00, 0x03,
853 0x1D, 0x4A, 0xBA, 0x5A, 0x24, 0x30, 0x0A, 0x27,
854 0xC6, 0x00, 0x76, 0xD0, 0x11, 0x40, 0xB0, 0x14,
855 0x20, 0x8A, 0xDA, 0xC3, 0x79, 0xA0, 0x79, 0x65,
856 0x5B, 0x06, 0x16, 0x70, 0x1C, 0x27, 0x00, 0x3B
858 complex.Write(binaryStuff
, sizeof(binaryStuff
));
860 complex.NextPart(boundary
);
861 complex.SetTransferEncoding("8bit");
862 complex.SetContentType("text/plain");
863 complex << "This is the last part of a multipart message.\n";
868 void MainWindow::TestSSLCmd()
871 if (tcp
.Connect("www.microtelco.com")) {
873 if (ssl
.Connect(tcp
)) {
875 if (http
.Open(ssl
)) {
877 if (http
.GetTextDocument("/", content
))
878 PSimpleDialog::Info(this, "Success!\n" + content
.Left(200));
880 PSimpleDialog::Error(this, "HTTP GET from server failed: " + http
.GetErrorText());
883 PSimpleDialog::Error(this, "HTTP connect to server failed: " + http
.GetErrorText());
886 PSimpleDialog::Error(this, "SSL connect to server failed: " + ssl
.GetErrorText());
889 PSimpleDialog::Error(this, "TCP connect to server failed: " + tcp
.GetErrorText());
893 // End of File ///////////////////////////////////////////////////////////////