Undo revision 23130 which was a merge with 2.5, a messy one because I did something...
[blender.git] / source / blender / readblenfile / intern / BLO_readblenfile.c
index 9b9bf7d..40a991a 100644 (file)
@@ -1,15 +1,12 @@
-/**
+/*
  * $Id$
  *
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ * ***** BEGIN GPL LICENSE BLOCK *****
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License.  See http://www.blender.org/BL/ for information
- * about this.
+ * of the License, or (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  *
  * Contributor(s): none yet.
  *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * ***** END GPL LICENSE BLOCK *****
  *
  */
-
+/**
+ * \file BLO_readblenfile.c
+ * \brief This file handles the loading if .blend files
+ * \ingroup mainmodule
+ */
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <fcntl.h>
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #ifdef WIN32
 #include <io.h>                // read, open
 #else // ! WIN32
 #include <unistd.h>            // read
 #endif
 
-#include "BLO_readStreamGlue.h"
-
 #include "BLO_readfile.h"
 #include "BLO_readblenfile.h"
 
 #include "BKE_blender.h"
+#include "BKE_report.h"
 
-#define CACHESIZE 100000
+#include "BLI_blenlib.h"
 
+/** Magic number for the file header */
 char *headerMagic = "BLENDFI";
 
+/**
+ * \brief Set the version number into the array.
+ *
+ * version contains the integer number of the version
+ * i.e. 227
+ * array[1] gets set to the div of the number by 100 i.e. 2
+ * array[2] gets the remainder i.e. 27
+ */
 void BLO_setversionnumber(char array[4], int version)
 {
-       memset(array, 0, sizeof(array));
+       memset(array, 0, sizeof(char)*4);
 
        array[1] = version / 100;
        array[2] = version % 100;
 }
 
+/**
+ * Sets version number using BLENDER_VERSION
+ * Function that calls the setversionnumber(char[],int) with 
+ * the BLENDER_VERSION constant and sets the resultant array
+ * with the version parts.  
+ * see BLO_setversionnumber(char[],int).
+ */
 void BLO_setcurrentversionnumber(char array[4])
 {
        BLO_setversionnumber(array, BLENDER_VERSION);
@@ -70,428 +90,7 @@ void BLO_setcurrentversionnumber(char array[4])
 #define O_BINARY 0
 #endif
 
-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
-
-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);
-}
-
-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);
-}
-
-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);
-}
-
-
-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);
-}
-
-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)
-{
-       static char *functionality_check= "\0FUNCTIONALITY_CHECK += BLO_readblenfilememory\n";
-       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)
-{
-       static char *functionality_check= "\0FUNCTIONALITY_CHECK += BLO_readblenfilehandle\n";
-       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)
-{
-       static char *functionality_check= "\0FUNCTIONALITY_CHECK += BLO_readblenfilename\n";
-       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];
@@ -532,34 +131,37 @@ cleanup:
 BlendFileData *
 blo_read_runtime(
        char *path, 
-       BlendReadError *error_r) 
+       ReportList *reports)
 {
-       static char *functionality_check= "\0FUNCTIONALITY_CHECK += BLO_read_runtime\n";
        BlendFileData *bfd= NULL;
-       int fd, datastart;
+       int fd, actualsize, datastart;
        char buf[8];
 
        fd= open(path, O_BINARY|O_RDONLY, 0);
        if (fd==-1) {
-               *error_r= BRE_UNABLE_TO_OPEN;
+               BKE_report(reports, RPT_ERROR, "Unable to open");
                goto cleanup;
        }
+       
+       actualsize= BLI_filesize(fd);
 
        lseek(fd, -12, SEEK_END);
 
        datastart= handle_read_msb_int(fd);
        if (datastart==-1) {
-               *error_r= BRE_UNABLE_TO_READ;
+               BKE_report(reports, RPT_ERROR, "Unable to read");
                goto cleanup;
        } else if (read(fd, buf, 8)!=8) {
-               *error_r= BRE_UNABLE_TO_READ;
+               BKE_report(reports, RPT_ERROR, "Unable to read");
                goto cleanup;
        } else if (memcmp(buf, "BRUNTIME", 8)!=0) {
-               *error_r= BRE_NOT_A_BLEND;
+               BKE_report(reports, RPT_ERROR, "File is not a Blender file");
                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, path, actualsize-datastart, reports);
+               fd= -1; // file was closed in blo_read_blendafterruntime()
        }
        
 cleanup:
@@ -569,79 +171,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