JWS C++ Library
C++ language utility library
readable.cpp
Go to the documentation of this file.
00001 /*
00002  * This work is licensed under a Creative Commons 
00003  * Attribution-Noncommercial-Share Alike 3.0 United States License.
00004  * 
00005  *    http://creativecommons.org/licenses/by-nc-sa/3.0/us/
00006  * 
00007  * You are free:
00008  * 
00009  *    to Share - to copy, distribute, display, and perform the work
00010  *    to Remix - to make derivative works
00011  * 
00012  * Under the following conditions:
00013  * 
00014  *    Attribution. You must attribute the work in the manner specified by the
00015  *    author or licensor (but not in any way that suggests that they endorse you
00016  *    or your use of the work).
00017  * 
00018  *    Noncommercial. You may not use this work for commercial purposes.
00019  * 
00020  *    Share Alike. If you alter, transform, or build upon this work, you may
00021  *    distribute the resulting work only under the same or similar license to
00022  *    this one.
00023  * 
00024  * For any reuse or distribution, you must make clear to others the license
00025  * terms of this work. The best way to do this is by including this header.
00026  * 
00027  * Any of the above conditions can be waived if you get permission from the
00028  * copyright holder.
00029  * 
00030  * Apart from the remix rights granted under this license, nothing in this
00031  * license impairs or restricts the author's moral rights.
00032  */
00033 
00034 
00046 #include <jwsc++/config.h>
00047 
00048 #include <iostream>
00049 #include <sstream>
00050 #include <fstream>
00051 #include <cctype>
00052 #include <cstring>
00053 
00054 #include <jwsc++/base/exception.h>
00055 #include <jwsc++/base/readable.h>
00056 
00057 #ifdef JWSCXX_HAVE_DMALLOC
00058 #include <dmalloc.h>
00059 #endif
00060 
00061 
00062 using namespace jwscxx::base;
00063 
00064 
00071 void Readable::read(const char* fname) throw (jwscxx::base::IO_error,
00072         jwscxx::base::Arg_error)
00073 {
00074     std::ifstream in;
00075     std::ostringstream ost;
00076 
00077     in.open(fname);
00078     if (in.fail())
00079     {
00080         ost << fname << ": Could not open file";
00081         throw IO_error(ost.str());
00082     }
00083 
00084     try
00085     {
00086         read(in);
00087     }
00088     catch (IO_error e)
00089     {
00090         ost << fname << ": " << e.get_msg();
00091         throw IO_error(ost.str());
00092     }
00093 
00094     in.close();
00095     if (in.fail())
00096     {
00097         ost << fname << ": Could not close file";
00098         throw IO_error(ost.str());
00099     }
00100 }
00101 
00102 
00129 const char* Readable::read_field_value
00130 (
00131     std::istream& in,
00132     const char*   field_name, 
00133     char*         field_buf,
00134     size_t        buf_len,
00135     char          separator
00136 ) 
00137 throw (jwscxx::base::Arg_error, jwscxx::base::IO_error)
00138 {
00139     using std::ostringstream;
00140     using std::isspace;
00141     using std::strlen;
00142     using std::strncmp;
00143 
00144     in.getline(field_buf, buf_len);
00145     if (in.fail()) 
00146     {
00147         throw IO_error("Could not read field line");
00148     }
00149 
00150     const char* field_ptr = field_buf;
00151 
00152     while (isspace(*field_ptr) && *field_ptr != 0)
00153     {
00154         field_ptr++;
00155     }
00156 
00157     if (strncmp(field_ptr, field_name, strlen(field_name)) != 0)
00158     {
00159         ostringstream ost;
00160         ost << "Field name '" << field_name << "' not found in '" 
00161             << field_buf << "'";
00162         throw Arg_error(ost.str());
00163     }
00164 
00165     while (*field_ptr != separator && *field_ptr != 0)
00166     {
00167         field_ptr++;
00168     }
00169 
00170     if (*field_ptr == 0)
00171     {
00172         ostringstream ost;
00173         ost << "Field '" << field_buf << "' improperly formatted";
00174         throw Arg_error(ost.str());
00175     }
00176 
00177     field_ptr++;
00178 
00179     while (isspace(*field_ptr) && *field_ptr != 0)
00180     {
00181         field_ptr++;
00182     }
00183 
00184     if (*field_ptr == 0)
00185         return 0;
00186 
00187     return field_ptr;
00188 }
00189 
00190 
00216 const char* Readable::read_field_value
00217 (
00218     std::istream& in,
00219     const char*   field_name, 
00220     char          separator
00221 ) 
00222 throw (jwscxx::base::Arg_error, jwscxx::base::IO_error)
00223 {
00224     // TODO This is not thread-safe.
00225     static char field_buf[256] = {0};
00226 
00227     return read_field_value(in, field_name, field_buf, 256, separator);
00228 }