forked from pEp.foundation/pEpEngine
reorga
parent
f825f336d2
commit
9b85561fb7
|
@ -0,0 +1,109 @@
|
|||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "bloblist.h"
|
||||
|
||||
DYNAMIC_API bloblist_t *new_bloblist(char *blob, size_t size, const char *mime_type,
|
||||
const char *file_name)
|
||||
{
|
||||
bloblist_t * bloblist = calloc(1, sizeof(bloblist_t));
|
||||
assert(bloblist);
|
||||
if (bloblist == NULL)
|
||||
return NULL;
|
||||
|
||||
if (mime_type) {
|
||||
bloblist->mime_type = strdup(mime_type);
|
||||
if (bloblist->mime_type == NULL) {
|
||||
free(bloblist);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (file_name) {
|
||||
bloblist->file_name = strdup(file_name);
|
||||
if (bloblist->file_name == NULL) {
|
||||
free(bloblist->mime_type);
|
||||
free(bloblist);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bloblist->data = blob;
|
||||
bloblist->size = size;
|
||||
|
||||
return bloblist;
|
||||
}
|
||||
|
||||
DYNAMIC_API void free_bloblist(bloblist_t *bloblist)
|
||||
{
|
||||
if (bloblist) {
|
||||
if (bloblist->next)
|
||||
free_bloblist(bloblist->next);
|
||||
free(bloblist->data);
|
||||
free(bloblist->mime_type);
|
||||
free(bloblist->file_name);
|
||||
free(bloblist);
|
||||
}
|
||||
}
|
||||
|
||||
DYNAMIC_API bloblist_t *bloblist_dup(const bloblist_t *src)
|
||||
{
|
||||
bloblist_t *bloblist = NULL;
|
||||
|
||||
assert(src);
|
||||
|
||||
bloblist = new_bloblist(src->data, src->size, src->mime_type, src->file_name);
|
||||
if (bloblist == NULL)
|
||||
goto enomem;
|
||||
|
||||
if (src->next) {
|
||||
bloblist->next = bloblist_dup(src->next);
|
||||
if (bloblist->next == NULL)
|
||||
goto enomem;
|
||||
}
|
||||
|
||||
return bloblist;
|
||||
|
||||
enomem:
|
||||
free_bloblist(bloblist);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DYNAMIC_API bloblist_t *bloblist_add(bloblist_t *bloblist, char *blob, size_t size,
|
||||
const char *mime_type, const char *file_name)
|
||||
{
|
||||
assert(blob);
|
||||
|
||||
if (bloblist == NULL)
|
||||
return new_bloblist(blob, size, mime_type, file_name);
|
||||
|
||||
if (bloblist->data == NULL) {
|
||||
if (mime_type) {
|
||||
bloblist->mime_type = strdup(mime_type);
|
||||
if (bloblist->mime_type == NULL) {
|
||||
free(bloblist);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (file_name) {
|
||||
bloblist->file_name = strdup(file_name);
|
||||
if (bloblist->file_name == NULL) {
|
||||
free(bloblist->mime_type);
|
||||
free(bloblist);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
bloblist->data = blob;
|
||||
bloblist->size = size;
|
||||
return bloblist;
|
||||
}
|
||||
|
||||
if (bloblist->next == NULL) {
|
||||
bloblist->next = new_bloblist(blob, size, mime_type, file_name);
|
||||
return bloblist->next;
|
||||
}
|
||||
|
||||
return bloblist_add(bloblist->next, blob, size, mime_type, file_name);
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
#pragma once
|
||||
|
||||
#include "dynamic_api.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct _bloblist_t {
|
||||
char *data; // blob
|
||||
size_t size; // size of blob
|
||||
char *mime_type; // UTF-8 string of MIME type of blob or
|
||||
// NULL if unknown
|
||||
char *file_name; // UTF-8 string of file name of blob or
|
||||
// NULL if unknown
|
||||
struct _bloblist_t *next;
|
||||
} bloblist_t;
|
||||
|
||||
|
||||
// new_bloblist() - allocate a new bloblist
|
||||
//
|
||||
// parameters:
|
||||
// blob (in) blob to add to the list
|
||||
// size (in) size of the blob
|
||||
// mime_type (in) MIME type of the blob data or NULL if unknown
|
||||
// file_name (in) file name of origin of blob data or NULL if unknown
|
||||
//
|
||||
// return value:
|
||||
// pointer to new bloblist_t or NULL if out of memory
|
||||
//
|
||||
// caveat:
|
||||
// the ownership of the blob goes to the bloblist; mime_type and file_name
|
||||
// are being copied, the originals remain in the ownership of the caller
|
||||
|
||||
DYNAMIC_API bloblist_t *new_bloblist(char *blob, size_t size, const char *mime_type,
|
||||
const char *file_name);
|
||||
|
||||
|
||||
// free_bloblist() - free bloblist
|
||||
//
|
||||
// parameters:
|
||||
// bloblist (in) bloblist to free
|
||||
|
||||
DYNAMIC_API void free_bloblist(bloblist_t *bloblist);
|
||||
|
||||
|
||||
// bloblist_dup() - duplicate bloblist
|
||||
//
|
||||
// parameters:
|
||||
// src (in) bloblist to duplicate
|
||||
//
|
||||
// return value:
|
||||
// pointer to a new bloblist_t or NULL if out of memory
|
||||
//
|
||||
// caveat:
|
||||
// this is an expensive operation because all blobs are copied
|
||||
|
||||
DYNAMIC_API bloblist_t *bloblist_dup(const bloblist_t *src);
|
||||
|
||||
// bloblist_add() - add reference to a blob to bloblist
|
||||
//
|
||||
// parameters:
|
||||
// bloblist (in) bloblist to add to
|
||||
// blob (in) blob
|
||||
// size (in) size of the blob
|
||||
// mime_type (in) MIME type of the blob or NULL if unknown
|
||||
// file_name (in) file name of the blob or NULL if unknown
|
||||
//
|
||||
// return value:
|
||||
// pointer to the last element of bloblist or NULL if out of memory
|
||||
//
|
||||
// caveat:
|
||||
// the ownership of the blob goes to the bloblist; mime_type and file_name
|
||||
// are being copied, the originals remain in the ownership of the caller
|
||||
|
||||
DYNAMIC_API bloblist_t *bloblist_add(bloblist_t *bloblist, char *blob, size_t size,
|
||||
const char *mime_type, const char *file_name);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _EXPORT_PEP_ENGINE_DLL
|
||||
#define DYNAMIC_API __declspec(dllexport)
|
||||
#else
|
||||
#define DYNAMIC_API __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define DYNAMIC_API
|
||||
#endif
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "pEpEngine.h"
|
||||
#include "identity_list.h"
|
||||
|
||||
DYNAMIC_API identity_list *new_identity_list(pEp_identity *ident)
|
||||
{
|
||||
identity_list *id_list = calloc(1, sizeof(identity_list));
|
||||
assert(id_list);
|
||||
if (id_list == NULL)
|
||||
return NULL;
|
||||
|
||||
id_list->ident = ident;
|
||||
|
||||
return id_list;
|
||||
}
|
||||
|
||||
DYNAMIC_API identity_list *identity_list_dup(const identity_list *src)
|
||||
{
|
||||
assert(src);
|
||||
|
||||
identity_list *id_list = new_identity_list(identity_dup(src->ident));
|
||||
assert(id_list);
|
||||
if (id_list == NULL)
|
||||
return NULL;
|
||||
|
||||
if (src->next) {
|
||||
id_list->next = identity_list_dup(src->next);
|
||||
if (id_list->next == NULL) {
|
||||
free_identity_list(id_list);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return id_list;
|
||||
}
|
||||
|
||||
DYNAMIC_API void free_identity_list(identity_list *id_list)
|
||||
{
|
||||
if (id_list) {
|
||||
free_identity_list(id_list->next);
|
||||
free_identity(id_list->ident);
|
||||
free(id_list);
|
||||
}
|
||||
}
|
||||
|
||||
DYNAMIC_API identity_list *identity_list_add(identity_list *id_list, pEp_identity *ident)
|
||||
{
|
||||
assert(ident);
|
||||
|
||||
if (id_list == NULL)
|
||||
return new_identity_list(ident);
|
||||
|
||||
if (id_list->ident == NULL) {
|
||||
id_list->ident = ident;
|
||||
return id_list;
|
||||
}
|
||||
else if (id_list->next == NULL) {
|
||||
id_list->next = new_identity_list(ident);
|
||||
return id_list->next;
|
||||
}
|
||||
else {
|
||||
return identity_list_add(id_list->next, ident);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
#pragma once
|
||||
|
||||
#include "dynamic_api.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct _identity_list {
|
||||
pEp_identity *ident;
|
||||
struct _identity_list *next;
|
||||
} identity_list;
|
||||
|
||||
|
||||
// new_identity_list() - allocate a new identity list
|
||||
//
|
||||
// parameters:
|
||||
// ident (in) identity to move for first element
|
||||
//
|
||||
// return value:
|
||||
// new identity_list or NULL if out of memory
|
||||
//
|
||||
// caveat:
|
||||
// ident is being moved if the function succeeds, the caller loses
|
||||
// ownership
|
||||
|
||||
DYNAMIC_API identity_list *new_identity_list(pEp_identity *ident);
|
||||
|
||||
|
||||
// identity_list_dup() - duplicate identity_list (deep copy)
|
||||
//
|
||||
// parameters:
|
||||
// id_list (in) identity_list to copy
|
||||
//
|
||||
// return value:
|
||||
// new identity_list or NULL if out of memory
|
||||
|
||||
DYNAMIC_API identity_list *identity_list_dup(const identity_list *src);
|
||||
|
||||
|
||||
// free_identity_list() - free memory allocated by identity_list
|
||||
//
|
||||
// parameters:
|
||||
// id_list (in) identity_list to free
|
||||
//
|
||||
// caveat:
|
||||
// this function frees all identities in the list additional to the
|
||||
// identity_list itself
|
||||
|
||||
DYNAMIC_API void free_identity_list(identity_list *id_list);
|
||||
|
||||
|
||||
// identity_list_add - add identity to an identity_list
|
||||
//
|
||||
// parameters:
|
||||
// id_list (in) identity_list to add to
|
||||
// ident (in) identity being added
|
||||
//
|
||||
// return value:
|
||||
// pointer to the last element in identity_list or NULL if out of memory
|
||||
//
|
||||
// caveat:
|
||||
// ident is being moved, the caller loses ownership if the function is
|
||||
// successful
|
||||
|
||||
DYNAMIC_API identity_list *identity_list_add(identity_list *id_list, pEp_identity *ident);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
@ -547,9 +547,11 @@ static PEP_STATUS build_fields(const message *msg, struct mailimf_fields **resul
|
|||
}
|
||||
}
|
||||
|
||||
r = _append_optional_field(fields_list, "X-pEp-Version", PEP_VERSION);
|
||||
if (r)
|
||||
goto enomem;
|
||||
if (msg->opt_fields) {
|
||||
r = _append_optional_field(fields_list, "X-pEp-Version", PEP_VERSION);
|
||||
if (r)
|
||||
goto enomem;
|
||||
}
|
||||
|
||||
fields = mailimf_fields_new(fields_list);
|
||||
assert(fields);
|
||||
|
|
104
src/pEpEngine.c
104
src/pEpEngine.c
|
@ -1,3 +1,4 @@
|
|||
#include "dynamic_api.h"
|
||||
#include "pEp_internal.h"
|
||||
#include "cryptotech.h"
|
||||
#include "transport.h"
|
||||
|
@ -292,109 +293,6 @@ DYNAMIC_API void release(PEP_SESSION session)
|
|||
}
|
||||
}
|
||||
|
||||
stringlist_t *new_stringlist(const char *value)
|
||||
{
|
||||
stringlist_t *result = (stringlist_t *) calloc(1, sizeof(stringlist_t));
|
||||
if (result && value) {
|
||||
result->value = strdup(value);
|
||||
assert(result->value);
|
||||
if (result->value == 0) {
|
||||
free(result);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
DYNAMIC_API stringlist_t *stringlist_dup(const stringlist_t *src)
|
||||
{
|
||||
assert(src);
|
||||
if (src == NULL)
|
||||
return NULL;
|
||||
|
||||
stringlist_t *dst = new_stringlist(src->value);
|
||||
if (dst == NULL)
|
||||
return NULL;
|
||||
|
||||
if (src->next) {
|
||||
dst->next = stringlist_dup(src->next);
|
||||
if (dst->next == NULL) {
|
||||
free_stringlist(dst);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
stringlist_t *stringlist_add(stringlist_t *stringlist, const char *value)
|
||||
{
|
||||
assert(value);
|
||||
|
||||
if (stringlist == NULL)
|
||||
return new_stringlist(value);
|
||||
|
||||
if (stringlist->next != NULL)
|
||||
return stringlist_add(stringlist->next, value);
|
||||
if (stringlist->value == NULL) {
|
||||
stringlist->value = strdup(value);
|
||||
assert(stringlist->value);
|
||||
if (stringlist->value == NULL)
|
||||
return NULL;
|
||||
return stringlist;
|
||||
}
|
||||
|
||||
stringlist->next = new_stringlist(value);
|
||||
assert(stringlist->next);
|
||||
if (stringlist->next == NULL)
|
||||
return NULL;
|
||||
|
||||
return stringlist->next;
|
||||
}
|
||||
|
||||
DYNAMIC_API stringlist_t *stringlist_append(stringlist_t *stringlist,
|
||||
stringlist_t *second)
|
||||
{
|
||||
assert(stringlist);
|
||||
|
||||
if (second == NULL || second->value == NULL)
|
||||
return stringlist;
|
||||
|
||||
stringlist_t *_s = stringlist;
|
||||
stringlist_t *_s2;
|
||||
for (_s2 = second; _s2 != NULL; _s2 = _s2->next) {
|
||||
_s = stringlist_add(_s, _s2->value);
|
||||
if (_s == NULL)
|
||||
return NULL;
|
||||
}
|
||||
return _s;
|
||||
}
|
||||
|
||||
int stringlist_length(const stringlist_t *stringlist)
|
||||
{
|
||||
int len = 1;
|
||||
stringlist_t *_stringlist;
|
||||
|
||||
assert(stringlist);
|
||||
|
||||
if (stringlist->value == NULL)
|
||||
return 0;
|
||||
|
||||
for (_stringlist=stringlist->next; _stringlist!=NULL; _stringlist=_stringlist->next)
|
||||
len += 1;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
void free_stringlist(stringlist_t *stringlist)
|
||||
{
|
||||
if (stringlist) {
|
||||
free_stringlist(stringlist->next);
|
||||
free(stringlist->value);
|
||||
free(stringlist);
|
||||
}
|
||||
}
|
||||
|
||||
DYNAMIC_API PEP_STATUS log_event(
|
||||
PEP_SESSION session, const char *title, const char *entity,
|
||||
const char *description, const char *comment
|
||||
|
|
|
@ -8,16 +8,8 @@ extern "C" {
|
|||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _EXPORT_PEP_ENGINE_DLL
|
||||
#define DYNAMIC_API __declspec(dllexport)
|
||||
#else
|
||||
#define DYNAMIC_API __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define DYNAMIC_API
|
||||
#endif
|
||||
|
||||
#include "dynamic_api.h"
|
||||
#include "stringlist.h"
|
||||
|
||||
#define PEP_VERSION "1.0"
|
||||
|
||||
|
@ -116,90 +108,6 @@ DYNAMIC_API PEP_STATUS init(PEP_SESSION *session);
|
|||
DYNAMIC_API void release(PEP_SESSION session);
|
||||
|
||||
|
||||
typedef struct _stringlist_t {
|
||||
char *value;
|
||||
struct _stringlist_t *next;
|
||||
} stringlist_t;
|
||||
|
||||
|
||||
// new_stringlist() - allocate a new stringlist
|
||||
//
|
||||
// parameters:
|
||||
// value (in) initial value as C string or NULL for empty list
|
||||
//
|
||||
// return value:
|
||||
// pointer to stringlist_t object or NULL if out of memory
|
||||
//
|
||||
// caveat:
|
||||
// the value is being copied before being added to the list
|
||||
// the original string is still being owned by the caller
|
||||
|
||||
DYNAMIC_API stringlist_t *new_stringlist(const char *value);
|
||||
|
||||
|
||||
// stringlist_dup() - duplicate a stringlist
|
||||
//
|
||||
// parameters:
|
||||
// src (in) stringlist to copy
|
||||
//
|
||||
// return value:
|
||||
// pointer to stringlist_t object or NULL if out of memory
|
||||
|
||||
DYNAMIC_API stringlist_t *stringlist_dup(const stringlist_t *src);
|
||||
|
||||
|
||||
// stringlist_add() - add key to stringlist
|
||||
//
|
||||
// parameters:
|
||||
// stringlist (in) stringlist struct or NULL to create a new one
|
||||
// value (in) value as C string
|
||||
//
|
||||
// return value:
|
||||
// pointer to last element in stringlist or NULL if out of memory
|
||||
//
|
||||
// caveat:
|
||||
// the value is being copied before being added to the list
|
||||
// the original string is still being owned by the caller
|
||||
|
||||
DYNAMIC_API stringlist_t *stringlist_add(stringlist_t *stringlist, const char *value);
|
||||
|
||||
|
||||
// stringlist_append() - append stringlist to stringlist
|
||||
//
|
||||
// parameters:
|
||||
// stringlist (in) stringlist struct to append to
|
||||
// second (in) stringlist struct to append
|
||||
//
|
||||
// return value:
|
||||
// pointer to last element in stringlist or NULL if out of memory
|
||||
//
|
||||
// caveat:
|
||||
// all values are being copied before being added to the list
|
||||
// the original values are still being owned by the caller
|
||||
|
||||
DYNAMIC_API stringlist_t *stringlist_append(stringlist_t *stringlist,
|
||||
stringlist_t *second);
|
||||
|
||||
|
||||
// stringlist_length() - get length of stringlist
|
||||
//
|
||||
// parameters:
|
||||
// stringlist (in) stringlist struct to determine length of
|
||||
//
|
||||
// return value:
|
||||
// length of stringlist in number of elements
|
||||
|
||||
DYNAMIC_API int stringlist_length(const stringlist_t *stringlist);
|
||||
|
||||
|
||||
// free_stringlist() - free memory occupied by stringlist
|
||||
//
|
||||
// parameters:
|
||||
// stringlist (in) stringlist to free
|
||||
|
||||
DYNAMIC_API void free_stringlist(stringlist_t *stringlist);
|
||||
|
||||
|
||||
// decrypt_and_verify() - decrypt and/or verify a message
|
||||
//
|
||||
// parameters:
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "stringlist.h"
|
||||
|
||||
|
||||
DYNAMIC_API stringlist_t *new_stringlist(const char *value)
|
||||
{
|
||||
stringlist_t *result = (stringlist_t *) calloc(1, sizeof(stringlist_t));
|
||||
if (result && value) {
|
||||
result->value = strdup(value);
|
||||
assert(result->value);
|
||||
if (result->value == 0) {
|
||||
free(result);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
DYNAMIC_API stringlist_t *stringlist_dup(const stringlist_t *src)
|
||||
{
|
||||
assert(src);
|
||||
if (src == NULL)
|
||||
return NULL;
|
||||
|
||||
stringlist_t *dst = new_stringlist(src->value);
|
||||
if (dst == NULL)
|
||||
return NULL;
|
||||
|
||||
if (src->next) {
|
||||
dst->next = stringlist_dup(src->next);
|
||||
if (dst->next == NULL) {
|
||||
free_stringlist(dst);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
DYNAMIC_API stringlist_t *stringlist_add(stringlist_t *stringlist, const char *value)
|
||||
{
|
||||
assert(value);
|
||||
|
||||
if (stringlist == NULL)
|
||||
return new_stringlist(value);
|
||||
|
||||
if (stringlist->next != NULL)
|
||||
return stringlist_add(stringlist->next, value);
|
||||
if (stringlist->value == NULL) {
|
||||
stringlist->value = strdup(value);
|
||||
assert(stringlist->value);
|
||||
if (stringlist->value == NULL)
|
||||
return NULL;
|
||||
return stringlist;
|
||||
}
|
||||
|
||||
stringlist->next = new_stringlist(value);
|
||||
assert(stringlist->next);
|
||||
if (stringlist->next == NULL)
|
||||
return NULL;
|
||||
|
||||
return stringlist->next;
|
||||
}
|
||||
|
||||
DYNAMIC_API stringlist_t *stringlist_append(stringlist_t *stringlist,
|
||||
stringlist_t *second)
|
||||
{
|
||||
assert(stringlist);
|
||||
|
||||
if (second == NULL || second->value == NULL)
|
||||
return stringlist;
|
||||
|
||||
stringlist_t *_s = stringlist;
|
||||
stringlist_t *_s2;
|
||||
for (_s2 = second; _s2 != NULL; _s2 = _s2->next) {
|
||||
_s = stringlist_add(_s, _s2->value);
|
||||
if (_s == NULL)
|
||||
return NULL;
|
||||
}
|
||||
return _s;
|
||||
}
|
||||
|
||||
DYNAMIC_API int stringlist_length(const stringlist_t *stringlist)
|
||||
{
|
||||
int len = 1;
|
||||
stringlist_t *_stringlist;
|
||||
|
||||
assert(stringlist);
|
||||
|
||||
if (stringlist->value == NULL)
|
||||
return 0;
|
||||
|
||||
for (_stringlist=stringlist->next; _stringlist!=NULL; _stringlist=_stringlist->next)
|
||||
len += 1;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
DYNAMIC_API void free_stringlist(stringlist_t *stringlist)
|
||||
{
|
||||
if (stringlist) {
|
||||
free_stringlist(stringlist->next);
|
||||
free(stringlist->value);
|
||||
free(stringlist);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
#pragma once
|
||||
|
||||
#include "dynamic_api.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct _stringlist_t {
|
||||
char *value;
|
||||
struct _stringlist_t *next;
|
||||
} stringlist_t;
|
||||
|
||||
|
||||
// new_stringlist() - allocate a new stringlist
|
||||
//
|
||||
// parameters:
|
||||
// value (in) initial value as C string or NULL for empty list
|
||||
//
|
||||
// return value:
|
||||
// pointer to stringlist_t object or NULL if out of memory
|
||||
//
|
||||
// caveat:
|
||||
// the value is being copied before being added to the list
|
||||
// the original string is still being owned by the caller
|
||||
|
||||
DYNAMIC_API stringlist_t *new_stringlist(const char *value);
|
||||
|
||||
|
||||
// stringlist_dup() - duplicate a stringlist
|
||||
//
|
||||
// parameters:
|
||||
// src (in) stringlist to copy
|
||||
//
|
||||
// return value:
|
||||
// pointer to stringlist_t object or NULL if out of memory
|
||||
|
||||
DYNAMIC_API stringlist_t *stringlist_dup(const stringlist_t *src);
|
||||
|
||||
|
||||
// stringlist_add() - add key to stringlist
|
||||
//
|
||||
// parameters:
|
||||
// stringlist (in) stringlist struct or NULL to create a new one
|
||||
// value (in) value as C string
|
||||
//
|
||||
// return value:
|
||||
// pointer to last element in stringlist or NULL if out of memory
|
||||
//
|
||||
// caveat:
|
||||
// the value is being copied before being added to the list
|
||||
// the original string is still being owned by the caller
|
||||
|
||||
DYNAMIC_API stringlist_t *stringlist_add(stringlist_t *stringlist, const char *value);
|
||||
|
||||
|
||||
// stringlist_append() - append stringlist to stringlist
|
||||
//
|
||||
// parameters:
|
||||
// stringlist (in) stringlist struct to append to
|
||||
// second (in) stringlist struct to append
|
||||
//
|
||||
// return value:
|
||||
// pointer to last element in stringlist or NULL if out of memory
|
||||
//
|
||||
// caveat:
|
||||
// all values are being copied before being added to the list
|
||||
// the original values are still being owned by the caller
|
||||
|
||||
DYNAMIC_API stringlist_t *stringlist_append(stringlist_t *stringlist,
|
||||
stringlist_t *second);
|
||||
|
||||
|
||||
// stringlist_length() - get length of stringlist
|
||||
//
|
||||
// parameters:
|
||||
// stringlist (in) stringlist struct to determine length of
|
||||
//
|
||||
// return value:
|
||||
// length of stringlist in number of elements
|
||||
|
||||
DYNAMIC_API int stringlist_length(const stringlist_t *stringlist);
|
||||
|
||||
|
||||
// free_stringlist() - free memory occupied by stringlist
|
||||
//
|
||||
// parameters:
|
||||
// stringlist (in) stringlist to free
|
||||
|
||||
DYNAMIC_API void free_stringlist(stringlist_t *stringlist);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,177 @@
|
|||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "stringpair.h"
|
||||
|
||||
DYNAMIC_API stringpair_t * new_stringpair(const char *key, const char *value)
|
||||
{
|
||||
stringpair_t *pair = NULL;
|
||||
|
||||
assert(key);
|
||||
assert(value),
|
||||
|
||||
pair = calloc(1, sizeof(stringpair_t));
|
||||
assert(pair);
|
||||
if (pair == NULL)
|
||||
goto enomem;
|
||||
|
||||
pair->key = strdup(key);
|
||||
assert(pair->key);
|
||||
if (pair->key == NULL)
|
||||
goto enomem;
|
||||
|
||||
pair->value = strdup(value);
|
||||
assert(pair->value);
|
||||
if (pair->value == NULL)
|
||||
goto enomem;
|
||||
|
||||
return pair;
|
||||
|
||||
enomem:
|
||||
free_stringpair(pair);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DYNAMIC_API void free_stringpair(stringpair_t * pair)
|
||||
{
|
||||
if (pair) {
|
||||
free(pair->key);
|
||||
free(pair->value);
|
||||
free(pair);
|
||||
}
|
||||
}
|
||||
|
||||
DYNAMIC_API stringpair_t * stringpair_dup(const stringpair_t *src)
|
||||
{
|
||||
assert(src);
|
||||
return new_stringpair(src->key, src->value);
|
||||
}
|
||||
|
||||
DYNAMIC_API stringpair_list_t *new_stringpair_list(const stringpair_t *value)
|
||||
{
|
||||
stringpair_list_t *result = (stringpair_list_t *) calloc(1,
|
||||
sizeof(stringpair_list_t));
|
||||
if (result && value) {
|
||||
result->value = stringpair_dup(value);
|
||||
if (result->value == 0) {
|
||||
free(result);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
DYNAMIC_API stringpair_list_t *stringpair_list_dup(
|
||||
const stringpair_list_t *src
|
||||
)
|
||||
{
|
||||
assert(src);
|
||||
if (src == NULL)
|
||||
return NULL;
|
||||
|
||||
stringpair_list_t *dst = new_stringpair_list(src->value);
|
||||
if (dst == NULL)
|
||||
return NULL;
|
||||
|
||||
if (src->next) {
|
||||
dst->next = stringpair_list_dup(src->next);
|
||||
if (dst->next == NULL) {
|
||||
free_stringpair_list(dst);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
DYNAMIC_API stringpair_list_t *stringpair_list_add(
|
||||
stringpair_list_t *stringpair_list,
|
||||
const stringpair_t *value
|
||||
)
|
||||
{
|
||||
assert(value);
|
||||
|
||||
if (stringpair_list == NULL)
|
||||
return new_stringpair_list(value);
|
||||
|
||||
if (stringpair_list->next != NULL)
|
||||
return stringpair_list_add(stringpair_list->next, value);
|
||||
if (stringpair_list->value == NULL) {
|
||||
stringpair_list->value = stringpair_dup(value);
|
||||
if (stringpair_list->value == NULL)
|
||||
return NULL;
|
||||
return stringpair_list;
|
||||
}
|
||||
|
||||
stringpair_list->next = new_stringpair_list(value);
|
||||
if (stringpair_list->next == NULL)
|
||||
return NULL;
|
||||
|
||||
return stringpair_list->next;
|
||||
}
|
||||
|
||||
DYNAMIC_API stringpair_list_t *stringpair_list_append(
|
||||
stringpair_list_t *stringpair_list,
|
||||
stringpair_list_t *second
|
||||
)
|
||||
{
|
||||
assert(stringpair_list);
|
||||
|
||||
if (second == NULL || second->value == NULL)
|
||||
return stringpair_list;
|
||||
|
||||
stringpair_list_t *_s = stringpair_list;
|
||||
stringpair_list_t *_s2;
|
||||
for (_s2 = second; _s2 != NULL; _s2 = _s2->next) {
|
||||
_s = stringpair_list_add(_s, _s2->value);
|
||||
if (_s == NULL)
|
||||
return NULL;
|
||||
}
|
||||
return _s;
|
||||
}
|
||||
|
||||
DYNAMIC_API int stringpair_list_length(
|
||||
const stringpair_list_t *stringpair_list
|
||||
)
|
||||
{
|
||||
int len = 1;
|
||||
stringpair_list_t *_stringpair_list;
|
||||
|
||||
assert(stringpair_list);
|
||||
|
||||
if (stringpair_list->value == NULL)
|
||||
return 0;
|
||||
|
||||
for (_stringpair_list=stringpair_list->next; _stringpair_list!=NULL;
|
||||
_stringpair_list=_stringpair_list->next)
|
||||
len += 1;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
DYNAMIC_API void free_stringpair_list(stringpair_list_t *stringpair_list)
|
||||
{
|
||||
if (stringpair_list) {
|
||||
free_stringpair_list(stringpair_list->next);
|
||||
free_stringpair(stringpair_list->value);
|
||||
free(stringpair_list);
|
||||
}
|
||||
}
|
||||
|
||||
DYNAMIC_API stringpair_t *stringpair_list_find(
|
||||
stringpair_list_t *stringpair_list,
|
||||
const char *key
|
||||
)
|
||||
{
|
||||
assert(key);
|
||||
|
||||
if (stringpair_list == NULL)
|
||||
return NULL;
|
||||
|
||||
if (strcoll(stringpair_list->value->key, key) == 0)
|
||||
return stringpair_list->value;
|
||||
else
|
||||
return stringpair_list_find(stringpair_list->next, key);
|
||||
}
|
||||
|
|
@ -0,0 +1,163 @@
|
|||
#pragma once
|
||||
|
||||
#include "dynamic_api.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct _stringpair_t {
|
||||
char * key;
|
||||
char * value;
|
||||
} stringpair_t;
|
||||
|
||||
|
||||
// new_stringpair() - allocate new stringpair_t
|
||||
//
|
||||
// parameters:
|
||||
// key (in) utf-8 string used as key
|
||||
// value (in) utf-8 string containing the value
|
||||
//
|
||||
// return value:
|
||||
// pointer to stringpair_t or NULL on failure
|
||||
//
|
||||
// caveat:
|
||||
// key and value are copied and remain in the ownership of the caller
|
||||
|
||||
DYNAMIC_API stringpair_t * new_stringpair(const char *key, const char *value);
|
||||
|
||||
|
||||
// free_stringpair() - free memory allocated by stringpair_t
|
||||
//
|
||||
// parameters:
|
||||
// pair (in) pointer to stringpair_t to free
|
||||
|
||||
DYNAMIC_API void free_stringpair(stringpair_t * pair);
|
||||
|
||||
|
||||
// stringpair_dup() - duplicate stringpair_t (deep copy)
|
||||
//
|
||||
// parameters:
|
||||
// src (in) pointer to stringpair_t to duplicate
|
||||
//
|
||||
// return value:
|
||||
// pointer to copy of src or NULL on failure
|
||||
|
||||
DYNAMIC_API stringpair_t * stringpair_dup(const stringpair_t *src);
|
||||
|
||||
|
||||
typedef struct _stringpair_list_t {
|
||||
stringpair_t *value;
|
||||
struct _stringpair_list_t *next;
|
||||
} stringpair_list_t;
|
||||
|
||||
|
||||
// new_stringpair_list() - allocate a new stringpair_list
|
||||
//
|
||||
// parameters:
|
||||
// value (in) initial value as C string or NULL for empty
|
||||
// list
|
||||
//
|
||||
// return value:
|
||||
// pointer to stringpair_list_t object or NULL if out of memory
|
||||
//
|
||||
// caveat:
|
||||
// the value is being copied before being added to the list
|
||||
// the original value is still being owned by the caller
|
||||
|
||||
DYNAMIC_API stringpair_list_t *new_stringpair_list(const stringpair_t *value);
|
||||
|
||||
|
||||
// stringpair_list_dup() - duplicate a stringpair_list
|
||||
//
|
||||
// parameters:
|
||||
// src (in) stringpair_list to copy
|
||||
//
|
||||
// return value:
|
||||
// pointer to stringpair_list_t object or NULL if out of memory
|
||||
|
||||
DYNAMIC_API stringpair_list_t *stringpair_list_dup(
|
||||
const stringpair_list_t *src
|
||||
);
|
||||
|
||||
|
||||
// stringpair_list_add() - add key to stringpair_list
|
||||
//
|
||||
// parameters:
|
||||
// stringpair_list (in) stringpair_list struct or NULL to create a new
|
||||
// one
|
||||
// value (in) value as C string
|
||||
//
|
||||
// return value:
|
||||
// pointer to last element in stringpair_list or NULL if out of memory
|
||||
//
|
||||
// caveat:
|
||||
// the value is being copied before being added to the list
|
||||
// the original value is still being owned by the caller
|
||||
|
||||
DYNAMIC_API stringpair_list_t *stringpair_list_add(
|
||||
stringpair_list_t *stringpair_list,
|
||||
const stringpair_t *value
|
||||
);
|
||||
|
||||
|
||||
// stringpair_list_append() - append stringpair_list to stringpair_list
|
||||
//
|
||||
// parameters:
|
||||
// stringpair_list (in) stringpair_list struct to append to
|
||||
// second (in) stringpair_list struct to append
|
||||
//
|
||||
// return value:
|
||||
// pointer to last element in stringpair_list or NULL if out of memory
|
||||
//
|
||||
// caveat:
|
||||
// all values are being copied before being added to the list
|
||||
// the original values are still being owned by the caller
|
||||
|
||||
DYNAMIC_API stringpair_list_t *stringpair_list_append(
|
||||
stringpair_list_t *stringpair_list,
|
||||
stringpair_list_t *second
|
||||
);
|
||||
|
||||
|
||||
// stringpair_list_length() - get length of stringpair_list
|
||||
//
|
||||
// parameters:
|
||||
// stringpair_list (in) stringpair_list struct to determine length of
|
||||
//
|
||||
// return value:
|
||||
// length of stringpair_list in number of elements
|
||||
|
||||
DYNAMIC_API int stringpair_list_length(
|
||||
const stringpair_list_t *stringpair_list
|
||||
);
|
||||
|
||||
|
||||
// free_stringpair_list() - free memory occupied by stringpair_list
|
||||
//
|
||||
// parameters:
|
||||
// stringpair_list (in) stringpair_list to free
|
||||
|
||||
DYNAMIC_API void free_stringpair_list(stringpair_list_t *stringpair_list);
|
||||
|
||||
|
||||
// stringpair_list_find() - find element in list using key
|
||||
//
|
||||
// parameters:
|
||||
// stringpair_list (in) list to search
|
||||
// key (in) key to search for
|
||||
//
|
||||
// return value:
|
||||
// stringpair_t if found or NULL if not
|
||||
|
||||
DYNAMIC_API stringpair_t *stringpair_list_find(
|
||||
stringpair_list_t *stringpair_list,
|
||||
const char *key
|
||||
);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
521
src/transport.c
521
src/transport.c
|
@ -23,525 +23,12 @@ PEP_STATUS init_transport_system(PEP_SESSION session, bool in_first)
|
|||
return PEP_STATUS_OK;
|
||||
}
|
||||
|
||||
void release_transport_system(PEP_SESSION session, bool out_last)
|
||||
DYNAMIC_API void release_transport_system(PEP_SESSION session, bool out_last)
|
||||
{
|
||||
assert(session);
|
||||
// nothing yet
|
||||
}
|
||||
|
||||
DYNAMIC_API identity_list *new_identity_list(pEp_identity *ident)
|
||||
{
|
||||
identity_list *id_list = calloc(1, sizeof(identity_list));
|
||||
assert(id_list);
|
||||
if (id_list == NULL)
|
||||
return NULL;
|
||||
|
||||
id_list->ident = ident;
|
||||
|
||||
return id_list;
|
||||
}
|
||||
|
||||
DYNAMIC_API identity_list *identity_list_dup(const identity_list *src)
|
||||
{
|
||||
assert(src);
|
||||
|
||||
identity_list *id_list = new_identity_list(identity_dup(src->ident));
|
||||
assert(id_list);
|
||||
if (id_list == NULL)
|
||||
return NULL;
|
||||
|
||||
if (src->next) {
|
||||
id_list->next = identity_list_dup(src->next);
|
||||
if (id_list->next == NULL) {
|
||||
free_identity_list(id_list);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return id_list;
|
||||
}
|
||||
|
||||
DYNAMIC_API void free_identity_list(identity_list *id_list)
|
||||
{
|
||||
if (id_list) {
|
||||
free_identity_list(id_list->next);
|
||||
free_identity(id_list->ident);
|
||||
free(id_list);
|
||||
}
|
||||
}
|
||||
|
||||
DYNAMIC_API identity_list *identity_list_add(identity_list *id_list, pEp_identity *ident)
|
||||
{
|
||||
assert(ident);
|
||||
|
||||
if (id_list == NULL)
|
||||
return new_identity_list(ident);
|
||||
|
||||
if (id_list->ident == NULL) {
|
||||
id_list->ident = ident;
|
||||
return id_list;
|
||||
}
|
||||
else if (id_list->next == NULL) {
|
||||
id_list->next = new_identity_list(ident);
|
||||
return id_list->next;
|
||||
}
|
||||
else {
|
||||
return identity_list_add(id_list->next, ident);
|
||||
}
|
||||
}
|
||||
|
||||
DYNAMIC_API bloblist_t *new_bloblist(char *blob, size_t size, const char *mime_type,
|
||||
const char *file_name)
|
||||
{
|
||||
bloblist_t * bloblist = calloc(1, sizeof(bloblist_t));
|
||||
assert(bloblist);
|
||||
if (bloblist == NULL)
|
||||
return NULL;
|
||||
|
||||
if (mime_type) {
|
||||
bloblist->mime_type = strdup(mime_type);
|
||||
if (bloblist->mime_type == NULL) {
|
||||
free(bloblist);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (file_name) {
|
||||
bloblist->file_name = strdup(file_name);
|
||||
if (bloblist->file_name == NULL) {
|
||||
free(bloblist->mime_type);
|
||||
free(bloblist);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bloblist->data = blob;
|
||||
bloblist->size = size;
|
||||
|
||||
return bloblist;
|
||||
}
|
||||
|
||||
DYNAMIC_API void free_bloblist(bloblist_t *bloblist)
|
||||
{
|
||||
if (bloblist) {
|
||||
if (bloblist->next)
|
||||
free_bloblist(bloblist->next);
|
||||
free(bloblist->data);
|
||||
free(bloblist->mime_type);
|
||||
free(bloblist->file_name);
|
||||
free(bloblist);
|
||||
}
|
||||
}
|
||||
|
||||
DYNAMIC_API bloblist_t *bloblist_dup(const bloblist_t *src)
|
||||
{
|
||||
bloblist_t *bloblist = NULL;
|
||||
|
||||
assert(src);
|
||||
|
||||
bloblist = new_bloblist(src->data, src->size, src->mime_type, src->file_name);
|
||||
if (bloblist == NULL)
|
||||
goto enomem;
|
||||
|
||||
if (src->next) {
|
||||
bloblist->next = bloblist_dup(src->next);
|
||||
if (bloblist->next == NULL)
|
||||
goto enomem;
|
||||
}
|
||||
|
||||
return bloblist;
|
||||
|
||||
enomem:
|
||||
free_bloblist(bloblist);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DYNAMIC_API bloblist_t *bloblist_add(bloblist_t *bloblist, char *blob, size_t size,
|
||||
const char *mime_type, const char *file_name)
|
||||
{
|
||||
assert(blob);
|
||||
|
||||
if (bloblist == NULL)
|
||||
return new_bloblist(blob, size, mime_type, file_name);
|
||||
|
||||
if (bloblist->data == NULL) {
|
||||
if (mime_type) {
|
||||
bloblist->mime_type = strdup(mime_type);
|
||||
if (bloblist->mime_type == NULL) {
|
||||
free(bloblist);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (file_name) {
|
||||
bloblist->file_name = strdup(file_name);
|
||||
if (bloblist->file_name == NULL) {
|
||||
free(bloblist->mime_type);
|
||||
free(bloblist);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
bloblist->data = blob;
|
||||
bloblist->size = size;
|
||||
return bloblist;
|
||||
}
|
||||
|
||||
if (bloblist->next == NULL) {
|
||||
bloblist->next = new_bloblist(blob, size, mime_type, file_name);
|
||||
return bloblist->next;
|
||||
}
|
||||
|
||||
return bloblist_add(bloblist->next, blob, size, mime_type, file_name);
|
||||
}
|
||||
|
||||
DYNAMIC_API stringpair_t * new_stringpair(const char *key, const char *value)
|
||||
{
|
||||
stringpair_t *pair = NULL;
|
||||
|
||||
assert(key);
|
||||
assert(value),
|
||||
|
||||
pair = calloc(1, sizeof(stringpair_t));
|
||||
assert(pair);
|
||||
if (pair == NULL)
|
||||
goto enomem;
|
||||
|
||||
pair->key = strdup(key);
|
||||
assert(pair->key);
|
||||
if (pair->key == NULL)
|
||||
goto enomem;
|
||||
|
||||
pair->value = strdup(value);
|
||||
assert(pair->value);
|
||||
if (pair->value == NULL)
|
||||
goto enomem;
|
||||
|
||||
return pair;
|
||||
|
||||
enomem:
|
||||
free_stringpair(pair);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DYNAMIC_API void free_stringpair(stringpair_t * pair)
|
||||
{
|
||||
if (pair) {
|
||||
free(pair->key);
|
||||
free(pair->value);
|
||||
free(pair);
|
||||
}
|
||||
}
|
||||
|
||||
DYNAMIC_API stringpair_t * stringpair_dup(const stringpair_t *src)
|
||||
{
|
||||
assert(src);
|
||||
return new_stringpair(src->key, src->value);
|
||||
}
|
||||
|
||||
DYNAMIC_API stringpair_map_t * new_stringpair_map(const stringpair_t *pair)
|
||||
{
|
||||
stringpair_map_t *map = NULL;
|
||||
|
||||
map = calloc(1, sizeof(stringpair_map_t));
|
||||
assert(map);
|
||||
if (map == NULL)
|
||||
goto enomem;
|
||||
|
||||
if (pair) {
|
||||
map->pair = stringpair_dup(pair);
|
||||
if (map->pair == NULL)
|
||||
goto enomem;
|
||||
}
|
||||
|
||||
return map;
|
||||
|
||||
enomem:
|
||||
free_stringpair_map(map);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DYNAMIC_API void free_stringpair_map(stringpair_map_t *map)
|
||||
{
|
||||
if (map) {
|
||||
free_stringpair_map(map->left);
|
||||
free_stringpair_map(map->right);
|
||||
free_stringpair(map->pair);
|
||||
free(map);
|
||||
}
|
||||
}
|
||||
|
||||
static stringpair_map_t * _stringpair_map_dup(
|
||||
const stringpair_map_t *src,
|
||||
stringpair_map_t *parent
|
||||
)
|
||||
{
|
||||
stringpair_map_t *map = NULL;
|
||||
|
||||
assert(src);
|
||||
|
||||
map = new_stringpair_map(src->pair);
|
||||
if (map == NULL)
|
||||
goto enomem;
|
||||
|
||||
map->color = src->color;
|
||||
|
||||
if (src->left) {
|
||||
map->left = _stringpair_map_dup(src->left, map);
|
||||
if (map->left == NULL)
|
||||
goto enomem;
|
||||
}
|
||||
|
||||
if (src->right) {
|
||||
map->right = _stringpair_map_dup(src->right, map);
|
||||
if (map->right == NULL)
|
||||
goto enomem;
|
||||
}
|
||||
|
||||
map->parent_ref = parent;
|
||||
|
||||
return map;
|
||||
|
||||
enomem:
|
||||
free_stringpair_map(map);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DYNAMIC_API stringpair_map_t * stringpair_map_dup(const stringpair_map_t *src)
|
||||
{
|
||||
return _stringpair_map_dup(src, NULL);
|
||||
}
|
||||
|
||||
DYNAMIC_API stringpair_map_t * stringpair_map_find(
|
||||
stringpair_map_t *map,
|
||||
const char *key
|
||||
)
|
||||
{
|
||||
int c;
|
||||
|
||||
assert(key);
|
||||
|
||||
if (map == NULL || map->pair == NULL) // empty map
|
||||
return NULL;
|
||||
|
||||
c = strcoll(map->pair->key, key);
|
||||
|
||||
if (c == 0)
|
||||
return map;
|
||||
else if (c < 0)
|
||||
return stringpair_map_find(map->left, key);
|
||||
else
|
||||
return stringpair_map_find(map->right, key);
|
||||
}
|
||||
|
||||
static stringpair_map_t * stringpair_map_grandparent(stringpair_map_t *node)
|
||||
{
|
||||
assert(node);
|
||||
|
||||
if (node->parent_ref == NULL)
|
||||
return NULL;
|
||||
|
||||
return node->parent_ref->parent_ref;
|
||||
}
|
||||
|
||||
static stringpair_map_t * stringpair_map_uncle(stringpair_map_t *node)
|
||||
{
|
||||
assert(stringpair_map_grandparent(node));
|
||||
|
||||
if (node->parent_ref == stringpair_map_grandparent(node)->left)
|
||||
return stringpair_map_grandparent(node)->right;
|
||||
else
|
||||
return stringpair_map_grandparent(node)->left;
|
||||
}
|
||||
|
||||
static stringpair_map_t * _stringpair_map_add(
|
||||
stringpair_map_t *map,
|
||||
stringpair_t * pair
|
||||
)
|
||||
{
|
||||
int c;
|
||||
|
||||
assert(map);
|
||||
assert(pair);
|
||||
|
||||
if (map->pair == NULL) {
|
||||
map->pair = stringpair_dup(pair);
|
||||
if (map->pair == NULL)
|
||||
return NULL;
|
||||
return map;
|
||||
}
|
||||
|
||||
assert(map->pair->key);
|
||||
assert(pair->key);
|
||||
|
||||
c = strcoll(map->pair->key, pair->key);
|
||||
if (c == 0) {
|
||||
free(map->pair->value);
|
||||
|
||||
assert(pair->value);
|
||||
|
||||
map->pair->value = strdup(pair->value);
|
||||
assert(map->pair->value);
|
||||
if (map->pair->value == NULL)
|
||||
return NULL;
|
||||
}
|
||||
else if (c < 0) {
|
||||
if (map->left == NULL) {
|
||||
map->left = new_stringpair_map(pair);
|
||||
if (map->left)
|
||||
return NULL;
|
||||
map = map->left;
|
||||
}
|
||||
else {
|
||||
map = _stringpair_map_add(map->left, pair);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (map->right == NULL) {
|
||||
map->right = new_stringpair_map(pair);
|
||||
if (map->right)
|
||||
return NULL;
|
||||
map = map->right;
|
||||
}
|
||||
else {
|
||||
map = _stringpair_map_add(map->right, pair);
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
static void stringpair_map_rotate_left(stringpair_map_t *l)
|
||||
{
|
||||
stringpair_map_t * _parent;
|
||||
stringpair_map_t * _r;
|
||||
|
||||
assert(l);
|
||||
assert(l->parent_ref);
|
||||
assert(l->right);
|
||||
|
||||
_parent = l->parent_ref;
|
||||
_r = l->right;
|
||||
|
||||
l->right = _r->left;
|
||||
_r->left = l;
|
||||
|
||||
if (_parent->left == l)
|
||||
_parent->left = _r;
|
||||
else
|
||||
_parent->right = _r;
|
||||
}
|
||||
|
||||
static void stringpair_map_rotate_right(stringpair_map_t *r)
|
||||
{
|
||||
stringpair_map_t * _parent;
|
||||
stringpair_map_t * _l;
|
||||
|
||||
assert(r);
|
||||
assert(r->parent_ref);
|
||||
assert(r->left);
|
||||
|
||||
_parent = r->parent_ref;
|
||||
_l = r->left;
|
||||
|
||||
r->left = _l->right;
|
||||
_l->right = r;
|
||||
|
||||
if (_parent->left == r)
|
||||
_parent->left = _l;
|
||||
else
|
||||
_parent->right = _l;
|
||||
}
|
||||
|
||||
static void stringpair_map_case5(stringpair_map_t *map)
|
||||
{
|
||||
map->parent_ref->color = rbt_black;
|
||||
stringpair_map_grandparent(map)->color = rbt_red;
|
||||
|
||||
if (map == map->parent_ref->left &&
|
||||
map->parent_ref == stringpair_map_grandparent(map)->left) {
|
||||
stringpair_map_rotate_right(stringpair_map_grandparent(map));
|
||||