在proe模型文件里面存储用户数据

存储外部数据

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();


};
View Code

 

.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);
}
View Code

 

 

 

 

posted on 2014-02-22 13:19  DoJustForFun  阅读(1476)  评论(0编辑  收藏  举报

导航