mirror of https://github.com/nirenjan/libx52.git
87 lines
2.6 KiB
C
87 lines
2.6 KiB
C
/*
|
|
* Saitek X52 Pro Character Map Lookup
|
|
*
|
|
* This file implements functions to perform a lookup of a UTF-8 character
|
|
* in the generated lookup table.
|
|
*
|
|
* Copyright (C) 2015 Nirenjan Krishnan (nirenjan@nirenjan.org)
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License as
|
|
* published by the Free Software Foundation, version 2.
|
|
*
|
|
*/
|
|
|
|
#include <stdint.h>
|
|
#include <errno.h>
|
|
|
|
#include "libx52util.h"
|
|
#include "x52_char_map.h"
|
|
|
|
/**
|
|
* @brief Convert UTF8 string to X52 character map.
|
|
*
|
|
* This function takes in a UTF-8 string and converts it to the character
|
|
* map used by the X52Pro MFD. Unrecognized characters are silently dropped.
|
|
*
|
|
* @param[in] input Input string in UTF-8. Must be NUL-terminated
|
|
* @param[out] output Output buffer
|
|
* @param[inout] len Length of output buffer
|
|
*
|
|
* @returns 0 on success, -EINVAL on invalid parameters, -E2BIG if the buffer
|
|
* filled up before converting the entire string.
|
|
*/
|
|
int libx52util_convert_utf8_string(const uint8_t *input,
|
|
uint8_t *output, size_t *len)
|
|
{
|
|
struct map_entry *entry;
|
|
size_t index;
|
|
int retval = 0;
|
|
unsigned char local_index;
|
|
|
|
if (!input || !output || !len || !*len) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
index = 0;
|
|
entry = &map_root[*input];
|
|
while (*input) {
|
|
input++;
|
|
if (entry->type == TYPE_ENTRY) {
|
|
output[index] = entry->value;
|
|
index++;
|
|
if (index >= *len) {
|
|
retval = -E2BIG;
|
|
break;
|
|
}
|
|
entry = &map_root[*input];
|
|
} else if (entry->type == TYPE_POINTER) {
|
|
local_index = *input;
|
|
if (local_index < 0x80 || local_index >= 0xC0) {
|
|
/* Invalid input, skip till we find the start of another
|
|
* valid UTF-8 character
|
|
*/
|
|
while (*input >= 0x80 && *input < 0xC0) {
|
|
input++; /* Skip invalid characters */
|
|
}
|
|
|
|
/* New UTF-8 character, reset the entry pointer */
|
|
entry = &map_root[*input];
|
|
} else {
|
|
/* Mask off the upper bits, we only care about the lower 6 bits */
|
|
local_index &= 0x3F;
|
|
entry = &(entry->next[local_index]);
|
|
}
|
|
} else {
|
|
/* Invalid value, skip */
|
|
while (*input >= 0x80 && *input < 0xC0) {
|
|
input++; /* Skip invalid characters */
|
|
}
|
|
}
|
|
}
|
|
|
|
*len = index;
|
|
return retval;
|
|
}
|
|
|