Changeset 802 in Sophya for trunk/SophyaLib/BaseTools/ppersist.cc


Ignore:
Timestamp:
Apr 3, 2000, 7:32:27 PM (25 years ago)
Author:
ansari
Message:

Mise au point du nouveau schema (Version=2) de PPersist - Mise en place

de tag complet pour toutes les donnees/objets ecrits - Gestion a peu
pres correct des objets references plusieurs fois, ecrit une seule fois.
Mecanisme d'enregistrement pour les DataObject associe et Methodes
(PutObject/GetObjet) facilitant l'ecriture/lecture de DataObject.
Separation du fichier de la classe FIO_NDataBlock<T>.

Reza03/04/2000

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/SophyaLib/BaseTools/ppersist.cc

    r754 r802  
    55#include "pexceptions.h"
    66#include "ppersist.h"
     7#include "anydataobj.h"
    78#include <fstream.h>
    89#include <iostream.h>
     
    1314#include "unixmac.h"
    1415#include <SIOUX.h>
     16#endif
     17
     18//  strptime n'est pas defini sous Linux  - Reza Mars 2000
     19#if defined(OS_LINUX)
     20extern "C" {
     21char *strptime(char *buf, const char *format, const struct tm *tm);
     22}
    1523#endif
    1624
     
    3543
    3644MD5_CONTEXT PIOPersist::ctx;
    37 PIOPersist::ClassList * PIOPersist::classList = NULL;   // $CHECK$ Reza 26/04/99
    38 map<string, uint_8> * PIOPersist::typeids = NULL;
     45PIOPersist::ClassList * PIOPersist::ppclassList = NULL;   // $CHECK$ Reza 26/04/99
     46map<string, uint_8> * PIOPersist::ppclassNameList = NULL;
     47map<string, uint_8> * PIOPersist::dobjclassNameList = NULL;
    3948
    4049//++
     
    4453//--
    4554{
    46 classList = new PIOPersist::ClassList;
    47 typeids = new map<string, uint_8>;
    48 }
    49 
    50 //++
    51 void
    52 PIOPersist::RegisterClass(uint_8 classId, string typname, ClassCreatorFunc f)
     55ppclassList = new PIOPersist::ClassList;
     56ppclassNameList = new map<string, uint_8>;
     57dobjclassNameList = new map<string, uint_8>;
     58}
     59
     60//++
     61void
     62PIOPersist::RegisterPPHandlerClass(uint_8 classId, string ppclass_name, ClassCreatorFunc f)
    5363//
    54 //      Register a new persistant class.
    55 //      The classId is usually a hash of the class name, and this
    56 //      method is called only through the PPersistRegistrar template
    57 //      class, with the PPRegister(className) macro.
     64//      Register a new persistence handler (PPersist) class.
     65//      The classId is usually a hash of the class name, and
     66//      ppclass_name is typeid(PPersistClass).name() .
     67//      This method is called only through the PPersistRegistrar template
    5868//
    5969//--
    6070{
    61   if (classList->size() && (classList->find(classId) != classList->end())) {
    62       cerr << "RegisterClass : Error, " << hex << classId << dec
    63            << " already registered." << endl;
    64       throw(DuplicateIdExc("PIOPersist::RegisterClass"));
     71  if (ppclassList->size() && (ppclassList->find(classId) != ppclassList->end()) ) {
     72    cerr << "RegisterClass : Error, " << hex << classId << dec
     73         << " already registered." << endl;
     74    throw(DuplicateIdExc("PIOPersist::RegisterPPHandlerClass"));
     75  }
     76  if (ppclassNameList->size() && (ppclassNameList->find(ppclass_name) != ppclassNameList->end())) {
     77    cerr << "RegisterClass : Error (2) " <<  ppclass_name
     78         << " already registered." << endl;
     79      throw(DuplicateIdExc("PIOPersist::RegisterPPHandlerClass (3)"));
    6580    }
    6681 
    67   (*classList)[classId] = f;
    68   (*typeids)[typname]  = classId;
    69 }
    70 
     82  (*ppclassList)[classId] = f;
     83  (*ppclassNameList)[ppclass_name]  = classId;
     84}
     85
     86//++
     87void
     88PIOPersist::RegisterDataObjClass(uint_8 classId, string class_name)
     89//      Register a new DataObj class corresponding to a PPersist classId
     90//      class_typename should be typeid(DataObject).name()
     91//--
     92{
     93  if (ppclassList->find(classId) == ppclassList->end() )
     94    throw( NotFoundExc("PIOPersist::RegisterDataObjClass() Not found classId") );
     95  if (dobjclassNameList->size() && (dobjclassNameList->find(class_name) != dobjclassNameList->end()))
     96      throw(DuplicateIdExc("PIOPersist::RegisterDataObjClass"));
     97
     98  (*dobjclassNameList)[class_name]  = classId;
     99}
     100
     101//      class_typename should be typeid(DataObject).name(), to be
     102//      used by POutPersist::PutDataObject() methods.
    71103
    72104PIOPersist::ClassCreatorFunc
    73105PIOPersist::FindCreatorFunc(uint_8 classId)
    74 {
    75   ClassList::iterator i = classList->find(classId);
    76   if (i == classList->end()) throw(NotFoundExc("PIOPersist::FindCreatorFunc"));
     106// Returns the PPersist class creator function for the specified classId
     107{
     108  ClassList::iterator i = ppclassList->find(classId);
     109  if (i == ppclassList->end()) throw(NotFoundExc("PIOPersist::FindCreatorFunc() Not found classId"));
    77110  return (*i).second;
     111}
     112
     113string
     114PIOPersist::getPPClassName(uint_8 classId)
     115// Returns the PPersist class name for the specified classId
     116{
     117  map<string, uint_8>::iterator i;
     118  for (i= ppclassNameList->begin(); i != ppclassNameList->end(); i++)
     119    if ( (*i).second == classId ) return (*i).first;
     120
     121  throw(NotFoundExc("PIOPersist::getPPClassName() Not found classId"));
     122}
     123
     124uint_8
     125PIOPersist::getPPClassId(string const & typ_name)
     126// Returns the classId for the specified PPersist class type name
     127{
     128  map<string, uint_8>::iterator i = ppclassNameList->find(typ_name);
     129  if (i == ppclassNameList->end())
     130    throw(NotFoundExc("PIOPersist::getPPClassId() Not found className"));
     131  return (*i).second;
     132}
     133
     134uint_8
     135PIOPersist::getPPClassId(PPersist const & ppo)
     136// Returns the classId for the specified PPersist class
     137{
     138  string typ_name = typeid(ppo).name() ;
     139  return (getPPClassId(typ_name) );
     140}
     141
     142
     143string
     144PIOPersist::getDataObjClassName(uint_8 classId)
     145// Returns the PPersist class name for the specified classId
     146{
     147  map<string, uint_8>::iterator i;
     148  for (i= dobjclassNameList->begin(); i != dobjclassNameList->end(); i++)
     149    if ( (*i).second == classId ) return (*i).first;
     150
     151  throw(NotFoundExc("PIOPersist::getDataObjClassName() Not found classId"));
     152}
     153
     154uint_8
     155PIOPersist::getDataObjClassId(string const & typ_name)
     156// Returns the classId for the specified PPersist class type name
     157{
     158  map<string, uint_8>::iterator i = dobjclassNameList->find(typ_name);
     159  if (i == dobjclassNameList->end())
     160    throw(NotFoundExc("PIOPersist::getDataObjClassId() Not found className"));
     161  return (*i).second;
     162}
     163
     164uint_8
     165PIOPersist::getDataObjClassId(AnyDataObj const & o)
     166// Returns the classId for the specified PPersist class
     167{
     168  string typ_name = typeid(o).name() ;
     169  return (getDataObjClassId(typ_name) );
    78170}
    79171
     
    140232//--
    141233{
    142    s.PutObject(this);
     234   s.PutPPObject(this);
    143235}
    144236
     
    156248  // We should be the exact type 
    157249  // Check tag value
    158   char ppstype;
     250  unsigned char ppstype,ppstag;
    159251  s.GetTypeTag(ppstype);
    160   if (ppstype != PInPersist::PPS_OBJECT) {
    161     throw FileFormatExc("PPersist::Read : not an object in flow");
    162   }
    163  
    164   // Check class id
    165   uint_8 classId;
    166   s.GetRawU8(classId);
    167   uint_8 myClassId = PIOPersist::getTypeId(typeid(*this).name());
    168   if (classId != myClassId) {
    169     throw FileFormatExc("PPersist::Read : not the same object type");
    170   }
    171 
    172   ReadSelf(s);
     252  if ( (ppstype != PInPersist::PPS_OBJECT) && ( ppstype != PInPersist::PPS_REFERENCE ) ) {
     253  }
     254  if (ppstype == PInPersist::PPS_OBJECT) {
     255    // Check class id
     256    uint_8 classId;
     257    s.GetRawU8(classId);
     258    uint_8 oid,oid2;
     259    s.GetRawU8(oid);
     260    if (classId != PIOPersist::getPPClassId(*this) )
     261      throw FileFormatExc("PPersist::Read (): not the same object type"); 
     262    ReadSelf(s);
     263    // Read the ENDOBJECT
     264    s.GetRawUByte(ppstag);
     265    if (ppstag != PInPersist::PPS_ENDOBJECT)
     266      throw FileFormatExc("PPersist::Read() No PPS_ENDOBJECT tag");
     267    s.GetRawU8(oid2);
     268    if (oid2 != oid)
     269      throw FileFormatExc("PPersist::Read() Inconsistent PPS-OId at PPS_ENDOBJECT ");
     270    s.KeepOId(oid, *this);   // Object should be kept with its PPS_OId  (if oid > 0)
     271  }
     272  else if ( ppstype == PInPersist::PPS_REFERENCE )
     273    s.ReadReference(*this);
     274
     275  else  throw FileFormatExc("PPersist::Read() : not an object in flow");
     276
    173277}
    174278
     
    181285{
    182286  s.WriteTag(tag);
    183   s.PutObject(this);
     287  s.PutPPObject(this);
    184288}
    185289
     
    196300}
    197301
     302// Renvoie l'identificateur de l'objet  - par defaut=0
     303
     304uint_8
     305PPersist::getMemOId() const
     306{
     307  return(0);
     308}
     309
     310// Ces deux methodes doivent etre redefinies si   getMemOId() renvoie non nul (>0)
     311// ShareDataReference() et CloneSharedReference()
     312void
     313PPersist::ShareDataReference(PPersist & pcs)
     314{
     315  throw NotAvailableOperation("PPersist::ShareDataReference() - Unsupported operation !");
     316}
     317
     318PPersist *
     319PPersist::CloneSharedReference()
     320{
     321  throw NotAvailableOperation("PPersist::CloneSharedReference() - Unsupported operation !");
     322}
    198323
    199324//++
     
    233358    throw FileFormatExc("PInPersist::PInPersist  bad header");
    234359  }
    235   version = atoi(rbuf+24);
    236 
     360  rbuf[32] = '\0';
     361  version = atoi(rbuf+25);
     362  if (version < 2) {
     363    cerr << "PInPersist::PInPersist(" << flnm << ") Version(=" << version
     364         << ") < 2 not supported !" << endl;
     365    throw FileFormatExc("PInPersist::PInPersist() - Unsupported (Old) Version");
     366  }
    237367  // read endianness
    238368  GetRawBytes(rbuf, 32);
     
    249379  rbuf[32] = '\0';
    250380  struct tm tm;
    251   #ifndef __MWERKS__
     381  #ifndef __MWERKS__ 
    252382  strptime(rbuf,"%d/%m/%Y %H:%M:%S GMT",&tm);
    253383  #else
     
    258388  #endif
    259389  creationdate = mktime(&tm);
    260 
     390  filename = flnm;  // keep the filename
     391  seqread = true;   // To flag non sequential reads
    261392  if (scan) Scan();
    262393}
     
    266397PInPersist::~PInPersist()
    267398{
     399  ObjList::iterator i;
     400  for(i=objList.begin(); i!= objList.end(); i++) 
     401    if ((*i).second)  delete (*i).second;
    268402  delete s;
    269403}
    270404
    271405
     406string
     407PInPersist::CreationDateStr()
     408{
     409  time_t cdt = CreationDate();
     410  string cdate = ctime(&cdt);
     411  return(cdate);
     412}
     413
    272414void
    273415PInPersist::Scan()
     
    275417  // On cherche la liste des tags, a la fin du fichier
    276418
    277   char ppstype;
     419  unsigned char ppstype;
    278420  size_t debut;
    279421#ifdef STREAMPOS_IS_CLASS
     
    333475      //    throw NotFoundExc("PInPersist::GotoTag   tag not found");
    334476  s->seekg((*i).second);
    335   objList.clear(); // $CHECK$ EA 171199
     477  seqread = false;
     478  //  objList.clear(); $CHECK$ EA 171199 Ne pas faire ? Reza 03/2000 ?
    336479  return(true);
    337480}
     
    344487  for (int j=0; j<itag; j++) i++;
    345488  s->seekg((*i).second);
    346   objList.clear(); // $CHECK$ EA 171199
     489  // objList.clear();  $CHECK$ EA 171199  Ne pas faire ? Reza 03/2000 ?
    347490  return(true);
    348491}
     
    355498  for (int j=0; j<itag; j++) i++;
    356499  return((*i).first);
     500}
     501
     502string
     503PInPersist::GetTagClassName(int itag)
     504{
     505  // A faire
     506//   if (itag<0 || itag >= (int)tags.size()) return "";
     507//   map<string, int_8>::iterator i = tags.begin();
     508//   for (int j=0; j<itag; j++) i++;
     509//   uint_8 cid = (*i).second;
     510//   return(GetClassName(cid));
     511  return("");
    357512}
    358513
     
    424579
    425580void
    426 PInPersist::GetTypeTag(char& c)
    427 {
    428   GetRawByte(c);
    429   while (c == PPS_TAG_MARK) {
    430     objList.clear();
    431     GetRawByte(c);
    432   }
     581PInPersist::GetTypeTag(unsigned char& c)
     582{
     583  c = PPS_TAG_MARK;
     584  while (c == PPS_TAG_MARK) GetRawUByte(c);
     585  //  while (c == PPS_TAG_MARK) {    Il ne faut plus faire ca !
     586  //    objList.clear();             $CHECK$ Reza 03/2000
     587  //    GetRawByte(c);
     588  //  }
    433589}
    434590
     
    441597
    442598void
     599PInPersist::GetRawUByte(unsigned char& c)
     600{
     601  GetRawBytes(&c, 1);
     602}
     603
     604void
    443605PInPersist::GetRawBytes(void* ptr, size_t bytes)
    444606{
     
    479641
    480642void
    481 PInPersist::CheckTag(short datasz)
    482 {
    483   char ppstype;
     643PInPersist::CheckTag(short datasz, short datatype)
     644// datatype = PPS_DATATYPE_CHAR or PPS_DATATYPE_FLOAT or PPS_DATATYPE_INTEGER or PPS_DATATYPE_UNSIGNED
     645{
     646  unsigned char ppstype;
    484647  GetTypeTag(ppstype);
    485   if (ppstype != PPS_SIMPLE + datasz)
     648  if (ppstype != PPS_SIMPLE + datasz + datatype)
    486649    throw FileFormatExc("PInPersist::CheckTag   bad type in ppersist file");
    487650}
    488651
    489652void
    490 PInPersist::CheckArrayTag(short datasz, size_t sz)
    491 {
    492   char ppstype;
     653PInPersist::CheckArrayTag(short datasz, size_t sz, short datatype)
     654// datatype = PPS_DATATYPE_CHAR or PPS_DATATYPE_FLOAT or PPS_DATATYPE_INTEGER or PPS_DATATYPE_UNSIGNED
     655{
     656  unsigned char ppstype;
    493657  GetTypeTag(ppstype);
    494658  size_t filesz;
    495   if (sz <= 0x7fff) {
    496     if (ppstype != PPS_SIMPLE_ARRAY + datasz)
    497       throw FileFormatExc("PInPersist::CheckTag   bad type in ppersist file");
    498     int_2 ff;
    499     GetRawI2(ff); filesz=ff;
    500   } else if (sz <= 0x7fffffff) {
    501     if (ppstype != PPS_SIMPLE_ARRAY4 + datasz)
    502       throw FileFormatExc("PInPersist::CheckTag   bad type in ppersist file");
     659  if (sz <= 0x7fffffff) {
     660    if (ppstype != PPS_SIMPLE_ARRAY4 + datasz + datatype)
     661      throw FileFormatExc("PInPersist::CheckArrayTag   bad type in ppersist file");
    503662    int_4 ff;
    504663    GetRawI4(ff); filesz=ff;
    505664  } else {
    506     if (ppstype != PPS_SIMPLE_ARRAY8 + datasz)
    507       throw FileFormatExc("PInPersist::CheckTag   bad type in ppersist file");
     665    if (ppstype != PPS_SIMPLE_ARRAY8 + datasz + datatype)
     666      throw FileFormatExc("PInPersist::CheckArrayTag   bad type in ppersist file");
    508667    uint_8 ff;
    509668    GetRawU8(ff); filesz=ff;
    510669  }
    511670  if (filesz != sz)
    512     throw FileFormatExc("PInPersist::CheckTag   bad array size in ppersist file");
     671    throw FileFormatExc("PInPersist::CheckArrayTag   bad array size in ppersist file");
    513672}
    514673
     
    516675PInPersist::GetByte(char& c)
    517676{
    518   CheckTag(1);
     677  CheckTag(1,PPS_DATATYPE_CHAR);
    519678  GetRawBytes(&c, 1);
    520679}
    521680
     681
    522682void
    523683PInPersist::GetBytes(void* ptr, size_t bytes)
    524684{
    525   CheckArrayTag(1, bytes);
     685  CheckArrayTag(1, bytes, PPS_DATATYPE_CHAR);
    526686  GetRawBytes(ptr, bytes);
    527687}
     
    529689PInPersist::GetR4   (r_4& result)
    530690{
    531   CheckTag(4);
     691  CheckTag(4,PPS_DATATYPE_FLOAT);
    532692  GetRawBytes(&result, sizeof(r_4));
    533693  if (bigEndian != IS_BIG_ENDIAN)
     
    539699PInPersist::GetR4s  (r_4* tab, size_t n)
    540700{
    541   CheckArrayTag(4,n);
     701  CheckArrayTag(4,n,PPS_DATATYPE_FLOAT);
    542702  GetRawBytes(tab, n*sizeof(r_4));
    543703  if (bigEndian == IS_BIG_ENDIAN) return;
     
    552712PInPersist::GetR8   (r_8& result)
    553713{
    554   CheckTag(8);
     714  CheckTag(8,PPS_DATATYPE_FLOAT);
    555715  GetRawBytes(&result, sizeof(r_8));
    556716  if (bigEndian != IS_BIG_ENDIAN)
     
    561721PInPersist::GetR8s  (r_8* tab, size_t n)
    562722{
    563   CheckArrayTag(8,n);
     723  CheckArrayTag(8,n,PPS_DATATYPE_FLOAT);
    564724  GetRawBytes(tab, n*sizeof(r_8));
    565725  if (bigEndian == IS_BIG_ENDIAN) return;
     
    574734PInPersist::GetI2   (int_2& result)
    575735{
    576   CheckTag(2);
     736  CheckTag(2,PPS_DATATYPE_INTEGER);
    577737  GetRawBytes(&result, sizeof(int_2));
    578738  if (bigEndian != IS_BIG_ENDIAN)
     
    583743PInPersist::GetI2s  (int_2* tab, size_t n)
    584744{
    585   CheckArrayTag(2,n);
     745  CheckArrayTag(2,n,PPS_DATATYPE_INTEGER);
    586746  GetRawBytes(tab, n*sizeof(int_2));
    587747  if (bigEndian == IS_BIG_ENDIAN) return;
     
    596756PInPersist::GetU2   (uint_2& result)
    597757{
    598   CheckTag(2);
     758  CheckTag(2,PPS_DATATYPE_UNSIGNED);
    599759  GetRawBytes(&result, sizeof(uint_2));
    600760  if (bigEndian != IS_BIG_ENDIAN)
     
    605765PInPersist::GetU2s  (uint_2* tab, size_t n)
    606766{
    607   CheckArrayTag(2,n);
     767  CheckArrayTag(2,n,PPS_DATATYPE_UNSIGNED);
    608768  GetRawBytes(tab, n*sizeof(uint_2));
    609769  if (bigEndian == IS_BIG_ENDIAN) return;
     
    618778PInPersist::GetI4   (int_4& result)
    619779{
    620   CheckTag(4);
     780  CheckTag(4,PPS_DATATYPE_INTEGER);
    621781  GetRawBytes(&result, sizeof(int_4));
    622782  if (bigEndian != IS_BIG_ENDIAN)
     
    627787PInPersist::GetI4s  (int_4* tab, size_t n)
    628788{
    629   CheckArrayTag(4,n);
     789  CheckArrayTag(4,n,PPS_DATATYPE_INTEGER);
    630790  GetRawBytes(tab, n*sizeof(int_4));
    631791  if (bigEndian == IS_BIG_ENDIAN) return;
     
    640800PInPersist::GetU4   (uint_4& result)
    641801{
    642   CheckTag(4);
     802  CheckTag(4,PPS_DATATYPE_UNSIGNED);
    643803  GetRawBytes(&result, sizeof(uint_4));
    644804  if (bigEndian != IS_BIG_ENDIAN)
     
    649809PInPersist::GetU4s  (uint_4* tab, size_t n)
    650810{
    651   CheckArrayTag(4,n);
     811  CheckArrayTag(4,n,PPS_DATATYPE_UNSIGNED);
    652812  GetRawBytes(tab, n*sizeof(uint_4));
    653813  if (bigEndian == IS_BIG_ENDIAN) return;
     
    663823PInPersist::GetI8   (int_8& result)
    664824{
    665   CheckTag(8);
     825  CheckTag(8,PPS_DATATYPE_INTEGER);
    666826  GetRawBytes(&result, sizeof(int_8));
    667827  if (bigEndian != IS_BIG_ENDIAN)
     
    672832PInPersist::GetI8s  (int_8* tab, size_t n)
    673833{
    674   CheckArrayTag(8,n);
     834  CheckArrayTag(8,n,PPS_DATATYPE_INTEGER);
    675835  GetRawBytes(tab, n*sizeof(int_8));
    676836  if (bigEndian == IS_BIG_ENDIAN) return;
     
    685845PInPersist::GetU8   (uint_8& result)
    686846{
    687   CheckTag(8);
     847  CheckTag(8,PPS_DATATYPE_UNSIGNED);
    688848  GetRawBytes(&result, sizeof(uint_8));
    689849  if (bigEndian != IS_BIG_ENDIAN)
     
    694854PInPersist::GetU8s  (uint_8* tab, size_t n)
    695855{
    696   CheckArrayTag(8,n);
     856  CheckArrayTag(8,n,PPS_DATATYPE_UNSIGNED);
    697857  GetRawBytes(tab, n*sizeof(uint_8));
    698858  if (bigEndian == IS_BIG_ENDIAN) return;
     
    708868PInPersist::GetLine(char* ptr, size_t len)
    709869{
    710   char ppstype;
    711   GetTypeTag(ppstype);
    712   if (ppstype != PPS_LINE)
    713     throw FileFormatExc("PInPersist::GetLine   bad type in ppersist file");
    714   s->getline(ptr, len, '\n');
     870  string str;
     871  GetStr(str);
     872  strncpy(ptr, str.c_str(), len);
     873  ptr[len] = '\0';
    715874}
    716875
     
    718877PInPersist::GetStr(string& str)
    719878{
    720   char ppstype;
     879  unsigned char ppstype;
    721880  GetTypeTag(ppstype);
    722881  if (ppstype != PPS_STRING)
    723     throw FileFormatExc("PInPersist::GetLine   bad type in ppersist file");
    724   int_2 len;
    725   GetRawI2(len);
     882    throw FileFormatExc("PInPersist::GetStr   bad type in ppersist file");
     883  int_4 len;
     884  GetRawI4(len);
    726885  char * buff = new char[len+1];
    727886  GetRawBytes(buff, len);
     
    731890}
    732891
     892
    733893PPersist*
    734894PInPersist::ReadObject()
    735895{
     896  return(GetPPObject());
     897}
     898
     899void
     900PInPersist::GetObject(AnyDataObj & o)
     901{
     902  GetPPObject(&o);
     903  return;
     904}
     905
     906void
     907PInPersist::GetObject(AnyDataObj & o, string tagname)
     908{
     909  GotoTag(tagname);
     910  GetPPObject(&o);
     911  return;
     912}
     913
     914PPersist*
     915PInPersist::GetPPObject(AnyDataObj * po)
     916{
    736917  // Get tag
    737   char ppstype;
     918  unsigned char ppstype;
    738919  GetTypeTag(ppstype);
    739920  if (ppstype != PPS_OBJECT && ppstype != PPS_REFERENCE && ppstype != PPS_NULL) {
     
    747928    uint_8 classId;
    748929    GetRawU8(classId);
     930    uint_8 oid,oid2;
     931    GetRawU8(oid);
    749932   
    750933    // Get factory method
     
    756939    // Create object
    757940    PPersist* object = f();
     941    //  If a DataObject was specified , we assign it to the PPersistObject
     942    if (po != NULL) object->SetDataObj(*po);
     943
    758944    object->ReadSelf(*this);
    759     assignObjectId(object);
     945    unsigned char ppstag;
     946    // Read the ENDOBJECT
     947    GetRawUByte(ppstag);
     948    if (ppstag != PPS_ENDOBJECT)
     949      throw FileFormatExc("PInPersist::ReadObject No PPS_ENDOBJECT tag");
     950    GetRawU8(oid2);
     951    if (oid2 != oid)
     952      throw FileFormatExc("PInPersist::ReadObject Inconsistent PPS-OId at PPS_ENDOBJECT ");
     953
     954    KeepOId(oid, *object);
    760955    return object;
    761   } else {
    762     // Get object id
    763     int_4 id;
    764     GetRawI4(id);
    765     if (id <0 || id>=objList.size()) {
    766       char msg[200];
    767       sprintf(msg, "PInPersist::ReadObject    invalid object id for reference: %d/%d",id,objList.size());
    768       throw FileFormatExc(msg);
     956  }
     957  else if (ppstype == PPS_REFERENCE)
     958    return ReadReference();
     959
     960  else throw FileFormatExc("PInPersist::ReadObject invalide Tag Type !"); 
     961}
     962
     963
     964void
     965PInPersist::AnalyseTags(int lev)
     966{
     967  unsigned char ppstag=0;
     968  unsigned char ppst1,ppst2,ppst3;
     969  uint_8 cpos,fsize;
     970  uint_8 ui8,cid,oid;
     971  int_4 i4;
     972  int_8 i8;
     973  char * buff;
     974  string str;
     975 
     976  cout << "\n ---------------------------------------------------------- " << endl;
     977  cout << " PInPersist::AnalyseTags(Level= " << lev << ")" << endl;
     978
     979
     980#ifdef STREAMPOS_IS_CLASS
     981  cpos = s->tellg().offset();
     982#else
     983  cpos = s->tellg();
     984#endif
     985  s->seekg(0,ios::end);
     986#ifdef STREAMPOS_IS_CLASS
     987  fsize = s->tellg().offset();
     988#else
     989  fsize = s->tellg();
     990#endif
     991  s->seekg(cpos,ios::beg);
     992
     993  cout << "   Version= " << Version() << " FileSize= " << fsize
     994       << " Creation Date= " << CreationDateStr() <<  endl;
     995 
     996  uint_8 totntags = 0;
     997  bool eofok = false;
     998
     999  while ( (ppstag != PPS_EOF) &&  (cpos < fsize) ) {
     1000#ifdef STREAMPOS_IS_CLASS
     1001  cpos = s->tellg().offset();
     1002#else
     1003  cpos = s->tellg();
     1004#endif
     1005    GetRawUByte(ppstag);
     1006    totntags++;
     1007
     1008    ppst1 = ppstag&0x0f;  // bits 0123
     1009    ppst2 = ppstag&0x30;  // bits     45
     1010    ppst3 = ppstag&0xc0;  // bits       67
     1011    if ((ppst2 == 0) && (ppst3 == 0) ) {
     1012      switch (ppst1) {
     1013
     1014      case PPS_NULL :
     1015        if (lev > 1)  cout << "<PPS_NULL> tag at position " << hex << cpos << dec << endl;
     1016        break;
     1017
     1018      case PPS_STRING :
     1019        GetRawI4(i4);
     1020        if (lev > 1)  cout << "<PPS_STRING> tag at position " << hex << cpos << dec
     1021                           << " Length=" << i4 << endl;
     1022        s->seekg(i4,ios::cur);
     1023        break;
     1024
     1025      case PPS_OBJECT :
     1026        GetRawU8(cid);
     1027        GetRawU8(oid);
     1028        cout << "<PPS_OBJECT> tag at position " << hex << cpos << " ClassId= " << cid
     1029             << "  ObjectId= " << oid << dec << endl;
     1030        break;
     1031
     1032      case PPS_REFERENCE :
     1033        GetRawU8(oid);
     1034        GetRawI8(i8);
     1035        cout << "<PPS_REFERENCE> tag at position " << hex << cpos << "  ObjectId= "
     1036             << oid << "  OrigPos=" << i8 << dec << endl;
     1037        break;
     1038
     1039      case PPS_TAG_MARK :
     1040        cout << "<PPS_TAG_MARK> tag at position " << hex << cpos << dec << endl;
     1041        break;
     1042     
     1043      case PPS_ENDOBJECT :
     1044        GetRawU8(oid);
     1045        cout << "<PPS_ENDOBJECT> tag at position " << hex << cpos << "  ObjectId= "
     1046             << oid << dec << endl;
     1047        break;
     1048
     1049      case PPS_TAG :
     1050        GetRawI8(i8);
     1051        GetRawI4(i4);
     1052        buff = new char[i4+1];
     1053        GetRawBytes(buff, i4);
     1054        buff[i4] = '\0';  str = buff;
     1055        delete[] buff;
     1056        cout << "<PPS_TAG> tag at position " << hex << cpos << dec
     1057             << " Name= " << str << endl;
     1058        break;
     1059
     1060      case PPS_EOF :
     1061        GetRawI8(i8);   
     1062        cout << "<PPS_EOF> tag at position " << hex << cpos 
     1063             << " TagPos=" << i8 << dec << endl;
     1064        eofok = true;
     1065        break;
     1066
     1067      default :
     1068        cerr << " ERROR : Unexpected tag value " << hex << ppstag
     1069             << " At position" << cpos << dec << endl;
     1070        throw FileFormatExc("PInPersist::AnalyseTags() - Unexpected tag value !");
     1071      }
    7691072    }
    770     return objList[id];
    771   }
    772 }
    773 
    774 int_4
    775 PInPersist::assignObjectId(PPersist* x)
    776 {
    777   objList.push_back(x);
    778   return objList.size()-1;
     1073    else {
     1074      string dtype = "???? x";
     1075      if (ppst3 == PPS_DATATYPE_CHAR) dtype = "CHAR x";
     1076      else if (ppst3 == PPS_DATATYPE_FLOAT) dtype = "FLOAT x";
     1077      else if (ppst3 == PPS_DATATYPE_INTEGER) dtype = "INTEGER x";
     1078      else if (ppst3 == PPS_DATATYPE_UNSIGNED) dtype = "UNSIGNED x";
     1079      int_4 dsize = ppst1;
     1080      char sb[16];
     1081      sprintf(sb, "%d", dsize);
     1082      dtype += sb;
     1083
     1084      switch (ppst2) {
     1085
     1086      case PPS_SIMPLE :
     1087        if (lev > 2)  cout << "<PPS_SIMPLE> tag at position " << hex << cpos << dec
     1088                           << " DataType=" << dtype << endl;
     1089        s->seekg(dsize, ios::cur);
     1090        break;
     1091
     1092      case PPS_SIMPLE_ARRAY4 :
     1093        GetRawI4(i4);
     1094        if (lev > 0)  cout << "<PPS_SIMPLE_ARRAY4> tag at position " << hex << cpos << dec
     1095                           << " DataType=" << dtype << " NElts= " << i4 << endl;
     1096        s->seekg((uint_8)dsize*(uint_8)i4, ios::cur);
     1097        break;
     1098
     1099      case PPS_SIMPLE_ARRAY8 :
     1100        GetRawU8(ui8);
     1101        if (lev > 0)  cout << "<PPS_SIMPLE_ARRAY8> tag at position " << hex << cpos << dec
     1102                           << " DataType=" << dtype << " NElts= " << ui8 << endl;
     1103        s->seekg((uint_8)dsize*ui8, ios::cur);
     1104        break;
     1105      }
     1106    }
     1107  }
     1108  if (!eofok)
     1109    throw FileFormatExc("PInPersist::AnalyseTags() - Not found <PPS_EOF> tag ");
     1110
     1111  cout << " PInPersist::AnalyseTags() - End - Total Number of Tags= " << totntags << endl;
     1112  cout << " ---------------------------------------------------------- \n" << endl;
     1113  return;
     1114}
     1115
     1116void
     1117PInPersist::ReadReference(PPersist & ppo)
     1118{
     1119  PPersist * pr = ReadReference();
     1120  ppo.ShareDataReference(*pr);
     1121}
     1122
     1123
     1124PPersist *
     1125PInPersist::ReadReference()
     1126{
     1127  uint_8 oid;
     1128  int_8 pos;
     1129  GetRawU8(oid);
     1130  GetRawI8(pos);
     1131  //  cerr << " DBG - PInPersist::ReadReference-A "  << oid << " Pos= " << pos << endl;
     1132  map<uint_8, PPersist *>::iterator i = objList.find(oid);
     1133  if (i != objList.end()) return (*i).second;
     1134  else  {  // We may have skeeped it !
     1135    // Let's try to read it
     1136    int_8 cpos;
     1137#ifdef STREAMPOS_IS_CLASS
     1138    cpos = s->tellg().offset();
     1139#else
     1140    cpos = s->tellg();
     1141#endif
     1142    s->seekg(pos);
     1143    PPersist* ppo = ReadObject();
     1144    s->seekg(cpos);
     1145    delete ppo;
     1146    //    cerr << " DBG - PInPersist::ReadReference-B ... " << endl; 
     1147
     1148    map<uint_8, PPersist *>::iterator i2 = objList.find(oid);
     1149    if (i2 == objList.end())
     1150      throw FileFormatExc("PInPersist::ReadReference()   Not found PPS_OId ");
     1151    return (*i2).second;
     1152  }
     1153}
     1154
     1155
     1156void
     1157PInPersist::KeepOId(uint_8 oid, PPersist & ppo)
     1158{
     1159  if ((oid&0x1) == 0)  return; // This is not an object which can be referenced
     1160  //  cerr << " DBG - PInPersist::KeepOId() " << oid << endl;
     1161  if ((objList.size() > 0) && (objList.find(oid) != objList.end()) ) {
     1162    //  Ceci ne devrait arriver que si on lit dans le desordre (avec GotoTag)
     1163    //  et pas avec une lecture sequentielle ...   Reza 03/2000
     1164    //  cerr << "PInPersist::KeepOId()/Warning - already present PPS_ObjectId ! " << oid << endl;
     1165    if (seqread) throw FileFormatExc("PInPersist::KeepOId() already present PPS_ObjectId ");
     1166    PPersist *pp = (*objList.find(oid)).second;
     1167    ppo.ShareDataReference(*pp);
     1168  }
     1169  else {
     1170    PPersist * npp = ppo.CloneSharedReference();
     1171    if (npp == NULL) throw PError("PInPersist::KeepOId() NULL returned by PPersist.Clone() ! ");
     1172    objList[oid] = npp;
     1173  }
     1174  return;
    7791175}
    7801176
     
    8031199    bigEndian = endianness;
    8041200
     1201  // PPS (POutPersist stream) Object Id initialisation
     1202  pps_OId = 0;
    8051203  // Output stream creation
    8061204  s = new ofstream(flnm.c_str(),ios::out | IOS_BIN); 
    8071205
    8081206  // Header
    809   PutRawBytes("SOS-SOPHYA-PPersistFile V1               ",32);
     1207  PutRawBytes("SOS-SOPHYA-PPersistFile V2               ",32);
    8101208  PutRawBytes(bigEndian
    8111209           ? "BIG-ENDIAN                             "
     
    8191217  datestring[32] = '\0';
    8201218  PutRawBytes(datestring, 32);
     1219  filename = flnm;
    8211220}
    8221221
     
    8241223{
    8251224  if (tags.size() == 0) {
    826     PutRawByte(PPS_EOF);
     1225    PutRawUByte(PPS_EOF);
    8271226    PutRawI8(-1);
    8281227  } else {
     
    8361235      string name = (*i).first;
    8371236      int_8 pos = (*i).second;
    838       PutRawByte(PPS_TAG);                       // This is a tag
     1237      PutRawUByte(PPS_TAG);                       // This is a tag
    8391238      PutRawI8(pos);                             // position of previous tag
    8401239      PutRawI4(name.length());                   // length of the name
    8411240      PutRawBytes(name.c_str(), name.length());  // name, without final "0".
    8421241    }
    843     PutRawByte(PPS_EOF);
     1242    PutRawUByte(PPS_EOF);
    8441243    PutRawI8(tagPos);
    8451244  }
     
    8681267
    8691268  tags[name] = tagPos;
    870   PutRawByte(PPS_TAG_MARK);                       // This is a tag
    871   objList.clear(); // $CHECK$ EA 171199
     1269  PutRawUByte(PPS_TAG_MARK);                       // This is a tag
     1270  //  objList.clear(); // $CHECK$ EA 171199  - Ne pas faire ? Reza 03/2000
    8721271}
    8731272
     
    9141313
    9151314void
     1315POutPersist::PutRawUByte(unsigned char c)
     1316{
     1317  PutRawBytes(&c, 1);
     1318}
     1319
     1320void
    9161321POutPersist::PutRawI2   (int_2 val)
    9171322{
     
    9501355
    9511356void
    952 POutPersist::PutArrayTag(short datasz, size_t sz)
    953 {
    954   if (sz <= 0x7fff) {
    955     PutRawByte(PPS_SIMPLE_ARRAY + datasz);
    956     PutRawI2(sz);
    957   } else if (sz <= 0x7fffffff) {
    958     PutRawByte(PPS_SIMPLE_ARRAY4 + datasz);
     1357POutPersist::PutArrayTag(short datasz, size_t sz, short datatype)
     1358// datatype = PPS_DATATYPE_CHAR or PPS_DATATYPE_FLOAT or PPS_DATATYPE_INTEGER or PPS_DATATYPE_UNSIGNED
     1359{
     1360  if (sz <= 0x7fffffff) {
     1361    PutRawUByte(PPS_SIMPLE_ARRAY4 + datasz + datatype);
    9591362    PutRawI4(sz);
    9601363  } else {
    961     PutRawByte(PPS_SIMPLE_ARRAY8 + datasz);
     1364    PutRawUByte(PPS_SIMPLE_ARRAY8 + datasz + datatype);
    9621365    PutRawU8(sz);
    9631366  }
     
    9671370POutPersist::PutByte(char c)
    9681371{
    969   PutRawByte(PPS_SIMPLE + 1);
     1372  PutRawByte(PPS_SIMPLE + 1 + PPS_DATATYPE_CHAR);
    9701373  PutRawBytes(&c, 1);
    9711374}
     
    9761379POutPersist::PutBytes(void const* ptr, size_t bytes)
    9771380{
    978   PutArrayTag(1, bytes);
     1381  PutArrayTag(1, bytes, PPS_DATATYPE_CHAR);
    9791382  PutRawBytes(ptr, bytes);
    9801383}
     
    9831386POutPersist::PutR4   (r_4 val)
    9841387{
    985   PutRawByte(PPS_SIMPLE + 4);
     1388  PutRawUByte(PPS_SIMPLE + 4 + PPS_DATATYPE_FLOAT);
    9861389 
    9871390  if (bigEndian != IS_BIG_ENDIAN)
     
    9941397POutPersist::PutR4s  (r_4 const* tab, size_t n)
    9951398{
    996   PutArrayTag(4, n);
     1399  PutArrayTag(4, n, PPS_DATATYPE_FLOAT);
    9971400
    9981401  if (bigEndian == IS_BIG_ENDIAN) {
     
    10101413POutPersist::PutR8   (r_8 val)
    10111414{
    1012   PutRawByte(PPS_SIMPLE + 8);
     1415  PutRawUByte(PPS_SIMPLE + 8 + PPS_DATATYPE_FLOAT);
    10131416
    10141417  if (bigEndian != IS_BIG_ENDIAN)
     
    10211424POutPersist::PutR8s  (r_8 const* tab, size_t n)
    10221425{
    1023   PutArrayTag(8, n);
     1426  PutArrayTag(8, n, PPS_DATATYPE_FLOAT);
    10241427
    10251428  if (bigEndian == IS_BIG_ENDIAN) {
     
    10371440POutPersist::PutI2   (int_2 val)
    10381441{
    1039   PutRawByte(PPS_SIMPLE + 2);
     1442  PutRawUByte(PPS_SIMPLE + 2 + PPS_DATATYPE_INTEGER);
    10401443
    10411444  if (bigEndian != IS_BIG_ENDIAN)
     
    10481451POutPersist::PutI2s  (int_2 const* tab, size_t n)
    10491452{
    1050   PutArrayTag(2, n);
     1453  PutArrayTag(2, n, PPS_DATATYPE_INTEGER);
    10511454 
    10521455  if (bigEndian == IS_BIG_ENDIAN) {
     
    10641467POutPersist::PutU2   (uint_2 val)
    10651468{
    1066   PutRawByte(PPS_SIMPLE + 2);
     1469  PutRawUByte(PPS_SIMPLE + 2 + PPS_DATATYPE_UNSIGNED);
    10671470
    10681471  if (bigEndian != IS_BIG_ENDIAN)
     
    10751478POutPersist::PutU2s  (uint_2 const* tab, size_t n)
    10761479{
    1077   PutArrayTag(2, n);
     1480  PutArrayTag(2, n, PPS_DATATYPE_UNSIGNED);
    10781481
    10791482  if (bigEndian == IS_BIG_ENDIAN) {
     
    10911494POutPersist::PutI4   (int_4 val)
    10921495{
    1093   PutRawByte(PPS_SIMPLE + 4);
     1496  PutRawUByte(PPS_SIMPLE + 4 + PPS_DATATYPE_INTEGER);
    10941497
    10951498  if (bigEndian != IS_BIG_ENDIAN)
     
    11021505POutPersist::PutI4s  (int_4 const* tab, size_t n)
    11031506{
    1104   PutArrayTag(4, n);
     1507  PutArrayTag(4, n, PPS_DATATYPE_INTEGER);
    11051508
    11061509  if (bigEndian == IS_BIG_ENDIAN) {
     
    11181521POutPersist::PutU4   (uint_4 val)
    11191522{
    1120   PutRawByte(PPS_SIMPLE + 4);
     1523  PutRawUByte(PPS_SIMPLE + 4 + PPS_DATATYPE_UNSIGNED);
    11211524
    11221525  if (bigEndian != IS_BIG_ENDIAN)
     
    11291532POutPersist::PutU4s  (uint_4 const* tab, size_t n)
    11301533{
    1131   PutArrayTag(4, n);
     1534  PutArrayTag(4, n, PPS_DATATYPE_UNSIGNED);
    11321535
    11331536  if (bigEndian == IS_BIG_ENDIAN) {
     
    11451548POutPersist::PutI8   (int_8 val)
    11461549{
    1147   PutRawByte(PPS_SIMPLE + 8);
     1550  PutRawUByte(PPS_SIMPLE + 8 + PPS_DATATYPE_INTEGER);
    11481551
    11491552  if (bigEndian != IS_BIG_ENDIAN)
     
    11561559POutPersist::PutI8s  (int_8 const* tab, size_t n)
    11571560{
    1158   PutArrayTag(8, n);
     1561  PutArrayTag(8, n, PPS_DATATYPE_INTEGER);
    11591562
    11601563  if (bigEndian == IS_BIG_ENDIAN) {
     
    11721575POutPersist::PutU8   (uint_8 val)
    11731576{
    1174   PutRawByte(PPS_SIMPLE + 8);
     1577  PutRawUByte(PPS_SIMPLE + 8 + PPS_DATATYPE_UNSIGNED);
    11751578
    11761579  if (bigEndian != IS_BIG_ENDIAN)
     
    11831586POutPersist::PutU8s  (uint_8 const* tab, size_t n)
    11841587{
    1185   PutArrayTag(8, n);
     1588  PutArrayTag(8, n, PPS_DATATYPE_UNSIGNED);
    11861589
    11871590  if (bigEndian == IS_BIG_ENDIAN) {
     
    11991602POutPersist::PutStr(string const& str)
    12001603{
    1201   PutRawByte(PPS_STRING);
    1202   PutRawI2(str.length());
     1604  PutRawUByte(PPS_STRING);
     1605  PutRawI4(str.length());
    12031606  PutRawBytes(str.c_str(), str.length());
    12041607}
     
    12071610POutPersist::PutLine(char const* ptr, size_t len)
    12081611{
    1209   PutRawByte(PPS_LINE);
    1210 
    1211   if (len == 0)  len = strlen(ptr);
    1212   PutRawBytes(ptr, len);
    1213   PutRawByte('\n');
    1214 }
    1215 
    1216 void
    1217 POutPersist::PutObject(PPersist const* obj)
    1218 {
    1219   if (serializeNullAndRepeat(obj)) return;
    1220 
    1221   PutRawByte(PPS_OBJECT);
    1222   PutRawU8(getTypeId(typeid(*obj).name()));
    1223   //PutRawU8(PIOPersist::Hash(typeid(*obj).name()));
    1224   assignObjectId(obj);
     1612  string str = ptr;
     1613  PutStr(str);
     1614}
     1615
     1616
     1617void
     1618POutPersist::PutObject(AnyDataObj & o)
     1619{
     1620  ClassCreatorFunc f = FindCreatorFunc(getDataObjClassId(o));
     1621  if (!f)
     1622      throw NotFoundExc("PInPersist::PutObject()   class not registered");
     1623  PPersist* ppo = f();
     1624  ppo->SetDataObj(o);
     1625  PutPPObject(ppo);
     1626}
     1627
     1628void
     1629POutPersist::PutObject(AnyDataObj & o, string tagname)
     1630{
     1631  WriteTag(tagname);
     1632  PutObject(o);
     1633}
     1634
     1635
     1636void
     1637POutPersist::PutPPObject(PPersist const* obj)
     1638{
     1639  if (serializeNullAndRepeat(obj)) return;  // NULL object or already written in stream
     1640
     1641  //   We have to write the object
     1642  uint_8 oid = assignObjectId(obj);       // We assing a PPS Object Id
     1643  PutRawUByte(PPS_OBJECT);         // We write the Object Tag
     1644  PutRawU8(getPPClassId(*obj));    // Writing the PPersist ClassId
     1645  PutRawU8(oid);                   // Write the PPS Object Id
    12251646  obj->WriteSelf(*this);
     1647  PutRawUByte(PPS_ENDOBJECT);      // We write the End-Of-Object Tag
     1648  PutRawU8(oid);                   // and again its PPS Object Id
    12261649}
    12271650
     
    12301653{
    12311654  if (x == NULL) {
    1232     PutRawByte(PPS_NULL);
     1655    PutRawUByte(PPS_NULL);
    12331656    return true;
    12341657  }
    12351658
    1236   int_4 id = findObjectId(x);
    1237   if (id >= 0) {
    1238     PutRawByte(PPS_REFERENCE);
    1239     PutRawI4(id);
     1659  int_8 pos;
     1660  uint_8 id = findObjectId(x, pos);
     1661  if (id > 0) {
     1662    PutRawUByte(PPS_REFERENCE);
     1663    PutRawU8(id);      // Writing the corresponding object Id
     1664    PutRawI8(pos);     // The original object position
    12401665    return true;
    12411666  }
    12421667 
    1243   return false;
    1244 }
    1245 
    1246 int_4
     1668  return false;  // Object have to be written in stream ...
     1669}
     1670
     1671uint_8
    12471672POutPersist::assignObjectId(PPersist const* x)
    12481673{
    1249   int_4 id = objList.size();
    1250   objList[x] = id;
     1674  pps_OId += 16;  // We keep the three first bytes for future usage
     1675                  // Bit 1 non zero -> Object can be referenced
     1676  uint_8 id = pps_OId;
     1677  uint_8 mid = x->getMemOId();
     1678  if (mid > 0) {
     1679    int_8 pos;
     1680    if (findObjectId(x,pos) > 0) 
     1681      throw PError("POutPersist::assignObjectId() Error - Already serialized object ! ");
     1682    id += 1;  // Object Id starting at zero
     1683    objreftag rt;
     1684    rt.ppsoid = id;
     1685#ifdef STREAMPOS_IS_CLASS
     1686    rt.ppspos = s->tellp().offset();
     1687#else
     1688    rt.ppspos = s->tellp();
     1689#endif
     1690    objList[mid] = rt;
     1691  }
    12511692  return id;
    12521693}
    12531694
    1254 int_4
    1255 POutPersist::findObjectId(PPersist const* x)
    1256 {
    1257   ObjList::iterator i = objList.find(x);
    1258   if (i == objList.end()) return -1;
    1259   return (*i).second;
    1260 }
    1261 
    1262 
     1695uint_8
     1696POutPersist::findObjectId(PPersist const* x, int_8 & pos)
     1697{
     1698  pos = -1;
     1699  uint_8 mid = x->getMemOId();
     1700  if (mid == 0)   return(0);
     1701  ObjList::iterator i = objList.find(mid);
     1702  if (i == objList.end()) return 0;
     1703  pos = (*i).second.ppspos;
     1704  return (*i).second.ppsoid;
     1705}
     1706
     1707
Note: See TracChangeset for help on using the changeset viewer.