#pragma once #if defined(WIN32) || defined(_WIN64) #include #include "../../code_device/hgsane/cJSON.h" #define PATH_SYMBOL "\\" #else #include "cJSON.h" #define PATH_SYMBOL "/" #define NULL nullptr #define DWORD_PTR char* #define _countof(a) sizeof(a) / sizeof(a[0]) #endif // #include #include #include #include namespace gb { class scanner_cfg; class refer { volatile long ref_; protected: refer(); virtual ~refer(); public: long add_ref(void); long release(void); }; class json : public refer { enum val_type { VAL_TYPE_NULL = 0, VAL_TYPE_BOOL, VAL_TYPE_INT, VAL_TYPE_FLOAT, VAL_TYPE_STRING, VAL_TYPE_OBJECT, VAL_TYPE_ARRAY, }; val_type type_; std::string key_; union { bool bval; int nval; double dval; }simple_val_; std::string strval_; std::vector arr_val_; size_t cur_child_; static std::string object_key(json* jsn); static std::string array_key(json* jsn); void from_cjson(cJSON* cj); json* find_child(const char* key, bool remove = false); public: json(char* json_txt = 0); protected: json(const char* key, bool val); json(const char* key, int val); json(const char* key, double val); json(const char* key, const char* val); json(json& r); ~json(); public: // parse/un-parse ... void copy_from(json& r); bool attach_text(char* json_txt); void clear(bool as_array = false); std::string to_string(void); // attributes ... std::string& key(void); bool is_array(void); bool is_leaf_node(void); // whether this object is a leaf node contains final value // value access ... bool get_value(const char* key, bool& val); bool get_value(const char* key, int& val); bool get_value(const char* key, double& val); bool get_value(const char* key, std::string& val); bool get_value(const char* key, json*& val); // enumeration ... size_t children(void); // return children count if was object or array, or else -1 returned json* child(size_t ind); json* first_child(void); json* next_child(void); // change the item matching 'key', otherwise add a new item bool set_value(const char* key, bool val); bool set_value(const char* key, int val); bool set_value(const char* key, double val); bool set_value(const char* key, const char* val); bool set_value(const char* key, json* val); // operator+= only for array json& operator+=(bool val); json& operator+=(int val); json& operator+=(double val); json& operator+=(const char* val); json& operator+=(json* val); // remove item json& operator-=(int ind); bool remove(const char* key); bool remove(json* child); bool remove(int ind); // position management int index(json* child); int index_move_to(json* child, int ind); // leaf node value ... bool value(bool& val); bool value(int& val); bool value(double& val); bool value(std::string& val); json& operator=(bool val); json& operator=(int val); json& operator=(double val); json& operator=(const char* val); }; class base64 { char base64_ind_[128]; char base64_char_[80]; char padding_char_; bool is_valid_base64_table(const char* table); bool initialize_base64_table(const char* table); public: base64(); ~base64(); public: bool set_base64_table(const char* table = NULL); std::string encode(const char* data, size_t bytes, unsigned int line_bytes = -1, bool need_padding = true); std::string decode(const char* data, size_t bytes); }; // NOTE: 2021-01-28 all stored string value are in default language (i.e. Chinese-Simplified), user should call app_language::to_default_language/from_default_language for real value class sane_config_schm : public refer { std::string scheme_name_; scanner_cfg *scanner_; std::string file_; json* jsn_; json* bkp_; json* def_val_; // name_id: id, name_val: val bool in_setting_; void clear(); std::string default_value(const char* name); protected: ~sane_config_schm(); public: sane_config_schm(scanner_cfg* scanner = nullptr); static std::string opt_data_appendix_; static std::string opt_def_id_appendix_; static std::string opt_def_val_appendix_; static std::string opt_def_type_appendix_; static std::string opt_def_title_appendix_; static bool hex(unsigned char ch, unsigned char* val); static bool hex_char(const char* data, unsigned char* val); static std::string to_hex_letter(const char* data, size_t bytes); static std::string from_hex_letter(const char* data, size_t bytes); static bool is_option_data(std::string& name); // reset baase option name into 'name' if name was option data, and return true static void set_default_value(json* jsn, int id, const char* name, const char* title, void* data, size_t bytes, int type); static int option_name_2_id(json* jsn, const char* name); static int option_type(json* jsn, const char* name); static std::string option_title(json* jsn, const char* name); static std::string option_default_value(json* jsn, const char* name); static std::string sane_option_value_2_string(void* val, size_t bytes, int type); public: sane_config_schm* copy(void); bool load_from_file(const char* file); bool load_from_mem(const char* mem, bool in_b64 = true); bool save_to(const char* file); void set_default_value(int sn, const char* name, const char* title, const char* val, size_t bytes, int type); bool first_config(std::string& name, std::string& val); bool next_config(std::string& name, std::string& val); bool get_config(const char* name, std::string& val); void begin_setting(bool restore = false); void config_changed(const char* name, const char* val, size_t bytes, bool extra = false); void config_changed(int sn, const char* val, size_t bytes, bool extra = false); void remove_config(const char* name); void set_value(const char* name, const char* val, size_t bytes, bool extra = false); bool has_changed(int* items = nullptr); void end_setting(bool cancel); int id_from_name(const char* name); std::string to_text_stream(bool b64 = true, bool with_ver = true); std::string get_version(void); std::string get_scheme_name(void); void set_scheme_name(const char* name); std::string auto_gen_scheme_name(const char* (__stdcall* lang_trans)(const char*, bool/*true - default language to cur language*/, void*), void* param); }; class scanner_cfg : public refer { // format: in base64 // // { // "global": { // "ver": "4.33", // "cur": -1 // }, // "scheme_1": sane_config_schm*, // "scheme_2": sane_config_schm*, // "scheme_3": sane_config_schm*, // ... // } // std::string path_; std::string scanner_name_; // scanner type: HUAGOSCAN G100 - 0100 json *global_; // version, current scheme, ... json *opt_default_value_; const char* (__stdcall* lang_trans_)(const char*, bool/*true - default language to cur language*/, void*); void* lang_param_; typedef struct _cfg_schm { std::string name; bool should_rename; sane_config_schm* schm; struct _cfg_schm() { name = ""; should_rename = false; schm = nullptr; } bool operator==(const char* n) { return name == n; } }CFGSCHM; std::vector schemes_; static const char* __stdcall language_trans(const char* in, bool from_def, void* param); void clear(void); void init_version(void); void init_select(void); const char* trans_language(const char* in, bool from_default); protected: ~scanner_cfg(); public: scanner_cfg(); typedef struct _update_func { void(* trans_number)(const char* name, std::string& val, void* param); const char* (* title2name)(const char* title, void* param); std::string discard_msg; // update failed items ... void* func_param; }UDF, *LPUDF; static bool update(const char* file, LPUDF func); static std::string global_name_; static std::string cur_sel_; static std::string default_setting_name_; public: int load_file(const char* file); int load_mem(const char* mem); int save(const char* file = nullptr); void set_language_transform(const char* (__stdcall* lang_trans)(const char*, bool/*true - default language to cur language*/, void*), void* param); json* get_option_default_value(void); void get_all_schemes(std::vector& schemes); // return all schemes name queue, the first is always be 'Default settings' sane_config_schm* get_scheme(const char* scheme_name = nullptr/*return current scheme if was null*/); // call sane_config_schm::release() if not use anymore sane_config_schm* create_empty_scheme(bool selected); // create an empty scheme and add to scheme queue std::string get_current_scheme_name(void); std::string to_text_stream(void); void set_default_value(int id, const char* name, const char* title, void* data, size_t bytes, int type); int option_value_type(const char* name); std::string option_title(const char* name); bool remove_scheme(const char* scheme_name); void remove_all_schemes(void); bool select_scheme(const char* scheme_name); sane_config_schm* copy_scheme(const char* cp_from_name); // for UI setting, call release() if not use anymore bool add_scheme(sane_config_schm* schm, const char* name = nullptr, bool should_rename = false); bool rename_scheme(const char* from, const char* to); }; };