diff options
Diffstat (limited to 'source/blender/readblenfile')
-rw-r--r-- | source/blender/readblenfile/SConscript | 11 | ||||
-rw-r--r-- | source/blender/readblenfile/intern/BLO_readblenfile.c | 555 |
2 files changed, 15 insertions, 551 deletions
diff --git a/source/blender/readblenfile/SConscript b/source/blender/readblenfile/SConscript index 69671732055..32c474d1eb6 100644 --- a/source/blender/readblenfile/SConscript +++ b/source/blender/readblenfile/SConscript @@ -6,9 +6,12 @@ readblenfile_env = library_env.Copy () source_files = ['intern/BLO_readblenfile.c'] readblenfile_env.Append (CPPPATH = ['.', - '../readstreamglue', - '../blenloader', - '../blenkernel', - '../../kernel/gen_messaging']) + '../readstreamglue', + '../blenloader', + '../blenloader/intern', + '../blenkernel', + '../blenlib', + '../makesdna', + '../../kernel/gen_messaging']) readblenfile_env.Library (target='#'+user_options_dict['BUILD_DIR']+'/lib/blender_readblenfile', source=source_files) diff --git a/source/blender/readblenfile/intern/BLO_readblenfile.c b/source/blender/readblenfile/intern/BLO_readblenfile.c index 902066fbbeb..698fed79842 100644 --- a/source/blender/readblenfile/intern/BLO_readblenfile.c +++ b/source/blender/readblenfile/intern/BLO_readblenfile.c @@ -50,14 +50,12 @@ #include <unistd.h> // read #endif -#include "BLO_readStreamGlue.h" - #include "BLO_readfile.h" #include "BLO_readblenfile.h" #include "BKE_blender.h" -#define CACHESIZE 100000 +#include "BLI_blenlib.h" /** Magic number for the file header */ char *headerMagic = "BLENDFI"; @@ -94,470 +92,7 @@ void BLO_setcurrentversionnumber(char array[4]) #define O_BINARY 0 #endif -/** - * Defines the data struct for the .blend file - */ -struct BLO_readblenfileStruct { - struct readStreamGlueStruct *streamGlue; - int fileDes; - unsigned int cacheSize; - unsigned int inCache; - unsigned int leftToRead; - unsigned int Seek; - - int (*read)(struct BLO_readblenfileStruct *readblenfileStruct, void *buffer, int size); - - char *readCache; - char *fromBuffer; - int fromBufferSize; - char crInBuffer; - char removeCR; -}; - -// declare static functions - -static int readfromfilehandle( - struct BLO_readblenfileStruct *readblenfileStruct, - void *buffer, - int size); - -static int readfrommemory( - struct BLO_readblenfileStruct *readblenfileStruct, - void *buffer, - int size); - -static int fillcache( - struct BLO_readblenfileStruct *readblenfileStruct); - -static unsigned int readfromcache( - struct BLO_readblenfileStruct *readblenfileStruct, - void * buffer, - unsigned int size); - -static BlendFileData *readblenfilegeneric( - struct BLO_readblenfileStruct *readblenfileStruct, - BlendReadError *error_r); - -// implementation of static functions - -/** - * \brief Reads data from the already opened file. - * Given the file structure a buffer and the size of the block - * the function will read from the file if it is open. - * If not it will return -1 indicating an unopened file. - * - * \return Returns the size of the file read, or -1. - */ -static int readfromfilehandle( - struct BLO_readblenfileStruct *readblenfileStruct, - void *buffer, - int size) -{ - int readsize = -1; - - if (readblenfileStruct->fileDes != -1) { - readsize = read(readblenfileStruct->fileDes, buffer, size); - } - - return(readsize); -} - -/** - * \brief Reads and erases from readblenfileStruct->fromBuffer - * - * Copies information from the from the fromBuffer to the buffer, then - * decrements the size of the fromBuffer, and moves the pointer along - * thereby effectively removing the data forever. - * - * \return Returns the size of the read from memory - */ -static int readfrommemory( - struct BLO_readblenfileStruct *readblenfileStruct, - void *buffer, - int size) -{ - int readsize = -1; - - if (readblenfileStruct->fromBuffer) { - if (size > readblenfileStruct->fromBufferSize) { - size = readblenfileStruct->fromBufferSize; - } - - memcpy(buffer, readblenfileStruct->fromBuffer, size); - readblenfileStruct->fromBufferSize -= size; - readblenfileStruct->fromBuffer += size; - - readsize = size; - } - - return(readsize); -} - -/** - * Read in data from the file into a cache. - * - * \return Returns the size of the read. - * - * \attention Note: there is some code missing to return CR if the - * structure indicates it. -*/ -static int fillcache( - struct BLO_readblenfileStruct *readblenfileStruct) -{ - int readsize; - int toread; - - // how many bytes can we read ? - - toread = readblenfileStruct->leftToRead; - - if (toread > readblenfileStruct->cacheSize) { - toread = readblenfileStruct->cacheSize; - } - - readsize = readblenfileStruct->read(readblenfileStruct, readblenfileStruct->readCache, toread); - if (readsize > 0) { - if (readblenfileStruct->removeCR) { - // do some stuff here - } - readblenfileStruct->inCache = readsize; - readblenfileStruct->leftToRead -= readsize; - } - - return (readsize); -} - -/** - * \brief Read data from the cache into a buffer. - * Marks the last read location with a seek value. - * - * \return Returns the size of the read from the cache. - * - * \attention Note: missing some handling code if the location is - * \attention outside of the cache. - */ -static unsigned int readfromcache( - struct BLO_readblenfileStruct *readblenfileStruct, - void * buffer, - unsigned int size) -{ - unsigned int readsize = 0; - - if (readblenfileStruct->inCache - readblenfileStruct->Seek > size) { - memcpy(buffer, readblenfileStruct->readCache + readblenfileStruct->Seek, size); - readblenfileStruct->Seek += size; - readsize = size; - } else { - // handle me - } - - return(readsize); -} - -/** - * \brief Converts from BRS error code to BRE error code. - * - * Error conversion method to convert from - * the BRS type errors and return a BRE - * type error code. - * Decodes based on the function, the generic, - * and the specific portions of the error. - */ -static BlendReadError brs_to_bre(int err) -{ - int errFunction = BRS_GETFUNCTION(err); - int errGeneric = BRS_GETGENERR(err); - int errSpecific = BRS_GETSPECERR(err); - - if (errGeneric) { - switch (errGeneric) { - case BRS_MALLOC: - return BRE_OUT_OF_MEMORY; - case BRS_NULL: - return BRE_INTERNAL_ERROR; - case BRS_MAGIC: - return BRE_NOT_A_BLEND; - case BRS_CRCHEADER: - case BRS_CRCDATA: - return BRE_CORRUPT; - case BRS_DATALEN: - return BRE_INCOMPLETE; - case BRS_STUB: - return BRE_NOT_A_BLEND; - } - } else if (errSpecific) { - switch (errFunction) { - case BRS_READSTREAMGLUE: - switch (errSpecific) { - case BRS_UNKNOWN: - return BRE_INTERNAL_ERROR; - } - break; - case BRS_READSTREAMFILE: - switch (errSpecific) { - case BRS_NOTABLEND: - return BRE_NOT_A_BLEND; - case BRS_READERROR: - return BRE_UNABLE_TO_READ; - } - break; - case BRS_INFLATE: - switch (errSpecific) { - case BRS_INFLATEERROR: - return BRE_CORRUPT; - } - break; - case BRS_DECRYPT: - switch (errSpecific) { - case BRS_RSANEWERROR: - return BRE_INTERNAL_ERROR; - case BRS_DECRYPTERROR: - return BRE_INTERNAL_ERROR; - case BRS_NOTOURPUBKEY: - return BRE_NOT_ALLOWED; - } - break; - case BRS_VERIFY: - switch (errSpecific) { - case BRS_RSANEWERROR: - return BRE_INTERNAL_ERROR; - case BRS_SIGFAILED: - return BRE_INTERNAL_ERROR; - } - break; - } - } - - return BRE_INVALID; -} - -static BlendFileData *readblenfilegeneric( - struct BLO_readblenfileStruct *readblenfileStruct, - BlendReadError *error_r) -{ - BlendFileData *bfd= NULL; - unsigned char reserved[BLO_RESERVEDSIZE]; - uint8_t minversion[4]; - uint8_t myversion[4]; - uint8_t version[4]; - uint8_t flags[4]; - void *parms[2]; - int filesize; - - parms[0]= &bfd; - parms[1]= error_r; - - BLO_setcurrentversionnumber(myversion); - - readblenfileStruct->cacheSize = CACHESIZE; - readblenfileStruct->readCache = malloc(readblenfileStruct->cacheSize); - - if (fillcache(readblenfileStruct) <= 0) { - *error_r = BRE_UNABLE_TO_READ; - } else if (readfromcache(readblenfileStruct, minversion, sizeof(minversion)) != sizeof(minversion)) { - *error_r = BRE_UNABLE_TO_READ; - } else if (memcmp(minversion, myversion, sizeof(minversion)) > 0) { - *error_r = BRE_TOO_NEW; - } else if (readfromcache(readblenfileStruct, version, sizeof(version)) != sizeof(version)) { - *error_r = BRE_UNABLE_TO_READ; - } else if (readfromcache(readblenfileStruct, flags, sizeof(flags)) != sizeof(flags)) { - *error_r = BRE_UNABLE_TO_READ; - } else if (readfromcache(readblenfileStruct, &filesize, sizeof(filesize)) != sizeof(filesize)) { - *error_r = BRE_UNABLE_TO_READ; - } else if (readfromcache(readblenfileStruct, reserved, sizeof(reserved)) != sizeof(reserved)) { - *error_r = BRE_UNABLE_TO_READ; - } else { - filesize = ntohl(filesize); - - // substract number of bytes we've - // been handling outside readfromcache() - filesize -= strlen(headerMagic); - filesize--; - - if (filesize < readblenfileStruct->inCache) { - // we've allready read more than we're supposed to - readblenfileStruct->inCache = filesize; - readblenfileStruct->leftToRead = 0; - } else { - // - readblenfileStruct->leftToRead = filesize - readblenfileStruct->inCache; - } - - do { - int err; - - *error_r = BRE_NONE; - err = readStreamGlue( - parms, - &(readblenfileStruct->streamGlue), - readblenfileStruct->readCache + readblenfileStruct->Seek, - readblenfileStruct->inCache - readblenfileStruct->Seek); - - readblenfileStruct->inCache = 0; - readblenfileStruct->Seek = 0; - - if (err) { - bfd = NULL; - - /* If *error_r != BRE_NONE then it is - * blo_readstreamfile_end signaling an error - * in the loading code. Otherwise it is some - * other part of the streamglue system signalling - * and error so we convert the BRS error into - * a BRE error. - * - * Does this have to be so convoluted? No. - */ - if (*error_r == BRE_NONE) { - *error_r = brs_to_bre(err); - } - - break; - } - } while (fillcache(readblenfileStruct) > 0); - } - - free(readblenfileStruct->readCache); - readblenfileStruct->readCache = 0; - - return bfd; -} - -// implementation of exported functions - -BlendFileData * -BLO_readblenfilememory( - char *fromBuffer, - int fromBufferSize, - BlendReadError *error_r) -{ - int magiclen = strlen(headerMagic); - BlendFileData *bfd = NULL; - - if (!fromBuffer) { - *error_r = BRE_UNABLE_TO_OPEN; - } else if (fromBufferSize < magiclen) { - *error_r = BRE_UNABLE_TO_READ; - } else if (strncmp(fromBuffer, headerMagic, magiclen) != 0) { - *error_r = BRE_NOT_A_BLEND; - } else if (fromBufferSize < magiclen+1) { - *error_r = BRE_UNABLE_TO_READ; - } else if (fromBuffer[magiclen] != '\r' && fromBuffer[magiclen] != '\n') { - *error_r = BRE_NOT_A_BLEND; - } else { - int crnl; - - fromBuffer+= magiclen; - fromBufferSize-= magiclen; - crnl = (fromBuffer[0] == '\r'); - fromBuffer++; - fromBufferSize--; - - if (crnl && fromBufferSize<1) { - *error_r = BRE_UNABLE_TO_READ; - } else { - struct BLO_readblenfileStruct *readblenfileStruct = NULL; - - /* skip carriage return if necessary */ - if (crnl) { - fromBuffer++; - fromBufferSize--; - } - - // Allocate all the stuff we need - readblenfileStruct = calloc(sizeof(struct BLO_readblenfileStruct), 1); - readblenfileStruct->fileDes = -1; - readblenfileStruct->fromBuffer = fromBuffer; - readblenfileStruct->fromBufferSize = fromBufferSize; - readblenfileStruct->read = readfrommemory; - - readblenfileStruct->removeCR = crnl; - // fake filesize for now until we've - // actually read in the filesize from the header - // make sure we don't read more bytes than there - // are left to handle accoding to fromBufferSize - readblenfileStruct->leftToRead = readblenfileStruct->fromBufferSize; - - bfd = readblenfilegeneric(readblenfileStruct, error_r); - - free(readblenfileStruct); - readblenfileStruct = 0; - } - } - - return bfd; -} - - -BlendFileData * -BLO_readblenfilehandle( - int fd, - BlendReadError *error_r) -{ - int magiclen = strlen(headerMagic); - BlendFileData *bfd = NULL; - char tempbuffer[256]; - - if (fd==-1) { - *error_r = BRE_UNABLE_TO_OPEN; - } else if (read(fd, tempbuffer, magiclen) != magiclen) { - *error_r = BRE_UNABLE_TO_READ; - } else if (strncmp(tempbuffer, headerMagic, magiclen) != 0 ) { - *error_r = BRE_NOT_A_BLEND; - } else if (read(fd, tempbuffer, 1) != 1) { - *error_r = BRE_UNABLE_TO_READ; - } else if (tempbuffer[0] != '\r' && tempbuffer[0] != '\n') { - *error_r = BRE_NOT_A_BLEND; - } else { - int crnl = (tempbuffer[0] == '\r'); - - if (crnl && read(fd, tempbuffer, 1)!=1) { - *error_r = BRE_UNABLE_TO_READ; - } else { - struct BLO_readblenfileStruct *readblenfileStruct; - - // Allocate all the stuff we need - readblenfileStruct = calloc(sizeof(struct BLO_readblenfileStruct), 1); - readblenfileStruct->fileDes = fd; - readblenfileStruct->read = readfromfilehandle; - - readblenfileStruct->removeCR = crnl; - // fake filesize for now until we've - // actually read in the filesize from the header - readblenfileStruct->leftToRead = CACHESIZE; - - bfd = readblenfilegeneric(readblenfileStruct, error_r); - - free(readblenfileStruct); - readblenfileStruct = 0; - } - } - - return bfd; -} - -BlendFileData * -BLO_readblenfilename( - char *fileName, - BlendReadError *error_r) -{ - BlendFileData *bfd = NULL; - int fd; - - fd = open(fileName, O_RDONLY | O_BINARY); - if (fd==-1) { - *error_r= BRE_UNABLE_TO_OPEN; - } else { - bfd = BLO_readblenfilehandle(fd, error_r); - } - - if (fd!=-1) - close(fd); - - return bfd; -} - - /* Runtime reading */ +/* Runtime reading */ static int handle_read_msb_int(int handle) { unsigned char buf[4]; @@ -601,7 +136,8 @@ blo_read_runtime( BlendReadError *error_r) { BlendFileData *bfd= NULL; - int fd, datastart; + void *filedata= NULL; + int fd, actualsize, datastart; char buf[8]; fd= open(path, O_BINARY|O_RDONLY, 0); @@ -609,6 +145,8 @@ blo_read_runtime( *error_r= BRE_UNABLE_TO_OPEN; goto cleanup; } + + actualsize= BLI_filesize(fd); lseek(fd, -12, SEEK_END); @@ -623,8 +161,9 @@ blo_read_runtime( *error_r= BRE_NOT_A_BLEND; goto cleanup; } else { + printf("starting to read runtime from %s at datastart %d\n", path, datastart); lseek(fd, datastart, SEEK_SET); - bfd= BLO_readblenfilehandle(fd, error_r); + bfd = blo_read_blendafterruntime(fd, actualsize-datastart, error_r); } cleanup: @@ -634,81 +173,3 @@ cleanup: return bfd; } -#if 0 -static char *brs_error_to_string(int err) { - int errFunction = BRS_GETFUNCTION(err); - int errGeneric = BRS_GETGENERR(err); - int errSpecific = BRS_GETSPECERR(err); - char *errFunctionStrings[] = { - "", - "The read stream", - "The read stream loopback", - "The key store", - "The file reading", - "Decompressing the file", - "Decrypting the file", - "Verifying the signature"}; - char *errGenericStrings[] = { - "", - "generated an out of memory error", - "bumped on an internal programming error", - "did not recognize this as a blend file", - "failed a blend file check", - "bumped on corrupted data", - "needed the rest of the blend file", - "is not allowed in this version"}; - char *errReadStreamGlueStrings[] = { - "", - "does not know how to proceed"}; - char *errReadStreamFileStrings[] = { - "", - "did not recognize this as a blend file", - "was busted on a read error"}; - char *errInflateStrings[] = { - "", - "bumped on a decompress error"}; - char *errDecryptStrings[] = { - "", - "could not make a new key", - "bumped on a decrypt error", - "was not allowed. This blend file is not made by you."}; - char *errVerifyStrings[] = { - "", - "could not make a new key", - "failed"}; - char *errFunctionString= errFunctionStrings[errFunction]; - char *errExtraString= ""; - char *errString; - - if (errGeneric) { - errExtraString= errGenericStrings[errGeneric]; - } else if (errSpecific) { - switch (errFunction) { - case BRS_READSTREAMGLUE: - errExtraString= errReadStreamGlueStrings[errSpecific]; - break; - case BRS_READSTREAMFILE: - errExtraString= errReadStreamFileStrings[errSpecific]; - break; - case BRS_INFLATE: - errExtraString= errInflateStrings[errSpecific]; - break; - case BRS_DECRYPT: - errExtraString= errDecryptStrings[errSpecific]; - break; - case BRS_VERIFY: - errExtraString= errVerifyStrings[errSpecific]; - break; - default: - break; - } - } - - errString= MEM_mallocN(strlen(errFunctionString) + 1 + strlen(errExtraString) + 1); - sprintf(errString, "%s %s", errFunctionString, errExtraString); - - return errString; -} -#endif - - |