• 在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 ] ='';
        }
        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
  • 相关阅读:
    perlsplice
    perl中数组函数:delete和grep
    Python字符串格式化
    blast命令解释
    通俗解释托管与非托管
    四、GO语言的转义字符
    六、GO语言的指针
    五、GO语言的变量及数据类型
    一、GO语言的特点
    前台生成验证码案例
  • 原文地址:https://www.cnblogs.com/JustHaveFun-SAN/p/proplus_ext.html
Copyright © 2020-2023  润新知