insert code for reading double numbers from ini-file

Fork of IniFileLib by rinosh 2

Files at this revision

API Documentation at this revision

Comitter:
rinosh2
Date:
Tue Nov 16 16:34:45 2010 +0000
Child:
1:3601c7feb547
Commit message:

Changed in this revision

IniFile.cpp Show annotated file Show diff for this revision Revisions of this file
IniFile.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IniFile.cpp	Tue Nov 16 16:34:45 2010 +0000
@@ -0,0 +1,139 @@
+///////////////////////////////////////////////////////////////////////////////
+// IniFile: .ini file parser    by rinos 2010
+///////////////////////////////////////////////////////////////////////////////
+
+#include "IniFile.h"
+#include <string.h>
+#include <stdlib.h>
+
+////////////////////////////////////////////////////////////////////////////////
+// defines
+const char	INI_DELIM[] = " \t\r\n";
+const int	INI_LINE_BUF= 256;
+
+////////////////////////////////////////////////////////////////////////////////
+// IniFile
+IniFile::IniFile(const char* file): m_fp(0) {
+	if(file) open(file);
+}
+IniFile::~IniFile(){
+	close();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// internal funcs
+IniFile::Status IniFile::strtrim(char* dst, const char* src, int dst_size){
+	if(!dst_size) return S_BUFFER_TOO_SHORT; // myStrcpy needs more than 1 byte for '\0'.
+	
+	// Find valid string area
+	const char* p1 =     strchr (src,  '"');
+	const char* p2 = p1? strrchr(++p1, '"') : 0;
+	if(!p2){
+		// trim space or tab
+		for(p1 = src ; *p1 && strchr(INI_DELIM, *p1) ; p1++);
+		if(!*p1){ // all char is space or tab
+			*dst = 0;
+			return S_SUCCESS;
+		}
+		for(p2 = p1 + strlen(p1) ; strchr(INI_DELIM, p2[-1]) ; --p2);
+	}
+	
+	// Check copy size
+	Status ret;
+	if(dst_size > p2 - p1){
+		dst_size = p2 - p1;
+		ret = S_SUCCESS;
+	} else {
+		dst_size--;
+		ret = S_BUFFER_TOO_SHORT;
+	}
+	
+	// copy buffer
+	if(dst != p1) memmove(dst, p1, dst_size);
+	dst[dst_size] = 0;
+	return ret;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Access methods
+IniFile::Status IniFile::open(const char* file){
+	close();
+	m_fp = fopen(file, "r");
+	if(m_fp) return S_SUCCESS;
+	
+	//printf("IniFile: Can't open %s\n", file);
+	return S_OPEN_ERROR;
+}
+
+IniFile::Status IniFile::close(){
+	if(!m_fp) return S_NOT_OPENED;
+
+	fclose(m_fp);
+	m_fp = 0;
+	return S_SUCCESS;
+}
+
+IniFile::Status IniFile::get(const char* key, char* ret, int ret_size){
+	if(!m_fp) return S_OPEN_ERROR;
+
+	rewind(m_fp);
+	char line[INI_LINE_BUF];
+	while(fgets(line, sizeof(line), m_fp)){
+		if(*line == '#') continue; // comment line
+
+		char* p = strchr(line, '=');
+		if(!p || line == p) continue; // invalid line
+
+		*p++ = 0;
+		strtrim(line, line, p - line);
+		if(strcmp(line, key)) continue; // different key
+
+		// check data type
+		switch(ret_size){
+		case DTYPE_INT:
+			strtrim(line, p, INI_LINE_BUF);
+			*(int*)ret = strtoul(line, &p, 0);
+			//return p[0]? S_FORMAT_ERROR : S_SUCCESS; // check end
+			return S_SUCCESS; // always success
+
+		case DTYPE_BOOL:
+			strtrim(line, p, INI_LINE_BUF);
+			switch(line[0]){
+			case 'T':
+			case 't':	*(bool*)ret = true;		break;
+			case 'F':
+			case 'f':	*(bool*)ret = false;	break;
+			default:	*(bool*)ret = strtoul(line, &p, 0)? true : false;
+			}
+			return S_SUCCESS;
+
+		default: // string
+			return strtrim(ret, p, ret_size);
+		}
+	}
+	return S_NO_KEY; // No key
+}
+IniFile::Status IniFile::get(const char* key, int& ret){
+	return get(key, (char*)&ret, DTYPE_INT);
+}
+IniFile::Status IniFile::get(const char* key, bool& ret){
+	return get(key, (char*)&ret, DTYPE_BOOL);
+}
+
+
+IniFile::Status IniFile::get(IniFile::IniList* inilist){
+	Status ret = S_SUCCESS;
+	for(; inilist->key ; ++inilist){
+		Status sts = get(inilist->key, (char*)inilist->buf, inilist->typelen);
+		switch(sts){
+		case S_SUCCESS:
+			break;
+		case S_NO_KEY:
+			ret = sts;	// continue
+			break;
+		default:
+			return sts;	// fatal error
+		}
+	}
+	return ret;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IniFile.h	Tue Nov 16 16:34:45 2010 +0000
@@ -0,0 +1,86 @@
+///////////////////////////////////////////////////////////////////////////////
+// IniFile: .ini file parser   by rinos 2010
+///////////////////////////////////////////////////////////////////////////////
+
+// Ini file value (int/bool/string)
+// Key1 = 123            -> 123         (int)
+// Key2 = 0x123          -> 291         (int)
+// Key3 = FALSE          -> false       (bool)
+// Key4 = TRUE           -> true        (bool)
+// Key5 = 123            -> true        (bool)
+// key6 =   abc "def     -> 'abc "def'  (string)
+// key7 = " ghi "jkl "   -> ' ghi "jkl '(string)
+// #comment line
+
+#ifndef __INI_FILE_H__
+#define __INI_FILE_H__
+
+#include "mbed.h"
+
+class IniFile{
+	// defines /////////////////////////////////////////////////////////////////
+public:
+	// data type
+	typedef enum {
+		DTYPE_INT	= -1,
+		DTYPE_BOOL	= -2,
+		// other string
+	} DataType;
+
+	// For the multiple read
+	struct IniList{
+		const char* key;	// key name  (set NULL for list end)
+		int   typelen;		// >0: buffer length, <0: DataType
+		void* buf;			// return buffer
+	};
+
+	// error code
+	typedef enum {
+		S_SUCCESS,
+		S_OPEN_ERROR,
+		S_NOT_OPENED,
+		S_NO_KEY,
+		S_BUFFER_TOO_SHORT,
+		S_FORMAT_ERROR,
+	} Status;
+	
+	// internal member/method //////////////////////////////////////////////////
+private:
+	FILE* m_fp;
+
+	Status strtrim(char* dst, const char* src, int dst_size);
+	
+	// Invalid method
+protected:
+	IniFile(const IniFile& v) {}
+	const IniFile& operator =(const IniFile& v) {return v;}
+
+public:
+	IniFile(const char* file = 0);
+	~IniFile();
+
+	// Access methods
+	Status open(const char* file);
+	Status close();
+	
+	Status get(const char* key, char* ret, int ret_size);
+	Status get(const char* key, int&  ret);
+	Status get(const char* key, bool& ret);
+	Status get(IniList* inilist);
+	
+	// For easy acccess
+	static Status getval(const char* inifile, const char* key, char* ret, int ret_size){
+		return IniFile(inifile).get(key, ret, ret_size);
+	}
+	static Status getval(const char* inifile, const char* key, int& ret){
+		return IniFile(inifile).get(key, ret);
+	}
+	static Status getval(const char* inifile, const char* key, bool& ret){
+		return IniFile(inifile).get(key, ret);
+	}
+	static Status getval(const char* inifile, IniList* inilist){
+		return IniFile(inifile).get(inilist);
+	}
+};
+
+#endif