Home | History | Annotate | Download | only in file
      1 /*
      2  * Copyright (c) 2009-2012 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 import java.util.ArrayList;
     37 import java.util.List;
     38 
     39 /**
     40  * A class that represents a pointer of any level that can be stored in the file.
     41  * @author Marcin Roguski
     42  */
     43 public class Pointer {
     44 
     45     /** The blender context. */
     46     private BlenderContext blenderContext;
     47     /** The level of the pointer. */
     48     private int pointerLevel;
     49     /** The address in file it points to. */
     50     private long oldMemoryAddress;
     51     /** This variable indicates if the field is a function pointer. */
     52     public boolean function;
     53 
     54     /**
     55      * Constructr. Stores the basic data about the pointer.
     56      * @param pointerLevel
     57      *        the level of the pointer
     58      * @param function
     59      *        this variable indicates if the field is a function pointer
     60      * @param blenderContext
     61      *        the repository f data; used in fetching the value that the pointer points
     62      */
     63     public Pointer(int pointerLevel, boolean function, BlenderContext blenderContext) {
     64         this.pointerLevel = pointerLevel;
     65         this.function = function;
     66         this.blenderContext = blenderContext;
     67     }
     68 
     69     /**
     70      * This method fills the pointer with its address value (it doesn't get the actual data yet. Use the 'fetch' method
     71      * for this.
     72      * @param inputStream
     73      *        the stream we read the pointer value from
     74      */
     75     public void fill(BlenderInputStream inputStream) {
     76         oldMemoryAddress = inputStream.readPointer();
     77     }
     78 
     79     /**
     80      * This method fetches the data stored under the given address.
     81      * @param inputStream
     82      *        the stream we read data from
     83      * @return the data read from the file
     84      * @throws BlenderFileException
     85      *         this exception is thrown when the blend file structure is somehow invalid or corrupted
     86      */
     87     public List<Structure> fetchData(BlenderInputStream inputStream) throws BlenderFileException {
     88         if (oldMemoryAddress == 0) {
     89             throw new NullPointerException("The pointer points to nothing!");
     90         }
     91         List<Structure> structures = null;
     92         FileBlockHeader dataFileBlock = blenderContext.getFileBlock(oldMemoryAddress);
     93         if (pointerLevel > 1) {
     94             int pointersAmount = dataFileBlock.getSize() / inputStream.getPointerSize() * dataFileBlock.getCount();
     95             for (int i = 0; i < pointersAmount; ++i) {
     96                 inputStream.setPosition(dataFileBlock.getBlockPosition() + inputStream.getPointerSize() * i);
     97                 long oldMemoryAddress = inputStream.readPointer();
     98                 if (oldMemoryAddress != 0L) {
     99                     Pointer p = new Pointer(pointerLevel - 1, this.function, blenderContext);
    100                     p.oldMemoryAddress = oldMemoryAddress;
    101                     if (structures == null) {
    102                         structures = p.fetchData(inputStream);
    103                     } else {
    104                         structures.addAll(p.fetchData(inputStream));
    105                     }
    106                 }
    107             }
    108         } else {
    109             inputStream.setPosition(dataFileBlock.getBlockPosition());
    110             structures = new ArrayList<Structure>(dataFileBlock.getCount());
    111             for (int i = 0; i < dataFileBlock.getCount(); ++i) {
    112                 Structure structure = blenderContext.getDnaBlockData().getStructure(dataFileBlock.getSdnaIndex());
    113                 structure.fill(inputStream);
    114                 structures.add(structure);
    115             }
    116             return structures;
    117         }
    118         return structures;
    119     }
    120 
    121     /**
    122      * This method indicates if this pointer points to a function.
    123      * @return <b>true</b> if this is a function pointer and <b>false</b> otherwise
    124      */
    125     public boolean isFunction() {
    126         return function;
    127     }
    128 
    129     /**
    130      * This method indicates if this is a null-pointer or not.
    131      * @return <b>true</b> if the pointer is null and <b>false</b> otherwise
    132      */
    133     public boolean isNull() {
    134         return oldMemoryAddress == 0;
    135     }
    136 
    137     /**
    138      * This method indicates if this is a null-pointer or not.
    139      * @return <b>true</b> if the pointer is not null and <b>false</b> otherwise
    140      */
    141     public boolean isNotNull() {
    142         return oldMemoryAddress != 0;
    143     }
    144 
    145     /**
    146      * This method returns the old memory address of the structure pointed by the pointer.
    147      * @return the old memory address of the structure pointed by the pointer
    148      */
    149     public long getOldMemoryAddress() {
    150         return oldMemoryAddress;
    151     }
    152 
    153     @Override
    154     public String toString() {
    155         return oldMemoryAddress == 0 ? "{$null$}" : "{$" + oldMemoryAddress + "$}";
    156     }
    157 
    158     @Override
    159     public int hashCode() {
    160         return 31 + (int) (oldMemoryAddress ^ oldMemoryAddress >>> 32);
    161     }
    162 
    163     @Override
    164     public boolean equals(Object obj) {
    165         if (this == obj) {
    166             return true;
    167         }
    168         if (obj == null) {
    169             return false;
    170         }
    171         if (this.getClass() != obj.getClass()) {
    172             return false;
    173         }
    174         Pointer other = (Pointer) obj;
    175         if (oldMemoryAddress != other.oldMemoryAddress) {
    176             return false;
    177         }
    178         return true;
    179     }
    180 }
    181