166 lines
3.4 KiB
C
166 lines
3.4 KiB
C
/* 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;
|
|
*/
|