Home | History | Annotate | Download | only in file
      1 /*
      2  * Copyright (c) 2009-2010 jMonkeyEngine
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions are
      7  * met:
      8  *
      9  * * Redistributions of source code must retain the above copyright
     10  *   notice, this list of conditions and the following disclaimer.
     11  *
     12  * * Redistributions in binary form must reproduce the above copyright
     13  *   notice, this list of conditions and the following disclaimer in the
     14  *   documentation and/or other materials provided with the distribution.
     15  *
     16  * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
     17  *   may be used to endorse or promote products derived from this software
     18  *   without specific prior written permission.
     19  *
     20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31  */
     32 package com.jme3.scene.plugins.blender.file;
     33 
     34 import com.jme3.scene.plugins.blender.BlenderContext;
     35 import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
     36 
     37 /**
     38  * A class that holds the header data of a file block. The file block itself is not implemented. This class holds its
     39  * start position in the stream and using this the structure can fill itself with the proper data.
     40  * @author Marcin Roguski
     41  */
     42 public class FileBlockHeader {
     43 
     44     public static final int BLOCK_TE00 = 'T' << 24 | 'E' << 16;					//TE00
     45     public static final int BLOCK_ME00 = 'M' << 24 | 'E' << 16;					//ME00
     46     public static final int BLOCK_SR00 = 'S' << 24 | 'R' << 16;					//SR00
     47     public static final int BLOCK_CA00 = 'C' << 24 | 'A' << 16;					//CA00
     48     public static final int BLOCK_LA00 = 'L' << 24 | 'A' << 16;					//LA00
     49     public static final int BLOCK_OB00 = 'O' << 24 | 'B' << 16;					//OB00
     50     public static final int BLOCK_MA00 = 'M' << 24 | 'A' << 16;					//MA00
     51     public static final int BLOCK_SC00 = 'S' << 24 | 'C' << 16;					//SC00
     52     public static final int BLOCK_WO00 = 'W' << 24 | 'O' << 16;					//WO00
     53     public static final int BLOCK_TX00 = 'T' << 24 | 'X' << 16;					//TX00
     54     public static final int BLOCK_IP00 = 'I' << 24 | 'P' << 16;					//IP00
     55     public static final int BLOCK_AC00 = 'A' << 24 | 'C' << 16;					//AC00
     56     public static final int BLOCK_GLOB = 'G' << 24 | 'L' << 16 | 'O' << 8 | 'B';	//GLOB
     57     public static final int BLOCK_REND = 'R' << 24 | 'E' << 16 | 'N' << 8 | 'D';	//REND
     58     public static final int BLOCK_DATA = 'D' << 24 | 'A' << 16 | 'T' << 8 | 'A';	//DATA
     59     public static final int BLOCK_DNA1 = 'D' << 24 | 'N' << 16 | 'A' << 8 | '1';	//DNA1
     60     public static final int BLOCK_ENDB = 'E' << 24 | 'N' << 16 | 'D' << 8 | 'B';	//ENDB
     61     /** Identifier of the file-block [4 bytes]. */
     62     private int code;
     63     /** Total length of the data after the file-block-header [4 bytes]. */
     64     private int size;
     65     /**
     66      * Memory address the structure was located when written to disk [4 or 8 bytes (defined in file header as a pointer
     67      * size)].
     68      */
     69     private long oldMemoryAddress;
     70     /** Index of the SDNA structure [4 bytes]. */
     71     private int sdnaIndex;
     72     /** Number of structure located in this file-block [4 bytes]. */
     73     private int count;
     74     /** Start position of the block's data in the stream. */
     75     private int blockPosition;
     76 
     77     /**
     78      * Constructor. Loads the block header from the given stream during instance creation.
     79      * @param inputStream
     80      *        the stream we read the block header from
     81      * @param blenderContext
     82      *        the blender context
     83      * @throws BlenderFileException
     84      *         this exception is thrown when the pointer size is neither 4 nor 8
     85      */
     86     public FileBlockHeader(BlenderInputStream inputStream, BlenderContext blenderContext) throws BlenderFileException {
     87         inputStream.alignPosition(4);
     88         code = inputStream.readByte() << 24 | inputStream.readByte() << 16
     89                 | inputStream.readByte() << 8 | inputStream.readByte();
     90         size = inputStream.readInt();
     91         oldMemoryAddress = inputStream.readPointer();
     92         sdnaIndex = inputStream.readInt();
     93         count = inputStream.readInt();
     94         blockPosition = inputStream.getPosition();
     95         if (FileBlockHeader.BLOCK_DNA1 == code) {
     96             blenderContext.setBlockData(new DnaBlockData(inputStream, blenderContext));
     97         } else {
     98             inputStream.setPosition(blockPosition + size);
     99             blenderContext.addFileBlockHeader(Long.valueOf(oldMemoryAddress), this);
    100         }
    101     }
    102 
    103     /**
    104      * This method returns the structure described by the header filled with appropriate data.
    105      * @param blenderContext
    106      *        the blender context
    107      * @return structure filled with data
    108      * @throws BlenderFileException
    109      */
    110     public Structure getStructure(BlenderContext blenderContext) throws BlenderFileException {
    111         blenderContext.getInputStream().setPosition(blockPosition);
    112         Structure structure = blenderContext.getDnaBlockData().getStructure(sdnaIndex);
    113         structure.fill(blenderContext.getInputStream());
    114         return structure;
    115     }
    116 
    117     /**
    118      * This method returns the code of this data block.
    119      * @return the code of this data block
    120      */
    121     public int getCode() {
    122         return code;
    123     }
    124 
    125     /**
    126      * This method returns the size of the data stored in this block.
    127      * @return the size of the data stored in this block
    128      */
    129     public int getSize() {
    130         return size;
    131     }
    132 
    133     /**
    134      * This method returns the memory address.
    135      * @return the memory address
    136      */
    137     public long getOldMemoryAddress() {
    138         return oldMemoryAddress;
    139     }
    140 
    141     /**
    142      * This method returns the sdna index.
    143      * @return the sdna index
    144      */
    145     public int getSdnaIndex() {
    146         return sdnaIndex;
    147     }
    148 
    149     /**
    150      * This data returns the number of structure stored in the data block after this header.
    151      * @return the number of structure stored in the data block after this header
    152      */
    153     public int getCount() {
    154         return count;
    155     }
    156 
    157     /**
    158      * This method returns the start position of the data block in the blend file stream.
    159      * @return the start position of the data block
    160      */
    161     public int getBlockPosition() {
    162         return blockPosition;
    163     }
    164 
    165     /**
    166      * This method indicates if the block is the last block in the file.
    167      * @return true if this block is the last one in the file nad false otherwise
    168      */
    169     public boolean isLastBlock() {
    170         return FileBlockHeader.BLOCK_ENDB == code;
    171     }
    172 
    173     /**
    174      * This method indicates if the block is the SDNA block.
    175      * @return true if this block is the SDNA block and false otherwise
    176      */
    177     public boolean isDnaBlock() {
    178         return FileBlockHeader.BLOCK_DNA1 == code;
    179     }
    180 
    181     @Override
    182     public String toString() {
    183         return "FILE BLOCK HEADER [" + this.codeToString(code) + " : " + size + " : " + oldMemoryAddress + " : " + sdnaIndex + " : " + count + "]";
    184     }
    185 
    186     /**
    187      * This method transforms the coded bloch id into a string value.
    188      * @param code
    189      *        the id of the block
    190      * @return the string value of the block id
    191      */
    192     protected String codeToString(int code) {
    193         char c1 = (char) ((code & 0xFF000000) >> 24);
    194         char c2 = (char) ((code & 0xFF0000) >> 16);
    195         char c3 = (char) ((code & 0xFF00) >> 8);
    196         char c4 = (char) (code & 0xFF);
    197         return String.valueOf(c1) + c2 + c3 + c4;
    198     }
    199 }
    200