#include "mgvalue.h"
#include <stdlib.h>
#include <string.h>
#include "mgallocator.h"
#include "mgclient.h"
mg_string *mg_string_alloc(uint32_t size, mg_allocator *allocator) {
char *block = mg_allocator_malloc(allocator, sizeof(mg_string) + size);
if (!block) {
return NULL;
}
mg_string *str = (mg_string *)block;
str->data = block + sizeof(mg_string);
return str;
}
mg_list *mg_list_alloc(uint32_t size, mg_allocator *allocator) {
size_t elements_size = size * sizeof(mg_value *);
char *block = mg_allocator_malloc(allocator, sizeof(mg_list) + elements_size);
if (!block) {
return NULL;
}
mg_list *list = (mg_list *)block;
list->elements = (mg_value **)(block + sizeof(mg_list));
return list;
}
mg_map *mg_map_alloc(uint32_t size, mg_allocator *allocator) {
size_t keys_size = size * sizeof(mg_string *);
size_t values_size = size * sizeof(mg_value *);
char *block =
mg_allocator_malloc(allocator, sizeof(mg_map) + keys_size + values_size);
if (!block) {
return NULL;
}
mg_map *map = (mg_map *)block;
map->keys = (mg_string **)(block + sizeof(mg_map));
map->values = (mg_value **)(block + sizeof(mg_map) + keys_size);
return map;
}
mg_node *mg_node_alloc(uint32_t label_count, mg_allocator *allocator) {
size_t labels_size = label_count * sizeof(mg_string *);
char *block = mg_allocator_malloc(allocator, sizeof(mg_node) + labels_size);
if (!block) {
return NULL;
}
mg_node *node = (mg_node *)block;
node->labels = (mg_string **)(block + sizeof(mg_node));
return node;
}
mg_path *mg_path_alloc(uint32_t node_count, uint32_t relationship_count,
uint32_t sequence_length, mg_allocator *allocator) {
size_t nodes_size = node_count * sizeof(mg_node *);
size_t relationships_size =
relationship_count * sizeof(mg_unbound_relationship *);
size_t sequence_size = sequence_length * sizeof(int64_t);
char *block =
mg_allocator_malloc(allocator, sizeof(mg_path) + nodes_size +
relationships_size + sequence_size);
if (!block) {
return NULL;
}
mg_path *path = (mg_path *)block;
path->nodes = (mg_node **)(block + sizeof(mg_path));
path->relationships =
(mg_unbound_relationship **)(block + sizeof(mg_path) + nodes_size);
path->sequence =
(int64_t *)(block + sizeof(mg_path) + nodes_size + relationships_size);
return path;
}
mg_date *mg_date_alloc(mg_allocator *allocator) {
char *block = mg_allocator_malloc(allocator, sizeof(mg_date));
if (!block) {
return NULL;
}
mg_date *date = (mg_date *)block;
return date;
}
mg_time *mg_time_alloc(mg_allocator *allocator) {
char *block = mg_allocator_malloc(allocator, sizeof(mg_time));
if (!block) {
return NULL;
}
mg_time *time = (mg_time *)block;
return time;
}
mg_local_time *mg_local_time_alloc(mg_allocator *allocator) {
char *block = mg_allocator_malloc(allocator, sizeof(mg_local_time));
if (!block) {
return NULL;
}
mg_local_time *local_time = (mg_local_time *)block;
return local_time;
}
mg_date_time *mg_date_time_alloc(mg_allocator *allocator) {
char *block = mg_allocator_malloc(allocator, sizeof(mg_date_time));
if (!block) {
return NULL;
}
mg_date_time *date_time = (mg_date_time *)block;
return date_time;
}
mg_date_time_zone_id *mg_date_time_zone_id_alloc(mg_allocator *allocator) {
char *block = mg_allocator_malloc(allocator, sizeof(mg_date_time_zone_id));
if (!block) {
return NULL;
}
mg_date_time_zone_id *date_time_zone_id = (mg_date_time_zone_id *)block;
date_time_zone_id->seconds = 0;
date_time_zone_id->nanoseconds = 0;
date_time_zone_id->timezone_name = NULL;
return date_time_zone_id;
}
mg_local_date_time *mg_local_date_time_alloc(mg_allocator *allocator) {
char *block = mg_allocator_malloc(allocator, sizeof(mg_local_date_time));
if (!block) {
return NULL;
}
mg_local_date_time *local_date_time = (mg_local_date_time *)block;
return local_date_time;
}
mg_duration *mg_duration_alloc(mg_allocator *allocator) {
char *block = mg_allocator_malloc(allocator, sizeof(mg_duration));
if (!block) {
return NULL;
}
mg_duration *duration = (mg_duration *)block;
return duration;
}
mg_point_2d *mg_point_2d_alloc(mg_allocator *allocator) {
char *block = mg_allocator_malloc(allocator, sizeof(mg_point_2d));
if (!block) {
return NULL;
}
mg_point_2d *point_2d = (mg_point_2d *)block;
return point_2d;
}
mg_point_3d *mg_point_3d_alloc(mg_allocator *allocator) {
char *block = mg_allocator_malloc(allocator, sizeof(mg_point_3d));
if (!block) {
return NULL;
}
mg_point_3d *point_3d = (mg_point_3d *)block;
return point_3d;
}
mg_value *mg_value_make_null(void) {
mg_value *value = mg_allocator_malloc(&mg_system_allocator, sizeof(mg_value));
if (!value) {
return NULL;
}
value->type = MG_VALUE_TYPE_NULL;
return value;
}
mg_value *mg_value_make_bool(int val) {
mg_value *value = mg_allocator_malloc(&mg_system_allocator, sizeof(mg_value));
if (!value) {
return NULL;
}
value->type = MG_VALUE_TYPE_BOOL;
value->bool_v = val;
return value;
}
mg_value *mg_value_make_integer(int64_t val) {
mg_value *value = mg_allocator_malloc(&mg_system_allocator, sizeof(mg_value));
if (!value) {
return NULL;
}
value->type = MG_VALUE_TYPE_INTEGER;
value->integer_v = val;
return value;
}
mg_value *mg_value_make_float(double val) {
mg_value *value = mg_allocator_malloc(&mg_system_allocator, sizeof(mg_value));
if (!value) {
return NULL;
}
value->type = MG_VALUE_TYPE_FLOAT;
value->float_v = val;
return value;
}
mg_value *mg_value_make_string(const char *str) {
mg_string *tstr = mg_string_make(str);
if (!tstr) {
return NULL;
}
return mg_value_make_string2(tstr);
}
mg_value *mg_value_make_string2(mg_string *str) {
mg_value *value = mg_allocator_malloc(&mg_system_allocator, sizeof(mg_value));
if (!value) {
return NULL;
}
value->type = MG_VALUE_TYPE_STRING;
value->string_v = str;
return value;
}
mg_value *mg_value_make_list(mg_list *list) {
mg_value *value = mg_allocator_malloc(&mg_system_allocator, sizeof(mg_value));
if (!value) {
return NULL;
}
value->type = MG_VALUE_TYPE_LIST;
value->list_v = list;
return value;
}
mg_value *mg_value_make_map(mg_map *map) {
mg_value *value = mg_allocator_malloc(&mg_system_allocator, sizeof(mg_value));
if (!value) {
return NULL;
}
value->type = MG_VALUE_TYPE_MAP;
value->map_v = map;
return value;
}
mg_value *mg_value_make_node(mg_node *node) {
mg_value *value = mg_allocator_malloc(&mg_system_allocator, sizeof(mg_value));
if (!value) {
return NULL;
}
value->type = MG_VALUE_TYPE_NODE;
value->node_v = node;
return value;
}
mg_value *mg_value_make_relationship(mg_relationship *rel) {
mg_value *value = mg_allocator_malloc(&mg_system_allocator, sizeof(mg_value));
if (!value) {
return NULL;
}
value->type = MG_VALUE_TYPE_RELATIONSHIP;
value->relationship_v = rel;
return value;
}
mg_value *mg_value_make_unbound_relationship(mg_unbound_relationship *rel) {
mg_value *value = mg_allocator_malloc(&mg_system_allocator, sizeof(mg_value));
if (!value) {
return NULL;
}
value->type = MG_VALUE_TYPE_UNBOUND_RELATIONSHIP;
value->unbound_relationship_v = rel;
return value;
}
mg_value *mg_value_make_path(mg_path *path) {
mg_value *value = mg_allocator_malloc(&mg_system_allocator, sizeof(mg_value));
if (!value) {
return NULL;
}
value->type = MG_VALUE_TYPE_PATH;
value->path_v = path;
return value;
}
mg_value *mg_value_make_date(mg_date *date) {
mg_value *value = mg_allocator_malloc(&mg_system_allocator, sizeof(mg_value));
if (!value) {
return NULL;
}
value->type = MG_VALUE_TYPE_DATE;
value->date_v = date;
return value;
}
mg_value *mg_value_make_time(mg_time *time) {
mg_value *value = mg_allocator_malloc(&mg_system_allocator, sizeof(mg_value));
if (!value) {
return NULL;
}
value->type = MG_VALUE_TYPE_TIME;
value->time_v = time;
return value;
}
mg_value *mg_value_make_local_time(mg_local_time *local_time) {
mg_value *value = mg_allocator_malloc(&mg_system_allocator, sizeof(mg_value));
if (!value) {
return NULL;
}
value->type = MG_VALUE_TYPE_LOCAL_TIME;
value->local_time_v = local_time;
return value;
}
mg_value *mg_value_make_date_time(mg_date_time *date_time) {
mg_value *value = mg_allocator_malloc(&mg_system_allocator, sizeof(mg_value));
if (!value) {
return NULL;
}
value->type = MG_VALUE_TYPE_DATE_TIME;
value->date_time_v = date_time;
return value;
}
mg_value *mg_value_make_date_time_zone_id(
mg_date_time_zone_id *date_time_zone_id) {
mg_value *value = mg_allocator_malloc(&mg_system_allocator, sizeof(mg_value));
if (!value) {
return NULL;
}
value->type = MG_VALUE_TYPE_DATE_TIME_ZONE_ID;
value->date_time_zone_id_v = date_time_zone_id;
return value;
}
mg_value *mg_value_make_local_date_time(mg_local_date_time *local_date_time) {
mg_value *value = mg_allocator_malloc(&mg_system_allocator, sizeof(mg_value));
if (!value) {
return NULL;
}
value->type = MG_VALUE_TYPE_LOCAL_DATE_TIME;
value->local_date_time_v = local_date_time;
return value;
}
mg_value *mg_value_make_duration(mg_duration *duration) {
mg_value *value = mg_allocator_malloc(&mg_system_allocator, sizeof(mg_value));
if (!value) {
return NULL;
}
value->type = MG_VALUE_TYPE_DURATION;
value->duration_v = duration;
return value;
}
mg_value *mg_value_make_point_2d(mg_point_2d *point_2d) {
mg_value *value = mg_allocator_malloc(&mg_system_allocator, sizeof(mg_value));
if (!value) {
return NULL;
}
value->type = MG_VALUE_TYPE_POINT_2D;
value->point_2d_v = point_2d;
return value;
}
mg_value *mg_value_make_point_3d(mg_point_3d *point_3d) {
mg_value *value = mg_allocator_malloc(&mg_system_allocator, sizeof(mg_value));
if (!value) {
return NULL;
}
value->type = MG_VALUE_TYPE_POINT_3D;
value->point_3d_v = point_3d;
return value;
}
enum mg_value_type mg_value_get_type(const mg_value *val) { return val->type; }
int mg_value_bool(const mg_value *val) { return val->bool_v; }
int64_t mg_value_integer(const mg_value *val) { return val->integer_v; }
double mg_value_float(const mg_value *val) { return val->float_v; }
const mg_string *mg_value_string(const mg_value *val) { return val->string_v; }
const mg_list *mg_value_list(const mg_value *val) { return val->list_v; }
const mg_map *mg_value_map(const mg_value *val) { return val->map_v; }
const mg_node *mg_value_node(const mg_value *val) { return val->node_v; }
const mg_relationship *mg_value_relationship(const mg_value *val) {
return val->relationship_v;
}
const mg_unbound_relationship *mg_value_unbound_relationship(
const mg_value *val) {
return val->unbound_relationship_v;
}
const mg_path *mg_value_path(const mg_value *val) { return val->path_v; }
const mg_date *mg_value_date(const mg_value *val) { return val->date_v; }
const mg_time *mg_value_time(const mg_value *val) { return val->time_v; }
const mg_local_time *mg_value_local_time(const mg_value *val) {
return val->local_time_v;
}
const mg_date_time *mg_value_date_time(const mg_value *val) {
return val->date_time_v;
}
const mg_date_time_zone_id *mg_value_date_time_zone_id(const mg_value *val) {
return val->date_time_zone_id_v;
}
const mg_local_date_time *mg_value_local_date_time(const mg_value *val) {
return val->local_date_time_v;
}
const mg_duration *mg_value_duration(const mg_value *val) {
return val->duration_v;
}
const mg_point_2d *mg_value_point_2d(const mg_value *val) {
return val->point_2d_v;
}
const mg_point_3d *mg_value_point_3d(const mg_value *val) {
return val->point_3d_v;
}
mg_value *mg_value_copy_ca(const mg_value *val, mg_allocator *allocator) {
if (!val) {
return NULL;
}
mg_value *new_val = mg_allocator_malloc(allocator, sizeof(mg_value));
if (!new_val) {
return NULL;
}
new_val->type = val->type;
switch (val->type) {
case MG_VALUE_TYPE_NULL:
break;
case MG_VALUE_TYPE_BOOL:
new_val->bool_v = val->bool_v;
break;
case MG_VALUE_TYPE_INTEGER:
new_val->integer_v = val->integer_v;
break;
case MG_VALUE_TYPE_FLOAT:
new_val->float_v = val->float_v;
break;
case MG_VALUE_TYPE_STRING:
new_val->string_v = mg_string_copy_ca(val->string_v, allocator);
if (!new_val->string_v) {
goto cleanup;
}
break;
case MG_VALUE_TYPE_LIST:
new_val->list_v = mg_list_copy_ca(val->list_v, allocator);
if (!new_val->list_v) {
goto cleanup;
}
break;
case MG_VALUE_TYPE_MAP:
new_val->map_v = mg_map_copy_ca(val->map_v, allocator);
if (!new_val->map_v) {
goto cleanup;
}
break;
case MG_VALUE_TYPE_NODE:
new_val->node_v = mg_node_copy_ca(val->node_v, allocator);
if (!new_val->node_v) {
goto cleanup;
}
break;
case MG_VALUE_TYPE_RELATIONSHIP:
new_val->relationship_v =
mg_relationship_copy_ca(val->relationship_v, allocator);
if (!new_val->relationship_v) {
goto cleanup;
}
break;
case MG_VALUE_TYPE_UNBOUND_RELATIONSHIP:
new_val->unbound_relationship_v = mg_unbound_relationship_copy_ca(
val->unbound_relationship_v, allocator);
if (!new_val->unbound_relationship_v) {
goto cleanup;
}
break;
case MG_VALUE_TYPE_PATH:
new_val->path_v = mg_path_copy_ca(val->path_v, allocator);
if (!new_val->path_v) {
goto cleanup;
}
break;
case MG_VALUE_TYPE_DATE:
new_val->date_v = mg_date_copy_ca(val->date_v, allocator);
if (!new_val->date_v) {
goto cleanup;
}
break;
case MG_VALUE_TYPE_TIME:
new_val->time_v = mg_time_copy_ca(val->time_v, allocator);
if (!new_val->time_v) {
goto cleanup;
}
break;
case MG_VALUE_TYPE_LOCAL_TIME:
new_val->local_time_v =
mg_local_time_copy_ca(val->local_time_v, allocator);
if (!new_val->local_time_v) {
goto cleanup;
}
break;
case MG_VALUE_TYPE_DATE_TIME:
new_val->date_time_v = mg_date_time_copy_ca(val->date_time_v, allocator);
if (!new_val->date_time_v) {
goto cleanup;
}
break;
case MG_VALUE_TYPE_DATE_TIME_ZONE_ID:
new_val->date_time_zone_id_v =
mg_date_time_zone_id_copy_ca(val->date_time_zone_id_v, allocator);
if (!new_val->date_time_zone_id_v) {
goto cleanup;
}
break;
case MG_VALUE_TYPE_LOCAL_DATE_TIME:
new_val->local_date_time_v =
mg_local_date_time_copy_ca(val->local_date_time_v, allocator);
if (!new_val->local_date_time_v) {
goto cleanup;
}
break;
case MG_VALUE_TYPE_DURATION:
new_val->duration_v = mg_duration_copy_ca(val->duration_v, allocator);
if (!new_val->duration_v) {
goto cleanup;
}
break;
case MG_VALUE_TYPE_POINT_2D:
new_val->point_2d_v = mg_point_2d_copy_ca(val->point_2d_v, allocator);
if (!new_val->point_2d_v) {
goto cleanup;
}
break;
case MG_VALUE_TYPE_POINT_3D:
new_val->point_3d_v = mg_point_3d_copy_ca(val->point_3d_v, allocator);
if (!new_val->point_3d_v) {
goto cleanup;
}
break;
case MG_VALUE_TYPE_UNKNOWN:
break;
}
return new_val;
cleanup:
mg_allocator_free(&mg_system_allocator, new_val);
return NULL;
}
mg_value *mg_value_copy(const mg_value *val) {
return mg_value_copy_ca(val, &mg_system_allocator);
}
void mg_value_destroy_ca(mg_value *val, mg_allocator *allocator) {
if (!val) {
return;
}
switch (val->type) {
case MG_VALUE_TYPE_NULL:
case MG_VALUE_TYPE_BOOL:
case MG_VALUE_TYPE_INTEGER:
case MG_VALUE_TYPE_FLOAT:
break;
case MG_VALUE_TYPE_DATE:
mg_date_destroy_ca(val->date_v, allocator);
break;
case MG_VALUE_TYPE_TIME:
mg_time_destroy_ca(val->time_v, allocator);
break;
case MG_VALUE_TYPE_LOCAL_TIME:
mg_local_time_destroy_ca(val->local_time_v, allocator);
break;
case MG_VALUE_TYPE_DATE_TIME:
mg_date_time_destroy_ca(val->date_time_v, allocator);
break;
case MG_VALUE_TYPE_DATE_TIME_ZONE_ID:
mg_date_time_zone_id_destroy_ca(val->date_time_zone_id_v, allocator);
break;
case MG_VALUE_TYPE_LOCAL_DATE_TIME:
mg_local_date_time_destroy_ca(val->local_date_time_v, allocator);
break;
case MG_VALUE_TYPE_DURATION:
mg_duration_destroy_ca(val->duration_v, allocator);
break;
case MG_VALUE_TYPE_POINT_2D:
mg_point_2d_destroy_ca(val->point_2d_v, allocator);
break;
case MG_VALUE_TYPE_POINT_3D:
mg_point_3d_destroy_ca(val->point_3d_v, allocator);
break;
case MG_VALUE_TYPE_STRING:
mg_string_destroy_ca(val->string_v, allocator);
break;
case MG_VALUE_TYPE_LIST:
mg_list_destroy_ca(val->list_v, allocator);
break;
case MG_VALUE_TYPE_MAP:
mg_map_destroy_ca(val->map_v, allocator);
break;
case MG_VALUE_TYPE_NODE:
mg_node_destroy_ca(val->node_v, allocator);
break;
case MG_VALUE_TYPE_RELATIONSHIP:
mg_relationship_destroy_ca(val->relationship_v, allocator);
break;
case MG_VALUE_TYPE_UNBOUND_RELATIONSHIP:
mg_unbound_relationship_destroy_ca(val->unbound_relationship_v,
allocator);
break;
case MG_VALUE_TYPE_PATH:
mg_path_destroy_ca(val->path_v, allocator);
break;
case MG_VALUE_TYPE_UNKNOWN:
break;
}
mg_allocator_free(allocator, val);
}
void mg_value_destroy(mg_value *val) {
if (!val) {
return;
}
mg_value_destroy_ca(val, &mg_system_allocator);
}
mg_string *mg_string_make(const char *str) {
size_t size = strlen(str);
if (size >= UINT32_MAX) return NULL;
return mg_string_make2((uint32_t)size, str);
}
mg_string *mg_string_make2(uint32_t len, const char *data) {
mg_string *str = mg_string_alloc(len, &mg_system_allocator);
if (!str) {
return NULL;
}
str->size = len;
memcpy(str->data, data, len);
return str;
}
const char *mg_string_data(const mg_string *str) { return str->data; }
uint32_t mg_string_size(const mg_string *str) { return str->size; }
mg_string *mg_string_copy_ca(const mg_string *src, mg_allocator *allocator) {
if (!src) {
return NULL;
}
mg_string *str = mg_string_alloc(src->size, allocator);
if (!str) {
return NULL;
}
str->size = src->size;
memcpy(str->data, src->data, src->size);
return str;
}
mg_string *mg_string_copy(const mg_string *str) {
return mg_string_copy_ca(str, &mg_system_allocator);
}
void mg_string_destroy_ca(mg_string *str, mg_allocator *allocator) {
if (!str) {
return;
}
mg_allocator_free(allocator, str);
}
void mg_string_destroy(mg_string *str) {
mg_string_destroy_ca(str, &mg_system_allocator);
}
static int mg_string_eq(uint32_t size1, const char *str1, uint32_t size2,
const char *str2) {
if (size1 != size2) return 0;
return memcmp(str1, str2, size1) == 0;
}
mg_list *mg_list_make_empty(uint32_t capacity) {
mg_list *list = mg_list_alloc(capacity, &mg_system_allocator);
if (!list) {
return NULL;
}
list->size = 0;
list->capacity = capacity;
return list;
}
int mg_list_append(mg_list *list, mg_value *value) {
if (list->size >= list->capacity) {
return MG_ERROR_CONTAINER_FULL;
}
list->elements[list->size] = value;
list->size++;
return 0;
}
uint32_t mg_list_size(const mg_list *list) { return list->size; }
const mg_value *mg_list_at(const mg_list *list, uint32_t pos) {
if (pos < list->size) {
return list->elements[pos];
} else {
return NULL;
}
}
mg_list *mg_list_copy_ca(const mg_list *list, mg_allocator *allocator) {
if (!list) {
return NULL;
}
mg_list *nlist = mg_list_alloc(list->size, allocator);
if (!nlist) {
return NULL;
}
nlist->capacity = list->size;
nlist->size = 0;
for (uint32_t i = 0; i < list->size; ++i) {
nlist->elements[i] = mg_value_copy_ca(list->elements[i], allocator);
if (!nlist->elements[i]) {
goto cleanup;
}
nlist->size++;
}
return nlist;
cleanup:
for (uint32_t i = 0; i < nlist->size; ++i) {
mg_value_destroy(nlist->elements[i]);
}
mg_allocator_free(allocator, nlist);
return NULL;
}
mg_list *mg_list_copy(const mg_list *list) {
return mg_list_copy_ca(list, &mg_system_allocator);
}
void mg_list_destroy_ca(mg_list *list, mg_allocator *allocator) {
if (!list) {
return;
}
for (uint32_t i = 0; i < list->size; ++i) {
mg_value_destroy_ca(list->elements[i], allocator);
}
mg_allocator_free(allocator, list);
}
void mg_list_destroy(mg_list *list) {
mg_list_destroy_ca(list, &mg_system_allocator);
}
mg_map *mg_map_make_empty(uint32_t capacity) {
mg_map *map = mg_map_alloc(capacity, &mg_system_allocator);
if (!map) {
return NULL;
}
map->size = 0;
map->capacity = capacity;
return map;
}
static uint32_t mg_map_find_key(const mg_map *map, uint32_t key_size,
const char *key_data) {
for (uint32_t i = 0; i < map->size; ++i) {
if (mg_string_eq(map->keys[i]->size, map->keys[i]->data, key_size,
key_data)) {
return i;
}
}
return map->size;
}
static void mg_map_append(mg_map *map, mg_string *key, mg_value *value) {
map->keys[map->size] = key;
map->values[map->size] = value;
map->size++;
}
int mg_map_insert(mg_map *map, const char *key_str, mg_value *value) {
size_t key_size = strlen(key_str);
if (key_size >= UINT32_MAX) {
return MG_ERROR_SIZE_EXCEEDED;
}
if (map->size >= map->capacity) {
return MG_ERROR_CONTAINER_FULL;
}
if (mg_map_find_key(map, (uint32_t)key_size, key_str) != map->size) {
return MG_ERROR_DUPLICATE_KEY;
}
mg_string *key = mg_string_make2((uint32_t)key_size, key_str);
if (!key) {
return MG_ERROR_OOM;
}
mg_map_append(map, key, value);
return 0;
}
int mg_map_insert2(mg_map *map, mg_string *key, mg_value *value) {
if (map->size >= map->capacity) {
return MG_ERROR_CONTAINER_FULL;
}
if (mg_map_find_key(map, key->size, key->data) != map->size) {
return MG_ERROR_DUPLICATE_KEY;
}
mg_map_append(map, key, value);
return 0;
}
int mg_map_insert_unsafe(mg_map *map, const char *key_str, mg_value *value) {
if (map->size >= map->capacity) {
return MG_ERROR_CONTAINER_FULL;
}
size_t key_len = strlen(key_str);
if (key_len >= UINT32_MAX) {
return MG_ERROR_SIZE_EXCEEDED;
}
mg_string *key = mg_string_make2((uint32_t)key_len, key_str);
if (key == NULL) {
return MG_ERROR_OOM;
}
mg_map_append(map, key, value);
return 0;
}
int mg_map_insert_unsafe2(mg_map *map, mg_string *key, mg_value *value) {
if (map->size >= map->capacity) {
return MG_ERROR_CONTAINER_FULL;
}
mg_map_append(map, key, value);
return 0;
}
const mg_value *mg_map_at(const mg_map *map, const char *key_str) {
size_t key_size = strlen(key_str);
if (key_size >= UINT32_MAX) {
return NULL;
}
return mg_map_at2(map, (uint32_t)key_size, key_str);
}
const mg_value *mg_map_at2(const mg_map *map, uint32_t key_size,
const char *key_data) {
uint32_t pos = mg_map_find_key(map, key_size, key_data);
if (pos != map->size) {
return map->values[pos];
}
return NULL;
}
uint32_t mg_map_size(const mg_map *map) { return map->size; }
const mg_string *mg_map_key_at(const mg_map *map, uint32_t pos) {
if (pos < map->size) {
return map->keys[pos];
} else {
return NULL;
}
}
const mg_value *mg_map_value_at(const mg_map *map, uint32_t pos) {
if (pos < map->size) {
return map->values[pos];
} else {
return NULL;
}
}
mg_map *mg_map_copy_ca(const mg_map *map, mg_allocator *allocator) {
if (!map) {
return NULL;
}
mg_map *nmap = mg_map_alloc(map->size, allocator);
if (!nmap) {
return NULL;
}
nmap->capacity = map->size;
nmap->size = map->size;
uint32_t keys_copied = 0;
uint32_t values_copied = 0;
for (uint32_t i = 0; i < map->size; ++i) {
nmap->keys[i] = mg_string_copy_ca(map->keys[i], allocator);
if (!nmap->keys[i]) {
goto cleanup;
}
keys_copied++;
nmap->values[i] = mg_value_copy_ca(map->values[i], allocator);
if (!nmap->values[i]) {
goto cleanup;
}
values_copied++;
}
return nmap;
cleanup:
for (uint32_t i = 0; i < keys_copied; ++i) {
mg_string_destroy(map->keys[i]);
}
for (uint32_t i = 0; i < values_copied; ++i) {
mg_value_destroy(map->values[i]);
}
mg_allocator_free(&mg_system_allocator, nmap);
return NULL;
}
mg_map *mg_map_copy(const mg_map *map) {
return mg_map_copy_ca(map, &mg_system_allocator);
}
void mg_map_destroy_ca(mg_map *map, mg_allocator *allocator) {
if (!map || map == &mg_empty_map) {
return;
}
for (uint32_t i = 0; i < map->size; ++i) {
mg_string_destroy_ca(map->keys[i], allocator);
mg_value_destroy_ca(map->values[i], allocator);
}
mg_allocator_free(allocator, map);
}
void mg_map_destroy(mg_map *map) {
mg_map_destroy_ca(map, &mg_system_allocator);
}
int64_t mg_node_id(const mg_node *node) { return node->id; }
uint32_t mg_node_label_count(const mg_node *node) { return node->label_count; }
const mg_string *mg_node_label_at(const mg_node *node, uint32_t pos) {
if (pos < node->label_count) {
return node->labels[pos];
} else {
return NULL;
}
}
const mg_map *mg_node_properties(const mg_node *node) {
return node->properties;
}
mg_node *mg_node_copy_ca(const mg_node *node, mg_allocator *allocator) {
if (!node) {
return NULL;
}
mg_node *nnode = mg_node_alloc(node->label_count, &mg_system_allocator);
if (!nnode) {
return NULL;
}
nnode->id = node->id;
nnode->label_count = 0;
for (uint32_t i = 0; i < node->label_count; ++i) {
nnode->labels[i] = mg_string_copy_ca(node->labels[i], allocator);
if (!nnode->labels[i]) {
goto cleanup;
}
nnode->label_count++;
}
nnode->properties = mg_map_copy_ca(node->properties, allocator);
if (!nnode->properties) {
goto cleanup;
}
return nnode;
cleanup:
for (uint32_t i = 0; i < nnode->label_count; ++i) {
mg_string_destroy(nnode->labels[i]);
}
mg_allocator_free(&mg_system_allocator, nnode);
return NULL;
}
mg_node *mg_node_copy(const mg_node *node) {
return mg_node_copy_ca(node, &mg_system_allocator);
}
void mg_node_destroy_ca(mg_node *node, mg_allocator *allocator) {
if (!node) {
return;
}
for (uint32_t i = 0; i < node->label_count; ++i) {
mg_string_destroy_ca(node->labels[i], allocator);
}
mg_map_destroy_ca(node->properties, allocator);
mg_allocator_free(allocator, node);
}
void mg_node_destroy(mg_node *node) {
mg_node_destroy_ca(node, &mg_system_allocator);
}
int64_t mg_relationship_id(const mg_relationship *rel) { return rel->id; }
int64_t mg_relationship_start_id(const mg_relationship *rel) {
return rel->start_id;
}
int64_t mg_relationship_end_id(const mg_relationship *rel) {
return rel->end_id;
}
const mg_string *mg_relationship_type(const mg_relationship *rel) {
return rel->type;
}
const mg_map *mg_relationship_properties(const mg_relationship *rel) {
return rel->properties;
}
mg_relationship *mg_relationship_copy_ca(const mg_relationship *rel,
mg_allocator *allocator) {
if (!rel) {
return NULL;
}
mg_relationship *nrel =
mg_allocator_malloc(&mg_system_allocator, sizeof(mg_relationship));
if (!nrel) {
return NULL;
}
nrel->id = rel->id;
nrel->start_id = rel->start_id;
nrel->end_id = rel->end_id;
nrel->type = mg_string_copy_ca(rel->type, allocator);
if (!nrel->type) {
goto cleanup;
}
nrel->properties = mg_map_copy_ca(rel->properties, allocator);
if (!nrel->properties) {
goto cleanup_type;
}
return nrel;
cleanup_type:
mg_string_destroy(nrel->type);
cleanup:
mg_allocator_free(&mg_system_allocator, nrel);
return NULL;
}
mg_relationship *mg_relationship_copy(const mg_relationship *rel) {
return mg_relationship_copy_ca(rel, &mg_system_allocator);
}
void mg_relationship_destroy_ca(mg_relationship *rel, mg_allocator *allocator) {
if (!rel) {
return;
}
mg_string_destroy_ca(rel->type, allocator);
mg_map_destroy_ca(rel->properties, allocator);
mg_allocator_free(allocator, rel);
}
void mg_relationship_destroy(mg_relationship *rel) {
mg_relationship_destroy_ca(rel, &mg_system_allocator);
}
int64_t mg_unbound_relationship_id(const mg_unbound_relationship *rel) {
return rel->id;
}
const mg_string *mg_unbound_relationship_type(
const mg_unbound_relationship *rel) {
return rel->type;
}
const mg_map *mg_unbound_relationship_properties(
const mg_unbound_relationship *rel) {
return rel->properties;
}
mg_unbound_relationship *mg_unbound_relationship_copy_ca(
const mg_unbound_relationship *rel, mg_allocator *allocator) {
mg_unbound_relationship *nrel = mg_allocator_malloc(
&mg_system_allocator, sizeof(mg_unbound_relationship));
if (!nrel) {
return NULL;
}
nrel->id = rel->id;
nrel->type = mg_string_copy_ca(rel->type, allocator);
if (!nrel->type) {
goto cleanup;
}
nrel->properties = mg_map_copy_ca(rel->properties, allocator);
if (!nrel->properties) {
goto cleanup_type;
}
return nrel;
cleanup_type:
mg_string_destroy(nrel->type);
cleanup:
mg_allocator_free(&mg_system_allocator, nrel);
return NULL;
}
mg_unbound_relationship *mg_unbound_relationship_copy(
const mg_unbound_relationship *rel) {
return mg_unbound_relationship_copy_ca(rel, &mg_system_allocator);
}
void mg_unbound_relationship_destroy_ca(mg_unbound_relationship *rel,
mg_allocator *allocator) {
if (!rel) {
return;
}
mg_string_destroy_ca(rel->type, allocator);
mg_map_destroy_ca(rel->properties, allocator);
mg_allocator_free(allocator, rel);
}
void mg_unbound_relationship_destroy(mg_unbound_relationship *rel) {
mg_unbound_relationship_destroy_ca(rel, &mg_system_allocator);
}
uint32_t mg_path_length(const mg_path *path) {
return path->sequence_length / 2;
}
const mg_node *mg_path_node_at(const mg_path *path, uint32_t pos) {
if (pos <= path->sequence_length / 2) {
if (pos == 0) {
return path->nodes[0];
}
return path->nodes[path->sequence[2 * pos - 1]];
} else {
return NULL;
}
}
const mg_unbound_relationship *mg_path_relationship_at(const mg_path *path,
uint32_t pos) {
if (pos < path->sequence_length / 2) {
int64_t idx = path->sequence[2 * pos];
if (idx < 0) {
idx = -idx;
}
return path->relationships[idx - 1];
} else {
return NULL;
}
}
int mg_path_relationship_reversed_at(const mg_path *path, uint32_t pos) {
if (pos < path->sequence_length / 2) {
int64_t idx = path->sequence[2 * pos];
if (idx < 0) {
return 1;
} else {
return 0;
}
} else {
return -1;
}
}
mg_path *mg_path_copy_ca(const mg_path *path, mg_allocator *allocator) {
mg_path *npath = mg_path_alloc(path->node_count, path->relationship_count,
path->sequence_length, &mg_system_allocator);
if (!npath) {
return NULL;
}
npath->node_count = 0;
for (uint32_t i = 0; i < path->node_count; ++i) {
npath->nodes[i] = mg_node_copy_ca(path->nodes[i], allocator);
if (!npath->nodes[i]) {
goto cleanup;
}
npath->node_count++;
}
npath->relationship_count = 0;
for (uint32_t i = 0; i < path->relationship_count; ++i) {
npath->relationships[i] =
mg_unbound_relationship_copy_ca(path->relationships[i], allocator);
if (!npath->relationships[i]) {
goto cleanup;
}
npath->relationship_count++;
}
npath->sequence_length = path->sequence_length;
memcpy(npath->sequence, path->sequence,
path->sequence_length * sizeof(int64_t));
return npath;
cleanup:
for (uint32_t i = 0; i < npath->node_count; ++i) {
mg_node_destroy(npath->nodes[i]);
}
for (uint32_t i = 0; i < npath->relationship_count; ++i) {
mg_unbound_relationship_destroy(npath->relationships[i]);
}
mg_allocator_free(&mg_system_allocator, npath);
return NULL;
}
mg_path *mg_path_copy(const mg_path *path) {
return mg_path_copy_ca(path, &mg_system_allocator);
}
void mg_path_destroy_ca(mg_path *path, mg_allocator *allocator) {
if (!path) {
return;
}
for (uint32_t i = 0; i < path->node_count; ++i) {
mg_node_destroy_ca(path->nodes[i], allocator);
}
for (uint32_t i = 0; i < path->relationship_count; ++i) {
mg_unbound_relationship_destroy_ca(path->relationships[i], allocator);
}
mg_allocator_free(allocator, path);
}
void mg_path_destroy(mg_path *path) {
mg_path_destroy_ca(path, &mg_system_allocator);
}
int64_t mg_date_days(const mg_date *date) { return date->days; }
int64_t mg_time_nanoseconds(const mg_time *time) { return time->nanoseconds; }
int64_t mg_time_tz_offset_seconds(const mg_time *time) {
return time->tz_offset_seconds;
}
int64_t mg_local_time_nanoseconds(const mg_local_time *local_time) {
return local_time->nanoseconds;
}
int64_t mg_date_time_seconds(const mg_date_time *date_time) {
return date_time->seconds;
}
int64_t mg_date_time_nanoseconds(const mg_date_time *date_time) {
return date_time->nanoseconds;
}
int64_t mg_date_time_tz_offset_minutes(const mg_date_time *date_time) {
return date_time->tz_offset_minutes;
}
int64_t mg_date_time_zone_id_seconds(
const mg_date_time_zone_id *date_time_zone_id) {
return date_time_zone_id->seconds;
}
int64_t mg_date_time_zone_id_nanoseconds(
const mg_date_time_zone_id *date_time_zone_id) {
return date_time_zone_id->nanoseconds;
}
const mg_string *mg_date_time_zone_id_timezone_name(
const mg_date_time_zone_id *date_time_zone_id) {
return date_time_zone_id->timezone_name;
}
int64_t mg_local_date_time_seconds(const mg_local_date_time *local_date_time) {
return local_date_time->seconds;
}
int64_t mg_local_date_time_nanoseconds(
const mg_local_date_time *local_date_time) {
return local_date_time->nanoseconds;
}
int64_t mg_duration_months(const mg_duration *duration) {
return duration->months;
}
int64_t mg_duration_days(const mg_duration *duration) { return duration->days; }
int64_t mg_duration_seconds(const mg_duration *duration) {
return duration->seconds;
}
int64_t mg_duration_nanoseconds(const mg_duration *duration) {
return duration->nanoseconds;
}
int64_t mg_point_2d_srid(const mg_point_2d *point_2d) { return point_2d->srid; }
double mg_point_2d_x(const mg_point_2d *point_2d) { return point_2d->x; }
double mg_point_2d_y(const mg_point_2d *point_2d) { return point_2d->y; }
int64_t mg_point_3d_srid(const mg_point_3d *point_3d) { return point_3d->srid; }
double mg_point_3d_x(const mg_point_3d *point_3d) { return point_3d->x; }
double mg_point_3d_y(const mg_point_3d *point_3d) { return point_3d->y; }
double mg_point_3d_z(const mg_point_3d *point_3d) { return point_3d->z; }
mg_date *mg_date_copy_ca(const mg_date *src, mg_allocator *allocator) {
if (!src) {
return NULL;
}
mg_date *date = mg_date_alloc(allocator);
if (!date) {
return NULL;
}
memcpy(date, src, sizeof(mg_date));
return date;
}
mg_date *mg_date_copy(const mg_date *date) {
return mg_date_copy_ca(date, &mg_system_allocator);
}
void mg_date_destroy_ca(mg_date *date, mg_allocator *allocator) {
if (!date) {
return;
}
mg_allocator_free(allocator, date);
}
void mg_date_destroy(mg_date *date) {
mg_date_destroy_ca(date, &mg_system_allocator);
}
mg_time *mg_time_copy_ca(const mg_time *src, mg_allocator *allocator) {
if (!src) {
return NULL;
}
mg_time *time = mg_time_alloc(allocator);
if (!time) {
return NULL;
}
memcpy(time, src, sizeof(mg_time));
return time;
}
mg_time *mg_time_copy(const mg_time *time) {
return mg_time_copy_ca(time, &mg_system_allocator);
}
void mg_time_destroy_ca(mg_time *time, mg_allocator *allocator) {
if (!time) {
return;
}
mg_allocator_free(allocator, time);
}
void mg_time_destroy(mg_time *time) {
mg_time_destroy_ca(time, &mg_system_allocator);
}
mg_local_time *mg_local_time_copy_ca(const mg_local_time *src,
mg_allocator *allocator) {
if (!src) {
return NULL;
}
mg_local_time *local_time = mg_local_time_alloc(allocator);
if (!local_time) {
return NULL;
}
memcpy(local_time, src, sizeof(mg_local_time));
return local_time;
}
mg_local_time *mg_local_time_copy(const mg_local_time *local_time) {
return mg_local_time_copy_ca(local_time, &mg_system_allocator);
}
void mg_local_time_destroy_ca(mg_local_time *local_time,
mg_allocator *allocator) {
if (!local_time) {
return;
}
mg_allocator_free(allocator, local_time);
}
void mg_local_time_destroy(mg_local_time *local_time) {
mg_local_time_destroy_ca(local_time, &mg_system_allocator);
}
mg_date_time *mg_date_time_copy_ca(const mg_date_time *src,
mg_allocator *allocator) {
if (!src) {
return NULL;
}
mg_date_time *date_time = mg_date_time_alloc(allocator);
if (!date_time) {
return NULL;
}
memcpy(date_time, src, sizeof(mg_date_time));
return date_time;
}
mg_date_time *mg_date_time_copy(const mg_date_time *date_time) {
return mg_date_time_copy_ca(date_time, &mg_system_allocator);
}
void mg_date_time_destroy_ca(mg_date_time *date_time, mg_allocator *allocator) {
if (!date_time) {
return;
}
mg_allocator_free(allocator, date_time);
}
void mg_date_time_destroy(mg_date_time *date_time) {
mg_date_time_destroy_ca(date_time, &mg_system_allocator);
}
mg_date_time_zone_id *mg_date_time_zone_id_copy_ca(
const mg_date_time_zone_id *src, mg_allocator *allocator) {
if (!src) {
return NULL;
}
mg_date_time_zone_id *date_time_zone_id =
mg_date_time_zone_id_alloc(allocator);
if (!date_time_zone_id) {
return NULL;
}
date_time_zone_id->seconds = src->seconds;
date_time_zone_id->nanoseconds = src->nanoseconds;
date_time_zone_id->timezone_name =
mg_string_copy_ca(src->timezone_name, allocator);
if (!date_time_zone_id->timezone_name) {
mg_date_time_zone_id_destroy_ca(date_time_zone_id, allocator);
return NULL;
}
return date_time_zone_id;
}
mg_date_time_zone_id *mg_date_time_zone_id_copy(
const mg_date_time_zone_id *date_time_zone_id) {
return mg_date_time_zone_id_copy_ca(date_time_zone_id, &mg_system_allocator);
}
void mg_date_time_zone_id_destroy_ca(mg_date_time_zone_id *date_time_zone_id,
mg_allocator *allocator) {
if (!date_time_zone_id) {
return;
}
mg_string_destroy_ca(date_time_zone_id->timezone_name, allocator);
mg_allocator_free(allocator, date_time_zone_id);
}
void mg_date_time_zone_id_destroy(mg_date_time_zone_id *date_time_zone_id) {
mg_date_time_zone_id_destroy_ca(date_time_zone_id, &mg_system_allocator);
}
mg_local_date_time *mg_local_date_time_copy_ca(const mg_local_date_time *src,
mg_allocator *allocator) {
if (!src) {
return NULL;
}
mg_local_date_time *local_date_time = mg_local_date_time_alloc(allocator);
if (!local_date_time) {
return NULL;
}
memcpy(local_date_time, src, sizeof(mg_local_date_time));
return local_date_time;
}
mg_local_date_time *mg_local_date_time_copy(
const mg_local_date_time *local_date_time) {
return mg_local_date_time_copy_ca(local_date_time, &mg_system_allocator);
}
void mg_local_date_time_destroy_ca(mg_local_date_time *local_date_time,
mg_allocator *allocator) {
if (!local_date_time) {
return;
}
mg_allocator_free(allocator, local_date_time);
}
void mg_local_date_time_destroy(mg_local_date_time *local_date_time) {
mg_local_date_time_destroy_ca(local_date_time, &mg_system_allocator);
}
mg_duration *mg_duration_copy_ca(const mg_duration *src,
mg_allocator *allocator) {
if (!src) {
return NULL;
}
mg_duration *duration = mg_duration_alloc(allocator);
if (!duration) {
return NULL;
}
memcpy(duration, src, sizeof(mg_duration));
return duration;
}
mg_duration *mg_duration_copy(const mg_duration *duration) {
return mg_duration_copy_ca(duration, &mg_system_allocator);
}
void mg_duration_destroy_ca(mg_duration *duration, mg_allocator *allocator) {
if (!duration) {
return;
}
mg_allocator_free(allocator, duration);
}
void mg_duration_destroy(mg_duration *duration) {
mg_duration_destroy_ca(duration, &mg_system_allocator);
}
mg_point_2d *mg_point_2d_copy_ca(const mg_point_2d *src,
mg_allocator *allocator) {
if (!src) {
return NULL;
}
mg_point_2d *point_2d = mg_point_2d_alloc(allocator);
if (!point_2d) {
return NULL;
}
memcpy(point_2d, src, sizeof(mg_point_2d));
return point_2d;
}
mg_point_2d *mg_point_2d_copy(const mg_point_2d *point_2d) {
return mg_point_2d_copy_ca(point_2d, &mg_system_allocator);
}
void mg_point_2d_destroy_ca(mg_point_2d *point_2d, mg_allocator *allocator) {
if (!point_2d) {
return;
}
mg_allocator_free(allocator, point_2d);
}
void mg_point_2d_destroy(mg_point_2d *point_2d) {
mg_point_2d_destroy_ca(point_2d, &mg_system_allocator);
}
mg_point_3d *mg_point_3d_copy_ca(const mg_point_3d *src,
mg_allocator *allocator) {
if (!src) {
return NULL;
}
mg_point_3d *point_3d = mg_point_3d_alloc(allocator);
if (!point_3d) {
return NULL;
}
memcpy(point_3d, src, sizeof(mg_point_3d));
return point_3d;
}
mg_point_3d *mg_point_3d_copy(const mg_point_3d *point_3d) {
return mg_point_3d_copy_ca(point_3d, &mg_system_allocator);
}
void mg_point_3d_destroy_ca(mg_point_3d *point_3d, mg_allocator *allocator) {
if (!point_3d) {
return;
}
mg_allocator_free(allocator, point_3d);
}
void mg_point_3d_destroy(mg_point_3d *point_3d) {
mg_point_3d_destroy_ca(point_3d, &mg_system_allocator);
}
mg_node *mg_node_make(int64_t id, uint32_t label_count, mg_string **labels,
mg_map *properties) {
mg_node *node = mg_node_alloc(label_count, &mg_system_allocator);
if (!node) {
return NULL;
}
node->id = id;
node->label_count = label_count;
memcpy(node->labels, labels, label_count * sizeof(mg_string *));
node->properties = properties;
return node;
}
mg_relationship *mg_relationship_make(int64_t id, int64_t start_id,
int64_t end_id, mg_string *type,
mg_map *properties) {
mg_relationship *rel =
mg_allocator_malloc(&mg_system_allocator, sizeof(mg_relationship));
if (!rel) {
return NULL;
}
rel->id = id;
rel->start_id = start_id;
rel->end_id = end_id;
rel->type = type;
rel->properties = properties;
return rel;
}
mg_unbound_relationship *mg_unbound_relationship_make(int64_t id,
mg_string *type,
mg_map *properties) {
mg_unbound_relationship *rel = mg_allocator_malloc(
&mg_system_allocator, sizeof(mg_unbound_relationship));
if (!rel) {
return NULL;
}
rel->id = id;
rel->type = type;
rel->properties = properties;
return rel;
}
mg_path *mg_path_make(uint32_t node_count, mg_node **nodes,
uint32_t relationship_count,
mg_unbound_relationship **relationships,
uint32_t sequence_length, const int64_t *const sequence) {
mg_path *path = mg_path_alloc(node_count, relationship_count, sequence_length,
&mg_system_allocator);
if (!path) {
return NULL;
}
path->node_count = node_count;
memcpy(path->nodes, nodes, node_count * sizeof(mg_node *));
path->relationship_count = relationship_count;
memcpy(path->relationships, relationships,
relationship_count * sizeof(mg_unbound_relationship *));
path->sequence_length = sequence_length;
memcpy(path->sequence, sequence, sequence_length * sizeof(int64_t));
return path;
}
mg_date *mg_date_make(int64_t days) {
mg_date *date = mg_date_alloc(&mg_system_allocator);
if (!date) {
return NULL;
}
date->days = days;
return date;
}
mg_local_time *mg_local_time_make(int64_t nanoseconds) {
mg_local_time *lt = mg_local_time_alloc(&mg_system_allocator);
if (!lt) {
return NULL;
}
lt->nanoseconds = nanoseconds;
return lt;
}
mg_date_time *mg_date_time_make(int64_t seconds, int64_t nanoseconds,
int32_t tz_offset_minutes) {
mg_date_time *dt = mg_date_time_alloc(&mg_system_allocator);
if (!dt) {
return NULL;
}
dt->seconds = seconds;
dt->nanoseconds = nanoseconds;
dt->tz_offset_minutes = tz_offset_minutes;
return dt;
}
mg_date_time_zone_id *mg_date_time_zone_id_make(int64_t seconds,
int64_t nanoseconds,
const char *timezone_name) {
mg_date_time_zone_id *dt_zone_id =
mg_date_time_zone_id_alloc(&mg_system_allocator);
if (!dt_zone_id) {
return NULL;
}
mg_string *tz_name = mg_string_make(timezone_name);
if (!tz_name) {
mg_date_time_zone_id_destroy_ca(dt_zone_id, &mg_system_allocator);
return NULL;
}
dt_zone_id->seconds = seconds;
dt_zone_id->nanoseconds = nanoseconds;
dt_zone_id->timezone_name = tz_name;
return dt_zone_id;
}
mg_local_date_time *mg_local_date_time_make(int64_t seconds,
int64_t nanoseconds) {
mg_local_date_time *ldt = mg_local_date_time_alloc(&mg_system_allocator);
if (!ldt) {
return NULL;
}
ldt->seconds = seconds;
ldt->nanoseconds = nanoseconds;
return ldt;
}
mg_duration *mg_duration_make(int64_t months, int64_t days, int64_t seconds,
int64_t nanoseconds) {
mg_duration *dur = mg_duration_alloc(&mg_system_allocator);
if (!dur) {
return NULL;
}
dur->months = months;
dur->days = days;
dur->seconds = seconds;
dur->nanoseconds = nanoseconds;
return dur;
}
mg_point_2d *mg_point_2d_make(uint16_t srid, double x_longitude,
double y_latitude) {
mg_point_2d *point = mg_point_2d_alloc(&mg_system_allocator);
if (!point) {
return NULL;
}
point->srid = srid;
point->x = x_longitude;
point->y = y_latitude;
return point;
}
mg_point_3d *mg_point_3d_make(uint16_t srid, double x_longitude,
double y_latitude, double z_height) {
mg_point_3d *point = mg_point_3d_alloc(&mg_system_allocator);
if (!point) {
return NULL;
}
point->srid = srid;
point->x = x_longitude;
point->y = y_latitude;
point->z = z_height;
;
return point;
}
int mg_string_equal(const mg_string *lhs, const mg_string *rhs) {
if (lhs->size != rhs->size) {
return 0;
}
return memcmp(lhs->data, rhs->data, lhs->size) == 0;
}
int mg_map_equal(const mg_map *lhs, const mg_map *rhs) {
if (lhs->size != rhs->size) {
return 0;
}
for (uint32_t i = 0; i < lhs->size; ++i) {
if (!mg_string_equal(lhs->keys[i], rhs->keys[i])) return 0;
if (!mg_value_equal(lhs->values[i], rhs->values[i])) return 0;
}
return 1;
}
int mg_node_equal(const mg_node *lhs, const mg_node *rhs) {
if (lhs->id != rhs->id) {
return 0;
}
if (lhs->label_count != rhs->label_count) {
return 0;
}
for (uint32_t i = 0; i < lhs->label_count; ++i) {
if (!mg_string_equal(lhs->labels[i], rhs->labels[i])) {
return 0;
}
}
return mg_map_equal(lhs->properties, rhs->properties);
}
int mg_relationship_equal(const mg_relationship *lhs,
const mg_relationship *rhs) {
if (lhs->id != rhs->id || lhs->start_id != rhs->start_id ||
lhs->end_id != rhs->end_id) {
return 0;
}
if (!mg_string_equal(lhs->type, rhs->type)) {
return 0;
}
return mg_map_equal(lhs->properties, rhs->properties);
}
int mg_unbound_relationship_equal(const mg_unbound_relationship *lhs,
const mg_unbound_relationship *rhs) {
if (lhs->id != rhs->id) {
return 0;
}
if (!mg_string_equal(lhs->type, rhs->type)) {
return 0;
}
return mg_map_equal(lhs->properties, rhs->properties);
}
int mg_path_equal(const mg_path *lhs, const mg_path *rhs) {
if (lhs->node_count != rhs->node_count ||
lhs->relationship_count != rhs->relationship_count ||
lhs->sequence_length != rhs->sequence_length) {
return 0;
}
for (uint32_t i = 0; i < lhs->node_count; ++i) {
if (!mg_node_equal(lhs->nodes[i], rhs->nodes[i])) {
return 0;
}
}
for (uint32_t i = 0; i < lhs->relationship_count; ++i) {
if (!mg_unbound_relationship_equal(lhs->relationships[i],
rhs->relationships[i])) {
return 0;
}
}
for (uint32_t i = 0; i < lhs->sequence_length; ++i) {
if (lhs->sequence[i] != rhs->sequence[i]) {
return 0;
}
}
return 1;
}
int mg_date_equal(const mg_date *lhs, const mg_date *rhs) {
return lhs->days == rhs->days;
}
int mg_time_equal(const mg_time *lhs, const mg_time *rhs) {
return lhs->nanoseconds == rhs->nanoseconds &&
lhs->tz_offset_seconds == rhs->tz_offset_seconds;
}
int mg_local_time_equal(const mg_local_time *lhs, const mg_local_time *rhs) {
return lhs->nanoseconds == rhs->nanoseconds;
}
int mg_date_time_equal(const mg_date_time *lhs, const mg_date_time *rhs) {
return lhs->seconds == rhs->seconds && lhs->nanoseconds == rhs->nanoseconds &&
lhs->tz_offset_minutes == rhs->tz_offset_minutes;
}
int mg_local_date_time_equal(const mg_local_date_time *lhs,
const mg_local_date_time *rhs) {
return lhs->seconds == rhs->seconds && lhs->nanoseconds == rhs->nanoseconds;
}
int mg_date_time_zone_id_equal(const mg_date_time_zone_id *lhs,
const mg_date_time_zone_id *rhs) {
return lhs->seconds == rhs->seconds && lhs->nanoseconds == rhs->nanoseconds &&
mg_string_equal(lhs->timezone_name, rhs->timezone_name);
}
int mg_duration_equal(const mg_duration *lhs, const mg_duration *rhs) {
return lhs->days == rhs->days && lhs->months == rhs->months &&
lhs->seconds == rhs->seconds && lhs->nanoseconds == rhs->nanoseconds;
}
int mg_point_2d_equal(const mg_point_2d *lhs, const mg_point_2d *rhs) {
return lhs->srid == rhs->srid && lhs->x == rhs->x && lhs->y == rhs->y;
}
int mg_point_3d_equal(const mg_point_3d *lhs, const mg_point_3d *rhs) {
return lhs->srid == rhs->srid && lhs->x == rhs->x && lhs->y == rhs->y &&
lhs->z == rhs->z;
}
int mg_value_equal(const mg_value *lhs, const mg_value *rhs) {
if (lhs->type != rhs->type) {
return 0;
}
switch (lhs->type) {
case MG_VALUE_TYPE_NULL:
return 1;
case MG_VALUE_TYPE_BOOL:
return (lhs->bool_v == 0) == (rhs->bool_v == 0);
case MG_VALUE_TYPE_INTEGER:
return lhs->integer_v == rhs->integer_v;
case MG_VALUE_TYPE_FLOAT:
return lhs->integer_v == rhs->integer_v;
case MG_VALUE_TYPE_STRING:
return mg_string_equal(lhs->string_v, rhs->string_v);
case MG_VALUE_TYPE_LIST:
if (lhs->list_v->size != rhs->list_v->size) {
return 0;
}
for (uint32_t i = 0; i < lhs->list_v->size; ++i) {
if (!mg_value_equal(lhs->list_v->elements[i], rhs->list_v->elements[i]))
return 0;
}
return 1;
case MG_VALUE_TYPE_MAP:
return mg_map_equal(lhs->map_v, rhs->map_v);
case MG_VALUE_TYPE_NODE:
return mg_node_equal(lhs->node_v, rhs->node_v);
case MG_VALUE_TYPE_RELATIONSHIP:
return mg_relationship_equal(lhs->relationship_v, rhs->relationship_v);
case MG_VALUE_TYPE_UNBOUND_RELATIONSHIP:
return mg_unbound_relationship_equal(lhs->unbound_relationship_v,
rhs->unbound_relationship_v);
case MG_VALUE_TYPE_PATH:
return mg_path_equal(lhs->path_v, rhs->path_v);
case MG_VALUE_TYPE_DATE:
return mg_date_equal(lhs->date_v, rhs->date_v);
case MG_VALUE_TYPE_TIME:
return mg_time_equal(lhs->time_v, rhs->time_v);
case MG_VALUE_TYPE_LOCAL_TIME:
return mg_local_time_equal(lhs->local_time_v, rhs->local_time_v);
case MG_VALUE_TYPE_DATE_TIME:
return mg_date_time_equal(lhs->date_time_v, rhs->date_time_v);
case MG_VALUE_TYPE_DATE_TIME_ZONE_ID:
return mg_date_time_zone_id_equal(lhs->date_time_zone_id_v,
rhs->date_time_zone_id_v);
case MG_VALUE_TYPE_LOCAL_DATE_TIME:
return mg_local_date_time_equal(lhs->local_date_time_v,
rhs->local_date_time_v);
case MG_VALUE_TYPE_DURATION:
return mg_duration_equal(lhs->duration_v, rhs->duration_v);
case MG_VALUE_TYPE_POINT_2D:
return mg_point_2d_equal(lhs->point_2d_v, rhs->point_2d_v);
case MG_VALUE_TYPE_POINT_3D:
return mg_point_3d_equal(lhs->point_3d_v, rhs->point_3d_v);
case MG_VALUE_TYPE_UNKNOWN:
return 0;
}
return 0;
}
mg_map *mg_default_pull_extra_map;
mg_map mg_empty_map = {0, 0, NULL, NULL};