xabsl_tools.cpp

00001
00002 /***************************************************************************
00003  *  xabsl_tools.cpp - Tools required for XABSL
00004  *
00005  *  Created: Wed Aug 06 17:25:51 2008
00006  *  Copyright  2006-2008  Tim Niemueller [www.niemueller.de]
00007  *
00008  ****************************************************************************/
00009
00010 /*  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version.
00014  *
00015  *  This program is distributed in the hope that it will be useful,
00016  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  *  GNU Library General Public License for more details.
00019  *
00020  *  Read the full text in the LICENSE.GPL file in the doc directory.
00021  */
00022
00023 #include "xabsl_tools.h"
00024
00025 #include <core/exception.h>
00026 #include <utils/logging/logger.h>
00027
00028 #include <cstdlib>
00029 #include <cstring>
00030 
00031 /** @class XabslLoggingErrorHandler "xabsl_tools.h"
00032  * Logging error handler for XABSL integration.
00033  * Simple error handler that prints errors to the Fawkes log.
00034  * @author Tim Niemueller
00035  */
00036 
00037 /** Constructor.
00038  * @param logger Fawkes logger
00039  */
00040 XabslLoggingErrorHandler::XabslLoggingErrorHandler(fawkes::Logger *logger)
00041 {
00042   __logger = logger;
00043 }
00044
00045 
00046 /** Print error message.
00047  * @param text text of the error message
00048  */
00049 void
00050 XabslLoggingErrorHandler::printError(const char *text)
00051 {
00052   __logger->log_error("XABSL", "%s", text);
00053 }
00054
00055 
00056 /** Print info message.
00057  * @param text text of the info message
00058  */
00059 void
00060 XabslLoggingErrorHandler::printMessage(const char *text)
00061 {
00062   __logger->log_info("XABSL", "%s", text);
00063 }
00064
00065 
00066 /** @class XabslFileInputSource "xabsl_tools.h"
00067  * File input class for Xabsl integration.
00068  * @author Tim Niemueller
00069  */
00070 
00071 /** Constructor.
00072  * @param filename name of the file to read
00073  */
00074 XabslFileInputSource::XabslFileInputSource(const char *filename)
00075 {
00076   __filename = strdup(filename);
00077   __f = NULL;
00078 }
00079
00080 
00081 /** Destructor. */
00082 XabslFileInputSource::~XabslFileInputSource()
00083 {
00084   close();
00085   free(__filename);
00086 }
00087
00088 
00089 /** Open file.
00090  * @return true if file has been opened successfully, false otherwise
00091  */
00092 bool
00093 XabslFileInputSource::open()
00094 {
00095   close();
00096   __f = fopen(__filename, "r");
00097   return (__f != NULL);
00098 }
00099
00100 
00101 /** Close file. */
00102 void
00103 XabslFileInputSource::close()
00104 {
00105   if ( __f )  fclose(__f);
00106   __f = NULL;
00107 }
00108
00109 
00110 /** Read a double value from the file.
00111  * @return value read from the file
00112  */
00113 double
00114 XabslFileInputSource::readValue()
00115 {
00116   char buf[20];
00117   if (read_from_file(buf, sizeof(buf)-1)) {
00118     return atof(buf);
00119   } else {
00120     return 0.;
00121   }
00122 }
00123
00124 
00125 /** Read a string from the file.
00126  * @param buf buffer where the string is stored
00127  * @param buf_length maximum length of the string to be read, warning, this
00128  * method will write one more byte than buf_length. This is done to be compatible
00129  * with broken Xabsl.
00130  */
00131 bool
00132 XabslFileInputSource::readString(char *buf, int buf_length)
00133 {
00134   return read_from_file(buf, buf_length);
00135 }
00136
00137 
00138 /** Omit comments. */
00139 void
00140 XabslFileInputSource::omit_comment()
00141 {
00142   while ( !feof(__f) ) {
00143     char c;
00144     if (fread(&c, 1, 1, __f)) {
00145       if ( c == '\n')  return;
00146     } else {
00147       return;
00148     }
00149   }
00150 }
00151 
00152 /** Read and possibly omit whitespace.
00153  * @param omit_whitespace if true whitespace is omitted
00154  * @return first char read or 0 on error
00155  */
00156 char
00157 XabslFileInputSource::read_and_omit_whitespace(bool omit_whitespace)
00158 {
00159   while ( ! feof(__f) ) {
00160     char c;
00161     if (fread(&c, 1, 1, __f)) {
00162       if ( c == '/' ) {
00163         omit_comment();
00164         continue;
00165       }
00166       if ( (c != ' ') && (c != '\n') && (c != '\r') && (c != '\t') ) {
00167         return c;
00168       } else if ( ! omit_whitespace ) {
00169         return 0;
00170       }
00171     } else {
00172       throw fawkes::Exception ("XabslFileInputSource: omit_whitespace() fread failed");
00173     }
00174   }
00175
00176   return 0;
00177 }
00178 
00179 /** Read bytes from file.
00180  * @param buf buffer where the string is stored
00181  * @param buf_length maximum length of the string to be read, warning, this
00182  * method will write one more byte than buf_length. This is done to be compatible
00183  * with broken Xabsl.
00184  * @return true if anything was read from the file, false if nothing has been read
00185  */
00186 bool
00187 XabslFileInputSource::read_from_file(char *buf, size_t buf_length)
00188 {
00189   if ( ! __f || feof(__f) )  return false;
00190
00191   memset(buf, 0, buf_length);
00192   size_t cur_length = 0;
00193   bool is_first = true;
00194   while (! feof(__f) && (cur_length < buf_length)) {
00195     char c = read_and_omit_whitespace(is_first);
00196     is_first = false;
00197     if (c) {
00198       buf[cur_length++] = c;
00199       buf[cur_length] = 0;
00200     } else {
00201       return (cur_length > 0);
00202     }
00203   }
00204
00205   return (cur_length > 0);
00206 }