libutf8/src/tests/random.c

166 lines
3.4 KiB
C
Raw Normal View History

/* libutf8/src/tests/random.c
*
* (c)2006, Laurence Withers. Released under the GNU GPL. See file
* COPYING for more information / terms of license.
*/
#include "utf8.h"
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
void make_rand(wchar_t* buf, int ch)
{
int fd = open("/dev/urandom", O_RDONLY);
if(fd < 0) {
perror("open(\"/dev/urandom\")");
exit(1);
}
ch *= sizeof(wchar_t);
if(read(fd, (char*)buf, ch) != ch) {
perror("read(\"/dev/urandom\")");
exit(1);
}
close(fd);
ch /= sizeof(wchar_t);
while(ch--) {
buf[ch] &= 0x7FFFFFFF;
}
}
int do_encode(char* dest, size_t size, wchar_t* src, size_t amt)
{
struct utf8_encode_state ctx;
memset(&ctx, 0, sizeof(ctx));
ctx.rd = src;
ctx.rd_remain = amt;
ctx.wr = dest;
ctx.wr_size = 20;
while(ctx.rd_remain) {
if(!utf8_encoder(&ctx)) {
perror("utf8_encoder");
exit(1);
}
ctx.wr += ctx.written;
if(ctx.wr + ctx.wr_size > dest + size) {
fprintf(stderr, "do_encode: we're going to run out of memory\n");
exit(1);
}
}
return ctx.wr - dest;
}
int MIN(int x, int y)
{
return (x < y) ? x : y;
}
void do_decode_easy(wchar_t* dest, size_t size, const char* src, size_t amt)
{
struct utf8_decode_state ctx;
memset(&ctx, 0, sizeof(ctx));
ctx.rd = src;
ctx.rd_remain = amt;
ctx.wr = dest;
ctx.wr_size = size;
if(!utf8_decoder(&ctx)) {
perror("[easy] utf8_decoder");
exit(1);
}
if(ctx.rd_remain) {
fprintf(stderr, "do_decode_easy: %d bytes left in buffer\n", ctx.rd_remain);
exit(1);
}
if(!ctx.complete) {
fprintf(stderr, "do_decode_easy: incomplete character at end of data\n");
exit(1);
}
}
void do_decode(wchar_t* dest, size_t size, const char* src, size_t amt)
{
struct utf8_decode_state ctx;
memset(&ctx, 0, sizeof(ctx));
ctx.rd = src;
ctx.rd_remain = MIN(20, amt);
amt -= ctx.rd_remain;
ctx.wr = dest;
ctx.wr_size = 20;
while(ctx.rd_remain) {
if(!utf8_decoder(&ctx)) {
perror("utf8_decoder");
exit(1);
}
if(!ctx.rd_remain) {
ctx.rd_remain = MIN(20, amt);
amt -= ctx.rd_remain;
}
ctx.wr += ctx.written;
if(ctx.wr + ctx.wr_size > dest + size) {
ctx.wr_size = ctx.wr - dest - size;
}
}
}
int main(int argc, char* argv[])
{
wchar_t wbuf[1024], wbuf2[1025];
char cbuf[8192];
int amt;
if(argc == 2 && !strcmp(argv[1], "--print-summary")) {
printf("Encodes and decodes random well-formed strings.\n");
return 0;
}
make_rand(wbuf, 1024);
amt = do_encode(cbuf, 8192, wbuf, 1024);
do_decode_easy(wbuf2, 1025, cbuf, amt);
do_decode(wbuf2, 1025, cbuf, amt);
if(memcmp(wbuf, wbuf2, 1024 * sizeof(wchar_t))) {
fprintf(stderr, "Output doesn't match input!\n");
for(amt = 0; amt < 1024; ++amt) {
if(wbuf[amt] != wbuf2[amt])
fprintf(stderr, "%4d: %08X != %08X\n", amt, wbuf[amt], wbuf2[amt]);
}
return 1;
}
printf("Success.\n");
return 0;
}
/* options for text editors
kate: replace-trailing-space-save true; space-indent true; tab-width 4;
*/