// configimpl.cpp
//
// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Matthew Flood
// See file AUTHORS for contact information
//
// This file is part of RudeConfig.
//
// RudeConfig is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or (at your option)
// any later version.
//
// RudeConfig is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with RudeConfig; (see COPYING) if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
//------------------------------------------------------------------------
#include "ConfigImpl.h"
#ifndef INCLUDED_Section_H
#include "Section.h"
#endif
#ifndef INCLUDED_File_H
#include "File.h"
#endif
#ifndef INCLUDED_Writer_H
#include "Writer.h"
#endif
#ifndef INPUT_RealOrganiser_h
#include "RealOrganiser.h"
#endif
#ifndef INPUT_ParserJuly2004_h
#include "ParserJuly2004.h"
#endif
#ifndef INCLUDED_BASE64ENCODER_H
#include "Base64Encoder.h"
#endif
#ifndef INCLUDED_CSTDIO
#include <cstdio>
#define INCLUDED_CSTDIO
#endif
#ifndef INCLUDED_CSTDLIB
#include <cstdlib>
#define INCLUDED_CSTDLIB
#endif
#ifndef INCLUDED_IOSTREAM
#include <iostream>
#define INCLUDED_IOSTREAM
#endif
#ifndef INCLUDED_FSTREAM
#include <fstream>
#define INCLUDED_FSTREAM
#endif
using namespace std;
namespace rude{
namespace config{
// STATIC DATA
//
std::string ConfigImpl::s_defaultConfigFile = "default.ini";
char ConfigImpl::s_defaultCommentChar = '#';
char ConfigImpl::s_defaultDelimiter = '=';
bool ConfigImpl::s_defaultPreserveDeleted = false;
bool ConfigImpl::s_defaultAllowDuplicate = false;
bool ConfigImpl::s_defaultIgnoreCase = false;
std::string ConfigImpl::s_returnValue="";
//////////////////////////////////////
// STATIC METHODS
//////////////////////////////////////
const char *ConfigImpl::version()
{
return "0";
}
void ConfigImpl::setDefaultConfigFile(const char *filepath)
{
s_defaultConfigFile = filepath ? filepath : "default.ini";
}
const char *ConfigImpl::getDefaultConfigFile()
{
return s_defaultConfigFile.c_str();
}
void ConfigImpl::setDefaultCommentCharacter(char c)
{
s_defaultCommentChar = c;
}
char ConfigImpl::getDefaultCommentCharacter()
{
return s_defaultCommentChar;
}
void ConfigImpl::setDefaultDelimiter(char c)
{
s_defaultDelimiter = c;
}
char ConfigImpl::getDefaultDelimiter()
{
return s_defaultDelimiter;
}
void ConfigImpl::setDefaultPreserveDeleted(bool shouldPreserve)
{
s_defaultPreserveDeleted = shouldPreserve;
}
bool ConfigImpl::getDefaultPreserveDeleted()
{
return s_defaultPreserveDeleted;
}
void ConfigImpl::setDefaultIgnoreCase(bool shouldIgnore)
{
s_defaultIgnoreCase = shouldIgnore;
}
void ConfigImpl::setDefaultAllowDuplicateKeys(bool shouldAllow)
{
s_defaultAllowDuplicate = shouldAllow;
}
// STATIC DATA CONVERSION
//
bool ConfigImpl::stringToBool(const char *value)
{
if(value)
{
// Values that mean true:
// yes, on, true, 1
// [yY]*, [oO][nN]*, O*, [Tt]*, 1
// Values that mean false:
// no, off, false, 0
switch(value[0])
{
case 't':
return true;
case 'T':
return true;
case 'y':
return true;
case 'Y':
return true;
case '1':
return true;
case 'o':
if(value[1] == 'n' || value[1] == 'N')
{
// since value[0] was not null, we can rest assured that there is a value[1] -
// it is at least the null string terminator!
return true;
}
break;
case 'O':
if(value[1] == 'n' || value[1] == 'N')
{
return true;
}
break;
default:
return false;
}
}
return false;
}
const char *ConfigImpl::boolToString(bool value)
{
return (value ? "true" : "false");
}
int ConfigImpl::stringToInt(const char *string)
{
if(string)
{
return atoi(string);
}
return 0;
}
const char *ConfigImpl::intToString(int value)
{
char myint[25];
sprintf(myint, "%i", value);
s_returnValue = myint;
return s_returnValue.c_str();
}
double ConfigImpl::stringToDouble(const char *string)
{
if(string)
{
return atof(string);
}
return 0;
}
const char *ConfigImpl::doubleToString(double value)
{
char mydouble[25];
sprintf(mydouble, "%g", value);
s_returnValue = mydouble;
return s_returnValue.c_str();
}
char * ConfigImpl::stringToBinary(const char *value, int &outlength)
{
// Base64Encoder USAGE:
// static char * decode(const char *data, int datalength, int &outlength);
if(value)
{
int datalength=strlen(value);
return Base64Encoder::decode(value, datalength, outlength);
}
outlength=0;
return 0;
}
const char *ConfigImpl::binaryToString(const char *value, int length)
{
// Base64Encoder USAGE:
// static char * encode(const char *data, int datalength, int &outlength);
if(value)
{
int outlength;
s_returnValue = Base64Encoder::encode(value, length, outlength);
}
else
{
s_returnValue = "";
}
return s_returnValue.c_str();
}
//////////////////////////////////////
// INSTANCE METHODS
//////////////////////////////////////
///////////////////////////
// CONSTRUCTOR & DESTRUCTOR
///////////////////////////
ConfigImpl::ConfigImpl()
{
d_file = new File();
// Create the appropriate Objects here,
// all other methods interact with
// the base class interfaces
//
d_writer = new Writer();
d_parser = new ParserJuly2004();
d_error="";
d_errorcode="";
d_commentcharacter = s_defaultCommentChar;
d_delimiter = s_defaultDelimiter;
d_configfile = s_defaultConfigFile;
d_preserveDeleted = s_defaultPreserveDeleted;
d_allowDuplicate = s_defaultAllowDuplicate;
d_ignoreCase = s_defaultIgnoreCase;
}
ConfigImpl::~ConfigImpl()
{
delete d_writer;
delete d_parser;
delete d_file;
}
////////////
// STATUS
////////////
void ConfigImpl::setError(const char *errorcode, const char *errorstring)
{
d_errorcode = errorcode ? errorcode : "";
d_error = errorstring ? errorstring : "";
}
const char *ConfigImpl::getError() const
{
return d_error.c_str();
}
const char *ConfigImpl::getErrorCode() const
{
return d_errorcode.c_str();
}
//////////////////////
// INSTANCE BEHAVIOR
//////////////////////
void ConfigImpl::setConfigFile(const char *filepath)
{
d_configfile = filepath ? filepath : s_defaultConfigFile.c_str();
}
const char * ConfigImpl::getConfigFile()
{
return d_configfile.c_str();
}
void ConfigImpl::setCommentCharacter(char c)
{
d_commentcharacter = c;
}
void ConfigImpl::setDelimiter(char c)
{
d_delimiter = c;
}
void ConfigImpl::preserveDeletedData(bool shouldPreserve)
{
d_preserveDeleted = shouldPreserve;
}
void ConfigImpl::ignoreCase(bool shouldIgnore)
{
d_ignoreCase = shouldIgnore;
}
void ConfigImpl::allowDuplicateKeys(bool shouldAllow)
{
d_allowDuplicate = shouldAllow;
}
//////////////////////////////
// LOADING & SAVING & CLEARING
//////////////////////////////
bool ConfigImpl::load()
{
// forward to load(filepath)
//
return load(d_configfile.c_str());
}
bool ConfigImpl::load(const char *filepath)
{
if(filepath && filepath[0])
{
d_configfile=filepath;
std::ifstream infile(filepath);
if(infile)
{
// forward to load(std::istream&)
bool retval = load(infile);
infile.close();
return retval;
}
else
{
setError("2001", "Error opening config file for reading");
return false;
}
}
else
{
return load(std::cin);
}
}
bool ConfigImpl::load(std::istream& inputstream)
{
d_parser->setCommentCharacter(d_commentcharacter);
d_parser->setDelimiter(d_delimiter);
RealOrganiser organiser(d_file);
if(d_parser->parse(inputstream, organiser))
{
setSection("");
return true;
}
else
{
setSection("");
setError(d_parser->getErrorCode(), d_parser->getError());
return false;
}
}
bool ConfigImpl::save()
{
// forward to save(filepath)
//
return save(d_configfile.c_str());
}
bool ConfigImpl::save(const char *filepath)
{
if(filepath && filepath[0] != 0)
{
ofstream outstream(filepath);
if(outstream)
{
// forward to save(std::ostream&)
//
bool retval = save(outstream);
outstream.close();
return retval;
}
else
{
setError("2002", "Error opening config file for writing");
return false;
}
}
else
{
return save(std::cout);
}
}
bool ConfigImpl::save(std::ostream& outstream)
{
d_writer->setOutputStream(outstream);
d_writer->setCommentChar(d_commentcharacter);
d_writer->setDelimiter(d_delimiter);
d_writer->preserveDeleted(d_preserveDeleted);
d_file->acceptWriter(*d_writer);
return true;
}
void ConfigImpl::clear()
{
d_file->clear();
}
//////////////////
// SECTION METHODS
//////////////////
int ConfigImpl::getNumSections() const
{
return d_file->getNumSections();
}
const char *ConfigImpl::getSectionNameAt(int index) const
{
return d_file->getSectionNameAt(index);
}
bool ConfigImpl::setSection(const char *sectionname, bool shouldCreate)
{
return d_file->setSection(sectionname, shouldCreate);
}
bool ConfigImpl::setSection(const char *sectionname)
{
return d_file->setSection(sectionname, true);
}
bool ConfigImpl::deleteSection(const char *sectionname)
{
return d_file->deleteSection(sectionname);
}
////////////////
// DATA METHODS
////////////////
int ConfigImpl::getNumDataMembers() const
{
return d_file->getNumDataMembers();
}
const char *ConfigImpl::getDataNameAt(int index) const
{
return d_file->getDataNameAt(index);
}
const char *ConfigImpl::getDataValueAt(int index) const
{
return d_file->getDataValueAt(index);
}
bool ConfigImpl::exists(const char *name) const
{
return d_file->exists(name);
}
const char * ConfigImpl::getStringValue(const char *name) const
{
return d_file->getStringValue(name);
}
void ConfigImpl::setStringValue(const char *name, const char *value)
{
d_file->setStringValue(name, value);
}
bool ConfigImpl::deleteData(const char *name)
{
return d_file->deleteData(name);
}
///////////////////////////////
// Working with Duplicate Keys
// NOT IMPLEMENTED YET
///////////////////////////////
int ConfigImpl::getNumDataMembers(const char *key) const
{
if(exists(key))
{
return 1;
}
else
{
return 0;
}
}
const char * ConfigImpl::getStringValue(const char *name, int index) const
{
return d_file->getStringValue(name);
}
void ConfigImpl::addStringValue(const char *name, const char *value)
{
d_file->setStringValue(name, value);
}
bool ConfigImpl::deleteData(const char *name, int index)
{
return d_file->deleteData(name);
}
}}// end namespace rude::config
syntax highlighted by Code2HTML, v. 0.9.1