kmx.io/kv/rope.c

Branch

Thomas de Grivel f1843fc12 2022-01-03T14:06:48
quote
/*
 * kv - key value text file format
 *
 * Copyright 2022 Thomas de Grivel
*/

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "rope.h"

void rope_init (s_rope *r, char *str, size_t size, s_rope *next)
{
  assert(r);
  r->str = str;
  r->size = size;
  r->next = next;
}

s_rope * rope_new (char *str, size_t size, s_rope *next)
{
  s_rope *r = calloc(sizeof(s_rope), 1);
  if (r)
    rope_init(r, str, size, next);
  return r;
}

void rope_delete (s_rope *r)
{
  r->str = NULL;
  r->next = NULL;
  free(r);
}

void rope_delete_all (s_rope *r)
{
  while (r) {
    s_rope *t = r;
    r = r->next;
    rope_delete(t);
  }
}

void rope_delete_all_free (s_rope *r)
{
  while (r) {
    s_rope *t = r;
    r = r->next;
    free(t->str);
    t->str = NULL;
    t->size = 0;
    rope_delete(t);
  }
}

int rope_push (s_rope **r, char *str, size_t size)
{
  s_rope *n;
  assert(r);
  n = rope_new(str, size, *r);
  if (n) {
    *r = n;
    return 0;
  }
  return -1;
}

size_t rope_length (const s_rope *r)
{
  size_t l = 0;
  while (r) {
    l++;
    r = r->next;
  }
  return l;
}

void rope_swap (s_rope *a, s_rope *b)
{
  char  *str;
  size_t size;
  assert(a);
  assert(b);
  str = a->str;
  size = a->size;
  a->str = b->str;
  a->size = b->size;
  b->str = str;
  b->size = size;
}

void rope_sort_by_size (s_rope *r)
{
  s_rope *i;
  size_t  n;
  assert(r);
  n = rope_length(r);
  while (n > 1) {
    size_t k = n;
    int swap = 0;
    i = r;
    while (k > 1) {
      if (i->size > i->next->size) {
        swap = 1;
        rope_swap(i, i->next);
      }
      k--;
      i = i->next;
    }
    if (!swap)
      break;
    n--;
  }
}

int rope_print (s_rope *r, FILE *fp)
{
  int ret;
  if (r) {
    assert(fp);
    ret = fwrite(r->str, r->size, 1, fp);
    if (ret != 1)
      return -1;
    r = r->next;
    while (r) {
      ret = fwrite("\n\n", 2, 1, fp);
      if (ret != 1)
        return -1;
      ret = fwrite(r->str, r->size, 1, fp);
      if (ret != 1)
        return -1;
      r = r->next;
    }
  }
  ret = fwrite("\n", 1, 1, fp);
  if (ret != 1)
    return -1;
  return 0;
}
Download