blocxx

Format.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002 * Copyright (C) 2005, Vintela, Inc. All rights reserved.
00003 * Copyright (C) 2006, Novell, Inc. All rights reserved.
00004 * 
00005 * Redistribution and use in source and binary forms, with or without
00006 * modification, are permitted provided that the following conditions are met:
00007 * 
00008 *     * Redistributions of source code must retain the above copyright notice,
00009 *       this list of conditions and the following disclaimer.
00010 *     * Redistributions in binary form must reproduce the above copyright
00011 *       notice, this list of conditions and the following disclaimer in the
00012 *       documentation and/or other materials provided with the distribution.
00013 *     * Neither the name of 
00014 *       Vintela, Inc., 
00015 *       nor Novell, Inc., 
00016 *       nor the names of its contributors or employees may be used to 
00017 *       endorse or promote products derived from this software without 
00018 *       specific prior written permission.
00019 * 
00020 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00021 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00022 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00023 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00024 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00025 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00026 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00027 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00028 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00029 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00030 * POSSIBILITY OF SUCH DAMAGE.
00031 *******************************************************************************/
00032 
00033 
00038 #include "blocxx/BLOCXX_config.h"
00039 #include "blocxx/Format.hpp"
00040 
00041 namespace BLOCXX_NAMESPACE
00042 {
00043 
00045 Format::operator String() const
00046 {
00047    return oss.toString();
00048 }
00050 String Format::toString() const
00051 {
00052    return oss.toString();
00053 }
00055 const char* Format::c_str() const
00056 {
00057    return oss.c_str();
00058 }
00060 char Format::process(String& str, char numArgs)
00061 {
00062    int len(str.length());
00063    char c(' ');
00064    bool err = false;
00065    int i = 0;
00066    while (i < len && c == ' ' && !err)
00067    {
00068       switch (str[i])
00069       {
00070          case '%':
00071             if (i + 1 < len)
00072             {
00073                ++i;
00074                switch (str[i])
00075                {
00076                   case '1': case '2': case '3': case '4': case '5': 
00077                   case '6': case '7': case '8': case '9':
00078                      c = str[i]; 
00079                      break;
00080                   case '%': 
00081                      oss << str[i]; 
00082                      break;
00083                   default: 
00084                      err = true;
00085                } // inner switch
00086             } else err = true; 
00087             break;
00088          default: 
00089             oss << str[i];
00090             break;
00091       } // outer switch
00092       ++i;
00093    } // for
00094    if ( i <= len && c > numArgs )
00095    {
00096       oss << "\n*** Parameter specifier too large.";
00097       err = true;
00098    }
00099    if (err)
00100    {
00101       oss << "\n*** Error in format string at \"" << str.substring(i-1) << "\".\n";
00102       str.erase();
00103       return '0';
00104    }
00105    str.erase(0, i);
00106    return c;
00107 } // process
00109 std::ostream&
00110 operator<<(std::ostream& os, const Format& f)
00111 {
00112    os.write(f.oss.c_str(), f.oss.length());
00113    return os;
00114 }
00116 void Format::put(const String& t)
00117 { // t is inserted into oss
00118    if (!oss.good())
00119    {
00120       return;
00121    }
00122    oss << t;
00123 }
00125 #define BLOCXX_DEFINE_PUT(type) \
00126 void Format::put(type t) \
00127 { \
00128 \
00129    if (!oss.good()) \
00130    { \
00131       return; \
00132    } \
00133 \
00134    oss << t; \
00135 }
00136 BLOCXX_DEFINE_PUT(char);
00137 BLOCXX_DEFINE_PUT(unsigned char);
00138 BLOCXX_DEFINE_PUT(short);
00139 BLOCXX_DEFINE_PUT(unsigned short);
00140 BLOCXX_DEFINE_PUT(int);
00141 BLOCXX_DEFINE_PUT(unsigned int);
00142 BLOCXX_DEFINE_PUT(long);
00143 BLOCXX_DEFINE_PUT(unsigned long);
00144 BLOCXX_DEFINE_PUT(long long);
00145 BLOCXX_DEFINE_PUT(unsigned long long);
00146 #undef BLOCXX_DEFINE_PUT
00147 
00148 Format::Format(const char* ca, const String& a) : oss()
00149 {
00150    String fmt(ca);
00151    while (!fmt.empty())
00152    {
00153       switch (process(fmt, '1'))
00154       {
00155          case '1': put(a); break;
00156       }
00157    }
00158 }
00159 Format::Format(const char* ca, const String& a, const String& b) : oss()
00160 {
00161    String fmt(ca);
00162    while (!fmt.empty())
00163    {
00164       switch (process(fmt, '2'))
00165       {
00166          case '1': put(a); break;
00167          case '2': put(b); break;
00168       }
00169    }
00170 }
00171 Format::Format(const char* ca, const String& a, const String& b, const String& c) : oss()
00172 {
00173    String fmt(ca);
00174    while (!fmt.empty())
00175    {
00176       switch (process(fmt, '3'))
00177       {
00178          case '1': put(a); break;
00179          case '2': put(b); break;
00180          case '3': put(c); break;
00181       }
00182    }
00183 }
00184 
00185 } // end namespace BLOCXX_NAMESPACE
00186