tizen 2.4 release
[external/xdelta3.git] / examples / small_page_test.c
1 /* Copyright (C) 2007 Josh MacDonald */
2
3 #include <stdio.h>
4
5 #define PAGE_SIZE 4096
6
7 #define SPACE_MAX 131072   // how much memory per process
8 #define OUTPUT_MAX 1024    // max size for output
9 #define XD3_ALLOCSIZE 256  // internal size for various buffers
10 #define IOPT_SIZE 128      // instruction buffer
11
12 // SPACE_MAX of 32K is sufficient for most inputs with XD3_COMPLEVEL_1
13 // XD3_COMPLEVEL_9 requires about 4x more space than XD3_COMPLEVEL_1
14
15 #include "xdelta3.h"
16 #include "xdelta3.c"
17
18 typedef struct _context {
19   uint8_t *buffer;
20   int allocated;
21 } context_t;
22
23 static int max_allocated = 0;
24
25 void*
26 process_alloc (void* opaque, usize_t items, usize_t size)
27 {
28   context_t *ctx = (context_t*) opaque;
29   usize_t t = items * size;
30   void *ret;
31
32   if (ctx->allocated + t > SPACE_MAX)
33     {
34       return NULL;
35     }
36
37   ret = ctx->buffer + ctx->allocated;
38   ctx->allocated += t;
39   return ret;
40 }
41
42 void
43 process_free (void* opaque, void *ptr)
44 {
45 }
46
47 int
48 process_page (int            is_encode,
49               int          (*func) (xd3_stream *),
50               const uint8_t *input,
51               usize_t        input_size,
52               const uint8_t *source,
53               uint8_t       *output,
54               usize_t       *output_size,
55               usize_t        output_size_max,
56               int            flags) {
57
58   /* On my x86 this is 1072 of objects on the stack */
59   xd3_stream stream;
60   xd3_config config;
61   xd3_source src;
62   context_t *ctx = calloc(SPACE_MAX, 1);
63   int ret;
64
65   memset (&config, 0, sizeof(config));
66
67   if (ctx == NULL)
68     {
69       printf("calloc failed\n");
70       return -1;
71     }
72
73   ctx->buffer = (uint8_t*)ctx;
74   ctx->allocated = sizeof(*ctx);
75
76   config.flags = flags;
77   config.winsize = PAGE_SIZE;
78   config.sprevsz = PAGE_SIZE;
79   config.srcwin_maxsz = PAGE_SIZE;
80   config.iopt_size = IOPT_SIZE;
81   config.alloc = &process_alloc;
82   config.freef = &process_free;
83   config.opaque = (void*) ctx;
84
85   src.blksize = PAGE_SIZE;
86   src.onblk = PAGE_SIZE;
87   src.curblk = source;
88   src.curblkno = 0;
89
90   if ((ret = xd3_config_stream (&stream, &config)) != 0 ||
91       (ret = xd3_set_source_and_size (&stream, &src, PAGE_SIZE)) != 0 ||
92       (ret = xd3_process_stream (is_encode,
93                                  &stream,
94                                  func, 1,
95                                  input, input_size,
96                                  output, output_size,
97                                  output_size_max)) != 0)
98     {
99       if (stream.msg != NULL)
100         {
101           fprintf(stderr, "stream message: %s\n", stream.msg);
102         }
103     }
104
105   xd3_free_stream (&stream);
106   if (max_allocated < ctx->allocated)
107     {
108       max_allocated = ctx->allocated;
109       fprintf(stderr, "max allocated %d\n", max_allocated);
110     }
111
112   free(ctx);
113   return ret;
114 }
115
116 int test(int stride, int encode_flags)
117 {
118   uint8_t frompg[PAGE_SIZE];
119   uint8_t topg[PAGE_SIZE];
120   uint8_t output[OUTPUT_MAX];
121   uint8_t reout[PAGE_SIZE];
122   usize_t output_size;
123   usize_t re_size;
124   int i, j, ret;
125
126   for (i = 0; i < PAGE_SIZE; i++)
127     {
128       topg[i] = frompg[i] = (rand() >> 3 ^ rand() >> 6 ^ rand() >> 9);
129     }
130
131   // change 1 byte every stride
132   if (stride > 0)
133     {
134       for (j = stride; j <= PAGE_SIZE; j += stride)
135         {
136           topg[j - 1] ^= 0xff;
137         }
138     }
139
140   if ((ret = process_page (1, xd3_encode_input,
141                            topg, PAGE_SIZE,
142                            frompg, output,
143                            &output_size, OUTPUT_MAX,
144                            encode_flags)) != 0)
145     {
146       fprintf (stderr, "encode failed: stride %u flags 0x%x\n",
147                stride, encode_flags);
148       return ret;
149     }
150
151   if ((ret = process_page (0, xd3_decode_input,
152                            output, output_size,
153                            frompg, reout,
154                            &re_size, PAGE_SIZE,
155                            0)) != 0)
156     {
157       fprintf (stderr, "decode failed: stride %u output_size %u flags 0x%x\n",
158                stride, output_size, encode_flags);
159       return ret;
160     }
161
162   if (output_size > OUTPUT_MAX || re_size != PAGE_SIZE)
163     {
164       fprintf (stderr, "internal error: %u != %u\n", output_size, re_size);
165       return -1;
166     }
167
168   for (i = 0; i < PAGE_SIZE; i++)
169     {
170       if (reout[i] != topg[i])
171         {
172           fprintf (stderr, "encode-decode error: position %d\n", i);
173           return -1;
174         }
175     }
176
177   fprintf(stderr, "stride %d flags 0x%x size %u ",
178           stride, encode_flags, output_size);
179   fprintf(stderr, "%s\n", (ret == 0) ? "OK" : "FAIL");
180
181   return 0;
182 }
183
184 int main()
185 {
186   int stride;
187   int level;
188
189   for (level = 1; level < 10; level = (level == 1 ? 3 : level + 3))
190     {
191       int lflag = level << XD3_COMPLEVEL_SHIFT;
192
193       for (stride = 2; stride <= PAGE_SIZE; stride += 2)
194         {
195           test(stride, lflag);
196           test(stride, lflag | XD3_SEC_DJW);
197         }
198     }
199
200   return 0;
201 }