Index: trunk/SophyaLib/BaseTools/ppfbinstream.cc
===================================================================
--- trunk/SophyaLib/BaseTools/ppfbinstream.cc	(revision 2476)
+++ trunk/SophyaLib/BaseTools/ppfbinstream.cc	(revision 2477)
@@ -49,4 +49,72 @@
 }
 
+//-------------------------------------------------------------------------
+//----------------------  Classe PPFBinaryIOStream ------------------------
+//-------------------------------------------------------------------------
+
+
+PPFBinaryIOStream::PPFBinaryIOStream()
+{
+  version = 0;     // PPersist(In/Out) version 
+  //  creationdate = time(NULL);   // Date de creation du fichier
+  _nbpostag = 0;     // Nb de tag de positionnement
+  _nbobjs = 0;       // Nb total d'objets
+  _nbtlobjs = 0;     // Nb d'objets de niveau 1 
+}
+
+PPFBinaryIOStream::~PPFBinaryIOStream()
+{
+}
+
+string 
+PPFBinaryIOStream::CreationDateStr()
+{
+  time_t cdt = CreationDate();
+  string cdate = ctime(&cdt);
+  return(cdate);
+}
+
+string 
+PPFBinaryIOStream::InfoString()
+{
+  string rs;
+  char buff[256];
+  sprintf(buff,"PPFStream Version= %d  CreationDate= ", Version());
+  rs += buff;
+  rs += CreationDateStr();
+  sprintf(buff,"\n NbObjs= %ld NbTopLevObjs= %ld ", (long)NbObjects(), 
+	  (long)NbTopLevelObjects());
+  rs += buff;
+  sprintf(buff,"\n NbPosTag= %ld NbNameTag= %ld ", (long)NbPosTags(), 
+	  (long)NbNameTags());
+   rs += buff;
+   return rs;
+}
+
+
+string
+PPFBinaryIOStream::GetTagName(int itag)
+{
+  if (itag<0 || itag >= (int)tags.size()) return "";
+  map<string, int_8>::iterator i = tags.begin();
+  for (int j=0; j<itag; j++) i++;
+  return((*i).first);
+}
+
+
+static vector<string> * ret_tag_names = NULL;
+vector<string> const &
+PPFBinaryIOStream::GetNameTags()
+{
+if (ret_tag_names) delete ret_tag_names;
+ret_tag_names = new vector<string> ;
+map<string, int_8>::iterator i;
+for(i=tags.begin(); i!=tags.end(); i++) ret_tag_names->push_back((*i).first);
+return(*ret_tag_names);  
+}
+
+//-------------------------------------------------------------------------
+//--------------------  Classe PPFBinaryInputStream -----------------------
+//-------------------------------------------------------------------------
 
 PPFBinaryInputStream::PPFBinaryInputStream(RawInOutStream * is, bool ad, bool scan)
@@ -123,15 +191,4 @@
 
 
-
-
-
-string 
-PPFBinaryInputStream::CreationDateStr()
-{
-  time_t cdt = CreationDate();
-  string cdate = ctime(&cdt);
-  return(cdate);
-}
-
 void
 PPFBinaryInputStream::ReadNameTagTable()
@@ -142,16 +199,10 @@
 
   s->seekg(-(sizeof(int_8)+1), ios::end);
-
+  // Lecture position NameTagTable et tag EOF
+  int_8 pos;
+  GetRawI8(pos);
   GetTypeTag(ppstype);
   if (ppstype != PPS_EOF)
     throw FileFormatExc("PPFBinaryInputStream::ReadNameTagTable()  Corrupted file, no EOF tag at end of file");
-
-  // Lecture position NameTagTable
-  int_8 pos;
-  GetRawI8(pos);
-  if (pos < 0) {  // no tags
-    s->seekg(debut);
-    return;
-  }
   
   // On se positionne au debut du NameTagTable
@@ -160,12 +211,19 @@
   if (ppstype != PPS_NAMETAG_TABLE)
     throw FileFormatExc("PPFBinaryInputStream::ReadNameTagTable()  Corrupted file PPS_NAMETAG_TABLE not found");
+  // Lecture nb de PosTag et nb d'objets dans le flot
+  GetI8(_nbpostag);
+  GetI8(_nbobjs);
+  GetI8(_nbtlobjs);
   uint_8 ttsz,it;
+  // Lecture nombre de NameTag
   GetU8(ttsz);
-  for(it=0; it<ttsz; it++) {
-    int_8 tpos;
-    string tname;
-    GetI8(tpos);
-    GetStr(tname);
-    tags[tname] = tpos;
+  if (ttsz > 0) {
+    for(it=0; it<ttsz; it++) {
+      int_8 tpos;
+      string tname;
+      GetI8(tpos);
+      GetStr(tname);
+      tags[tname] = tpos;
+    }
   }
   // On revient au debut du float, juste apres l'entete
@@ -218,10 +276,4 @@
 
 
-int
-PPFBinaryInputStream::NbNameTags()
-{
-  return tags.size();
-}
-
 bool 
 PPFBinaryInputStream::GotoPositionTag(int_8 pos)
@@ -261,30 +313,23 @@
 }
 
-string
-PPFBinaryInputStream::GetTagName(int itag)
-{
-  if (itag<0 || itag >= (int)tags.size()) return "";
-  map<string, int_8>::iterator i = tags.begin();
-  for (int j=0; j<itag; j++) i++;
-  return((*i).first);
-}
-
-
-static vector<string> * ret_tag_names = NULL;
-vector<string> const &
-PPFBinaryInputStream::GetNameTags()
-{
-if (ret_tag_names) delete ret_tag_names;
-ret_tag_names = new vector<string> ;
-map<string, int_8>::iterator i;
-for(i=tags.begin(); i!=tags.end(); i++) ret_tag_names->push_back((*i).first);
-return(*ret_tag_names);  
-}
 
 bool
 PPFBinaryInputStream::SkipToNextObject()
 {
-  // A FAIRE NOV 2003 - REZA
-  return true;
+  if (! s->isSeekable())  return false;
+  unsigned char ppstag=0;
+  // int kss;
+  while ((ppstag != PPS_OBJECT) && (ppstag != PPS_REFERENCE) && (ppstag != PPS_EOF)) {
+    // kss++;
+    GetRawUByte(ppstag);
+    //    cout << " DBG--SkipToNextObject(" << kss << ")" << (int)ppstag << "," 
+    //	 << (int)PPS_OBJECT << " fpos=" << s->tellg() << endl;
+    if  ((ppstag != PPS_OBJECT) && (ppstag != PPS_REFERENCE) && (ppstag != PPS_EOF))
+      SkipItem(false, ppstag);
+  }
+  s->seekg(-1, ios::cur);
+  if (ppstag == PPS_OBJECT) return true;
+  else return false;
+  
 }
 
@@ -292,20 +337,195 @@
 PPFBinaryInputStream::SkipNextItem()
 {
-  // A FAIRE NOV 2003 - REZA
+  if (! s->isSeekable())  return false;
+  SkipItem();
   return true;
 }
 
 char
-PPFBinaryInputStream::NextItemTag(short datasz, size_t sz)
-{
+PPFBinaryInputStream::NextItemTag(short datasz, size_t asz)
+{
+  int_8 cpos;
+  cpos = s->tellg();
+
+  unsigned char ppstag=0;
+  unsigned char ppst1,ppst2,ppst3,ppst30;
+  GetRawUByte(ppstag);
+  ppst1 = ppstag&0x0f;  // bits 0123
+  ppst2 = ppstag&0x30;  // bits     45
+  ppst3 = ppstag&0xc0;  // bits       67
+  ppst30 = ppstag&0xc1; // bits 0     67
+  
   datasz = 0;
-  sz = 0;
-  return 0;
+  asz = 0;
+
+  int_4 i4;
+  int_8 i8;
+  uint_8 ui8;
+
+  if ((ppst2 == 0) && (ppst3 == 0) ) {
+    switch (ppst1) {
+    case PPS_STRING :
+      GetRawI4(i4);
+      datasz = 1;
+      asz = i4;
+      break;
+      
+    case PPS_NULL :
+    case PPS_OBJECT :
+    case PPS_REFERENCE :
+    case PPS_NAMETAG_MARK :
+    case PPS_POSTAG_MARK :
+    case PPS_ENDOBJECT :
+    case PPS_POSTAG_TABLE :
+    case PPS_NAMETAG_TABLE :
+    case PPS_EOF :
+      datasz = 0;
+      asz = 0;
+      break;
+
+    default :
+      throw FileFormatExc("PPFBinaryInputStream::NextItemTag() - Unexpected tag value !");
+      break;
+    }
+  }
+  else {
+    int_4 dsize = ppst1;
+    int_4 dsizeskip = dsize;
+    if (ppst30 == PPS_DATATYPE_COMPLEX) { 
+      dsize--;
+      dsizeskip = 2*dsize;
+    }
+    switch (ppst2) {      
+    case PPS_SIMPLE :
+      datasz = dsize;
+      asz = 1;      
+      break;
+
+    case PPS_SIMPLE_ARRAY4 :
+      GetRawI4(i4);
+      datasz = dsize;
+      asz = i4;      
+      break;
+
+    case PPS_SIMPLE_ARRAY8 :
+      GetRawU8(ui8);
+      datasz = dsize;
+      asz = i8;      
+      break;
+    }
+  }
+
+  s->seekg(cpos,ios::beg);
+  return(ppstag);
 }
 
 void 
-PPFBinaryInputStream::SkipItem(bool fgrdt, char itag)
-{
-  return;
+PPFBinaryInputStream::SkipItem(bool fgrdt, unsigned char itag)
+{
+  unsigned char ppstag=0;
+  unsigned char ppst1,ppst2,ppst3,ppst30;
+  uint_8 ui8;
+  int_4 i4;
+  int_8 i8;
+  
+
+  if (fgrdt)  GetRawUByte(ppstag);
+  else ppstag = itag;
+
+  ppst1 = ppstag&0x0f;  // bits 0123
+  ppst2 = ppstag&0x30;  // bits     45
+  ppst3 = ppstag&0xc0;  // bits       67
+  ppst30 = ppstag&0xc1; // bits 0     67
+  if ((ppst2 == 0) && (ppst3 == 0) ) {
+    switch (ppst1) {  
+    case PPS_NULL :
+    case PPS_NAMETAG_MARK :
+      break;
+
+    case PPS_STRING :
+      GetRawI4(i4);
+      s->seekg(i4,ios::cur);
+      break;
+
+    case PPS_OBJECT :
+      GetRawU8(ui8);
+      GetRawU8(ui8);
+      break;
+      
+    case PPS_REFERENCE :
+      GetRawU8(ui8);
+      GetRawI8(i8);
+      break;
+
+    case PPS_POSTAG_MARK :
+      GetRawI8(i8);	
+      break;
+     
+    case PPS_ENDOBJECT :
+      GetRawU8(ui8);
+      break;
+
+    case PPS_POSTAG_TABLE :
+      GetRawI4(i4);
+      //      for(int kkt=0; kkt<i4; kkt++)  GetRawI8(i8);	
+      s->seekg((int_8)i4*8,ios::cur);
+      break;
+
+    case PPS_NAMETAG_TABLE :
+      if (Version() < 3) {
+	GetRawI8(i8);
+	GetRawI4(i4);
+	s->seekg(i4,ios::cur);
+	}
+      else {
+	GetI8(i8);  // nb pos tag
+	GetI8(i8);  // nb d'objets
+	GetI8(i8);  // nb objets toplevel
+	GetU8(ui8); // nb de nametag
+	for(int kt=0; kt<ui8; kt++) {
+	  GetRawI4(i4);
+	  s->seekg(i4,ios::cur);
+	}
+	GetI8(i8);  // position debut NameTagTable
+      }
+      break;
+      
+
+    case PPS_EOF :
+      if (Version() < 3) GetRawI8(i8);	
+      break;
+      
+    default :
+      cerr << "PPFBinaryInputStream::SkipItem() ERROR : Unexpected tag value " 
+	   << hex << ppstag << " At position" << s->tellg() << dec << endl;
+      throw FileFormatExc("PPFBinaryInputStream::SkipItem() - Unexpected tag value !");
+    }
+  }
+  else {
+    string dtype = "???? x";
+    int_4 dsize = ppst1;
+    int_8 dsizeskip = dsize;
+    if (ppst30 == PPS_DATATYPE_COMPLEX) { 
+      dsize--;
+      dsizeskip = 2*dsize;
+    }
+
+    switch (ppst2) {
+    case PPS_SIMPLE :
+      s->seekg(dsizeskip, ios::cur);
+      break;
+
+    case PPS_SIMPLE_ARRAY4 :
+      GetRawI4(i4);
+      s->seekg(dsizeskip*(int_8)i4, ios::cur);
+      break;
+      
+    case PPS_SIMPLE_ARRAY8 :
+      GetRawU8(ui8);
+      s->seekg(dsizeskip*ui8, ios::cur);
+      break;
+    }
+  }
+return;
 }
 
@@ -793,7 +1013,11 @@
   s->seekg(cpos,ios::beg);
 
+  cout << "   FileName= " << FileName() << endl;
   cout << "   Version= " << Version() << " FileSize= " << fsize 
        << " Creation Date= " << CreationDateStr() <<  endl;
-  
+  cout << " NbPosTag=" << NbPosTags() << " NbNameTag=" << tags.size() 
+       << " NbObjs=" << NbObjects() << " NbTopLevObjs=" << NbTopLevelObjects()
+       << endl << endl;
+
   uint_8 totntags = 0;
   bool eofok = false;
@@ -859,16 +1083,34 @@
 
       case PPS_NAMETAG_TABLE :
-	GetRawI8(i8);
-	GetRawI4(i4);
-	buff = new char[i4+1];
-	GetRawBytes(buff, i4); 
-        buff[i4] = '\0';  str = buff;
-	delete[] buff;
-	cout << "<PPS_TAG> tag at position " << hex << cpos << dec 
-	     << " Name= " << str << endl; 
+	if (Version() < 3) {
+	  GetRawI8(i8);
+	  GetRawI4(i4);
+	  buff = new char[i4+1];
+	  GetRawBytes(buff, i4); 
+	  buff[i4] = '\0';  str = buff;
+	  delete[] buff;
+	  cout << "<PPS_NAMETAG_TABLE> tag at position " << hex << cpos << dec 
+	       << " Name= " << str << endl; 
+	}
+	else {
+	  cout << "<PPS_NAMETAG_TABLE> tag at position " << hex << cpos << dec << endl;
+	  GetI8(i8);  // nb pos tag
+	  GetI8(i8);  // nb d'objets
+	  GetI8(i8);  // nb objets toplevel
+	  GetU8(ui8); // nb de nametag
+	  for(int kt=0; kt<ui8; kt++) {
+	    string tname;
+	    GetI8(i8);
+	    GetStr(tname);
+	    if (lev > 0)  
+	      cout << "<PPS_NAMETAG_ENTRY>  NameTag=" << tname 
+		   << " NameTagMark Position=" << hex << i8 << dec << endl; 
+	  }
+	  GetRawI8(i8);  // position debut NameTagTable
+	}
 	break;
 
       case PPS_EOF :
-	GetRawI8(i8);	
+	if (Version() < 3) GetRawI8(i8);	
 	cout << "<PPS_EOF> tag at position " << hex << cpos  
 	     << " TagPos=" << i8 << dec << endl;
@@ -890,5 +1132,5 @@
       else if (ppst3 == PPS_DATATYPE_UNSIGNED) dtype = "UNSIGNED x";
       int_4 dsize = ppst1;
-      int_4 dsizeskip = dsize;
+      int_8 dsizeskip = dsize;
       if (ppst30 == PPS_DATATYPE_COMPLEX) { 
 	dsize--;
@@ -911,5 +1153,5 @@
 	if (lev > 0)  cout << "<PPS_SIMPLE_ARRAY4> tag at position " << hex << cpos << dec 
 			   << " DataType=" << dtype << " NElts= " << i4 << endl;
-	s->seekg((int_8)dsizeskip*(int_8)i4, ios::cur);
+	s->seekg(dsizeskip*(int_8)i4, ios::cur);
 	break;
 
@@ -918,5 +1160,5 @@
 	if (lev > 0)  cout << "<PPS_SIMPLE_ARRAY8> tag at position " << hex << cpos << dec 
 			   << " DataType=" << dtype << " NElts= " << ui8 << endl;
-	s->seekg((int_8)dsizeskip*ui8, ios::cur);
+	s->seekg(dsizeskip*ui8, ios::cur);
 	break;
       }
@@ -930,4 +1172,9 @@
   return;
 }
+
+
+//-------------------------------------------------------------------------
+//-------------------  Classe PPFBinaryOutputStream -----------------------
+//-------------------------------------------------------------------------
 
 
@@ -988,4 +1235,5 @@
 // ---- GMT creation date of the file
   time_t tm = time(NULL);
+  creationdate = tm;
   char datestring[33];
   int l=strftime(datestring,32,"%d/%m/%Y %H:%M:%S GMT",gmtime(&tm));
@@ -998,13 +1246,14 @@
 PPFBinaryOutputStream::WriteNameTagTable()
 {  
-  if (tags.size() == 0) {
-    PutRawUByte(PPS_EOF);
-    PutRawI8(-1);
-  } 
-  else {
-    int_8 tagPos;
-    tagPos = s->tellp();
-    PutRawUByte(PPS_NAMETAG_TABLE);                       // This is a tag
-    PutU8((uint_8)tags.size());    // Number of tags
+  int_8 tagPos;
+  tagPos = s->tellp();
+  PutRawUByte(PPS_NAMETAG_TABLE);  //   NameTagTable tag
+  // Ecriture nb de PosTag et nb d'objets dans le flot
+  PutI8(_nbpostag);
+  PutI8(_nbobjs);
+  PutI8(_nbtlobjs);  
+  // Ecriture nb de tag et les tags
+  PutU8((uint_8)tags.size());    // Number of tags
+  if (tags.size() > 0) {
     for (map<string,int_8>::iterator i = tags.begin(); i != tags.end(); i++) {
       int_8 pos = (*i).second;
@@ -1012,8 +1261,8 @@
       PutStr((*i).first);
     }
-    PutRawUByte(PPS_EOF);
-    PutRawI8(tagPos);
-  }
-  
+  }
+  PutRawI8(tagPos);
+  PutRawUByte(PPS_EOF);
+  return;
 }
 
@@ -1049,4 +1298,5 @@
   PutRawByte(PPS_POSTAG_MARK);
   PutI8(tagpos);
+  _nbpostag++;  // Compteur de nombre de tags 
   return(tagpos);
 }
