Bullet Collision Detection & Physics Library
bFile.cpp
Go to the documentation of this file.
1 /*
2 bParse
3 Copyright (c) 2006-2009 Charlie C & Erwin Coumans http://gamekit.googlecode.com
4 
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the use of this software.
7 Permission is granted to anyone to use this software for any purpose,
8 including commercial applications, and to alter it and redistribute it freely,
9 subject to the following restrictions:
10 
11 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
14 */
15 #include "bFile.h"
16 #include "bCommon.h"
17 #include "bChunk.h"
18 #include "bDNA.h"
19 #include <math.h>
20 #include <string.h>
21 #include <stdlib.h>
22 #include "bDefines.h"
25 #include "LinearMath/btMinMax.h"
26 
27 #define SIZEOFBLENDERHEADER 12
28 #define MAX_ARRAY_LENGTH 512
29 using namespace bParse;
30 #define MAX_STRLEN 1024
31 
32 const char* getCleanName(const char* memName, char* buffer)
33 {
34  int slen = strlen(memName);
35  assert(slen<MAX_STRLEN);
36  slen=btMin(slen,MAX_STRLEN);
37  for (int i=0;i<slen;i++)
38  {
39  if (memName[i]==']'||memName[i]=='[')
40  {
41  buffer[i] = 0;//'_';
42  } else
43  {
44  buffer[i] = memName[i];
45  }
46  }
47  buffer[slen]=0;
48  return buffer;
49 }
50 
51 
52 int numallocs = 0;
53 
54 // ----------------------------------------------------- //
55 bFile::bFile(const char *filename, const char headerString[7])
56  : mOwnsBuffer(true),
57  mFileBuffer(0),
58  mFileLen(0),
59  mVersion(0),
60  mDataStart(0),
61  mFileDNA(0),
62  mMemoryDNA(0),
63  mFlags(FD_INVALID)
64 {
65  for (int i=0;i<7;i++)
66  {
67  m_headerString[i] = headerString[i];
68  }
69 
70  FILE *fp = fopen(filename, "rb");
71  if (fp)
72  {
73  fseek(fp, 0L, SEEK_END);
74  mFileLen = ftell(fp);
75  fseek(fp, 0L, SEEK_SET);
76 
77  mFileBuffer = (char*)malloc(mFileLen+1);
78  fread(mFileBuffer, mFileLen, 1, fp);
79 
80  fclose(fp);
81 
82  //
83  parseHeader();
84 
85  }
86 }
87 
88 // ----------------------------------------------------- //
89 bFile::bFile( char *memoryBuffer, int len, const char headerString[7])
90 : mOwnsBuffer(false),
91  mFileBuffer(0),
92  mFileLen(0),
93  mVersion(0),
94  mDataStart(0),
95  mFileDNA(0),
96  mMemoryDNA(0),
98 {
99  for (int i=0;i<7;i++)
100  {
101  m_headerString[i] = headerString[i];
102  }
103  mFileBuffer = memoryBuffer;
104  mFileLen = len;
105 
106  parseHeader();
107 
108 }
109 
110 
111 // ----------------------------------------------------- //
113 {
114  if (mOwnsBuffer && mFileBuffer)
115  {
116  free(mFileBuffer);
117  mFileBuffer = 0;
118  }
119 
120 
121  delete mMemoryDNA;
122  delete mFileDNA;
123 }
124 
125 
126 
127 
128 
129 // ----------------------------------------------------- //
131 {
132  if (!mFileLen || !mFileBuffer)
133  return;
134 
135  char *blenderBuf = mFileBuffer;
136  char header[SIZEOFBLENDERHEADER+1] ;
137  memcpy(header, blenderBuf, SIZEOFBLENDERHEADER);
138  header[SIZEOFBLENDERHEADER]='\0';
139 
140  if (strncmp(header, m_headerString, 6)!=0)
141  {
142  memcpy(header, m_headerString, SIZEOFBLENDERHEADER);
143  return;
144  }
145 
146  if (header[6] == 'd')
147  {
149  }
150 
151  char *ver = header+9;
152  mVersion = atoi(ver);
153  if (mVersion <= 241)
154  {
155  //printf("Warning, %d not fully tested : <= 242\n", mVersion);
156  }
157 
158  int littleEndian= 1;
159  littleEndian= ((char*)&littleEndian)[0];
160 
161  // swap ptr sizes...
162  if (header[7]=='-')
163  {
164  mFlags |= FD_FILE_64;
165  if (!VOID_IS_8)
167  }
168  else if (VOID_IS_8) mFlags |= FD_BITS_VARIES;
169 
170  // swap endian...
171  if (header[8]=='V')
172  {
173  if (littleEndian ==1)
175  }
176  else
177  if (littleEndian==0)
179 
180 
181  mFlags |= FD_OK;
182 }
183 
184 // ----------------------------------------------------- //
185 bool bFile::ok()
186 {
187  return (mFlags &FD_OK)!=0;
188 }
189 
190 // ----------------------------------------------------- //
191 void bFile::parseInternal(int verboseMode, char* memDna,int memDnaLength)
192 {
193  if ( (mFlags &FD_OK) ==0)
194  return;
195 
196  char *blenderData = mFileBuffer;
197  bChunkInd dna;
198  dna.oldPtr = 0;
199 
200  char *tempBuffer = blenderData;
201  for (int i=0; i<mFileLen; i++)
202  {
203  // looking for the data's starting position
204  // and the start of SDNA decls
205 
206  if (!mDataStart && strncmp(tempBuffer, "REND", 4)==0)
207  mDataStart = i;
208 
209  if (strncmp(tempBuffer, "DNA1", 4)==0)
210  {
211  // read the DNA1 block and extract SDNA
212  if (getNextBlock(&dna, tempBuffer, mFlags) > 0)
213  {
214  if (strncmp((tempBuffer + ChunkUtils::getOffset(mFlags)), "SDNANAME", 8) ==0)
215  dna.oldPtr = (tempBuffer + ChunkUtils::getOffset(mFlags));
216  else dna.oldPtr = 0;
217  }
218  else dna.oldPtr = 0;
219  }
220  // Some Bullet files are missing the DNA1 block
221  // In Blender it's DNA1 + ChunkUtils::getOffset() + SDNA + NAME
222  // In Bullet tests its SDNA + NAME
223  else if (strncmp(tempBuffer, "SDNANAME", 8) ==0)
224  {
225  dna.oldPtr = blenderData + i;
226  dna.len = mFileLen-i;
227 
228  // Also no REND block, so exit now.
229  if (mVersion==276) break;
230  }
231 
232  if (mDataStart && dna.oldPtr) break;
233  tempBuffer++;
234  }
235  if (!dna.oldPtr || !dna.len)
236  {
237  //printf("Failed to find DNA1+SDNA pair\n");
238  mFlags &= ~FD_OK;
239  return;
240  }
241 
242 
243  mFileDNA = new bDNA();
244 
245 
247  mFileDNA->init((char*)dna.oldPtr, dna.len, (mFlags & FD_ENDIAN_SWAP)!=0);
248 
249 
250  if (mVersion==276)
251  {
252  int i;
253  for (i=0;i<mFileDNA->getNumNames();i++)
254  {
255  if (strcmp(mFileDNA->getName(i),"int")==0)
256  {
258  }
259  }
260  if ((mFlags&FD_BROKEN_DNA)!=0)
261  {
262  //printf("warning: fixing some broken DNA version\n");
263  }
264  }
265 
266 
267 
268  if (verboseMode & FD_VERBOSE_DUMP_DNA_TYPE_DEFINITIONS)
270 
271  mMemoryDNA = new bDNA();
272  int littleEndian= 1;
273  littleEndian= ((char*)&littleEndian)[0];
274 
275  mMemoryDNA->init(memDna,memDnaLength,littleEndian==0);
276 
277 
278 
279 
282  {
284  //printf ("Warning, file DNA is different than built in, performance is reduced. Best to re-export file with a matching version/platform");
285  }
286 
287  // as long as it kept up to date it will be ok!!
289  {
290  //printf ("Warning, file DNA is newer than built in.");
291  }
292 
293 
295 
296  parseData();
297 
298  resolvePointers(verboseMode);
299 
301 
302 
303 }
304 
305 
306 
307 // ----------------------------------------------------- //
308 void bFile::swap(char *head, bChunkInd& dataChunk, bool ignoreEndianFlag)
309 {
310  char *data = head;
311  short *strc = mFileDNA->getStruct(dataChunk.dna_nr);
312 
313 
314 
315  const char s[] = "SoftBodyMaterialData";
316  int szs = sizeof(s);
317  if (strncmp((char*)&dataChunk.code,"ARAY",4)==0)
318  {
319  short *oldStruct = mFileDNA->getStruct(dataChunk.dna_nr);
320  char *oldType = mFileDNA->getType(oldStruct[0]);
321  if (strncmp(oldType,s,szs)==0)
322  {
323  return;
324  }
325  }
326 
327 
328  int len = mFileDNA->getLength(strc[0]);
329 
330  for (int i=0; i<dataChunk.nr; i++)
331  {
332  swapStruct(dataChunk.dna_nr, data,ignoreEndianFlag);
333  data+=len;
334  }
335 }
336 
337 void bFile::swapLen(char *dataPtr)
338 {
339  const bool VOID_IS_8 = ((sizeof(void*)==8));
340  if (VOID_IS_8)
341  {
342  if (mFlags &FD_BITS_VARIES)
343  {
344  bChunkPtr4*c = (bChunkPtr4*) dataPtr;
345  if ((c->code & 0xFFFF)==0)
346  c->code >>=16;
347  SWITCH_INT(c->len);
348  SWITCH_INT(c->dna_nr);
349  SWITCH_INT(c->nr);
350  } else
351  {
352  bChunkPtr8* c = (bChunkPtr8*) dataPtr;
353  if ((c->code & 0xFFFF)==0)
354  c->code >>=16;
355  SWITCH_INT(c->len);
356  SWITCH_INT(c->dna_nr);
357  SWITCH_INT(c->nr);
358 
359  }
360  } else
361  {
362  if (mFlags &FD_BITS_VARIES)
363  {
364  bChunkPtr8*c = (bChunkPtr8*) dataPtr;
365  if ((c->code & 0xFFFF)==0)
366  c->code >>=16;
367  SWITCH_INT(c->len);
368  SWITCH_INT(c->dna_nr);
369  SWITCH_INT(c->nr);
370 
371  } else
372  {
373  bChunkPtr4* c = (bChunkPtr4*) dataPtr;
374  if ((c->code & 0xFFFF)==0)
375  c->code >>=16;
376  SWITCH_INT(c->len);
377 
378  SWITCH_INT(c->dna_nr);
379  SWITCH_INT(c->nr);
380 
381  }
382  }
383 
384 }
385 
386 
387 void bFile::swapDNA(char* ptr)
388 {
389  bool swap = ((mFlags & FD_ENDIAN_SWAP)!=0);
390 
391  int offset = (mFlags & FD_FILE_64)? 24 : 20;
392  char* data = &ptr[offset];
393 
394 // void bDNA::init(char *data, int len, bool swap)
395  int *intPtr=0;short *shtPtr=0;
396  char *cp = 0;int dataLen =0;long nr=0;
397  intPtr = (int*)data;
398 
399  /*
400  SDNA (4 bytes) (magic number)
401  NAME (4 bytes)
402  <nr> (4 bytes) amount of names (int)
403  <string>
404  <string>
405  */
406 
407  if (strncmp(data, "SDNA", 4)==0)
408  {
409  // skip ++ NAME
410  intPtr++;
411  intPtr++;
412  } else
413  {
414 
415  if (strncmp(data+4, "SDNA", 4)==0)
416  {
417  // skip ++ NAME
418  intPtr++;
419  intPtr++;
420  intPtr++;
421  }
422  }
423 
424 
425 
426 
427  // Parse names
428  if (swap)
429  dataLen = ChunkUtils::swapInt(*intPtr);
430  else
431  dataLen = *intPtr;
432 
433  *intPtr = ChunkUtils::swapInt(*intPtr);
434  intPtr++;
435 
436  cp = (char*)intPtr;
437  int i;
438  for ( i=0; i<dataLen; i++)
439  {
440  while (*cp)cp++;
441  cp++;
442  }
443 
444 
445  {
446  nr= (long)cp;
447  //long mask=3;
448  nr= ((nr+3)&~3)-nr;
449  while (nr--)
450  {
451  cp++;
452  }
453  }
454 
455 
456  /*
457  TYPE (4 bytes)
458  <nr> amount of types (int)
459  <string>
460  <string>
461  */
462 
463  intPtr = (int*)cp;
464  assert(strncmp(cp, "TYPE", 4)==0); intPtr++;
465 
466  if (swap)
467  dataLen = ChunkUtils::swapInt(*intPtr);
468  else
469  dataLen = *intPtr;
470 
471  *intPtr = ChunkUtils::swapInt(*intPtr);
472 
473  intPtr++;
474 
475  cp = (char*)intPtr;
476  for ( i=0; i<dataLen; i++)
477  {
478  while (*cp)cp++;
479  cp++;
480  }
481 
482 {
483  nr= (long)cp;
484  // long mask=3;
485  nr= ((nr+3)&~3)-nr;
486  while (nr--)
487  {
488  cp++;
489  }
490  }
491 
492 
493  /*
494  TLEN (4 bytes)
495  <len> (short) the lengths of types
496  <len>
497  */
498 
499  // Parse type lens
500  intPtr = (int*)cp;
501  assert(strncmp(cp, "TLEN", 4)==0); intPtr++;
502 
503 
504  shtPtr = (short*)intPtr;
505  for ( i=0; i<dataLen; i++, shtPtr++)
506  {
507  //??????if (swap)
508  shtPtr[0] = ChunkUtils::swapShort(shtPtr[0]);
509  }
510 
511  if (dataLen & 1)
512  shtPtr++;
513 
514  /*
515  STRC (4 bytes)
516  <nr> amount of structs (int)
517  <typenr>
518  <nr_of_elems>
519  <typenr>
520  <namenr>
521  <typenr>
522  <namenr>
523  */
524 
525  intPtr = (int*)shtPtr;
526  cp = (char*)intPtr;
527  assert(strncmp(cp, "STRC", 4)==0);
528  intPtr++;
529 
530  if (swap)
531  dataLen = ChunkUtils::swapInt(*intPtr);
532  else
533  dataLen = *intPtr;
534 
535  *intPtr = ChunkUtils::swapInt(*intPtr);
536 
537  intPtr++;
538 
539 
540  shtPtr = (short*)intPtr;
541  for ( i=0; i<dataLen; i++)
542  {
543 
544  //if (swap)
545  {
546  int len = shtPtr[1];
547 
548  shtPtr[0]= ChunkUtils::swapShort(shtPtr[0]);
549  shtPtr[1]= ChunkUtils::swapShort(shtPtr[1]);
550 
551  shtPtr+= 2;
552 
553  for (int a=0; a<len; a++, shtPtr+=2)
554  {
555  shtPtr[0]= ChunkUtils::swapShort(shtPtr[0]);
556  shtPtr[1]= ChunkUtils::swapShort(shtPtr[1]);
557  }
558  }
559 // else
560 // shtPtr+= (2*shtPtr[1])+2;
561  }
562 
563 }
564 
565 void bFile::writeFile(const char* fileName)
566 {
567  FILE* f = fopen(fileName,"wb");
568  fwrite(mFileBuffer,1,mFileLen,f);
569  fclose(f);
570 }
571 
573 {
574 
575  const bool brokenDNA = (mFlags&FD_BROKEN_DNA)!=0;
576  //FD_ENDIAN_SWAP
577  //byte 8 determines the endianness of the file, little (v) versus big (V)
578  int littleEndian= 1;
579  littleEndian= ((char*)&littleEndian)[0];
580 
581 
582  if (mFileBuffer[8]=='V')
583  {
584  mFileBuffer[8]='v';
585  }
586  else
587  {
588  mFileBuffer[8]='V';
589  }
590 
591 
592 
593 
594 
595 
596  mDataStart = 12;
597 
598  char *dataPtr = mFileBuffer+mDataStart;
599 
600  bChunkInd dataChunk;
601  dataChunk.code = 0;
602  bool ignoreEndianFlag = true;
603 
604  //we always want to swap here
605 
606  int seek = getNextBlock(&dataChunk, dataPtr, mFlags);
607  //dataPtr += ChunkUtils::getOffset(mFlags);
608  char *dataPtrHead = 0;
609 
610  while (1)
611  {
612  // one behind
613  if (dataChunk.code == SDNA || dataChunk.code==DNA1 || dataChunk.code == TYPE || dataChunk.code == TLEN || dataChunk.code==STRC)
614  {
615 
616  swapDNA(dataPtr);
617  break;
618  } else
619  {
620  //if (dataChunk.code == DNA1) break;
621  dataPtrHead = dataPtr+ChunkUtils::getOffset(mFlags);
622 
623  swapLen(dataPtr);
624  if (dataChunk.dna_nr>=0)
625  {
626  swap(dataPtrHead, dataChunk,ignoreEndianFlag);
627  } else
628  {
629  printf("unknown chunk\n");
630  }
631  }
632 
633  // next please!
634  dataPtr += seek;
635 
636  seek = getNextBlock(&dataChunk, dataPtr, mFlags);
637  if (seek < 0)
638  break;
639  }
640 
641  if (mFlags & FD_ENDIAN_SWAP)
642  {
643  mFlags &= ~FD_ENDIAN_SWAP;
644  } else
645  {
647  }
648 
649 
650 
651 }
652 
653 
654 // ----------------------------------------------------- //
655 char* bFile::readStruct(char *head, bChunkInd& dataChunk)
656 {
657  bool ignoreEndianFlag = false;
658 
659  if (mFlags & FD_ENDIAN_SWAP)
660  swap(head, dataChunk, ignoreEndianFlag);
661 
662 
663 
664  if (!mFileDNA->flagEqual(dataChunk.dna_nr))
665  {
666  // Ouch! need to rebuild the struct
667  short *oldStruct,*curStruct;
668  char *oldType, *newType;
669  int oldLen, curLen, reverseOld;
670 
671 
672  oldStruct = mFileDNA->getStruct(dataChunk.dna_nr);
673  oldType = mFileDNA->getType(oldStruct[0]);
674 
675  oldLen = mFileDNA->getLength(oldStruct[0]);
676 
677  if ((mFlags&FD_BROKEN_DNA)!=0)
678  {
679  if ((strcmp(oldType,"btQuantizedBvhNodeData")==0)&&oldLen==20)
680  {
681  return 0;
682  }
683  if ((strcmp(oldType,"btShortIntIndexData")==0))
684  {
685  int allocLen = 2;
686  char *dataAlloc = new char[(dataChunk.nr*allocLen)+1];
687  memset(dataAlloc, 0, (dataChunk.nr*allocLen)+1);
688  short* dest = (short*) dataAlloc;
689  const short* src = (short*) head;
690  for (int i=0;i<dataChunk.nr;i++)
691  {
692  dest[i] = src[i];
693  if (mFlags &FD_ENDIAN_SWAP)
694  {
695  SWITCH_SHORT(dest[i]);
696  }
697  }
698  addDataBlock(dataAlloc);
699  return dataAlloc;
700  }
701  }
702 
703 
704 
706  if (strcmp("Link",oldType)!=0)
707  {
708  reverseOld = mMemoryDNA->getReverseType(oldType);
709 
710  if ((reverseOld!=-1))
711  {
712  // make sure it's here
713  //assert(reverseOld!= -1 && "getReverseType() returned -1, struct required!");
714 
715  //
716  curStruct = mMemoryDNA->getStruct(reverseOld);
717  newType = mMemoryDNA->getType(curStruct[0]);
718  curLen = mMemoryDNA->getLength(curStruct[0]);
719 
720 
721 
722  // make sure it's the same
723  assert((strcmp(oldType, newType)==0) && "internal error, struct mismatch!");
724 
725 
726  numallocs++;
727  // numBlocks * length
728 
729  int allocLen = (curLen);
730  char *dataAlloc = new char[(dataChunk.nr*allocLen)+1];
731  memset(dataAlloc, 0, (dataChunk.nr*allocLen));
732 
733  // track allocated
734  addDataBlock(dataAlloc);
735 
736  char *cur = dataAlloc;
737  char *old = head;
738  for (int block=0; block<dataChunk.nr; block++)
739  {
740  bool fixupPointers = true;
741  parseStruct(cur, old, dataChunk.dna_nr, reverseOld, fixupPointers);
742  mLibPointers.insert(old,(bStructHandle*)cur);
743 
744  cur += curLen;
745  old += oldLen;
746  }
747  return dataAlloc;
748  }
749  } else
750  {
751  //printf("Link found\n");
752  }
753  } else
754  {
755 //#define DEBUG_EQUAL_STRUCTS
756 #ifdef DEBUG_EQUAL_STRUCTS
757  short *oldStruct;
758  char *oldType;
759  oldStruct = mFileDNA->getStruct(dataChunk.dna_nr);
760  oldType = mFileDNA->getType(oldStruct[0]);
761  printf("%s equal structure, just memcpy\n",oldType);
762 #endif //
763  }
764 
765 
766  char *dataAlloc = new char[(dataChunk.len)+1];
767  memset(dataAlloc, 0, dataChunk.len+1);
768 
769 
770  // track allocated
771  addDataBlock(dataAlloc);
772 
773  memcpy(dataAlloc, head, dataChunk.len);
774  return dataAlloc;
775 
776 }
777 
778 
779 // ----------------------------------------------------- //
780 void bFile::parseStruct(char *strcPtr, char *dtPtr, int old_dna, int new_dna, bool fixupPointers)
781 {
782  if (old_dna == -1) return;
783  if (new_dna == -1) return;
784 
785  //disable this, because we need to fixup pointers/ListBase
786  if (0)//mFileDNA->flagEqual(old_dna))
787  {
788  short *strc = mFileDNA->getStruct(old_dna);
789  int len = mFileDNA->getLength(strc[0]);
790 
791  memcpy(strcPtr, dtPtr, len);
792  return;
793  }
794 
795  // Ok, now build the struct
796  char *memType, *memName, *cpc, *cpo;
797  short *fileStruct, *filePtrOld, *memoryStruct, *firstStruct;
798  int elementLength, size, revType, old_nr, new_nr, fpLen;
799  short firstStructType;
800 
801 
802  // File to memory lookup
803  memoryStruct = mMemoryDNA->getStruct(new_dna);
804  fileStruct = mFileDNA->getStruct(old_dna);
805  firstStruct = fileStruct;
806 
807 
808  filePtrOld = fileStruct;
809  firstStructType = mMemoryDNA->getStruct(0)[0];
810 
811  // Get number of elements
812  elementLength = memoryStruct[1];
813  memoryStruct+=2;
814 
815  cpc = strcPtr; cpo = 0;
816  for (int ele=0; ele<elementLength; ele++, memoryStruct+=2)
817  {
818  memType = mMemoryDNA->getType(memoryStruct[0]);
819  memName = mMemoryDNA->getName(memoryStruct[1]);
820 
821 
822  size = mMemoryDNA->getElementSize(memoryStruct[0], memoryStruct[1]);
823  revType = mMemoryDNA->getReverseType(memoryStruct[0]);
824 
825  if (revType != -1 && memoryStruct[0]>=firstStructType && memName[0] != '*')
826  {
827  cpo = getFileElement(firstStruct, memName, memType, dtPtr, &filePtrOld);
828  if (cpo)
829  {
830  int arrayLen = mFileDNA->getArraySizeNew(filePtrOld[1]);
831  old_nr = mFileDNA->getReverseType(memType);
832  new_nr = revType;
833  fpLen = mFileDNA->getElementSize(filePtrOld[0], filePtrOld[1]);
834  if (arrayLen==1)
835  {
836  parseStruct(cpc, cpo, old_nr, new_nr,fixupPointers);
837  } else
838  {
839  char* tmpCpc = cpc;
840  char* tmpCpo = cpo;
841 
842  for (int i=0;i<arrayLen;i++)
843  {
844  parseStruct(tmpCpc, tmpCpo, old_nr, new_nr,fixupPointers);
845  tmpCpc += size/arrayLen;
846  tmpCpo += fpLen/arrayLen;
847  }
848  }
849  cpc+=size;
850  cpo+=fpLen;
851  }
852  else
853  cpc+=size;
854  }
855  else
856  {
857  getMatchingFileDNA(fileStruct, memName, memType, cpc, dtPtr,fixupPointers);
858  cpc+=size;
859  }
860 
861  }
862 }
863 
864 
865 // ----------------------------------------------------- //
866 static void getElement(int arrayLen, const char *cur, const char *old, char *oldPtr, char *curData)
867 {
868 #define getEle(value, current, type, cast, size, ptr)\
869  if (strcmp(current, type)==0)\
870  {\
871  value = (*(cast*)ptr);\
872  ptr += size;\
873  }
874 
875 #define setEle(value, current, type, cast, size, ptr)\
876  if (strcmp(current, type)==0)\
877  {\
878  (*(cast*)ptr) = (cast)value;\
879  ptr += size;\
880  }
881  double value = 0.0;
882 
883  for (int i=0; i<arrayLen; i++)
884  {
885  getEle(value, old, "char", char, sizeof(char), oldPtr);
886  setEle(value, cur, "char", char, sizeof(char), curData);
887  getEle(value, old, "short", short, sizeof(short), oldPtr);
888  setEle(value, cur, "short", short, sizeof(short), curData);
889  getEle(value, old, "ushort", unsigned short, sizeof(unsigned short), oldPtr);
890  setEle(value, cur, "ushort", unsigned short, sizeof(unsigned short), curData);
891  getEle(value, old, "int", int, sizeof(int), oldPtr);
892  setEle(value, cur, "int", int, sizeof(int), curData);
893  getEle(value, old, "long", int, sizeof(int), oldPtr);
894  setEle(value, cur, "long", int, sizeof(int), curData);
895  getEle(value, old, "float", float, sizeof(float), oldPtr);
896  setEle(value, cur, "float", float, sizeof(float), curData);
897  getEle(value, old, "double", double, sizeof(double), oldPtr);
898  setEle(value, cur, "double", double, sizeof(double), curData);
899  }
900 }
901 
902 
903 // ----------------------------------------------------- //
904 void bFile::swapData(char *data, short type, int arraySize,bool ignoreEndianFlag)
905 {
906  if (ignoreEndianFlag || (mFlags &FD_ENDIAN_SWAP))
907  {
908  if (type == 2 || type == 3)
909  {
910  short *sp = (short*)data;
911  for (int i=0; i<arraySize; i++)
912  {
913  sp[0] = ChunkUtils::swapShort(sp[0]);
914  sp++;
915  }
916  }
917  if (type>3 && type <8)
918  {
919  char c;
920  char *cp = data;
921  for (int i=0; i<arraySize; i++)
922  {
923  c = cp[0];
924  cp[0] = cp[3];
925  cp[3] = c;
926  c = cp[1];
927  cp[1] = cp[2];
928  cp[2] = c;
929  cp+=4;
930  }
931  }
932  }
933 }
934 
935 
936 
937 void bFile::safeSwapPtr(char *dst, const char *src)
938 {
939  int ptrFile = mFileDNA->getPointerSize();
940  int ptrMem = mMemoryDNA->getPointerSize();
941 
942  if (!src && !dst)
943  return;
944 
945 
946  if (ptrFile == ptrMem)
947  {
948  memcpy(dst, src, ptrMem);
949  }
950  else if (ptrMem==4 && ptrFile==8)
951  {
952  btPointerUid* oldPtr = (btPointerUid*)src;
953  btPointerUid* newPtr = (btPointerUid*)dst;
954 
955  if (oldPtr->m_uniqueIds[0] == oldPtr->m_uniqueIds[1])
956  {
957  //Bullet stores the 32bit unique ID in both upper and lower part of 64bit pointers
958  //so it can be used to distinguish between .blend and .bullet
959  newPtr->m_uniqueIds[0] = oldPtr->m_uniqueIds[0];
960  } else
961  {
962  //deal with pointers the Blender .blend style way, see
963  //readfile.c in the Blender source tree
964  long64 longValue = *((long64*)src);
965  //endian swap for 64bit pointer otherwise truncation will fail due to trailing zeros
966  if (mFlags & FD_ENDIAN_SWAP)
967  SWITCH_LONGINT(longValue);
968  *((int*)dst) = (int)(longValue>>3);
969  }
970 
971  }
972  else if (ptrMem==8 && ptrFile==4)
973  {
974  btPointerUid* oldPtr = (btPointerUid*)src;
975  btPointerUid* newPtr = (btPointerUid*)dst;
976  if (oldPtr->m_uniqueIds[0] == oldPtr->m_uniqueIds[1])
977  {
978  newPtr->m_uniqueIds[0] = oldPtr->m_uniqueIds[0];
979  newPtr->m_uniqueIds[1] = 0;
980  } else
981  {
982  *((long64*)dst)= *((int*)src);
983  }
984  }
985  else
986  {
987  printf ("%d %d\n", ptrFile,ptrMem);
988  assert(0 && "Invalid pointer len");
989  }
990 
991 
992 }
993 
994 
995 // ----------------------------------------------------- //
996 void bFile::getMatchingFileDNA(short* dna_addr, const char* lookupName, const char* lookupType, char *strcData, char *data, bool fixupPointers)
997 {
998  // find the matching memory dna data
999  // to the file being loaded. Fill the
1000  // memory with the file data...
1001 
1002  int len = dna_addr[1];
1003  dna_addr+=2;
1004 
1005  for (int i=0; i<len; i++, dna_addr+=2)
1006  {
1007  const char* type = mFileDNA->getType(dna_addr[0]);
1008  const char* name = mFileDNA->getName(dna_addr[1]);
1009 
1010 
1011 
1012  int eleLen = mFileDNA->getElementSize(dna_addr[0], dna_addr[1]);
1013 
1014  if ((mFlags&FD_BROKEN_DNA)!=0)
1015  {
1016  if ((strcmp(type,"short")==0)&&(strcmp(name,"int")==0))
1017  {
1018  eleLen = 0;
1019  }
1020  }
1021 
1022  if (strcmp(lookupName, name)==0)
1023  {
1024  //int arrayLenold = mFileDNA->getArraySize((char*)name.c_str());
1025  int arrayLen = mFileDNA->getArraySizeNew(dna_addr[1]);
1026  //assert(arrayLenold == arrayLen);
1027 
1028  if (name[0] == '*')
1029  {
1030  // cast pointers
1031  int ptrFile = mFileDNA->getPointerSize();
1032  int ptrMem = mMemoryDNA->getPointerSize();
1033  safeSwapPtr(strcData,data);
1034 
1035  if (fixupPointers)
1036  {
1037  if (arrayLen > 1)
1038  {
1039  //void **sarray = (void**)strcData;
1040  //void **darray = (void**)data;
1041 
1042  char *cpc, *cpo;
1043  cpc = (char*)strcData;
1044  cpo = (char*)data;
1045 
1046  for (int a=0; a<arrayLen; a++)
1047  {
1048  safeSwapPtr(cpc, cpo);
1050  cpc += ptrMem;
1051  cpo += ptrFile;
1052  }
1053  }
1054  else
1055  {
1056  if (name[1] == '*')
1058  else
1059  m_pointerFixupArray.push_back(strcData);
1060  }
1061  }
1062  else
1063  {
1064 // printf("skipped %s %s : %x\n",type.c_str(),name.c_str(),strcData);
1065  }
1066 
1067  }
1068 
1069  else if (strcmp(type, lookupType)==0)
1070  memcpy(strcData, data, eleLen);
1071  else
1072  getElement(arrayLen, lookupType, type, data, strcData);
1073 
1074  // --
1075  return;
1076  }
1077  data+=eleLen;
1078  }
1079 }
1080 
1081 
1082 // ----------------------------------------------------- //
1083 char* bFile::getFileElement(short *firstStruct, char *lookupName, char *lookupType, char *data, short **foundPos)
1084 {
1085  short *old = firstStruct;//mFileDNA->getStruct(old_nr);
1086  int elementLength = old[1];
1087  old+=2;
1088 
1089  for (int i=0; i<elementLength; i++, old+=2)
1090  {
1091  char* type = mFileDNA->getType(old[0]);
1092  char* name = mFileDNA->getName(old[1]);
1093  int len = mFileDNA->getElementSize(old[0], old[1]);
1094 
1095  if (strcmp(lookupName, name)==0)
1096  {
1097  if (strcmp(type, lookupType)==0)
1098  {
1099  if (foundPos)
1100  *foundPos = old;
1101  return data;
1102  }
1103  return 0;
1104  }
1105  data+=len;
1106  }
1107  return 0;
1108 }
1109 
1110 
1111 // ----------------------------------------------------- //
1112 void bFile::swapStruct(int dna_nr, char *data,bool ignoreEndianFlag)
1113 {
1114  if (dna_nr == -1) return;
1115 
1116  short *strc = mFileDNA->getStruct(dna_nr);
1117  //short *firstStrc = strc;
1118 
1119  int elementLen= strc[1];
1120  strc+=2;
1121 
1122  short first = mFileDNA->getStruct(0)[0];
1123 
1124  char *buf = data;
1125  for (int i=0; i<elementLen; i++, strc+=2)
1126  {
1127  char *type = mFileDNA->getType(strc[0]);
1128  char *name = mFileDNA->getName(strc[1]);
1129 
1130  int size = mFileDNA->getElementSize(strc[0], strc[1]);
1131  if (strc[0] >= first && name[0]!='*')
1132  {
1133  int old_nr = mFileDNA->getReverseType(type);
1134  int arrayLen = mFileDNA->getArraySizeNew(strc[1]);
1135  if (arrayLen==1)
1136  {
1137  swapStruct(old_nr,buf,ignoreEndianFlag);
1138  } else
1139  {
1140  char* tmpBuf = buf;
1141  for (int i=0;i<arrayLen;i++)
1142  {
1143  swapStruct(old_nr,tmpBuf,ignoreEndianFlag);
1144  tmpBuf+=size/arrayLen;
1145  }
1146  }
1147  }
1148  else
1149  {
1150  //int arrayLenOld = mFileDNA->getArraySize(name);
1151  int arrayLen = mFileDNA->getArraySizeNew(strc[1]);
1152  //assert(arrayLenOld == arrayLen);
1153  swapData(buf, strc[0], arrayLen,ignoreEndianFlag);
1154  }
1155  buf+=size;
1156  }
1157 }
1158 
1160 {
1161 // printf("resolvePointersStructMismatch\n");
1162 
1163  int i;
1164 
1165  for (i=0;i< m_pointerFixupArray.size();i++)
1166  {
1167  char* cur = m_pointerFixupArray.at(i);
1168  void** ptrptr = (void**) cur;
1169  void* ptr = *ptrptr;
1170  ptr = findLibPointer(ptr);
1171  if (ptr)
1172  {
1173  //printf("Fixup pointer!\n");
1174  *(ptrptr) = ptr;
1175  } else
1176  {
1177 // printf("pointer not found: %x\n",cur);
1178  }
1179  }
1180 
1181 
1182  for (i=0; i<m_pointerPtrFixupArray.size(); i++)
1183  {
1184  char* cur= m_pointerPtrFixupArray.at(i);
1185  void** ptrptr = (void**)cur;
1186 
1187  bChunkInd *block = m_chunkPtrPtrMap.find(*ptrptr);
1188  if (block)
1189  {
1190  int ptrMem = mMemoryDNA->getPointerSize();
1191  int ptrFile = mFileDNA->getPointerSize();
1192 
1193 
1194  int blockLen = block->len / ptrFile;
1195 
1196  void *onptr = findLibPointer(*ptrptr);
1197  if (onptr)
1198  {
1199  char *newPtr = new char[blockLen * ptrMem];
1200  addDataBlock(newPtr);
1201  memset(newPtr, 0, blockLen * ptrMem);
1202 
1203  void **onarray = (void**)onptr;
1204  char *oldPtr = (char*)onarray;
1205 
1206  int p = 0;
1207  while (blockLen-- > 0)
1208  {
1209  btPointerUid dp = {0};
1210  safeSwapPtr((char*)dp.m_uniqueIds, oldPtr);
1211 
1212  void **tptr = (void**)(newPtr + p * ptrMem);
1213  *tptr = findLibPointer(dp.m_ptr);
1214 
1215  oldPtr += ptrFile;
1216  ++p;
1217  }
1218 
1219  *ptrptr = newPtr;
1220  }
1221  }
1222  }
1223 }
1224 
1225 
1227 void bFile::resolvePointersChunk(const bChunkInd& dataChunk, int verboseMode)
1228 {
1229  bParse::bDNA* fileDna = mFileDNA ? mFileDNA : mMemoryDNA;
1230 
1231  short int* oldStruct = fileDna->getStruct(dataChunk.dna_nr);
1232  short oldLen = fileDna->getLength(oldStruct[0]);
1233  //char* structType = fileDna->getType(oldStruct[0]);
1234 
1235  char* cur = (char*)findLibPointer(dataChunk.oldPtr);
1236  for (int block=0; block<dataChunk.nr; block++)
1237  {
1238  resolvePointersStructRecursive(cur,dataChunk.dna_nr, verboseMode,1);
1239  cur += oldLen;
1240  }
1241 }
1242 
1243 
1244 int bFile::resolvePointersStructRecursive(char *strcPtr, int dna_nr, int verboseMode,int recursion)
1245 {
1246 
1247  bParse::bDNA* fileDna = mFileDNA ? mFileDNA : mMemoryDNA;
1248 
1249  char* memType;
1250  char* memName;
1251  short firstStructType = fileDna->getStruct(0)[0];
1252 
1253 
1254  char* elemPtr= strcPtr;
1255 
1256  short int* oldStruct = fileDna->getStruct(dna_nr);
1257 
1258  int elementLength = oldStruct[1];
1259  oldStruct+=2;
1260 
1261  int totalSize = 0;
1262 
1263  for (int ele=0; ele<elementLength; ele++, oldStruct+=2)
1264  {
1265 
1266  memType = fileDna->getType(oldStruct[0]);
1267  memName = fileDna->getName(oldStruct[1]);
1268 
1269 
1270 
1271  int arrayLen = fileDna->getArraySizeNew(oldStruct[1]);
1272  if (memName[0] == '*')
1273  {
1274  if (arrayLen > 1)
1275  {
1276  void **array= (void**)elemPtr;
1277  for (int a=0; a<arrayLen; a++)
1278  {
1279  if (verboseMode & FD_VERBOSE_EXPORT_XML)
1280  {
1281  for (int i=0;i<recursion;i++)
1282  {
1283  printf(" ");
1284  }
1285  //skip the *
1286  printf("<%s type=\"pointer\"> ",&memName[1]);
1287  printf("%d ", array[a]);
1288  printf("</%s>\n",&memName[1]);
1289  }
1290 
1291  array[a] = findLibPointer(array[a]);
1292  }
1293  }
1294  else
1295  {
1296  void** ptrptr = (void**) elemPtr;
1297  void* ptr = *ptrptr;
1298  if (verboseMode & FD_VERBOSE_EXPORT_XML)
1299  {
1300  for (int i=0;i<recursion;i++)
1301  {
1302  printf(" ");
1303  }
1304  printf("<%s type=\"pointer\"> ",&memName[1]);
1305  printf("%d ", ptr);
1306  printf("</%s>\n",&memName[1]);
1307  }
1308  ptr = findLibPointer(ptr);
1309 
1310  if (ptr)
1311  {
1312  // printf("Fixup pointer at 0x%x from 0x%x to 0x%x!\n",ptrptr,*ptrptr,ptr);
1313  *(ptrptr) = ptr;
1314  if (memName[1] == '*' && ptrptr && *ptrptr)
1315  {
1316  // This will only work if the given **array is continuous
1317  void **array= (void**)*(ptrptr);
1318  void *np= array[0];
1319  int n=0;
1320  while (np)
1321  {
1322  np= findLibPointer(array[n]);
1323  if (np) array[n]= np;
1324  n++;
1325  }
1326  }
1327  } else
1328  {
1329  // printf("Cannot fixup pointer at 0x%x from 0x%x to 0x%x!\n",ptrptr,*ptrptr,ptr);
1330  }
1331  }
1332  } else
1333  {
1334  int revType = fileDna->getReverseType(oldStruct[0]);
1335  if (oldStruct[0]>=firstStructType) //revType != -1 &&
1336  {
1337  char cleanName[MAX_STRLEN];
1338  getCleanName(memName,cleanName);
1339 
1340  int arrayLen = fileDna->getArraySizeNew(oldStruct[1]);
1341  int byteOffset = 0;
1342 
1343  if (verboseMode & FD_VERBOSE_EXPORT_XML)
1344  {
1345  for (int i=0;i<recursion;i++)
1346  {
1347  printf(" ");
1348  }
1349 
1350  if (arrayLen>1)
1351  {
1352  printf("<%s type=\"%s\" count=%d>\n",cleanName,memType, arrayLen);
1353  } else
1354  {
1355  printf("<%s type=\"%s\">\n",cleanName,memType);
1356  }
1357  }
1358 
1359  for (int i=0;i<arrayLen;i++)
1360  {
1361  byteOffset += resolvePointersStructRecursive(elemPtr+byteOffset,revType, verboseMode,recursion+1);
1362  }
1363  if (verboseMode & FD_VERBOSE_EXPORT_XML)
1364  {
1365  for (int i=0;i<recursion;i++)
1366  {
1367  printf(" ");
1368  }
1369  printf("</%s>\n",cleanName);
1370  }
1371  } else
1372  {
1373  //export a simple type
1374  if (verboseMode & FD_VERBOSE_EXPORT_XML)
1375  {
1376 
1377  if (arrayLen>MAX_ARRAY_LENGTH)
1378  {
1379  printf("too long\n");
1380  } else
1381  {
1382  //printf("%s %s\n",memType,memName);
1383 
1384  bool isIntegerType = (strcmp(memType,"char")==0) || (strcmp(memType,"int")==0) || (strcmp(memType,"short")==0);
1385 
1386  if (isIntegerType)
1387  {
1388  const char* newtype="int";
1389  int dbarray[MAX_ARRAY_LENGTH];
1390  int* dbPtr = 0;
1391  char* tmp = elemPtr;
1392  dbPtr = &dbarray[0];
1393  if (dbPtr)
1394  {
1395  char cleanName[MAX_STRLEN];
1396  getCleanName(memName,cleanName);
1397 
1398  int i;
1399  getElement(arrayLen, newtype,memType, tmp, (char*)dbPtr);
1400  for (i=0;i<recursion;i++)
1401  printf(" ");
1402  if (arrayLen==1)
1403  printf("<%s type=\"%s\">",cleanName,memType);
1404  else
1405  printf("<%s type=\"%s\" count=%d>",cleanName,memType,arrayLen);
1406  for (i=0;i<arrayLen;i++)
1407  printf(" %d ",dbPtr[i]);
1408  printf("</%s>\n",cleanName);
1409  }
1410  } else
1411  {
1412  const char* newtype="double";
1413  double dbarray[MAX_ARRAY_LENGTH];
1414  double* dbPtr = 0;
1415  char* tmp = elemPtr;
1416  dbPtr = &dbarray[0];
1417  if (dbPtr)
1418  {
1419  int i;
1420  getElement(arrayLen, newtype,memType, tmp, (char*)dbPtr);
1421  for (i=0;i<recursion;i++)
1422  printf(" ");
1423  char cleanName[MAX_STRLEN];
1424  getCleanName(memName,cleanName);
1425 
1426  if (arrayLen==1)
1427  {
1428  printf("<%s type=\"%s\">",memName,memType);
1429  }
1430  else
1431  {
1432  printf("<%s type=\"%s\" count=%d>",cleanName,memType,arrayLen);
1433  }
1434  for (i=0;i<arrayLen;i++)
1435  printf(" %f ",dbPtr[i]);
1436  printf("</%s>\n",cleanName);
1437  }
1438  }
1439  }
1440 
1441  }
1442  }
1443  }
1444 
1445  int size = fileDna->getElementSize(oldStruct[0], oldStruct[1]);
1446  totalSize += size;
1447  elemPtr+=size;
1448 
1449  }
1450 
1451  return totalSize;
1452 }
1453 
1454 
1456 void bFile::resolvePointers(int verboseMode)
1457 {
1458  bParse::bDNA* fileDna = mFileDNA ? mFileDNA : mMemoryDNA;
1459 
1460  //char *dataPtr = mFileBuffer+mDataStart;
1461 
1462  if (1) //mFlags & (FD_BITS_VARIES | FD_VERSION_VARIES))
1463  {
1465  }
1466 
1467  {
1468 
1469  if (verboseMode & FD_VERBOSE_EXPORT_XML)
1470  {
1471  printf("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
1472  int numitems = m_chunks.size();
1473  printf("<bullet_physics version=%d itemcount = %d>\n", btGetVersion(), numitems);
1474  }
1475  for (int i=0;i<m_chunks.size();i++)
1476  {
1477  const bChunkInd& dataChunk = m_chunks.at(i);
1478 
1479  if (!mFileDNA || fileDna->flagEqual(dataChunk.dna_nr))
1480  {
1481  //dataChunk.len
1482  short int* oldStruct = fileDna->getStruct(dataChunk.dna_nr);
1483  char* oldType = fileDna->getType(oldStruct[0]);
1484 
1485  if (verboseMode & FD_VERBOSE_EXPORT_XML)
1486  printf(" <%s pointer=%d>\n",oldType,dataChunk.oldPtr);
1487 
1488  resolvePointersChunk(dataChunk, verboseMode);
1489 
1490  if (verboseMode & FD_VERBOSE_EXPORT_XML)
1491  printf(" </%s>\n",oldType);
1492  } else
1493  {
1494  //printf("skipping mStruct\n");
1495  }
1496  }
1497  if (verboseMode & FD_VERBOSE_EXPORT_XML)
1498  {
1499  printf("</bullet_physics>\n");
1500  }
1501  }
1502 
1503 
1504 }
1505 
1506 
1507 // ----------------------------------------------------- //
1508 void* bFile::findLibPointer(void *ptr)
1509 {
1510 
1511  bStructHandle** ptrptr = getLibPointers().find(ptr);
1512  if (ptrptr)
1513  return *ptrptr;
1514  return 0;
1515 }
1516 
1517 
1519 {
1520  int i;
1521 
1522  for (i=0;i<m_chunks.size();i++)
1523  {
1524  bChunkInd& dataChunk = m_chunks[i];
1525  dataChunk.oldPtr = findLibPointer(dataChunk.oldPtr);
1526  }
1527 }
1529 {
1530  int i;
1531 
1532  for (i=0;i<m_chunks.size();i++)
1533  {
1534  bChunkInd& dataChunk = m_chunks[i];
1535  char* codeptr = (char*)&dataChunk.code;
1536  char codestr[5] = {codeptr[0],codeptr[1],codeptr[2],codeptr[3],0};
1537 
1538  short* newStruct = dna->getStruct(dataChunk.dna_nr);
1539  char* typeName = dna->getType(newStruct[0]);
1540  printf("%3d: %s ",i,typeName);
1541 
1542  printf("code=%s ",codestr);
1543 
1544  printf("ptr=%p ",dataChunk.oldPtr);
1545  printf("len=%d ",dataChunk.len);
1546  printf("nr=%d ",dataChunk.nr);
1547  if (dataChunk.nr!=1)
1548  {
1549  printf("not 1\n");
1550  }
1551  printf("\n");
1552 
1553 
1554 
1555 
1556  }
1557 
1558 #if 0
1559  IDFinderData ifd;
1560  ifd.success = 0;
1561  ifd.IDname = NULL;
1562  ifd.just_print_it = 1;
1563  for (i=0; i<bf->m_blocks.size(); ++i)
1564  {
1565  BlendBlock* bb = bf->m_blocks[i];
1566  printf("tag='%s'\tptr=%p\ttype=%s\t[%4d]", bb->tag, bb,bf->types[bb->type_index].name,bb->m_array_entries_.size());
1567  block_ID_finder(bb, bf, &ifd);
1568  printf("\n");
1569  }
1570 #endif
1571 
1572 }
1573 
1574 
1575 void bFile::writeChunks(FILE* fp, bool fixupPointers)
1576 {
1577  bParse::bDNA* fileDna = mFileDNA ? mFileDNA : mMemoryDNA;
1578 
1579  for (int i=0;i<m_chunks.size();i++)
1580  {
1581  bChunkInd& dataChunk = m_chunks.at(i);
1582 
1583  // Ouch! need to rebuild the struct
1584  short *oldStruct,*curStruct;
1585  char *oldType, *newType;
1586  int oldLen, curLen, reverseOld;
1587 
1588  oldStruct = fileDna->getStruct(dataChunk.dna_nr);
1589  oldType = fileDna->getType(oldStruct[0]);
1590  oldLen = fileDna->getLength(oldStruct[0]);
1592  reverseOld = mMemoryDNA->getReverseType(oldType);
1593 
1594 
1595  if ((reverseOld!=-1))
1596  {
1597  // make sure it's here
1598  //assert(reverseOld!= -1 && "getReverseType() returned -1, struct required!");
1599  //
1600  curStruct = mMemoryDNA->getStruct(reverseOld);
1601  newType = mMemoryDNA->getType(curStruct[0]);
1602  // make sure it's the same
1603  assert((strcmp(oldType, newType)==0) && "internal error, struct mismatch!");
1604 
1605 
1606  curLen = mMemoryDNA->getLength(curStruct[0]);
1607  dataChunk.dna_nr = reverseOld;
1608  if (strcmp("Link",oldType)!=0)
1609  {
1610  dataChunk.len = curLen * dataChunk.nr;
1611  } else
1612  {
1613 // printf("keep length of link = %d\n",dataChunk.len);
1614  }
1615 
1616  //write the structure header
1617  fwrite(&dataChunk,sizeof(bChunkInd),1,fp);
1618 
1619 
1620 
1621  short int* curStruct1;
1622  curStruct1 = mMemoryDNA->getStruct(dataChunk.dna_nr);
1623  assert(curStruct1 == curStruct);
1624 
1625  char* cur = fixupPointers ? (char*)findLibPointer(dataChunk.oldPtr) : (char*)dataChunk.oldPtr;
1626 
1627  //write the actual contents of the structure(s)
1628  fwrite(cur,dataChunk.len,1,fp);
1629  } else
1630  {
1631  printf("serious error, struct mismatch: don't write\n");
1632  }
1633  }
1634 
1635 }
1636 
1637 
1638 // ----------------------------------------------------- //
1639 int bFile::getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int flags)
1640 {
1641  bool swap = false;
1642  bool varies = false;
1643 
1644  if (flags &FD_ENDIAN_SWAP)
1645  swap = true;
1646  if (flags &FD_BITS_VARIES)
1647  varies = true;
1648 
1649  if (VOID_IS_8)
1650  {
1651  if (varies)
1652  {
1653  bChunkPtr4 head;
1654  memcpy(&head, dataPtr, sizeof(bChunkPtr4));
1655 
1656 
1657  bChunkPtr8 chunk;
1658 
1659  chunk.code = head.code;
1660  chunk.len = head.len;
1661  chunk.m_uniqueInts[0] = head.m_uniqueInt;
1662  chunk.m_uniqueInts[1] = 0;
1663  chunk.dna_nr = head.dna_nr;
1664  chunk.nr = head.nr;
1665 
1666  if (swap)
1667  {
1668  if ((chunk.code & 0xFFFF)==0)
1669  chunk.code >>=16;
1670 
1671  SWITCH_INT(chunk.len);
1672  SWITCH_INT(chunk.dna_nr);
1673  SWITCH_INT(chunk.nr);
1674  }
1675 
1676 
1677  memcpy(dataChunk, &chunk, sizeof(bChunkInd));
1678  }
1679  else
1680  {
1681  bChunkPtr8 c;
1682  memcpy(&c, dataPtr, sizeof(bChunkPtr8));
1683 
1684  if (swap)
1685  {
1686  if ((c.code & 0xFFFF)==0)
1687  c.code >>=16;
1688 
1689  SWITCH_INT(c.len);
1690  SWITCH_INT(c.dna_nr);
1691  SWITCH_INT(c.nr);
1692  }
1693 
1694  memcpy(dataChunk, &c, sizeof(bChunkInd));
1695  }
1696  }
1697  else
1698  {
1699  if (varies)
1700  {
1701  bChunkPtr8 head;
1702  memcpy(&head, dataPtr, sizeof(bChunkPtr8));
1703 
1704 
1705  bChunkPtr4 chunk;
1706  chunk.code = head.code;
1707  chunk.len = head.len;
1708 
1709  if (head.m_uniqueInts[0]==head.m_uniqueInts[1])
1710  {
1711  chunk.m_uniqueInt = head.m_uniqueInts[0];
1712  } else
1713  {
1714  long64 oldPtr =0;
1715  memcpy(&oldPtr, &head.m_uniqueInts[0], 8);
1716  if (swap)
1717  SWITCH_LONGINT(oldPtr);
1718  chunk.m_uniqueInt = (int)(oldPtr >> 3);
1719  }
1720 
1721 
1722  chunk.dna_nr = head.dna_nr;
1723  chunk.nr = head.nr;
1724 
1725  if (swap)
1726  {
1727  if ((chunk.code & 0xFFFF)==0)
1728  chunk.code >>=16;
1729 
1730  SWITCH_INT(chunk.len);
1731  SWITCH_INT(chunk.dna_nr);
1732  SWITCH_INT(chunk.nr);
1733  }
1734 
1735  memcpy(dataChunk, &chunk, sizeof(bChunkInd));
1736  }
1737  else
1738  {
1739  bChunkPtr4 c;
1740  memcpy(&c, dataPtr, sizeof(bChunkPtr4));
1741 
1742  if (swap)
1743  {
1744  if ((c.code & 0xFFFF)==0)
1745  c.code >>=16;
1746 
1747  SWITCH_INT(c.len);
1748  SWITCH_INT(c.dna_nr);
1749  SWITCH_INT(c.nr);
1750  }
1751  memcpy(dataChunk, &c, sizeof(bChunkInd));
1752  }
1753  }
1754 
1755  if (dataChunk->len < 0)
1756  return -1;
1757 
1758 #if 0
1759  print ("----------");
1760  print (dataChunk->code);
1761  print (dataChunk->len);
1762  print (dataChunk->old);
1763  print (dataChunk->dna_nr);
1764  print (dataChunk->nr);
1765 #endif
1766  return (dataChunk->len+ChunkUtils::getOffset(flags));
1767 }
1768 
1769 
1770 
1771 //eof
void push_back(const T &_Val)
void resolvePointersChunk(const bChunkInd &dataChunk, int verboseMode)
this loop only works fine if the Blender DNA structure of the file matches the headerfiles ...
Definition: bFile.cpp:1227
#define setEle(value, current, type, cast, size, ptr)
btAlignedObjectArray< char * > m_pointerPtrFixupArray
Definition: bFile.h:66
int getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int flags)
Definition: bFile.cpp:1639
int m_uniqueIds[2]
Definition: btSerializer.h:136
int getArraySizeNew(short name)
Definition: bDNA.h:41
bDNA * mMemoryDNA
Definition: bFile.h:63
bool lessThan(bDNA *other)
Definition: bDNA.cpp:44
const T & at(int n) const
char * readStruct(char *head, class bChunkInd &chunk)
Definition: bFile.cpp:655
virtual void parseData()=0
void parseInternal(int verboseMode, char *memDna, int memDnaLength)
Definition: bFile.cpp:191
static void getElement(int arrayLen, const char *cur, const char *old, char *oldPtr, char *curData)
Definition: bFile.cpp:866
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
char * getName(int ind)
Definition: bDNA.cpp:50
virtual void addDataBlock(char *dataBlock)=0
char * mFileBuffer
Definition: bFile.h:54
void swapDNA(char *ptr)
Definition: bFile.cpp:387
#define SDNA
Definition: bDefines.h:112
void dumpTypeDefinitions()
Definition: bDNA.cpp:546
int m_uniqueInts[2]
Definition: bChunk.h:56
void dumpChunks(bDNA *dna)
Definition: bFile.cpp:1528
#define TYPE
Definition: bDefines.h:113
int resolvePointersStructRecursive(char *strcPtr, int old_dna, int verboseMode, int recursion)
Definition: bFile.cpp:1244
#define STRC
Definition: bDefines.h:115
bFile(const char *filename, const char headerString[7])
Definition: bFile.cpp:55
int getNumNames() const
Definition: bDNA.h:53
void initCmpFlags(bDNA *memDNA)
Definition: bDNA.cpp:172
#define SIZEOFBLENDERHEADER
Definition: bFile.cpp:27
void swapLen(char *dataPtr)
Definition: bFile.cpp:337
#define DNA1
Definition: bDefines.h:108
static int swapInt(int inte)
Definition: bChunk.cpp:37
#define SWITCH_LONGINT(a)
Definition: bDefines.h:132
void preSwap()
Definition: bFile.cpp:572
int size() const
return the number of elements in the array
#define MAX_STRLEN
Definition: bFile.cpp:30
void * oldPtr
Definition: bChunk.h:67
const bool VOID_IS_8
Definition: bChunk.h:89
btAlignedObjectArray< char * > m_pointerFixupArray
Definition: bFile.h:65
void resolvePointers(int verboseMode)
Resolve pointers replaces the original pointers in structures, and linked lists by the new in-memory ...
Definition: bFile.cpp:1456
int getPointerSize()
Definition: bDNA.cpp:133
void swapStruct(int dna_nr, char *data, bool ignoreEndianFlag)
Definition: bFile.cpp:1112
void insert(const Key &key, const Value &value)
Definition: btHashMap.h:269
void parseStruct(char *strcPtr, char *dtPtr, int old_dna, int new_dna, bool fixupPointers)
Definition: bFile.cpp:780
int mFlags
Definition: bFile.h:76
#define SWITCH_INT(a)
Definition: bDefines.h:119
int btGetVersion()
Definition: btScalar.h:33
void safeSwapPtr(char *dst, const char *src)
Definition: bFile.cpp:937
const char * getCleanName(const char *memName, char *buffer)
Definition: bFile.cpp:32
virtual void parseHeader()
Definition: bFile.cpp:130
void writeFile(const char *fileName)
Definition: bFile.cpp:565
int mFileLen
Definition: bFile.h:55
const Value * find(const Key &key) const
Definition: btHashMap.h:402
virtual ~bFile()
Definition: bFile.cpp:112
#define TLEN
Definition: bDefines.h:114
int mDataStart
Definition: bFile.h:61
bPtrMap & getLibPointers()
Definition: bFile.h:131
int mVersion
Definition: bFile.h:56
#define getEle(value, current, type, cast, size, ptr)
btAlignedObjectArray< bChunkInd > m_chunks
Definition: bFile.h:68
short * getStruct(int ind)
Definition: bDNA.cpp:66
int numallocs
Definition: bFile.cpp:52
void getMatchingFileDNA(short *old, const char *lookupName, const char *lookupType, char *strcData, char *data, bool fixupPointers)
Definition: bFile.cpp:996
void init(char *data, int len, bool swap=false)
Definition: bDNA.cpp:348
virtual void writeChunks(FILE *fp, bool fixupPointers)
Definition: bFile.cpp:1575
bool flagEqual(int dna_nr)
Definition: bDNA.cpp:118
void * findLibPointer(void *ptr)
Definition: bFile.cpp:1508
void swapData(char *data, short type, int arraySize, bool ignoreEndianFlag)
Definition: bFile.cpp:904
char m_headerString[7]
Definition: bFile.h:51
int getElementSize(short type, short name)
Definition: bDNA.h:46
char * getFileElement(short *firstStruct, char *lookupName, char *lookupType, char *data, short **foundPos)
Definition: bFile.cpp:1083
static short swapShort(short sht)
Definition: bChunk.cpp:30
bDNA * mFileDNA
Definition: bFile.h:62
void swap(char *head, class bChunkInd &ch, bool ignoreEndianFlag)
Definition: bFile.cpp:308
const T & btMin(const T &a, const T &b)
Definition: btMinMax.h:23
bPtrMap mLibPointers
Definition: bFile.h:59
#define SWITCH_SHORT(a)
Definition: bDefines.h:126
bool ok()
Definition: bFile.cpp:185
void updateOldPointers()
Definition: bFile.cpp:1518
#define long64
Definition: bChunk.h:20
int getReverseType(short type)
Definition: bDNA.cpp:82
btHashMap< btHashPtr, bChunkInd > m_chunkPtrPtrMap
Definition: bFile.h:69
short getLength(int ind)
Definition: bDNA.cpp:74
bool mOwnsBuffer
Definition: bFile.h:53
#define MAX_ARRAY_LENGTH
Definition: bFile.cpp:28
char * getType(int ind)
Definition: bDNA.cpp:58
static int getOffset(int flags)
Definition: bChunk.cpp:51
void resolvePointersMismatch()
Definition: bFile.cpp:1159