OCAF save/open

Hi, everyone.
I am working on an OCAF document, I build a framework but I can't save my OCAF doc (generated with the OcafAppWizard). it produces a zero length file, which obviously can not be open.
I use open CASCADE 6.3.0 compiled with Visual Studio 6.0, all the environment variables are set.
I found this trouble in a lot of topic but no solution. Did anyone resolve it?

golden tiger's picture

One thing I want to say firstly is that this is not the resolution of the question above.It is just a explanation for it, and I will show the directed question which causes the question above.I will take the OCAF open function for example to detail it.
In the OCAF framwork which generated by the OcafAppWizard, when we want to open a file with the extension sta,such as OCAF1.sta ,we will find an error in it.Detailedly,It is happened in the function:
BOOL C***Doc::OnOpenDocument(LPCTSTR lpszPathName)
and the error sentence is:
CDF_RetrievableStatus RS = m_App->Open(TPath, OCAFDoc);
The function of this sentence we want is to open a file with the path (TPath )and to create a document object ( OCAFDoc ) to get the data in the file.but the problem is that we do not create the document object-- OCAFDoc
correctly in the sentence( you will find the OCAFDoc is still NULL with the function OCAFDoc.IsNull() ),So that in the next sentence
TPrsStd_AISViewer::New(OCAFDoc->Main(),myViewer);
the parameter OCAFDoc->Main() is can not be gotten because the OCAFDoc is NULL and as a result an error is raised in VC.
So we have to analyze the function m_App->Open(TPath, OCAFDoc) and find the question inside the source code of occ which cause the problem.
Below is the analyzation of it.

golden tiger's picture

Follow the above.
When an OCAF framework is generated,in the constructor of application( C***App::C***App() ),we can find that the environment variable has been set .In detail,that is CSF_ResourcesDefaults and CSF_PluginDefaults been
set as project directory.
In the directory ,we can find a file named of which the content like this:
/////////////////////////////////////
formatlist:MyFormat
MyFormat.Description: MyFormat Document Version 1.0
MyFormat.FileExtension: sta
MyFormat.StoragePlugin: ad696000-5b34-11d1-b5ba-00a0c9064368
MyFormat.RetrievalPlugin: ad696001-5b34-11d1-b5ba-00a0c9064368
MyFormatSchema: ad696002-5b34-11d1-b5ba-00a0c9064368
MyFormat.AttributeStoragePlugin: 47b0b826-d931-11d1-b5da-00a0c9064368
MyFormat.AttributeRetrievalPlugin: 47b0b827-d931-11d1-b5da-00a0c9064368
/////////////////////////////////////
In the source code of function < m_App->Open(TPath, OCAFDoc); >,The file is read when the environment variable has been set as the project directory(hehe, that is a fact as above detailed ).
The purpose of reading the file is to save the content. In the source code ,the content of the file is saved in a data structure named .It is no need for us to know the structure very well,we just need to see the analogous structure .For any person who has studied the C Language,the structure is just a small
case.The main contents in we mentioned are The Index and The Value,when want to find The Value been saved in ( The form of The Value is a[i]),we need to find The Index firstly.Similarly, the structure also have two main contents:
The Key and The Item.The using of the Key is liked as The Index in array while The Item liked as The Value.The only difference is both The Key and The Item must be saved in ,while in just The Value should be saved ,The Index is computed by computer inside.
we can detail the contents in
like this:(it just a look but not the structure inside)
////////////////////////////////////////////////////////////////////
counter| The Key |The Item
------------------------------------------------------------------------
0 |formatlist |MyFormat
------------------------------------------------------------------------
1 |MyFormat.Description |MyFormat Document Version 1.0
------------------------------------------------------------------------
2 |MyFormat.FileExtension |sta
------------------------------------------------------------------------
3 |MyFormat.StoragePlugin |ad696000-5b34-11d1-b5ba-00a0c9064368
------------------------------------------------------------------------
4 |MyFormat.RetrievalPlugin |ad696001-5b34-11d1-b5ba-00a0c9064368
------------------------------------------------------------------------
5 |MyFormatSchema |ad696002-5b34-11d1-b5ba-00a0c9064368
------------------------------------------------------------------------
6 |MyFormat.AttributeStoragePlugin |47b0b826-d931-11d1-b5da-00a0c9064368
------------------------------------------------------------------------
7 |MyFormat.AttributeRetrievalPlugin |47b0b827-d931-11d1-b5da-00a0c9064368
------------------------------------------------------------------------
comment:The contents are saved in a
typed object , not or others.
I do not find error in this Saving Step.

golden tiger's picture

The error is found in the Find Step.the Find Step is used to Tell whether a resource exits.The code is:
//=======================================================================
//function : Find
//purpose : Tells if a resource exits.
//=======================================================================
Standard_Boolean Resource_Manager::Find(const Standard_CString aResource) const
{
TCollection_AsciiString Resource(aResource);
if (myUserMap.IsBound(Resource) || myRefMap.IsBound(Resource))
return Standard_True;
return Standard_False;
}
////////////////////////////////////////////////////////////////////////
To this code we just have to know that the return value of the function must be Standard_True,or the Open error will occur.The parameter is "MyFormat.RetrievalPlugin" when we want to open a ocaf file.
Now the function myRefMap.IsBound(Resource) is used to find if the parameter value can be find in myRefMap.TheKey which has been shown in the table above (=>counter 4).
So we can think that the Find function should and always return Standard_True,
and as a result the framework's open function will always be OK!
But now the error happens ,we then find the code detailedly.Then The Error jumps out:in this sentence -- < TCollection_AsciiString , Resource(aResource);>.
The right thing is that after the constructor of TCollection_AsciiString ,the relative value is :
aResource="MyFormat.RetrievalPlugin"; address=0x023e1fbc
Resource.mystring="MyFormat.RetrievalPlugin"; address=0x0e4f000c
Resource.mylength=24;
We can find the address is Different!

but now the value is :
aResource=""; address=0x023e1fbc
Resource.mystring=""; address=0x023e1fbc
Resource.mylength=24;
This time We can find the address is the same!

So the question of the Open function is just the question of the constructor of TCollection_AsciiString ,or more detailedly of this sentenct :
/////////////////////////////////////////////////////////////////////
TCollection_AsciiString::TCollection_AsciiString(const Standard_CString astring)
: mystring(0)
{
...
mystring = (Standard_CString)Standard::Allocate(ROUNDMEM(mylength+1));
...

}
So we can also say that it is a question of Standard::Allocate.

golden tiger's picture

In conclusion,
the question of the Open function <=> the question of the constructor of TCollection_AsciiString <=> the question of Standard::Allocate

Below I will give the test samples and show where the exact question is . Unfortunately ,I can just go to this step ,If somebady who can solve the question,Please shows the solution and receives my thankness.

golden tiger's picture

The test samples:used to test Standard::Allocate.
//1. input object for the test sample --> astring

//--situation 1 : Standard_CString =>Standard_CString(copy)
Standard_CString astring="MyFormat.RetrievalPlugin";

//--situation 2 : TCollection_AsciiString =>Standard_CString =>Standard_CString(copy)

TCollection_AsciiString ResourceName;
ResourceName="MyFormat";
ResourceName+=".RetrievalPlugin";
Standard_CString astring= ResourceName.ToCString();

//--situation 3: TCollection_ExtendedString=>Standard_CString =>Standard_CString(copy)

TCollection_ExtendedString ResourceName;
ResourceName="MyFormat";
ResourceName+=".RetrievalPlugin";

Standard_CString astring = ASCII(ResourceName).ToCString();

//2 test sample
Standard_CString mystring=0;
Standard_Integer mylength=0;

{
if (astring) {
//2.1 get length
STRLEN(astring,mylength);

//2.2 allocate and initialize
mystring = (Standard_CString)Standard::Allocate(ROUNDMEM(mylength+1));

//2.3 copy
STRCPY(mystring,astring,mylength);
mystring[mylength] = '\0';
}

//3. result
//--situation 1:
---//astring="MyFormat.RetrievalPlugin"; address=0x0063f4bc;
---//mystring="MyFormat.RetrievalPlugin"; address=0x023e15b0;
---//mylength=24;
conclusion: right

golden tiger's picture

The test samples:used to test Standard::Allocate.
//1. input object for the test sample --> astring

//--situation 1 : Standard_CString =>Standard_CString(copy)
Standard_CString astring="MyFormat.RetrievalPlugin";

//--situation 2 : TCollection_AsciiString =>Standard_CString =>Standard_CString(copy)

TCollection_AsciiString ResourceName;
ResourceName="MyFormat";
ResourceName+=".RetrievalPlugin";
Standard_CString astring= ResourceName.ToCString();

//--situation 3: TCollection_ExtendedString=>Standard_CString =>Standard_CString(copy)

TCollection_ExtendedString ResourceName;
ResourceName="MyFormat";
ResourceName+=".RetrievalPlugin";

Standard_CString astring = ASCII(ResourceName).ToCString();

//2 test sample
Standard_CString mystring=0;
Standard_Integer mylength=0;

{
if (astring) {
//2.1 get length
STRLEN(astring,mylength);

//2.2 allocate and initialize
mystring = (Standard_CString)Standard::Allocate(ROUNDMEM(mylength+1));

//2.3 copy
STRCPY(mystring,astring,mylength);
mystring[mylength] = '\0';
}

//3. result
//--situation 1:
---//astring="MyFormat.RetrievalPlugin"; address=0x0063f4bc;
---//mystring="MyFormat.RetrievalPlugin"; address=0x023e15b0;
---//mylength=24;
conclusion: right

golden tiger's picture

//--situation 2:
---//astring="MyFormat.RetrievalPlugin"; address=0x023e15b0;
---//mystring="MyFormat.RetrievalPlugin"; address=0x023e1fbc;
---//mylength=24;
conclusion: right

//--situation 3:

---//before Standard::Allocate
astring="MyFormat.RetrievalPlugin"; address=0x023e1fbc;
---//after Standard::Allocate
astring=""; address=0x023e1fbc;
---//mystring=""; address=0x023e1fbc;
---//mylength=24;
conclusion: wrong

//--something needed:

#include

#define MaxChar 10000
static Standard_Character longtc[MaxChar];
static Standard_CString aLongCString = longtc;
static TCollection_ExtendedString outExtendedString;

static TCollection_AsciiString ASCII(const TCollection_ExtendedString& anXString) {
Resource_Unicode::ConvertUnicodeToFormat(anXString,aLongCString,MaxChar);
return TCollection_AsciiString(aLongCString);
}

//4.My trouble
The OCC source code for open function uses the to generate the object Resource.mystring(see below).

//=======================================================================
//function : Find
//purpose : Tells if a resource exits.
//=======================================================================
Standard_Boolean Resource_Manager::Find(const Standard_CString aResource) const
{
TCollection_AsciiString Resource(aResource);
if (myUserMap.IsBound(Resource) || myRefMap.IsBound(Resource))
return Standard_True;
return Standard_False;
}

So we have to make an effort to solve the 's question,then the question about Open function will be solved indirectly .

fatmice's picture

Thank you for your help!!!
you are right,nobody can sovle the problem?

fatmice's picture

why nobady?