00001 /* 00002 * ConfigurationReader.cc 00003 * 00004 * Smalltalk like class library for C++ 00005 * Configuration file reader. 00006 * 00007 * Copyright (c) 2004 Milan Cermak, Petr Stepanek 00008 */ 00009 /* 00010 * This library is free software; you can redistribute it and/or 00011 * modify it under the terms of the GNU Lesser General Public 00012 * License as published by the Free Software Foundation; either 00013 * version 2.1 of the License, or (at your option) any later version. 00014 * 00015 * This library 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 GNU 00018 * Lesser General Public License for more details. 00019 * 00020 * You should have received a copy of the GNU Lesser General Public 00021 * License along with this library; if not, write to the Free Software 00022 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00023 */ 00024 00025 #include <stlib/Character.h> 00026 #include <stlib/EncodedStream.h> 00027 #include <stlib/ExternalReadStream.h> 00028 #include <stlib/GenericException.h> 00029 #include <stlib/ReadStream.h> 00030 #include <stlib/String.h> 00031 #include <stlib/tools/Configuration.h> 00032 #include <stlib/tools/Filename.h> 00033 #include <stlib/tools/FileEncodedStreamFactory.h> 00034 00035 #include <stlib/tools/ConfigurationReader.h> 00036 00037 using namespace Tools; 00038 00039 /* Initialize-release protocol */ 00040 void ConfigurationReader::onFilename(String *filename) 00041 { 00042 stream((new Filename(filename))->withEncoding("default")->readStream()); 00043 } 00044 00045 void ConfigurationReader::onString(String *str) 00046 { 00047 stream(str->readStream()); 00048 } 00049 00050 void ConfigurationReader::stream(Stream *str) 00051 { 00052 _stream = str; 00053 } 00054 00055 /* Accessing protocol */ 00056 void ConfigurationReader::put(String *item, Object *value) 00057 { 00058 _configuration->put(item, value); 00059 } 00060 00061 /* Processing protocol */ 00062 Configuration *ConfigurationReader::readConfiguration(void) 00063 { 00064 return readConfiguration(new Configuration); 00065 } 00066 00067 Configuration *ConfigurationReader::readConfiguration(Configuration *configuration) 00068 { 00069 _configuration = configuration; 00070 _ensure ( 00071 read(), 00072 _stream->close() 00073 ); 00074 00075 return _configuration; 00076 } 00077 00078 void ConfigurationReader::read(void) 00079 { 00080 while (!_stream->atEnd()) { 00081 _stream->skipSeparators(); 00082 readLine(); 00083 } 00084 } 00085 00086 void ConfigurationReader::readLine(void) 00087 { 00088 String *item, *value; 00089 String *line = dynamic_cast<String *>(_stream->nextLine()); 00090 long idx; 00091 00092 line->replaceAll(Character::tab(), Character::space()); 00093 00094 /* Remove comments */ 00095 idx = line->indexOf('#'); 00096 if (idx > 0) line = dynamic_cast<String *>(line->copy(0, idx)); 00097 line = line->trimBlanks(); 00098 if (idx == 0 || line->isEmpty()) return; 00099 00100 /* Parse assignment */ 00101 idx = line->indexOf('='); 00102 if (idx <= 0) return; 00103 00104 item = dynamic_cast<String *>(line->copy(0, idx))->trimBlanks(); 00105 if (item->isEmpty()) return; 00106 00107 if (idx + 1 < line->size()) 00108 value = dynamic_cast<String *>(line->copy(idx + 1, line->size()))->trimBlanks(); 00109 else 00110 value = new String; 00111 put(item, value); 00112 }