1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-06 18:26:22 +03:00
occt/src/StepData/StepData_StepWriter.cxx
bugmaster b311480ed5 0023024: Update headers of OCCT files
Added appropriate copyright and license information in source files
2012-03-21 19:43:04 +04:00

1172 lines
37 KiB
C++
Executable File

// Copyright (c) 1999-2012 OPEN CASCADE SAS
//
// The content of this file is subject to the Open CASCADE Technology Public
// License Version 6.5 (the "License"). You may not use the content of this file
// except in compliance with the License. Please obtain a copy of the License
// at http://www.opencascade.org and read it completely before using this file.
//
// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
//
// The Original Code and all software distributed under the License is
// distributed on an "AS IS" basis, without warranty of any kind, and the
// Initial Developer hereby disclaims all such warranties, including without
// limitation, any warranties of merchantability, fitness for a particular
// purpose or non-infringement. Please see the License for the specific terms
// and conditions governing the rights and limitations under the License.
// List of changes:
//skl 29.01.2003 - deleted one space symbol at the begining
// of strings from Header Section
#include <StepData_StepWriter.ixx>
#include <StepData_WriterLib.hxx>
#include <StepData_ReadWriteModule.hxx>
#include <StepData_Protocol.hxx>
#include <StepData_UndefinedEntity.hxx>
#include <TCollection_HAsciiString.hxx>
#include <StepData_SelectMember.hxx>
#include <StepData_SelectArrReal.hxx>
#include <Interface_EntityIterator.hxx>
#include <Interface_ReportEntity.hxx>
#include <Interface_Check.hxx>
#include <Interface_InterfaceMismatch.hxx>
#include <Standard_NoSuchObject.hxx>
#include <Interface_Macros.hxx>
#include <stdio.h>
#define StepLong 72
// StepLong : longueur maxi d une ligne de fichier Step
// Constantes litterales (interessantes, pour les performances ET LA MEMOIRE)
static TCollection_AsciiString textscope (" &SCOPE");
static TCollection_AsciiString textendscope (" ENDSCOPE");
static TCollection_AsciiString textcomm (" /* ");
static TCollection_AsciiString textendcomm (" */");
static TCollection_AsciiString textlist ("(");
static TCollection_AsciiString textendlist (")");
static TCollection_AsciiString textendent (");");
static TCollection_AsciiString textparam (",");
static TCollection_AsciiString textundef ("$");
static TCollection_AsciiString textderived ("*");
static TCollection_AsciiString texttrue (".T.");
static TCollection_AsciiString textfalse (".F.");
static TCollection_AsciiString textunknown (".U.");
//=======================================================================
//function : StepData_StepWriter
//purpose :
//=======================================================================
StepData_StepWriter::StepData_StepWriter(const Handle(StepData_StepModel)& amodel)
: thecurr (StepLong) , thefloatw (12)
{
themodel = amodel; thelabmode = thetypmode = 0;
thefile = new TColStd_HSequenceOfHAsciiString();
thesect = Standard_False; thefirst = Standard_True;
themult = Standard_False; thecomm = Standard_False;
thelevel = theindval = 0; theindent = Standard_False;
// Format flottant : reporte dans le FloatWriter
}
// .... Controle d Envoi des Flottants ....
//=======================================================================
//function : FloatWriter
//purpose :
//=======================================================================
Interface_FloatWriter& StepData_StepWriter::FloatWriter ()
{ return thefloatw; } // s y reporter
//=======================================================================
//function : LabelMode
//purpose :
//=======================================================================
Standard_Integer& StepData_StepWriter::LabelMode ()
{ return thelabmode; }
//=======================================================================
//function : TypeMode
//purpose :
//=======================================================================
Standard_Integer& StepData_StepWriter::TypeMode ()
{ return thetypmode; }
// .... Description des Scopes (AVANT Envoi) ....
//=======================================================================
//function : SetScope
//purpose :
//=======================================================================
void StepData_StepWriter::SetScope (const Standard_Integer numscope,
const Standard_Integer numin)
{
Standard_Integer nb = themodel->NbEntities();
if (numscope <= 0 || numscope > nb || numin <= 0 || numin > nb)
Interface_InterfaceMismatch::Raise("StepWriter : SetScope, out of range");
if (thescopenext.IsNull()) {
thescopebeg = new TColStd_HArray1OfInteger (1,nb); thescopebeg->Init(0);
thescopeend = new TColStd_HArray1OfInteger (1,nb); thescopeend->Init(0);
thescopenext = new TColStd_HArray1OfInteger (1,nb); thescopenext->Init(0);
}
else if (thescopenext->Value(numin) != 0) {
#ifdef DEB
cout << "StepWriter : SetScope (scope : " << numscope << " entity : "
<< numin << "), Entity already in a Scope"<<endl;
#endif
Interface_InterfaceMismatch::Raise("StepWriter : SetScope, already set");
}
thescopenext->SetValue(numin,-1); // nouvelle fin de scope
if (thescopebeg->Value(numscope) == 0) thescopebeg->SetValue(numscope,numin);
Standard_Integer lastin = thescopeend->Value(numscope);
if (lastin > 0) thescopenext->SetValue(lastin,numin);
thescopeend->SetValue(numscope,numin);
}
//=======================================================================
//function : IsInScope
//purpose :
//=======================================================================
Standard_Boolean StepData_StepWriter::IsInScope(const Standard_Integer num) const
{
if (thescopenext.IsNull()) return Standard_False;
return (thescopenext->Value(num) != 0);
}
// ###########################################################################
// ## ## ## ## ENVOI DES SECTIONS ## ## ## ##
// .... Envoi du Modele Complet ....
//=======================================================================
//function : SendModel
//purpose :
//=======================================================================
void StepData_StepWriter::SendModel(const Handle(StepData_Protocol)& protocol,
const Standard_Boolean headeronly)
{
StepData_WriterLib lib(protocol);
if (!headeronly)
thefile->Append (new TCollection_HAsciiString("ISO-10303-21;"));
SendHeader();
// .... Header : suite d entites sans Ident ....
Interface_EntityIterator header = themodel->Header();
thenum = 0;
for (header.Start(); header.More(); header.Next()) {
Handle(Standard_Transient) anent = header.Value();
// Write Entity via Lib (similaire a SendEntity)
Handle(StepData_ReadWriteModule) module; Standard_Integer CN;
if (lib.Select(anent,module,CN)) {
if (module->IsComplex(CN)) StartComplex();
else {
TCollection_AsciiString styp;
if (thetypmode > 0) styp = module->ShortType(CN);
if (styp.Length() == 0) styp = module->StepType(CN);
StartEntity (styp);
}
module->WriteStep(CN,*this,anent);
if (module->IsComplex(CN)) EndComplex();
} else {
// Pas trouve ci-dessus ... tenter UndefinedEntity
DeclareAndCast(StepData_UndefinedEntity,und,anent);
if (und.IsNull()) continue;
if (und->IsComplex()) StartComplex();
und->WriteParams(*this);
if (und->IsComplex()) EndComplex();
}
EndEntity ();
}
EndSec();
if (headeronly) return;
// Data : Comme Header mais avec des Idents ... sinon le code est le meme
SendData();
// .... Erreurs Globales (silya) ....
Handle(Interface_Check) achglob = themodel->GlobalCheck();
Standard_Integer nbfails = achglob->NbFails();
if (nbfails > 0) {
Comment(Standard_True);
SendComment("GLOBAL FAIL MESSAGES, recorded at Read time :");
for (Standard_Integer ifail = 1; ifail <= nbfails; ifail ++) {
SendComment (achglob->Fail(ifail));
}
Comment(Standard_False);
NewLine(Standard_False);
}
// .... Sortie des Entites une par une ....
Standard_Integer nb = themodel->NbEntities();
for (Standard_Integer i = 1 ; i <= nb; i ++) {
// Liste principale : on n envoie pas les Entites dans un Scope
// Elles le seront par l intermediaire du Scope qui les contient
if (!thescopebeg.IsNull()) { if (thescopenext->Value(i) != 0) continue; }
SendEntity (i,lib);
}
EndSec();
EndFile();
}
// .... DECOUPAGE DU FICHIER EN SECTIONS ....
//=======================================================================
//function : SendHeader
//purpose :
//=======================================================================
void StepData_StepWriter::SendHeader ()
{
NewLine(Standard_False);
thefile->Append (new TCollection_HAsciiString("HEADER;"));
thesect = Standard_True;
}
//=======================================================================
//function : SendData
//purpose :
//=======================================================================
void StepData_StepWriter::SendData ()
{
if (thesect) Interface_InterfaceMismatch::Raise("StepWriter : Data section");
NewLine(Standard_False);
thefile->Append (new TCollection_HAsciiString("DATA;"));
thesect = Standard_True;
}
//=======================================================================
//function : EndSec
//purpose :
//=======================================================================
void StepData_StepWriter::EndSec ()
{
thefile->Append (new TCollection_HAsciiString("ENDSEC;"));
thesect = Standard_False;
}
//=======================================================================
//function : EndFile
//purpose :
//=======================================================================
void StepData_StepWriter::EndFile ()
{
if (thesect) Interface_InterfaceMismatch::Raise("StepWriter : EndFile");
NewLine(Standard_False);
thefile->Append (new TCollection_HAsciiString("END-ISO-10303-21;"));
thesect = Standard_False;
}
// .... ENVOI D UNE ENTITE ....
//=======================================================================
//function : SendEntity
//purpose :
//=======================================================================
void StepData_StepWriter::SendEntity(const Standard_Integer num,
const StepData_WriterLib& lib)
{
char lident[20];
Handle(Standard_Transient) anent = themodel->Entity(num);
Standard_Integer idnum = num , idtrue = 0;
// themodel->Number(anent) et-ou IdentLabel(anent)
if (thelabmode > 0) idtrue = themodel->IdentLabel(anent);
if (thelabmode == 1) idnum = idtrue;
if (idnum == 0) idnum = num;
if (thelabmode < 2 || idnum == idtrue) sprintf(lident,"#%d = ",idnum); //skl 29.01.2003
else sprintf(lident,"%d:#%d = ",idnum,idtrue); //skl 29.01.2003
// SendIdent repris , lident vient d etre calcule
thecurr.Clear();
thecurr.Add (lident);
themult = Standard_False;
// .... Traitement du Scope Eventuel
if (!thescopebeg.IsNull()) {
Standard_Integer numin = thescopebeg->Value(num);
if (numin != 0) {
SendScope();
for (Standard_Integer nument = numin; numin > 0; nument = numin) {
SendEntity(nument,lib);
numin = thescopenext->Value(nument);
}
SendEndscope();
}
}
// .... Envoi de l Entite proprement dite
// Write Entity via Lib
thenum = num;
Handle(StepData_ReadWriteModule) module; Standard_Integer CN;
if (themodel->IsRedefinedContent(num)) {
// Entite Erreur : Ecrire le Contenu + les Erreurs en Commentaires
Handle(Interface_ReportEntity) rep = themodel->ReportEntity(num);
DeclareAndCast(StepData_UndefinedEntity,und,rep->Content());
if (und.IsNull()) {
thechecks.CCheck(num)->AddFail("Erroneous Entity, Content lost");
StartEntity(TCollection_AsciiString("!?LOST_DATA"));
} else {
thechecks.CCheck(num)->AddWarning("Erroneous Entity, equivalent content");
if (und->IsComplex()) AddString(" (",2);
und->WriteParams(*this);
if (und->IsComplex()) { AddString(") ",2); } //thelevel --; }
}
EndEntity (); // AVANT les Commentaires
NewLine(Standard_False);
Comment(Standard_True);
if (und.IsNull()) SendComment(" ERRONEOUS ENTITY, DATA LOST");
SendComment("On Entity above, Fail Messages recorded at Read time :");
Handle(Interface_Check) ach = rep->Check();
Standard_Integer nbfails = ach->NbFails();
for (Standard_Integer ifail = 1; ifail <= nbfails; ifail ++) {
SendComment (ach->Fail(ifail));
}
Comment(Standard_False);
NewLine(Standard_False);
// Cas normal
}
else if (lib.Select(anent,module,CN)) {
if (module->IsComplex(CN)) StartComplex();
else {
TCollection_AsciiString styp;
if (thetypmode > 0) styp = module->ShortType(CN);
if (styp.Length() == 0) styp = module->StepType(CN);
StartEntity (styp);
}
module->WriteStep(CN,*this,anent);
if (module->IsComplex(CN)) EndComplex();
EndEntity ();
}
else {
// Pas trouve ci-dessus ... tenter UndefinedEntity
DeclareAndCast(StepData_UndefinedEntity,und,anent);
if (und.IsNull()) return;
if (und->IsComplex()) StartComplex();
und->WriteParams(*this);
if (und->IsComplex()) EndComplex();
EndEntity ();
}
}
// ###########################################################################
// ## ## ## CONSTITUTION DU TEXTE A ENVOYER ## ## ##
// Passer a la ligne. Ligne vide pas comptee sauf si evenempty == Standard_True
//=======================================================================
//function : NewLine
//purpose :
//=======================================================================
void StepData_StepWriter::NewLine (const Standard_Boolean evenempty)
{
if (evenempty || thecurr.Length() > 0) {
thefile->Append(thecurr.Moved());
}
Standard_Integer indst = thelevel * 2; if (theindent) indst += theindval;
thecurr.SetInitial(indst); thecurr.Clear();
}
// Regrouper ligne en cours avec precedente; reste en cours sauf si newline
// == Standard_True, auquel cas on commence une nouvelle ligne
// Ne fait rien si : total correspondant > StepLong ou debut ou fin d`entite
//=======================================================================
//function : JoinLast
//purpose :
//=======================================================================
void StepData_StepWriter::JoinLast (const Standard_Boolean newline)
{
/*
Handle(TCollection_HAsciiString) lst = thefile->Last();
Standard_Integer lng = lst->Length();
if (thecurr.Length() == 0) return;
if (lng + thecurr.Length() > StepLong) return;
if (lst->Value(1) == '#' || lst->Search(";") > 0) return;
lst->AssignCat(thecurr.Moved());
if (!newline) {
thecurr.Add (lst->ToCString(),lst->Length());
thefile->Remove(thefile->Length());
thecurr.SetInitial(0); .. inclus dans lst ...
}
*/
thecurr.SetKeep();
}
//=======================================================================
//function : Indent
//purpose :
//=======================================================================
void StepData_StepWriter::Indent (const Standard_Boolean onent)
{ theindent = onent; }
//=======================================================================
//function : SendIdent
//purpose :
//=======================================================================
void StepData_StepWriter::SendIdent(const Standard_Integer ident)
{
char lident[12];
sprintf(lident,"#%d =",ident);
thecurr.Clear();
thecurr.Add (lident);
themult = Standard_False;
}
//=======================================================================
//function : SendScope
//purpose :
//=======================================================================
void StepData_StepWriter::SendScope ()
{ AddString(textscope); }
//=======================================================================
//function : SendEndscope
//purpose :
//=======================================================================
void StepData_StepWriter::SendEndscope ()
{
NewLine(Standard_False);
thefile->Append(new TCollection_HAsciiString(textendscope));
}
//=======================================================================
//function : Comment
//purpose :
//=======================================================================
void StepData_StepWriter::Comment (const Standard_Boolean mode)
{
if (mode && !thecomm) AddString(textcomm,20);
if (!mode && thecomm) AddString(textendcomm);
thecomm = mode;
}
//=======================================================================
//function : SendComment
//purpose :
//=======================================================================
void StepData_StepWriter::SendComment(const Handle(TCollection_HAsciiString)& text)
{
if (!thecomm) Interface_InterfaceMismatch::Raise("StepWriter : Comment");
AddString(text->ToCString(),text->Length());
}
//=======================================================================
//function : SendComment
//purpose :
//=======================================================================
void StepData_StepWriter::SendComment (const Standard_CString text)
{
if (!thecomm) Interface_InterfaceMismatch::Raise("StepWriter : Comment");
AddString(text,strlen(text));
}
//=======================================================================
//function : StartEntity
//purpose :
//=======================================================================
void StepData_StepWriter::StartEntity(const TCollection_AsciiString& atype)
{
if (atype.Length() == 0) return;
if (themult) {
if (thelevel != 1) Interface_InterfaceMismatch::Raise
("StepWriter : StartEntity"); // decompte de parentheses mauvais ...
AddString(textendlist);
AddString(" ",1); //skl 29.01.2003
}
themult = Standard_True;
//AddString(" ",1); //skl 29.01.2003
AddString(atype);
thelevel = 0;
theindval = thecurr.Length();
thecurr.SetInitial(0);
thefirst = Standard_True;
OpenSub();
}
//=======================================================================
//function : StartComplex
//purpose :
//=======================================================================
void StepData_StepWriter::StartComplex ()
{
AddString("( ",2); //skl 29.01.2003
} // thelevel unchanged
//=======================================================================
//function : EndComplex
//purpose :
//=======================================================================
void StepData_StepWriter::EndComplex ()
{ AddString(") ",2); } // thelevel unchanged
// .... SendField et ce qui va avec
//=======================================================================
//function : SendField
//purpose :
//=======================================================================
void StepData_StepWriter::SendField(const StepData_Field& fild,
const Handle(StepData_PDescr)& descr)
{
Standard_Boolean done = Standard_True;
Standard_Integer kind = fild.Kind (Standard_False); // valeur interne
if (kind == 16) {
DeclareAndCast(StepData_SelectMember,sm,fild.Transient());
SendSelect (sm,descr);
return;
}
switch (kind) {
// ici les cas simples; ensuite on caste et on voit
case 0 : SendUndef(); break;
case 1 : Send (fild.Integer ()); break;
case 2 : SendBoolean (fild.Boolean ()); break;
case 3 : SendLogical (fild.Logical ()); break;
case 4 : SendEnum (fild.EnumText ()); break; // enum : descr ?
case 5 : Send (fild.Real ()); break;
case 6 : Send (fild.String ()); break;
case 7 : Send (fild.Entity ()); break;
case 8 : done = Standard_False; break;
case 9 : SendDerived (); break;
default: done = Standard_False; break;
}
if (done) return;
// Que reste-t-il : les tableaux ...
Standard_Integer arity = fild.Arity();
if (arity == 0) { SendUndef(); return; } // PAS NORMAL
if (arity == 1) {
OpenSub();
Standard_Integer i,low = fild.Lower(), up = low + fild.Length() - 1;
for (i = low; i <= up; i ++) {
kind = fild.ItemKind(i);
done = Standard_True;
switch (kind) {
case 0 : SendUndef(); break;
case 1 : Send (fild.Integer (i)); break;
case 2 : SendBoolean (fild.Boolean (i)); break;
case 3 : SendLogical (fild.Logical (i)); break;
case 4 : SendEnum (fild.EnumText (i)); break;
case 5 : Send (fild.Real (i)); break;
case 6 : Send (fild.String (i)); break;
case 7 : Send (fild.Entity (i)); break;
default: SendUndef(); done = Standard_False; break; // ANORMAL
}
}
CloseSub();
return;
}
if (arity == 2) {
OpenSub();
Standard_Integer j,low1 = fild.Lower(1), up1 = low1 + fild.Length(1) - 1;
for (j = low1; j <= up1; j ++) {
Standard_Integer i=0,low2 = fild.Lower(2), up2 = low2 + fild.Length(2) - 1;
OpenSub();
for (i = low2; i <= up2; i ++) {
kind = fild.ItemKind(i,j);
done = Standard_True;
switch (kind) {
case 0 : SendUndef(); break;
case 1 : Send (fild.Integer (i,j)); break;
case 2 : SendBoolean (fild.Boolean (i,j)); break;
case 3 : SendLogical (fild.Logical (i,j)); break;
case 4 : SendEnum (fild.EnumText (i,j)); break;
case 5 : Send (fild.Real (i,j)); break;
case 6 : Send (fild.String (i,j)); break;
case 7 : Send (fild.Entity (i,j)); break;
default: SendUndef(); done = Standard_False; break; // ANORMAL
}
}
CloseSub();
}
CloseSub();
return;
}
}
//=======================================================================
//function : SendSelect
//purpose :
//=======================================================================
void StepData_StepWriter::SendSelect(const Handle(StepData_SelectMember)& sm,
const Handle(StepData_PDescr)& descr)
{
// Cas du SelectMember. Traiter le Select puis la valeur
// NB : traitement actuel non recursif (pas de SELNAME(SELNAME(..)) )
Standard_Boolean selname = Standard_False;
if (sm.IsNull()) return; // ??
if (sm->HasName()) {
selname = Standard_True;
// SendString (sm->Name());
// AddString(textlist); // SANS AJOUT DE PARAMETRE !!
OpenTypedSub (sm->Name());
}
Standard_Integer kind = sm->Kind();
switch (kind) {
case 0 : SendUndef(); break;
case 1 : Send (sm->Integer ()); break;
case 2 : SendBoolean (sm->Boolean ()); break;
case 3 : SendLogical (sm->Logical ()); break;
case 4 : SendEnum (sm->EnumText ()); break; // enum : descr ?
case 5 : Send (sm->Real ()); break;
case 6 : Send (sm->String ()); break;
case 8 : SendArrReal (Handle(StepData_SelectArrReal)::DownCast(sm)->ArrReal()); break;
default: break; // ??
}
if (selname) CloseSub();
}
//=======================================================================
//function : SendList
//purpose :
//=======================================================================
void StepData_StepWriter::SendList(const StepData_FieldList& list,
const Handle(StepData_ESDescr)& descr)
{
// start entity ?
Standard_Integer i, nb = list.NbFields();
for (i = 1; i <= nb; i ++) {
Handle(StepData_PDescr) pde;
if (!descr.IsNull()) pde = descr->Field(i);
const StepData_Field fild = list.Field(i);
SendField (fild,pde);
}
// end entity ?
}
// .... Send* de base
//=======================================================================
//function : OpenSub
//purpose :
//=======================================================================
void StepData_StepWriter::OpenSub ()
{
AddParam();
AddString(textlist);
thefirst = Standard_True;
thelevel ++;
}
//=======================================================================
//function : OpenTypedSub
//purpose :
//=======================================================================
void StepData_StepWriter::OpenTypedSub (const Standard_CString subtype)
{
AddParam();
if (subtype[0] != '\0') AddString (subtype,strlen(subtype));
AddString(textlist);
thefirst = Standard_True;
thelevel ++;
}
//=======================================================================
//function : CloseSub
//purpose :
//=======================================================================
void StepData_StepWriter::CloseSub ()
{
AddString(textendlist);
thefirst = Standard_False; // le parametre suivant une sous-liste n est donc pas 1er
thelevel --;
}
//=======================================================================
//function : AddParam
//purpose :
//=======================================================================
void StepData_StepWriter::AddParam ()
{
if (!thefirst) AddString(textparam);
thefirst = Standard_False;
}
//=======================================================================
//function : Send
//purpose :
//=======================================================================
void StepData_StepWriter::Send (const Standard_Integer val)
{
char lval[12];
AddParam();
sprintf(lval,"%d",val);
AddString(lval,strlen(lval));
}
//=======================================================================
//function : Send
//purpose :
//=======================================================================
void StepData_StepWriter::Send (const Standard_Real val)
{
// Valeur flottante, expurgee de "0000" qui trainent et de "E+00"
char lval[24];
Standard_Integer lng = thefloatw.Write(val,lval);
AddParam();
AddString(lval,lng); // gere le format specifique : si besoin est
}
// Send(String) : attention, on envoie un Texte ... donc entre ' '
//=======================================================================
//function : Send
//purpose :
//=======================================================================
void StepData_StepWriter::Send (const TCollection_AsciiString& val)
{
AddParam();
TCollection_AsciiString aval(val); // on duplique pour trafiquer si besoin
Standard_Integer nb = aval.Length(); Standard_Integer nn = nb;
aval.AssignCat('\''); // comme cela, Insert(i+1) est OK
// Conversion des Caracteres speciaux
for (Standard_Integer i = nb; i > 0; i --) {
char uncar = aval.Value(i);
if (uncar == '\'') { aval.Insert(i+1,'\''); nn ++; continue; }
if (uncar == '\\') { aval.Insert(i+1,'\\'); nn ++; continue; }
if (uncar == '\n') { aval.SetValue(i,'\\'); aval.Insert(i+1,'\\');
aval.Insert(i+1,'N' ); nn += 2; continue; }
if (uncar == '\t') { aval.SetValue(i,'\\'); aval.Insert(i+1,'\\');
aval.Insert(i+1,'T' ); nn += 2; continue; }
}
//:i2 abv 31 Aug 98: ProSTEP TR9: avoid wrapping text or do it at spaces
aval.Insert(1,'\'');
nn += 2;
//:i2 AddString ("\'",1); nn ++;
// Attention au depassement des 72 caracteres
if (thecurr.CanGet(nn)) AddString(aval,0);
//:i2
else {
thefile->Append(thecurr.Moved());
Standard_Integer indst = thelevel * 2; if (theindent) indst += theindval;
if ( indst+nn <= StepLong ) thecurr.SetInitial(indst);
else thecurr.SetInitial(0);
if ( thecurr.CanGet(nn) ) AddString(aval,0);
else {
while ( nn >0 ) {
if (nn <= StepLong) {
thecurr.Add (aval); // Ca yet, on a tout epuise
thecurr.FreezeInitial();
break;
}
Standard_Integer stop = StepLong; // position of last separator
for ( ; stop > 0 && aval.Value(stop) != ' '; stop-- );
if ( ! stop ) {
stop = StepLong;
for ( ; stop > 0 && aval.Value(stop) != '\\'; stop-- );
if ( ! stop ) {
stop = StepLong;
for ( ; stop > 0 && aval.Value(stop) != '_'; stop-- );
if ( ! stop ) stop = StepLong;
}
}
TCollection_AsciiString bval = aval.Split(stop);
thefile->Append(new TCollection_HAsciiString(aval));
aval = bval;
nn -= stop;
}
}
}
/* //:i2
else {
// Il faut tronconner ... lignes limitees a 72 caracteres (StepLong)
Standard_Integer ncurr = thecurr.Length();
Standard_Integer nbuff = StepLong - ncurr;
thecurr.Add (aval.ToCString(),nbuff);
thefile->Append(thecurr.Moved());
aval.Remove(1,nbuff);
nn -= nbuff;
while (nn > 0) {
if (nn <= StepLong) {
thecurr.Add (aval); // Ca yet, on a tout epuise
thecurr.FreezeInitial();
break;
}
TCollection_AsciiString bval = aval.Split(StepLong);
thefile->Append(new TCollection_HAsciiString(bval));
nn -= StepLong;
}
}
//:i2 */
// thecurr.Add('\''); deja mis dans aval au debut
}
//=======================================================================
//function : Send
//purpose :
//=======================================================================
void StepData_StepWriter::Send (const Handle(Standard_Transient)& val)
{
char lident[20];
// Undefined ?
if (val.IsNull()) {
// Interface_InterfaceMismatch::Raise("StepWriter : Sending Null Reference");
thechecks.CCheck(thenum)->AddFail("Null Reference");
SendUndef();
Comment(Standard_True);
SendComment(" NUL REF ");
Comment(Standard_False);
return;
}
Standard_Integer num = themodel->Number(val);
// String ? (si non repertoriee dans le Modele)
if (num == 0) {
if (val->IsKind(STANDARD_TYPE(TCollection_HAsciiString))) {
DeclareAndCast(TCollection_HAsciiString,strval,val);
Send (TCollection_AsciiString(strval->ToCString()));
return;
}
// SelectMember ? (toujours, si non repertoriee)
// mais attention, pas de description attachee
else if (val->IsKind(STANDARD_TYPE(StepData_SelectMember))) {
DeclareAndCast(StepData_SelectMember,sm,val);
Handle(StepData_PDescr) descr; // null
SendSelect (sm,descr);
}
// Sinon, PAS NORMAL !
else {
thechecks.CCheck(thenum)->AddFail("UnknownReference");
SendUndef();
Comment(Standard_True);
SendComment(" UNKNOWN REF ");
Comment(Standard_False);
// Interface_InterfaceMismatch::Raise("StepWriter : Sending Unknown Reference");
}
}
// Cas normal : une bonne Entite, on envoie son Ident.
else {
Standard_Integer idnum = num, idtrue = 0;
if (thelabmode > 0) idtrue = themodel->IdentLabel(val);
if (thelabmode == 1) idnum = idtrue;
if (idnum == 0) idnum = num;
if (thelabmode < 2 || idnum == idtrue) sprintf(lident,"#%d",idnum);
else sprintf(lident,"%d:#%d",idnum,idtrue);
AddParam();
AddString(lident,strlen(lident));
}
}
//=======================================================================
//function : SendBoolean
//purpose :
//=======================================================================
void StepData_StepWriter::SendBoolean (const Standard_Boolean val)
{
if (val) SendString(texttrue);
else SendString(textfalse);
}
//=======================================================================
//function : SendLogical
//purpose :
//=======================================================================
void StepData_StepWriter::SendLogical (const StepData_Logical val)
{
if (val == StepData_LTrue) SendString(texttrue);
else if (val == StepData_LFalse) SendString(textfalse);
else SendString(textunknown);
}
// SendString : attention, on donne l'intitule exact
//=======================================================================
//function : SendString
//purpose :
//=======================================================================
void StepData_StepWriter::SendString (const TCollection_AsciiString& val)
{
AddParam();
AddString(val);
}
// SendString : attention, on donne l'intitule exact
//=======================================================================
//function : SendString
//purpose :
//=======================================================================
void StepData_StepWriter::SendString (const Standard_CString val)
{
AddParam();
AddString(val,strlen(val));
}
// SendEnum : attention, on envoie un intitule d'Enum ... donc entre . .
//=======================================================================
//function : SendEnum
//purpose :
//=======================================================================
void StepData_StepWriter::SendEnum (const TCollection_AsciiString& val)
{
if (val.Length() == 1 && val.Value(1) == '$') { SendUndef(); return; }
AddParam();
TCollection_AsciiString aValue = val;
if (aValue.Value(1) != '.') aValue.Prepend('.');
if (aValue.Value(aValue.Length()) != '.') aValue+='.';
AddString(aValue,2);
}
// SendEnum : attention, on envoie un intitule d'Enum ... donc entre . .
//=======================================================================
//function : SendEnum
//purpose :
//=======================================================================
void StepData_StepWriter::SendEnum (const Standard_CString val)
{
if (val[0] == '$' && val[1] == '\0') { SendUndef(); return; }
TCollection_AsciiString aValue(val);
SendEnum(aValue);
}
//=======================================================================
//function : SendArrReal
//purpose :
//=======================================================================
void StepData_StepWriter::SendArrReal (const Handle(TColStd_HArray1OfReal) &anArr)
{
AddString(textlist);
if(anArr->Length()>0) {
// add real
Send(anArr->Value(1));
for( Standard_Integer i=2; i<=anArr->Length(); i++) {
// AddString(textparam);
//add real
Send(anArr->Value(i));
}
}
AddString(textendlist);
}
//=======================================================================
//function : SendUndef
//purpose :
//=======================================================================
void StepData_StepWriter::SendUndef ()
{
AddParam();
AddString(textundef);
}
//=======================================================================
//function : SendDerived
//purpose :
//=======================================================================
void StepData_StepWriter::SendDerived ()
{
AddParam();
AddString(textderived);
}
// EndEntity : s'il faut mettre ; a la ligne, l'aligner sur debut d'entite ...
//=======================================================================
//function : EndEntity
//purpose :
//=======================================================================
void StepData_StepWriter::EndEntity ()
{
if (thelevel != 1) Interface_InterfaceMismatch::Raise
("StepWriter : EndEntity"); // decompte de parentheses mauvais ...
AddString(textendent);
thelevel = 0; // on garde theindval : sera traite au prochain NewLine
Standard_Boolean indent = theindent; theindent = Standard_False;
NewLine(Standard_False); theindent = indent;
themult = Standard_False;
// pour forcer indentation si necessaire
}
// gestion de la ligne courante (cf aussi NewLine/JoinLine)
//=======================================================================
//function : AddString
//purpose :
//=======================================================================
void StepData_StepWriter::AddString(const TCollection_AsciiString& astr,
const Standard_Integer more)
{
while (!thecurr.CanGet(astr.Length() + more)) {
thefile->Append(thecurr.Moved());
Standard_Integer indst = thelevel * 2; if (theindent) indst += theindval;
thecurr.SetInitial(indst);
}
thecurr.Add(astr);
}
//=======================================================================
//function : AddString
//purpose :
//=======================================================================
void StepData_StepWriter::AddString(const Standard_CString astr,
const Standard_Integer lnstr,
const Standard_Integer more)
{
while (!thecurr.CanGet(lnstr + more)) {
thefile->Append(thecurr.Moved());
Standard_Integer indst = thelevel * 2; if (theindent) indst += theindval;
thecurr.SetInitial(indst);
}
thecurr.Add(astr,lnstr);
}
// ENVOI FINAL
//=======================================================================
//function : CheckList
//purpose :
//=======================================================================
Interface_CheckIterator StepData_StepWriter::CheckList () const
{
return thechecks;
}
//=======================================================================
//function : NbLines
//purpose :
//=======================================================================
Standard_Integer StepData_StepWriter::NbLines () const
{ return thefile->Length(); }
//=======================================================================
//function : Line
//purpose :
//=======================================================================
Handle(TCollection_HAsciiString) StepData_StepWriter::Line
(const Standard_Integer num) const
{ return thefile->Value(num); }
//=======================================================================
//function : Printw
//purpose :
//=======================================================================
Standard_Boolean StepData_StepWriter::Print (Standard_OStream& S)
{
Standard_Boolean isGood = (S.good());
Standard_Integer nb = thefile->Length();
for (Standard_Integer i = 1; i <= nb && isGood; i ++)
S << thefile->Value(i)->ToCString() << "\n";
S<< flush;
isGood = (S && S.good());
return isGood;
}