Imported Upstream version 1.8.15
[platform/upstream/doxygen.git] / src / marshal.cpp
1 #include <qfile.h>
2 #include <assert.h>
3
4 #include "sortdict.h"
5 #include "marshal.h"
6 #include "entry.h"
7 #include "section.h"
8 #include "memberlist.h"
9 #include "definition.h"
10 #include "groupdef.h"
11 #include "example.h"
12 #include "arguments.h"
13 #include "doxygen.h"
14
15 #define HEADER ('D'<<24)+('O'<<16)+('X'<<8)+'!'
16
17 void marshalInt(StorageIntf *s,int v)
18 {
19   uchar b[4];
20   b[0]=((uint)v)>>24;
21   b[1]=(((uint)v)>>16)&0xff;
22   b[2]=(((uint)v)>>8)&0xff;
23   b[3]=v&0xff;
24   s->write((const char *)b,4);
25 }
26
27 void marshalUInt(StorageIntf *s,uint v)
28 {
29   uchar b[4];
30   b[0]=v>>24;
31   b[1]=(v>>16)&0xff;
32   b[2]=(v>>8)&0xff;
33   b[3]=v&0xff;
34   s->write((const char *)b,4);
35 }
36
37 void marshalUInt64(StorageIntf *s,uint64 v)
38 {
39   marshalUInt(s, uint(v>>32));
40   marshalUInt(s, uint(v&0xFFFFFFFF));
41 }
42
43 void marshalBool(StorageIntf *s,bool b)
44 {
45   char c = b;
46   s->write(&c,sizeof(char));
47 }
48
49 void marshalQCString(StorageIntf *s,const QCString &str)
50 {
51   uint l=str.length();
52   marshalUInt(s,l);
53   if (l>0) s->write(str.data(),l);
54 }
55
56 void marshalQGString(StorageIntf *s,const QGString &str)
57 {
58   uint l=str.length();
59   marshalUInt(s,l);
60   if (l>0) s->write(str.data(),l);
61 }
62
63 void marshalArgumentList(StorageIntf *s,ArgumentList *argList)
64 {
65   ArgumentList::marshal(s,argList);
66 }
67
68 void marshalArgumentLists(StorageIntf *s,QList<ArgumentList> *argLists)
69 {
70   if (argLists==0)
71   {
72     marshalUInt(s,NULL_LIST); // null pointer representation
73   }
74   else
75   {
76     marshalUInt(s,argLists->count());
77     QListIterator<ArgumentList> ali(*argLists);
78     ArgumentList *al;
79     for (ali.toFirst();(al=ali.current());++ali)
80     {
81       marshalArgumentList(s,al);
82     }
83   }
84 }
85
86 void marshalBaseInfoList(StorageIntf *s, QList<BaseInfo> *baseList)
87 {
88   if (baseList==0)
89   {
90     marshalUInt(s,NULL_LIST); // null pointer representation
91   }
92   else
93   {
94     marshalUInt(s,baseList->count());
95     QListIterator<BaseInfo> bli(*baseList);
96     BaseInfo *bi;
97     for (bli.toFirst();(bi=bli.current());++bli)
98     {
99       marshalQCString(s,bi->name);
100       marshalInt(s,(int)bi->prot);
101       marshalInt(s,(int)bi->virt);
102     }
103   }
104 }
105
106 void marshalGroupingList(StorageIntf *s, QList<Grouping> *groups)
107 {
108   if (groups==0)
109   {
110     marshalUInt(s,NULL_LIST); // null pointer representation
111   }
112   else
113   {
114     marshalUInt(s,groups->count());
115     QListIterator<Grouping> gli(*groups);
116     Grouping *g;
117     for (gli.toFirst();(g=gli.current());++gli)
118     {
119       marshalQCString(s,g->groupname);
120       marshalInt(s,(int)g->pri);
121     }
122   }
123 }
124
125 void marshalSectionInfoList(StorageIntf *s, QList<SectionInfo> *anchors)
126 {
127   if (anchors==0)
128   {
129     marshalUInt(s,NULL_LIST); // null pointer representation
130   }
131   else
132   {
133     marshalUInt(s,anchors->count());
134     QListIterator<SectionInfo> sli(*anchors);
135     SectionInfo *si;
136     for (sli.toFirst();(si=sli.current());++sli)
137     {
138       marshalQCString(s,si->label);
139       marshalQCString(s,si->title);
140       marshalQCString(s,si->ref);
141       marshalInt(s,(int)si->type);
142       marshalQCString(s,si->fileName);
143       marshalInt(s,si->lineNr);
144       marshalInt(s,si->level);
145     }
146     anchors->clear();
147   }
148 }
149
150 void marshalItemInfoList(StorageIntf *s, QList<ListItemInfo> *sli)
151 {
152   if (sli==0)
153   {
154     marshalUInt(s,NULL_LIST); // null pointer representation
155   }
156   else
157   {
158     marshalUInt(s,sli->count());
159     QListIterator<ListItemInfo> liii(*sli);
160     ListItemInfo *lii;
161     for (liii.toFirst();(lii=liii.current());++liii)
162     {
163       marshalQCString(s,lii->type);
164       marshalInt(s,lii->itemId);
165     }
166   }
167 }
168
169 void marshalObjPointer(StorageIntf *s,void *obj)
170 {
171   char *b = (char *)&obj;
172   s->write(b,sizeof(void *));
173 }
174
175 void marshalSectionDict(StorageIntf *s,SectionDict *sections)
176 {
177   if (sections==0)
178   {
179     marshalUInt(s,NULL_LIST); // null pointer representation
180   }
181   else
182   {
183     marshalUInt(s,sections->count());
184     SDict<SectionInfo>::IteratorDict sli(*sections);
185     SectionInfo *si;
186     for (sli.toFirst();(si=sli.current());++sli)
187     {
188       marshalQCString(s,sli.currentKey());
189       marshalObjPointer(s,si);
190     }
191   }
192 }
193
194 void marshalMemberSDict(StorageIntf *s,MemberSDict *memberSDict)
195 {
196   if (memberSDict==0)
197   {
198     marshalUInt(s,NULL_LIST); // null pointer representation
199   }
200   else
201   {
202     marshalUInt(s,memberSDict->count());
203     //printf("  marshalMemberSDict: items=%d\n",memberSDict->count());
204     SDict<MemberDef>::IteratorDict mdi(*memberSDict);
205     MemberDef *md;
206     int count=0;
207     for (mdi.toFirst();(md=mdi.current());++mdi)
208     {
209       //printf("  marshalMemberSDict: %d: key=%s value=%p\n",count,mdi.currentKey().data(),md);
210       marshalQCString(s,mdi.currentKey());
211       marshalObjPointer(s,md);
212       count++;
213     }
214     assert(count==memberSDict->count());
215   }
216 }
217
218 void marshalDocInfo(StorageIntf *s,DocInfo *docInfo)
219 {
220   if (docInfo==0)
221   {
222     marshalUInt(s,NULL_LIST); // null pointer representation
223   }
224   else
225   {
226     marshalUInt(s,1); 
227     marshalQCString(s,docInfo->doc);
228     marshalInt(s,docInfo->line);
229     marshalQCString(s,docInfo->file);
230   }
231 }
232
233 void marshalBriefInfo(StorageIntf *s,BriefInfo *briefInfo)
234 {
235   if (briefInfo==0)
236   {
237     marshalUInt(s,NULL_LIST); // null pointer representation
238   }
239   else
240   {
241     marshalUInt(s,1); 
242     marshalQCString(s,briefInfo->doc);
243     marshalQCString(s,briefInfo->tooltip);
244     marshalInt(s,briefInfo->line);
245     marshalQCString(s,briefInfo->file);
246   }
247 }
248
249 void marshalBodyInfo(StorageIntf *s,BodyInfo *bodyInfo)
250 {
251   if (bodyInfo==0)
252   {
253     marshalUInt(s,NULL_LIST); // null pointer representation
254   }
255   else
256   {
257     marshalUInt(s,1); 
258     marshalInt(s,bodyInfo->startLine);
259     marshalInt(s,bodyInfo->endLine);
260     marshalObjPointer(s,bodyInfo->fileDef);
261   }
262 }
263
264 void marshalGroupList(StorageIntf *s,GroupList *groupList)
265 {
266   if (groupList==0)
267   {
268     marshalUInt(s,NULL_LIST); // null pointer representation
269   }
270   else
271   {
272     marshalUInt(s,groupList->count());
273     QListIterator<GroupDef> gli(*groupList);
274     GroupDef *gd=0;
275     for (gli.toFirst();(gd=gli.current());++gli)
276     {
277       marshalObjPointer(s,gd);
278     }
279   }
280 }
281
282 void marshalMemberList(StorageIntf *s,MemberList *ml)
283 {
284   if (ml==0)
285   {
286     marshalUInt(s,NULL_LIST); // null pointer representation
287   }
288   else
289   {
290     marshalUInt(s,ml->count());
291     MemberListIterator mli(*ml);
292     MemberDef *md;
293     uint count=0;
294     for (mli.toFirst();(md=mli.current());++mli)
295     {
296       marshalObjPointer(s,md);
297       count++;
298     }
299     assert(count==ml->count());
300
301     ml->marshal(s);
302   }
303 }
304
305 void marshalExampleSDict(StorageIntf *s,ExampleSDict *ed)
306 {
307   if (ed==0)
308   {
309     marshalUInt(s,NULL_LIST); // null pointer representation
310   }
311   else
312   {
313     marshalUInt(s,ed->count());
314     //printf("  marshalMemberSDict: items=%d\n",memberSDict->count());
315     SDict<Example>::IteratorDict edi(*ed);
316     Example *e;
317     for (edi.toFirst();(e=edi.current());++edi)
318     {
319       //printf("  marshalMemberSDict: %d: key=%s value=%p\n",count,mdi.currentKey().data(),md);
320       marshalQCString(s,edi.currentKey());
321       marshalQCString(s,e->anchor);
322       marshalQCString(s,e->name);
323       marshalQCString(s,e->file);
324     }
325   }
326 }
327
328 void marshalMemberLists(StorageIntf *s,SDict<MemberList> *mls)
329 {
330   if (mls==0)
331   {
332     marshalUInt(s,NULL_LIST); // null pointer representation
333   }
334   else
335   {
336     marshalUInt(s,mls->count());
337     //printf("  marshalMemberSDict: items=%d\n",memberSDict->count());
338     SDict<MemberList>::IteratorDict mli(*mls);
339     MemberList *ml;
340     for (mli.toFirst();(ml=mli.current());++mli)
341     {
342       //printf("  marshalMemberSDict: %d: key=%s value=%p\n",count,mdi.currentKey().data(),md);
343       marshalQCString(s,mli.currentKey());
344       marshalObjPointer(s,ml); // assume we are not owner of the list
345     }
346   }
347 }
348
349 void marshalLocalToc(StorageIntf *s,const LocalToc &lt)
350 {
351   marshalInt(s,lt.mask());
352   marshalInt(s,lt.htmlLevel());
353   marshalInt(s,lt.latexLevel());
354   marshalInt(s,lt.xmlLevel());
355   marshalInt(s,lt.docbookLevel());
356 }
357
358 void marshalEntry(StorageIntf *s,Entry *e)
359 {
360   marshalUInt(s,HEADER);
361   marshalQCString(s,e->name);
362   marshalQCString(s,e->type);
363   marshalInt(s,e->section);
364   marshalInt(s,(int)e->protection);
365   marshalInt(s,(int)e->mtype);
366   marshalUInt64(s,e->spec);
367   marshalInt(s,e->initLines);
368   marshalBool(s,e->stat);
369   marshalLocalToc(s,e->localToc);
370   marshalBool(s,e->explicitExternal);
371   marshalBool(s,e->proto);
372   marshalBool(s,e->subGrouping);
373   marshalBool(s,e->callGraph);
374   marshalBool(s,e->callerGraph);
375   marshalBool(s,e->referencedByRelation);
376   marshalBool(s,e->referencesRelation);
377   marshalInt(s,(int)e->virt);
378   marshalQCString(s,e->args);
379   marshalQCString(s,e->bitfields);
380   marshalArgumentList(s,e->argList);
381   marshalArgumentLists(s,e->tArgLists);
382   marshalQGString(s,e->program);
383   marshalQGString(s,e->initializer);
384   marshalQCString(s,e->includeFile);
385   marshalQCString(s,e->includeName);
386   marshalQCString(s,e->doc);
387   marshalInt(s,e->docLine);
388   marshalQCString(s,e->docFile);
389   marshalQCString(s,e->brief);
390   marshalInt(s,e->briefLine);
391   marshalQCString(s,e->briefFile);
392   marshalQCString(s,e->inbodyDocs);
393   marshalInt(s,e->inbodyLine);
394   marshalQCString(s,e->inbodyFile);
395   marshalQCString(s,e->relates);
396   marshalInt(s,e->relatesType);
397   marshalQCString(s,e->read);
398   marshalQCString(s,e->write);
399   marshalQCString(s,e->inside);
400   marshalQCString(s,e->exception);
401   marshalArgumentList(s,e->typeConstr);
402   marshalInt(s,e->bodyLine);
403   marshalInt(s,e->endBodyLine);
404   marshalInt(s,e->mGrpId);
405   marshalBaseInfoList(s,e->extends);
406   marshalGroupingList(s,e->groups);
407   marshalSectionInfoList(s,e->anchors);
408   marshalQCString(s,e->fileName);
409   marshalInt(s,e->startLine);
410   marshalItemInfoList(s,e->sli);
411   marshalInt(s,(int)e->lang);
412   marshalBool(s,e->hidden);
413   marshalBool(s,e->artificial);
414   marshalInt(s,(int)e->groupDocType);
415   marshalQCString(s,e->id);
416   marshalQCString(s,e->metaData);
417 }
418
419 void marshalEntryTree(StorageIntf *s,Entry *e)
420 {
421   marshalEntry(s,e);
422   marshalUInt(s,e->children()->count());
423   QListIterator<Entry> eli(*e->children());
424   Entry *child;
425   for (eli.toFirst();(child=eli.current());++eli)
426   {
427     marshalEntryTree(s,child);
428   }
429 }
430
431 //------------------------------------------------------------------
432
433 int unmarshalInt(StorageIntf *s)
434 {
435   uchar b[4];
436   s->read((char *)b,4);
437   int result=(int)((((uint)b[0])<<24)+((uint)b[1]<<16)+((uint)b[2]<<8)+(uint)b[3]);
438   //printf("unmarshalInt: %x %x %x %x: %x offset=%llx\n",b[0],b[1],b[2],b[3],result,f.pos());
439   return result;
440 }
441
442 uint unmarshalUInt(StorageIntf *s)
443 {
444   uchar b[4];
445   s->read((char *)b,4);
446   uint result=(((uint)b[0])<<24)+((uint)b[1]<<16)+((uint)b[2]<<8)+(uint)b[3];
447   //printf("unmarshalUInt: %x %x %x %x: %x offset=%llx\n",b[0],b[1],b[2],b[3],result,f.pos());
448   return result;
449 }
450
451 uint64 unmarshalUInt64(StorageIntf *s)
452 {
453   uint64 result=uint64(unmarshalUInt(s))<<32;
454   result|=unmarshalUInt(s);
455   return result;
456 }
457
458 bool unmarshalBool(StorageIntf *s)
459 {
460   char result;
461   s->read(&result,sizeof(result));
462   //printf("unmarshalBool: %x offset=%llx\n",result,f.pos());
463   return result;
464 }
465
466 QCString unmarshalQCString(StorageIntf *s)
467 {
468   uint len = unmarshalUInt(s);
469   //printf("unmarshalQCString: len=%d offset=%llx\n",len,f.pos());
470   QCString result(len+1);
471   result.at(len)='\0';
472   if (len>0)
473   {
474     s->read(result.rawData(),len);
475   }
476   //printf("unmarshalQCString: result=%s\n",result.data());
477   return result;
478 }
479
480 QGString unmarshalQGString(StorageIntf *s)
481 {
482   uint len = unmarshalUInt(s);
483   //printf("unmarshalQCString: len=%d offset=%llx\n",len,f.pos());
484   QGString result(len+1);
485   result.at(len)='\0';
486   if (len>0)
487   {
488     s->read(result.data(),len);
489   }
490   //printf("unmarshalQCString: result=%s\n",result.data());
491   return result;
492 }
493
494 ArgumentList *unmarshalArgumentList(StorageIntf *s)
495 {
496   return ArgumentList::unmarshal(s);
497 }
498
499 QList<ArgumentList> *unmarshalArgumentLists(StorageIntf *s)
500 {
501   uint i;
502   uint count = unmarshalUInt(s);
503   if (count==NULL_LIST) return 0; // null list
504   QList<ArgumentList> *result = new QList<ArgumentList>;
505   result->setAutoDelete(TRUE);
506   assert(count<1000000);
507   //printf("unmarshalArgumentLists: %d\n",count);
508   for (i=0;i<count;i++)
509   {
510     result->append(unmarshalArgumentList(s));
511   }
512   return result;
513 }
514
515 QList<BaseInfo> *unmarshalBaseInfoList(StorageIntf *s)
516 {
517   uint i;
518   uint count = unmarshalUInt(s);
519   if (count==NULL_LIST) return 0; // null list
520   QList<BaseInfo> *result = new QList<BaseInfo>;
521   result->setAutoDelete(TRUE);
522   assert(count<1000000);
523   for (i=0;i<count;i++)
524   {
525     QCString name   = unmarshalQCString(s);
526     Protection prot = (Protection)unmarshalInt(s);
527     Specifier virt  = (Specifier)unmarshalInt(s);
528     result->append(new BaseInfo(name,prot,virt));
529   }
530   return result;
531 }
532
533 QList<Grouping> *unmarshalGroupingList(StorageIntf *s)
534 {
535   uint i;
536   uint count = unmarshalUInt(s);
537   if (count==NULL_LIST) return 0; // null list
538   QList<Grouping> *result = new QList<Grouping>;
539   result->setAutoDelete(TRUE);
540   assert(count<1000000);
541   for (i=0;i<count;i++)
542   {
543     QCString name = unmarshalQCString(s);
544     Grouping::GroupPri_t prio = (Grouping::GroupPri_t)unmarshalInt(s);
545     result->append(new Grouping(name,prio));
546   }
547   return result;
548 }
549
550 QList<SectionInfo> *unmarshalSectionInfoList(StorageIntf *s)
551 {
552   uint i;
553   uint count = unmarshalUInt(s);
554   if (count==NULL_LIST) return 0; // null list
555   QList<SectionInfo> *anchors = new QList<SectionInfo>;
556   assert(count<1000000);
557   for (i=0;i<count;i++)
558   {
559     QCString label = unmarshalQCString(s);
560     QCString title = unmarshalQCString(s);
561     QCString ref   = unmarshalQCString(s);
562     SectionInfo::SectionType type = (SectionInfo::SectionType)unmarshalInt(s);
563     QCString fileName = unmarshalQCString(s);
564     int lineNr = unmarshalInt(s);
565     int level = unmarshalInt(s);
566     SectionInfo *si = Doxygen::sectionDict->find(label);
567     if (si==0) // This should actually never be true since all anchors should be in sectionDict.
568                // Could still optimize the marshaling routine by only storing label.
569     {
570       SectionInfo *si = new SectionInfo(fileName,lineNr,label,title,type,level,ref);
571       anchors->append(si);
572       Doxygen::sectionDict->append(label,si); // this dict owns the anchor objects
573     }
574     else
575     {
576       anchors->append(si);
577     }
578   }
579   return anchors;
580 }
581
582 QList<ListItemInfo> *unmarshalItemInfoList(StorageIntf *s)
583 {
584   uint i;
585   uint count = unmarshalUInt(s);
586   if (count==NULL_LIST) return 0; // null list
587   QList<ListItemInfo> *result = new QList<ListItemInfo>;
588   result->setAutoDelete(TRUE);
589   assert(count<1000000);
590   for (i=0;i<count;i++)
591   { 
592     ListItemInfo *lii = new ListItemInfo;
593     lii->type   = unmarshalQCString(s);
594     lii->itemId = unmarshalInt(s);
595     result->append(lii);
596   }
597   return result;
598 }
599
600 void *unmarshalObjPointer(StorageIntf *s)
601 {
602   void *result;
603   s->read((char *)&result,sizeof(void*));
604   return result;
605 }
606
607 SectionDict *unmarshalSectionDict(StorageIntf *s)
608 {
609   uint i;
610   uint count = unmarshalUInt(s);
611   //printf("unmarshalSectionDict count=%d\n",count);
612   if (count==NULL_LIST) return 0; // null list
613   SectionDict *result = new SectionDict(17);
614   assert(count<1000000);
615   for (i=0;i<count;i++)
616   {
617     QCString key    = unmarshalQCString(s);
618     SectionInfo *si = (SectionInfo *)unmarshalObjPointer(s);
619     //printf("  unmarshalSectionDict i=%d key=%s si=%s\n",count,key.data(),si->label.data());
620     result->append(key,si);
621   }
622   return result;
623 }
624
625 MemberSDict *unmarshalMemberSDict(StorageIntf *s)
626 {
627   uint i;
628   uint count = unmarshalUInt(s);
629   //printf("--- unmarshalMemberSDict count=%d\n",count);
630   if (count==NULL_LIST) 
631   {
632     //printf("--- end unmarshalMemberSDict\n");
633     return 0; // null list
634   }
635   MemberSDict *result = new MemberSDict;
636   assert(count<1000000);
637   //printf("Reading %d key-value pairs\n",count);
638   for (i=0;i<count;i++)
639   {
640     //printf("  unmarshaling pair %d\n",i);
641     QCString key    = unmarshalQCString(s);
642     //printf("  unmarshaling key %s\n",key.data());
643     MemberDef *md = (MemberDef *)unmarshalObjPointer(s);
644     //printf("  unmarshalMemberSDict i=%d key=%s md=%p\n",i,key.data(),md);
645     result->append(key,md); 
646   }
647
648   //printf("--- end unmarshalMemberSDict\n");
649   return result;
650 }
651
652 DocInfo *unmarshalDocInfo(StorageIntf *s)
653 {
654   uint count = unmarshalUInt(s); 
655   if (count==NULL_LIST) return 0;
656   DocInfo *result = new DocInfo;
657   result->doc  = unmarshalQCString(s);
658   result->line = unmarshalInt(s);
659   result->file = unmarshalQCString(s);
660   return result;
661 }
662
663 BriefInfo *unmarshalBriefInfo(StorageIntf *s)
664 {
665   uint count = unmarshalUInt(s); 
666   if (count==NULL_LIST) return 0;
667   BriefInfo *result = new BriefInfo;
668   result->doc     = unmarshalQCString(s);
669   result->tooltip = unmarshalQCString(s);
670   result->line    = unmarshalInt(s);
671   result->file    = unmarshalQCString(s);
672   return result;
673 }
674
675 BodyInfo *unmarshalBodyInfo(StorageIntf *s)
676 {
677   uint count = unmarshalUInt(s); 
678   if (count==NULL_LIST) return 0;
679   BodyInfo *result = new BodyInfo;
680   result->startLine = unmarshalInt(s);
681   result->endLine   = unmarshalInt(s);
682   result->fileDef   = (FileDef*)unmarshalObjPointer(s);
683   return result;
684 }
685
686 GroupList *unmarshalGroupList(StorageIntf *s)
687 {
688   uint i;
689   uint count = unmarshalUInt(s);
690   if (count==NULL_LIST) return 0; // null list
691   assert(count<1000000);
692   GroupList *result = new GroupList;
693   for (i=0;i<count;i++)
694   {
695     GroupDef *gd = (GroupDef *)unmarshalObjPointer(s);
696     result->append(gd);
697   }
698   return result;
699 }
700
701 MemberList *unmarshalMemberList(StorageIntf *s)
702 {
703   uint i;
704   uint count = unmarshalUInt(s); 
705   if (count==NULL_LIST) return 0;
706   MemberList *result = new MemberList;
707   assert(count<1000000);
708   for (i=0;i<count;i++)
709   {
710     MemberDef *md = (MemberDef*)unmarshalObjPointer(s);
711     result->append(md);
712   }
713   result->unmarshal(s);
714   return result;
715 }
716
717 ExampleSDict *unmarshalExampleSDict(StorageIntf *s)
718 {
719   uint i;
720   uint count = unmarshalUInt(s); 
721   if (count==NULL_LIST) return 0;
722   ExampleSDict *result = new ExampleSDict;
723   assert(count<1000000);
724   for (i=0;i<count;i++)
725   {
726     QCString key = unmarshalQCString(s);
727     Example *e = new Example;
728     e->anchor = unmarshalQCString(s);
729     e->name   = unmarshalQCString(s);
730     e->file   = unmarshalQCString(s);
731     result->inSort(key,e);
732   }
733   return result;
734 }
735
736 SDict<MemberList> *unmarshalMemberLists(StorageIntf *s)
737 {
738   uint i;
739   uint count = unmarshalUInt(s); 
740   if (count==NULL_LIST) return 0;
741   SDict<MemberList> *result = new SDict<MemberList>(7);
742   assert(count<1000000);
743   for (i=0;i<count;i++)
744   {
745     QCString key = unmarshalQCString(s);
746     MemberList *ml = (MemberList *)unmarshalObjPointer(s);
747     result->append(key,ml);
748   }
749   return result;
750 }
751
752 LocalToc unmarshalLocalToc(StorageIntf *s)
753 {
754   LocalToc result;
755   int mask       = unmarshalInt(s);
756   int htmlLevel  = unmarshalInt(s);
757   int latexLevel = unmarshalInt(s);
758   int xmlLevel   = unmarshalInt(s);
759   int docbookLevel   = unmarshalInt(s);
760   if ((mask & (1<<LocalToc::Html))!=0)
761   {
762     result.enableHtml(htmlLevel);
763   }
764   if ((mask & (1<<LocalToc::Latex))!=0)
765   {
766     result.enableLatex(latexLevel);
767   }
768   if ((mask & (1<<LocalToc::Xml))!=0)
769   {
770     result.enableXml(xmlLevel);
771   }
772   if ((mask & (1<<LocalToc::Docbook))!=0)
773   {
774     result.enableDocbook(docbookLevel);
775   }
776   return result;
777 }
778
779 Entry * unmarshalEntry(StorageIntf *s)
780 {
781   Entry *e = new Entry;
782   uint header=unmarshalUInt(s);
783   ASSERT(header==HEADER);
784   e->name             = unmarshalQCString(s);
785   e->type             = unmarshalQCString(s);
786   e->section          = unmarshalInt(s);
787   e->protection       = (Protection)unmarshalInt(s);
788   e->mtype            = (MethodTypes)unmarshalInt(s);
789   e->spec             = unmarshalUInt64(s);
790   e->initLines        = unmarshalInt(s);
791   e->stat             = unmarshalBool(s);
792   e->localToc         = unmarshalLocalToc(s);
793   e->explicitExternal = unmarshalBool(s);
794   e->proto            = unmarshalBool(s);
795   e->subGrouping      = unmarshalBool(s);
796   e->callGraph        = unmarshalBool(s);
797   e->callerGraph      = unmarshalBool(s);
798   e->referencedByRelation = unmarshalBool(s);
799   e->referencesRelation   = unmarshalBool(s);
800   e->virt             = (Specifier)unmarshalInt(s);
801   e->args             = unmarshalQCString(s);
802   e->bitfields        = unmarshalQCString(s);
803   delete e->argList;
804   e->argList          = unmarshalArgumentList(s);
805   e->tArgLists        = unmarshalArgumentLists(s);
806   e->program          = unmarshalQGString(s);
807   e->initializer      = unmarshalQGString(s);
808   e->includeFile      = unmarshalQCString(s);
809   e->includeName      = unmarshalQCString(s);
810   e->doc              = unmarshalQCString(s);
811   e->docLine          = unmarshalInt(s);
812   e->docFile          = unmarshalQCString(s);
813   e->brief            = unmarshalQCString(s);
814   e->briefLine        = unmarshalInt(s);
815   e->briefFile        = unmarshalQCString(s);
816   e->inbodyDocs       = unmarshalQCString(s);
817   e->inbodyLine       = unmarshalInt(s);
818   e->inbodyFile       = unmarshalQCString(s);
819   e->relates          = unmarshalQCString(s);
820   e->relatesType      = (RelatesType)unmarshalInt(s);
821   e->read             = unmarshalQCString(s);
822   e->write            = unmarshalQCString(s);
823   e->inside           = unmarshalQCString(s);
824   e->exception        = unmarshalQCString(s);
825   e->typeConstr       = unmarshalArgumentList(s);
826   e->bodyLine         = unmarshalInt(s);
827   e->endBodyLine      = unmarshalInt(s);
828   e->mGrpId           = unmarshalInt(s);
829   delete e->extends;
830   e->extends          = unmarshalBaseInfoList(s);
831   delete e->groups;
832   e->groups           = unmarshalGroupingList(s);
833   delete e->anchors;
834   e->anchors          = unmarshalSectionInfoList(s);
835   e->fileName         = unmarshalQCString(s);
836   e->startLine        = unmarshalInt(s);
837   e->sli              = unmarshalItemInfoList(s);
838   e->lang             = (SrcLangExt)unmarshalInt(s);
839   e->hidden           = unmarshalBool(s);
840   e->artificial       = unmarshalBool(s);
841   e->groupDocType     = (Entry::GroupDocType)unmarshalInt(s);
842   e->id               = unmarshalQCString(s);
843   e->metaData         = unmarshalQCString(s);
844   return e;
845 }
846
847 Entry * unmarshalEntryTree(StorageIntf *s)
848 {
849   Entry *e = unmarshalEntry(s);
850   uint count = unmarshalUInt(s);
851   uint i;
852   for (i=0;i<count;i++)
853   {
854     e->addSubEntry(unmarshalEntryTree(s));
855   }
856   return e;
857 }