static celix_status_t celix_utils_convertStringToArrayList()

in libs/utils/src/celix_convert_utils.c [141:219]


static celix_status_t celix_utils_convertStringToArrayList(const char* val,
                                                           celix_array_list_t* listIn,
                                                           const celix_array_list_t* defaultValue,
                                                           celix_status_t (*addEntry)(celix_array_list_t*,
                                                                                      const char*),
                                                           celix_array_list_t** listOut) {
    assert(listOut != NULL);
    *listOut = NULL;
    celix_autoptr(celix_array_list_t) list = listIn;

    if (!val && defaultValue) {
        *listOut = celix_arrayList_copy(defaultValue);
        return *listOut ? CELIX_ILLEGAL_ARGUMENT : CELIX_ENOMEM;
    } else if (!list) {
        return ENOMEM;
    } else if (!val) {
        return CELIX_ILLEGAL_ARGUMENT;
    }

    if (celix_utils_isStringNullOrEmpty(val)) {
        *listOut = celix_steal_ptr(list);
        return CELIX_SUCCESS; // empty string -> empty list
    }

    char* buf = NULL;
    size_t bufSize = 0;
    FILE* entryStream = NULL;
    celix_status_t status = CELIX_SUCCESS;
    size_t max = strlen(val);
    entryStream = open_memstream(&buf, &bufSize);
    if (!entryStream) {
        return CELIX_ENOMEM;
    }
    for (size_t i = 0; i <= max && status == CELIX_SUCCESS; ++i) {
        if (val[i] == ESCAPE_CHAR) {
            // escape character, next char must be escapeChar or separatorChar
            if (i + 1 < max && (val[i + 1] == ESCAPE_CHAR || val[i + 1] == SEPARATOR_CHAR)) {
                // write escaped char
                i += 1;
                int rc = fputc(val[i], entryStream);
                if (rc == EOF) {
                    status = CELIX_ENOMEM;
                }
            } else {
                // invalid escape (ending with escapeChar or followed by an invalid char)
                status = CELIX_ILLEGAL_ARGUMENT;
            }
        } else if (val[i] == SEPARATOR_CHAR || val[i] == '\0') {
            //end of entry
            int rc = fputc('\0', entryStream);
            if (rc == EOF) {
                status = CELIX_ENOMEM;
                continue;
            }
            fflush(entryStream);
            status = addEntry(list, buf);
            rewind(entryStream);
        } else {
            //normal char
            int rc = fputc(val[i], entryStream);
            if (rc == EOF) {
                status = CELIX_ENOMEM;
            }
        }
    }
    fclose(entryStream);
    free(buf);

    if (status == CELIX_SUCCESS) {
        *listOut = celix_steal_ptr(list);
    } else if (status == CELIX_ILLEGAL_ARGUMENT) {
        if (defaultValue) {
            *listOut = celix_arrayList_copy(defaultValue);
            return *listOut ? status : CELIX_ENOMEM;
        }
        return status;
    }
    return status;
}