CacheReader.java :  » IDE-Netbeans » performance » org » netbeans » imagecache » Java Open Source

Java Open Source » IDE Netbeans » performance 
performance » org » netbeans » imagecache » CacheReader.java
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common
 * Development and Distribution License("CDDL") (collectively, the
 * "License"). You may not use this file except in compliance with the
 * License. You can obtain a copy of the License at
 * http://www.netbeans.org/cddl-gplv2.html
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
 * specific language governing permissions and limitations under the
 * License.  When distributing the software, include this License Header
 * Notice in each file and include the License file at
 * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the GPL Version 2 section of the License file that
 * accompanied this code. If applicable, add the following below the
 * License Header, with the fields enclosed by brackets [] replaced by
 * your own identifying information:
 * "Portions Copyrighted [year] [name of copyright owner]"
 *
 * Contributor(s):
 *
 * The Original Software is NetBeans. The Initial Developer of the Original
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
 * Microsystems, Inc. All Rights Reserved.
 *
 * If you wish your version of this file to be governed by only the CDDL
 * or only the GPL Version 2, indicate your decision by adding
 * "[Contributor] elects to include this software in this distribution
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
 * single choice of license, a recipient has the option to distribute
 * your version of this file under either the CDDL, the GPL Version 2 or
 * to extend the choice of license to its licensees as provided above.
 * However, if you add GPL Version 2 code and therefore, elected the GPL
 * Version 2 license, then the option applies only if the new code is
 * made subject to such option by the copyright holder.
 *//*
 * CacheReader.java
 *
 * Created on February 16, 2004, 8:11 PM
 */

package org.netbeans.imagecache;

import java.awt.Image;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.nio.LongBuffer;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Arrays;

/**
 *
 * @author  Tim Boudreau
 */
public class CacheReader {
    static final String filename = CacheWriter.filename;
    static final int METAENTRY_LENGTH = CacheWriter.METAENTRY_LENGTH;
    static final int ID_OFFSET = CacheWriter.ID_OFFSET;
    private File cachefile;
    private File metafile;
    private ByteBuffer cachebuffer = null;
    private ByteBuffer metabuffer = null;

    
    /** Creates a new instance of CacheReader */
    public CacheReader(File cacheDir) throws IOException {
        this (new File(cacheDir + File.separator + filename + ".cache"), 
            new File(cacheDir + File.separator + filename + ".metadata"));
    }
    
    public CacheReader(File cachefile, File metafile) throws IOException {
        if (!cachefile.exists() || !metafile.exists()) {
            throw new IOException ("Cache does not exist: " + cachefile + "," + metafile);
        }
        this.cachefile = cachefile;
        this.metafile = metafile;
    }
    
    public String[] getIDs() throws IOException {
        ArrayList a = new ArrayList();
        ByteBuffer b = getMetaBuffer().asReadOnlyBuffer();
        int max = b.limit() / METAENTRY_LENGTH;
        for (int i=0; i < max; i++) {
            int len = b.asIntBuffer().get();
            b.mark();
            b.position(b.position() + ID_OFFSET);
            byte[] bytes = new byte[len];
            b.get(bytes);
            a.add(new String(bytes));
            b.reset();
            if (i != max-1) {
                b.position(b.position() + METAENTRY_LENGTH);
            }
        }
        String[] result = new String[a.size()];
        result = (String[]) a.toArray(result);
        return result;
    }
    
    public Image find (String id) throws IOException {
        ByteBuffer buf = findMetadataFor (toByteArray(id));
        if (buf == null) {
            return null;
        }
        
        IntBuffer ibuf = buf.asIntBuffer();
        
        int[] intEntries = new int[3];
        ibuf.get(intEntries);
        
        assert id.length() == intEntries[0];
        
        int width = intEntries[1];
        int height = intEntries[2];
        
        long[] longEntries = new long[2];

        buf.position(buf.position() + 12);
        
        LongBuffer lbuf = buf.asLongBuffer();
        lbuf.get(longEntries);
        
        //The cast to int is safe, the writer will never write a cache file
        //bigger than Integer.MAX_VALUE
        int start = (int) longEntries[0];
        int end = (int) longEntries[1];
        
        ByteBuffer cache = getBuffer().asReadOnlyBuffer();
        cache.position(start);
        
        System.err.println("Cache position is " + cache.position());
        IntBuffer databuffer = cache.asIntBuffer();
        System.err.println("IntBuffer position is " + databuffer.position());
        return createImageFrom (databuffer, width, height);
    }
    
    /*
    private Image createImageFrom (IntBuffer data, int width, int height) {
        //Cheap'n'cheesy for now - should really create a custom DataSource which
        //reads the buffer for its pixel data
        
        BufferedImage bi = new BufferedImage (width, height, BufferedImage.TYPE_INT_ARGB);
        for (int x=0; x < width; x++) {
            for (int y=0; y < height; y++) {
                try {
                    bi.setRGB (x, y, data.get());
                } catch (Exception e) {
                    System.err.println("Exception getting " + x + "," + y + " pos:" + data.position());
                }
            }
        }
        return bi;
    }
     */
    
    private Image createImageFrom (IntBuffer data, int width, int height) {
        CRaster raster = new CRaster (data, width, height);
        return new CImage (ColorModel.getRGBdefault(), raster, false, null);
    }
    
    /** Locates metadata related to the passed id (converted into a byte
     * array).  Returns either a bytebuffer with the position set to the
     * start of the metadata or null.  */
    private ByteBuffer findMetadataFor (byte[] id) throws IOException {
        System.err.println("FindMetadataFor " + new String(id));
        
        long result = -1;
        //Get a buffer clone so we don't have threading problems - never
        //use the master buffer
        ByteBuffer buf = getMetaBuffer().asReadOnlyBuffer();
        
        IntBuffer ibuf = buf.asIntBuffer();
        
        do {
           //First, see if the ID (image filename) length matches the ID
           //we received - if it doesn't, no need to examine the record
           int thisIdLength = ibuf.get();
           System.err.println("pos:" + ibuf.position() + " idLen: " + thisIdLength + " looking for len: " + id.length);
           
           if (thisIdLength == id.length) {
               //Mark the start of this metadata record and position to
               //the start of the ID entry
               System.err.println("Length match. Putting mark at " + (buf.position()) + " and moving to " + (buf.position() + ID_OFFSET) + " to check data");
               buf.mark().position (buf.position() + ID_OFFSET);
               
               byte[] chars = new byte[id.length];
               
               //Fetch the ID into the array, and reset the buffer position
               //for either returning or skipping to the next record
               buf.get(chars).reset();
               System.err.println(" id from metadata: " + new String(chars));
               
               //Compare it with the id we were passed
               if (Arrays.equals(chars, id)) {
                   System.err.println("  MATCHED - position: " + buf.position());
                   return buf;
               }
           }
           //Skip ahead to the next record
           buf.position(buf.position() + METAENTRY_LENGTH);
           ibuf.position(buf.position() / 4);
           System.err.println("Buffer pos: " + buf.position() + " ibuf: " + ibuf.position());
        } while (buf.position() <= buf.limit() - METAENTRY_LENGTH);
        
        return null;
    }
    
    private static byte[] toByteArray(String s) {
        char[] c = s.toCharArray();
        byte[] result = new byte[c.length];
        for (int i=0; i < c.length; i++) {
            result[i] = (byte) c[i];
        }
        return result;
    }
    
    protected ByteBuffer createBuffer(File file) throws IOException {
        return new FileInputStream (file).getChannel().map(
            FileChannel.MapMode.READ_ONLY, 0, file.length());
    }
    
    private ByteBuffer getBuffer() throws IOException {
        if (cachebuffer == null) {
            cachebuffer = createBuffer(cachefile);
        }
        cachebuffer.position(0);
        return cachebuffer;
    }
    
    private ByteBuffer getMetaBuffer() throws IOException {
        if (metabuffer == null) {
            metabuffer = createBuffer(metafile);
        }
        return metabuffer;
    }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.