source: nikanabo/current/xdelta/diy/examples/small_page_test.c @ 185

Last change on this file since 185 was 185, checked in by geyser, 14 years ago
File size: 4.2 KB
Line 
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
18typedef struct _context {
19  uint8_t *buffer;
20  int allocated;
21} context_t;
22
23static int max_allocated = 0;
24
25void*
26process_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
42void
43process_free (void* opaque, void *ptr)
44{
45}
46
47int
48process_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  if (ctx == NULL)
66    {
67      printf("calloc failed\n");
68      return -1;
69    }
70
71  ctx->buffer = (uint8_t*)ctx;
72  ctx->allocated = sizeof(*ctx);
73
74  config.flags = flags;
75  config.winsize = PAGE_SIZE;
76  config.sprevsz = PAGE_SIZE;
77  config.srcwin_maxsz = PAGE_SIZE;
78  config.iopt_size = IOPT_SIZE;
79  config.alloc = &process_alloc;
80  config.freef = &process_free;
81  config.opaque = (void*) ctx;
82
83  src.size = PAGE_SIZE;
84  src.blksize = PAGE_SIZE;
85  src.onblk = PAGE_SIZE;
86  src.curblk = source;
87  src.curblkno = 0;
88
89  if ((ret = xd3_config_stream (&stream, &config)) != 0 ||
90      (ret = xd3_set_source (&stream, &src)) != 0 ||
91      (ret = xd3_process_stream (is_encode,
92                                 &stream,
93                                 func, 1,
94                                 input, input_size,
95                                 output, output_size,
96                                 output_size_max)) != 0)
97    {
98      if (stream.msg != NULL)
99        {
100          fprintf(stderr, "stream message: %s\n", stream.msg);
101        }
102    }
103
104  xd3_free_stream (&stream);
105  if (max_allocated < ctx->allocated)
106    {
107      max_allocated = ctx->allocated;
108      fprintf(stderr, "max allocated %d\n", max_allocated);
109    }
110
111  free(ctx);
112  return ret;
113}
114
115int test(int stride, int encode_flags)
116{
117  uint8_t frompg[PAGE_SIZE];
118  uint8_t topg[PAGE_SIZE];
119  uint8_t output[OUTPUT_MAX];
120  uint8_t reout[PAGE_SIZE];
121  usize_t output_size;
122  usize_t re_size;
123  int i, j, ret;
124
125  for (i = 0; i < PAGE_SIZE; i++)
126    {
127      topg[i] = frompg[i] = (rand() >> 3 ^ rand() >> 6 ^ rand() >> 9);
128    }
129
130  // change 1 byte every stride
131  if (stride > 0)
132    {
133      for (j = stride; j <= PAGE_SIZE; j += stride)
134        {
135          topg[j - 1] ^= 0xff;
136        }
137    }
138
139  if ((ret = process_page (1, xd3_encode_input,
140                           topg, PAGE_SIZE,
141                           frompg, output,
142                           &output_size, OUTPUT_MAX,
143                           encode_flags)) != 0)
144    {
145      fprintf (stderr, "encode failed: stride %u flags 0x%x\n", stride, encode_flags);
146      return ret;
147    }
148
149  if ((ret = process_page (0, xd3_decode_input,
150                           output, output_size,
151                           frompg, reout,
152                           &re_size, PAGE_SIZE,
153                           0)) != 0)
154    {
155      fprintf (stderr, "decode failed: stride %u output_size %u flags 0x%x\n",
156              stride, output_size, encode_flags);
157      return ret;
158    }
159
160  if (output_size > OUTPUT_MAX || re_size != PAGE_SIZE)
161    {
162      fprintf (stderr, "internal error: %u != %u\n", output_size, re_size);
163      return -1;
164    }
165
166  for (i = 0; i < PAGE_SIZE; i++)
167    {
168      if (reout[i] != topg[i])
169        {
170          fprintf (stderr, "encode-decode error: position %d\n", i);
171          return -1;
172        }
173    }
174
175  fprintf(stderr, "stride %d flags 0x%x size %u ", stride, encode_flags, output_size);
176  fprintf(stderr, "%s\n", (ret == 0) ? "OK" : "FAIL");
177
178  return 0;
179}
180
181int main()
182{
183  int stride;
184  int level;
185
186  for (level = 1; level < 10; level = (level == 1 ? 3 : level + 3))
187    {
188      int lflag = level << XD3_COMPLEVEL_SHIFT;
189
190      for (stride = 2; stride <= PAGE_SIZE; stride += 2)
191        {
192          test(stride, lflag);
193          test(stride, lflag | XD3_SEC_DJW);
194        }
195    }
196
197  return 0;
198}
Note: See TracBrowser for help on using the repository browser.