00001 class __meta_table_enum_wrapper {
00002 public:
00003 __meta_table_enum_wrapper(file_info & p_info) : m_info(p_info) {}
00004 void operator() (const char * p_name,const pfc::chain_list_t<pfc::string8> & p_values) {
00005 t_size index = infinite;
00006 for(pfc::chain_list_t<pfc::string8>::const_iterator iter = p_values.first(); iter.is_valid(); ++iter) {
00007 if (index == infinite) index = m_info.__meta_add_unsafe(p_name,*iter);
00008 else m_info.meta_add_value(index,*iter);
00009 }
00010 }
00011 private:
00012 file_info & m_info;
00013 };
00014
00016 class meta_table_builder {
00017 public:
00018 void add(const char * p_name,const char * p_value,t_size p_value_len = infinite) {
00019 if (file_info::g_is_valid_field_name(p_name)) {
00020 __add(p_name).insert_last()->set_string(p_value,p_value_len);
00021 }
00022 }
00023
00024 void remove(const char * p_name) {
00025 m_data.remove(p_name);
00026 }
00027 void set(const char * p_name,const char * p_value,t_size p_value_len = infinite) {
00028 if (file_info::g_is_valid_field_name(p_name)) {
00029 t_entry & entry = __add(p_name);
00030 entry.remove_all();
00031 entry.insert_last()->set_string(p_value,p_value_len);
00032 }
00033 }
00034 pfc::chain_list_t<pfc::string8> & add(const char * p_name) {
00035 if (!file_info::g_is_valid_field_name(p_name)) throw pfc::exception_bug_check();
00036 return __add(p_name);
00037 }
00038 void finalize(file_info & p_info) {
00039 p_info.meta_remove_all();
00040 m_data.enumerate(__meta_table_enum_wrapper(p_info));
00041 }
00042
00043 void from_info(const file_info & p_info) {
00044 m_data.remove_all();
00045 from_info_overwrite(p_info);
00046 }
00047 void from_info_overwrite(const file_info & p_info) {
00048 for(t_size metawalk = 0, metacount = p_info.meta_get_count(); metawalk < metacount; ++metawalk ) {
00049 const t_size valuecount = p_info.meta_enum_value_count(metawalk);
00050 if (valuecount > 0) {
00051 t_entry & entry = add(p_info.meta_enum_name(metawalk));
00052 entry.remove_all();
00053 for(t_size valuewalk = 0; valuewalk < valuecount; ++valuewalk) {
00054 entry.insert_last(p_info.meta_enum_value(metawalk,valuewalk));
00055 }
00056 }
00057 }
00058 }
00059 private:
00060 typedef pfc::chain_list_t<pfc::string8> t_entry;
00061
00062 t_entry & __add(const char * p_name) {
00063 return m_data.find_or_add(p_name);
00064 }
00065
00066 pfc::map_t<pfc::string8,t_entry,file_info::field_name_comparator> m_data;
00067 };