⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pstcache.java

📁 cygwin 是一个在windows平台上运行的unix模拟环境
💻 JAVA
字号:
/* PstCache.java
 * Component: ProperJavaRDP
 * 
 * Revision: $Revision: 1.4 $
 * Author: $Author: telliott $
 * Date: $Date: 2005/09/27 14:15:39 $
 *
 * Copyright (c) 2005 Propero Limited
 *
 * Purpose: Handle persistent caching
 *
 * 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.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
 * 
 * (See gpl.txt for details of the GNU General Public License.)
 * 
 */

package net.propero.rdp;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.log4j.Logger;

public class PstCache {

    protected static Logger logger = Logger.getLogger(Rdp.class);
    
    public static final int MAX_CELL_SIZE = 0x1000;  /* pixels */

    protected static boolean IS_PERSISTENT(int id){
        return (id < 8 && g_pstcache_fd[id] != null);
    }

    static int g_stamp;
    static File[] g_pstcache_fd = new File[8];
    static int g_pstcache_Bpp;
    static boolean g_pstcache_enumerated = false;

    /* Update usage info for a bitmap */
    protected static void touchBitmap(int cache_id, int cache_idx, int stamp)
    {
        logger.info("PstCache.touchBitmap");
    FileOutputStream fd;

    if (!IS_PERSISTENT(cache_id) || cache_idx >= Rdp.BMPCACHE2_NUM_PSTCELLS)
        return;

    try {
        fd = new FileOutputStream(g_pstcache_fd[cache_id]);
        
        fd.write(toBigEndian32(stamp), 12 + cache_idx * (g_pstcache_Bpp * MAX_CELL_SIZE + CELLHEADER.size()),4);
        //rd_lseek_file(fd, 12 + cache_idx * (g_pstcache_Bpp * MAX_CELL_SIZE + sizeof(CELLHEADER))); // this seems to do nothing (return 0) in rdesktop
        //rd_write_file(fd, &stamp, sizeof(stamp)); // same with this one???

    } catch (IOException e) {
        return;
    }
 }
    
    private static byte[] toBigEndian32(int value){
        byte[] out = new byte[4];
        out[0] = (byte) (value & 0xFF);
        out[1] = (byte) (value & 0xFF00);
        out[2] = (byte) (value & 0xFF0000);
        out[3] = (byte) (value & 0xFF000000);
        return out;
    }

 /* Load a bitmap from the persistent cache */
 static boolean pstcache_load_bitmap(int cache_id, int cache_idx) throws IOException, RdesktopException
 {
     logger.info("PstCache.pstcache_load_bitmap");
    byte[] celldata = null;
    FileInputStream fd;
    //CELLHEADER cellhdr;
    Bitmap bitmap;
    byte[] cellHead = null;
    
    if (!Options.persistent_bitmap_caching)
        return false;

    if (!IS_PERSISTENT(cache_id) || cache_idx >= Rdp.BMPCACHE2_NUM_PSTCELLS)
        return false;

        fd = new FileInputStream(g_pstcache_fd[cache_id]);
        int offset = cache_idx * (g_pstcache_Bpp * MAX_CELL_SIZE + CELLHEADER.size());
        fd.read(cellHead, offset, CELLHEADER.size());
        CELLHEADER c = new CELLHEADER(cellHead);
        //rd_lseek_file(fd, cache_idx * (g_pstcache_Bpp * MAX_CELL_SIZE + sizeof(CELLHEADER)));
        //rd_read_file(fd, &cellhdr, sizeof(CELLHEADER));
        //celldata = (uint8 *) xmalloc(cellhdr.length);
        //rd_read_file(fd, celldata, cellhdr.length);
        celldata = new byte[c.length];
        fd.read(celldata);
        logger.debug("Loading bitmap from disk (" + cache_id + ":" + cache_idx + ")\n");

        bitmap = new Bitmap(celldata,c.width,c.height,0,0,Options.Bpp);
        //bitmap = ui_create_bitmap(cellhdr.width, cellhdr.height, celldata);
        Orders.cache.putBitmap(cache_id,cache_idx,bitmap,c.stamp);

    //xfree(celldata);
    return true;
 }

 /* Store a bitmap in the persistent cache */
 static boolean pstcache_put_bitmap(int cache_id, int cache_idx, byte[] bitmap_id, int width, int height, int length, byte[] data) throws IOException
 {
     logger.info("PstCache.pstcache_put_bitmap");
    FileOutputStream fd;
    CELLHEADER cellhdr = new CELLHEADER();

    if (!IS_PERSISTENT(cache_id) || cache_idx >= Rdp.BMPCACHE2_NUM_PSTCELLS)
        return false;

    cellhdr.bitmap_id = bitmap_id;
    //memcpy(cellhdr.bitmap_id, bitmap_id, 8/* sizeof(BITMAP_ID) */);
    
    cellhdr.width = width;
    cellhdr.height = height;
    cellhdr.length = length;
    cellhdr.stamp = 0;

        fd = new FileOutputStream(g_pstcache_fd[cache_id]);
        int offset = cache_idx * (Options.Bpp * MAX_CELL_SIZE + CELLHEADER.size());
        fd.write(cellhdr.toBytes(),offset,CELLHEADER.size());
        fd.write(data);
        //rd_lseek_file(fd, cache_idx * (g_pstcache_Bpp * MAX_CELL_SIZE + sizeof(CELLHEADER)));
        //rd_write_file(fd, &cellhdr, sizeof(CELLHEADER));
        //rd_write_file(fd, data, length);
    return true;
 }

 /* list the bitmaps from the persistent cache file */
 static int pstcache_enumerate(int cache_id, int[] idlist) throws IOException, RdesktopException
 {
     logger.info("PstCache.pstcache_enumerate");
    FileInputStream fd;
    int n, c = 0;
    CELLHEADER cellhdr = null;

    if (!(Options.bitmap_caching && Options.persistent_bitmap_caching && IS_PERSISTENT(cache_id)))
        return 0;

    /* The server disconnects if the bitmap cache content is sent more than once */
    if (g_pstcache_enumerated)
        return 0;

    logger.debug("pstcache enumeration... ");
    for (n = 0; n < Rdp.BMPCACHE2_NUM_PSTCELLS; n++)
    {
        fd = new FileInputStream(g_pstcache_fd[cache_id]);
        
        byte[] cellhead_data = new byte[CELLHEADER.size()];
        if (fd.read(cellhead_data,n * (g_pstcache_Bpp * MAX_CELL_SIZE + CELLHEADER.size()), CELLHEADER.size()) <= 0)
            break;

        cellhdr = new CELLHEADER(cellhead_data);
        
        int result = 0;
        for(int i = 0; i < cellhdr.bitmap_id.length; i++){
            result += cellhdr.bitmap_id[i];
        }
        
        if (result != 0)
        {
            for(int i = 0; i < 8; i++){
                idlist[(n * 8) + i] = cellhdr.bitmap_id[i];
            }


            if (cellhdr.stamp != 0)
            {
                /* Pre-caching is not possible with 8bpp because a colourmap
                 * is needed to load them */
                if (Options.precache_bitmaps && (Options.server_bpp > 8))
                {
                    if (pstcache_load_bitmap(cache_id, n))
                        c++;
                }

                g_stamp = Math.max(g_stamp, cellhdr.stamp);
            }
        }
        else
        {
            break;
        }
    }

    logger.info(n + " bitmaps in persistent cache, " + c + " bitmaps loaded in memory\n");
    g_pstcache_enumerated = true;
    return n;
 }

 /* initialise the persistent bitmap cache */
 static boolean pstcache_init(int cache_id)
 {
    //int fd;
    String filename;

    if (g_pstcache_enumerated)
        return true;

    g_pstcache_fd[cache_id] = null;

    if (!(Options.bitmap_caching && Options.persistent_bitmap_caching))
        return false;

    g_pstcache_Bpp = Options.Bpp;
    filename = "./cache/pstcache_" + cache_id + "_" + g_pstcache_Bpp;
    logger.debug("persistent bitmap cache file: " + filename);
    
    File cacheDir = new File("./cache/");
    if(!cacheDir.exists() && !cacheDir.mkdir()){
        logger.warn("failed to get/make cache directory");
        return false;
    }
    
    File f = new File(filename);
    
    try {
        if(!f.exists() && !f.createNewFile()){
            logger.warn("Could not create cache file");
            return false;
        }
    } catch (IOException e) {
        return false;
    }

   /* if (!rd_lock_file(fd, 0, 0))
    {
        logger.warn("Persistent bitmap caching is disabled. (The file is already in use)\n");
        rd_close_file(fd);
        return false;
    }*/

    g_pstcache_fd[cache_id] = f;
    return true;
 }
 
 
}

/* Header for an entry in the persistent bitmap cache file */
class CELLHEADER
{
   byte[] bitmap_id = new byte[8]; // int8 *
   int width, height; // int8
   int length; // int16
   int stamp; // int32
   static int size(){
       return 8*8 + 8*2 + 16 + 32;
   }
   
   public CELLHEADER(){
       
   }
   
   public CELLHEADER(byte[] data){
       for(int i = 0; i < bitmap_id.length; i++) bitmap_id[i] = data[i];
       
       width = data[bitmap_id.length];
       height = data[bitmap_id.length + 1];
       length = (data[bitmap_id.length + 2] >> 8) + data[bitmap_id.length + 3];
       stamp = (data[bitmap_id.length + 6] >> 24) + (data[bitmap_id.length + 6] >> 16) +(data[bitmap_id.length + 6] >> 8) + data[bitmap_id.length + 7];
   }
   
   public byte[] toBytes(){
       return null;
   }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -