Created
January 12, 2017 02:10
-
-
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 file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 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