Skip to content

Instantly share code, notes, and snippets.

@alexandream
Created January 12, 2017 02:10
Show Gist options
  • Save alexandream/a8e86f71f07b3b537c1dc8e54674d7e9 to your computer and use it in GitHub Desktop.
Save alexandream/a8e86f71f07b3b537c1dc8e54674d7e9 to your computer and use it in GitHub Desktop.
Basic set of functions to encode/decode line breaks in a string. Useful when trying to store program outputs in a text/plain line-based serialization format.
/* This is a quite simple set of functions that turns multi-line strings in
single line strings with the line breaking characters backslash escaped.
The encode_crfl does the following transformation.
transform : character -> string
transform '\n' = "\\n"
transform '\r' = "\\r"
transform '\\' = "\\\\"
transform c = c
The mirror transformation is provided by decode_crlf and is smart enough
to identify invalid codifications (in which case it returns NULL).
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
static size_t
compute_encoded_length(const char* input) {
size_t original_length = strlen(input);
size_t i;
size_t result = 0;
for (i = 0; i < original_length; i++) {
char c = input[i];
result += (c == '\\' || c == '\r' || c == '\n') ? 2 : 1;
}
return result;
}
char*
encode_crlf(const char* input) {
size_t original_length = strlen(input);
size_t encoded_length = compute_encoded_length(input);
size_t i;
size_t j;
char* result;
result = malloc(sizeof(char) * (encoded_length+1));
if (result == NULL) {
return NULL;
}
for (i = 0, j = 0; i < original_length; i++, j++) {
char c = input[i];
if (c == '\\' || c == '\r' || c == '\n') {
result[j++] = '\\';
result[j] = (c == '\\') ? '\\'
: (c == '\r') ? 'r'
: 'n'; /* can only be \n */
}
else {
result[j] = c;
}
}
result[j] = '\0';
return result;
}
char*
decode_crlf(const char* input) {
char* result;
size_t length = strlen(input);
size_t i;
size_t j;
result = malloc(sizeof(char) * (length + 1));
if (result == NULL) {
return NULL;
}
for (i = 0, j = 0; i < length; i++, j++) {
if (input[i] == '\\') {
char c = input[i+1];
if (c != '\\' && c != 'n' && c != 'r') {
/* Invalid codification. Free up memory and set errno */
free(result);
errno = EDOM;
return NULL;
}
result[j] = (c == '\\') ? '\\'
: (c == 'r') ? '\r'
: '\n'; /* Can only be n */
i++;
}
else {
result[j] = input[i];
}
}
result[j] = '\0';
return result;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment