slovo/benchmarks/json-quote-loop/c/json_quote_loop.c

119 lines
3.1 KiB
C

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LOOP_COUNT 1000000
#define EXPECTED_CHECKSUM 15000001
static int32_t configured_loop_count(void) {
int32_t value = LOOP_COUNT;
if (scanf("%d", &value) != 1 || value <= 0) {
return LOOP_COUNT;
}
return value;
}
static const char *configured_target(int argc, char **argv) {
return argc > 1 ? argv[1] : "slo\"vo\\path";
}
static char json_hex_digit(unsigned char value) {
return value < 10 ? (char)('0' + value) : (char)('A' + (value - 10));
}
static char *quote_json_string(const char *text) {
size_t len = 2;
for (const unsigned char *cursor = (const unsigned char *)text; *cursor != '\0'; cursor++) {
switch (*cursor) {
case '"':
case '\\':
case '\n':
case '\t':
case '\r':
case '\b':
case '\f':
len += 2;
break;
default:
len += *cursor < 0x20 ? 6 : 1;
break;
}
}
char *out = malloc(len + 1);
if (out == NULL) {
exit(2);
}
char *write = out;
*write++ = '"';
for (const unsigned char *cursor = (const unsigned char *)text; *cursor != '\0'; cursor++) {
switch (*cursor) {
case '"':
*write++ = '\\';
*write++ = '"';
break;
case '\\':
*write++ = '\\';
*write++ = '\\';
break;
case '\n':
*write++ = '\\';
*write++ = 'n';
break;
case '\t':
*write++ = '\\';
*write++ = 't';
break;
case '\r':
*write++ = '\\';
*write++ = 'r';
break;
case '\b':
*write++ = '\\';
*write++ = 'b';
break;
case '\f':
*write++ = '\\';
*write++ = 'f';
break;
default:
if (*cursor < 0x20) {
*write++ = '\\';
*write++ = 'u';
*write++ = '0';
*write++ = '0';
*write++ = json_hex_digit((unsigned char)(*cursor >> 4));
*write++ = json_hex_digit((unsigned char)(*cursor & 0x0F));
} else {
*write++ = (char)*cursor;
}
break;
}
}
*write++ = '"';
*write = '\0';
return out;
}
static int32_t json_quote_loop(int32_t limit, const char *target) {
int32_t i = 0;
int32_t acc = 1;
while (i < limit) {
char *quoted = quote_json_string(target);
acc += (int32_t)strlen(quoted);
free(quoted);
i += 1;
}
return acc;
}
int main(int argc, char **argv) {
int32_t result = json_quote_loop(configured_loop_count(), configured_target(argc, argv));
printf("%d\n", result);
return result == EXPECTED_CHECKSUM ? 0 : 1;
}