summaryrefslogtreecommitdiff
path: root/thirdparty/bullet/src/Bullet3Serialize/Bullet2FileLoader/b3DNA.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/bullet/src/Bullet3Serialize/Bullet2FileLoader/b3DNA.cpp')
-rw-r--r--thirdparty/bullet/src/Bullet3Serialize/Bullet2FileLoader/b3DNA.cpp629
1 files changed, 629 insertions, 0 deletions
diff --git a/thirdparty/bullet/src/Bullet3Serialize/Bullet2FileLoader/b3DNA.cpp b/thirdparty/bullet/src/Bullet3Serialize/Bullet2FileLoader/b3DNA.cpp
new file mode 100644
index 0000000000..0fe5056922
--- /dev/null
+++ b/thirdparty/bullet/src/Bullet3Serialize/Bullet2FileLoader/b3DNA.cpp
@@ -0,0 +1,629 @@
+/*
+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 <assert.h>
+
+#include "b3DNA.h"
+#include "b3Chunk.h"
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+//this define will force traversal of structures, to check backward (and forward) compatibility
+//#define TEST_BACKWARD_FORWARD_COMPATIBILITY
+
+
+using namespace bParse;
+
+
+// ----------------------------------------------------- //
+bDNA::bDNA()
+ : mPtrLen(0)
+{
+ // --
+}
+
+// ----------------------------------------------------- //
+bDNA::~bDNA()
+{
+ // --
+}
+
+// ----------------------------------------------------- //
+bool bDNA::lessThan(bDNA *file)
+{
+ return ( m_Names.size() < file->m_Names.size());
+}
+
+// ----------------------------------------------------- //
+char *bDNA::getName(int ind)
+{
+ assert(ind <= (int)m_Names.size());
+ return m_Names[ind].m_name;
+}
+
+
+// ----------------------------------------------------- //
+char *bDNA::getType(int ind)
+{
+ assert(ind<= (int)mTypes.size());
+ return mTypes[ind];
+}
+
+
+// ----------------------------------------------------- //
+short *bDNA::getStruct(int ind)
+{
+ assert(ind <= (int)mStructs.size());
+ return mStructs[ind];
+}
+
+
+// ----------------------------------------------------- //
+short bDNA::getLength(int ind)
+{
+ assert(ind <= (int)mTlens.size());
+ return mTlens[ind];
+}
+
+
+// ----------------------------------------------------- //
+int bDNA::getReverseType(short type)
+{
+
+ int* intPtr = mStructReverse.find(type);
+ if (intPtr)
+ return *intPtr;
+
+ return -1;
+}
+
+// ----------------------------------------------------- //
+int bDNA::getReverseType(const char *type)
+{
+
+ b3HashString key(type);
+ int* valuePtr = mTypeLookup.find(key);
+ if (valuePtr)
+ return *valuePtr;
+
+ return -1;
+}
+
+// ----------------------------------------------------- //
+int bDNA::getNumStructs()
+{
+ return (int)mStructs.size();
+}
+
+// ----------------------------------------------------- //
+bool bDNA::flagNotEqual(int dna_nr)
+{
+ assert(dna_nr <= (int)mCMPFlags.size());
+ return mCMPFlags[dna_nr] == FDF_STRUCT_NEQU;
+}
+
+// ----------------------------------------------------- //
+bool bDNA::flagEqual(int dna_nr)
+{
+ assert(dna_nr <= (int)mCMPFlags.size());
+ int flag = mCMPFlags[dna_nr];
+ return flag == FDF_STRUCT_EQU;
+}
+
+// ----------------------------------------------------- //
+bool bDNA::flagNone(int dna_nr)
+{
+ assert(dna_nr <= (int)mCMPFlags.size());
+ return mCMPFlags[dna_nr] == FDF_NONE;
+}
+
+// ----------------------------------------------------- //
+int bDNA::getPointerSize()
+{
+ return mPtrLen;
+}
+
+// ----------------------------------------------------- //
+void bDNA::initRecurseCmpFlags(int iter)
+{
+ // iter is FDF_STRUCT_NEQU
+
+ short *oldStrc = mStructs[iter];
+ short type = oldStrc[0];
+
+ for (int i=0; i<(int)mStructs.size(); i++)
+ {
+ if (i != iter && mCMPFlags[i] == FDF_STRUCT_EQU )
+ {
+ short *curStruct = mStructs[i];
+ int eleLen = curStruct[1];
+ curStruct+=2;
+
+ for (int j=0; j<eleLen; j++, curStruct+=2)
+ {
+ if (curStruct[0] == type)
+ {
+ //char *name = m_Names[curStruct[1]].m_name;
+ //if (name[0] != '*')
+ if (m_Names[curStruct[1]].m_isPointer)
+ {
+ mCMPFlags[i] = FDF_STRUCT_NEQU;
+ initRecurseCmpFlags(i);
+ }
+ }
+ }
+ }
+ }
+}
+
+// ----------------------------------------------------- //
+void bDNA::initCmpFlags(bDNA *memDNA)
+{
+
+ // compare the file to memory
+ // this ptr should be the file data
+
+
+ assert(!(m_Names.size() == 0));// && "SDNA empty!");
+ mCMPFlags.resize(mStructs.size(), FDF_NONE);
+
+
+
+ int i;
+ for ( i=0; i<(int)mStructs.size(); i++)
+ {
+ short *oldStruct = mStructs[i];
+
+ int oldLookup = getReverseType(oldStruct[0]);
+ if (oldLookup == -1)
+ {
+ mCMPFlags[i] = FDF_NONE;
+ continue;
+ }
+ //char* typeName = mTypes[oldStruct[0]];
+
+//#define SLOW_FORWARD_COMPATIBLE 1
+#ifdef SLOW_FORWARD_COMPATIBLE
+ char* typeName = mTypes[oldLookup];
+ int newLookup = memDNA->getReverseType(typeName);
+ if (newLookup == -1)
+ {
+ mCMPFlags[i] = FDF_NONE;
+ continue;
+ }
+ short *curStruct = memDNA->mStructs[newLookup];
+#else
+ // memory for file
+
+ if (oldLookup < memDNA->mStructs.size())
+ {
+ short *curStruct = memDNA->mStructs[oldLookup];
+#endif
+
+
+
+ // rebuild...
+ mCMPFlags[i] = FDF_STRUCT_NEQU;
+
+#ifndef TEST_BACKWARD_FORWARD_COMPATIBILITY
+
+ if (curStruct[1] == oldStruct[1])
+ {
+ // type len same ...
+ if (mTlens[oldStruct[0]] == memDNA->mTlens[curStruct[0]])
+ {
+ bool isSame = true;
+ int elementLength = oldStruct[1];
+
+
+ curStruct+=2;
+ oldStruct+=2;
+
+
+ for (int j=0; j<elementLength; j++, curStruct+=2, oldStruct+=2)
+ {
+ // type the same
+ //const char* typeFileDNA = mTypes[oldStruct[0]];
+ //const char* typeMemDNA = mTypes[curStruct[0]];
+ if (strcmp(mTypes[oldStruct[0]], memDNA->mTypes[curStruct[0]])!=0)
+ {
+ isSame=false;
+ break;
+ }
+
+ // name the same
+ if (strcmp(m_Names[oldStruct[1]].m_name, memDNA->m_Names[curStruct[1]].m_name)!=0)
+ {
+ isSame=false;
+ break;
+ }
+ }
+ // flag valid ==
+ if (isSame)
+ mCMPFlags[i] = FDF_STRUCT_EQU;
+ }
+ }
+#endif
+ }
+ }
+
+
+
+
+
+ // recurse in
+ for ( i=0; i<(int)mStructs.size(); i++)
+ {
+ if (mCMPFlags[i] == FDF_STRUCT_NEQU)
+ initRecurseCmpFlags(i);
+ }
+}
+
+
+
+
+static int name_is_array(char* name, int* dim1, int* dim2) {
+ int len = strlen(name);
+ /*fprintf(stderr,"[%s]",name);*/
+ /*if (len >= 1) {
+ if (name[len-1] != ']')
+ return 1;
+ }
+ return 0;*/
+ char *bp;
+ int num;
+ if (dim1) {
+ *dim1 = 1;
+ }
+ if (dim2) {
+ *dim2 = 1;
+ }
+ bp = strchr(name, '[');
+ if (!bp) {
+ return 0;
+ }
+ num = 0;
+ while (++bp < name+len-1) {
+ const char c = *bp;
+ if (c == ']') {
+ break;
+ }
+ if (c <= '9' && c >= '0') {
+ num *= 10;
+ num += (c - '0');
+ } else {
+ printf("array parse error.\n");
+ return 0;
+ }
+ }
+ if (dim2) {
+ *dim2 = num;
+ }
+
+ /* find second dim, if any. */
+ bp = strchr(bp, '[');
+ if (!bp) {
+ return 1; /* at least we got the first dim. */
+ }
+ num = 0;
+ while (++bp < name+len-1) {
+ const char c = *bp;
+ if (c == ']') {
+ break;
+ }
+ if (c <= '9' && c >= '0') {
+ num *= 10;
+ num += (c - '0');
+ } else {
+ printf("array2 parse error.\n");
+ return 1;
+ }
+ }
+ if (dim1) {
+ if (dim2) {
+ *dim1 = *dim2;
+ *dim2 = num;
+ } else {
+ *dim1 = num;
+ }
+ }
+
+ return 1;
+}
+
+
+// ----------------------------------------------------- //
+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++;
+ }
+
+
+
+ // Parse names
+ if (swap)
+ {
+ *intPtr = ChunkUtils::swapInt(*intPtr);
+ }
+ dataLen = *intPtr;
+ intPtr++;
+
+ cp = (char*)intPtr;
+ int i;
+ for ( i=0; i<dataLen; i++)
+ {
+ bNameInfo info;
+ info.m_name = cp;
+ info.m_isPointer = (info.m_name[0] == '*') || (info.m_name[1] == '*');
+ name_is_array(info.m_name,&info.m_dim0,&info.m_dim1);
+ m_Names.push_back(info);
+ while (*cp)cp++;
+ cp++;
+ }
+
+
+ cp = b3AlignPointer(cp,4);
+
+
+ /*
+ TYPE (4 bytes)
+ <nr> amount of types (int)
+ <string>
+ <string>
+ */
+
+ intPtr = (int*)cp;
+ assert(strncmp(cp, "TYPE", 4)==0); intPtr++;
+
+ if (swap)
+ {
+ *intPtr = ChunkUtils::swapInt(*intPtr);
+ }
+ dataLen = *intPtr;
+ intPtr++;
+
+ cp = (char*)intPtr;
+ for ( i=0; i<dataLen; i++)
+ {
+ mTypes.push_back(cp);
+ while (*cp)cp++;
+ cp++;
+ }
+
+
+ cp = b3AlignPointer(cp,4);
+
+ /*
+ TLEN (4 bytes)
+ <len> (short) the lengths of types
+ <len>
+ */
+
+ // Parse type lens
+ intPtr = (int*)cp;
+ assert(strncmp(cp, "TLEN", 4)==0); intPtr++;
+
+ dataLen = (int)mTypes.size();
+
+ shtPtr = (short*)intPtr;
+ for ( i=0; i<dataLen; i++, shtPtr++)
+ {
+ if (swap)
+ shtPtr[0] = ChunkUtils::swapShort(shtPtr[0]);
+ mTlens.push_back(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)
+ {
+ *intPtr = ChunkUtils::swapInt(*intPtr);
+ }
+ dataLen = *intPtr;
+ intPtr++;
+
+
+ shtPtr = (short*)intPtr;
+ for ( i=0; i<dataLen; i++)
+ {
+ mStructs.push_back (shtPtr);
+ if (swap)
+ {
+ shtPtr[0]= ChunkUtils::swapShort(shtPtr[0]);
+ shtPtr[1]= ChunkUtils::swapShort(shtPtr[1]);
+
+ int len = 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;
+ }
+
+
+ // build reverse lookups
+ for ( i=0; i<(int)mStructs.size(); i++)
+ {
+ short *strc = mStructs.at(i);
+ if (!mPtrLen && strcmp(mTypes[strc[0]],"ListBase")==0)
+ {
+ mPtrLen = mTlens[strc[0]]/2;
+ }
+
+ mStructReverse.insert(strc[0], i);
+ mTypeLookup.insert(b3HashString(mTypes[strc[0]]),i);
+ }
+}
+
+
+// ----------------------------------------------------- //
+int bDNA::getArraySize(char* string)
+{
+ int ret = 1;
+ int len = strlen(string);
+
+
+ char* next = 0;
+ for (int i=0; i<len; i++)
+ {
+ char c = string[i];
+
+ if (c == '[')
+ next = &string[i+1];
+ else if (c==']')
+ if (next)
+ ret *= atoi(next);
+ }
+
+// print (string << ' ' << ret);
+ return ret;
+}
+
+
+void bDNA::dumpTypeDefinitions()
+{
+ int i;
+
+ int numTypes = mTypes.size();
+
+ for (i=0;i<numTypes;i++)
+ {
+
+ }
+
+ for ( i=0; i<(int)mStructs.size(); i++)
+ {
+ int totalBytes=0;
+ short *oldStruct = mStructs[i];
+
+ int oldLookup = getReverseType(oldStruct[0]);
+ if (oldLookup == -1)
+ {
+ mCMPFlags[i] = FDF_NONE;
+ continue;
+ }
+
+ short* newStruct = mStructs[oldLookup];
+ char* typeName = mTypes[newStruct[0]];
+ printf("%3d: %s ",i,typeName);
+
+ //char *name = mNames[oldStruct[1]];
+ int len = oldStruct[1];
+ printf(" (%d fields) ",len);
+ oldStruct+=2;
+
+ printf("{");
+ int j;
+ for (j=0; j<len; ++j,oldStruct+=2) {
+ const char* name = m_Names[oldStruct[1]].m_name;
+ printf("%s %s", mTypes[oldStruct[0]],name);
+ int elemNumBytes= 0;
+ int arrayDimensions = getArraySizeNew(oldStruct[1]);
+
+ if (m_Names[oldStruct[1]].m_isPointer)
+ {
+ elemNumBytes = VOID_IS_8 ? 8 : 4;
+ } else
+ {
+ elemNumBytes = getLength(oldStruct[0]);
+ }
+ printf(" /* %d bytes */",elemNumBytes*arrayDimensions);
+
+ if (j == len-1) {
+ printf(";}");
+ } else {
+ printf("; ");
+ }
+ totalBytes+=elemNumBytes*arrayDimensions;
+ }
+ printf("\ntotalBytes=%d\n\n",totalBytes);
+
+ }
+
+
+
+#if 0
+ /* dump out display of types and their sizes */
+ for (i=0; i<bf->types_count; ++i) {
+ /* if (!bf->types[i].is_struct)*/
+ {
+ printf("%3d: sizeof(%s%s)=%d",
+ i,
+ bf->types[i].is_struct ? "struct " : "atomic ",
+ bf->types[i].name, bf->types[i].size);
+ if (bf->types[i].is_struct) {
+ int j;
+ printf(", %d fields: { ", bf->types[i].fieldtypes_count);
+ for (j=0; j<bf->types[i].fieldtypes_count; ++j) {
+ printf("%s %s",
+ bf->types[bf->types[i].fieldtypes[j]].name,
+ bf->names[bf->types[i].fieldnames[j]]);
+ if (j == bf->types[i].fieldtypes_count-1) {
+ printf(";}");
+ } else {
+ printf("; ");
+ }
+ }
+ }
+ printf("\n\n");
+
+ }
+ }
+#endif
+
+}
+
+
+
+
+//eof
+
+