static void cstring_change_case(cstring_t *self, int up);
/** For path-related functions */
static void normalize_path(cstring_t *self);
+/** Actual implemenation of both addfn and addfN */
+static int cstring_addfNn(cstring_t *self, const char source[], size_t idx,
+ size_t n, int force_n);
// Private variables
}
int cstring_add(cstring_t *self, const char source[]) {
- return cstring_addf(self, source, 0);
+ return cstring_addfNn(self, source, 0, 0, 0);
}
int cstring_addf(cstring_t *self, const char source[], size_t idx) {
- return cstring_addfn(self, source, idx, 0);
+ return cstring_addfNn(self, source, idx, 0, 0);
}
int cstring_addn(cstring_t *self, const char source[], size_t n) {
- return cstring_addfn(self, source, 0, n);
+ return cstring_addfNn(self, source, 0, n, 0);
}
int cstring_addfn(cstring_t *self, const char source[], size_t idx, size_t n) {
+ return cstring_addfNn(self, source, idx, n, 0);
+}
+
+int cstring_addfN(cstring_t *self, const char source[], size_t idx, size_t n) {
+ return cstring_addfNn(self, source, idx, n, 1);
+}
+
+int cstring_addfNn(cstring_t *self, const char source[], size_t idx, size_t n,
+ int force_n) {
size_t ss;
ss = strlen(source);
if (source && ss > idx && idx >= 0) {
ss -= idx;
- if (n && n < ss)
+ if (n && (force_n || (n < ss)))
ss = n;
if (ss) {
size_t cstring_remove_crlf(char *self) {
size_t sz = strlen(self);
+ return cstring_remove_crlf_sz(self, sz);
+}
+
+size_t cstring_remove_crlf_sz(char *self, size_t sz) {
if (sz && self[sz - 1] == '\n')
sz--;
if (sz && self[sz - 1] == '\r')
if (!file)
return 0;
- buffer[BUFFER_SIZE - 1] = '\0'; // just in case
-
if (!feof(file)) {
+ // Allow '\0' in data (1/4)
+ //buffer[BUFFER_SIZE - 1] = '\0'; // just in case
+ memset(buffer, ~0, BUFFER_SIZE);
+
cstring_clear(self);
buffer[0] = '\0';
// Note: fgets() could return NULL if EOF is reached
if (!fgets(buffer, (int) BUFFER_SIZE - 1, file))
return 0;
+
+ // Allow '\0' in data (2/4)
+ //size = strlen(buffer);
+ size = BUFFER_SIZE;
+ while(size && buffer[size - 1])
+ size--;
+ if (size)
+ size--;
- size = strlen(buffer);
full_line = ((file && feof(file)) || size == 0
|| buffer[size - 1] == '\n');
- size = cstring_remove_crlf(buffer);
- cstring_add(self, buffer);
+ size = cstring_remove_crlf_sz(buffer, size);
+ cstring_addfN(self, buffer, 0, size);
// No luck, we need to continue getting data
while (!full_line) {
+ // Allow '\0' in data (3/4)
+ //buffer[BUFFER_SIZE - 1] = '\0'; // just in case
+ memset(buffer, ~0, BUFFER_SIZE);
+
if (!fgets(buffer, (int) BUFFER_SIZE - 1, file))
break;
- size = strlen(buffer);
+ // Allow '\0' in data (4/4)
+ //size = strlen(buffer);
+ size = BUFFER_SIZE;
+ while(size && buffer[size - 1])
+ size--;
+ if (size)
+ size--;
+
full_line = ((file && feof(file)) || size == 0
|| buffer[size - 1] == '\n');
- size = cstring_remove_crlf(buffer);
- cstring_add(self, buffer);
+ size = cstring_remove_crlf_sz(buffer, size);
+ cstring_addfN(self, buffer, 0, size);
}
return 1;
*/
int cstring_addfn(cstring_t *self, const char source[], size_t idx, size_t n);
+/**
+ * Add a string (a sequence of char that MAY end with '\0') at the end of the
+ * given cstring, starting from index, N chars long (even if the source
+ * string contains '\0' characters).
+ *
+ * @param self the string to work on
+ * @param source the string to add
+ * @param idx the starting index at which to copy from the source
+ * @param n the number of chars to add (excluding the NUL byte) or 0
+ * to add the whole source (which MUST then end with a '\0')
+ *
+ * @return TRUE if success (FALSE means it was unable to grow due to memory
+ * pressure)
+ */
+int cstring_addfN(cstring_t *self, const char source[], size_t idx, size_t n);
+
/**
* Add a string via the usual <tt>printf</tt> formatters.
*
*/
size_t cstring_remove_crlf(char *self);
+/**
+ * Remove the \r and \n sequence (or one OR the other) at the end of the string.
+ *
+ * @param self the string to change
+ * @param sz the current size of the string
+ *
+ * @return the new length of the string
+ */
+size_t cstring_remove_crlf_sz(char *self, size_t sz);
+
/**
* Change the case to upper-case (UTF-8 compatible, but the string MUST be
* whole).