通用配置文件生成类
2012-08-24 18:37
260 查看
//config.h /* 此为一个通用配置文件生成类 主要是为了解决配置文件的生成,配置文件的读,配置文件的修改 此类的功能: 给定配置文件,则自动分析配置文件,并以字符串数组的形式返回; 以键值形式赋值 可以给定一个结构体数组,可以单个给定键值 格式如下 ************************************************** #配置文件总体说明 # #键值1说明 key1=value1 #键值2说明 key2=value2 ...... ...... *************************************************** *爱锦 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #ifndef True #define True 1 #define False 0 #endif #ifndef KEY_VALUE #define KEY_VALUE #define MAX_KEY 128 #define MAX_VALUE 1024 #define MAX_PATH MAX_KEY #define MAX_DESCRIPTION 2 * MAX_VALUE typedef struct key_value { char key[MAX_KEY]; char value[MAX_VALUE]; char description[MAX_DESCRIPTION]; int level;/*not used*/ /* level is used as [info] ... ... [name] ... ... but here i didn't want to use it */ struct key_value *next; }Key_Value; #endif #ifndef config_file #define config_file typedef struct p { char path[MAX_PATH]; int changed; char description[MAX_DESCRIPTION]; Key_Value *head; int len; }Properties; #endif #ifndef Config_State #define Config_State enum F_ACCESS{S_N=0,S_R=1,S_W=2,S_RW=4}; #endif class Config { public : Config(const char *path, const char *description=NULL); Config(const char *path, const Key_Value *kv, int len, const char *description = NULL); ~Config(); //set or get the configs //set int setDescription(const char *description); int setDescription(const char *key, const char *description); int setProperty(const char *key, const char *value); int setPropertys(const Key_Value *kv, int len); void remove(const char *key); //get int getDescription(char *description); int getDescription(const char *key, char *description); int getProperty(const char *key, char *value); int getPropertys(Key_Value *kv, int len); //others void clear(); F_ACCESS rwable(); protected: Properties *properties; void init(); //deals with file I\O void import(); void copy(char *dest, const char *source, int m_size); Key_Value *index(const char *key, int flag=0); void write(); }; //config.cpp #include "config.h" #include <unistd.h> Config::Config(const char *path, const char *description) { properties = new Properties; copy(properties->path,path, MAX_PATH); if(description == NULL) properties->description[0] = 0; else copy(properties->description, description, MAX_DESCRIPTION); properties->changed = 0; properties->len = 0; init(); import(); } Config::Config(const char *path, const Key_Value *kv, int len, const char *description) { properties = new Properties; copy(properties->path, path, MAX_PATH); if(description == NULL) properties->description[0] = 0; else copy(properties->description, description, MAX_DESCRIPTION); properties->changed = False; properties->len = 0; init(); setPropertys(kv, len); properties->changed = 1; } Config::~Config() { if(properties->changed == 1) { write(); } if(properties->description[0] != 0) { putchar('#'); for(int i = 0;i < strlen(properties->description); i ++) { putchar(properties->description[i]); if(properties->description[i] == 10) putchar('#'); } putchar(10); putchar(10); } Key_Value *tmp = properties->head->next; for (int i = 0;i < properties->len && tmp; i++) { if(tmp->description[0] != 0) { putchar('#'); for(int j = 0;j < strlen(tmp->description); j ++) { putchar(tmp->description[j]); if(tmp->description[j] == 10) putchar('#'); } putchar(10); } printf("%s=\"%s\" ", tmp->key, tmp->value); if(tmp->value[strlen(tmp->value) - 1] != '\n') putchar(10); tmp = tmp->next; putchar(10); } } int Config::setDescription(const char *description) { if(description == NULL) return False; copy(properties->description, description, MAX_DESCRIPTION); properties->changed = 1; return True; } int Config::setDescription(const char *key, const char *description) { if(key == NULL || description == NULL) return False; Key_Value *tmp = index(key); if(tmp != NULL) { copy(tmp->description, description, MAX_DESCRIPTION); properties->changed = 1; return True; } return False; } int Config::setProperty(const char *key, const char *value) { if(key == NULL || value == NULL) return False; Key_Value *tmp = index(key); if(tmp == NULL) { tmp = new Key_Value; copy(tmp->key, key, MAX_KEY); copy(tmp->value, value, MAX_VALUE); tmp->description[0] = 0; tmp->level = 0; tmp->next = properties->head->next; properties->head->next = tmp; properties->len ++; } else { copy(tmp->value, value, MAX_VALUE); } properties->changed = 1; return True; } int Config::setPropertys(const Key_Value *kv, int len) { if(kv == NULL) return False; Key_Value *tmp; for(int i = 0;i < len;i ++) { tmp = index(kv[i].key); if(tmp == NULL) { tmp = new Key_Value; copy(tmp->key,kv[i].key,MAX_KEY); tmp->level = 0; tmp->next = properties->head->next; properties->head->next = tmp; properties->len ++; } copy(tmp->value, kv[i].value, MAX_VALUE); copy(tmp->description, kv[i].description,MAX_DESCRIPTION); } properties->changed = 1; return True; } void Config::remove(const char *key) { if(key == NULL) return; Key_Value *previous,*tmp; previous = index(key, 1); if(previous != NULL) { tmp = previous->next; previous->next = tmp->next; delete tmp; } properties->changed = 1; } int Config::getDescription(char *description) { if(description != NULL) copy(description, properties->description, MAX_DESCRIPTION); return True; } int Config::getDescription(const char *key, char *description) { if(key == NULL || description == NULL) return False; Key_Value *tmp = index(key, 0); if(tmp != NULL) { copy(description, tmp->description, MAX_DESCRIPTION); return True; } return False; } int Config::getProperty(const char *key, char *value) { if(key == NULL || value == NULL) return False; Key_Value *tmp = index(key, 0); if(tmp != NULL) { copy(value, tmp->value, MAX_VALUE); return True; } return False; } int Config::getPropertys(Key_Value *kv, int len) { if(kv == NULL || len > properties->len) return 0; Key_Value *next = properties->head->next; for(int i = 0;i < properties->len && next;i ++) { copy(kv[i].key,next->key,MAX_KEY); copy(kv[i].value, next->value, MAX_VALUE); next = next->next; } return properties->len; } void Config::clear() { Key_Value *next = properties->head->next; while(next) { properties->head->next = next->next; delete next; next = properties->head->next; } properties->description[0] = 0; properties->changed = 1; properties->len = 0; } F_ACCESS Config::rwable() { if(properties->path == NULL) return S_N; if(access(properties->path, R_OK | W_OK) == 0) return S_RW; else if(access(properties->path, R_OK) == 0) return S_R; else if(access(properties->path, W_OK) == 0) return S_W; return S_N; } //int Config::touch(const char *path,int access) {} void Config::init() { //init head properties->head = new Key_Value; properties->head->level = 0; properties->head->next = NULL; } void Config::import() { if(rwable() != S_R && rwable() != S_RW) return ; FILE *f = fopen(properties->path, "r"); char str[MAX_DESCRIPTION]; Key_Value *tmp, *last = properties->head; // char *delim = "="; if(fgets(str,MAX_DESCRIPTION, f ) == NULL) goto END; //must have global descripton while(str[0] == '#') { sprintf(properties->description + strlen(properties->description) , "%s", str + 2); if(fgets(str,MAX_DESCRIPTION, f ) == NULL) goto END; } properties->description[strlen(properties->description) - 1] = 0; //problem do{ while(str[0] == '\n') if(fgets(str,MAX_DESCRIPTION, f ) == NULL) goto END; tmp = new Key_Value; tmp->description[0] = 0; int i; while(str[0] == '#') { sprintf(tmp->description + strlen(tmp->description), "%s", str + 2); if(fgets(str,MAX_DESCRIPTION, f ) == NULL) goto END; } tmp->description[strlen(tmp->description) - 1] = 0; if(str[0] != '\0' && str[0] != '\n') { for(i = 0;str[i] != '=' && i < MAX_KEY; i ++); copy(tmp->key,str, i + 1); copy(tmp->value, str + i + 1, MAX_VALUE); tmp->value[strlen(tmp->value) - 1] = 0; tmp->level = 0; last->next = tmp; last = tmp; properties->len ++; } if(fgets(str,MAX_DESCRIPTION, f ) == NULL) goto END; } while(!feof(f)) ; END : last->next = NULL; fclose(f); } /* 0 -- it self 1 -- previous */ Key_Value *Config::index(const char *key, int flag) { Key_Value *next = properties->head; for(int i = 0;i < properties->len && next->next;i ++) { if(strcmp(next->next->key, key) == 0) { if(flag) return next; else if(flag == 0) return next->next; } next = next->next; } return NULL; } void Config::write() { if(rwable() != S_W && rwable() != S_RW) return ; FILE *f = fopen(properties->path, "w"); Key_Value *next = properties->head->next; char tmp[MAX_DESCRIPTION]; if(properties->description[0] != 0) { fputc('#',f); fputc(' ',f); for(int i = 0; i < strlen(properties->description); i ++) { fputc(properties->description[i],f); if(properties->description[i] == '\n' && i != strlen(properties->description) - 1) { fputc('#',f); fputc(' ',f); } } fputc('\n',f); fputc('\n',f); } for(int i = 0; i < properties->len && next; i ++) { if(next->description[0] != 0) { fputc('#',f); fputc(' ',f); for(int j = 0; j < strlen(next->description); j ++) { fputc(next->description[j], f); if(next->description[j] == '\n' && i != strlen(next->description) - 1) { fputc('#',f); fputc(' ',f); } } fputc('\n',f); } sprintf(tmp, "%s=%s\n\n", next->key, next->value); fwrite(tmp, 1, strlen(tmp), f); next = next->next; } fclose(f); properties->changed = 0; } void Config::copy(char *dest, const char *source, int m_size) { int size = strlen(source) < m_size -1 ? strlen(source) : m_size - 1; strncpy(dest, source, size); dest[size] = 0; }
相关文章推荐
- intellij配置hibernate自动生成hbm.xml文件
- 利用Ant和Xdoclet从pojo类生成hibernate的映射文件并生成hibernate的配置文件
- protobuf的配置原始文件.proto中,使用修饰符repeated、required、optional生成的java文件的区别
- IAR编译ZStack-CC2530,生成HEX文件完全配置
- Silverlight4-RIAServices开发记事1-自动生成的web.config配置文件
- php 生成配置文件 file_put_contents
- CentOS开启coredump转储并生成core文件的配置(centos服务端应用程序开启dump)
- Ambari生成的hive配置文件位置
- properties 的生成与解析配置文件
- 自动生成数据库连接配置文件的工具(调用VS2005数据源选择对话框)
- 根据配置文件生成ServiceInfo对象,并对外提供最快的检索ServiceInfo的功能
- eclipse当中生成C/C++头文件配置:
- 在MyEclipse中利用XDoclet自动生成Hibernate配置和映射文件
- Mybatis使用generator自动生成映射配置文件信息
- CC2640R2F BLE5.0 蓝牙协议栈通用属性配置文件(GATT)
- Hibernate配置文件生成数据库
- win7 安装oracle 10g 未生成监听文件 导致配置监听时无法保存
- 安卓NDK开发环境配置与生成so文件方法二
- 生成XMl配置文件常用方法
- Mybatis 如何自动生成bean dao xml 配置文件 generatorconfig.xml (mysql)