79 lines
2.4 KiB
C
79 lines
2.4 KiB
C
/* ************************************************************************** */
|
|
/* _____ _ */
|
|
/* utils/escape.c |_ _|__ _ _| |__ ___ _ _ */
|
|
/* | Project: libp7 | |/ _ \| | | | '_ \ / _ \ | | | */
|
|
/* | | (_) | |_| | | | | __/ |_| | */
|
|
/* By: thomas <thomas@touhey.fr> |_|\___/ \__,_|_| |_|\___|\__, |.fr */
|
|
/* Last updated: 2016/10/13 07:33:17 |___/ */
|
|
/* */
|
|
/* ************************************************************************** */
|
|
#include <libp7/internals.h>
|
|
|
|
/**
|
|
* p7_encode:
|
|
* Encode data.
|
|
*
|
|
* The fxReverse project documentation says that bytes lesser or equal to
|
|
* 0x1F and 0x5C ('\') must be preceded by a 0x5C character. Moreover, bytes
|
|
* lesser or equal to 0x1F must be offset by 0x20.
|
|
*
|
|
* @arg fnal the final buffer
|
|
* @arg raw the original buffer
|
|
* @arg size the size of the data in the original buffer
|
|
* @return the new size of the data
|
|
*/
|
|
|
|
p7ushort_t p7_encode(void *fnal, const void *raw, p7ushort_t size)
|
|
{
|
|
unsigned char *f = (unsigned char*)fnal;
|
|
const unsigned char *r = (const unsigned char*)raw;
|
|
unsigned int fsize = size;
|
|
|
|
while (size--) {
|
|
int c = *r++;
|
|
|
|
if (c < 0x20 || c == '\\') {
|
|
*f++ = '\\'; fsize++;
|
|
if (c < 0x20) c += 0x20;
|
|
}
|
|
|
|
*f++ = (unsigned char)c;
|
|
}
|
|
return (fsize);
|
|
}
|
|
|
|
/**
|
|
* p7_decode:
|
|
* Decode data.
|
|
*
|
|
* This does the opposite of the previous function, that is : copies data,
|
|
* and in case of a 0x5C ('\') character, copies what's next and if it is
|
|
* not the 0x5C character, it removes the 0x20 offset.
|
|
*
|
|
* @arg fnal the decoded data buffer
|
|
* @arg encoded the encoded data
|
|
* @arg size the encoded data size
|
|
* @return the decoded data size
|
|
*/
|
|
|
|
p7ushort_t p7_decode(void *fnal, const void *encoded, p7ushort_t size)
|
|
{
|
|
unsigned char *f = (unsigned char*)fnal;
|
|
const unsigned char *e = (const unsigned char*)encoded;
|
|
unsigned int fsize = size;
|
|
|
|
while (size--) {
|
|
int c = *e++;
|
|
|
|
/* if byte is '\', then next byte should be took alone and
|
|
* we should remove its 0x20-offset if it isn't a '\'. */
|
|
if (c == '\\') {
|
|
c = *e++; size--; fsize--;
|
|
if (c != '\\') c -= 0x20;
|
|
}
|
|
|
|
*f++ = (unsigned char)c;
|
|
}
|
|
return (fsize);
|
|
}
|