Как то в один прекрасный день потребоволось хранить дерево в одной программе на vala. И обуяла меня жажда велосипедостроения (ну за одно и потренироваться в работе с json оказалось неплохо). В результате родился ниже приведенный класс. Класс умеет проверять наличие ключа (не значения) в json - структуре. Читать с диска и сохранять на диск результат а так же работать с строковыми значениями. Остальные значения допустимые в json в данном примере не включены из за эконимии места, и строкового типа хватить для показа работоспособности.
Так как используется модуль Json то при сборке проэкта не забудьте указать пакет json-glib-1.0. К примеру строка сборки тестового примера у меня выглядит как vala --pkg json-glib-1.0 -o test_config_d -g
Для разделения веток конфига используется символ "/".
К примеру чтение значение cfg.get_string_value("Key 1/Key 2/Key 3") примененое к json файлу вида
"Key 4":"value 1"
}
Так как используется модуль Json то при сборке проэкта не забудьте указать пакет json-glib-1.0. К примеру строка сборки тестового примера у меня выглядит как vala --pkg json-glib-1.0 -o test_config_d -g
Для разделения веток конфига используется символ "/".
К примеру чтение значение cfg.get_string_value("Key 1/Key 2/Key 3") примененое к json файлу вида
{"Key 1":{"Key 2":{"Key 3":"value 2"},
"Key 4":"value 1"
}
}вернет значение value 2
/**
* LGPL 2
* CAV Inc.
* cavinc@mail.ru
*/
using Json;
struct leaf {
int level;
string value;
}
class Config{
private Json.Object root_config;
public Config(){
root_config=new Json.Object();
}
/* читаем файл с конфигом*/
public void LoadCFG(string fname){
Json.Parser parser = new Json.Parser ();
try {
parser.load_from_file(fname);
root_config = parser.get_root ().get_object ();
} catch (Error e) {
warning("%s", e.message);
}
}
/* пишем файл с конфигом */
public void SaveCFG(string fname){
Json.Generator gen=new Json.Generator();
Json.Node rt=new Json.Node(NodeType.OBJECT);
rt.set_object(root_config);
gen.set_root(rt);
gen.to_file(fname);
}
/* добавляем целый элемент*/
private Json.Object set_int(string key,int value){
Json.Object obj=new Json.Object();
obj.set_int_member(key,value);
return obj;
}
private void __set_str(Json.Object obj,string[] key, string value){
if (key.length!=1){
if (obj.has_member(key[0])) {
Json.Node node=obj.get_member(key[0]);
if (node.get_node_type()==NodeType.OBJECT){
__set_str(node.get_object(),key[1:key.length],value);
}
if (node.get_node_type()==NodeType.VALUE){
obj.set_string_member(key[0],value); // ???
}
}else{
obj.set_object_member(key[0],new Json.Object());
__set_str(obj.get_object_member(key[0]),key[1:key.length],value);
}
} else{
obj.set_string_member(key[0],value);
}
}
/* добавляем строковой элемент */
public void set_string_value(string key,string value){
string[] lkey=key.split("/");
if (lkey.length==1) {
root_config.set_string_member(lkey[0],value);
}else{
__set_str(root_config,lkey,value);
}
}
/* извлекаем строку из объекта */
private string _get_string(Json.Object obj,string[] key,int index){
Json.Node node=obj.get_member(key[index]);
int i=index;
if (node.get_node_type()==NodeType.OBJECT){
i+=1;
return _get_string(node.get_object(),key,i);
}
if (node.get_node_type()==NodeType.VALUE){
return obj.get_string_member(key[index]);
}
return "";
}
/* читаем строковой элемент */
public string get_string_value(string key){
string[] lkey=key.split("/");
return _get_string(root_config,lkey,0);
}
/* проверяем наличие ключа на объекте */
private bool __has_key(Json.Object obj,string key){
return obj.has_member(key);
}
/* рекурсивно обходим ветку останавливаемся если не нашли хотя бы один из ключей */
private bool __has_key_rec(Json.Object obj,string[] key,int index){
int i=index;
if (__has_key(obj,key[index])) {
Json.Node node=obj.get_member(key[index]);
if (node.get_node_type()==NodeType.OBJECT){
i+=1;
if (i<=key.length){
return __has_key_rec(node.get_object(),key,i);
}
}
return true;
} else{
return false;
}
}
public bool has_key(string key){
string[] lkey=key.split("/");
return __has_key_rec(root_config,lkey,0);
}
}
Комментариев нет:
Отправить комментарий