]> icculus.org git repositories - icculus/xz.git/blob - src/liblzma/delta/delta_common.c
Added lzma_delta_coder_memusage() which also validates
[icculus/xz.git] / src / liblzma / delta / delta_common.c
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 /// \file       delta_common.c
4 /// \brief      Common stuff for Delta encoder and decoder
5 //
6 //  Copyright (C) 2007 Lasse Collin
7 //
8 //  This library is free software; you can redistribute it and/or
9 //  modify it under the terms of the GNU Lesser General Public
10 //  License as published by the Free Software Foundation; either
11 //  version 2.1 of the License, or (at your option) any later version.
12 //
13 //  This library is distributed in the hope that it will be useful,
14 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
15 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 //  Lesser General Public License for more details.
17 //
18 ///////////////////////////////////////////////////////////////////////////////
19
20 #include "delta_common.h"
21 #include "delta_private.h"
22
23
24 static void
25 delta_coder_end(lzma_coder *coder, lzma_allocator *allocator)
26 {
27         lzma_next_end(&coder->next, allocator);
28         lzma_free(coder, allocator);
29         return;
30 }
31
32
33 extern lzma_ret
34 lzma_delta_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
35                 const lzma_filter_info *filters, lzma_code_function code)
36 {
37         // Allocate memory for the decoder if needed.
38         if (next->coder == NULL) {
39                 next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
40                 if (next->coder == NULL)
41                         return LZMA_MEM_ERROR;
42
43                 // End function is the same for encoder and decoder.
44                 next->end = &delta_coder_end;
45                 next->coder->next = LZMA_NEXT_CODER_INIT;
46         }
47
48         // Coding function is different for encoder and decoder.
49         next->code = code;
50
51         // Validate the options.
52         if (lzma_delta_coder_memusage(filters[0].options) == UINT64_MAX)
53                 return LZMA_OPTIONS_ERROR;
54
55         // Set the delta distance.
56         const lzma_options_delta *opt = filters[0].options;
57         next->coder->distance = opt->dist;
58
59         // Initialize the rest of the variables.
60         next->coder->pos = 0;
61         memzero(next->coder->history, LZMA_DELTA_DIST_MAX);
62
63         // Initialize the next decoder in the chain, if any.
64         return lzma_next_filter_init(&next->coder->next,
65                         allocator, filters + 1);
66 }
67
68
69 extern uint64_t
70 lzma_delta_coder_memusage(const void *options)
71 {
72         const lzma_options_delta *opt = options;
73
74         if (opt == NULL || opt->type != LZMA_DELTA_TYPE_BYTE
75                         || opt->dist < LZMA_DELTA_DIST_MIN
76                         || opt->dist > LZMA_DELTA_DIST_MAX)
77                 return UINT64_MAX;
78
79         return sizeof(lzma_coder);
80 }