aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-01-05 13:59:05 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-01-05 13:59:05 +0000
commit98b8e9487dc40100d8031136f2241a66ce9dffb0 (patch)
tree0cfd892118648205ff3762330f37a0fc6dfaf085
parent89d49a42362f342d643503a40625e1cb70b7ee7f (diff)
downloadbusybox-w32-98b8e9487dc40100d8031136f2241a66ce9dffb0.tar.gz
busybox-w32-98b8e9487dc40100d8031136f2241a66ce9dffb0.tar.bz2
busybox-w32-98b8e9487dc40100d8031136f2241a66ce9dffb0.zip
simplify access to buffer, making code a bit smaller
-rw-r--r--archival/libunarchive/decompress_unlzma.c170
1 files changed, 90 insertions, 80 deletions
diff --git a/archival/libunarchive/decompress_unlzma.c b/archival/libunarchive/decompress_unlzma.c
index a6902807b..c1b0a3118 100644
--- a/archival/libunarchive/decompress_unlzma.c
+++ b/archival/libunarchive/decompress_unlzma.c
@@ -22,7 +22,7 @@
22typedef struct { 22typedef struct {
23 int fd; 23 int fd;
24 uint8_t *ptr; 24 uint8_t *ptr;
25 uint8_t *buffer; 25// uint8_t *buffer;
26 uint8_t *buffer_end; 26 uint8_t *buffer_end;
27 int buffer_size; 27 int buffer_size;
28 uint32_t code; 28 uint32_t code;
@@ -30,6 +30,8 @@ typedef struct {
30 uint32_t bound; 30 uint32_t bound;
31} rc_t; 31} rc_t;
32 32
33//#define RC_BUFFER ((uint8_t*)(void*)(rc+1))
34#define RC_BUFFER ((uint8_t*)(rc+1))
33 35
34#define RC_TOP_BITS 24 36#define RC_TOP_BITS 24
35#define RC_MOVE_BITS 5 37#define RC_MOVE_BITS 5
@@ -39,22 +41,24 @@ typedef struct {
39/* Called twice: once at startup and once in rc_normalize() */ 41/* Called twice: once at startup and once in rc_normalize() */
40static void rc_read(rc_t * rc) 42static void rc_read(rc_t * rc)
41{ 43{
42 rc->buffer_size = read(rc->fd, rc->buffer, rc->buffer_size); 44 rc->buffer_size = read(rc->fd, RC_BUFFER, rc->buffer_size);
43 if (rc->buffer_size <= 0) 45 if (rc->buffer_size <= 0)
44 bb_error_msg_and_die("unexpected EOF"); 46 bb_error_msg_and_die("unexpected EOF");
45 rc->ptr = rc->buffer; 47 rc->ptr = RC_BUFFER;
46 rc->buffer_end = rc->buffer + rc->buffer_size; 48 rc->buffer_end = RC_BUFFER + rc->buffer_size;
47} 49}
48 50
49/* Called once */ 51/* Called once */
50static void rc_init(rc_t * rc, int fd, int buffer_size) 52static rc_t* rc_init(int fd, int buffer_size)
51{ 53{
52 int i; 54 int i;
55 rc_t* rc;
56
57 rc = xmalloc(sizeof(rc_t) + buffer_size);
53 58
54 rc->fd = fd; 59 rc->fd = fd;
55 rc->buffer = xmalloc(buffer_size);
56 rc->buffer_size = buffer_size; 60 rc->buffer_size = buffer_size;
57 rc->buffer_end = rc->buffer + rc->buffer_size; 61 rc->buffer_end = RC_BUFFER + rc->buffer_size;
58 rc->ptr = rc->buffer_end; 62 rc->ptr = rc->buffer_end;
59 63
60 rc->code = 0; 64 rc->code = 0;
@@ -64,13 +68,14 @@ static void rc_init(rc_t * rc, int fd, int buffer_size)
64 rc_read(rc); 68 rc_read(rc);
65 rc->code = (rc->code << 8) | *rc->ptr++; 69 rc->code = (rc->code << 8) | *rc->ptr++;
66 } 70 }
71 return rc;
67} 72}
68 73
69/* Called once. TODO: bb_maybe_free() */ 74/* Called once */
70static ATTRIBUTE_ALWAYS_INLINE void rc_free(rc_t * rc) 75static ATTRIBUTE_ALWAYS_INLINE void rc_free(rc_t * rc)
71{ 76{
72 if (ENABLE_FEATURE_CLEAN_UP) 77 if (ENABLE_FEATURE_CLEAN_UP)
73 free(rc->buffer); 78 free(rc);
74} 79}
75 80
76/* Called twice, but one callsite is in speed_inline'd rc_is_bit_0_helper() */ 81/* Called twice, but one callsite is in speed_inline'd rc_is_bit_0_helper() */
@@ -163,53 +168,58 @@ typedef struct {
163} __attribute__ ((packed)) lzma_header_t; 168} __attribute__ ((packed)) lzma_header_t;
164 169
165 170
166#define LZMA_BASE_SIZE 1846 171/* #defines will make compiler to compute/optimize each one with each usage.
167#define LZMA_LIT_SIZE 768 172 * Have heart and use enum instead. */
173enum {
174 LZMA_BASE_SIZE = 1846,
175 LZMA_LIT_SIZE = 768,
176
177 LZMA_NUM_POS_BITS_MAX = 4,
168 178
169#define LZMA_NUM_POS_BITS_MAX 4 179 LZMA_LEN_NUM_LOW_BITS = 3,
180 LZMA_LEN_NUM_MID_BITS = 3,
181 LZMA_LEN_NUM_HIGH_BITS = 8,
170 182
171#define LZMA_LEN_NUM_LOW_BITS 3 183 LZMA_LEN_CHOICE = 0,
172#define LZMA_LEN_NUM_MID_BITS 3 184 LZMA_LEN_CHOICE_2 = (LZMA_LEN_CHOICE + 1),
173#define LZMA_LEN_NUM_HIGH_BITS 8 185 LZMA_LEN_LOW = (LZMA_LEN_CHOICE_2 + 1),
186 LZMA_LEN_MID = (LZMA_LEN_LOW \
187 + (1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_LOW_BITS))),
188 LZMA_LEN_HIGH = (LZMA_LEN_MID \
189 + (1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_MID_BITS))),
190 LZMA_NUM_LEN_PROBS = (LZMA_LEN_HIGH + (1 << LZMA_LEN_NUM_HIGH_BITS)),
174 191
175#define LZMA_LEN_CHOICE 0 192 LZMA_NUM_STATES = 12,
176#define LZMA_LEN_CHOICE_2 (LZMA_LEN_CHOICE + 1) 193 LZMA_NUM_LIT_STATES = 7,
177#define LZMA_LEN_LOW (LZMA_LEN_CHOICE_2 + 1)
178#define LZMA_LEN_MID (LZMA_LEN_LOW \
179 + (1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_LOW_BITS)))
180#define LZMA_LEN_HIGH (LZMA_LEN_MID \
181 +(1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_MID_BITS)))
182#define LZMA_NUM_LEN_PROBS (LZMA_LEN_HIGH + (1 << LZMA_LEN_NUM_HIGH_BITS))
183 194
184#define LZMA_NUM_STATES 12 195 LZMA_START_POS_MODEL_INDEX = 4,
185#define LZMA_NUM_LIT_STATES 7 196 LZMA_END_POS_MODEL_INDEX = 14,
197 LZMA_NUM_FULL_DISTANCES = (1 << (LZMA_END_POS_MODEL_INDEX >> 1)),
186 198
187#define LZMA_START_POS_MODEL_INDEX 4 199 LZMA_NUM_POS_SLOT_BITS = 6,
188#define LZMA_END_POS_MODEL_INDEX 14 200 LZMA_NUM_LEN_TO_POS_STATES = 4,
189#define LZMA_NUM_FULL_DISTANCES (1 << (LZMA_END_POS_MODEL_INDEX >> 1))
190 201
191#define LZMA_NUM_POS_SLOT_BITS 6 202 LZMA_NUM_ALIGN_BITS = 4,
192#define LZMA_NUM_LEN_TO_POS_STATES 4
193 203
194#define LZMA_NUM_ALIGN_BITS 4 204 LZMA_MATCH_MIN_LEN = 2,
195 205
196#define LZMA_MATCH_MIN_LEN 2 206 LZMA_IS_MATCH = 0,
207 LZMA_IS_REP = (LZMA_IS_MATCH + (LZMA_NUM_STATES << LZMA_NUM_POS_BITS_MAX)),
208 LZMA_IS_REP_G0 = (LZMA_IS_REP + LZMA_NUM_STATES),
209 LZMA_IS_REP_G1 = (LZMA_IS_REP_G0 + LZMA_NUM_STATES),
210 LZMA_IS_REP_G2 = (LZMA_IS_REP_G1 + LZMA_NUM_STATES),
211 LZMA_IS_REP_0_LONG = (LZMA_IS_REP_G2 + LZMA_NUM_STATES),
212 LZMA_POS_SLOT = (LZMA_IS_REP_0_LONG \
213 + (LZMA_NUM_STATES << LZMA_NUM_POS_BITS_MAX)),
214 LZMA_SPEC_POS = (LZMA_POS_SLOT \
215 + (LZMA_NUM_LEN_TO_POS_STATES << LZMA_NUM_POS_SLOT_BITS)),
216 LZMA_ALIGN = (LZMA_SPEC_POS \
217 + LZMA_NUM_FULL_DISTANCES - LZMA_END_POS_MODEL_INDEX),
218 LZMA_LEN_CODER = (LZMA_ALIGN + (1 << LZMA_NUM_ALIGN_BITS)),
219 LZMA_REP_LEN_CODER = (LZMA_LEN_CODER + LZMA_NUM_LEN_PROBS),
220 LZMA_LITERAL = (LZMA_REP_LEN_CODER + LZMA_NUM_LEN_PROBS),
221};
197 222
198#define LZMA_IS_MATCH 0
199#define LZMA_IS_REP (LZMA_IS_MATCH + (LZMA_NUM_STATES <<LZMA_NUM_POS_BITS_MAX))
200#define LZMA_IS_REP_G0 (LZMA_IS_REP + LZMA_NUM_STATES)
201#define LZMA_IS_REP_G1 (LZMA_IS_REP_G0 + LZMA_NUM_STATES)
202#define LZMA_IS_REP_G2 (LZMA_IS_REP_G1 + LZMA_NUM_STATES)
203#define LZMA_IS_REP_0_LONG (LZMA_IS_REP_G2 + LZMA_NUM_STATES)
204#define LZMA_POS_SLOT (LZMA_IS_REP_0_LONG \
205 + (LZMA_NUM_STATES << LZMA_NUM_POS_BITS_MAX))
206#define LZMA_SPEC_POS (LZMA_POS_SLOT \
207 +(LZMA_NUM_LEN_TO_POS_STATES << LZMA_NUM_POS_SLOT_BITS))
208#define LZMA_ALIGN (LZMA_SPEC_POS \
209 + LZMA_NUM_FULL_DISTANCES - LZMA_END_POS_MODEL_INDEX)
210#define LZMA_LEN_CODER (LZMA_ALIGN + (1 << LZMA_NUM_ALIGN_BITS))
211#define LZMA_REP_LEN_CODER (LZMA_LEN_CODER + LZMA_NUM_LEN_PROBS)
212#define LZMA_LITERAL (LZMA_REP_LEN_CODER + LZMA_NUM_LEN_PROBS)
213 223
214USE_DESKTOP(long long) int 224USE_DESKTOP(long long) int
215unlzma(int src_fd, int dst_fd) 225unlzma(int src_fd, int dst_fd)
@@ -225,7 +235,7 @@ unlzma(int src_fd, int dst_fd)
225 uint16_t *prob_lit; 235 uint16_t *prob_lit;
226 int num_bits; 236 int num_bits;
227 int num_probs; 237 int num_probs;
228 rc_t rc; 238 rc_t *rc;
229 int i, mi; 239 int i, mi;
230 uint8_t *buffer; 240 uint8_t *buffer;
231 uint8_t previous_byte = 0; 241 uint8_t previous_byte = 0;
@@ -260,16 +270,16 @@ unlzma(int src_fd, int dst_fd)
260 for (i = 0; i < num_probs; i++) 270 for (i = 0; i < num_probs; i++)
261 p[i] = (1 << RC_MODEL_TOTAL_BITS) >> 1; 271 p[i] = (1 << RC_MODEL_TOTAL_BITS) >> 1;
262 272
263 rc_init(&rc, src_fd, 0x10000); 273 rc = rc_init(src_fd, 0x10000);
264 274
265 while (global_pos + buffer_pos < header.dst_size) { 275 while (global_pos + buffer_pos < header.dst_size) {
266 int pos_state = (buffer_pos + global_pos) & pos_state_mask; 276 int pos_state = (buffer_pos + global_pos) & pos_state_mask;
267 277
268 prob = 278 prob =
269 p + LZMA_IS_MATCH + (state << LZMA_NUM_POS_BITS_MAX) + pos_state; 279 p + LZMA_IS_MATCH + (state << LZMA_NUM_POS_BITS_MAX) + pos_state;
270 if (rc_is_bit_0(&rc, prob)) { 280 if (rc_is_bit_0(rc, prob)) {
271 mi = 1; 281 mi = 1;
272 rc_update_bit_0(&rc, prob); 282 rc_update_bit_0(rc, prob);
273 prob = (p + LZMA_LITERAL + (LZMA_LIT_SIZE 283 prob = (p + LZMA_LITERAL + (LZMA_LIT_SIZE
274 * ((((buffer_pos + global_pos) & literal_pos_mask) << lc) 284 * ((((buffer_pos + global_pos) & literal_pos_mask) << lc)
275 + (previous_byte >> (8 - lc))))); 285 + (previous_byte >> (8 - lc)))));
@@ -287,7 +297,7 @@ unlzma(int src_fd, int dst_fd)
287 match_byte <<= 1; 297 match_byte <<= 1;
288 bit = match_byte & 0x100; 298 bit = match_byte & 0x100;
289 prob_lit = prob + 0x100 + bit + mi; 299 prob_lit = prob + 0x100 + bit + mi;
290 if (rc_get_bit(&rc, prob_lit, &mi)) { 300 if (rc_get_bit(rc, prob_lit, &mi)) {
291 if (!bit) 301 if (!bit)
292 break; 302 break;
293 } else { 303 } else {
@@ -298,7 +308,7 @@ unlzma(int src_fd, int dst_fd)
298 } 308 }
299 while (mi < 0x100) { 309 while (mi < 0x100) {
300 prob_lit = prob + mi; 310 prob_lit = prob + mi;
301 rc_get_bit(&rc, prob_lit, &mi); 311 rc_get_bit(rc, prob_lit, &mi);
302 } 312 }
303 previous_byte = (uint8_t) mi; 313 previous_byte = (uint8_t) mi;
304 314
@@ -320,24 +330,24 @@ unlzma(int src_fd, int dst_fd)
320 int offset; 330 int offset;
321 uint16_t *prob_len; 331 uint16_t *prob_len;
322 332
323 rc_update_bit_1(&rc, prob); 333 rc_update_bit_1(rc, prob);
324 prob = p + LZMA_IS_REP + state; 334 prob = p + LZMA_IS_REP + state;
325 if (rc_is_bit_0(&rc, prob)) { 335 if (rc_is_bit_0(rc, prob)) {
326 rc_update_bit_0(&rc, prob); 336 rc_update_bit_0(rc, prob);
327 rep3 = rep2; 337 rep3 = rep2;
328 rep2 = rep1; 338 rep2 = rep1;
329 rep1 = rep0; 339 rep1 = rep0;
330 state = state < LZMA_NUM_LIT_STATES ? 0 : 3; 340 state = state < LZMA_NUM_LIT_STATES ? 0 : 3;
331 prob = p + LZMA_LEN_CODER; 341 prob = p + LZMA_LEN_CODER;
332 } else { 342 } else {
333 rc_update_bit_1(&rc, prob); 343 rc_update_bit_1(rc, prob);
334 prob = p + LZMA_IS_REP_G0 + state; 344 prob = p + LZMA_IS_REP_G0 + state;
335 if (rc_is_bit_0(&rc, prob)) { 345 if (rc_is_bit_0(rc, prob)) {
336 rc_update_bit_0(&rc, prob); 346 rc_update_bit_0(rc, prob);
337 prob = (p + LZMA_IS_REP_0_LONG 347 prob = (p + LZMA_IS_REP_0_LONG
338 + (state << LZMA_NUM_POS_BITS_MAX) + pos_state); 348 + (state << LZMA_NUM_POS_BITS_MAX) + pos_state);
339 if (rc_is_bit_0(&rc, prob)) { 349 if (rc_is_bit_0(rc, prob)) {
340 rc_update_bit_0(&rc, prob); 350 rc_update_bit_0(rc, prob);
341 351
342 state = state < LZMA_NUM_LIT_STATES ? 9 : 11; 352 state = state < LZMA_NUM_LIT_STATES ? 9 : 11;
343 pos = buffer_pos - rep0; 353 pos = buffer_pos - rep0;
@@ -354,24 +364,24 @@ unlzma(int src_fd, int dst_fd)
354 } 364 }
355 continue; 365 continue;
356 } else { 366 } else {
357 rc_update_bit_1(&rc, prob); 367 rc_update_bit_1(rc, prob);
358 } 368 }
359 } else { 369 } else {
360 uint32_t distance; 370 uint32_t distance;
361 371
362 rc_update_bit_1(&rc, prob); 372 rc_update_bit_1(rc, prob);
363 prob = p + LZMA_IS_REP_G1 + state; 373 prob = p + LZMA_IS_REP_G1 + state;
364 if (rc_is_bit_0(&rc, prob)) { 374 if (rc_is_bit_0(rc, prob)) {
365 rc_update_bit_0(&rc, prob); 375 rc_update_bit_0(rc, prob);
366 distance = rep1; 376 distance = rep1;
367 } else { 377 } else {
368 rc_update_bit_1(&rc, prob); 378 rc_update_bit_1(rc, prob);
369 prob = p + LZMA_IS_REP_G2 + state; 379 prob = p + LZMA_IS_REP_G2 + state;
370 if (rc_is_bit_0(&rc, prob)) { 380 if (rc_is_bit_0(rc, prob)) {
371 rc_update_bit_0(&rc, prob); 381 rc_update_bit_0(rc, prob);
372 distance = rep2; 382 distance = rep2;
373 } else { 383 } else {
374 rc_update_bit_1(&rc, prob); 384 rc_update_bit_1(rc, prob);
375 distance = rep3; 385 distance = rep3;
376 rep3 = rep2; 386 rep3 = rep2;
377 } 387 }
@@ -385,30 +395,30 @@ unlzma(int src_fd, int dst_fd)
385 } 395 }
386 396
387 prob_len = prob + LZMA_LEN_CHOICE; 397 prob_len = prob + LZMA_LEN_CHOICE;
388 if (rc_is_bit_0(&rc, prob_len)) { 398 if (rc_is_bit_0(rc, prob_len)) {
389 rc_update_bit_0(&rc, prob_len); 399 rc_update_bit_0(rc, prob_len);
390 prob_len = (prob + LZMA_LEN_LOW 400 prob_len = (prob + LZMA_LEN_LOW
391 + (pos_state << LZMA_LEN_NUM_LOW_BITS)); 401 + (pos_state << LZMA_LEN_NUM_LOW_BITS));
392 offset = 0; 402 offset = 0;
393 num_bits = LZMA_LEN_NUM_LOW_BITS; 403 num_bits = LZMA_LEN_NUM_LOW_BITS;
394 } else { 404 } else {
395 rc_update_bit_1(&rc, prob_len); 405 rc_update_bit_1(rc, prob_len);
396 prob_len = prob + LZMA_LEN_CHOICE_2; 406 prob_len = prob + LZMA_LEN_CHOICE_2;
397 if (rc_is_bit_0(&rc, prob_len)) { 407 if (rc_is_bit_0(rc, prob_len)) {
398 rc_update_bit_0(&rc, prob_len); 408 rc_update_bit_0(rc, prob_len);
399 prob_len = (prob + LZMA_LEN_MID 409 prob_len = (prob + LZMA_LEN_MID
400 + (pos_state << LZMA_LEN_NUM_MID_BITS)); 410 + (pos_state << LZMA_LEN_NUM_MID_BITS));
401 offset = 1 << LZMA_LEN_NUM_LOW_BITS; 411 offset = 1 << LZMA_LEN_NUM_LOW_BITS;
402 num_bits = LZMA_LEN_NUM_MID_BITS; 412 num_bits = LZMA_LEN_NUM_MID_BITS;
403 } else { 413 } else {
404 rc_update_bit_1(&rc, prob_len); 414 rc_update_bit_1(rc, prob_len);
405 prob_len = prob + LZMA_LEN_HIGH; 415 prob_len = prob + LZMA_LEN_HIGH;
406 offset = ((1 << LZMA_LEN_NUM_LOW_BITS) 416 offset = ((1 << LZMA_LEN_NUM_LOW_BITS)
407 + (1 << LZMA_LEN_NUM_MID_BITS)); 417 + (1 << LZMA_LEN_NUM_MID_BITS));
408 num_bits = LZMA_LEN_NUM_HIGH_BITS; 418 num_bits = LZMA_LEN_NUM_HIGH_BITS;
409 } 419 }
410 } 420 }
411 rc_bit_tree_decode(&rc, prob_len, num_bits, &len); 421 rc_bit_tree_decode(rc, prob_len, num_bits, &len);
412 len += offset; 422 len += offset;
413 423
414 if (state < 4) { 424 if (state < 4) {
@@ -421,7 +431,7 @@ unlzma(int src_fd, int dst_fd)
421 LZMA_NUM_LEN_TO_POS_STATES ? len : 431 LZMA_NUM_LEN_TO_POS_STATES ? len :
422 LZMA_NUM_LEN_TO_POS_STATES - 1) 432 LZMA_NUM_LEN_TO_POS_STATES - 1)
423 << LZMA_NUM_POS_SLOT_BITS); 433 << LZMA_NUM_POS_SLOT_BITS);
424 rc_bit_tree_decode(&rc, prob, LZMA_NUM_POS_SLOT_BITS, 434 rc_bit_tree_decode(rc, prob, LZMA_NUM_POS_SLOT_BITS,
425 &pos_slot); 435 &pos_slot);
426 if (pos_slot >= LZMA_START_POS_MODEL_INDEX) { 436 if (pos_slot >= LZMA_START_POS_MODEL_INDEX) {
427 num_bits = (pos_slot >> 1) - 1; 437 num_bits = (pos_slot >> 1) - 1;
@@ -432,7 +442,7 @@ unlzma(int src_fd, int dst_fd)
432 } else { 442 } else {
433 num_bits -= LZMA_NUM_ALIGN_BITS; 443 num_bits -= LZMA_NUM_ALIGN_BITS;
434 while (num_bits--) 444 while (num_bits--)
435 rep0 = (rep0 << 1) | rc_direct_bit(&rc); 445 rep0 = (rep0 << 1) | rc_direct_bit(rc);
436 prob = p + LZMA_ALIGN; 446 prob = p + LZMA_ALIGN;
437 rep0 <<= LZMA_NUM_ALIGN_BITS; 447 rep0 <<= LZMA_NUM_ALIGN_BITS;
438 num_bits = LZMA_NUM_ALIGN_BITS; 448 num_bits = LZMA_NUM_ALIGN_BITS;
@@ -440,7 +450,7 @@ unlzma(int src_fd, int dst_fd)
440 i = 1; 450 i = 1;
441 mi = 1; 451 mi = 1;
442 while (num_bits--) { 452 while (num_bits--) {
443 if (rc_get_bit(&rc, prob + mi, &mi)) 453 if (rc_get_bit(rc, prob + mi, &mi))
444 rep0 |= i; 454 rep0 |= i;
445 i <<= 1; 455 i <<= 1;
446 } 456 }
@@ -473,6 +483,6 @@ unlzma(int src_fd, int dst_fd)
473 // FIXME: error check 483 // FIXME: error check
474 write(dst_fd, buffer, buffer_pos); 484 write(dst_fd, buffer, buffer_pos);
475 USE_DESKTOP(total_written += buffer_pos;) 485 USE_DESKTOP(total_written += buffer_pos;)
476 rc_free(&rc); 486 rc_free(rc);
477 return USE_DESKTOP(total_written) + 0; 487 return USE_DESKTOP(total_written) + 0;
478} 488}