存储外部数据
author:visualsan 2014.2 上海
1.简介
利用外部数据存储外部接口,可以在模型文件里面尺寸用户自定义数据。在模型保存时数据自动存储,在模型载入时数据自动载入。外部数据的管理完全依赖于TK函数,CROE默认情况下忽略外部数据的存在。
外部数据是由class和slot来管理的,一般情况下一个模型只需要一个class,而且每个模型的class名称必须唯一。每个class里面有一系列的slot列表,每个列表由名称或者id来表示,里面有一个数据结构用来存储数据,其类型为:int、double、wide string和stream。Stream结构里面存储的是数据流,最大长度为512kb,可以用来存储压缩数据或者数据结构。对于不同的操作系统,除了stream数据类型外,其他数据的从保存和载入都一致。
两个数据结构:ProExtdataClass和ProExtdataSlot,分别原来定义class和solt。其中solt可以通过名称或者id来定义,在创建solt时将名称为NULL时即可自动获取一个id。Class和solt的名称长度相加不能超过PRO_NAME_SIZE。Solt名称不能以数字开头。
2.C++封装
主要有三个类:Proplus_ext_solt、Proplus_ext_class和Proplus_ext_manager,作用分别为具体数据、类以及管理数据。
Proplus_ext_solt:具体数据类,封装了各种数据类型,其由CLASS创建。PTK支持四种数据double、int、string和void*。其中void*是二进制数据,可以存储长度小于512kb的数据。Proplus_ext_solt除了支持上面四种数据外,还支持大于512kb的数据。几种数据都是存储为stream格式。
设置数据的函数有:
其中info_msg是一个长度为20个字符的数据段,可以用来存自定义信息,在class里面有一个根据info_msg来查找的函数。
其它函数:
其中GetFileName是获取在SetValue_void_huge里面设置的文件名称,当保存的的数据是一个文件时,这个函数特别有用。
Proplus_ext_class:用来管理class,对于每个mdl一个class就够用了,每个class里面有若干solts,每个solt由Proplus_ext_solt管理。函数Proplus_ext_class 在析构后不会将proe内存中的solt删除,除非调用DeleteSolt或DeleteAllSolts。AddSolt函数用来添加一个新的solt。
Proplus_ext_manager:用来管理一个MDL的所有数据类。主要函数有:
3.例子
写入数据 ProMdl mdl; ProMdlCurrentGet(&mdl); ProExtdataInit(mdl);
Proplus_ext_manager cm(mdl); Proplus_ext_class &cl=*cm.ClassVector()[0];
//添加一个double数据 Proplus_ext_solt*ptr=cl.AddSolt(); ptr->SetValue_double(12.3,"---val_double");
//添加int数据 ptr=cl.AddSolt(); ptr->SetValue_int(23,"---val_int");
//添加string数据 ptr=cl.AddSolt(); ptr->SetValue_string("hello man","---val_string"); /写入二进制数据 struct st { char c[100]; int len; double d; ProName name; }; st c; strcpy(c.c,"string value"); c.len=123; c.d=3.45; ProStringToWstring(c.name,"this is wstring"); ptr=cl.AddSolt(); ptr->SetValue_void(&c,sizeof(st),"--void");
ProMdlSave(mdl);
写入文件:写入7个文件,文件大小从从1K到几十M。 ProMdl mdl; ProMdlCurrentGet(&mdl); ProExtdataInit(mdl); Proplus_ext_manager cm(mdl); Proplus_ext_class &cl=*cm.ClassVector()[0]; CString ds="E:\\temp\\"; //文件名称 char* names[]={ "《中国航空材料手册》第卷.结构钢.不锈钢.pdf", "[神经网络设计].(美国)Hagan.清晰版.pdf", "[讨论]复合材料金属层压板的建模.pdf", "x.exe","x.pdf","图片.rar","MSchart应用.zip" }; for (int i=0;i<7;++i) { CFile f; if(!f.Open(ds+names[i],CFile::modeRead)) continue; void*s=malloc( f.GetLength() ); f.Read(s,f.GetLength()); Proplus_ext_solt*ptr=cl.AddSolt(); ptr->SetValue_void_huge(s,f.GetLength(),names[i]); f.Close(); free(s); } ProMdlSave(mdl);
读取数据: ProMdl mdl; ProMdlCurrentGet(&mdl); Proplus_ext_manager cm(mdl); Proplus_ext_class &cl=*cm.ClassVector()[0]; DBG("solts list"); for (int i=0;i<cl.SoltsVector().size();++i) { Proplus_ext_solt*ptr=cl.SoltsVector()[i]; DBG_INT_(ptr->GetDataType()); DBG_INT_(ptr->GetDataLen()); DBG(ptr->GetSoltName()); DBG_INT_(ptr->GetID()); DBG(ptr->GetInfoMsg()); if(ptr->GetDataType()==1) { DBG("int"); int x=*(int*)ptr->GetValue(); DBG_INT(x); } if(ptr->GetDataType()==2) { DBG("double"); double x=*(double*)ptr->GetValue(); DBG_DOU_(x); } if(ptr->GetDataType()==3) { DBG("string"); char* x=(char*)ptr->GetValue(); int len=strlen(x); DBG_INT_(len); DBG(x); } if(ptr->GetDataType()==4) { DBG("void*"); DBG(ptr->GetInfoMsg()); struct st { char c[100]; int len; double d; ProName name; }; st*c=(st*)ptr->GetValue(); DBG(c->c); DBG_INT_(c->len); DBG_DOU_(c->d); char buf[200]; ProWstringToString(buf,c->name); DBG(buf); } } }
读取数据并且另存为文件: void ext_test::test_read_huge_data() { ProMdl mdl; ProMdlCurrentGet(&mdl); ProExtdataInit(mdl); Proplus_ext_manager cm(mdl); Proplus_ext_class &cl=*cm.ClassVector()[0]; CString ds="E:\\temp\\ds\\"; int n=cl.SoltsVector().size(); for (int i=0;i<n;i++) { Proplus_ext_solt*ptr=cl.SoltsVector()[i]; if(!ptr->GetHugeValue()) continue; CString ps=ds+ptr->GetFileName(); DBG(ps); FILE*f=fopen(ps,"wb"); fwrite(ptr->GetHugeValue(),1,ptr->GetHugeDataLen(),f); fclose(f); }
4.源代码
.h文件
#pragma once #include "TKInclude.h" #include <vector> #define VOID_INFO_MSG_LEN 20 #define HUGE_DATA_SIZE 520000 #define HUGE_DATA_HEAD_TAG "HUGE_DATA_HEAD" #define HUGE_DATA_BODY_TAG "HUGE_DATA_BODY" class Proplus_ext_class; class Proplus_ext_manager; class Proplus_ext_solt { friend class Proplus_ext_class; protected: Proplus_ext_solt(ProExtdataClass*,int solt_id,Proplus_ext_class*);//init solt Proplus_ext_solt(ProExtdataClass*,Proplus_ext_class*);//create solt public: virtual ~Proplus_ext_solt(void); int GetID(); CString GetSoltName(); //data_type //1 int //2 double //3 char* //4 void* //5 huge_data int GetDataType(); bool GetStatus(); CString GetStatusMsg(); void*SetValue_int(int ,char*info_msg=NULL); void*SetValue_double(double,char*info_msg=NULL); void*SetValue_string(char*,char*info_msg=NULL ); void*SetValue_void(void*pdata ,int len/*max 512KB*/,char*info_msg=NULL/*max length 20*/); void*SetValue_void_huge(void*phuge_data ,long len,char*file_name=NULL, char*info_msg=NULL/*max length 20*/); void*GetValue();//if huge data,return the head void*GetHugeValue();//only for huge data CString GetInfoMsg();//only for void* data //如果大数据是一个文件,那么可以保存文件名称 CString GetFileName();//only for huge data int GetDataLen();//if huge data,return the len of head long GetHugeDataLen(); private: bool m_status; CString m_msg; CString m_info_msg; void*m_data_format; int m_len_of_data; int m_data_size; int m_data_type; ProExtdataSlot m_solt; ProExtdataClass*m_pProExtdataClass; Proplus_ext_class*m_pProplus_ext_class; //将数据格式化,数据前面加一类型表示符,长度为sizeof(int) //data_type //1 int //2 double //3 char* //4 void* void *FormatData(int data_type,int data_size,void *ptr,int*plen,char*info_msg=NULL); //将数据前的类型长度去除,长度plen为数据长度减去sizeof(int) void *UnFormatData(int data_size,void *ptr,int*plen); // bool WriteSoltData(ProExtdataSlot&st,void*ptr,int len); //从PROE中删除,只供class调用 bool RemoveFromProe(); //HUGE_DATA_OPERATOR struct h_data_head { long _size_of_data; int _n_of_ids; char _file_name[MAX_PATH+1];//if is a file } m_huge_head; //将数据分隔,index 1 based void *m_phuge_data; long m_len_of_huge_data; void*h_sep_data(void*,int len,int &sep_len,int index); void h_clear_huge_data(); int h_body_id(int index);//0 based }; class Proplus_ext_class { friend class Proplus_ext_manager; friend class Proplus_ext_solt; public: ~Proplus_ext_class(); //根据信息查找 std::vector<Proplus_ext_solt*> FindSolts(char*info_msg); Proplus_ext_solt* FindSolts_first(char*info_msg); std::vector<Proplus_ext_solt*>& SoltsVector(); CString GetClassName(); //add and delete solts,also delete from proe Proplus_ext_solt*AddSolt(); bool DeleteSolt(int id); void DeleteAllSolts(); ProExtdataClass&GetClass(); protected: Proplus_ext_class(ProMdl mdl,char*class_name=NULL); private: ProMdl m_mdl; CString m_class_name; ProExtdataClass m_class; bool m_status; CString m_msg; //solt vector std::vector<Proplus_ext_solt*> m_Proplus_ext_solt_vector; std::vector<Proplus_ext_solt*> m_Proplus_ext_solt_body_vector; //初始化 bool InitSolts(); // void FreeVector(); //从PROE中删除,会删除类极其数据,只供manager调用 bool RemoveFromProe(); //读取大数据 void h_read_data(); bool h_read_solt(Proplus_ext_solt*); void h_del_body(int id); }; class Proplus_ext_manager { public: Proplus_ext_manager(ProMdl mdl); ~Proplus_ext_manager(); std::vector<Proplus_ext_class*>&ClassVector(); //保存模型 void SaveMdl(); //从内存中删除,没有保存的数据将丢失 void Erase(); //add and delete class,also delete from proe Proplus_ext_class*AddClass(char *class_name); bool DeleteClass(char *class_name); void DeleteAllClasses(); ProMdl GetMdl(); private: ProMdl m_mdl; std::vector<Proplus_ext_class*> m_class_vector; CString m_msg; bool m_status; void Init(); void FreeVector(); }; struct ext_test { static void test_new_class_solt(); static void test_read_class_solt(); static void test_write_huge_data(); static void test_read_huge_data(); static void test_del_huge_data(); };
.cpp文件
#include "StdAfx.h" #include "Proplus_ext_solt.h" #include "TKInclude.h" #define DBG OutputDebugString #define DBG_INT(x) {CString str;str.Format("%d",x);DBG(str);} #define DBG_INT_(x) {CString str;str.Format("%s=%d",#x,x);DBG(str);} #define DBG_DOU_(x) {CString str;str.Format("%s=%f",#x,x);DBG(str);} #define DBG_INT2(x,y) {CString str;str.Format("%s=%d",x,y);DBG(str);} #define ER(e) if(er==e) return #e; #define MAX_BUF_LEN 524288 CString GetErrorStatus(ProExtdataErr er) { ER( PROEXTDATA_TK_NO_ERROR ); ER( PROEXTDATA_TK_INVALID_OBJ_OR_CLASS ); ER( PROEXTDATA_TK_CLASS_OR_SLOT_EXISTS ); ER( PROEXTDATA_TK_NAMES_TOO_LONG ); ER( PROEXTDATA_TK_SLOT_NOT_FOUND ); ER( PROEXTDATA_TK_BAD_KEY_BY_FLAG ); ER( PROEXTDATA_TK_INVALID_OBJ_TYPE ); ER( PROEXTDATA_TK_EMPTY_SLOT ); ER( PROEXTDATA_TK_BAD_DATA_ARGS ); ER( PROEXTDATA_TK_STREAM_TOO_LARGE ); ER( PROEXTDATA_TK_INVALID_SLOT_NAME ); ER( PROEXTDATA_TK_ERROR ); ER( PROEXTDATA_TK_MAX_SLOTS_IN_MODEL ); return "unknow"; } Proplus_ext_solt::Proplus_ext_solt(ProExtdataClass*p,int solt_id,Proplus_ext_class*pclass) { DBG("Proplus_ext_solt()"); DBG_INT_(solt_id); char buf[200]; CString str; m_pProplus_ext_class=pclass; m_len_of_huge_data = 0; m_phuge_data = 0; m_data_format=0; m_len_of_data = 0; m_pProExtdataClass = p; m_solt.p_class = m_pProExtdataClass; m_solt.slot_id = solt_id; str.Format("%d",solt_id); strcpy(buf,str); ProStringToWstring(m_solt.slot_name,buf); int data_type; void*ptr=0; ProExtdataErr er= ProExtdataSlotRead(&m_solt,KEY_BY_ID,&data_type,&m_data_size, &ptr); m_status= er==PROEXTDATA_TK_NO_ERROR; m_msg=GetErrorStatus(er); DBG(m_msg); if( ptr ) { DBG("-------------------FormatData--------------------"); m_data_type = *(int*)ptr; #if 0 m_data_format= FormatData(m_data_type,m_data_size-sizeof(int), (char*)ptr+sizeof(int),&m_data_size); #endif m_data_format=malloc(m_data_size); memcpy(m_data_format,ptr,m_data_size); CString str=GetInfoMsg(); if(str==HUGE_DATA_HEAD_TAG) { m_huge_head = *(h_data_head*)GetValue(); } m_status= er==PROEXTDATA_TK_NO_ERROR; m_msg=GetErrorStatus(er); DBG(m_msg); ProExtdataFree(&ptr); m_info_msg = (char*)m_data_format+sizeof(int); } } Proplus_ext_solt::Proplus_ext_solt(ProExtdataClass*p,Proplus_ext_class*pclass) { DBG("Proplus_ext_solt()"); m_pProplus_ext_class=pclass; m_phuge_data=0; m_data_format=0; m_len_of_data = 0; m_len_of_huge_data = 0; m_pProExtdataClass = p; ProExtdataErr er= ProExtdataSlotCreate(m_pProExtdataClass,NULL,&m_solt); m_status= er==PROEXTDATA_TK_NO_ERROR; m_msg=GetErrorStatus(er); } Proplus_ext_solt::~Proplus_ext_solt(void) { DBG("~Proplus_ext_solt"); if(m_data_format) { DBG("~free m_data_format"); free(m_data_format); } if(m_phuge_data) { DBG("~free m_phuge_data"); free(m_phuge_data); } } int Proplus_ext_solt::GetDataType() { return m_data_type; } bool Proplus_ext_solt::GetStatus() { return m_status; } CString Proplus_ext_solt::GetStatusMsg() { return m_msg; } //将数据格式化,数据前面加一类型表示符,长度为sizeof(int) //data_type //1 int //2 double //3 void //4 char* void *Proplus_ext_solt::FormatData(int data_type,int data_size, void *ptr,int*plen,char*info_msg) { DBG("FormatData"); DBG_INT_(data_type); DBG_INT_(data_size); if ( !m_info_msg.IsEmpty() && NULL==info_msg) { strcpy(info_msg,m_info_msg); } *plen = data_size +sizeof(int)+VOID_INFO_MSG_LEN; char*pdata=(char*)malloc( *plen ); memcpy(pdata,&data_type,sizeof(int));//type m_info_msg=info_msg; if(info_msg) { int len=strlen(info_msg); if(len>=VOID_INFO_MSG_LEN) len = VOID_INFO_MSG_LEN-1; memcpy(pdata+sizeof(int),info_msg,len+1 ); pdata[ sizeof(int)+VOID_INFO_MSG_LEN ] ='\0'; } memcpy(pdata+sizeof(int)+VOID_INFO_MSG_LEN,ptr,data_size); DBG_INT_(*plen); return pdata; } int Proplus_ext_solt::h_body_id(int index) { int id=*(int*)( (char*)GetValue()+sizeof(h_data_head)+sizeof(int)*index ); DBG("------------------------h_body_id"); DBG_INT_(id); return id; } //将数据前的类型长度去除,长度plen为数据长度减去sizeof(int) void *Proplus_ext_solt::UnFormatData(int data_size,void *ptr,int*plen) { DBG("UnFormatData"); m_data_type=*(int*)ptr; DBG_INT_(data_size); *plen = data_size - sizeof(int)-VOID_INFO_MSG_LEN; DBG_INT_(*plen); return (char*)ptr+sizeof(int)+VOID_INFO_MSG_LEN; } void*Proplus_ext_solt::SetValue_int(int v,char*info_msg) { DBG("SetValue_int"); DBG_INT_(v); if(m_data_format) free(m_data_format); m_data_format = 0; m_data_type = 1; m_data_format = FormatData(m_data_type,sizeof(int),&v,&m_data_size,info_msg); return WriteSoltData(m_solt,m_data_format,m_data_size)?m_data_format:NULL; } void*Proplus_ext_solt::SetValue_double(double v,char*info_msg) { DBG("SetValue_double"); DBG_DOU_(v); if(m_data_format) free(m_data_format); m_data_format = 0; m_data_type = 2; m_data_format = FormatData(m_data_type,sizeof(double),&v,&m_data_size,info_msg); return WriteSoltData(m_solt,m_data_format,m_data_size)?m_data_format:NULL; } void*Proplus_ext_solt::SetValue_string(char* v,char*info_msg) { DBG("SetValue_string"); DBG(v); if(m_data_format) free(m_data_format); m_data_format = 0; m_data_type = 3; m_data_format = FormatData(m_data_type,strlen(v)+1,v,&m_data_size,info_msg); return WriteSoltData(m_solt,m_data_format,m_data_size)?m_data_format:NULL; } CString Proplus_ext_solt::GetFileName() { CString str=GetInfoMsg(); if(str==HUGE_DATA_HEAD_TAG) return m_huge_head._file_name; return NULL; } CString Proplus_ext_solt::GetInfoMsg()//only for void* data { return m_info_msg; } void*Proplus_ext_solt::SetValue_void(void* v,int len,char*info_msg) { DBG("SetValue_void"); DBG_INT_(len); if( len >MAX_BUF_LEN ) { DBG("data length too long"); return NULL; } if(m_data_format) free(m_data_format); m_data_format = 0; m_data_type = 4; m_data_format = FormatData(m_data_type,len,v,&m_data_size,info_msg); return WriteSoltData(m_solt,m_data_format,m_data_size)?m_data_format:NULL; } void*Proplus_ext_solt::SetValue_void_huge( void* v,long len,char*file_name,char*info_msg) { DBG("SetValue_void_huge"); DBG_INT_(len); //clear data if(m_data_format) { //clear huge data and head h_clear_huge_data(); } ZeroMemory(&m_huge_head,sizeof(h_data_head)); m_data_format = 0; m_data_type = 4; ProExtdataSlot s_solt; //store data m_len_of_huge_data = len; m_phuge_data = malloc(len); memcpy(m_phuge_data,v,len); DBG("set up data"); std::vector<int> solts_ids; void*p_body=0,*p_temp,*p_head; int body_len=0; int index=1; CString str; char buf[200]; p_body = h_sep_data(m_phuge_data,len,body_len,index++); while (p_body) { p_temp = 0; p_temp = FormatData(m_data_type,body_len,p_body,&body_len, HUGE_DATA_BODY_TAG); ProExtdataErr er= ProExtdataSlotCreate(m_pProExtdataClass,NULL,&s_solt); DBG("--------create solt-------------"); DBG( GetErrorStatus(er) ); if( WriteSoltData(s_solt,p_temp,body_len) ) { solts_ids.push_back( s_solt.slot_id ); DBG_INT_(index); }else { DBG("fail"); //clear for (int i=0;i<solts_ids.size();++i) { s_solt.p_class = m_pProExtdataClass; s_solt.slot_id = solts_ids[i]; str.Format("%d",solts_ids[i]); strcpy(buf,str); ProStringToWstring(s_solt.slot_name,buf); ProExtdataSlotDelete(&s_solt,KEY_BY_ID); } solts_ids.clear(); break; } p_body = h_sep_data(m_phuge_data,len,body_len,index++); free(p_temp); } m_data_format = 0; m_huge_head._size_of_data=len; m_huge_head._n_of_ids = solts_ids.size(); if(file_name) strcpy(m_huge_head._file_name,file_name); if(solts_ids.size()>0) { /* data_type|head|n_of_id|id list */ DBG("write head"); int sz=solts_ids.size(); long len=sizeof(h_data_head) + (solts_ids.size())*sizeof(int); p_head = malloc(len); memcpy(p_head,&m_huge_head,sizeof(h_data_head)); DBG("write id:"); for (int i=0;i<solts_ids.size();++i) { DBG_INT_(solts_ids[i]); sz=solts_ids[i]; memcpy((char*)p_head+sizeof(h_data_head)+sizeof(int)*i ,&sz,sizeof(int)); } DBG("format"); m_data_format = FormatData(m_data_type,len,p_head, &m_data_size,HUGE_DATA_HEAD_TAG); free(p_head); } //test //FILE*f=fopen("E:\\temp\\x3.pdf","w"); // fwrite(v,len,1,f); //for (int i=0;i<tp_list.size();i++) //{ // fwrite(tp_list[i],tp_len[i],1,f); // delete [] tp_list[i]; // DBG_INT_(tp_len[i]); //} //fclose(f); //write head data return WriteSoltData(m_solt,m_data_format,m_data_size)?m_data_format:NULL; } long Proplus_ext_solt::GetHugeDataLen() { return m_len_of_huge_data; } void Proplus_ext_solt::h_clear_huge_data() { DBG("h_clear_huge_data"); m_phuge_data = NULL; ProExtdataSlot st=m_solt; CString str; char buf[200]; char *p_head= (char*)GetValue(); for (int i=0; i<m_huge_head._n_of_ids; ++i ) { int id=*(int*)( p_head+sizeof(h_data_head)+sizeof(int)*i ); DBG("[ ]"); DBG_INT_(id); //从列表中删除,同时从PROE中删除 m_pProplus_ext_class->h_del_body(id); /* st.slot_id = id; str.Format("%d",id); strcpy(buf,str); ProStringToWstring(st.slot_name,buf); str=GetErrorStatus( ProExtdataSlotDelete(&st,KEY_BY_ID) ); DBG(str);*/ } free(m_data_format); free(m_phuge_data); m_data_format = NULL; m_phuge_data = NULL; } //将数据分隔 void*Proplus_ext_solt::h_sep_data(void*v,int len,int &sep_len,int index) { DBG("sep data"); char *ptr=(char*)v; int s1=HUGE_DATA_SIZE*index,s2=HUGE_DATA_SIZE*(index-1); if( s2 >= len ) { DBG("reach end"); DBG_INT_(s2); return NULL; } if(s1 > len ) { DBG("....part data...."); sep_len = len-s2; }else sep_len = HUGE_DATA_SIZE; DBG_INT_(len); DBG_INT_(index); DBG_INT_(sep_len); return ptr+s2; } void*Proplus_ext_solt::GetHugeValue()//only for huge data { if(m_data_type != 4) return NULL; return m_phuge_data; } void*Proplus_ext_solt::GetValue() { int len=0; return UnFormatData(m_data_size,m_data_format,&len); } bool Proplus_ext_solt::WriteSoltData(ProExtdataSlot&st,void*ptr,int len) { DBG("*********WriteSoltData"); DBG_INT_(len); ProExtdataErr er= ProExtdataSlotWrite(&st,KEY_BY_ID,PRO_STREAM_TYPE,len,ptr); m_status= er==PROEXTDATA_TK_NO_ERROR; m_msg=GetErrorStatus(er); DBG(m_msg); DBG("***************"); return m_status; } int Proplus_ext_solt::GetDataLen() { return m_data_size-sizeof(int)-VOID_INFO_MSG_LEN;//void* has comment } int Proplus_ext_solt::GetID() { return m_solt.slot_id; } //从PROE中删除,只供class调用 bool Proplus_ext_solt::RemoveFromProe() { if(m_status) { CString str=GetInfoMsg(); if(str==HUGE_DATA_HEAD_TAG) { h_clear_huge_data(); } DBG("ProExtdataSlotDelete"); m_status =ProExtdataSlotDelete(&m_solt,KEY_BY_ID); } return m_status; } CString Proplus_ext_solt::GetSoltName() { char buf[200]; ProWstringToString(buf,m_solt.slot_name); return buf; } /************************************************************************/ /* */ /************************************************************************/ Proplus_ext_class::Proplus_ext_class(ProMdl mdl,char*class_name) { char buf[200]; ProName name; DBG("Proplus_ext_class"); //set up class name if(class_name ==NULL) { ProMdlNameGet(mdl,name); ProWstringToString(buf,name); DBG("use mdl name:"); }else { strcpy(buf,class_name); ProStringToWstring(name,buf); } DBG(buf); //init class ProExtdataErr er= ProExtdataClassRegister(mdl,name,&m_class); m_status = er==PROEXTDATA_TK_NO_ERROR; m_msg = GetErrorStatus(er); DBG(m_msg); //类已近存在 if(er==PROEXTDATA_TK_CLASS_OR_SLOT_EXISTS) { m_status=1; ProStringToWstring(m_class.class_name,buf); m_class.p_model=mdl; } if(m_status) m_status=InitSolts(); if(m_status) h_read_data(); } Proplus_ext_class::~Proplus_ext_class() { DBG("~Proplus_ext_class"); FreeVector(); } //初始化 bool Proplus_ext_class::InitSolts() { DBG("InitSolts"); int n,*ids=0; char buf[200]; ProExtdataErr er= ProExtdataSlotIdsList(&m_class,&n,&ids); m_msg = GetErrorStatus(er); DBG(m_msg); ProExtdataNamesList name_list; er=ProExtdataSlotNamesList(&m_class,&n,&name_list); m_msg = GetErrorStatus(er); DBG(m_msg); if(er==PROEXTDATA_TK_NO_ERROR) { DBG_INT_(n); for (int i=0; i<n; ++i) { ProWstringToString(buf,name_list[i]); DBG(buf); DBG_INT_(ids[i]); Proplus_ext_solt*ptr=new Proplus_ext_solt(&m_class,ids[i],this); // CString str=ptr->GetInfoMsg(); if(str==HUGE_DATA_BODY_TAG)//push_body { DBG("ADD TO BODY"); m_Proplus_ext_solt_body_vector.push_back( ptr ); } else { DBG("ADD TO HEAD"); m_Proplus_ext_solt_vector.push_back( ptr ); } } ProArrayFree((ProArray*)&ids); ProArrayFree((ProArray*)&name_list); } DBG( GetErrorStatus(er) ); return er==PROEXTDATA_TK_NO_ERROR; } void Proplus_ext_class::h_del_body(int id) { for (int i=0;i<m_Proplus_ext_solt_body_vector.size();++i) { Proplus_ext_solt*ptr=m_Proplus_ext_solt_body_vector[i]; if(ptr->GetID()==id) { DBG("del body"); DBG_INT_(id); ptr->RemoveFromProe(); delete ptr; m_Proplus_ext_solt_body_vector.erase( m_Proplus_ext_solt_body_vector.begin()+i ); break; } } } void Proplus_ext_class::FreeVector() { DBG("FreeVector"); for (int i=0; i<m_Proplus_ext_solt_vector.size(); ++i ) { delete m_Proplus_ext_solt_vector[i]; } m_Proplus_ext_solt_vector.clear(); for (int i=0; i<m_Proplus_ext_solt_body_vector.size(); ++i ) { delete m_Proplus_ext_solt_body_vector[i]; } m_Proplus_ext_solt_body_vector.clear(); } //从PROE中删除,会删除类极其数据,只供manager调用 bool Proplus_ext_class::RemoveFromProe() { DeleteAllSolts(); ProExtdataClassUnregister(&m_class); return true; } std::vector<Proplus_ext_solt*>& Proplus_ext_class::SoltsVector() { return m_Proplus_ext_solt_vector; } //根据信息查找 std::vector<Proplus_ext_solt*> Proplus_ext_class::FindSolts(char*info_msg) { std::vector<Proplus_ext_solt*> vl; for (int i=0;i<m_Proplus_ext_solt_vector.size();++i) { if ( CString(info_msg) == m_Proplus_ext_solt_vector[i]->GetInfoMsg() ) { vl.push_back( m_Proplus_ext_solt_vector[i] ); } } return vl; } Proplus_ext_solt* Proplus_ext_class::FindSolts_first(char*info_msg) { for (int i=0;i<m_Proplus_ext_solt_vector.size();++i) { if ( CString(info_msg) == m_Proplus_ext_solt_vector[i]->GetInfoMsg() ) { return m_Proplus_ext_solt_vector[i]; } } return NULL; } //add and delete solts,also delete from proe Proplus_ext_solt*Proplus_ext_class::AddSolt() { DBG("AddSolt"); Proplus_ext_solt*ptr=new Proplus_ext_solt(&m_class,this); m_Proplus_ext_solt_vector.push_back( ptr ); return ptr; } bool Proplus_ext_class::DeleteSolt(int id) { DBG("DeleteSolt"); DBG_INT_(id); for (int i=0; i<m_Proplus_ext_solt_vector.size(); ++i) { if(m_Proplus_ext_solt_vector[i]->GetID() == id ) { DBG("find and delete,break"); m_Proplus_ext_solt_vector[i]->RemoveFromProe(); delete m_Proplus_ext_solt_vector[i]; m_Proplus_ext_solt_vector.erase( m_Proplus_ext_solt_vector.begin()+i ); return true; } } DBG("cant find id"); return false; } ProExtdataClass&Proplus_ext_class::GetClass() { return m_class; } void Proplus_ext_class::h_read_data() { DBG("读取大数据"); //读取大数据 while (1) { for (int i=0;i<m_Proplus_ext_solt_vector.size();++i) { Proplus_ext_solt*ptr=m_Proplus_ext_solt_vector[i]; if (ptr->GetDataType()==4)//void* { CString str=ptr->GetInfoMsg(); if( str== HUGE_DATA_HEAD_TAG ) { DBG("-----get head-----"); DBG_INT_(ptr->m_huge_head._size_of_data); DBG_INT_(ptr->m_huge_head._n_of_ids); ptr->m_len_of_huge_data=ptr->m_huge_head._size_of_data; ptr->m_phuge_data = malloc(ptr->m_huge_head._size_of_data); if( h_read_solt(ptr) ) { DBG("success read head"); }else { DBG("fail read head"); goto end; } } } } goto end; } end: DBG("读取大数据-----------------------end"); } bool Proplus_ext_class::h_read_solt(Proplus_ext_solt*ptr) { std::vector<int> index_to_del; long cur_pos=0; for (int i=0;i<m_Proplus_ext_solt_body_vector.size();++i) { Proplus_ext_solt*sr=m_Proplus_ext_solt_body_vector[i]; if (sr->GetDataType()==4)//void* { CString str=sr->GetInfoMsg(); if( str== HUGE_DATA_BODY_TAG ) { for (int k=0;k<ptr->m_huge_head._n_of_ids;++k) { int id= ptr->h_body_id(k); if( sr->GetID() == id) { DBG("-----get body-----"); DBG_INT_(cur_pos); index_to_del.push_back( i ); memcpy((char*)ptr->m_phuge_data+cur_pos, sr->GetValue(),sr->GetDataLen()); cur_pos+=sr->GetDataLen(); } } } } } if( index_to_del.size() != ptr->m_huge_head._n_of_ids ) return false; for (int i=0;i<ptr->m_huge_head._n_of_ids;++i) { CString str; str.Format("[ %d %d ]",ptr->h_body_id(i),index_to_del[i]); DBG(str); } return true; } void Proplus_ext_class::DeleteAllSolts() { DBG("DeleteAllSolts"); for (int i=0; i<m_Proplus_ext_solt_vector.size(); ++i) { m_Proplus_ext_solt_vector[i]->RemoveFromProe(); delete m_Proplus_ext_solt_vector[i]; } m_Proplus_ext_solt_vector.clear(); } CString Proplus_ext_class::GetClassName() { return m_class_name; } void ext_test::test_new_class_solt() { ProMdl mdl; ProMdlCurrentGet(&mdl); ProExtdataInit(mdl); Proplus_ext_manager cm(mdl); Proplus_ext_class &cl=*cm.ClassVector()[0]; Proplus_ext_solt*ptr=cl.AddSolt(); ptr->SetValue_double(12.3,"---val_double"); ptr=cl.AddSolt(); ptr->SetValue_int(23,"---val_int"); ptr=cl.AddSolt(); ptr->SetValue_string("hello man","---val_string"); //add struct struct st { char c[100]; int len; double d; ProName name; }; st c; strcpy(c.c,"我手机哦艰苦艰苦艰可i刻录机空间苦艰苦艰苦机"); c.len=123; c.d=3.45; ProStringToWstring(c.name,"this is wstring"); ptr=cl.AddSolt(); ptr->SetValue_void(&c,sizeof(st),"ikdjkdsjdksjadksajdkasjdk"); ProMdlSave(mdl); } void ext_test::test_read_class_solt() { ProMdl mdl; ProMdlCurrentGet(&mdl); ProExtdataInit(mdl); ProExtdataLoadAll(mdl); Proplus_ext_manager cm(mdl); Proplus_ext_class &cl=*cm.ClassVector()[0]; DBG("solts list"); for (int i=0;i<cl.SoltsVector().size();++i) { Proplus_ext_solt*ptr=cl.SoltsVector()[i]; DBG_INT_(ptr->GetDataType()); DBG_INT_(ptr->GetDataLen()); DBG(ptr->GetSoltName()); DBG_INT_(ptr->GetID()); DBG(ptr->GetInfoMsg()); if(ptr->GetDataType()==1) { DBG("int"); int x=*(int*)ptr->GetValue(); DBG_INT(x); } if(ptr->GetDataType()==2) { DBG("double"); double x=*(double*)ptr->GetValue(); DBG_DOU_(x); } if(ptr->GetDataType()==3) { DBG("string"); char* x=(char*)ptr->GetValue(); int len=strlen(x); DBG_INT_(len); DBG(x); } if(ptr->GetDataType()==4) { DBG("void*"); DBG(ptr->GetInfoMsg()); struct st { char c[100]; int len; double d; ProName name; }; st*c=(st*)ptr->GetValue(); DBG(c->c); DBG_INT_(c->len); DBG_DOU_(c->d); char buf[200]; ProWstringToString(buf,c->name); DBG(buf); } } } void ext_test::test_read_huge_data() { ProMdl mdl; ProMdlCurrentGet(&mdl); ProExtdataInit(mdl); Proplus_ext_manager cm(mdl); Proplus_ext_class &cl=*cm.ClassVector()[0]; CString ds="E:\\temp\\ds\\"; int n=cl.SoltsVector().size(); for (int i=0;i<n;i++) { Proplus_ext_solt*ptr=cl.SoltsVector()[i]; if(!ptr->GetHugeValue()) continue; CString ps=ds+ptr->GetFileName(); DBG(ps); FILE*f=fopen(ps,"wb"); fwrite(ptr->GetHugeValue(),1,ptr->GetHugeDataLen(),f); fclose(f); } } void ext_test::test_del_huge_data() { ProMdl mdl; ProMdlCurrentGet(&mdl); ProExtdataInit(mdl); Proplus_ext_manager cm(mdl); Proplus_ext_class &cl=*cm.ClassVector()[0]; cl.DeleteAllSolts(); ProMdlSave(mdl); } void ext_test::test_write_huge_data() { ProMdl mdl; ProMdlCurrentGet(&mdl); ProExtdataInit(mdl); Proplus_ext_manager cm(mdl); Proplus_ext_class &cl=*cm.ClassVector()[0]; /* int sz[]={ 1024*100, 1024*400, 1024*500, 1024*800 }; for (int i=0;i<4;i++) { Proplus_ext_solt*ptr=cl.AddSolt(); char*t=new char[ sz[i] ]; ptr->SetValue_void(t,sz[i]); } */ CString ds="E:\\temp\\"; char* names[]={ "《中国航空材料手册》第1卷.结构钢.不锈钢.pdf", "[神经网络设计].(美国)Hagan.清晰版.pdf", "[讨论]复合材料金属层压板的建模.pdf", "x.exe","x.pdf","图片.rar","MSchart应用.zip" }; for (int i=0;i<7;++i) { CFile f; if(!f.Open(ds+names[i],CFile::modeRead)) continue; void*s=malloc( f.GetLength() ); f.Read(s,f.GetLength()); Proplus_ext_solt*ptr=cl.AddSolt(); ptr->SetValue_void_huge(s,f.GetLength(),names[i]); f.Close(); free(s); } ProMdlSave(mdl); } /************************************************************************/ /* */ /************************************************************************/ Proplus_ext_manager::Proplus_ext_manager(ProMdl mdl) { m_mdl = mdl; Init(); } Proplus_ext_manager::~Proplus_ext_manager() { FreeVector(); } void Proplus_ext_manager::Init() { ProExtdataInit(m_mdl); ProExtdataLoadAll(m_mdl); ProExtdataNamesList names; int n=0; char buf[200]; ProExtdataErr er= ProExtdataClassNamesList(m_mdl,&n,&names); m_status = er==PROEXTDATA_TK_NO_ERROR; m_msg = GetErrorStatus(er); DBG("class list:"); for (int i=0; i<n; ++i ) { ProWstringToString(buf,names[i]); DBG(buf); Proplus_ext_class*ptr=new Proplus_ext_class(m_mdl,buf); m_class_vector.push_back( ptr ); } ProArrayFree((ProArray*)&names); } void Proplus_ext_manager::FreeVector() { for (int i=0; i<m_class_vector.size(); ++i ) { delete m_class_vector[i]; } m_class_vector.clear(); } std::vector<Proplus_ext_class*>&Proplus_ext_manager::ClassVector() { return m_class_vector; } //add and delete class,also delete from proe Proplus_ext_class*Proplus_ext_manager::AddClass(char *class_name) { //check if exists for (int i=0; i<m_class_vector.size(); ++i ) { if ( m_class_vector[i]->GetClassName() == class_name ) { return m_class_vector[i]; } } Proplus_ext_class*ptr=new Proplus_ext_class(m_mdl,class_name); m_class_vector.push_back( ptr ); return ptr; } //从内存中删除 void Proplus_ext_manager::Erase() { ProExtdataTerm(m_mdl); } bool Proplus_ext_manager::DeleteClass(char *class_name) { //check if exists for (int i=0; i<m_class_vector.size(); ++i ) { if ( m_class_vector[i]->GetClassName() == class_name ) { m_class_vector[i]->RemoveFromProe(); delete m_class_vector[i]; return true; } } return false; } void Proplus_ext_manager::DeleteAllClasses() { //check if exists for (int i=0; i<m_class_vector.size(); ++i ) { m_class_vector[i]->RemoveFromProe(); delete m_class_vector[i]; } m_class_vector.clear(); } ProMdl Proplus_ext_manager::GetMdl() { return m_mdl; } //保存模型 void Proplus_ext_manager::SaveMdl() { ProMdlSave(m_mdl); }