summaryrefslogtreecommitdiffstats
path: root/str.c
diff options
context:
space:
mode:
authorMartin Nagy <mnagy@redhat.com>2009-02-13 10:46:05 +0100
committerMartin Nagy <mnagy@redhat.com>2009-02-18 18:20:36 +0100
commit0755ae502284671fc8345781d3409e406d9e39ab (patch)
tree24c18337ebfd0a2ec788c236e458bd2d344f4f39 /str.c
parent2065d73266fe1abff3ae8a5554096f8dc06d4c33 (diff)
downloadldap_driver_testing-0755ae502284671fc8345781d3409e406d9e39ab.tar.gz
ldap_driver_testing-0755ae502284671fc8345781d3409e406d9e39ab.tar.xz
ldap_driver_testing-0755ae502284671fc8345781d3409e406d9e39ab.zip
Add split support.
Also fix a small isc_mem_put() issue in str_alloc().
Diffstat (limited to 'str.c')
-rw-r--r--str.c135
1 files changed, 133 insertions, 2 deletions
diff --git a/str.c b/str.c
index acad5f6..c340e73 100644
--- a/str.c
+++ b/str.c
@@ -46,15 +46,22 @@
/* Custom string, these shouldn't use these directly */
struct ld_string {
+ isc_mem_t *mctx; /* Memory context. */
char *data; /* String is stored here. */
size_t allocated; /* Number of bytes allocated. */
- isc_mem_t *mctx; /* Memory context. */
#if ISC_MEM_TRACKLINES
const char *file; /* File where the allocation occured. */
int line; /* Line in the file. */
#endif
};
+struct ld_split {
+ isc_mem_t *mctx; /* Memory context. */
+ char *data; /* Splits. */
+ size_t allocated; /* Number of bytes allocated. */
+ char *splits[LD_MAX_SPLITS];
+ size_t split_count; /* Number of splits. */
+};
/*
* Private functions.
@@ -93,7 +100,7 @@ str_alloc(ld_string_t *str, size_t len)
if (str->data != NULL) {
strncpy(new_buffer, str->data, len);
new_buffer[len] = '\0';
- isc_mem_put(str->mctx, str->data, new_size);
+ isc_mem_put(str->mctx, str->data, str->allocated);
} else {
new_buffer[0] = '\0';
}
@@ -352,3 +359,127 @@ str_vsprintf(ld_string_t *dest, const char *format, va_list ap)
cleanup:
return result;
}
+
+/*
+ * TODO: Review.
+ */
+isc_result_t
+str_new_split(isc_mem_t *mctx, ld_split_t **splitp)
+{
+ isc_result_t result;
+ ld_split_t *split;
+
+ REQUIRE(splitp != NULL && *splitp == NULL);
+
+ CHECKED_MEM_GET_PTR(mctx, split);
+ ZERO_PTR(split);
+ isc_mem_attach(mctx, &split->mctx);
+
+ *splitp = split;
+ return ISC_R_SUCCESS;
+
+cleanup:
+ return result;
+}
+
+void
+str_destroy_split(ld_split_t **splitp)
+{
+ ld_split_t *split;
+
+ IGNORE(splitp == NULL || *splitp == NULL);
+
+ split = *splitp;
+
+ if (split->allocated)
+ isc_mem_free(split->mctx, split->data);
+
+ isc_mem_putanddetach(&split->mctx, split, sizeof(*split));
+
+ *splitp = NULL;
+}
+
+static isc_result_t
+str_split_initialize(ld_split_t *split, const char *str)
+{
+ size_t size;
+
+ REQUIRE(split != NULL);
+ REQUIRE(split->mctx != NULL);
+ REQUIRE(str != NULL && *str != '\0');
+
+ if (split->allocated != 0) {
+ isc_mem_put(split->mctx, split->data, split->allocated);
+ split->allocated = 0;
+ }
+ split->splits[0] = NULL;
+ split->split_count = 0;
+
+ size = strlen(str) + 1;
+ split->data = isc_mem_strdup(split->mctx, str);
+ if (split->data == NULL)
+ return ISC_R_NOMEMORY;
+
+ split->allocated = size;
+
+ return ISC_R_SUCCESS;
+}
+
+isc_result_t
+str_split(const ld_string_t *src, const char delimiter, ld_split_t *split)
+{
+ isc_result_t result;
+ unsigned int current_pos;
+ int save;
+
+ REQUIRE(src != NULL);
+ REQUIRE(delimiter != '\0');
+ REQUIRE(split != NULL);
+
+ CHECK(str_split_initialize(split, src->data));
+
+ /* Replace all delimiters with '\0'. */
+ for (unsigned int i = 0; i < split->allocated; i++) {
+ if (split->data[i] == delimiter)
+ split->data[i] = '\0';
+ }
+
+ /* Now save the right positions. */
+ current_pos = 0;
+ save = 1;
+ for (unsigned int i = 0;
+ i < split->allocated && current_pos < LD_MAX_SPLITS;
+ i++) {
+ if (save && split->data[i] != '\0') {
+ split->splits[current_pos] = split->data + i;
+ current_pos++;
+ save = 0;
+ } else if (split->data[i] == '\0') {
+ save = 1;
+ }
+ }
+ split->splits[current_pos] = NULL;
+ split->split_count = current_pos;
+
+ return ISC_R_SUCCESS;
+
+cleanup:
+ return result;
+}
+
+size_t
+str_split_count(const ld_split_t *split)
+{
+ REQUIRE(split != NULL);
+
+ return split->split_count;
+}
+
+const char *
+str_split_get(const ld_split_t *split, unsigned int split_number)
+{
+ REQUIRE(split != NULL);
+ REQUIRE(split->split_count >= split_number);
+
+ return split->splits[split_number];
+}