Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members | Related Pages

unittest.d

Go to the documentation of this file.
00001 /******************************************************************************
00002 
00003         @mainpage The Mango Tree
00004 
00005         Mango is a collection of D packages with an orientation toward
00006         server-side programming. These packages may be used together
00007         or in isolation and, in many cases, can be just as applicable
00008         to client-side development. Mango is targeted for Win32 and
00009         linux platforms.
00010 
00011         There are currently eight packages under the Mango Tree:
00012 
00013         @li mango.io: a high-performance buffered IO package. Primary
00014             functionality includes memory Buffers, external Conduits
00015             (files, sockets, etc), file-system manipulation, several
00016             flavors of Readers and Writers (formatted data), TextFormat
00017             (printf) and TextLayout support, class serialization,
00018             tokenization, and a whole lot more. Socket support is via
00019             the gracious provision of Christopher Miller's socket module.
00020             See FilePath, FileProxy, FileConduit, FileSystem, SocketConduit,
00021             ServerSocket, MulticastSocket, SocketListener, Token, Stdin,
00022             Stdout, Reader, Writer, IPickle and PickleRegistry.
00023 
00024         @li mango.http.client: An HTTP client for conversing with a remote
00025             HTTP server. Supports headers, query parameters, cookies,
00026             timeout etc. Tokenizer classes in mango.io are handy for
00027             parsing returned content. See HttpClient.
00028 
00029         @li mango.http.server: an HTTP server framework is provided for
00030             implementing a variety of high performance servers based
00031             on the HTTP protocol. This is not a fully-fledged v1.1
00032             implementation. That is, it doesn't currently support
00033             'fields' or 'keep alive'. However, it happily processes
00034             each request without allocating memory, making it unusually
00035             efficient. This is an example of how D array-slicing can
00036             seriously improve runtime efficiency. An open-source HTTPS
00037             library should be fairly easy to bolt in. Modules HttpServer 
00038             and IProvider are the primary entry points: you implement an 
00039             instance of the latter, and hand it to the former.
00040 
00041         @li mango.servlet: A servlet-style engine that sits upon
00042             mango.server. Includes most of the things that Java servlet
00043             programmers would expect, and attempts to improve in certain
00044             key areas such as the IO system. See Servlet and ServletProvider.
00045 
00046         @li mango.cache: Some simple caching mechanisms. Includes MRU
00047             caching via a queue, and level-two caching (to disk) via
00048             class-serialization. Now based upon a derivative of Doug Lea's
00049             concurrent hashmap. The mango.cluster package derives from
00050             mango.cache, so it's really easy to switch between a local
00051             cache implementation and a clustered version. See ICache,
00052             IMutableCache, PlainCache, QueuedCache and VirtualCache.
00053 
00054         @li mango.log: A port of the wildly popular Log4J package, for
00055             logging and tracing of runtime behaviour. See
00056             <A HREF="http://logging.apache.org/log4j/docs/documentation.html">this page</A>
00057             for an introduction to Log4J. Mango.log exposes an extensible and
00058             customizable framework, has been optimised heavily for
00059             minimal runtime overhead, does not impact the GC once
00060             initialised, and operates with either Mango.io or Phobos.
00061             Mango.log can generate remote log messages for use with Chainsaw,
00062             and has a browser-based 'Administrator' which allows remote,
00063             dynamic inspection and adjustment of the log settings within an
00064             executing program. See Logger, BasicConfigurator and
00065             PropertyConfigurator. There are a number of examples that show
00066             how to use these facilities (e.g Servlets.d)
00067 
00068         @li mango.cluster: A clustering package for servers and other
00069             network aware applications. Currently supports clustered
00070             caching and queuing, where the former is limited to a fixed
00071             MRU number of entries per node, and the latter is limited to an
00072             upper memory waterline. While the underlying QOS (quality of
00073             service) substrate is setup to be plugable, the QOS
00074             currently provided is stream/multicast based. Note that this
00075             package is not a substitute for a persistence layer; instead
00076             it is a tool for enabling horizontal scaling within a system
00077             that has been designed explicitly from the outset to scale.
00078             On the other hand, it can significantly enhance the throughput
00079             of any persistence layer by offloading a large percentage of
00080             read operations. See CacheInvalidatee, CacheInvalidator,
00081             NetworkCombo, NetworkAlert, NetworkCache and NetworkQueue.
00082 
00083         @li mango.icu: Set of wrappers around the ICU I18N project. See
00084             <A HREF="http://oss.software.ibm.com/icu/">this page</A> for
00085             the scoop on what is probably the most comprehensive and
00086             functional project in this particular arena. Mango.icu exposes
00087             the C API in a manner that takes advantage of D arrays and
00088             so on. See UCalendar, UChar, UConverter, UDateFormat, ULocale,
00089             UMessageFormat, UNumberFormat, UResourceBundle, UString,
00090             UText, UCollator, USet, UTransform, USearch, UNormalize,
00091             UDomainName, UBreakIterator, and UTimeZone.
00092             Numeric formatting is handled by a range of subclasses,
00093             including UDecimalFormat, UCurrencyFormat, UPercentFormat,
00094             UScientificFormat, and USpelloutFormat.
00095             There is set of adapter classes in UMango which can be used
00096             to bind the ICU converters to Mango.io, thereby enabling
00097             Reader and Writer with the full suite of unicode transcoders.
00098 
00099         Package dependencies are as follows (from left to right):
00100 
00101         @code
00102         mango.io           => phobos   (minimal)
00103         mango.log          => mango.io (without -version=Isolated)
00104         mango.icu          => mango.io (without -version=Isolated)
00105         mango.cache        => mango.io
00106         mango.http.server  => mango.io
00107         mango.http.client  => mango.io, mango.server
00108         mango.cluster      => mango.io, mango.cache, mango.log
00109         mango.servlet      => mango.io, mango.http.server, mango.cache, mango.log
00110         @endcode
00111 
00112         Mango.icu and Mango.log are also made available as independent packages,
00113         outside of the regular Mango Tree. To enable this, specify the flag
00114         -version=Isolated when building those packages
00115 
00116         You might take a look at the unittest.d source to get a general
00117         feel for functionality, and browse the various pdf files
00118         <A HREF="http://svn.dsource.org/svn/projects/mango/trunk/doc/">here</A>
00119         along with the class-hierarchy or alphabetical-list linked at the
00120         top of this page. There's also a set of examples
00121         <A HREF="http://svn.dsource.org/svn/projects/mango/trunk/example/">over here</A>.
00122         Those will probably be sufficient to get an idea where the Mango Tree
00123         might come in handy within your projects.
00124 
00125         Discussion forums are hosted
00126         <A HREF="http://www.dsource.org/forums/viewforum.php?f=5">here</A>,
00127         and the general introduction starts
00128         <A HREF="http://www.dsource.org/forums/viewtopic.php?t=148">here</A>.
00129 
00130 *******************************************************************************/
00131 
00132 
00133 
00134 
00135 /******************************************************************************
00136 
00137         @file unittest.d
00138 
00139         Test jig for the mango.io package.
00140 
00141 
00142         This shows a number of different ways to manipulate buffers,
00143         readers, writers, and how to perform IO on files and sockets.
00144 
00145         The basic premise behind this IO package is as follows:
00146 
00147         1) the central concept is that of a buffer. The buffer acts
00148            as a queue (line) where items are removed from the front
00149            and new items are added to the back. Buffers are modeled
00150            by mango.io.model.IBuffer, and a concrete implementation
00151            is provided via mango.io.Buffer.
00152 
00153         2) buffers can be written to directly, but a Reader and/or
00154            Writer are typically used to read & write formatted data.
00155            These readers & writers are bound to a specific buffer;
00156            often the same buffer. It's also perfectly legitimate to
00157            bind multiple writers to the same buffer; they will all
00158            behave serially as one would expect. The same applies to
00159            multiple readers on the same buffer. Readers and writers
00160            support two styles of IO: put/get, and the C++ style <<
00161            and >> operators. All such operations can be chained.
00162 
00163         3) Any class can be made compatable with the reader/writer
00164            framework by implementing the IReadable and/or IWritable
00165            interfaces. Each of these specify just a single method.
00166 
00167         4) Buffers may also be tokenized. This is handy when one is
00168            dealing with text input, and/or the content suits a more
00169            fluid format than most typical readers & writers support.
00170            Tokens are mapped directly onto buffer content, so there
00171            is only minor overhead in using them. Tokens can be read
00172            and written by reader/writers also, using a more relaxed
00173            set of rules than those applied to integral IO.
00174 
00175         5) buffers are sometimes memory-only, in which case there
00176            is nothing left to do when a reader (or tokenizer) hits
00177            end of buffer conditions. Other buffers are themselves
00178            bound to a Conduit. When this is the case, a reader will
00179            eventually cause the buffer to reload via its associated
00180            conduit. Previous buffer content will thus be lost. The
00181            same concept is applied to writers, whereby they flush
00182            the content of a full buffer to a bound conduit before
00183            continuing.
00184 
00185         6) conduits provide virtualized access to external content,
00186            and represent things like files or Internet connections.
00187            They are just a different kind of stream. Conduits are
00188            modelled by mango.io.model.IConduit, and implemented via
00189            classes FileConduit and SocketConduit. Additional kinds
00190            of conduit are easy to construct: one either subclasses
00191            mango.io.Conduit, or implements mango.io.model.IConduit.
00192            The conduit reads and writes a buffer in large segments;
00193            typically the entire buffer.
00194 
00195         7) additional file-system support is provided through two
00196            classes: FileSystem supports operations such as getting
00197            and setting the current directory, and FileProxy exposes
00198            facilities to manipulate both files and directories.
00199 
00200         8) console IO is implemented via Stdio, using FileConduit
00201            and appropriate readers and writers. Console IO can be
00202            redirected in the traditional (shell) manner.
00203 
00204         9) the package is intended to be portable between linux and
00205            Win32 platforms.
00206 
00207 
00208         Kris Bell, March 26th 2004
00209 
00210 *******************************************************************************/
00211 
00212 
00213         // test these modules
00214 import  mango.io.Uri,
00215         mango.io.Stdin,
00216         mango.io.Stdout,
00217         mango.io.Token,
00218         mango.io.Reader,
00219         mango.io.Writer,
00220         mango.io.Buffer,
00221         mango.io.Socket,
00222         mango.io.Conduit,
00223         mango.io.FilePath,
00224         mango.io.FileStyle,
00225         mango.io.FileProxy,
00226         mango.io.Tokenizer,
00227         mango.io.TextReader,
00228         mango.io.TextWriter,
00229         mango.io.FileBucket,
00230         mango.io.FileConduit,
00231         mango.io.TextLayout,
00232         mango.io.TextFormat,
00233         mango.io.ColumnWriter,
00234         mango.io.DisplayWriter,
00235         mango.io.PickleReader,
00236         mango.io.PickleWriter,
00237         mango.io.SocketConduit,
00238         mango.io.SocketListener,
00239         mango.io.ArrayAllocator,
00240         mango.io.PickleRegistry,
00241         mango.io.DatagramSocket,
00242         mango.io.MulticastSocket;
00243 
00244         // need this for logging
00245 import  mango.log.Logger,
00246         mango.log.Layout,
00247         mango.log.Manager,
00248         mango.log.XmlLayout,
00249         mango.log.DateLayout,
00250         mango.log.Configurator,
00251         mango.log.FileAppender,
00252         mango.log.ConsoleAppender,
00253         mango.log.RollingFileAppender;
00254 
00255         // need these for reading & writing classes
00256 import  mango.io.model.IReader,
00257         mango.io.model.IWriter,
00258         mango.io.model.IPickle;
00259 
00260         // add a bunch of stuff for testing the http server
00261 import  mango.http.server.HttpParams,
00262         mango.http.server.HttpCookies,
00263         mango.http.server.HttpHeaders,
00264         mango.http.server.HttpServer,
00265         mango.http.server.HttpRequest,
00266         mango.http.server.HttpResponse,
00267         mango.http.server.HttpProvider;
00268 
00269 import  mango.http.server.model.IProvider,
00270         mango.http.server.model.IProviderBridge;
00271 
00272 import  mango.http.client.HttpClient;
00273 
00274 import  mango.servlet.Servlet,
00275         mango.servlet.ServletConfig,
00276         mango.servlet.ServletContext,
00277         mango.servlet.ServletProvider;
00278 
00279 import  mango.cache.PlainCache,
00280         mango.cache.HashMap,
00281         mango.cache.Payload,
00282         mango.cache.QueuedCache,
00283         mango.cache.VirtualCache;
00284 
00285 import  mango.cluster.Message,
00286         mango.cluster.NetworkQueue,
00287         mango.cluster.NetworkCache,
00288         mango.cluster.CacheInvalidator,
00289         mango.cluster.CacheInvalidatee;
00290 
00291 import  mango.cluster.qos.socket.Cluster,
00292         mango.cluster.qos.socket.ClusterServer,
00293         mango.cluster.qos.socket.ProtocolReader,
00294         mango.cluster.qos.socket.ProtocolWriter;
00295 
00296 import  mango.icu.UMango,
00297         mango.icu.UString,
00298         mango.icu.UDomainName,
00299         mango.icu.UStringPrep,
00300         mango.icu.UConverter,
00301         mango.icu.USet,
00302         mango.icu.UCollator,
00303         mango.icu.UTimeZone,
00304         mango.icu.UEnumeration,
00305         mango.icu.UMessageFormat;
00306 
00307 import  mango.format.Double;
00308 
00309 
00310 //import        mango.xml.dom.all;
00311 
00312 /*******************************************************************************
00313 
00314         global scope variables
00315 
00316 *******************************************************************************/
00317 
00318 private Logger logger;
00319 
00320 /*******************************************************************************
00321 
00322         Simple test of in-memory buffer. Bind both a Reader and a Writer
00323         onto the same buffer.
00324 
00325 *******************************************************************************/
00326 
00327 static void testBuffer()
00328 {
00329         // create a small heap buffer
00330         Buffer buf = new Buffer (256);
00331 
00332         // map same buffer into both reader and writer
00333         Writer w = new Writer (buf);
00334         Reader r = new Reader (buf);
00335 
00336         int i = 10;
00337         int j = 20;
00338         double d = 3.14159;
00339         char[] c = "testing";
00340 
00341         // write integral types out
00342         w (c) (i) (j) (d);
00343 
00344         // read them back again
00345         r (c) (i) (j) (d);
00346 
00347         assert(i==10);
00348         assert(j==20);
00349         assert(d==3.14159);
00350         assert(c=="testing");
00351 
00352         // reset
00353         buf.clear();
00354 
00355         // same thing again, but using iostream syntax instead
00356         w << c << i << j << d;
00357 
00358         // read them back again
00359         r >> c >> i >> j >> d;
00360 
00361         assert(i==10);
00362         assert(j==20);
00363         assert(d==3.14159);
00364         assert(c=="testing");
00365 
00366         // reset
00367         buf.clear();
00368 
00369         // same thing again, but using put() syntax instead (and swap i & j)
00370         w.put(c).put(i).put(j).put(d);
00371         r.get(c).get(j).get(i).get(d);
00372 
00373         assert(i==20);
00374         assert(j==10);
00375         assert(d==3.14159);
00376         assert(c=="testing");
00377 }
00378 
00379 
00380 /*******************************************************************************
00381 
00382         Append to a buffer directly without using a Writer. This can be
00383         useful for appending a set of strings (or other array type) to
00384         a contiguous space in a similar fashion to std.outbuffer.
00385 
00386 *******************************************************************************/
00387 
00388 static void testAppend()
00389 {
00390         char[] foo = "to write some D code";
00391 
00392         // create a small heap buffer
00393         Buffer buf = new Buffer (256);
00394 
00395         // append some text directly to it
00396         buf.append ("now is the time for all good men ").append(foo);
00397 
00398         // output the combined string
00399         Stdout (buf.toString) (CR);
00400 }
00401 
00402 
00403 /*******************************************************************************
00404 
00405         write delimited text tokens to a buffer, then read them back out
00406         to the console
00407 
00408 *******************************************************************************/
00409 
00410 static void testToken1()
00411 {
00412         // create a small buffer on top of a static array
00413         static ubyte[128] storage;
00414         Buffer buf = new Buffer (storage);
00415 
00416         // write tokens with a comma between each
00417         IWriter write = new TextWriter (buf, ",");
00418 
00419         // bind a comma-tokenizer to a token instance
00420         BoundToken token = new BoundToken (Tokenizers.comma);
00421 
00422         // write some stuff to the buffer
00423         write ("now is the time for all good men") (3.14159);
00424 
00425         // read it back, and display as text
00426         while (token.next (buf))
00427                Stdout (token) (CR);
00428 }
00429 
00430 /*******************************************************************************
00431 
00432         Use tokens directly with reader/writer also
00433 
00434 *******************************************************************************/
00435 
00436 static void testToken2()
00437 {
00438         // create a small buffer on the heap
00439         Buffer buf = new Buffer (256);
00440 
00441         // write items with a comma between each
00442         IWriter write = new TextWriter (buf, ",");
00443 
00444         // write some stuff to the buffer
00445         write ("now is the time for all good men") (3.14159);
00446 
00447         // bind a couple of tokens to a comma tokenizer
00448         ReaderToken text = new ReaderToken (Tokenizers.comma);
00449         ReaderToken number = new ReaderToken (Tokenizers.comma);
00450 
00451         // create any old reader since we only use it for handling tokens
00452         IReader read = new Reader (buf);
00453 
00454         // populate both tokens via reader
00455         read (text) (number);
00456 
00457         // print them to the console
00458         Stdout (text) (':') (number) (CR);
00459 }
00460 
00461 /*******************************************************************************
00462 
00463         use TextReader to convert text into integral types. This is akin
00464         to what scanf does.
00465 
00466 *******************************************************************************/
00467 
00468 static void testToken3()
00469 {
00470         // create a small buffer
00471         Buffer buf = new Buffer (256);
00472 
00473         // write tokens with a comma between each
00474         TextWriter write = new TextWriter (buf, ",");
00475 
00476         // write some stuff to the buffer
00477         write (101) (3.14159);
00478 
00479         // map a comma-tokenizing reader onto our buffer
00480         TextReader read = new TextReader (buf, Tokenizers.comma);
00481 
00482         real pi;
00483         int  integer;
00484 
00485         // convert both tokens via reader
00486         read (integer) (pi);
00487 
00488         // print them to the console
00489         Stdout (integer) (',') (pi) (CR);
00490 }
00491 
00492 
00493 /*******************************************************************************
00494 
00495         Read line tokens via a TextReader
00496 
00497 *******************************************************************************/
00498 
00499 static void testToken4()
00500 {
00501         // open a file for reading
00502         FileConduit fc = new FileConduit ("test.txt");
00503 
00504         // create a buffer for transferring content
00505         IBuffer buffer = fc.createBuffer ();
00506 
00507         // map a line-tokenizing reader onto our buffer
00508         TextReader read = new TextReader (buffer, Tokenizers.line);
00509 
00510         char[] ca;
00511 
00512         // read a line of text
00513         read (ca);
00514 
00515         // display it on the console
00516         Stdout (ca) (CR);
00517 }
00518 
00519 
00520 
00521 /*******************************************************************************
00522 
00523         Use printf via a wrapper class
00524 
00525 *******************************************************************************/
00526 
00527 static void testFormat()
00528 {
00529         // create a Format instance
00530         TextFormat format = new TextFormat (256);
00531 
00532         // write text to Stdout
00533         Stdout (format ("there are %d arguments to every %.*s", 3, "contradiction")) (CR);
00534 }
00535 
00536 
00537 /*******************************************************************************
00538 
00539         Layout text strings in an indexed fashion
00540 
00541 *******************************************************************************/
00542 
00543 static void testLayout()
00544 {
00545         // create a Layout instance
00546         LayoutChar layout = new LayoutChar (256);
00547 
00548         // write text to Stdout
00549         Stdout (layout ("%2 %1", "one", "two")) (CR);
00550 }
00551 
00552 
00553 /*******************************************************************************
00554 
00555         Use interfaces to make any class reader and/or writer compatible
00556 
00557 *******************************************************************************/
00558 
00559 static void testClassIO()
00560 {
00561         // define a readable/writable class (via interfaces)
00562         class Foo : IReadable, IWritable
00563         {
00564                 private int x = 11;
00565                 private int y = 112;
00566 
00567                 void write (IWriter put)
00568                 {
00569                         put (x) (y);
00570                 }
00571 
00572                 void read (IReader get)
00573                 {
00574                         get (x) (y);
00575                 }
00576         }
00577 
00578         // create a small heap buffer
00579         Buffer buf = new Buffer (256);
00580 
00581         // map reader/writer onto same buffer
00582         Writer write = new Writer (buf);
00583         Reader read = new Reader (buf);
00584 
00585         // construct a Foo
00586         Foo foo = new Foo();
00587 
00588         // write it
00589         write (foo);
00590 
00591         // read it back
00592         read (foo);
00593 }
00594 
00595 
00596 /*******************************************************************************
00597 
00598         Use interfaces to make any class serializable. This will be used
00599         by mango.server to move class-instances around the network. Each
00600         class is effectively a factory for itself.
00601 
00602         Note that this is not the same as Java; you can't ship code with
00603         the data ... one might perhaps use dll's or something to do that.
00604 
00605 *******************************************************************************/
00606 
00607 static void testClassSerialization()
00608 {
00609         // define a serializable class (via interfaces)
00610         class Bar : IPickle, IPickleFactory
00611         {
00612                 private int x = 11;
00613                 private int y = 112;
00614 
00615                 void write (IWriter write)
00616                 {
00617                         write (x) (y);
00618                 }
00619 
00620                 void read (IReader read)
00621                 {
00622                         read (x) (y);
00623                         assert (x == 11 && y == 112);
00624                 }
00625 
00626                 Object create (IReader reader)
00627                 {
00628                         Bar bar = new Bar ();
00629                         bar.read (reader);
00630                         return bar;
00631                 }
00632 
00633                 char[] getGuid ()
00634                 {
00635                         return "unittest.Bar";
00636                 }
00637         }
00638 
00639         static Object create (IReader reader)
00640         {
00641                 Bar bar = new Bar();
00642                 bar.read (reader);
00643                 return bar;
00644         }
00645 
00646         // setup for serialization
00647         Buffer buf = new Buffer (256);
00648         PickleWriter w = new PickleWriter (buf);
00649         PickleReader r = new PickleReader (buf);
00650 
00651         r.setAllocator (new BufferAllocator);
00652 
00653         // construct a Bar
00654         Bar bar = new Bar ();
00655 
00656         // tell registry about this object
00657         //PickleRegistry.enroll (&create, "unittest.Bar");
00658         PickleRegistry.enroll (bar);
00659 
00660         // serialize it
00661         w.freeze (bar);
00662 
00663         // create a new instance and populate. This just shows the basic
00664         // concept, not a fully operational implementation
00665         Object o = r.thaw ();
00666 }
00667 
00668 
00669 /*******************************************************************************
00670 
00671         open a file, and stream directly to console
00672 
00673 *******************************************************************************/
00674 
00675 static void testFile4()
00676 {
00677         // open a file for reading
00678         FileConduit fc = new FileConduit ("test.txt");
00679 
00680         // stream directly to console
00681         Stdout.conduit.copy (fc);
00682 }
00683 
00684 
00685 /*******************************************************************************
00686 
00687        Create a file for random access. Write some stuff to it, rewind to
00688        file start and read back.
00689 
00690 *******************************************************************************/
00691 
00692 static void testRandomAccess()
00693 {
00694         // open a file for reading
00695         auto FileConduit fc = new FileConduit ("random.bin", FileStyle.ReadWriteCreate);
00696 
00697         // construct (binary) reader & writer upon this conduit
00698         Reader read = new Reader(fc);
00699         Writer write = new Writer(fc);
00700 
00701         int x=10, y=20;
00702 
00703         // write some data
00704         write (x) (y);
00705 
00706         // flush output since IO is buffered
00707         write ();
00708 
00709         // rewind to file start
00710         fc.seek (0);
00711 
00712         // read data back again, but swap destinations
00713         read (y) (x);
00714 
00715         assert (y==10);
00716         assert (x==20);
00717 }
00718 
00719 
00720 /*******************************************************************************
00721 
00722        Create a file for random access. Write some stuff to it, rewind to
00723        file start and read back.
00724 
00725 *******************************************************************************/
00726 
00727 static void testConduitFilters()
00728 {
00729         class MyFilter1 : ConduitSource
00730         {
00731                 int reader (void[] dst)
00732                 {
00733                         printf ("filtering input ...\n");
00734                         return next.reader (dst);
00735                 }
00736         }
00737 
00738         class MyFilter2 : ConduitSink
00739         {
00740                 int writer (void[] src)
00741                 {
00742                         printf ("filtering output ...\n");
00743                         return next.writer (src);
00744                 }
00745         }
00746 
00747         // open a file for reading
00748         auto FileConduit fc = new FileConduit ("random.bin", FileStyle.ReadWriteCreate);
00749         fc.attach (new MyFilter2);
00750         fc.attach (new MyFilter1);
00751         fc.attach (new MyFilter1);
00752 
00753         // construct (binary) reader & writer upon this conduit
00754         Reader read = new Reader(fc);
00755         Writer write = new Writer(fc);
00756 
00757         int x=1;
00758 
00759         // write some data, and flush it
00760         write (x) ();
00761 
00762         // rewind to file start
00763         fc.seek (0);
00764 
00765         // read data back again
00766         read (x);
00767 }
00768 
00769 
00770 /*******************************************************************************
00771 
00772         open a file, and explicitly buffer it to another conduit. This is
00773         effectively what Conduit.copyTo() does.
00774 
00775 *******************************************************************************/
00776 
00777 static void testFile5()
00778 {
00779         // open a file for reading
00780         FileConduit fc = new FileConduit ("test.txt");
00781 
00782         // create a buffer for transferring content
00783         IBuffer buffer = fc.createBuffer ();
00784 
00785         // stream the data from file to stdout. This is probably as fast as
00786         // one can practically make operations of this type.
00787         while (fc.read (buffer) != fc.Eof)
00788                Stdout.conduit.write (buffer);
00789 
00790         // ensure the writer actually wrote everything
00791         Stdout.conduit.flush (buffer);
00792 }
00793 
00794 
00795 /*******************************************************************************
00796 
00797         Open a file and read it line-by-line using a line tokenizer. This
00798         uses CompositeToken to hide some of the details.
00799 
00800 *******************************************************************************/
00801 
00802 static void testFile1()
00803 {
00804         // open a file for reading
00805         FileConduit fc = new FileConduit ("test.txt");
00806 
00807         // create a Token and bind it to both the file and a line-tokenizer
00808         CompositeToken line = new CompositeToken (Tokenizers.line, fc);
00809 
00810         // read file a line at a time. Method next() returns false when no more
00811         // delimiters are found. Note there may be an unterminated line at eof
00812         while (line.get)
00813                Stdout (line) (CR);
00814 }
00815 
00816 
00817 /*******************************************************************************
00818 
00819         Unwound version of above: we now explicitly pass a buffer instance
00820         to the tokenizer, although the token itself is still bound.
00821 
00822 *******************************************************************************/
00823 
00824 static void testFile2()
00825 {
00826         // open a file for reading
00827         FileConduit fc = new FileConduit ("test.txt");
00828 
00829         // create a buffer for reading the file
00830         IBuffer buffer = fc.createBuffer();
00831 
00832         // bind a line-tokenizer to our input token
00833         BoundToken line = new BoundToken (Tokenizers.line);
00834 
00835         // read file a line at a time. Method next() returns false when no more
00836         // delimiters are found. Note there may be an unterminated line at eof
00837         while (line.next(buffer) || line.getLength())
00838                Stdout (line) (CR);
00839 }
00840 
00841 
00842 /*******************************************************************************
00843 
00844         Further unwinding of above: we invoke the tokenizer directly,
00845         explicitly passing both the buffer and the token
00846 
00847 *******************************************************************************/
00848 
00849 static void testFile3()
00850 {
00851         // open a file for reading
00852         FileConduit fc = new FileConduit ("test.txt");
00853 
00854         // create a buffer for reading the file
00855         IBuffer buffer = fc.createBuffer();
00856 
00857         // create a token for receiving the line
00858         Token token = new Token ();
00859 
00860         // read file a line at a time. Method next() returns false when no more
00861         // delimiters are found. Note there may be an unterminated line at eof
00862         while (Tokenizers.line.next(buffer, token) || token.getLength())
00863                Stdout.put(token).cr();
00864 }
00865 
00866 
00867 /*******************************************************************************
00868 
00869         Recursively scan files and directories, adding filtered files to
00870         an output structure as we go. Thanks to Chris S for this.
00871 
00872 *******************************************************************************/
00873 
00874 void testScanFiles()
00875 {
00876         /***********************************************************************
00877 
00878         ***********************************************************************/
00879 
00880         struct Dependencies
00881         {
00882                 FileProxy[]     mods;
00883                 FilePath[]      pkgs;
00884         }
00885 
00886         /***********************************************************************
00887 
00888         ***********************************************************************/
00889 
00890         void scanFiles (inout Dependencies deps, FilePath base)
00891         {
00892                 /***************************************************************
00893 
00894                         delegate for filtering sub-directories and
00895                         D source files
00896 
00897                 ***************************************************************/
00898 
00899                 bit filter (FilePath fp)
00900                 {
00901                         char[]  sbuf = fp.getExtension();
00902 
00903                         if (fp.getName[0] != '.')
00904                             if (sbuf.length == 0 || sbuf == "d")
00905                                 return true;
00906 
00907                         return false;
00908                 }
00909 
00910                 /***************************************************************
00911 
00912                 ***************************************************************/
00913 
00914                 FileProxy  proxy = new FileProxy (base);
00915                 FilePath[] paths = proxy.toList  (&filter);
00916 
00917                 // add packages only if there's something in them
00918                 if (paths.length)
00919                     deps.pkgs ~= base;
00920 
00921                 foreach (FilePath x; paths)
00922                         {
00923                         // combine base path with listed file
00924                         FilePath spliced = new FilePath (x.splice (base));
00925 
00926                         // recurse if this is a directory ...
00927                         proxy = new FileProxy (spliced);
00928                         if (proxy.isDirectory)
00929                             scanFiles (deps, spliced);
00930                         else
00931                            deps.mods ~= proxy;
00932                         }
00933         }
00934 
00935 
00936         /***********************************************************************
00937 
00938         ***********************************************************************/
00939 
00940         Dependencies deps;
00941         scanFiles (deps, new FilePath (r"\dmd\src\mango"));
00942 
00943         Stdout.put ("-----------------").cr();
00944         foreach (FileProxy mod; deps.mods)
00945                  Stdout.put (mod.getPath()).cr();
00946 
00947         Stdout.put ("-----------------").cr();
00948         foreach (FilePath pkg; deps.pkgs)
00949                  Stdout.put (pkg).cr();
00950 }
00951 
00952 
00953 /*******************************************************************************
00954 
00955         Open an internet connection, and copy home page to console (via
00956         Chris Miller's socket.d). We could use a line-by-line approach in
00957         the same manner as above since both Files & Sockets are conduits.
00958         All conduits are interchangable with others.
00959 
00960 *******************************************************************************/
00961 
00962 static void testSocket()
00963 {
00964         // create a socket and connect it to Walter's site
00965         SocketConduit sc = new SocketConduit();
00966         sc.connect (new InternetAddress("www.digitalmars.com", 80));
00967 
00968         // construct a writer and bind it to the socket
00969         IWriter write = new DisplayWriter (sc);
00970 
00971         // send HTTP request - flush the output
00972         write ("GET /d/intro.html HTTP/1.1\r\n"
00973                "Host: www.digitalmars.com\r\n\r\n") ();
00974 
00975         // set read-timeout to 0.5 seconds (avoids stalling)
00976         sc.setTimeout (System.Interval.Millisec * 500);
00977 
00978         // stream home-page directly to console conduit
00979         Stdout.conduit.copy (sc);
00980 }
00981 
00982 
00983 /*******************************************************************************
00984 
00985         Use a ColumnWriter to write formatted data onto the console. Note
00986         that we map the ColumnWriter directly into the Stdout buffer.
00987 
00988 *******************************************************************************/
00989 
00990 static void testColumn()
00991 {
00992         static int[] columns = [0, 4, 14, 24];
00993 
00994         // map a ColumnWriter directly onto Stdout
00995         ColumnWriter cw = new ColumnWriter (Stdout.getBuffer(), new ColumnList(columns));
00996 
00997         cw (1) (20.34) ("test") ("next") (CR) ();
00998 }
00999 
01000 /*******************************************************************************
01001 
01002         Get a line of input from the console, and extract an integer. Input
01003         from the console always waits until CR is pressed (at the OS level).
01004 
01005 *******************************************************************************/
01006 
01007 static void testStdin()
01008 {
01009         int x;
01010 
01011         // display a prompt - flush the output, since there is no 'newline'
01012         Stdout ("Enter a number: ") ();
01013 
01014         // wait for <cr>, then convert input to integer.
01015         Stdin  (x);
01016 }
01017 
01018 
01019 import std.regexp;
01020 
01021 /*******************************************************************************
01022 
01023         Use RegExp to scan words via a buffer.
01024 
01025 *******************************************************************************/
01026 
01027 static void wordRegex (IBuffer buffer)
01028 {
01029         // create a new regex tokenizer for words
01030         RegexTokenizer rt = new RegexTokenizer (new RegExp(r"\w+", null));
01031 
01032         // create a token to hold tokenized output, and bind it to the buffer
01033         CompositeToken word = new CompositeToken (rt, buffer);
01034 
01035         // read buffer a word at a time. Method next() returns false when no
01036         // more tokens are found
01037         while (word.next)
01038                Stdout (word) (CR);
01039 }
01040 
01041 
01042 
01043 /*******************************************************************************
01044 
01045         Use RegExp to scan file content via a buffer. Buffered scanning
01046         avoids loading the entire file into memory at one time.
01047 
01048 *******************************************************************************/
01049 
01050 static void testFileRegex()
01051 {
01052         // open a file for reading
01053         FileConduit fc = new FileConduit ("test.txt");
01054 
01055         // extract words from file
01056         wordRegex (fc.createBuffer);
01057 }
01058 
01059 
01060 /*******************************************************************************
01061 
01062         open an internet connection and scan home-page for words.
01063 
01064 *******************************************************************************/
01065 
01066 static void testSocketRegex()
01067 {
01068         // create a socket and connect it to Walter's site
01069         SocketConduit sc = new SocketConduit();
01070         sc.connect (new InternetAddress("www.digitalmars.com", 80));
01071 
01072         // construct a writer and bind it to the socket
01073         IWriter write = new DisplayWriter (sc);
01074 
01075         // write HTTP request, and flush output socket
01076         write ("GET /d/intro.html HTTP/1.1\r\n"
01077                "Host: www.digitalmars.com\r\n\r\n") ();
01078 
01079         // set read-timeout to 0.5 seconds (avoids stalling)
01080         sc.setTimeout (System.Interval.Millisec * 500);
01081 
01082         // scan words out of home page
01083         wordRegex (sc.createBuffer);
01084 }
01085 
01086 
01087 /*******************************************************************************
01088 
01089         Read lines from a file, and scan each line for words. This shows
01090         how to map the content of one buffer into another without copying
01091         any data. Unlikely to be a common activity.
01092 
01093 *******************************************************************************/
01094 
01095 static void testLineRegex()
01096 {
01097         // open a file for reading
01098         FileConduit fc = new FileConduit ("test.txt");
01099 
01100         // create a token for lines, and map it onto the file buffer.
01101         CompositeToken line = new CompositeToken (Tokenizers.line, fc);
01102 
01103         // create a seperate buffer for scanning within each line. We will
01104         // set the content for this buffer as we read each line. Note that
01105         // if we used the file buffer directly, then we'd continue reading
01106         // words right past the end of the line. This is because the file
01107         // buffer would just reload itself instead of halting at the line
01108         // termimator.
01109         Buffer rescan = new Buffer;
01110 
01111         // scan all lines in the file, including the final one
01112         while (line.get)
01113               {
01114               // map our rescan buffer onto the line content
01115               rescan.setValidContent (line.toString);
01116 
01117               // scan just this line for words
01118               wordRegex (rescan);
01119               }
01120 
01121 }
01122 
01123 /*******************************************************************************
01124 
01125         Display the size of a file
01126 
01127 *******************************************************************************/
01128 
01129 static void testFileSize()
01130 {
01131         FileProxy fp = new FileProxy ("test.txt");
01132 
01133         Stdout (fp.getPath)
01134                (" is ")
01135                (fp.getSize)
01136                (" bytes long")
01137                (CR);
01138 }
01139 
01140 
01141 /*******************************************************************************
01142 
01143         list a set of files
01144 
01145 *******************************************************************************/
01146 
01147 static void testFileList()
01148 {
01149         FileProxy proxy = new FileProxy (r".");
01150 
01151         foreach (FilePath path; proxy.toList())
01152                  Stdout.put(path).cr();
01153 }
01154 
01155 /*******************************************************************************
01156 
01157         list a set of files
01158 
01159 *******************************************************************************/
01160 
01161 static void testFilePath()
01162 {
01163         FilePath path = new FilePath (r"c:\1\2\3\4\abc.foo.bar");
01164 
01165         Stdout << path << CR;
01166 
01167         Uri uri = path.toUri();
01168         Stdout << uri.getScheme() << CR
01169                << uri.getHost() << CR
01170                << uri.getPath() << CR
01171                << uri.getPort() << CR
01172                << uri << CR;
01173 
01174         uri = new Uri (uri.toString());
01175         Stdout << uri.getScheme() << CR
01176                << uri.getHost() << CR
01177                << uri.getPath() << CR
01178                << uri.getPort() << CR
01179                << uri << CR;
01180 
01181         path = new FilePath (uri);
01182 
01183         Stdout << path << CR;
01184 }
01185 
01186 
01187 /*******************************************************************************
01188 
01189         Construct a memory-mapped buffer upon a 200MB file. Note that we
01190         should close both the conduit and buffer when finished.
01191 
01192         Note also that Win32 takes a while to close the initial file if
01193         it has just been created or resized. Subsequently opening the
01194         file as ReadWriteExising performs admirably. I imagine it's to
01195         do with spooling a gazillion dirty pages to the drive?
01196 
01197 *******************************************************************************/
01198 
01199 void testMappedFile()
01200 {
01201         FileConduit conduit = new FileConduit ("test.bin", FileStyle.ReadWriteCreate);
01202         conduit.seek (200_000_000);
01203         conduit.truncate ();
01204 
01205         MappedFile buffer = new MappedFile (conduit);
01206         buffer.setPosition (100_000_000);
01207         buffer.append ("test");
01208         buffer.close ();
01209 
01210         conduit.close ();
01211 }
01212 
01213 /*******************************************************************************
01214 
01215         Use Composite IO to read and write a data-set. See CompositeReader
01216         and CompositeWriter for more on this.
01217 
01218 *******************************************************************************/
01219 
01220 static void testCompositeIO()
01221 {
01222         // define a serializable class (via interfaces)
01223         class Wumpus : IReadable, IWritable
01224         {
01225                 private int     x = 11,
01226                                 y = 112,
01227                                 z = 1024;
01228 
01229                 void write (IWriter output)
01230                 {
01231                         output (x) (y) (z);
01232                 }
01233 
01234                 void read (IReader input)
01235                 {
01236                         input (x) (y) (z);
01237                 }
01238 
01239         }
01240 
01241         // construct a Wumpus
01242         Wumpus wumpus = new Wumpus;
01243 
01244         // open a file for IO
01245         FileConduit fc = new FileConduit ("random.bin", FileStyle.ReadWriteCreate);
01246 
01247         // construct composite reader & writer upon the file, with binary IO
01248         IWriter write = new Writer (fc);
01249         IReader read = new Reader (fc);
01250 
01251         // write the Wumpus (and flush it)
01252         write (wumpus) ();
01253 
01254         // rewind to file start
01255         fc.seek (0);
01256 
01257         // read Wumpus back again
01258         read (wumpus);
01259 
01260         fc.close();
01261 }
01262 
01263 
01264 
01265 /*******************************************************************************
01266 
01267         One can perform direct IO on a conduit, simply by mapping a Buffer
01268         onto a local array. No additional buffering takes place but readers,
01269         writers, and tokenizers can't tell the difference: they may all be
01270         used without issue.
01271 
01272         This example uses the same direct-buffer for both reading & writing.
01273         However, seperate buffers may be used as appropriate.
01274 
01275 *******************************************************************************/
01276 
01277 static void testDirectIO()
01278 {
01279         // open a file for IO
01280         auto FileConduit fc = new FileConduit ("random.bin", FileStyle.ReadWriteCreate);
01281 
01282         // direct IO area (on the stack)
01283         ubyte[1024] content;
01284 
01285         // map a buffer onto local content. State all of it is valid content.
01286         // There are other IBuffer methods, such as setValidContent(), which
01287         // stipulate how much data is really in the buffer.
01288         IBuffer direct = new Buffer(content, content.length);
01289 
01290         // map our buffer onto the file
01291         direct.setConduit(fc);
01292 
01293         // mess with the content[] ...
01294         // ...
01295         // ...
01296         // ...
01297 
01298         // write directly from the local buffer (might use fc.flush() instead)
01299         fc.write (direct);
01300 
01301         // rewind to file start
01302         fc.seek (0);
01303 
01304         // make space for reading
01305         direct.clear();
01306 
01307         // read it all back in again
01308         int count = fc.read (direct);
01309         delete fc;
01310 
01311 }
01312 
01313 
01314 /*******************************************************************************
01315 
01316 *******************************************************************************/
01317 
01318 static void testUri()
01319 {
01320         MutableUri uri;
01321 
01322         uri = new MutableUri ("ftp1://Me:My@a:21");
01323         Stdout << uri << CR;
01324 
01325         uri.parse ("http://a:8080/b/c/d;p?q=bar of soap#fragmented");
01326         Stdout << uri << CR;
01327 
01328         Stdin.wait();
01329 
01330         for (int i=10_000_000; i > 0; --i)
01331              uri.parse ("http://a:8080/b/c/d;p?q=bar of soap#fragmented");
01332 }
01333 
01334 
01335 /******************************************************************************
01336 ************************ SocketServer testing *********************************
01337 *******************************************************************************/
01338 
01339 
01340 
01341 /*******************************************************************************
01342 
01343         Test the http server by sending it a few thousand requests.  Note
01344         that we don't use a reader or a writer here, though we could just
01345         as easily have done so.
01346 
01347         Also note that (Gentoo) linux has a hard time scavenging sockets
01348         fast enough to complete more than around 6000 iterations. Without
01349         the appropriate guru incantations to make ulimit work as desired,
01350         we just limit the iterations to a more agreeable level. Testing
01351         under Win32 seems to be fine at the 100,000 iteration mark.
01352 
01353 *******************************************************************************/
01354 
01355 void testClient ()
01356 {
01357         Buffer buf = new Buffer(1024);
01358         InternetAddress addr = new InternetAddress("localhost", 80);
01359 
01360         for (int i=10000; --i >= 0;)
01361             {
01362             // connect to the server
01363             SocketConduit socket = new SocketConduit ();
01364             socket.connect (addr);
01365 
01366             // reset buffer for another go around
01367             buf.clear ();
01368 
01369             // would need this if we were using Reader/Writer IO
01370             // buf.setConduit(socket);
01371 
01372             // send a request. This will be serviced by our IProvider
01373             buf.append ("GET / HTTP/1.1\n\n");
01374             socket.write (buf);
01375 
01376             // wait for something to be returned (you can set a timeout)
01377             socket.read (buf);
01378 
01379             // dump response to the console
01380             //Stdout.conduit.write (buf);
01381 
01382             // when we close this socket, recycle it immediately!
01383             //socket.setLingerPeriod (0);
01384 
01385             // attempt a graceful shutdown
01386             //socket.shutdown ();
01387 
01388             // close and destroy socket (the latter will do both)
01389             socket.close ();
01390             delete socket;
01391             }
01392 }
01393 
01394 
01395 /*******************************************************************************
01396 
01397         Create an http server with the given IProvider
01398 
01399 *******************************************************************************/
01400 
01401 void testServer (IProvider provider)
01402 {
01403         // bind to port 80 on a local address
01404         InternetAddress addr = new InternetAddress (80);
01405 
01406         // create a (1 thread) server using the IProvider to service requests
01407         HttpServer server = new HttpServer (provider, addr, 1);
01408 
01409         // start listening for requests (but this thread does not listen)
01410         server.start ();
01411 
01412         // pause for some console input
01413         Stdout.put("hit return to start the client test ...").flush();
01414         Stdin.wait ();
01415 
01416         // send a few thousand requests
01417         long time = System.getMillisecs;
01418         testClient ();
01419         Stdout.put (System.getMillisecs - time).cr();
01420 }
01421 
01422 
01423 /*******************************************************************************
01424 
01425         Declare a class for handling http requests. This one just simply
01426         returns a status page
01427 
01428 *******************************************************************************/
01429 
01430 void testHttpServer ()
01431 {
01432         class Provider : HttpProvider
01433         {
01434                 void service (HttpRequest request, HttpResponse response)
01435                 {
01436                         response.sendError (HttpResponses.OK);
01437                 }
01438         }
01439 
01440         // create a new http-provider, and attach it to a server
01441         testServer (new Provider());
01442 }
01443 
01444 
01445 /*******************************************************************************
01446 
01447         Test the servlet wrapper. Point your Browser at http://127.0.0.1
01448         and optionally add a path, query params, etc ...
01449 
01450 *******************************************************************************/
01451 
01452 void testServletEngine ()
01453 {
01454         /***********************************************************************
01455 
01456                 Return a file. Deliberately supports GET requests only.
01457 
01458         ***********************************************************************/
01459 
01460         class FileServlet : MethodServlet
01461         {
01462                 void doGet (IServletRequest request, IServletResponse response)
01463                 {
01464                         response.copyFile (request.getContext(), request.getPathInfo());
01465                 }
01466         }
01467 
01468 
01469         /***********************************************************************
01470 
01471                 A whole bunch of diagnostic stuff, plus cookie return and
01472                 rudimentary form processing.
01473 
01474         ***********************************************************************/
01475 
01476         class MyServlet : Servlet
01477         {
01478                 void service (IServletRequest request, IServletResponse response)
01479                 {
01480                         Uri uri = request.getUri();
01481 
01482                         // log everything to the console
01483                         Stdout ("------------------------")
01484                                (CR)
01485                                ("Uri: ")
01486                                (uri)
01487                                ()
01488                                ("------------------------")
01489                                (CR)
01490                                ("Headers:")
01491                                (CR)
01492                                (request.getHeaders)
01493                                ("------------------------")
01494                                (CR)
01495                                ("Cookies:")
01496                                (CR)
01497                                (request.getCookies)
01498                                ("------------------------")
01499                                (CR)
01500                                ("Parameters:")
01501                                (CR)
01502                                (request.getParameters)
01503                                ("------------------------")
01504                                (CR);
01505 
01506                         // display the Servlet environment
01507                         Stdout ("encoding: ")
01508                                (request.getCharacterEncoding)
01509                                (CR)
01510                                ("content length: ") (request.getContentLength)
01511                                (CR)
01512                                ("content type: ") (request.getContentType)
01513                                (CR)
01514                                ("protocol: ") (request.getProtocol)
01515                                (CR)
01516                                ("scheme: ") (uri.getScheme)
01517                                (CR)
01518                                ("method: ") (request.getMethod)
01519                                (CR)
01520                                ("host name: ") (request.getServerName)
01521                                (CR)
01522                                ("host port: ") (request.getServerPort)
01523                                (CR)
01524                               //.put("remote address: ").put(request.getRemoteAddress()).cr()
01525                               //.put("remote host: ").put(request.getRemoteHost()).cr()
01526                                ("path info: ") (request.getPathInfo)
01527                                (CR)
01528                                ("query: ") (uri.getQuery())
01529                                (CR)
01530                                ("path: ") (uri.getPath())
01531                                (CR)
01532                                ("context path: ") (request.getContextPath)
01533                                (CR)
01534                                (CR)
01535                                (CR);
01536 
01537                         int i = request.getContentLength();
01538 
01539                         if (i > 0)
01540                            {
01541                            byte[] content = new byte[i];
01542 
01543                            request.getReader.getPostData (content);
01544                            printf ("Content:\n>>%.*s<<\n\n\n", content);
01545                            }
01546 
01547                         // send a cookie to the user-agent ...
01548                         response.getCookies().add (new Cookie ("fu", "'bar of soap'"));
01549 
01550                         // send a form to the user-agent ...
01551                         IWriter write = response.getWriter();
01552                         write ("<HTML><HEAD><TITLE>Form</TITLE></HEAD>")
01553                               ("<BODY><FORM method=POST action=\"/context/test\">")
01554                               ("Enter a POST parameter: ")
01555                               ("<INPUT type=text name=\"name\"><P>")
01556                               ("<INPUT type=hidden name=\"hidden\" value=\"test\"><P>")
01557                               ("<INPUT type=submit>")
01558                               ("<?FORM></BODY></HTML>")
01559                               (CR);
01560 
01561                 }
01562         }
01563 
01564 
01565         // construct a servlet-provider
01566         ServletProvider sp = new ServletProvider();
01567 
01568         // map all html requests to our file servlet
01569         IRegisteredServlet files = sp.addServlet (new FileServlet(), "files");
01570         sp.addMapping ("*.html", files);
01571         sp.addMapping ("*.htm", files);
01572 
01573         // map all other request to our test servlet
01574         IRegisteredServlet test = sp.addServlet (new MyServlet(), "test");
01575         sp.addMapping ("/", test);
01576 
01577         // fire up a server
01578         testServer (sp);
01579 }
01580 
01581 
01582 /*******************************************************************************
01583 
01584         Shows a variety of ways in which to access data returned from
01585         a client-side socket connection.
01586 
01587 *******************************************************************************/
01588 
01589 void testHttpClient ()
01590 {
01591         /***********************************************************************
01592 
01593                 Bulk copy from input to Stdout
01594 
01595         ***********************************************************************/
01596 
01597         void readBulk (IConduit conduit)
01598         {
01599                 // stream directly to console
01600                 Stdout.conduit.copy (conduit);
01601         }
01602 
01603         /***********************************************************************
01604 
01605                 Unwound version of the above, where we explicitly move
01606                 data between endpoints using a buffer
01607 
01608         ***********************************************************************/
01609 
01610         void readBulkExplicit (IConduit conduit)
01611         {
01612                 // create a buffer for transferring content
01613                 IBuffer buffer = conduit.createBuffer ();
01614 
01615                 // stream the data from file to stdout. This is probably as fast as
01616                 // one can practically make operations of this type.
01617                 while (conduit.read (buffer) != conduit.Eof)
01618                        Stdout.conduit.write (buffer);
01619 
01620                 // ensure the writer actually wrote everything
01621                 assert (Stdout.conduit.flush (buffer));
01622         }
01623 
01624         /***********************************************************************
01625 
01626                 Read input a line at a time from the input. You can access
01627                 the line content via method Token.toString()
01628 
01629         ***********************************************************************/
01630 
01631         void readLines (IConduit conduit)
01632         {
01633                 // create a Token and bind it to both the conduit and a line-tokenizer
01634                 CompositeToken line = new CompositeToken (Tokenizers.line, conduit);
01635 
01636                 // read data a line at a time. Method next() returns false when no more
01637                 // delimiters are found. Note there may be an unterminated line at eof
01638                 while (line.get)
01639                        Stdout (line) (CR);
01640         }
01641 
01642         /***********************************************************************
01643 
01644                 Read input a char at a time. This will read in big chunks
01645                 of data from the input, but spit them out one character at
01646                 a time. While this is a lot faster then reading one char
01647                 at a time from the OS (the typical approach), this style
01648                 of reading is not recommended. Instead, try the 'chunked'
01649                 approach (below).
01650 
01651         ***********************************************************************/
01652 
01653         void readChars (IConduit conduit)
01654         {
01655                 // create a reader on the conduit
01656                 Reader reader = new Reader (conduit);
01657 
01658                 // read a single character at a time, until we run out of them.
01659                 // An exception will eventually be thrown because we're using
01660                 // the 'formatted' data approach
01661                 try {
01662                     while (true)
01663                           {
01664                           char c;
01665                           reader (c);
01666                           Stdout (c);
01667                           }
01668                     } catch (IOException x){}
01669         }
01670 
01671         /***********************************************************************
01672 
01673                 Read big chunks of data, and process them as such. Each read
01674                 operation will eat as much as there is from the input, up to
01675                 the size limit of the buffer.
01676 
01677         ***********************************************************************/
01678 
01679         void readChunks (IConduit conduit)
01680         {
01681                 IBuffer buffer = new Buffer(1024);
01682 
01683                 while (conduit.read (buffer) != conduit.Eof)
01684                       {
01685                       Stdout (buffer.toString);
01686                       buffer.clear ();
01687                       }
01688         }
01689 
01690         /***********************************************************************
01691 
01692                 unwound version of the above, where we setup buffer space
01693                 on the stack (instead of the heap). We need to explicitly
01694                 ask the buffer how much data is actually available. One
01695                 could use the return value from read() as the number of
01696                 bytes available instead (in this particular case), or
01697                 use buffer.toString() as in the above case
01698 
01699         ***********************************************************************/
01700 
01701         void readChunksExplicit (IConduit conduit)
01702         {
01703                 char[1024] content;
01704 
01705                 IBuffer buffer = new Buffer (content);
01706 
01707                 while (conduit.read (buffer) != conduit.Eof)
01708                       {
01709                       Stdout (content[0..buffer.readable()]);
01710                       buffer.clear ();
01711                       }
01712         }
01713 
01714 
01715         /***********************************************************************
01716 
01717                 Open a web-site connection, and process the returned page
01718 
01719         ***********************************************************************/
01720 
01721         // create a socket and connect it to Walter's site
01722         SocketConduit sc = new SocketConduit();
01723         sc.connect (new InternetAddress("www.digitalmars.com", 80));
01724 
01725         // construct a writer and bind it to the socket
01726         IWriter w = new FlushWriter (sc);
01727 
01728         // send HTTP request
01729         w.put ("GET /d/intro.html HTTP/1.1")
01730          .cr  ()
01731          .put ("Host: www.digitalmars.com")
01732          .cr  ()
01733          .cr  ();
01734 
01735         // set read-timeout to 1 second (avoids stalling for ever!)
01736         sc.setTimeout (System.Interval.Second);
01737 
01738         //readBulk (sc);
01739         //readBulkExplicit(sc);
01740         //readLines(sc);
01741         //readChars(sc);
01742         //readChunks(sc);
01743         readChunksExplicit(sc);
01744 
01745         // flush output
01746         Stdout ();
01747 }
01748 
01749 
01750 /*******************************************************************************
01751 
01752         Extract client-side headers from an HTTP reply
01753 
01754 *******************************************************************************/
01755 
01756 void testHttpClient2 ()
01757 {
01758         // create a socket and connect it to Walter's site
01759         SocketConduit sc = new SocketConduit;
01760         sc.connect (new InternetAddress("www.digitalmars.com", 80));
01761 
01762         // construct a writer and bind it to the socket
01763         IWriter w = new FlushWriter (sc);
01764 
01765         // send HTTP request
01766         w.put ("GET /d/intro.html HTTP/1.1")
01767          .cr  ()
01768          .put ("Host: www.digitalmars.com")
01769          .cr  ()
01770          .cr  ();
01771 
01772         // set read-timeout to 1 second (avoids stalling for ever!)
01773         sc.setTimeout (System.Interval.Second);
01774 
01775         // create an input buffer
01776         IBuffer buffer = sc.createBuffer;
01777 
01778         // extract all headers
01779         HttpHeaders headers = new HttpHeaders;
01780         headers.parse (buffer);
01781 
01782         // display parsed headers -- these should match HttpHeader.HttpHeaders
01783         foreach (HeaderElement header; headers)
01784                  Stdout.put (header.name.value)
01785                        .put (header.value)
01786                        .cr  ();
01787 
01788         // display remaining content
01789         while (sc.read (buffer) != sc.Eof)
01790               {
01791               Stdout (buffer.toString);
01792               buffer.clear ();
01793               }
01794         Stdout ();
01795 }
01796 
01797 /*******************************************************************************
01798 
01799         Poke an HTTP server, using HttpClient.
01800 
01801 *******************************************************************************/
01802 
01803 void testHttpClient3()
01804 {
01805         // create client for a GET request
01806         auto HttpClient client = new HttpClient (HttpClient.Get, "http://www.digitalmars.com/d/intro.html");
01807 
01808         // setup a Host header
01809         client.getRequestHeaders.add (HttpHeader.Host, client.getUri.getHost);
01810 
01811         // make request
01812         IBuffer b = client.open ();
01813 
01814         // check return status for validity
01815         if (client.isResponseOK)
01816            {
01817            // extract content length (be aware of -1 return, for no header)
01818            int length = client.getResponseHeaders.getInt (HttpHeader.ContentLength);
01819            if (length < 0)
01820                length = int.max;
01821 
01822            // display all returned headers
01823            Stdout.put (client.getResponseHeaders);
01824 
01825            // display remaining content
01826            client.read (delegate (char[] c){Stdout.put(c);}, length);
01827            Stdout ();
01828            }
01829         else
01830            Stderr.put (client.getResponse);
01831 }
01832 
01833 
01834 
01835 
01836 /******************************************************************************
01837 **************************** Cache testing ************************************
01838 *******************************************************************************/
01839 
01840 
01841 
01842 /*******************************************************************************
01843 
01844 
01845 *******************************************************************************/
01846 
01847 void testPlainCache()
01848 {
01849         PlainCache cache = new PlainCache (2);
01850 
01851         cache.put ("a", new Payload);
01852         cache.put ("b", new Payload);
01853         cache.put ("c", new Payload);
01854         cache.put ("c", new Payload);
01855 
01856         cache.extract ("b");
01857         assert (cache.get("a"));
01858         assert (cache.get("c"));
01859         assert (cache.get("b") is null);
01860 }
01861 
01862 /*******************************************************************************
01863 
01864         QueuedCache maintains a linked list of items, in addition to a
01865         hashmap. Any reference to an item places it at the list head,
01866         resulting in the LRU items always being left at the tail. When
01867         the list becomes full, tail items are dropped and their places
01868         reused.
01869 
01870         This is great for keeping commonly accessed items around, while
01871         limiting the amount of memory used.
01872 
01873         Typically, the queue size would be set in the hundreds (perhaps
01874         thousands) but we just use 2 for testing purposes.
01875 
01876 *******************************************************************************/
01877 
01878 void testQueuedCache()
01879 {
01880         QueuedCache cache = new QueuedCache (2);
01881 
01882         cache.put ("a", new Payload);
01883         cache.put ("b", new Payload);
01884         cache.put ("c", new Payload);
01885         cache.put ("c", new Payload);
01886 
01887         assert (cache.get("a") is null);
01888         assert (cache.get("c"));
01889 }
01890 
01891 /*******************************************************************************
01892 
01893         Stuff some data into a FileBucket, and pull it out again.
01894 
01895 *******************************************************************************/
01896 
01897 void testFileBucket()
01898 {
01899         char[] text = "this is a test";
01900 
01901         FileBucket bucket = new FileBucket (new FilePath ("bucket.bin"), FileBucket.HalfK, 0);
01902 
01903         // insert some data, and retrieve it again
01904         bucket.put ("a", text);
01905         char[] b = cast(char[]) bucket.get ("a");
01906 
01907         assert (b == text);
01908         bucket.close();
01909 }
01910 
01911 
01912 /*******************************************************************************
01913 
01914         Use a combination of QueuedCache and FileBucket to spill LRU
01915         cache entries onto the hard-drive, and then recover them intact.
01916 
01917         This demonstrates what one can do with the IPickle notion.
01918 
01919 *******************************************************************************/
01920 
01921 void testVirtualCache()
01922 {
01923         FileBucket bucket = new FileBucket (new FilePath ("bucket.bin"), FileBucket.HalfK);
01924         VirtualCache cache = new VirtualCache (bucket, 2);
01925         PickleRegistry.enroll (new Payload);
01926 
01927         cache.put ("a", new Payload);
01928         cache.put ("b", new Payload);
01929         cache.put ("c", new Payload);
01930 
01931         assert (cache.get("a"));
01932         assert (cache.get("c"));
01933         assert (cache.get("b"));
01934         bucket.close();
01935 }
01936 
01937 /*******************************************************************************
01938 
01939 
01940 *******************************************************************************/
01941 
01942 void testProtocol()
01943 {
01944         class Protocol : Payload
01945         {
01946                 char[]  x;
01947                 int     y = 10;
01948                 bool    z = true;
01949 
01950                 this ()
01951                 {
01952                         x = "fred";
01953                 }
01954 
01955                 static this()
01956                 {
01957                         PickleRegistry.enroll(new Protocol);
01958                 }
01959 
01960                 void write (IWriter w)
01961                 {
01962                         super.write (w);
01963                         w.put (x)
01964                          .put (y)
01965                          .put (z);
01966                 }
01967 
01968                 void read (IReader r)
01969                 {
01970                         super.read (r);
01971                         r.get (x)
01972                          .get (y)
01973                          .get (z);
01974 
01975                         assert (x == "fred");
01976                         assert (y == 10);
01977                         assert (z == true);
01978                 }
01979 
01980                 Payload create ()
01981                 {
01982                         return new Protocol;
01983                 }
01984 
01985                 char[] getGuid ()
01986                 {
01987                         return this.classinfo.name;
01988                 }
01989         }
01990 
01991         Protocol p = new Protocol;
01992 
01993         Buffer b = new Buffer (1024);
01994         ProtocolWriter w = new ProtocolWriter (b);
01995         ProtocolReader r = new ProtocolReader (b);
01996 
01997         w.put (w.Command.Exception, "mychannel", p);
01998 
01999         ubyte   cmd;
02000         char[]  channel,
02001                 element;
02002 
02003         p = cast(Protocol) r.getPayload (channel, element, cmd);
02004 }
02005 
02006 
02007 /*******************************************************************************
02008 
02009 
02010 *******************************************************************************/
02011 
02012 version (Isolated){}
02013 else
02014 {
02015 void testRollingFileLog()
02016 {
02017         Logger l = Logger.getLogger ("test");
02018         l.addAppender (new RollingFileAppender (new FilePath (r"e:\test.log"), 3, 1024, new DateLayout));
02019 
02020         for (int i=100; --i;)
02021              l.error ("weqwer er wer werqwer wer wer wer wr wqrwe qrw rwe rwqerw");
02022 }
02023 }
02024 
02025 
02026 
02027 /******************************************************************************
02028 **************************** Cluster testing **********************************
02029 *******************************************************************************/
02030 
02031 
02032 
02033 /*******************************************************************************
02034 
02035         Join a socket to a multicast group, and send the group a packet.
02036 
02037 *******************************************************************************/
02038 
02039 void testMulticast()
02040 {
02041         class MyListener : SocketListener
02042         {
02043                 this (ISocketReader reader, IBuffer buffer)
02044                 {
02045                         super (reader, buffer);
02046                 }
02047 
02048                 void notify (IBuffer buffer)
02049                 {
02050                         printf ("listener received %d bytes\n", buffer.readable());
02051                 }
02052 
02053                 void exception (char[] msg)
02054                 {
02055                         printf ("listener error: %.*s\n", msg);
02056                 }
02057         }
02058 
02059         //auto MulticastSocket ms = new MulticastSocket ();
02060         MulticastSocket ms = new MulticastSocket ();
02061         InternetAddress ia = new InternetAddress ("226.1.1.1", 4444);
02062 
02063         ms.join (ia);
02064         MyListener s = new MyListener (ms, new Buffer (2000));
02065         s.start ();
02066 
02067         Stdin.wait ();
02068         //s.pause ();
02069         //s.resume ();
02070 
02071         byte[1000] xx;
02072         Buffer b = new Buffer (xx, xx.length);
02073 
02074         ms.write (b, ia);
02075         Stdin.wait ();
02076         //s.cancel ();
02077 }
02078 
02079 /*******************************************************************************
02080 
02081 *******************************************************************************/
02082 
02083 void testClusterCache()
02084 {
02085         //ClusterServer cs = new ClusterServer (new InternetAddress(4567), 1);
02086         //cs.start ();
02087 
02088         //auto FileConduit config = new FileConduit ("cluster.properties");
02089         //Cluster cluster = new Cluster (logger, config);
02090         Cluster cluster = new Cluster (logger, 4567);
02091 
02092         //NetworkCache cc = new NetworkCombo (cluster, "myChannel", new PlainCache);
02093         NetworkCache cc = new NetworkCache (cluster, "myChannel");
02094 
02095         InvalidatorPayload p = new InvalidatorPayload;
02096 
02097             cc.put ("key", p);
02098 //            cc.invalidate ("key");
02099         for (int i=100_000; i; --i)
02100             {
02101 //            p.setText ("fubar");
02102 //            cc.put ("key", p);
02103 //            cc.invalidate ("key");
02104             IPayload p = cc.get ("key");
02105 //            if ((i & 0x3f) == 0)
02106 //                 System.sleep (System.Interval.Second);
02107 /*
02108             p = cast(InvalidatorPayload) cc.get ("key");
02109             assert (p);
02110             assert (p.getText == "fubar");
02111 
02112             cc.invalidate ("key");
02113             p = cast(InvalidatorPayload) cc.get ("key");
02114 */
02115             }
02116         //assert (p is null);
02117 
02118 //        cc.invalidate ("key");
02119 
02120         //Stdin.wait ();
02121 }
02122 
02123 
02124 /*******************************************************************************
02125 
02126 *******************************************************************************/
02127 
02128 void testClusterQueue()
02129 {
02130         class Listen : IEventListener
02131         {
02132                 void notify (IEvent event, IPayload payload)
02133                 {
02134                         printf ("recieved queue entry from channel '%.*s'\n", event.getChannel.getName);
02135                 }
02136         }
02137 
02138         //ClusterServer cs = new ClusterServer (new InternetAddress(4567), 1);
02139         //cs.start ();
02140 
02141         Cluster cluster = new Cluster (logger, 4567);
02142         NetworkQueue queue = new NetworkQueue (cluster, "queue.channel");
02143 
02144         queue.createConsumer (new Listen);
02145         queue.put (new InvalidatorPayload);
02146         queue.put (new InvalidatorPayload);
02147 
02148         Stdin.wait ();
02149 }
02150 
02151 
02152 /*******************************************************************************
02153 
02154 *******************************************************************************/
02155 
02156 void testInvalidatee()
02157 {
02158         ICluster c = new Cluster (logger);
02159 
02160         CacheInvalidatee dst = new CacheInvalidatee (c, "abc", new PlainCache);
02161         CacheInvalidator src = new CacheInvalidator (c, "abc");
02162 
02163         src.invalidate ("key1");
02164 
02165         Stdin.wait ();
02166 }
02167 
02168 
02169 /*******************************************************************************
02170 
02171 
02172 *******************************************************************************/
02173 
02174 void testClusterServer()
02175 {
02176         ClusterServer cs = new ClusterServer (new InternetAddress(81), 1);
02177         SocketConduit sc = new SocketConduit ();
02178         cs.start();
02179 
02180         sc.connect (new InternetAddress ("127.0.0.1", 81));
02181         Stdin.wait ();
02182 }
02183 
02184 
02185 /*******************************************************************************
02186 
02187 
02188 *******************************************************************************/
02189 
02190 
02191 void testClusterMessage()
02192 {
02193         class MessageListener : IEventListener
02194         {
02195                 void notify (IEvent event, IPayload payload)
02196                 {
02197                         IMessage message = cast(IMessage) payload;
02198 
02199                         printf ("Replying to message\n");
02200                         event.reply (message.getReply, new InvalidatorPayload);
02201                 }
02202         }
02203 
02204         class ReplyListener : IEventListener
02205         {
02206                 void notify (IEvent event, IPayload payload)
02207                 {
02208                         printf ("Received reply\n");
02209                 }
02210         }
02211 
02212         //ClusterServer cs = new ClusterServer (new InternetAddress(4567), 1);
02213         //cs.start ();
02214 
02215         // open the cluster
02216         Cluster cluster = new Cluster (logger, 4567);
02217 
02218         // open up a message channel
02219         NetworkMessage msg = new NetworkMessage (cluster, "message.channel", new ReplyListener);
02220 
02221         // setup a listener to receive message (could do this earlier)
02222         msg.createConsumer (new MessageListener);
02223 
02224         // toss a message out to the cluster
02225         msg.put (new NullMessage);
02226 
02227         // wait for traffic to pass by
02228         Stdin.wait ();
02229 }
02230 
02231 
02232 /*******************************************************************************
02233 
02234 
02235 *******************************************************************************/
02236 
02237 void testCacheLoader()
02238 {
02239         class CacheLoader : ICacheLoader
02240         {
02241                 bool test (IPayload p)
02242                 {
02243                         return false;
02244                 }
02245 
02246                 IPayload load (char[] key, long time)
02247                 {
02248                         printf ("loading local cache instance\n");
02249                         return new NullMessage;
02250                 }
02251         }
02252 
02253         IMutableCache mc = new PlainCache;
02254         ICache c = mc.bind (new CacheLoader);
02255 
02256         c.get ("abcde");
02257 }
02258 
02259 
02260 /*******************************************************************************
02261 
02262 
02263 *******************************************************************************/
02264 
02265 void testRemoteCacheLoader()
02266 {
02267         class RemoteCacheLoader : Payload, IRemoteCacheLoader
02268         {
02269                 bool test (IPayload p)
02270                 {
02271                         return false;
02272                 }
02273 
02274                 IPayload load (char[] key, long time)
02275                 {
02276                         printf ("loading remote cache instance\n");
02277                         return new NullMessage;
02278                 }
02279 
02280                 /**********************************************************************
02281 
02282                         Recover the timestamp from the provided reader
02283 
02284                 **********************************************************************/
02285 
02286                 void read (IReader reader)
02287                 {
02288                         super.read (reader);
02289                 }
02290 
02291                 /**********************************************************************
02292 
02293                         Emit our timestamp to the provided writer
02294 
02295                 **********************************************************************/
02296 
02297                 void write (IWriter writer)
02298                 {
02299                         super.write (writer);
02300                 }
02301 
02302                 /***********************************************************************
02303 
02304                         Create a new instance of a payload, and populate it via
02305                         read() using the specified reader
02306 
02307                 ***********************************************************************/
02308 
02309                 Object create (IReader reader)
02310                 {
02311                         Payload r = new RemoteCacheLoader;
02312                         r.read (reader);
02313                         return r;
02314                 }
02315 
02316                 /**********************************************************************
02317 
02318                         Return the guid for this payload. This should be unique
02319                         per payload class, if said class is used in conjunction
02320                         with the clustering facilities. Inspected by the Pickle
02321                         utilitiy classes.
02322 
02323                 **********************************************************************/
02324 
02325                 char[] getGuid ()
02326                 {
02327                         return this.classinfo.name;
02328                 }
02329 
02330 
02331                 uint pause (uint wait)
02332                 {
02333                         return 100_000;
02334                 }
02335         }
02336 
02337         Cluster cluster = new Cluster (logger, 4567);
02338         NetworkCache nc = new NetworkCache (cluster, "my.channel");
02339         IRemoteCacheLoader cl = new RemoteCacheLoader;
02340         ICache c = nc.bind (cl);
02341 
02342         c.get ("abcde");
02343 }
02344 
02345 version (Isolated){}
02346 else
02347 {
02348 /*******************************************************************************
02349 
02350 
02351 *******************************************************************************/
02352 
02353 void testDecoder ()
02354 {
02355         IWriter w = new Writer (new Buffer(100));
02356         IReader r = new Reader (w.getBuffer());
02357         r.setAllocator (new BufferAllocator);
02358 
02359         UConverter cvt = new UConverter("utf16");
02360         w.setEncoder (new StringEncoder16 (cvt));
02361         r.setDecoder (new StringDecoder16 (cvt));
02362 
02363         UString ss = new UString ("hello");
02364 
02365         w (ss);
02366         r (ss);
02367 
02368         Stdout.setEncoder (new StringEncoder16("utf8"));
02369         Stdout (ss) (CR);
02370 }
02371 
02372 /*******************************************************************************
02373 
02374 
02375 *******************************************************************************/
02376 
02377 void testEncoder ()
02378 {
02379         FileConduit fc = new FileConduit("foo.txt", FileStyle.ReadWriteCreate);
02380         IWriter w = new DisplayWriter(fc);
02381         w.setEncoder (new StringEncoder8 ("utf8"));
02382         w.setEncoder (new StringEncoder16 ("utf8"));
02383         w.setEncoder (new StringEncoder32 ("utf8"));
02384         w ("<?xml version='1.0'?>") ("<element") (' ') ("/>") (CR);
02385 }
02386 }
02387 
02388 /*******************************************************************************
02389 
02390 
02391 *******************************************************************************/
02392 
02393 void testTextWriter ()
02394 {
02395         TextWriter output = new TextWriter (Stdout.getBuffer(), ", ");
02396 
02397         ubyte b = 129;
02398         uint ui = uint.max;
02399         int i = -3;
02400 
02401         output.setRadix (output.Radix.Decimal);
02402         output (b) (ui) (i) ("hello") ("test") (CR);
02403 }
02404 
02405 /*******************************************************************************
02406         
02407         Callback for dtoa allocation function
02408 
02409 *******************************************************************************/
02410 /+      
02411 extern (C)
02412 {
02413         int printf (char *format, ...)
02414         {
02415                 Stderr ("invalid call to printf")(CR);
02416                 return 0;
02417         }
02418 }
02419 +/
02420 
02421 /*******************************************************************************
02422 
02423 
02424 *******************************************************************************/
02425 /+
02426 private import mango.format.DGDouble;
02427 
02428 void testConvert ()
02429 {
02430         char[200] s;
02431         char[5] g;
02432         char *zz;
02433         static uint[] ff = [1, 2, 3, 4];
02434         char[] num = "0.12345678+1";
02435 
02436 
02437         double x = Double.parse (num);
02438         double y = std.c.stdlib.strtold (num, &zz);
02439         double z = DGDouble.parse (num);
02440 
02441         
02442         Stdout (Double.format (s, x, 20)) (CR);
02443         Stdout (Double.format (s, y, 20)) (CR);
02444         Stdout (Double.format (s, z, 20)) (CR);
02445         printf ("%.20lf\n", x);
02446         printf ("%.20lf\n", y);
02447         printf ("%.20lf\n", z);
02448         printf ("%.*s\n", DGDouble.format (s, x, 4));
02449         printf ("%.*s\n", DGDouble.format (s, z, 6, true, 0));
02450 }
02451 +/
02452 
02453 /*******************************************************************************
02454 
02455 
02456 *******************************************************************************/
02457 
02458 int main(char[][] args)
02459 {
02460         BasicConfigurator.configure ();
02461         //PropertyConfigurator.configure ("log.properties");
02462         logger = Logger.getLogger ("mango.unittest");
02463         //logger.setLevel (logger.Level.Error);
02464         //logger.addAppender (new FileAppender ("log.txt", new DateLayout));
02465         //logger.addAppender (new ConsoleAppender (new DateLayout));
02466         //logger.addAppender (new DebugAppender (new SimpleTimerLayout));
02467 
02468         try {
02469             //testDisplay();
02470             //testDecoder();
02471             //testTextWriter();
02472             //testHashMap();
02473             //testRemoteCacheLoader();
02474             //testCacheLoader();
02475             //testProtocol();
02476             //testClusterMessage();
02477             //testRollingFileLog();
02478             //testClusterCache();
02479             //testClusterQueue();
02480             //testClusterServer();
02481             //testInvalidatee();
02482             //testMulticast();
02483 
02484             //testAppend();
02485             //testFile4();
02486             //testClassSerialization();
02487             //testFormat();
02488             //testLayout();
02489             //testFileSize();
02490             //testFilePath();
02491             //testFileList();
02492             //testScanFiles();
02493             //testFile1();
02494             //testFile5();
02495             //testToken1();
02496             //testToken2();
02497             //testColumn();
02498             //testSocket();
02499             //testStdin();
02500             //testBuffer();
02501             //testToken3();
02502             //testFileRegex();
02503             //testLineRegex();
02504             //testSocketRegex();
02505             //testRandomAccess();
02506             //testCompositeIO();
02507             //testDirectIO();
02508             //testHttpServer();
02509             //testServletEngine();
02510             //testUri();
02511             //testHttpClient();
02512             //testHttpClient2();
02513             //testHttpClient3();
02514             //testQueuedCache();
02515             //testFileBucket();
02516             //testScanFiles();
02517             //testVirtualCache();
02518             //testQueuedCache();
02519             //testPlainCache();
02520             //testMappedFile();
02521             //testEncoder();
02522             //testClassIO();
02523             //testConvert();
02524             logger.info ("Done");
02525             } catch (Object x)
02526                     {
02527                     logger.fatal (x.toString);
02528                     }
02529 
02530         return 0;
02531 }
02532 

Generated on Sun Mar 6 00:31:00 2005 for Mango by doxygen 1.3.6