/[rdesktop]/sourceforge.net/trunk/rdesktop/pstcache.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /sourceforge.net/trunk/rdesktop/pstcache.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 808 - (hide annotations)
Sat Dec 25 13:37:08 2004 UTC (19 years, 6 months ago) by jdmeijer
File MIME type: text/plain
File size: 5159 byte(s)
fix huge persistent cache files bug

1 jsorg71 725 /*
2     rdesktop: A Remote Desktop Protocol client.
3     Persistent Bitmap Cache routines
4     Copyright (C) Jeroen Meijer 2004
5    
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10    
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     GNU General Public License for more details.
15    
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19     */
20    
21     #include "rdesktop.h"
22    
23 astrand 738 #define MAX_CELL_SIZE 0x1000 /* pixels */
24 jsorg71 725
25 jdmeijer 808 #define IS_PERSISTENT(id) (id < 8 && g_pstcache_fd[id] > 0)
26 jsorg71 725
27     extern int g_server_bpp;
28     extern uint32 g_stamp;
29     extern BOOL g_bitmap_cache;
30     extern BOOL g_bitmap_cache_persist_enable;
31     extern BOOL g_bitmap_cache_precache;
32    
33     int g_pstcache_fd[8];
34     int g_pstcache_Bpp;
35     BOOL g_pstcache_enumerated = False;
36 astrand 738 uint8 zero_id[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
37 jsorg71 725
38    
39     /* Update usage info for a bitmap */
40     void
41     pstcache_touch_bitmap(uint8 cache_id, uint16 cache_idx, uint32 stamp)
42     {
43     int fd;
44    
45 jdmeijer 808 if (!IS_PERSISTENT(cache_id) || cache_idx >= BMPCACHE2_NUM_PSTCELLS)
46 jsorg71 725 return;
47    
48     fd = g_pstcache_fd[cache_id];
49     rd_lseek_file(fd, 12 + cache_idx * (g_pstcache_Bpp * MAX_CELL_SIZE + sizeof(CELLHEADER)));
50     rd_write_file(fd, &stamp, sizeof(stamp));
51     }
52    
53     /* Load a bitmap from the persistent cache */
54     BOOL
55     pstcache_load_bitmap(uint8 cache_id, uint16 cache_idx)
56     {
57     uint8 *celldata;
58     int fd;
59     CELLHEADER cellhdr;
60     HBITMAP bitmap;
61    
62 jdmeijer 808 if (!g_bitmap_cache_persist_enable)
63 jsorg71 725 return False;
64    
65 jdmeijer 808 if (!IS_PERSISTENT(cache_id) || cache_idx >= BMPCACHE2_NUM_PSTCELLS)
66     return False;
67    
68 jsorg71 725 fd = g_pstcache_fd[cache_id];
69     rd_lseek_file(fd, cache_idx * (g_pstcache_Bpp * MAX_CELL_SIZE + sizeof(CELLHEADER)));
70     rd_read_file(fd, &cellhdr, sizeof(CELLHEADER));
71 astrand 738 celldata = (uint8 *) xmalloc(cellhdr.length);
72 jsorg71 725 rd_read_file(fd, celldata, cellhdr.length);
73    
74     DEBUG(("Loading bitmap from disk (%d:%d)\n", cache_id, cache_idx));
75    
76     bitmap = ui_create_bitmap(cellhdr.width, cellhdr.height, celldata);
77     cache_put_bitmap(cache_id, cache_idx, bitmap, cellhdr.stamp);
78    
79     xfree(celldata);
80     return True;
81     }
82    
83     /* Store a bitmap in the persistent cache */
84     BOOL
85 astrand 738 pstcache_put_bitmap(uint8 cache_id, uint16 cache_idx, uint8 * bitmap_id,
86     uint16 width, uint16 height, uint16 length, uint8 * data)
87 jsorg71 725 {
88     int fd;
89     CELLHEADER cellhdr;
90    
91 jdmeijer 808 if (!IS_PERSISTENT(cache_id) || cache_idx >= BMPCACHE2_NUM_PSTCELLS)
92 jsorg71 725 return False;
93    
94     memcpy(cellhdr.bitmap_id, bitmap_id, sizeof(BITMAP_ID));
95     cellhdr.width = width;
96     cellhdr.height = height;
97     cellhdr.length = length;
98     cellhdr.stamp = 0;
99    
100     fd = g_pstcache_fd[cache_id];
101     rd_lseek_file(fd, cache_idx * (g_pstcache_Bpp * MAX_CELL_SIZE + sizeof(CELLHEADER)));
102     rd_write_file(fd, &cellhdr, sizeof(CELLHEADER));
103     rd_write_file(fd, data, length);
104    
105     return True;
106     }
107    
108     /* list the bitmaps from the persistent cache file */
109     int
110 astrand 738 pstcache_enumerate(uint8 cache_id, uint8 * idlist)
111 jsorg71 725 {
112     int fd, n, c = 0;
113     CELLHEADER cellhdr;
114    
115     if (!(g_bitmap_cache && g_bitmap_cache_persist_enable && IS_PERSISTENT(cache_id)))
116     return 0;
117    
118     /* The server disconnects if the bitmap cache content is sent more than once */
119     if (g_pstcache_enumerated)
120     return 0;
121    
122     DEBUG(("pstcache enumeration... "));
123     for (n = 0; n < BMPCACHE2_NUM_PSTCELLS; n++)
124     {
125     fd = g_pstcache_fd[cache_id];
126     rd_lseek_file(fd, n * (g_pstcache_Bpp * MAX_CELL_SIZE + sizeof(CELLHEADER)));
127     if (rd_read_file(fd, &cellhdr, sizeof(CELLHEADER)) <= 0)
128     break;
129    
130     if (memcmp(cellhdr.bitmap_id, zero_id, sizeof(BITMAP_ID)) != 0)
131     {
132     memcpy(idlist + n * sizeof(BITMAP_ID), cellhdr.bitmap_id,
133 astrand 738 sizeof(BITMAP_ID));
134 jsorg71 725
135     if (cellhdr.stamp)
136     {
137     /* Pre-caching is not possible with 8bpp because a colourmap
138     * is needed to load them */
139     if (g_bitmap_cache_precache && (g_server_bpp > 8))
140     {
141     if (pstcache_load_bitmap(cache_id, n))
142     c++;
143     }
144    
145     g_stamp = MAX(g_stamp, cellhdr.stamp);
146     }
147     }
148     else
149     {
150     break;
151     }
152     }
153    
154     DEBUG(("%d bitmaps in persistent cache, %d bitmaps loaded in memory\n", n, c));
155     g_pstcache_enumerated = True;
156     return n;
157     }
158    
159     /* initialise the persistent bitmap cache */
160     BOOL
161     pstcache_init(uint8 cache_id)
162     {
163     int fd;
164     char filename[256];
165    
166     if (g_pstcache_enumerated)
167     return True;
168    
169     g_pstcache_fd[cache_id] = 0;
170    
171     if (!(g_bitmap_cache && g_bitmap_cache_persist_enable))
172     return False;
173    
174     if (!rd_pstcache_mkdir())
175     {
176     DEBUG(("failed to get/make cache directory!\n"));
177     return False;
178     }
179    
180     g_pstcache_Bpp = (g_server_bpp + 7) / 8;
181     sprintf(filename, "cache/pstcache_%d_%d", cache_id, g_pstcache_Bpp);
182     DEBUG(("persistent bitmap cache file: %s\n", filename));
183    
184     fd = rd_open_file(filename);
185     if (fd == -1)
186     return False;
187    
188     if (!rd_lock_file(fd, 0, 0))
189     {
190     warning("Persistent bitmap caching is disabled. (The file is already in use)\n");
191     rd_close_file(fd);
192     return False;
193     }
194    
195     g_pstcache_fd[cache_id] = fd;
196     return True;
197     }

  ViewVC Help
Powered by ViewVC 1.1.26