root/tolp/branches/NameBlockClass/tol/OIS/oisloader.cpp @ 520

Revision 520, 43.5 kB (checked in by vdebuen, 5 years ago)

New member BNameBlock::localName_ and related methods

  • Property svn:eol-style set to native
Line 
1/* oisloader.cpp: main and init functions of GNU/TOL language.
2
3   Copyright (C) 2005-2007, Bayes Decision, SL (Spain [EU])
4
5   This program is free software; you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published by
7   the Free Software Foundation; either version 2, or (at your option)
8   any later version.
9
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU General Public License for more details.
14
15   You should have received a copy of the GNU General Public License
16   along with this program; if not, write to the Free Software
17   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
18   USA.
19 */
20
21//#define TRACE_LEVEL 5
22
23#if defined(_MSC_VER)
24#  include <win_tolinc.h>
25#endif
26
27#include <tol/tol_oisloader.h>
28#include <tol/tol_bdir.h>
29#include <tol/tol_bfilter.h>
30#include <tol/tol_btoken.h>
31#include <tol/tol_bscanner.h>
32#include <tol/tol_bparser.h>
33#include <tol/tol_btmsgrav.h>
34#include <tol/tol_bcodgra.h>
35#include <tol/tol_btsrgra.h>
36#include <tol/tol_bmatgra.h>
37#include <tol/tol_bvmatgra.h>
38#include <tol/tol_bratgra.h>
39#include <tol/tol_btxtgra.h>
40#include <tol/tol_bdtegra.h>
41#include <tol/tol_bnameblock.h>
42#include <tol/tol_bstruct.h>
43
44BTraceInit("oisloader.cpp");
45
46
47//#define TRACE_OIS_HIERARCHY
48#ifdef TRACE_OIS_HIERARCHY
49  static FILE* logHrchyRead_ = 
50  fopen((BSys::TolAppData()+"syslog/OisHierarchyLogRead.log").String,"w");
51#endif
52
53//--------------------------------------------------------------------
54// BOisLoader::BOffsetObject Functions
55//--------------------------------------------------------------------
56
57//--------------------------------------------------------------------
58  BSyntaxObject* BOisLoader::BOffsetObject::PutObject(BSyntaxObject* obj)
59//--------------------------------------------------------------------
60{
61//Std(BText("\nBOisLoader::BOffsetObject::PutObject ")+(int)offset_+",["+(int)obj+"] "+obj->Identify());
62  if(offset_ && obj)
63  {
64    if(obj->OisOffset() && (obj->OisOffset()!=offset_))
65    {
66      ::Warning(I2("OIS Object already has assigned offset",
67                   "El objecto OIS ya tiene offset asignado")+
68                ": "+obj->Identify());
69      return(obj);
70    } 
71    object_ = obj;
72    obj->PutOisOffset(offset_);
73    obj->IncNRefs();
74    return(obj); 
75  }
76  else
77  {
78    if(!offset_) 
79    { 
80      ::Error(I2("OIS cannot assign NULL offset",
81                 "OIS no puede asignar un offset NULO")+
82              ": "+obj->Identify()); 
83    }
84    if(!obj    ) 
85    { 
86      ::Error(I2("OIS cannot assign offset to NULL object",
87                 "OIS no puede asignar un offset al objeto NULO")+
88              ": "+obj->Identify()); 
89    }
90    return(NULL);
91  }
92}
93
94//--------------------------------------------------------------------
95// BOisLoader Functions
96//--------------------------------------------------------------------
97
98//--------------------------------------------------------------------
99  BOisLoader::BOisLoader() 
100//--------------------------------------------------------------------
101: BOis(),
102  data_(NULL),
103  curHrchyPartialPath_(""),
104  checkSourceExists_(false),
105  checkSourceSize_(false),
106  checkSourceDate_(false),
107  obsoleteSource_(false),
108  showCheckingTraces_(false),
109  oisHasPriorityOnConflict_(true),
110  lostSource_(false),
111  tolSources_()
112{ 
113}
114
115
116//--------------------------------------------------------------------
117  BOisLoader::~BOisLoader() 
118//--------------------------------------------------------------------
119{ 
120}
121
122
123#define EnsureFileOpenR(fn,T,N)                     \
124if(! ( fn = streamHandler_->Open(T,SubPath()+N) ) ) \
125{                                                   \
126  return(false);                                    \
127}
128
129//--------------------------------------------------------------------
130  bool BOisLoader::BinError(const char* fileName)
131//--------------------------------------------------------------------
132{
133  return(Error(I2("Corrupted binary file: ",
134                  "Fichero binario corrupto: ")+
135         fileName)); 
136}
137
138
139//--------------------------------------------------------------------
140  bool BOisLoader::Open(bool errorWarning)
141//--------------------------------------------------------------------
142{
143#ifdef TRACE_LEVEL
144  BText fun = BText("BOisLoader::Open()");
145#endif
146  TRACE_SHOW_LOW(fun,"BEGIN");
147  streamHandler_ = BStreamHandler::GetConnect
148  (
149    connection_, 
150    BStreamHandler::BSHOM_READ, 
151    errorWarning
152  );
153  TRACE_SHOW_LOW(fun,"1");
154  if(streamHandler_)
155  {
156    TRACE_SHOW_LOW(fun,"2.1");
157    EnsureFileOpenR(header_,  "header",  "header.xml");
158    header_->SetPos(header_->Bytes()-10);
159    BText foundEnd="NO_FOUND_";
160    header_->Read(foundEnd.Buffer(), 1, 9);
161    foundEnd.PutLength(9);
162    TRACE_SHOW_LOW(fun,"2.2");
163    BText expectedEnd = "</header>";
164    if(foundEnd!=expectedEnd) 
165    { 
166      Error(I2("Corrupted XML file: ",
167               "Fichero XML corrupto: ")+
168            header_->Name()+
169            I2("\nThis file should ends with '",
170               "\nEl fichero debería acabar con '")+
171            expectedEnd+"'"+
172            I2(" instead of with '",
173               " en lugar de con '")+
174            foundEnd+"'");
175      Ensure(false); 
176    }
177    header_->SetPos(0);
178    EnsureFileOpenR(tolref_,  "tolref",  ".tolref"   );
179    EnsureFileOpenR(oisref_,  "oisref",  ".oisref"   );
180    EnsureFileOpenR(object_,  "object",  ".object"   );
181    EnsureFileOpenR(set_,     "set",     ".set"      );
182    EnsureFileOpenR(serie_,   "serie",   ".serie"    );
183    EnsureFileOpenR(timeset_, "timeset", ".timeset"  );
184    EnsureFileOpenR(matrix_,  "matrix",  ".matrix"   );
185    EnsureFileOpenR(polyn_,   "polyn",   ".polyn"    );
186    EnsureFileOpenR(ratio_,   "ratio",   ".ratio"    );
187    EnsureFileOpenR(code_,    "code",    ".code"     );
188    if(streamHandler_->HasFile(SubPath()+".hrchyDetail")) 
189    {
190      EnsureFileOpenR(hrchyDetail_, "hrchyDetail", ".hrchyDetail"    );
191      TRACE_SHOW_LOW(fun,"2.15");
192      EnsureFileOpenR(hrchyOffset_, "hrchyOffset", ".hrchyOffset"    );
193      TRACE_SHOW_LOW(fun,"2.16");
194      EnsureFileOpenR(hrchyOrder_,  "hrchyOrder",  ".hrchyOrder"     );
195      TRACE_SHOW_LOW(fun,"2.17");
196    }
197    EnsureFileOpenR(export_,    "export",    "export.csv"     );
198  }
199  TRACE_SHOW_LOW(fun,"3");
200  SetAllFiles();
201  TRACE_SHOW_LOW(fun,"4");
202  return((streamHandler_!=NULL)&&(streamHandler_->Connected()));
203}
204
205//--------------------------------------------------------------------
206  bool BOisLoader::CheckFileSizes()
207//--------------------------------------------------------------------
208{
209  int n;
210  int numFiles = allFiles_.Size();
211  bool ok = true;
212  BText aux;
213  BText address = SubPath();
214  enable_BSE_=
215    (control_.oisEngine_.oisVersion_>="01.04") &&
216    (control_.oisEngine_.oisVersion_< "01.08");
217  ERead(aux, tolref_ ); if(aux!=address+"/.tolref>\n" ) { return(BinError(".tolref"  )); }
218  ERead(aux, oisref_ ); if(aux!=address+"/.oisref>\n" ) { return(BinError(".oisref"  )); }
219  ERead(aux, object_ ); if(aux!=address+"/.object>\n" ) { return(BinError(".object"  )); }
220  ERead(aux, set_    ); if(aux!=address+"/.set>\n"    ) { return(BinError(".set"     )); }
221  ERead(aux, serie_  ); if(aux!=address+"/.serie>\n"  ) { return(BinError(".serie"   )); }
222  ERead(aux, timeset_); if(aux!=address+"/.timeset>\n") { return(BinError(".timeset" )); }
223  ERead(aux, matrix_ ); if(aux!=address+"/.matrix>\n" ) { return(BinError(".matrix"  )); }
224  ERead(aux, polyn_  ); if(aux!=address+"/.polyn>\n"  ) { return(BinError(".polyn"   )); }
225  ERead(aux, ratio_  ); if(aux!=address+"/.ratio>\n"  ) { return(BinError(".ratio"   )); }
226  ERead(aux, code_   ); if(aux!=address+"/.code>\n"   ) { return(BinError(".code"    )); }
227  if(control_.oisEngine_.oisVersion_>="01.07") {
228  ERead(aux, hrchyDetail_); if(aux!=address+"/.hrchyDetail>\n") { return(BinError(".hrchyDetail" )); }
229  ERead(aux, hrchyOffset_); if(aux!=address+"/.hrchyOffset>\n") { return(BinError(".hrchyOffset" )); }
230  ERead(aux, hrchyOrder_ ); if(aux!=address+"/.hrchyOrder>\n" ) { return(BinError(".hrchyOrder"  )); } }
231  else { numFiles-=3; }
232  enable_BSE_=(control_.oisEngine_.oisVersion_>="01.08")!=0;
233  for(n=1; n<numFiles; n++)
234  {
235    BINT64 size = allFiles_[n]->Bytes();
236    if(stat_.fileStat_[n].bytes_!=size)
237    {
238      Error(I2("OIS: File size integrity check failed",
239               "OIS: Fallo en el test de integridad de tamaño de ficheros")+
240               ".\n  "+allFiles_[n]->Name()+
241            I2(" seems to be corrupted due to has ",
242               " parece estar corrupto pues ocupa ")+
243            size + " Kb "+ 
244            I2(" instead of "," en lugar de ")+
245            stat_.fileStat_[n].bytes_);
246      ok = false; 
247    }
248  }
249  Ensure(ok);
250  return(ok);
251}
252
253
254//--------------------------------------------------------------------
255  bool BOisLoader::InitReaded() 
256//--------------------------------------------------------------------
257{
258  int n;
259  readed_.AllocBuffer(stat_.fileStat_[BFI_oisref].entries_);
260  BINT64 offset;
261  for(n=0; n<readed_.Size(); n++)
262  {     
263    ERead(offset, oisref_);
264    readed_[n].PutOffset(offset);
265    readed_[n].PutNullObject();
266  }
267  readed_.Sort(CompareOffset);
268//for(n=0; n<readed_.Size(); n++) { printf("\n%"_LLD64_, readed_[n].OisOffset()); }
269  return(true);
270}
271
272
273//--------------------------------------------------------------------
274bool BOisLoader::Read(BText& v, BStream* stream)
275//--------------------------------------------------------------------
276{
277  static char aux_[65536];
278  int sz;
279  ERead(sz,stream);
280  Ensure(Read(aux_,1,sz, stream));
281  aux_[sz]=0; 
282  v.Copy(aux_);
283  return(true);
284};
285
286//--------------------------------------------------------------------
287bool BOisLoader::Read(BDat& v, BStream* stream)
288//--------------------------------------------------------------------
289{
290  if(control_.typeSizes_.sizeof_BDat_==sizeof(BDatOld))
291  {
292    char   k;
293    double x;
294    ERead(k, stream);
295    ERead(x, stream);
296    if(k) { v = x; }
297    else  { v = BDat::Unknown(); }
298    return(true);
299  }
300  else if(control_.typeSizes_.sizeof_BDat_==sizeof(BDat))
301  {
302    double x;
303    ERead(x, stream);
304    v.PutValue(x);
305    return(true);
306  }
307  else
308  {
309    assert(1); 
310    return(false);
311  }
312};
313
314//--------------------------------------------------------------------
315bool BOisLoader::Read(BComplex& v, BStream* stream)
316//--------------------------------------------------------------------
317{
318  BDat x, y;
319  ERead(x, stream);
320  ERead(y, stream);
321  v = BComplex(x,y);
322  return(true);
323};
324
325//--------------------------------------------------------------------
326bool BOisLoader::Read(BDate& v, BStream* stream)
327//--------------------------------------------------------------------
328{
329  double h;
330  ERead(h,stream);
331  v.PutHash(h);
332  return(true);
333};
334
335//--------------------------------------------------------------------
336  bool BOisLoader::Read(BDat* buf, int s, BStream* stream)
337//--------------------------------------------------------------------
338{
339  if(control_.typeSizes_.sizeof_BDat_==sizeof(BDatOld))
340  {
341    BArray<BDatOld> d_(s);
342    if(!Read(d_.GetBuffer(),sizeof(BDatOld),s,stream))
343    { 
344      return(false); 
345    }
346    for(int i=0; i<s; i++)
347    {
348      if(d_(i).known_) { buf[i].PutValue(d_(i).value_); }
349      else             { buf[i] = BDat::Unknown(); }
350    }
351    return(true);
352  }
353  else if(control_.typeSizes_.sizeof_BDat_==sizeof(BDat))
354  {
355    return(Read(buf,sizeof(BDat),s,stream));
356  }
357  else
358  {
359    assert(1); 
360    return(false);
361  }
362};
363
364
365//--------------------------------------------------------------------
366  bool BOisLoader::Read(BPol& x, BStream* stream)
367//--------------------------------------------------------------------
368{
369  int s, i;
370  bool ok = true;
371  ERead(s, stream);
372  x.AllocBuffer(s);
373
374  if(control_.typeSizes_.sizeof_BCoefDeg_==sizeof(BCoefDegOld))
375  {
376    BCoefDegOld* buf = new BCoefDegOld[s];
377    Ensure(Read(buf,sizeof(BCoefDegOld),s,stream));
378    for(i=0; i<x.Size(); i++)
379    {
380      x[i].PutDegree(buf[i].degree_);
381      x[i].PutCoef  (buf[i].coefficient_.value_);
382    }
383    delete [] buf;
384  }
385  else if(control_.typeSizes_.sizeof_BCoefDeg_==sizeof(BCoefDeg))
386  {
387    BCoefDeg* buf = new BCoefDeg[s];
388    Ensure(Read(buf,sizeof(BCoefDeg),s,stream));
389    for(i=0; i<x.Size(); i++)
390    {
391      x[i].PutDegree(buf[i].degree_);
392      x[i].PutCoef  (buf[i].coefficient_);
393    }
394    delete [] buf;
395  }
396  else
397  {
398    assert(1); 
399    return(false);
400  }
401  Ensure(ok);
402  return(ok);
403}
404
405
406//--------------------------------------------------------------------
407  bool BOisLoader::Read(BMemberOwner& owner,
408                        BMemberOwner::BClassByNameHash& x, 
409                        BStream* stream)
410//--------------------------------------------------------------------
411{
412  BMemberOwner::BClassByNameHash::const_iterator iterC;
413  int n = 0;
414  int s;
415  ERead(s,stream);
416  for(n=0; n<s; n++)
417  {
418    BText parentName;
419    ERead(parentName,stream);
420    BClass* parent = FindClass(parentName);
421    if(!parent)
422    {
423      return(NullError(
424        I2("Cannot load from OIS Class ","No se puede cargar del OIS Class ")+ 
425        owner.getName()+
426        I2("due to ascent Class ","Debido a que su ascendiente Class ")+
427        parentName+I2(" doesn't exist"," no existe")));
428    }
429    x[parent->Name()] = parent;
430  }
431  return(true);
432}
433
434//--------------------------------------------------------------------
435  bool BOisLoader::Read(BClass& cls, BStream* stream)
436//--------------------------------------------------------------------
437{
438  BMemberOwner::BClassByNameHash& parents = *cls.parentHash_;
439  Ensure(Read(cls,parents,stream));
440  BMemberOwner::BClassByNameHash::const_iterator iterC;
441  int n = 0;
442  for(iterC=parents.begin(); iterC!=parents.end(); iterC++, n++)
443  {
444    iterC->second->IncNRefs();
445  }
446  Ensure(Read(cls,*cls.ascentHash_,stream));
447  int s;
448  ERead(s,stream);
449  cls.member_.AllocBuffer(s);
450  for(n=0; n<s; n++)
451  {
452    BText parentName;
453    BText name;
454    ERead(parentName, stream);
455    ERead(name      , stream);
456    BMember* mbr = NULL;
457    if(parentName==cls.getName())
458    {
459      char isMethod;
460      mbr = new BMember;
461      mbr->parent_ = &cls;
462      mbr->name_  = name;
463      mbr->branch_ = ReadTree(stream);
464      ERead(mbr->declaration_ , stream);
465      ERead(mbr->definition_  , stream);
466      ERead(isMethod          , stream);
467      mbr->isMethod_ = isMethod!=0;
468      mbr->isGood_ = true;
469    }
470    else
471    {
472      BClass* parent = FindClass(parentName);
473      mbr = parent->FindMember(name);
474      assert(mbr);
475    }
476    BMbrNum* mbrNum = new BMbrNum;
477    mbrNum->member_ = mbr;
478    mbrNum->position_ = n;
479    cls.member_[n] = mbrNum;
480    (*cls.memberHash_)[mbr->name_] = mbrNum;
481    if(mbr->definition_.HasName())
482    {
483      (*cls.mbrDefHash_)[mbr->declaration_] = mbr;
484    }
485    else
486    {
487      (*cls.mbrDecHash_)[mbr->declaration_] = mbr;
488    }
489  }
490  return(true);
491}
492
493
494//--------------------------------------------------------------------
495  BToken* BOisLoader::ReadTokenFromFile(BStream* stream)
496//--------------------------------------------------------------------
497{
498  BText name;
499  char  tt;
500  short pr;
501  char  cl;
502  ERead(name, stream);
503  ERead(tt, stream);
504  ERead(pr, stream);
505  ERead(cl, stream);
506  BToken* token = new BToken(name,(BTokenType)tt,pr);
507  token->PutClose(GetTokenCloseFromId(cl));
508#ifdef TRACE_OIS_TOKEN
509  BText aux0 = Compact(name);
510  BText aux1 = Replace(aux0,'\"','|');
511  BText aux2 = Replace(aux1,'\'','|');
512  fprintf(tokRead_,"\n%ld\t%ld\t%ld\t%s",(int)tt,(int)pr,(int)cl,aux2.String());
513  fflush(tokRead_);
514#endif
515  return(token);
516};
517
518
519//--------------------------------------------------------------------
520  List* BOisLoader::ReadTreeFromFile(BStream* stream)
521//--------------------------------------------------------------------
522{
523  char cl; 
524  ERead(cl,stream);
525  if(!cl)
526  {
527    return(NULL);
528  }
529  else
530  {
531    List* tre = new List;
532    if(cl==1)
533    {
534      BToken* tok = ReadTokenFromFile(stream);
535      tre->setCar(tok);
536    }
537    else
538    {
539      tre->setCar(ReadTreeFromFile(stream));
540    }
541    tre->setCdr(ReadTreeFromFile(stream));
542    return(tre);
543  }
544};
545
546
547//--------------------------------------------------------------------
548  BToken* BOisLoader::ReadTokenFromStream(BArray<char>& streamBuf, unsigned int& pos)
549//--------------------------------------------------------------------
550{
551  unsigned short   len;
552  char  tt;
553  short pr;
554  char  cl;
555
556  assert(pos+sizeof(unsigned short)<=unsigned(streamBuf.Size()));
557  memcpy(&len,streamBuf.Buffer()+pos,sizeof(unsigned short));
558  pos+=sizeof(unsigned short);
559  if(control_.machine_.isLittleEndian_!=isLittleEndian_)
560  {
561    SwapEndian(&len,sizeof(unsigned short));
562  }
563
564  BText name(len+1);
565  assert(pos+len<=unsigned(streamBuf.Size()));
566  memcpy(name.Buffer(),streamBuf.Buffer()+pos,len);
567  pos+=len;
568
569  assert(pos+1<=unsigned(streamBuf.Size()));
570  tt = streamBuf[pos];
571  pos+=sizeof(char);
572
573  assert(pos+sizeof(short)<=unsigned(streamBuf.Size()));
574  memcpy(&pr,streamBuf.Buffer()+pos,sizeof(short));
575  pos+=sizeof(short);
576  if(control_.machine_.isLittleEndian_!=isLittleEndian_)
577  {
578    SwapEndian(&pr,sizeof(short));
579  }
580
581  assert(pos+1<=unsigned(streamBuf.Size()));
582  cl = streamBuf[pos];
583  pos+=sizeof(char);
584
585  BToken* token = new BToken(name,(BTokenType)tt,pr);
586  token->PutClose(GetTokenCloseFromId(cl));
587#ifdef TRACE_OIS_TOKEN
588  BText aux0 = Compact(name);
589  BText aux1 = Replace(aux0,'\"','|');
590  BText aux2 = Replace(aux1,'\'','|');
591  fprintf(tokRead_,"\n%ld\t%ld\t%ld\t%s",(int)tt,(int)pr,(int)cl,aux2.String());
592  fflush(tokRead_);
593#endif
594  return(token);
595};
596
597
598//--------------------------------------------------------------------
599  List* BOisLoader::ReadTreeFromStream(BArray<char>& streamBuf, unsigned int& pos)
600//--------------------------------------------------------------------
601{
602  assert(pos+1<=unsigned(streamBuf.Size()));
603  char cl = streamBuf[pos];
604  pos+=sizeof(char);
605  if(!cl)
606  {
607    return(NULL);
608  }
609  else
610  {
611    List* tre = new List;
612    if(cl==1)
613    {
614      BToken* tok = ReadTokenFromStream(streamBuf,pos);
615      tre->setCar(tok);
616    }
617    else
618    {
619      tre->setCar(ReadTreeFromStream(streamBuf,pos));
620    }
621    tre->setCdr(ReadTreeFromStream(streamBuf,pos));
622    return(tre);
623  }
624};
625
626
627//--------------------------------------------------------------------
628  List* BOisLoader::ReadTree(BStream* stream)
629//--------------------------------------------------------------------
630{
631  if(control_.oisEngine_.oisVersion_<"01.04")
632  {
633    return ReadTreeFromFile(stream);
634  }
635  else
636  {
637    unsigned int pos;
638    ERead(pos,stream);
639    BArray<char> streamBuf(pos);
640    Read(streamBuf.GetBuffer(),1,pos,stream);
641    pos=0;
642    return(ReadTreeFromStream(streamBuf, pos));
643  }
644};
645
646
647//--------------------------------------------------------------------
648  BSyntaxObject* BOisLoader::PutVariableName(BSyntaxObject* result, 
649                                             const BText& name,
650                                             char is_referenceable)
651//--------------------------------------------------------------------
652{
653  BSyntaxObject* obj = result;
654  result->PutName(name);
655  if(is_referenceable) 
656  { 
657    obj = result->Grammar()->FindOperand(name,false);
658    if(obj)
659    {
660      #if !defined NDEBUG && defined WARN_ALREADY_EXISTS
661      Warning(I2("OIS referenceable object "+result->LexInfo()+
662                 " already exists in current TOL session "
663                 "and cannot be exported.",
664                 "El objeto OIS referenciable "+result->LexInfo()+
665                 " ya existe en la sesión actual de TOL "+
666                 "y no puede ser exportado."));
667      #endif
668      if(!oisHasPriorityOnConflict_)
669      {
670        SAFE_DESTROY(result, obj);
671      }
672      else
673      {
674        obj = result;
675      }
676    }
677    else
678    {
679      BGrammar::AddObject(result); 
680      obj = result;
681    }
682  }
683  return(obj);
684}
685
686//--------------------------------------------------------------------
687  BSyntaxObject* BOisLoader::ReadNextObject()
688//--------------------------------------------------------------------
689{
690  static BOffsetObject ofob;
691  ofob.PutOffset(object_->Offset());
692  int found = readed_.FindSorted(ofob, CompareOffset);
693  if(found<0)
694  {
695    return(NullError("FATAL BOisLoader::ReadNextObject misplaced offset"));
696  }
697  if(readed_[found].Object()) 
698  { return(readed_[found].Object()); }
699  unsigned int n, s;
700  BText name, description, aux;
701  char system, mode, tol_type, is_referenceable, format, gid;
702  BSyntaxObject* result = NULL;
703
704  ERead(system,           object_);
705  ERead(is_referenceable, object_);
706  ERead(mode,             object_);
707  ERead(tol_type,         object_);
708  ERead(name,             object_);
709  BGrammar* gra = BGrammar::FindByGid((BGrammarId)tol_type,true);
710  if(system) 
711  {
712    if(mode==BOBJECTMODE) 
713    { 
714      return(gra->FindOperand(name,false)); 
715    }
716    else if((mode==BBUILTINFUNMODE)||(mode==BUSERFUNMODE))
717    { 
718      return(gra->FindOperator(name)); 
719    }
720    else if(mode==BSTRUCTMODE) 
721    { 
722      return(FindStruct(name)); 
723    }
724    else if(mode==BCLASSMODE) 
725    { 
726      return(FindClass(name)); 
727    }
728    else 
729    { 
730      return(NullError("FATAL in BOisLoader::ReadNextObject()"));
731    }
732  }
733  else
734  {
735    if(mode==BSTRUCTMODE) 
736    { 
737      ERead(s, object_);
738      BStruct* str = NULL;
739      BStruct* fieldStr=NULL; 
740      if(is_referenceable) 
741      { 
742        str = FindStruct(name);
743        if(str)
744        {
745          #if !defined NDEBUG && defined WARN_ALREADY_EXISTS
746          Warning(I2("OIS referenceable Struct "+str->LexInfo()+
747                     " already exists in current TOL session "
748                     "and cannot be exported.",
749                     "El Struct OIS referenciable "+str->LexInfo()+
750                     " ya existe en la sesión actual de TOL "+
751                     "y no puede ser exportado."));
752          #endif
753
754        }
755      }
756      BArray<BField> field(s);
757      BText strFieldName; 
758      for(n=0; n<s; n++)
759      {
760        ERead(aux, object_);
761        ERead(gid, object_);
762        BGrammar* graGid = BGrammar::FindByGid((BGrammarId)gid);
763        if(graGid==GraSet())
764        {
765          ERead(strFieldName, object_);
766          if(strFieldName.HasName()) { fieldStr=FindStruct(strFieldName); }
767        } 
768        field[n].PutGrammar(graGid);
769        field[n].PutName(aux);
770        field[n].PutStruct(fieldStr);
771      } 
772      if(!str)
773      {
774        str = new BStruct(name, false);
775        str->PutField(field);
776        BGrammar::AddObject(str); 
777        str->PutFunction(new BNewStruct(*str));
778      }
779      return(readed_[found].PutObject(str));
780    }
781    else if(mode==BCLASSMODE) 
782    { 
783      BClass* cls = new BClass;
784      cls->PutName(name);
785      BScanner::AddSymbol(new BTypeToken(name,BTypeToken::BCLASS));
786      Ensure(Read(*cls,object_));
787      BGrammar::AddObject(cls); 
788      return(readed_[found].PutObject(cls));
789    }
790    else
791    {
792      ERead(description, object_);
793      ERead(format,      object_);
794      if(mode==BUSERFUNMODE)
795      { 
796        BINT64 offset;
797        ERead(offset, object_);
798        code_->SetPos(offset);
799        BUserFunction* usf = new BUserFunction("",gra);
800        usf->PutName(name);
801        List* dec = ReadTree(code_);
802        List* def = ReadTree(code_);
803        if(control_.oisEngine_.oisVersion_<"01.04")
804        { 
805          BText decTxt_, defTxt_;
806          ERead(decTxt_,code_);
807          ERead(defTxt_,code_);
808          decTxt_.Compact();
809          defTxt_.Compact();
810          BText decTxt = Compact(BParser::Unparse(dec,"  ","\n"));
811          BText defTxt = Compact(BParser::Unparse(def,"  ","\n"));
812          if(decTxt!=decTxt_)
813          {
814            return(NullError(BText("FATAL BOisLoader::ReadNextObject: incongruent tree and unparsed declaration of function ")+
815                             name +"\n" + 
816                             "///////////////////////////////////////////////////////////////////////////////\n"+
817                             decTxt+"\n" + 
818                             "///////////////////////////////////////////////////////////////////////////////\n"+
819                             " != \n" 
820                             "///////////////////////////////////////////////////////////////////////////////\n"+
821                             decTxt_+"\n" + 
822                             "///////////////////////////////////////////////////////////////////////////////\n"));
823          }
824          if(decTxt!=decTxt_)
825          {
826            return(NullError(BText("FATAL BOisLoader::ReadNextObject: incongruent tree and unparsed definition of function ")+
827                             name +"\n" + 
828                             "///////////////////////////////////////////////////////////////////////////////\n"+
829                             defTxt+"\n" + 
830                             "///////////////////////////////////////////////////////////////////////////////\n"+
831                             " != \n" 
832                             "///////////////////////////////////////////////////////////////////////////////\n"+
833                             defTxt_+"\n" + 
834                             "///////////////////////////////////////////////////////////////////////////////\n"));
835          }
836        }
837        if(!(usf->SetExpression(dec,def)))
838        {
839          return(NullError(Out()+I2("Function ","La función ")+name+
840                           I2(" could not been created", " no se pudo crear")));
841        } 
842        else
843        {
844          result=usf->GetCode();
845          result->PutName(name);
846          if(is_referenceable) 
847          { 
848            BOperator* ope = GraAnything()->FindOperator(name);
849            if(ope)
850            {
851              #if !defined NDEBUG && defined WARN_ALREADY_EXISTS
852              Warning(I2("OIS referenceable function "+ope->LexInfo()+
853                         " already exists in current TOL session "
854                         "and cannot be exported.",
855                         "La función OIS referenciable "+ope->LexInfo()+
856                         " ya existe en la sesión actual de TOL "+
857                         "y no puede ser exportado."));
858              #endif
859            }
860            else
861            {
862              BGrammar::AddObject(result);
863              BGrammar::AddObject(usf);
864            }
865          }
866        }
867      } 
868      else if(mode==BOBJECTMODE) 
869      { 
870        if(tol_type == BGI_Real) 
871        { 
872          BDat x;
873          ERead(x, object_); 
874          result = new BContensDat("", x, description);
875          result=PutVariableName(result,name,is_referenceable);
876        }
877        else if(tol_type == BGI_Date) 
878        { 
879          BDate x;
880          ERead(x, object_); 
881          result = new BContensDate("", x, description);
882          result=PutVariableName(result,name,is_referenceable);
883        }
884        else if(tol_type == BGI_Text) 
885        { 
886          BText x;
887          ERead(x, object_); 
888          result = new BContensText("", x, description);
889          result=PutVariableName(result,name,is_referenceable);
890        }
891        else if(tol_type == BGI_Complex) 
892        { 
893          BComplex x;
894          ERead(x, object_); 
895          result = new BContensCmp("", x, description);
896          result=PutVariableName(result,name,is_referenceable);
897        }
898        else if(tol_type == BGI_Code)
899        {
900          char  oprType;
901          BText oprName;
902          ERead(oprType, object_);
903          ERead(oprName, object_);
904          BGrammar*  oprGra = BGrammar::FindByGid((BGrammarId)oprType,true);
905          if(!oprGra)
906          {
907            return(NullError(BText("FATAL BOisLoader::ReadNextObject: cannot find grammar of object Code ")+name)); 
908          }
909          BStandardOperator* opr = (BStandardOperator*)oprGra->FindOperator(oprName);
910          if(!opr)
911          {
912            return(NullError(BText("FATAL BOisLoader::ReadNextObject: cannot find operator ")+oprGra->Name()+" "+oprName+" of object Code "+name)); 
913          }
914          BCode code;
915          BUserCode* uCode = new BContensCode("", code, description);
916          uCode->Contens().PutOperator(opr);
917          result = uCode;
918          result=PutVariableName(result,name,is_referenceable);
919        }
920        else if(tol_type == BGI_Matrix) 
921        {
922          BINT64 offset;
923          ERead(offset, object_);
924          matrix_->SetPos(offset);
925          int r,c;
926          ERead(r, matrix_);
927          ERead(c, matrix_);
928          BMat x(r,c);
929          Ensure(Read(x.GetData().GetBuffer(),r*c,matrix_));
930          result = new BContensMat("", x, description);
931          result=PutVariableName(result,name,is_referenceable);
932        }
933        else if(tol_type == BGI_VMatrix) 
934        {       
935          BVMat x;
936          result = new BContensVMat("", x, description);
937          VMat(result).Read(*this, matrix_);
938          result=PutVariableName(result,name,is_referenceable);
939        }
940        else if(tol_type == BGI_Polyn) 
941        {
942          BINT64 offset;
943          ERead(offset, object_);
944          polyn_->SetPos(offset);
945          BPol x;
946          ERead(x, polyn_);
947          result = new BContensPol("", x, description);
948          result=PutVariableName(result,name,is_referenceable);
949        }
950        else if(tol_type == BGI_Ratio) 
951        {
952          BINT64 offset;
953          ERead(offset, object_);
954          ratio_->SetPos(offset);
955          BPol x, y;
956          ERead(x, ratio_);
957          ERead(y, ratio_);
958          BRat z=x/y; 
959          result = new BContensRat("", z, description);
960          result=PutVariableName(result,name,is_referenceable);
961        }
962        else if(tol_type == BGI_Set)
963        {
964          BINT64 offset;
965          ERead(offset, object_);
966          set_->SetPos(offset);
967          ERead(s, set_);  BSet x; x.PrepareStore(s);
968          char sbt; ERead(sbt, set_);
969          x.PutSubType(BSet::BSubType(sbt));
970          BSetFromFile* sff = NULL;
971          const BSourcePath* oldSource = BSourcePath::Current();
972          if(control_.oisEngine_.oisVersion_>"02.04")
973          {
974            char isNameBlock;
975            ERead(isNameBlock,set_);
976            assert(!isNameBlock);
977            if(doc_.category_.BeginWith("Code.") && 
978               (x.SubType()>=BSet::MODFile)&&(x.SubType()<=BSet::BMIFile))
979            {
980              BText tolPath;
981              ERead(tolPath, set_);
982              sff = new BSetFromFile(tolPath);
983              x.PutSourcePath(BSourcePath::Current());
984            }
985          }
986          ERead(offset, set_);
987          BStruct* str = NULL;
988          if(offset) 
989          { 
990            object_->SetPos(offset);
991            BSyntaxObject* r = ReadNextObject(); 
992            if(!r || (r->Mode()!=BSTRUCTMODE)) 
993            { 
994              return(NullError("FATAL BOisLoader::ReadNextObject: cannot build structure of set")); 
995            } 
996            str = (BStruct*)r;
997          }
998          x.PutStruct (str); 
999          BSyntaxObject* r=NULL;
1000          for(n=1; n<=s; n++)
1001          {
1002            ERead(offset, set_);
1003            object_->SetPos(offset);
1004            r = ReadNextObject();
1005            if(!r) 
1006            { 
1007              return(NullError("BOisLoader::ReadNextObject: NULL element of set ")); 
1008            } 
1009            if(r) 
1010            {
1011              x.AddElement(r); 
1012            }
1013          } 
1014          if(sff) 
1015          { 
1016            sff->PutContens(x); 
1017            BSourcePath::SetCurrent(oldSource);
1018            result = GraSet()->New("", sff);
1019            result->PutDescription(description);
1020          }
1021          else
1022          {
1023            result = new BContensSet("", x, description);
1024          }
1025          result=PutVariableName(result,name,is_referenceable);
1026        } 
1027        else if(tol_type == BGI_NameBlock)
1028        {
1029          BINT64 offset;
1030          BText fullName;
1031          BText localName;
1032          ERead(offset, object_);
1033          set_->SetPos(offset);
1034          ERead(s, set_); 
1035          BUserNameBlock* unb = new BGraContensP<BNameBlock>(new BNameBlock);
1036          BNameBlock& x = unb->Contens(); 
1037          x.Set().PrepareStore(s);
1038          char sbt; ERead(sbt, set_);
1039          x.Set().PutSubType(BSet::BSubType(sbt));
1040
1041          char isNameBlock;
1042          ERead(isNameBlock,set_);
1043          assert(isNameBlock);
1044          ERead(fullName,set_);
1045          x.PutName(fullName);
1046          if(control_.oisEngine_.oisVersion_>="02.07")
1047          {
1048            ERead(localName,set_);
1049            x.PutLocalName(localName);
1050          }
1051          ERead(offset, set_);
1052          BStruct* str = NULL;
1053          if(offset) 
1054          { 
1055            object_->SetPos(offset);
1056            BSyntaxObject* r = ReadNextObject(); 
1057            if(!r || (r->Mode()!=BSTRUCTMODE)) 
1058            { 
1059              return(NullError("FATAL BOisLoader::ReadNextObject: cannot build structure of set")); 
1060            } 
1061            str = (BStruct*)r;
1062          }
1063          x.Set().PutStruct (str); 
1064          BSyntaxObject* r=NULL;
1065          for(n=1; n<=s; n++)
1066          {
1067            ERead(offset, set_);
1068            object_->SetPos(offset);
1069            r = ReadNextObject();
1070            if(!r) 
1071            { 
1072              return(NullError("BOisLoader::ReadNextObject: NULL element of set ")); 
1073            } 
1074            if(r) 
1075            {
1076              x.Set().AddElement(r); 
1077              r->PutNameBlock(&x);
1078            }
1079          } 
1080          x.Set().PutNameBlock(&x);
1081          x.Build();
1082          if(control_.oisEngine_.oisVersion_>="02.07")
1083          {
1084            char hasClass;
1085            Ensure(Read(hasClass, object_));
1086            if(hasClass)
1087            {
1088              BText className;
1089              Ensure(Read(className, object_));
1090              BClass* cls = FindClass(className);
1091              if(!cls)
1092              {
1093                return(NullError(
1094                  I2("Cannot load from OIS NameBlock ","No se puede cargar del OIS NameBlock ")+ 
1095                  name+
1096                  I2("due to ascent Class ","Debido a que su ascendiente Class ")+
1097                  className+I2(" doesn't exist"," no existe")));
1098              }
1099              cls->IncNRefs();
1100              x.PutClass(cls);
1101            }
1102          }
1103          result = unb;
1104          result->PutDescription(description);
1105          result=PutVariableName(result,name,is_referenceable);
1106        } 
1107        else if(tol_type == BGI_Serie) 
1108        {
1109          BINT64 offset;
1110          ERead(offset, object_);
1111          serie_->SetPos(offset);
1112          ERead(offset, serie_);
1113          BUserTimeSerie* x = NULL; 
1114          if(!offset)
1115          {
1116            BDat d;
1117            ERead(d, serie_);
1118            x = new BTsrFromReal(d); 
1119          }
1120          else
1121          {
1122            object_->SetPos(offset);
1123            BSyntaxObject* r = ReadNextObject();
1124            if(!r || (r->Grammar()!=GraTimeSet())) 
1125            { 
1126              return(NullError("FATAL cannot built dating of serie")); 
1127            }
1128            BUserTimeSet* dating = (BUserTimeSet*)r;
1129            BDate first, last, beginCache, endCache;
1130            ERead(first, serie_);
1131            ERead(last,  serie_);
1132            ERead(beginCache, serie_);
1133            ERead(endCache,   serie_);
1134            ERead(s,serie_);
1135            BData d(s);
1136            Ensure(Read(d.GetBuffer(),s,serie_));
1137            char loadTree;
1138            ERead(loadTree,serie_);
1139            if(loadTree)
1140            {
1141              List* tree = ReadTree(serie_);
1142              if(!tree) 
1143              { 
1144                return(NullError(BText("Cannot load syntax tree of Serie (name='")+
1145                       name+"' description='"+description+"')")); 
1146              }
1147              bool oldEnabled = BOut::Disable();
1148              x = (BUserTimeSerie*)GraSerie()->EvaluateTree(tree); 
1149              if(oldEnabled) { BOut::Enable(); }
1150              if(x) 
1151              { 
1152                x->GetDataBuffer() = d;
1153                x->PutFirstCache(beginCache);
1154                x->PutOisTree(tree);
1155                tree->Destroy();
1156              }
1157              else 
1158              {
1159                BText expr = BParser::Unparse(tree,"  ","\n");
1160                expr = Compact(expr); 
1161               #ifndef NDEBUG
1162                Warning(BText("Cannot rebuild virtual expression of "
1163                              "non bounded Serie ")+name+"="+expr+
1164                              "\nOnly cached data will be accessible "
1165                              "between ["+beginCache+","+endCache+"]"
1166                              "\nTo avoid this problem save just "
1167                              "bounded time series "); 
1168               #endif 
1169                if(tree) { tree->Destroy(); }
1170              }
1171            }
1172            if(!x)
1173            {
1174              x = new BTsrPrimary("",description,dating,beginCache,endCache,d);
1175              PutVariableName(x,name,is_referenceable);
1176            }
1177          }
1178          if(x->Name()!=name) 
1179          { 
1180            result = new BTsrRenamed("", x); 
1181            result=PutVariableName(result,name,is_referenceable);
1182          }
1183          else               
1184          { result = x; }
1185        }
1186        else if(tol_type == BGI_TimeSet) 
1187        {
1188          BINT64 offset;
1189          ERead(offset, object_);
1190          timeset_->SetPos(offset);
1191          BDate inf, sup, beginCache, endCache;
1192          ERead(inf,        timeset_);
1193          ERead(sup,        timeset_);
1194          ERead(beginCache, timeset_);
1195          ERead(endCache,   timeset_);
1196          ERead(s,          timeset_);
1197          BHash h(s);
1198          Ensure(Read(h.GetBuffer(),sizeof(double),h.Size(),timeset_));
1199          BUserTimeSet* x = NULL;
1200          char loadTree;
1201          ERead(loadTree,timeset_);
1202          if(loadTree)
1203          {
1204            List* tree = ReadTree(timeset_);
1205            if(!tree) 
1206            { 
1207              return(NullError(BText("Cannot load syntax tree TimeSet (name='")+
1208                     name+"' description='"+description+"')")); 
1209            }
1210            bool oldEnabled = BOut::Disable();
1211            x = (BUserTimeSet*)GraTimeSet()->EvaluateTree(tree); 
1212            if(oldEnabled) { BOut::Enable(); }
1213            if(x) 
1214            { 
1215              assert(s || (tree!=NULL));
1216              if(s && (control_.oisEngine_.oisVersion_>="02.03"))
1217              {
1218                x->PutCache(h, beginCache, endCache);
1219              }
1220              x->PutOisTree(tree); 
1221              tree->Destroy();
1222            }
1223            else 
1224            {
1225              BText expr = Compact(BParser::Unparse(tree,"  ","\n"));
1226             #ifndef NDEBUG
1227              Warning(BText("Cannot rebuild virtual expression of non "
1228                      "bounded TimeSet ")+name+"="+expr+ "\nOnly cached "
1229                      "dates will be accessible between ["+beginCache+","+
1230                      endCache+"]\nTo avoid this problem save just "
1231                      "bounded time sets " );
1232             #endif
1233              if(tree) { tree->Destroy(); }
1234            } 
1235          }
1236          if(!x)
1237          {
1238            x = new BTmsDatesOfSet(h);
1239          }
1240          if(x->Name()!=name) 
1241          { 
1242            result = new BTmsRenamed("", x); 
1243            result=PutVariableName(result,name,is_referenceable);
1244          }
1245          else               
1246          { result = x; }
1247        }
1248      }
1249      else 
1250      { 
1251        return(NullError("FATAL invalid object mode for BOisLoader::ReadNextObject()"));
1252      }
1253    }
1254    if(result && !result->Description().HasName() & description.HasName()) 
1255    { 
1256      result->PutDescription(description); 
1257    }
1258    return(readed_[found].PutObject(result));
1259  }
1260}
1261
1262//--------------------------------------------------------------------
1263  bool BOisLoader::Remove ()
1264//--------------------------------------------------------------------
1265{
1266  if(streamHandler_) 
1267  { 
1268    Close();
1269  }
1270  streamHandler_ = BStreamHandler::GetConnect
1271  (
1272    connection_, 
1273    BStreamHandler::BSHOM_WRITE, 
1274    true
1275  );
1276  bool ok = RemoveImage();
1277  return(ok);
1278}
1279
1280//--------------------------------------------------------------------
1281  BDate BOisLoader::Time() 
1282//--------------------------------------------------------------------
1283{ 
1284  if(!streamHandler_) { Open(false); }
1285  if(!header_) { return(BDate::Unknown()); } 
1286  else         { return(BTimer::TimeToDate(header_->Time())); } 
1287}
1288
1289//--------------------------------------------------------------------
1290  bool BOisLoader::CheckUpdatedSource(int n, const BText& path)
1291//--------------------------------------------------------------------
1292{
1293  bool isOza = (options_.compressor_.fileManager_.engine_==BAE_ZIPARC_);
1294  BDir dir(path);
1295  lostSource_=!dir.Exist();
1296  bool updated; 
1297  if(lostSource_) 
1298  {
1299    updated = true; 
1300  }
1301  else
1302  {
1303    BText name = BText("._tol_source_/")+PlainPath(path);
1304    BStream* fn = isOza?streamHandler_->Open(name,name):NULL;
1305    source_.Add(fn); 
1306    if(isOza && !fn) 
1307    { 
1308      updated = true; 
1309    }
1310    else
1311    {
1312      int size    = dir.Bytes();
1313      int oldSize = (int)tolSources_[n].bytes_;
1314      if(oldSize!=size) 
1315      { 
1316        updated = false; 
1317      }
1318      else
1319      {
1320        time_t time      = dir.Time();
1321        BDate  date      = BTimer::TimeToDate(time);
1322        BDate  oldDate   = tolSources_[n].release_;
1323        double diff      = DifInSeconds(oldDate,date);
1324        if(fabs(diff)<1.0) 
1325        { 
1326          updated = true; 
1327        }
1328        else if(!isOza)
1329        { 
1330          updated = false; 
1331        }
1332        else if(fn && fn->Bytes()!=size) 
1333        { 
1334          updated = false; 
1335        }
1336        else 
1337        {
1338          char* contens = new char[size+1];
1339          char* oldCont = new char[size+1];
1340          FILE* file=fopen(path.String(),"rb");
1341          if(!file) 
1342          { 
1343            Warning(I2("Cannot check if source file ",
1344                       "No se pudo comprobar si el fichero fuente ")+path+
1345                    I2(" is synchronized with this module.",
1346                       " está sincronizado con este módulo."));
1347            updated = true; 
1348          }
1349          else
1350          {
1351            int r = fread(contens,1,size,file); 
1352            contens[r]='\0';
1353            fclose(file);
1354            assert(r==size);
1355            Read(oldCont,1,size,fn);
1356            oldCont[size]='\0';
1357            int cmp = memcmp(oldCont,contens,r);
1358            delete [] contens;
1359            delete [] oldCont;
1360            updated = (cmp==0);
1361            if(updated) 
1362            { 
1363            //tolSources_[n].release_ = date;
1364              SetFileTime(path, BTimer::DateToTime(tolSources_[n].release_));
1365            }
1366          }
1367        }
1368      }
1369    }
1370  }
1371  return(updated);
1372}
1373
1374//--------------------------------------------------------------------
1375  bool BOisLoader::Load(bool errorWarning, 
1376                        bool doShowHierarchy,
1377                        bool checkIsUpdate,
1378                        bool doLoadData,
1379                        int  showHrchyDepth,
1380                        int  showHrchyMaxChilds,
1381                        const BSet* partial)
1382//--------------------------------------------------------------------
1383{
1384#ifdef TRACE_LEVEL
1385  BText fun = BText("BOisLoader::Load()");
1386#endif
1387  bool ok = true;
1388  Ensure(Open(errorWarning));
1389  Ensure(XMLReadHeader());
1390  const BSourcePath* curSourcePath = BSourcePath::Current();
1391  if(checkIsUpdate) { Ensure(!HasLostSource ()); }
1392  if(checkIsUpdate) { Ensure(!ObsoleteSource()); }
1393  if(doLoadData || doShowHierarchy)
1394  {
1395    Ensure(ReadHierarchyIndex());
1396  }
1397  if(doShowHierarchy)
1398  {
1399    ShowHierarchy();
1400  }
1401  if(doLoadData)
1402  {
1403    if(doc_.name_.HasName())
1404    {
1405      if(doc_.category_=="Code.Package")
1406      {
1407        Std(I2("OIS: Loading module ","OIS: Cargando el módulo ")+
1408            doc_.name_+"\n");
1409      }
1410    }
1411    Ensure(InitReaded());
1412    Ensure(SearchOffsetInHierarchy(partial));
1413    object_->GetPos();
1414    data_ = ReadNextObject();
1415    ok = (data_!=NULL);
1416  }
1417  Close();
1418  BSourcePath::SetCurrent(curSourcePath);
1419  return(ok);
1420}
1421
1422//--------------------------------------------------------------------
1423  bool BOisLoader::Close()
1424//--------------------------------------------------------------------
1425{
1426  if(closed_) { return(false); }
1427  int n;
1428  for(n=0; n<readed_.Size(); n++)
1429  {
1430    if(readed_[n].Object())
1431    {
1432      readed_[n].Object()->PutOisOffset(0);
1433      readed_[n].Object()->DecNRefs();
1434    }
1435  }
1436  BOis::Close();
1437  return(true);
1438}
1439
Note: See TracBrowser for help on using the browser.