存储外部数据
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()[]; //添加一个double数据
Proplus_ext_solt*ptr=cl.AddSolt();
ptr->SetValue_double(12.3,"---val_double"); //添加int数据
ptr=cl.AddSolt();
ptr->SetValue_int(,"---val_int"); //添加string数据
ptr=cl.AddSolt();
ptr->SetValue_string("hello man","---val_string"); /写入二进制数据
struct st
{
char c[];
int len;
double d;
ProName name;
};
st c;
strcpy(c.c,"string value");
c.len=;
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()[];
CString ds="E:\\temp\\"; //文件名称
char* names[]={
"《中国航空材料手册》第卷.结构钢.不锈钢.pdf",
"[神经网络设计].(美国)Hagan.清晰版.pdf",
"[讨论]复合材料金属层压板的建模.pdf",
"x.exe","x.pdf","图片.rar","MSchart应用.zip"
};
for (int i=;i<;++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()[];
DBG("solts list");
for (int i=;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()==)
{
DBG("int");
int x=*(int*)ptr->GetValue();
DBG_INT(x);
}
if(ptr->GetDataType()==)
{
DBG("double");
double x=*(double*)ptr->GetValue();
DBG_DOU_(x);
}
if(ptr->GetDataType()==)
{
DBG("string");
char* x=(char*)ptr->GetValue();
int len=strlen(x);
DBG_INT_(len);
DBG(x); }
if(ptr->GetDataType()==)
{
DBG("void*");
DBG(ptr->GetInfoMsg());
struct st
{
char c[];
int len;
double d;
ProName name;
};
st*c=(st*)ptr->GetValue(); DBG(c->c);
DBG_INT_(c->len);
DBG_DOU_(c->d); char buf[];
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()[]; CString ds="E:\\temp\\ds\\";
int n=cl.SoltsVector().size();
for (int i=;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(),,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+];//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[];
CString str; m_pProplus_ext_class=pclass;
m_len_of_huge_data = ;
m_phuge_data = ;
m_data_format=;
m_len_of_data = ;
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=;
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=;
m_data_format=;
m_len_of_data = ;
m_len_of_huge_data = ;
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-;
memcpy(pdata+sizeof(int),info_msg,len+ );
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 = ;
m_data_type = ;
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 = ;
m_data_type = ;
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 = ;
m_data_type = ;
m_data_format = FormatData(m_data_type,strlen(v)+,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 = ;
m_data_type = ;
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 = ;
m_data_type = ;
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=,*p_temp,*p_head;
int body_len=;
int index=;
CString str;
char buf[]; p_body = h_sep_data(m_phuge_data,len,body_len,index++);
while (p_body)
{
p_temp = ;
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=;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 = ;
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()>)
{
/*
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=;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[];
char *p_head=
(char*)GetValue();
for (int i=; 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-);
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 != )
return NULL;
return m_phuge_data;
}
void*Proplus_ext_solt::GetValue()
{
int len=;
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[];
ProWstringToString(buf,m_solt.slot_name);
return buf;
}
/************************************************************************/
/* */
/************************************************************************/
Proplus_ext_class::Proplus_ext_class(ProMdl mdl,char*class_name)
{
char buf[];
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=;
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=;
char buf[]; 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=; 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=;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=; i<m_Proplus_ext_solt_vector.size(); ++i )
{
delete m_Proplus_ext_solt_vector[i];
}
m_Proplus_ext_solt_vector.clear();
for (int i=; 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=;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=;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=; 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 ()
{ for (int i=;i<m_Proplus_ext_solt_vector.size();++i)
{
Proplus_ext_solt*ptr=m_Proplus_ext_solt_vector[i];
if (ptr->GetDataType()==)//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=; for (int i=;i<m_Proplus_ext_solt_body_vector.size();++i)
{
Proplus_ext_solt*sr=m_Proplus_ext_solt_body_vector[i];
if (sr->GetDataType()==)//void*
{
CString str=sr->GetInfoMsg();
if( str== HUGE_DATA_BODY_TAG )
{
for (int k=;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=;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=; 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()[]; Proplus_ext_solt*ptr=cl.AddSolt();
ptr->SetValue_double(12.3,"---val_double"); ptr=cl.AddSolt();
ptr->SetValue_int(,"---val_int"); ptr=cl.AddSolt();
ptr->SetValue_string("hello man","---val_string"); //add struct
struct st
{
char c[];
int len;
double d;
ProName name;
};
st c;
strcpy(c.c,"我手机哦艰苦艰苦艰可i刻录机空间苦艰苦艰苦机");
c.len=;
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()[]; DBG("solts list");
for (int i=;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()==)
{
DBG("int");
int x=*(int*)ptr->GetValue();
DBG_INT(x);
}
if(ptr->GetDataType()==)
{
DBG("double");
double x=*(double*)ptr->GetValue();
DBG_DOU_(x);
}
if(ptr->GetDataType()==)
{
DBG("string");
char* x=(char*)ptr->GetValue();
int len=strlen(x);
DBG_INT_(len);
DBG(x); }
if(ptr->GetDataType()==)
{
DBG("void*");
DBG(ptr->GetInfoMsg());
struct st
{
char c[];
int len;
double d;
ProName name;
};
st*c=(st*)ptr->GetValue(); DBG(c->c);
DBG_INT_(c->len);
DBG_DOU_(c->d); char buf[];
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()[]; CString ds="E:\\temp\\ds\\";
int n=cl.SoltsVector().size();
for (int i=;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(),,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()[]; 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()[]; /*
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=;i<;++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=;
char buf[]; ProExtdataErr er=
ProExtdataClassNamesList(m_mdl,&n,&names); m_status = er==PROEXTDATA_TK_NO_ERROR;
m_msg = GetErrorStatus(er); DBG("class list:");
for (int i=; 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=; 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=; 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=; 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=; 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);
}