| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789 |
- /*
- bParse
- Copyright (c) 2006-2009 Charlie C & Erwin Coumans http://gamekit.googlecode.com
- This software is provided 'as-is', without any express or implied warranty.
- In no event will the authors be held liable for any damages arising from the use of this software.
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it freely,
- subject to the following restrictions:
- 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.
- 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
- */
- #include "bFile.h"
- #include "bCommon.h"
- #include "bChunk.h"
- #include "bDNA.h"
- #include <math.h>
- #include <string.h>
- #include <stdlib.h>
- #include "bDefines.h"
- #include "LinearMath/btSerializer.h"
- #include "LinearMath/btAlignedAllocator.h"
- #include "LinearMath/btMinMax.h"
- #define SIZEOFBLENDERHEADER 12
- #define MAX_ARRAY_LENGTH 512
- using namespace bParse;
- #define MAX_STRLEN 1024
- const char* getCleanName(const char* memName, char* buffer)
- {
- int slen = strlen(memName);
- assert(slen<MAX_STRLEN);
- slen=btMin(slen,MAX_STRLEN);
- for (int i=0;i<slen;i++)
- {
- if (memName[i]==']'||memName[i]=='[')
- {
- buffer[i] = 0;//'_';
- } else
- {
- buffer[i] = memName[i];
- }
- }
- buffer[slen]=0;
- return buffer;
- }
- int numallocs = 0;
- // ----------------------------------------------------- //
- bFile::bFile(const char *filename, const char headerString[7])
- : mOwnsBuffer(true),
- mFileBuffer(0),
- mFileLen(0),
- mVersion(0),
- mDataStart(0),
- mFileDNA(0),
- mMemoryDNA(0),
- mFlags(FD_INVALID)
- {
- for (int i=0;i<7;i++)
- {
- m_headerString[i] = headerString[i];
- }
- FILE *fp = fopen(filename, "rb");
- if (fp)
- {
- fseek(fp, 0L, SEEK_END);
- mFileLen = ftell(fp);
- fseek(fp, 0L, SEEK_SET);
- mFileBuffer = (char*)malloc(mFileLen+1);
- fread(mFileBuffer, mFileLen, 1, fp);
- fclose(fp);
- //
- parseHeader();
-
- }
- }
- // ----------------------------------------------------- //
- bFile::bFile( char *memoryBuffer, int len, const char headerString[7])
- : mOwnsBuffer(false),
- mFileBuffer(0),
- mFileLen(0),
- mVersion(0),
- mDataStart(0),
- mFileDNA(0),
- mMemoryDNA(0),
- mFlags(FD_INVALID)
- {
- for (int i=0;i<7;i++)
- {
- m_headerString[i] = headerString[i];
- }
- mFileBuffer = memoryBuffer;
- mFileLen = len;
-
- parseHeader();
-
- }
- // ----------------------------------------------------- //
- bFile::~bFile()
- {
- if (mOwnsBuffer && mFileBuffer)
- {
- free(mFileBuffer);
- mFileBuffer = 0;
- }
- delete mMemoryDNA;
- delete mFileDNA;
- }
- // ----------------------------------------------------- //
- void bFile::parseHeader()
- {
- if (!mFileLen || !mFileBuffer)
- return;
- char *blenderBuf = mFileBuffer;
- char header[SIZEOFBLENDERHEADER+1] ;
- memcpy(header, blenderBuf, SIZEOFBLENDERHEADER);
- header[SIZEOFBLENDERHEADER]='\0';
- if (strncmp(header, m_headerString, 6)!=0)
- {
- memcpy(header, m_headerString, SIZEOFBLENDERHEADER);
- return;
- }
- if (header[6] == 'd')
- {
- mFlags |= FD_DOUBLE_PRECISION;
- }
- char *ver = header+9;
- mVersion = atoi(ver);
- if (mVersion <= 241)
- {
- //printf("Warning, %d not fully tested : <= 242\n", mVersion);
- }
- int littleEndian= 1;
- littleEndian= ((char*)&littleEndian)[0];
- // swap ptr sizes...
- if (header[7]=='-')
- {
- mFlags |= FD_FILE_64;
- if (!VOID_IS_8)
- mFlags |= FD_BITS_VARIES;
- }
- else if (VOID_IS_8) mFlags |= FD_BITS_VARIES;
- // swap endian...
- if (header[8]=='V')
- {
- if (littleEndian ==1)
- mFlags |= FD_ENDIAN_SWAP;
- }
- else
- if (littleEndian==0)
- mFlags |= FD_ENDIAN_SWAP;
- mFlags |= FD_OK;
- }
- // ----------------------------------------------------- //
- bool bFile::ok()
- {
- return (mFlags &FD_OK)!=0;
- }
- void bFile::setFileDNA(int verboseMode, char* dnaBuffer, int dnaLen)
- {
- mFileDNA = new bDNA();
-
- ///mFileDNA->init will convert part of DNA file endianness to current CPU endianness if necessary
- mFileDNA->init((char*)dnaBuffer, dnaLen, (mFlags & FD_ENDIAN_SWAP)!=0);
-
- if (verboseMode & FD_VERBOSE_DUMP_DNA_TYPE_DEFINITIONS)
- mFileDNA->dumpTypeDefinitions();
- }
- // ----------------------------------------------------- //
- void bFile::parseInternal(int verboseMode, char* memDna,int memDnaLength)
- {
- if ( (mFlags &FD_OK) ==0)
- return;
- if (mFlags & FD_FILEDNA_IS_MEMDNA)
- {
- setFileDNA(verboseMode,memDna,memDnaLength);
- }
- if (mFileDNA==0)
- {
- char *blenderData = mFileBuffer;
- bChunkInd dna;
- dna.oldPtr = 0;
- char *tempBuffer = blenderData;
- for (int i=0; i<mFileLen; i++)
- {
- // looking for the data's starting position
- // and the start of SDNA decls
- if (!mDataStart && strncmp(tempBuffer, "REND", 4)==0)
- mDataStart = i;
- if (strncmp(tempBuffer, "DNA1", 4)==0)
- {
- // read the DNA1 block and extract SDNA
- if (getNextBlock(&dna, tempBuffer, mFlags) > 0)
- {
- if (strncmp((tempBuffer + ChunkUtils::getOffset(mFlags)), "SDNANAME", 8) ==0)
- dna.oldPtr = (tempBuffer + ChunkUtils::getOffset(mFlags));
- else dna.oldPtr = 0;
- }
- else dna.oldPtr = 0;
- }
- // Some Bullet files are missing the DNA1 block
- // In Blender it's DNA1 + ChunkUtils::getOffset() + SDNA + NAME
- // In Bullet tests its SDNA + NAME
- else if (strncmp(tempBuffer, "SDNANAME", 8) ==0)
- {
- dna.oldPtr = blenderData + i;
- dna.len = mFileLen-i;
- // Also no REND block, so exit now.
- if (mVersion==276) break;
- }
- if (mDataStart && dna.oldPtr) break;
- tempBuffer++;
- }
- if (!dna.oldPtr || !dna.len)
- {
- //printf("Failed to find DNA1+SDNA pair\n");
- mFlags &= ~FD_OK;
- return;
- }
- mFileDNA = new bDNA();
-
-
- ///mFileDNA->init will convert part of DNA file endianness to current CPU endianness if necessary
- mFileDNA->init((char*)dna.oldPtr, dna.len, (mFlags & FD_ENDIAN_SWAP)!=0);
-
- if (mVersion==276)
- {
- int i;
- for (i=0;i<mFileDNA->getNumNames();i++)
- {
- if (strcmp(mFileDNA->getName(i),"int")==0)
- {
- mFlags |= FD_BROKEN_DNA;
- }
- }
- if ((mFlags&FD_BROKEN_DNA)!=0)
- {
- //printf("warning: fixing some broken DNA version\n");
- }
- }
- if (verboseMode & FD_VERBOSE_DUMP_DNA_TYPE_DEFINITIONS)
- mFileDNA->dumpTypeDefinitions();
- }
- mMemoryDNA = new bDNA();
- int littleEndian= 1;
- littleEndian= ((char*)&littleEndian)[0];
-
- mMemoryDNA->init(memDna,memDnaLength,littleEndian==0);
-
- ///@todo we need a better version check, add version/sub version info from FileGlobal into memory DNA/header files
- if (mMemoryDNA->getNumNames() != mFileDNA->getNumNames())
- {
- mFlags |= FD_VERSION_VARIES;
- //printf ("Warning, file DNA is different than built in, performance is reduced. Best to re-export file with a matching version/platform");
- }
- // as long as it kept up to date it will be ok!!
- if (mMemoryDNA->lessThan(mFileDNA))
- {
- //printf ("Warning, file DNA is newer than built in.");
- }
-
- mFileDNA->initCmpFlags(mMemoryDNA);
-
- parseData();
-
- resolvePointers(verboseMode);
-
- updateOldPointers();
-
-
- }
- // ----------------------------------------------------- //
- void bFile::swap(char *head, bChunkInd& dataChunk, bool ignoreEndianFlag)
- {
- char *data = head;
- short *strc = mFileDNA->getStruct(dataChunk.dna_nr);
-
-
- const char s[] = "SoftBodyMaterialData";
- int szs = sizeof(s);
- if (strncmp((char*)&dataChunk.code,"ARAY",4)==0)
- {
- short *oldStruct = mFileDNA->getStruct(dataChunk.dna_nr);
- char *oldType = mFileDNA->getType(oldStruct[0]);
- if (strncmp(oldType,s,szs)==0)
- {
- return;
- }
- }
-
- int len = mFileDNA->getLength(strc[0]);
- for (int i=0; i<dataChunk.nr; i++)
- {
- swapStruct(dataChunk.dna_nr, data,ignoreEndianFlag);
- data+=len;
- }
- }
- void bFile::swapLen(char *dataPtr)
- {
- const bool VOID_IS_8 = ((sizeof(void*)==8));
- if (VOID_IS_8)
- {
- if (mFlags &FD_BITS_VARIES)
- {
- bChunkPtr4*c = (bChunkPtr4*) dataPtr;
- if ((c->code & 0xFFFF)==0)
- c->code >>=16;
- SWITCH_INT(c->len);
- SWITCH_INT(c->dna_nr);
- SWITCH_INT(c->nr);
- } else
- {
- bChunkPtr8* c = (bChunkPtr8*) dataPtr;
- if ((c->code & 0xFFFF)==0)
- c->code >>=16;
- SWITCH_INT(c->len);
- SWITCH_INT(c->dna_nr);
- SWITCH_INT(c->nr);
- }
- } else
- {
- if (mFlags &FD_BITS_VARIES)
- {
- bChunkPtr8*c = (bChunkPtr8*) dataPtr;
- if ((c->code & 0xFFFF)==0)
- c->code >>=16;
- SWITCH_INT(c->len);
- SWITCH_INT(c->dna_nr);
- SWITCH_INT(c->nr);
- } else
- {
- bChunkPtr4* c = (bChunkPtr4*) dataPtr;
- if ((c->code & 0xFFFF)==0)
- c->code >>=16;
- SWITCH_INT(c->len);
- SWITCH_INT(c->dna_nr);
- SWITCH_INT(c->nr);
- }
- }
- }
- void bFile::swapDNA(char* ptr)
- {
- bool swap = ((mFlags & FD_ENDIAN_SWAP)!=0);
- int offset = (mFlags & FD_FILE_64)? 24 : 20;
- char* data = &ptr[offset];
- // void bDNA::init(char *data, int len, bool swap)
- int *intPtr=0;short *shtPtr=0;
- char *cp = 0;int dataLen =0;long nr=0;
- intPtr = (int*)data;
- /*
- SDNA (4 bytes) (magic number)
- NAME (4 bytes)
- <nr> (4 bytes) amount of names (int)
- <string>
- <string>
- */
- if (strncmp(data, "SDNA", 4)==0)
- {
- // skip ++ NAME
- intPtr++;
- intPtr++;
- } else
- {
-
- if (strncmp(data+4, "SDNA", 4)==0)
- {
- // skip ++ NAME
- intPtr++;
- intPtr++;
- intPtr++;
- }
- }
- // Parse names
- if (swap)
- dataLen = ChunkUtils::swapInt(*intPtr);
- else
- dataLen = *intPtr;
-
- *intPtr = ChunkUtils::swapInt(*intPtr);
- intPtr++;
- cp = (char*)intPtr;
- int i;
- for ( i=0; i<dataLen; i++)
- {
- while (*cp)cp++;
- cp++;
- }
-
- {
- nr= (long)cp;
- //long mask=3;
- nr= ((nr+3)&~3)-nr;
- while (nr--)
- {
- cp++;
- }
- }
- /*
- TYPE (4 bytes)
- <nr> amount of types (int)
- <string>
- <string>
- */
- intPtr = (int*)cp;
- assert(strncmp(cp, "TYPE", 4)==0); intPtr++;
- if (swap)
- dataLen = ChunkUtils::swapInt(*intPtr);
- else
- dataLen = *intPtr;
- *intPtr = ChunkUtils::swapInt(*intPtr);
- intPtr++;
- cp = (char*)intPtr;
- for ( i=0; i<dataLen; i++)
- {
- while (*cp)cp++;
- cp++;
- }
- {
- nr= (long)cp;
- // long mask=3;
- nr= ((nr+3)&~3)-nr;
- while (nr--)
- {
- cp++;
- }
- }
- /*
- TLEN (4 bytes)
- <len> (short) the lengths of types
- <len>
- */
- // Parse type lens
- intPtr = (int*)cp;
- assert(strncmp(cp, "TLEN", 4)==0); intPtr++;
-
- shtPtr = (short*)intPtr;
- for ( i=0; i<dataLen; i++, shtPtr++)
- {
- //??????if (swap)
- shtPtr[0] = ChunkUtils::swapShort(shtPtr[0]);
- }
- if (dataLen & 1)
- shtPtr++;
- /*
- STRC (4 bytes)
- <nr> amount of structs (int)
- <typenr>
- <nr_of_elems>
- <typenr>
- <namenr>
- <typenr>
- <namenr>
- */
- intPtr = (int*)shtPtr;
- cp = (char*)intPtr;
- assert(strncmp(cp, "STRC", 4)==0);
- intPtr++;
- if (swap)
- dataLen = ChunkUtils::swapInt(*intPtr);
- else
- dataLen = *intPtr;
- *intPtr = ChunkUtils::swapInt(*intPtr);
- intPtr++;
- shtPtr = (short*)intPtr;
- for ( i=0; i<dataLen; i++)
- {
-
- //if (swap)
- {
- int len = shtPtr[1];
- shtPtr[0]= ChunkUtils::swapShort(shtPtr[0]);
- shtPtr[1]= ChunkUtils::swapShort(shtPtr[1]);
- shtPtr+= 2;
- for (int a=0; a<len; a++, shtPtr+=2)
- {
- shtPtr[0]= ChunkUtils::swapShort(shtPtr[0]);
- shtPtr[1]= ChunkUtils::swapShort(shtPtr[1]);
- }
- }
- // else
- // shtPtr+= (2*shtPtr[1])+2;
- }
- }
- void bFile::writeFile(const char* fileName)
- {
- FILE* f = fopen(fileName,"wb");
- fwrite(mFileBuffer,1,mFileLen,f);
- fclose(f);
- }
- void bFile::preSwap()
- {
- const bool brokenDNA = (mFlags&FD_BROKEN_DNA)!=0;
- //FD_ENDIAN_SWAP
- //byte 8 determines the endianness of the file, little (v) versus big (V)
- int littleEndian= 1;
- littleEndian= ((char*)&littleEndian)[0];
- if (mFileBuffer[8]=='V')
- {
- mFileBuffer[8]='v';
- }
- else
- {
- mFileBuffer[8]='V';
- }
-
-
-
- mDataStart = 12;
- char *dataPtr = mFileBuffer+mDataStart;
- bChunkInd dataChunk;
- dataChunk.code = 0;
- bool ignoreEndianFlag = true;
- //we always want to swap here
- int seek = getNextBlock(&dataChunk, dataPtr, mFlags);
- //dataPtr += ChunkUtils::getOffset(mFlags);
- char *dataPtrHead = 0;
- while (1)
- {
- // one behind
- if (dataChunk.code == SDNA || dataChunk.code==DNA1 || dataChunk.code == TYPE || dataChunk.code == TLEN || dataChunk.code==STRC)
- {
- swapDNA(dataPtr);
- break;
- } else
- {
- //if (dataChunk.code == DNA1) break;
- dataPtrHead = dataPtr+ChunkUtils::getOffset(mFlags);
-
- swapLen(dataPtr);
- if (dataChunk.dna_nr>=0)
- {
- swap(dataPtrHead, dataChunk,ignoreEndianFlag);
- } else
- {
- printf("unknown chunk\n");
- }
- }
- // next please!
- dataPtr += seek;
- seek = getNextBlock(&dataChunk, dataPtr, mFlags);
- if (seek < 0)
- break;
- }
- if (mFlags & FD_ENDIAN_SWAP)
- {
- mFlags &= ~FD_ENDIAN_SWAP;
- } else
- {
- mFlags |= FD_ENDIAN_SWAP;
- }
-
- }
- // ----------------------------------------------------- //
- char* bFile::readStruct(char *head, bChunkInd& dataChunk)
- {
- bool ignoreEndianFlag = false;
- if (mFlags & FD_ENDIAN_SWAP)
- swap(head, dataChunk, ignoreEndianFlag);
-
- if (!mFileDNA->flagEqual(dataChunk.dna_nr))
- {
- // Ouch! need to rebuild the struct
- short *oldStruct,*curStruct;
- char *oldType, *newType;
- int oldLen, curLen, reverseOld;
- oldStruct = mFileDNA->getStruct(dataChunk.dna_nr);
- oldType = mFileDNA->getType(oldStruct[0]);
-
- oldLen = mFileDNA->getLength(oldStruct[0]);
- if ((mFlags&FD_BROKEN_DNA)!=0)
- {
- if ((strcmp(oldType,"btQuantizedBvhNodeData")==0)&&oldLen==20)
- {
- return 0;
- }
- if ((strcmp(oldType,"btShortIntIndexData")==0))
- {
- int allocLen = 2;
- char *dataAlloc = new char[(dataChunk.nr*allocLen)+1];
- memset(dataAlloc, 0, (dataChunk.nr*allocLen)+1);
- short* dest = (short*) dataAlloc;
- const short* src = (short*) head;
- for (int i=0;i<dataChunk.nr;i++)
- {
- dest[i] = src[i];
- if (mFlags &FD_ENDIAN_SWAP)
- {
- SWITCH_SHORT(dest[i]);
- }
- }
- addDataBlock(dataAlloc);
- return dataAlloc;
- }
- }
- ///don't try to convert Link block data, just memcpy it. Other data can be converted.
- if (strcmp("Link",oldType)!=0)
- {
- reverseOld = mMemoryDNA->getReverseType(oldType);
- if ((reverseOld!=-1))
- {
- // make sure it's here
- //assert(reverseOld!= -1 && "getReverseType() returned -1, struct required!");
- //
- curStruct = mMemoryDNA->getStruct(reverseOld);
- newType = mMemoryDNA->getType(curStruct[0]);
- curLen = mMemoryDNA->getLength(curStruct[0]);
- // make sure it's the same
- assert((strcmp(oldType, newType)==0) && "internal error, struct mismatch!");
- numallocs++;
- // numBlocks * length
- int allocLen = (curLen);
- char *dataAlloc = new char[(dataChunk.nr*allocLen)+1];
- memset(dataAlloc, 0, (dataChunk.nr*allocLen));
- // track allocated
- addDataBlock(dataAlloc);
- char *cur = dataAlloc;
- char *old = head;
- for (int block=0; block<dataChunk.nr; block++)
- {
- bool fixupPointers = true;
- parseStruct(cur, old, dataChunk.dna_nr, reverseOld, fixupPointers);
- mLibPointers.insert(old,(bStructHandle*)cur);
- cur += curLen;
- old += oldLen;
- }
- return dataAlloc;
- }
- } else
- {
- //printf("Link found\n");
- }
- } else
- {
- //#define DEBUG_EQUAL_STRUCTS
- #ifdef DEBUG_EQUAL_STRUCTS
- short *oldStruct;
- char *oldType;
- oldStruct = mFileDNA->getStruct(dataChunk.dna_nr);
- oldType = mFileDNA->getType(oldStruct[0]);
- printf("%s equal structure, just memcpy\n",oldType);
- #endif //
- }
- char *dataAlloc = new char[(dataChunk.len)+1];
- memset(dataAlloc, 0, dataChunk.len+1);
- // track allocated
- addDataBlock(dataAlloc);
- memcpy(dataAlloc, head, dataChunk.len);
- return dataAlloc;
- }
- // ----------------------------------------------------- //
- void bFile::parseStruct(char *strcPtr, char *dtPtr, int old_dna, int new_dna, bool fixupPointers)
- {
- if (old_dna == -1) return;
- if (new_dna == -1) return;
- //disable this, because we need to fixup pointers/ListBase
- if (0)//mFileDNA->flagEqual(old_dna))
- {
- short *strc = mFileDNA->getStruct(old_dna);
- int len = mFileDNA->getLength(strc[0]);
- memcpy(strcPtr, dtPtr, len);
- return;
- }
- // Ok, now build the struct
- char *memType, *memName, *cpc, *cpo;
- short *fileStruct, *filePtrOld, *memoryStruct, *firstStruct;
- int elementLength, size, revType, old_nr, new_nr, fpLen;
- short firstStructType;
- // File to memory lookup
- memoryStruct = mMemoryDNA->getStruct(new_dna);
- fileStruct = mFileDNA->getStruct(old_dna);
- firstStruct = fileStruct;
- filePtrOld = fileStruct;
- firstStructType = mMemoryDNA->getStruct(0)[0];
- // Get number of elements
- elementLength = memoryStruct[1];
- memoryStruct+=2;
- cpc = strcPtr; cpo = 0;
- for (int ele=0; ele<elementLength; ele++, memoryStruct+=2)
- {
- memType = mMemoryDNA->getType(memoryStruct[0]);
- memName = mMemoryDNA->getName(memoryStruct[1]);
- size = mMemoryDNA->getElementSize(memoryStruct[0], memoryStruct[1]);
- revType = mMemoryDNA->getReverseType(memoryStruct[0]);
- if (revType != -1 && memoryStruct[0]>=firstStructType && memName[0] != '*')
- {
- cpo = getFileElement(firstStruct, memName, memType, dtPtr, &filePtrOld);
- if (cpo)
- {
- int arrayLen = mFileDNA->getArraySizeNew(filePtrOld[1]);
- old_nr = mFileDNA->getReverseType(memType);
- new_nr = revType;
- fpLen = mFileDNA->getElementSize(filePtrOld[0], filePtrOld[1]);
- if (arrayLen==1)
- {
- parseStruct(cpc, cpo, old_nr, new_nr,fixupPointers);
- } else
- {
- char* tmpCpc = cpc;
- char* tmpCpo = cpo;
- for (int i=0;i<arrayLen;i++)
- {
- parseStruct(tmpCpc, tmpCpo, old_nr, new_nr,fixupPointers);
- tmpCpc += size/arrayLen;
- tmpCpo += fpLen/arrayLen;
- }
- }
- cpc+=size;
- cpo+=fpLen;
- }
- else
- cpc+=size;
- }
- else
- {
- getMatchingFileDNA(fileStruct, memName, memType, cpc, dtPtr,fixupPointers);
- cpc+=size;
- }
- }
- }
- // ----------------------------------------------------- //
- static void getElement(int arrayLen, const char *cur, const char *old, char *oldPtr, char *curData)
- {
- #define getEle(value, current, type, cast, size, ptr)\
- if (strcmp(current, type)==0)\
- {\
- value = (*(cast*)ptr);\
- ptr += size;\
- }
- #define setEle(value, current, type, cast, size, ptr)\
- if (strcmp(current, type)==0)\
- {\
- (*(cast*)ptr) = (cast)value;\
- ptr += size;\
- }
- double value = 0.0;
- for (int i=0; i<arrayLen; i++)
- {
- getEle(value, old, "char", char, sizeof(char), oldPtr);
- setEle(value, cur, "char", char, sizeof(char), curData);
- getEle(value, old, "short", short, sizeof(short), oldPtr);
- setEle(value, cur, "short", short, sizeof(short), curData);
- getEle(value, old, "ushort", unsigned short, sizeof(unsigned short), oldPtr);
- setEle(value, cur, "ushort", unsigned short, sizeof(unsigned short), curData);
- getEle(value, old, "int", int, sizeof(int), oldPtr);
- setEle(value, cur, "int", int, sizeof(int), curData);
- getEle(value, old, "long", int, sizeof(int), oldPtr);
- setEle(value, cur, "long", int, sizeof(int), curData);
- getEle(value, old, "float", float, sizeof(float), oldPtr);
- setEle(value, cur, "float", float, sizeof(float), curData);
- getEle(value, old, "double", double, sizeof(double), oldPtr);
- setEle(value, cur, "double", double, sizeof(double), curData);
- }
- }
- // ----------------------------------------------------- //
- void bFile::swapData(char *data, short type, int arraySize,bool ignoreEndianFlag)
- {
- if (ignoreEndianFlag || (mFlags &FD_ENDIAN_SWAP))
- {
- if (type == 2 || type == 3)
- {
- short *sp = (short*)data;
- for (int i=0; i<arraySize; i++)
- {
- sp[0] = ChunkUtils::swapShort(sp[0]);
- sp++;
- }
- }
- if (type>3 && type <8)
- {
- char c;
- char *cp = data;
- for (int i=0; i<arraySize; i++)
- {
- c = cp[0];
- cp[0] = cp[3];
- cp[3] = c;
- c = cp[1];
- cp[1] = cp[2];
- cp[2] = c;
- cp+=4;
- }
- }
- }
- }
- void bFile::safeSwapPtr(char *dst, const char *src)
- {
- int ptrFile = mFileDNA->getPointerSize();
- int ptrMem = mMemoryDNA->getPointerSize();
- if (!src && !dst)
- return;
- if (ptrFile == ptrMem)
- {
- memcpy(dst, src, ptrMem);
- }
- else if (ptrMem==4 && ptrFile==8)
- {
- btPointerUid* oldPtr = (btPointerUid*)src;
- btPointerUid* newPtr = (btPointerUid*)dst;
- if (oldPtr->m_uniqueIds[0] == oldPtr->m_uniqueIds[1])
- {
- //Bullet stores the 32bit unique ID in both upper and lower part of 64bit pointers
- //so it can be used to distinguish between .blend and .bullet
- newPtr->m_uniqueIds[0] = oldPtr->m_uniqueIds[0];
- } else
- {
- //deal with pointers the Blender .blend style way, see
- //readfile.c in the Blender source tree
- long64 longValue = *((long64*)src);
- //endian swap for 64bit pointer otherwise truncation will fail due to trailing zeros
- if (mFlags & FD_ENDIAN_SWAP)
- SWITCH_LONGINT(longValue);
- *((int*)dst) = (int)(longValue>>3);
- }
-
- }
- else if (ptrMem==8 && ptrFile==4)
- {
- btPointerUid* oldPtr = (btPointerUid*)src;
- btPointerUid* newPtr = (btPointerUid*)dst;
- if (oldPtr->m_uniqueIds[0] == oldPtr->m_uniqueIds[1])
- {
- newPtr->m_uniqueIds[0] = oldPtr->m_uniqueIds[0];
- newPtr->m_uniqueIds[1] = 0;
- } else
- {
- *((long64*)dst)= *((int*)src);
- }
- }
- else
- {
- printf ("%d %d\n", ptrFile,ptrMem);
- assert(0 && "Invalid pointer len");
- }
- }
- // ----------------------------------------------------- //
- void bFile::getMatchingFileDNA(short* dna_addr, const char* lookupName, const char* lookupType, char *strcData, char *data, bool fixupPointers)
- {
- // find the matching memory dna data
- // to the file being loaded. Fill the
- // memory with the file data...
- int len = dna_addr[1];
- dna_addr+=2;
- for (int i=0; i<len; i++, dna_addr+=2)
- {
- const char* type = mFileDNA->getType(dna_addr[0]);
- const char* name = mFileDNA->getName(dna_addr[1]);
-
- int eleLen = mFileDNA->getElementSize(dna_addr[0], dna_addr[1]);
- if ((mFlags&FD_BROKEN_DNA)!=0)
- {
- if ((strcmp(type,"short")==0)&&(strcmp(name,"int")==0))
- {
- eleLen = 0;
- }
- }
- if (strcmp(lookupName, name)==0)
- {
- //int arrayLenold = mFileDNA->getArraySize((char*)name.c_str());
- int arrayLen = mFileDNA->getArraySizeNew(dna_addr[1]);
- //assert(arrayLenold == arrayLen);
-
- if (name[0] == '*')
- {
- // cast pointers
- int ptrFile = mFileDNA->getPointerSize();
- int ptrMem = mMemoryDNA->getPointerSize();
- safeSwapPtr(strcData,data);
- if (fixupPointers)
- {
- if (arrayLen > 1)
- {
- //void **sarray = (void**)strcData;
- //void **darray = (void**)data;
-
- char *cpc, *cpo;
- cpc = (char*)strcData;
- cpo = (char*)data;
-
- for (int a=0; a<arrayLen; a++)
- {
- safeSwapPtr(cpc, cpo);
- m_pointerFixupArray.push_back(cpc);
- cpc += ptrMem;
- cpo += ptrFile;
- }
- }
- else
- {
- if (name[1] == '*')
- m_pointerPtrFixupArray.push_back(strcData);
- else
- m_pointerFixupArray.push_back(strcData);
- }
- }
- else
- {
- // printf("skipped %s %s : %x\n",type.c_str(),name.c_str(),strcData);
- }
- }
- else if (strcmp(type, lookupType)==0)
- memcpy(strcData, data, eleLen);
- else
- getElement(arrayLen, lookupType, type, data, strcData);
- // --
- return;
- }
- data+=eleLen;
- }
- }
- // ----------------------------------------------------- //
- char* bFile::getFileElement(short *firstStruct, char *lookupName, char *lookupType, char *data, short **foundPos)
- {
- short *old = firstStruct;//mFileDNA->getStruct(old_nr);
- int elementLength = old[1];
- old+=2;
- for (int i=0; i<elementLength; i++, old+=2)
- {
- char* type = mFileDNA->getType(old[0]);
- char* name = mFileDNA->getName(old[1]);
- int len = mFileDNA->getElementSize(old[0], old[1]);
- if (strcmp(lookupName, name)==0)
- {
- if (strcmp(type, lookupType)==0)
- {
- if (foundPos)
- *foundPos = old;
- return data;
- }
- return 0;
- }
- data+=len;
- }
- return 0;
- }
- // ----------------------------------------------------- //
- void bFile::swapStruct(int dna_nr, char *data,bool ignoreEndianFlag)
- {
- if (dna_nr == -1) return;
- short *strc = mFileDNA->getStruct(dna_nr);
- //short *firstStrc = strc;
- int elementLen= strc[1];
- strc+=2;
- short first = mFileDNA->getStruct(0)[0];
- char *buf = data;
- for (int i=0; i<elementLen; i++, strc+=2)
- {
- char *type = mFileDNA->getType(strc[0]);
- char *name = mFileDNA->getName(strc[1]);
- int size = mFileDNA->getElementSize(strc[0], strc[1]);
- if (strc[0] >= first && name[0]!='*')
- {
- int old_nr = mFileDNA->getReverseType(type);
- int arrayLen = mFileDNA->getArraySizeNew(strc[1]);
- if (arrayLen==1)
- {
- swapStruct(old_nr,buf,ignoreEndianFlag);
- } else
- {
- char* tmpBuf = buf;
- for (int i=0;i<arrayLen;i++)
- {
- swapStruct(old_nr,tmpBuf,ignoreEndianFlag);
- tmpBuf+=size/arrayLen;
- }
- }
- }
- else
- {
- //int arrayLenOld = mFileDNA->getArraySize(name);
- int arrayLen = mFileDNA->getArraySizeNew(strc[1]);
- //assert(arrayLenOld == arrayLen);
- swapData(buf, strc[0], arrayLen,ignoreEndianFlag);
- }
- buf+=size;
- }
- }
- void bFile::resolvePointersMismatch()
- {
- // printf("resolvePointersStructMismatch\n");
- int i;
- for (i=0;i< m_pointerFixupArray.size();i++)
- {
- char* cur = m_pointerFixupArray.at(i);
- void** ptrptr = (void**) cur;
- void* ptr = *ptrptr;
- ptr = findLibPointer(ptr);
- if (ptr)
- {
- //printf("Fixup pointer!\n");
- *(ptrptr) = ptr;
- } else
- {
- // printf("pointer not found: %x\n",cur);
- }
- }
-
- for (i=0; i<m_pointerPtrFixupArray.size(); i++)
- {
- char* cur= m_pointerPtrFixupArray.at(i);
- void** ptrptr = (void**)cur;
- bChunkInd *block = m_chunkPtrPtrMap.find(*ptrptr);
- if (block)
- {
- int ptrMem = mMemoryDNA->getPointerSize();
- int ptrFile = mFileDNA->getPointerSize();
- int blockLen = block->len / ptrFile;
- void *onptr = findLibPointer(*ptrptr);
- if (onptr)
- {
- char *newPtr = new char[blockLen * ptrMem];
- addDataBlock(newPtr);
- memset(newPtr, 0, blockLen * ptrMem);
- void **onarray = (void**)onptr;
- char *oldPtr = (char*)onarray;
- int p = 0;
- while (blockLen-- > 0)
- {
- btPointerUid dp = {{0}};
- safeSwapPtr((char*)dp.m_uniqueIds, oldPtr);
- void **tptr = (void**)(newPtr + p * ptrMem);
- *tptr = findLibPointer(dp.m_ptr);
- oldPtr += ptrFile;
- ++p;
- }
- *ptrptr = newPtr;
- }
- }
- }
- }
- ///this loop only works fine if the Blender DNA structure of the file matches the headerfiles
- void bFile::resolvePointersChunk(const bChunkInd& dataChunk, int verboseMode)
- {
- bParse::bDNA* fileDna = mFileDNA ? mFileDNA : mMemoryDNA;
- short int* oldStruct = fileDna->getStruct(dataChunk.dna_nr);
- short oldLen = fileDna->getLength(oldStruct[0]);
- //char* structType = fileDna->getType(oldStruct[0]);
- char* cur = (char*)findLibPointer(dataChunk.oldPtr);
- for (int block=0; block<dataChunk.nr; block++)
- {
- resolvePointersStructRecursive(cur,dataChunk.dna_nr, verboseMode,1);
- cur += oldLen;
- }
- }
- int bFile::resolvePointersStructRecursive(char *strcPtr, int dna_nr, int verboseMode,int recursion)
- {
-
- bParse::bDNA* fileDna = mFileDNA ? mFileDNA : mMemoryDNA;
- char* memType;
- char* memName;
- short firstStructType = fileDna->getStruct(0)[0];
- char* elemPtr= strcPtr;
- short int* oldStruct = fileDna->getStruct(dna_nr);
-
- int elementLength = oldStruct[1];
- oldStruct+=2;
- int totalSize = 0;
- for (int ele=0; ele<elementLength; ele++, oldStruct+=2)
- {
- memType = fileDna->getType(oldStruct[0]);
- memName = fileDna->getName(oldStruct[1]);
-
-
- int arrayLen = fileDna->getArraySizeNew(oldStruct[1]);
- if (memName[0] == '*')
- {
- if (arrayLen > 1)
- {
- void **array= (void**)elemPtr;
- for (int a=0; a<arrayLen; a++)
- {
- if (verboseMode & FD_VERBOSE_EXPORT_XML)
- {
- for (int i=0;i<recursion;i++)
- {
- printf(" ");
- }
- //skip the *
- printf("<%s type=\"pointer\"> ",&memName[1]);
- printf("%d ", array[a]);
- printf("</%s>\n",&memName[1]);
- }
- array[a] = findLibPointer(array[a]);
- }
- }
- else
- {
- void** ptrptr = (void**) elemPtr;
- void* ptr = *ptrptr;
- if (verboseMode & FD_VERBOSE_EXPORT_XML)
- {
- for (int i=0;i<recursion;i++)
- {
- printf(" ");
- }
- printf("<%s type=\"pointer\"> ",&memName[1]);
- printf("%d ", ptr);
- printf("</%s>\n",&memName[1]);
- }
- ptr = findLibPointer(ptr);
- if (ptr)
- {
- // printf("Fixup pointer at 0x%x from 0x%x to 0x%x!\n",ptrptr,*ptrptr,ptr);
- *(ptrptr) = ptr;
- if (memName[1] == '*' && ptrptr && *ptrptr)
- {
- // This will only work if the given **array is continuous
- void **array= (void**)*(ptrptr);
- void *np= array[0];
- int n=0;
- while (np)
- {
- np= findLibPointer(array[n]);
- if (np) array[n]= np;
- n++;
- }
- }
- } else
- {
- // printf("Cannot fixup pointer at 0x%x from 0x%x to 0x%x!\n",ptrptr,*ptrptr,ptr);
- }
- }
- } else
- {
- int revType = fileDna->getReverseType(oldStruct[0]);
- if (oldStruct[0]>=firstStructType) //revType != -1 &&
- {
- char cleanName[MAX_STRLEN];
- getCleanName(memName,cleanName);
- int arrayLen = fileDna->getArraySizeNew(oldStruct[1]);
- int byteOffset = 0;
- if (verboseMode & FD_VERBOSE_EXPORT_XML)
- {
- for (int i=0;i<recursion;i++)
- {
- printf(" ");
- }
- if (arrayLen>1)
- {
- printf("<%s type=\"%s\" count=%d>\n",cleanName,memType, arrayLen);
- } else
- {
- printf("<%s type=\"%s\">\n",cleanName,memType);
- }
- }
- for (int i=0;i<arrayLen;i++)
- {
- byteOffset += resolvePointersStructRecursive(elemPtr+byteOffset,revType, verboseMode,recursion+1);
- }
- if (verboseMode & FD_VERBOSE_EXPORT_XML)
- {
- for (int i=0;i<recursion;i++)
- {
- printf(" ");
- }
- printf("</%s>\n",cleanName);
- }
- } else
- {
- //export a simple type
- if (verboseMode & FD_VERBOSE_EXPORT_XML)
- {
- if (arrayLen>MAX_ARRAY_LENGTH)
- {
- printf("too long\n");
- } else
- {
- //printf("%s %s\n",memType,memName);
- bool isIntegerType = (strcmp(memType,"char")==0) || (strcmp(memType,"int")==0) || (strcmp(memType,"short")==0);
- if (isIntegerType)
- {
- const char* newtype="int";
- int dbarray[MAX_ARRAY_LENGTH];
- int* dbPtr = 0;
- char* tmp = elemPtr;
- dbPtr = &dbarray[0];
- if (dbPtr)
- {
- char cleanName[MAX_STRLEN];
- getCleanName(memName,cleanName);
- int i;
- getElement(arrayLen, newtype,memType, tmp, (char*)dbPtr);
- for (i=0;i<recursion;i++)
- printf(" ");
- if (arrayLen==1)
- printf("<%s type=\"%s\">",cleanName,memType);
- else
- printf("<%s type=\"%s\" count=%d>",cleanName,memType,arrayLen);
- for (i=0;i<arrayLen;i++)
- printf(" %d ",dbPtr[i]);
- printf("</%s>\n",cleanName);
- }
- } else
- {
- const char* newtype="double";
- double dbarray[MAX_ARRAY_LENGTH];
- double* dbPtr = 0;
- char* tmp = elemPtr;
- dbPtr = &dbarray[0];
- if (dbPtr)
- {
- int i;
- getElement(arrayLen, newtype,memType, tmp, (char*)dbPtr);
- for (i=0;i<recursion;i++)
- printf(" ");
- char cleanName[MAX_STRLEN];
- getCleanName(memName,cleanName);
- if (arrayLen==1)
- {
- printf("<%s type=\"%s\">",memName,memType);
- }
- else
- {
- printf("<%s type=\"%s\" count=%d>",cleanName,memType,arrayLen);
- }
- for (i=0;i<arrayLen;i++)
- printf(" %f ",dbPtr[i]);
- printf("</%s>\n",cleanName);
- }
- }
- }
-
- }
- }
- }
- int size = fileDna->getElementSize(oldStruct[0], oldStruct[1]);
- totalSize += size;
- elemPtr+=size;
-
- }
- return totalSize;
- }
- ///Resolve pointers replaces the original pointers in structures, and linked lists by the new in-memory structures
- void bFile::resolvePointers(int verboseMode)
- {
- bParse::bDNA* fileDna = mFileDNA ? mFileDNA : mMemoryDNA;
- //char *dataPtr = mFileBuffer+mDataStart;
- if (1) //mFlags & (FD_BITS_VARIES | FD_VERSION_VARIES))
- {
- resolvePointersMismatch();
- }
-
- {
- if (verboseMode & FD_VERBOSE_EXPORT_XML)
- {
- printf("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
- int numitems = m_chunks.size();
- printf("<bullet_physics version=%d itemcount = %d>\n", btGetVersion(), numitems);
- }
- for (int i=0;i<m_chunks.size();i++)
- {
- const bChunkInd& dataChunk = m_chunks.at(i);
- if (!mFileDNA || fileDna->flagEqual(dataChunk.dna_nr))
- {
- //dataChunk.len
- short int* oldStruct = fileDna->getStruct(dataChunk.dna_nr);
- char* oldType = fileDna->getType(oldStruct[0]);
-
- if (verboseMode & FD_VERBOSE_EXPORT_XML)
- printf(" <%s pointer=%d>\n",oldType,dataChunk.oldPtr);
- resolvePointersChunk(dataChunk, verboseMode);
- if (verboseMode & FD_VERBOSE_EXPORT_XML)
- printf(" </%s>\n",oldType);
- } else
- {
- //printf("skipping mStruct\n");
- }
- }
- if (verboseMode & FD_VERBOSE_EXPORT_XML)
- {
- printf("</bullet_physics>\n");
- }
- }
-
-
- }
- // ----------------------------------------------------- //
- void* bFile::findLibPointer(void *ptr)
- {
- bStructHandle** ptrptr = getLibPointers().find(ptr);
- if (ptrptr)
- return *ptrptr;
- return 0;
- }
- void bFile::updateOldPointers()
- {
- int i;
- for (i=0;i<m_chunks.size();i++)
- {
- bChunkInd& dataChunk = m_chunks[i];
- dataChunk.oldPtr = findLibPointer(dataChunk.oldPtr);
- }
- }
- void bFile::dumpChunks(bParse::bDNA* dna)
- {
- int i;
- for (i=0;i<m_chunks.size();i++)
- {
- bChunkInd& dataChunk = m_chunks[i];
- char* codeptr = (char*)&dataChunk.code;
- char codestr[5] = {codeptr[0],codeptr[1],codeptr[2],codeptr[3],0};
-
- short* newStruct = dna->getStruct(dataChunk.dna_nr);
- char* typeName = dna->getType(newStruct[0]);
- printf("%3d: %s ",i,typeName);
- printf("code=%s ",codestr);
-
- printf("ptr=%p ",dataChunk.oldPtr);
- printf("len=%d ",dataChunk.len);
- printf("nr=%d ",dataChunk.nr);
- if (dataChunk.nr!=1)
- {
- printf("not 1\n");
- }
- printf("\n");
-
-
- }
- #if 0
- IDFinderData ifd;
- ifd.success = 0;
- ifd.IDname = NULL;
- ifd.just_print_it = 1;
- for (i=0; i<bf->m_blocks.size(); ++i)
- {
- BlendBlock* bb = bf->m_blocks[i];
- printf("tag='%s'\tptr=%p\ttype=%s\t[%4d]", bb->tag, bb,bf->types[bb->type_index].name,bb->m_array_entries_.size());
- block_ID_finder(bb, bf, &ifd);
- printf("\n");
- }
- #endif
- }
- void bFile::writeChunks(FILE* fp, bool fixupPointers)
- {
- bParse::bDNA* fileDna = mFileDNA ? mFileDNA : mMemoryDNA;
- for (int i=0;i<m_chunks.size();i++)
- {
- bChunkInd& dataChunk = m_chunks.at(i);
-
- // Ouch! need to rebuild the struct
- short *oldStruct,*curStruct;
- char *oldType, *newType;
- int curLen, reverseOld;
- oldStruct = fileDna->getStruct(dataChunk.dna_nr);
- oldType = fileDna->getType(oldStruct[0]);
- //int oldLen = fileDna->getLength(oldStruct[0]);
- ///don't try to convert Link block data, just memcpy it. Other data can be converted.
- reverseOld = mMemoryDNA->getReverseType(oldType);
-
- if ((reverseOld!=-1))
- {
- // make sure it's here
- //assert(reverseOld!= -1 && "getReverseType() returned -1, struct required!");
- //
- curStruct = mMemoryDNA->getStruct(reverseOld);
- newType = mMemoryDNA->getType(curStruct[0]);
- // make sure it's the same
- assert((strcmp(oldType, newType)==0) && "internal error, struct mismatch!");
-
- curLen = mMemoryDNA->getLength(curStruct[0]);
- dataChunk.dna_nr = reverseOld;
- if (strcmp("Link",oldType)!=0)
- {
- dataChunk.len = curLen * dataChunk.nr;
- } else
- {
- // printf("keep length of link = %d\n",dataChunk.len);
- }
-
- //write the structure header
- fwrite(&dataChunk,sizeof(bChunkInd),1,fp);
-
- short int* curStruct1;
- curStruct1 = mMemoryDNA->getStruct(dataChunk.dna_nr);
- assert(curStruct1 == curStruct);
- char* cur = fixupPointers ? (char*)findLibPointer(dataChunk.oldPtr) : (char*)dataChunk.oldPtr;
- //write the actual contents of the structure(s)
- fwrite(cur,dataChunk.len,1,fp);
- } else
- {
- printf("serious error, struct mismatch: don't write\n");
- }
- }
-
- }
- // ----------------------------------------------------- //
- int bFile::getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int flags)
- {
- bool swap = false;
- bool varies = false;
- if (flags &FD_ENDIAN_SWAP)
- swap = true;
- if (flags &FD_BITS_VARIES)
- varies = true;
- if (VOID_IS_8)
- {
- if (varies)
- {
- bChunkPtr4 head;
- memcpy(&head, dataPtr, sizeof(bChunkPtr4));
- bChunkPtr8 chunk;
- chunk.code = head.code;
- chunk.len = head.len;
- chunk.m_uniqueInts[0] = head.m_uniqueInt;
- chunk.m_uniqueInts[1] = 0;
- chunk.dna_nr = head.dna_nr;
- chunk.nr = head.nr;
- if (swap)
- {
- if ((chunk.code & 0xFFFF)==0)
- chunk.code >>=16;
- SWITCH_INT(chunk.len);
- SWITCH_INT(chunk.dna_nr);
- SWITCH_INT(chunk.nr);
- }
- memcpy(dataChunk, &chunk, sizeof(bChunkInd));
- }
- else
- {
- bChunkPtr8 c;
- memcpy(&c, dataPtr, sizeof(bChunkPtr8));
- if (swap)
- {
- if ((c.code & 0xFFFF)==0)
- c.code >>=16;
- SWITCH_INT(c.len);
- SWITCH_INT(c.dna_nr);
- SWITCH_INT(c.nr);
- }
- memcpy(dataChunk, &c, sizeof(bChunkInd));
- }
- }
- else
- {
- if (varies)
- {
- bChunkPtr8 head;
- memcpy(&head, dataPtr, sizeof(bChunkPtr8));
- bChunkPtr4 chunk;
- chunk.code = head.code;
- chunk.len = head.len;
- if (head.m_uniqueInts[0]==head.m_uniqueInts[1])
- {
- chunk.m_uniqueInt = head.m_uniqueInts[0];
- } else
- {
- long64 oldPtr =0;
- memcpy(&oldPtr, &head.m_uniqueInts[0], 8);
- if (swap)
- SWITCH_LONGINT(oldPtr);
- chunk.m_uniqueInt = (int)(oldPtr >> 3);
- }
-
- chunk.dna_nr = head.dna_nr;
- chunk.nr = head.nr;
- if (swap)
- {
- if ((chunk.code & 0xFFFF)==0)
- chunk.code >>=16;
- SWITCH_INT(chunk.len);
- SWITCH_INT(chunk.dna_nr);
- SWITCH_INT(chunk.nr);
- }
- memcpy(dataChunk, &chunk, sizeof(bChunkInd));
- }
- else
- {
- bChunkPtr4 c;
- memcpy(&c, dataPtr, sizeof(bChunkPtr4));
- if (swap)
- {
- if ((c.code & 0xFFFF)==0)
- c.code >>=16;
- SWITCH_INT(c.len);
- SWITCH_INT(c.dna_nr);
- SWITCH_INT(c.nr);
- }
- memcpy(dataChunk, &c, sizeof(bChunkInd));
- }
- }
- if (dataChunk->len < 0)
- return -1;
- #if 0
- print ("----------");
- print (dataChunk->code);
- print (dataChunk->len);
- print (dataChunk->old);
- print (dataChunk->dna_nr);
- print (dataChunk->nr);
- #endif
- return (dataChunk->len+ChunkUtils::getOffset(flags));
- }
- //eof
|