PLearn 0.1
PStreamBufTest.cc
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // PStreamBufTest.cc
00004 //
00005 // Copyright (C) 2005 Nicolas Chapados
00006 // Copyright (C) 2005 Olivier Delalleau 
00007 // 
00008 // Redistribution and use in source and binary forms, with or without
00009 // modification, are permitted provided that the following conditions are met:
00010 // 
00011 //  1. Redistributions of source code must retain the above copyright
00012 //     notice, this list of conditions and the following disclaimer.
00013 // 
00014 //  2. Redistributions in binary form must reproduce the above copyright
00015 //     notice, this list of conditions and the following disclaimer in the
00016 //     documentation and/or other materials provided with the distribution.
00017 // 
00018 //  3. The name of the authors may not be used to endorse or promote
00019 //     products derived from this software without specific prior written
00020 //     permission.
00021 // 
00022 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
00023 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00024 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
00025 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00026 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
00027 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00028 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00029 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00030 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00031 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00032 // 
00033 // This file is part of the PLearn library. For more information on the PLearn
00034 // library, go to the PLearn Web site at www.plearn.org
00035 
00036 /* *******************************************************      
00037    * $Id: .pyskeleton_header 544 2003-09-01 00:05:31Z plearner $ 
00038    ******************************************************* */
00039 
00040 // Authors: Nicolas Chapados, Olivier Delalleau
00041 
00045 #include "PStreamBufTest.h"
00046 #include <iostream>
00047 #include <string>
00048 #include <plearn/io/openString.h>
00049 #include <plearn/io/StringPStreamBuf.h>
00050 
00051 
00052 namespace PLearn {
00053 using namespace std;
00054 
00055 PLEARN_IMPLEMENT_OBJECT(
00056     PStreamBufTest,
00057     "Test the different PStreamBuf implementations.",
00058     ""
00059 );
00060 
00062 // PStreamBufTest //
00064 PStreamBufTest::PStreamBufTest() 
00065     /* ### Initialize all fields to their default value */
00066 {
00067     // ...
00068 
00069     // ### You may (or not) want to call build_() to finish building the object
00070     // ### (doing so assumes the parent classes' build_() have been called too
00071     // ### in the parent classes' constructors, something that you must ensure)
00072 }
00073 
00075 // build //
00077 void PStreamBufTest::build()
00078 {
00079     inherited::build();
00080     build_();
00081 }
00082 
00084 // makeDeepCopyFromShallowCopy //
00086 void PStreamBufTest::makeDeepCopyFromShallowCopy(CopiesMap& copies)
00087 {
00088     inherited::makeDeepCopyFromShallowCopy(copies);
00089 
00090     // ### Call deepCopyField on all "pointer-like" fields 
00091     // ### that you wish to be deepCopied rather than 
00092     // ### shallow-copied.
00093     // ### ex:
00094     // deepCopyField(trainvec, copies);
00095 
00096     // ### Remove this line when you have fully implemented this method.
00097     PLERROR("PStreamBufTest::makeDeepCopyFromShallowCopy not fully (correctly) implemented yet!");
00098 }
00099 
00101 // declareOptions //
00103 void PStreamBufTest::declareOptions(OptionList& ol)
00104 {
00105     // ### Declare all of this object's options here
00106     // ### For the "flags" of each option, you should typically specify  
00107     // ### one of OptionBase::buildoption, OptionBase::learntoption or 
00108     // ### OptionBase::tuningoption. Another possible flag to be combined with
00109     // ### is OptionBase::nosave
00110 
00111     // ### ex:
00112     // declareOption(ol, "myoption", &PStreamBufTest::myoption, OptionBase::buildoption,
00113     //               "Help text describing this option");
00114     // ...
00115 
00116     // Now call the parent class' declareOptions
00117     inherited::declareOptions(ol);
00118 }
00119 
00121 // build_ //
00123 void PStreamBufTest::build_()
00124 {
00125     // ### This method should do the real building of the object,
00126     // ### according to set 'options', in *any* situation. 
00127     // ### Typical situations include:
00128     // ###  - Initial building of an object from a few user-specified options
00129     // ###  - Building of a "reloaded" object: i.e. from the complete set of all serialised options.
00130     // ###  - Updating or "re-building" of an object after a few "tuning" options have been modified.
00131     // ### You should assume that the parent class' build_() has already been called.
00132 }
00133 
00135 void test(const char* test_name, const std::string actual, const std::string expected)
00136 {
00137     if (actual != expected)
00138         std::cout << test_name << ": expected '" << expected
00139                   << "', got '" << actual << "'" << std::endl;
00140 }
00141 
00142 
00144 static std::string char_string(int c)
00145 {
00146     char string_template[] = { '\'', '!', '\'', '\0' };
00147     if (c == EOF)
00148         return "EOF";
00149     else {
00150         string_template[1] = c;
00151         return std::string(string_template);
00152     }
00153 }
00154 
00156 static void test(const char* test_name, const int actual, const int expected)
00157 {
00158     if (actual != expected)
00159         std::cout << test_name << ": expected " << char_string(expected)
00160                   << ", got " << char_string(actual) << "" << std::endl;
00161 }
00162 
00163 void test_read() {
00164     const std::string str = "abcdefghijklmnopqrstuvwxyz";
00165     PLearn::PStream s = PLearn::openString(str, PLearn::PStream::raw_ascii);
00166 
00167     const unsigned int inbuf_size = 6;
00168     const unsigned int outbuf_size = 5;
00169     const unsigned int ungetbuf_size = 4;
00170     s.setBufferCapacities(inbuf_size, outbuf_size, ungetbuf_size);
00171 
00172     test("Read a single char", s.get(), 'a');
00173 
00174     std::string temp;
00175   
00176     s.read(temp, 2);
00177     test("Read a couple of chars", temp, "bc");
00178 
00179     s.read(temp, inbuf_size - 2);
00180     test("Read enough to force a buffer refill", temp, "defg");
00181 
00182     s.read(temp, inbuf_size);
00183     test("Read a whole inbuf_size", temp, "hijklm");
00184 
00185     s.read(temp, inbuf_size + 2);
00186     test("Read a whole inbuf_size, and then some", temp, "nopqrstu");
00187 
00188     test("Peek", s.peek(), 'v');
00189 
00190     //test("Conversion to bool, not on EOF", bool(s), 1);//DEPRECATED
00191     test("stream.good(), not on EOF", s.good(), 1);
00192   
00193     s.putback('U');
00194     test("Putback of a single char", s.get(), 'U');
00195 
00196     s.unread("RSTu");
00197     s.read(temp, 5);
00198     test("Unread of 4 chars", temp, "RSTuv");
00199 
00200     s.read(temp, 4);
00201     test("Read rest of string", temp, "wxyz");
00202 
00203     test("EOF", s.get(), EOF);
00204 
00205     s.read(temp, 10);
00206     test("EOF, reading into a string", temp, "");
00207 
00208     //test("Conversion to bool on EOF", bool(s), 0);//DEPRECATED
00209     test("stream.good() on EOF", s.good(), 0);
00210   
00211     test("EOF, second time", s.get(), EOF);
00212 
00213     s.unread("1234");
00214     s.read(temp, 8);
00215     test("Unread after EOF", temp, "1234");
00216 
00217     // Test bug fixed in r8087 when reading a quoted string whose last
00218     // character is also the last quote.
00219     string quoted_str("\"123\"");
00220     s = PLearn::openString(quoted_str, PLearn::PStream::plearn_ascii);
00221     s >> temp;
00222     test("EOF at end of quoted string", s.peek(), EOF);
00223 }
00224 
00225 
00226 void test_write()
00227 {
00228     std::string str;
00229     PLearn::PStream s = PLearn::openString(str, PLearn::PStream::raw_ascii, "a");
00230 
00231     const unsigned int inbuf_size = 6;
00232     const unsigned int outbuf_size = 5;
00233     const unsigned int ungetbuf_size = 4;
00234     s.setBufferCapacities(inbuf_size, outbuf_size, ungetbuf_size);
00235 
00236     s.put('a');
00237     test("Write a single char", str, "");
00238 
00239     s.write("bcd");
00240     test("Write a couple of chars", str, "");
00241 
00242     s.write("ef");
00243     test("Write to overflow the outbuf", str, "abcde");
00244 
00245     s.flush();
00246     test("Flush", str, "abcdef");
00247 
00248     s.write("ghijk");
00249     test("Write a outbuf size chunk", str, "abcdef");
00250 
00251     s.flush();
00252     test("Flush of full buffer", str, "abcdefghijk");
00253 
00254     s.write("lmnopqrs");
00255     test("Write more than outbuf size", str, "abcdefghijklmnop");
00256 
00257     s.write("tuvwxyzABCDE");
00258     test("Write more than two outbuf size", str, "abcdefghijklmnopqrstuvwxyzABCDE");
00259 
00260     s.flush();
00261     test("Flush on empty buffer", str, "abcdefghijklmnopqrstuvwxyzABCDE");
00262 
00263     s.write("FGHIJK");
00264     test("Write outbuf size plus one", str, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJ");
00265 
00266     s.flush();
00267     test("Another flush", str, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJK");
00268 
00269     s.write("LMNOP");
00270     test("Fill up the buffer...", str, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJK");
00271 
00272     s.put('Q');
00273     test("... and put a single char", str, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP");
00274 }
00275 
00276 void test_write_unbuffered()
00277 {
00278     std::string str;
00279     PLearn::PStream s = PLearn::openString(str, PLearn::PStream::raw_ascii, "w");
00280 
00281     const unsigned int inbuf_size = 6;
00282     const unsigned int outbuf_size = 0;
00283     const unsigned int ungetbuf_size = 4;
00284     s.setBufferCapacities(inbuf_size, outbuf_size, ungetbuf_size);
00285 
00286     s.write("abc");
00287     test("Write a short string (unbuffered)", str, "abc");
00288 
00289     s.write("defghijklm");
00290     test("Write a longer string (unbuffered)", str, "abcdefghijklm");
00291 
00292     s.flush();
00293     test("Flush (unbuffered)", str, "abcdefghijklm");  
00294 }
00295 
00296 void test_negchar()
00297 {
00298     std::string str;
00299     PLearn::PStream s = PLearn::openString(str, PLearn::PStream::raw_ascii, "w");
00300 
00301     const unsigned int inbuf_size = 6;
00302     const unsigned int outbuf_size = 0;
00303     const unsigned int ungetbuf_size = 4;
00304     s.setBufferCapacities(inbuf_size, outbuf_size, ungetbuf_size);
00305 
00306     s.write("\xff");
00307     test("Write a single 'negative' character", str, "\xff");
00308 }
00309 
00311 // perform //
00313 void PStreamBufTest::perform()
00314 {
00315     using std::cerr;
00316     using std::endl;
00317 
00318     try {
00319         test_read();
00320         test_write();
00321         test_write_unbuffered();
00322         test_negchar();
00323     }
00324     catch (const PLearn::PLearnError& e) {
00325         cerr << "PLearnError: " << e.message() << endl;
00326     }
00327 }
00328 
00329 } // end of namespace PLearn
00330 
00331 
00332 /*
00333   Local Variables:
00334   mode:c++
00335   c-basic-offset:4
00336   c-file-style:"stroustrup"
00337   c-file-offsets:((innamespace . 0)(inline-open . 0))
00338   indent-tabs-mode:nil
00339   fill-column:79
00340   End:
00341 */
00342 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines