size_t sz; /* allocated space for data */
size_t chunksize;
+ char *encoded; /* encoded data (from mbs_safe_encode_to_buffer)) */
+ size_t encoded_sz; /* space allocated for encoded data */
+
char **ptrs; /* saved pointers */
size_t nptrs; /* number of saved poiters */
};
int ul_buffer_append_string(struct ul_buffer *buf, const char *str);
int ul_buffer_append_ntimes(struct ul_buffer *buf, size_t n, const char *str);
int ul_buffer_set_data(struct ul_buffer *buf, const char *data, size_t sz);
-char *ul_buffer_get_data(struct ul_buffer *buf, size_t *sz);
+
+char *ul_buffer_get_data(struct ul_buffer *buf, size_t *sz, size_t *width);
+char *ul_buffer_get_safe_data(struct ul_buffer *buf, size_t *sz, size_t *width, const char *safechars);
+
size_t ul_buffer_get_bufsiz(struct ul_buffer *buf);
int ul_buffer_save_pointer(struct ul_buffer *buf, unsigned short ptr_idx);
char *ul_buffer_get_pointer(struct ul_buffer *buf, unsigned short ptr_idx);
size_t ul_buffer_get_pointer_length(struct ul_buffer *buf, unsigned short ptr_idx);
+size_t ul_buffer_get_safe_pointer_width(struct ul_buffer *buf, unsigned short ptr_idx);
#endif /* UTIL_LINUX_BUFFER */
* Written by Karel Zak <kzak@redhat.com>
*/
#include "buffer.h"
+#include "mbsalign.h"
void ul_buffer_reset_data(struct ul_buffer *buf)
{
free(buf->ptrs);
buf->ptrs = NULL;
buf->nptrs = 0;
+
+ free(buf->encoded);
+ buf->encoded = NULL;
+ buf->encoded_sz = 0;
}
void ul_buffer_set_chunksize(struct ul_buffer *buf, size_t sz)
return NULL;
}
+/* returns length from begin to the pointer */
size_t ul_buffer_get_pointer_length(struct ul_buffer *buf, unsigned short ptr_idx)
{
char *ptr = ul_buffer_get_pointer(buf, ptr_idx);
- if (ptr)
+ if (ptr && ptr > buf->begin)
return ptr - buf->begin;
return 0;
}
+/* returns width of data in safe encoding (from the begin to the pointer) */
+size_t ul_buffer_get_safe_pointer_width(struct ul_buffer *buf, unsigned short ptr_idx)
+{
+ size_t len = ul_buffer_get_pointer_length(buf, ptr_idx);
+
+ if (!len)
+ return 0;
+
+ return mbs_safe_nwidth(buf->begin, len, NULL);
+}
void ul_buffer_refer_string(struct ul_buffer *buf, char *str)
{
return ul_buffer_append_data(buf, data, sz);
}
-char *ul_buffer_get_data(struct ul_buffer *buf, size_t *sz)
+char *ul_buffer_get_data(struct ul_buffer *buf, size_t *sz, size_t *width)
{
if (sz)
*sz = buf->end - buf->begin;
+ if (width)
+ *width = buf->begin && *buf->begin ? mbs_width(buf->begin) : 0;
return buf->begin;
}
return buf->sz;
}
+/* encode data by mbs_safe_encode() to avoid control and non-printable chars */
+char *ul_buffer_get_safe_data(struct ul_buffer *buf, size_t *sz, size_t *width, const char *safechars)
+{
+ char *data = ul_buffer_get_data(buf, NULL, NULL);
+ size_t encsz, wsz = 0;
+ char *res = NULL;
+
+ if (!data)
+ goto nothing;
+
+ encsz = mbs_safe_encode_size(buf->sz) + 1;
+ if (encsz > buf->encoded_sz) {
+ char *tmp = realloc(buf->encoded, encsz);
+ if (!tmp)
+ goto nothing;
+ buf->encoded = tmp;
+ buf->encoded_sz = encsz;
+ }
+
+ res = mbs_safe_encode_to_buffer(data, &wsz, buf->encoded, safechars);
+ if (!res || !wsz || wsz == (size_t) -1)
+ goto nothing;
+
+ if (width)
+ *width = wsz;
+ if (sz)
+ *sz = strlen(res);
+ return res;
+nothing:
+ if (width)
+ *width = 0;
+ if (sz)
+ *sz = 0;
+ return NULL;
+}
+
#ifdef TEST_PROGRAM_BUFFER
ul_buffer_append_string(&buf, "bbb");
ul_buffer_save_pointer(&buf, PTR_BBB);
- str = ul_buffer_get_data(&buf, &sz);
+ str = ul_buffer_get_data(&buf, &sz, NULL);
printf("data [%zu] '%s'\n", sz, str);
printf(" pointer data len: AAA=%zu, BBB=%zu\n",
ul_buffer_get_pointer_length(&buf, PTR_AAA),
ul_buffer_get_pointer_length(&buf, PTR_BBB));
+ printf(" pointer data width: AAA=%zu, BBB=%zu\n",
+ ul_buffer_get_safe_pointer_width(&buf, PTR_AAA),
+ ul_buffer_get_safe_pointer_width(&buf, PTR_BBB));
ul_buffer_reset_data(&buf);
ul_buffer_append_string(&buf, "This is really long string to test the buffer function.");
ul_buffer_save_pointer(&buf, PTR_AAA);
ul_buffer_append_string(&buf, " YES!");
- str = ul_buffer_get_data(&buf, &sz);
+ str = ul_buffer_get_data(&buf, &sz, NULL);
printf("data [%zu] '%s'\n", sz, str);
printf(" pointer data len: AAA=%zu\n", ul_buffer_get_pointer_length(&buf, PTR_AAA));
ul_buffer_refer_string(&buf, str);
ul_buffer_append_data(&buf, ",", 1);
ul_buffer_append_string(&buf, "bar");
- str = ul_buffer_get_data(&buf, &sz);
+ str = ul_buffer_get_data(&buf, &sz, NULL);
printf("data [%zu] '%s'\n", sz, str);
ul_buffer_free_data(&buf);
rc = __buffer_append_option(&buf, name, nsz, value, vsz);
- *optstr = ul_buffer_get_data(&buf, NULL);
+ *optstr = ul_buffer_get_data(&buf, NULL, NULL);
return rc;
}
/**
free(*optstr);
}
- *optstr = ul_buffer_get_data(&buf, NULL);
+ *optstr = ul_buffer_get_data(&buf, NULL, NULL);
return rc;
}
}
if (vfs)
- *vfs = rc ? NULL : ul_buffer_get_data(&xvfs, NULL);
+ *vfs = rc ? NULL : ul_buffer_get_data(&xvfs, NULL, NULL);
if (fs)
- *fs = rc ? NULL : ul_buffer_get_data(&xfs, NULL);
+ *fs = rc ? NULL : ul_buffer_get_data(&xfs, NULL, NULL);
if (user)
- *user = rc ? NULL : ul_buffer_get_data(&xuser, NULL);
+ *user = rc ? NULL : ul_buffer_get_data(&xuser, NULL, NULL);
if (rc) {
ul_buffer_free_data(&xvfs);
ul_buffer_free_data(&xfs);
break;
}
- *subset = rc ? NULL : ul_buffer_get_data(&buf, NULL);
+ *subset = rc ? NULL : ul_buffer_get_data(&buf, NULL, NULL);
if (rc)
ul_buffer_free_data(&buf);
return rc;
goto err;
}
- *optstr = ul_buffer_get_data(&buf, NULL);
+ *optstr = ul_buffer_get_data(&buf, NULL, NULL);
}
DBG(CXT, ul_debug("new optstr '%s'", *optstr));