#ifndef BSTACK_FEATURE_ATOMIC
# error "atomic_ops.c requires -DBSTACK_FEATURE_ATOMIC"
#endif
#include "../c/bstack.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static void show(const char *label, bstack_t *bs)
{
uint64_t len;
bstack_len(bs, &len);
char *buf = malloc((size_t)(len + 1));
size_t written;
bstack_peek(bs, 0, (uint8_t *)buf, &written);
buf[written] = '\0';
printf("%s: \"%s\"\n", label, buf);
free(buf);
}
static int uppercase_cb(const uint8_t *old, size_t old_len,
uint8_t **new_buf, size_t *new_len, void *ctx)
{
(void)ctx;
uint8_t *out = malloc(old_len);
if (!out) return -1;
for (size_t i = 0; i < old_len; i++) {
uint8_t c = old[i];
out[i] = (c >= 'a' && c <= 'z') ? (uint8_t)(c - 32) : c;
}
*new_buf = out;
*new_len = old_len;
return 0;
}
#ifdef BSTACK_FEATURE_SET
static int increment_cb(uint8_t *buf, size_t len, void *ctx)
{
(void)ctx;
if (len < 8) return 0;
uint32_t n = (uint32_t)buf[4]
| ((uint32_t)buf[5] << 8)
| ((uint32_t)buf[6] << 16)
| ((uint32_t)buf[7] << 24);
n++;
buf[4] = (uint8_t)(n);
buf[5] = (uint8_t)(n >> 8);
buf[6] = (uint8_t)(n >> 16);
buf[7] = (uint8_t)(n >> 24);
return 0;
}
#endif
int main(void)
{
bstack_t *bs = bstack_open("atomic_ops_example.bstack");
if (!bs) { perror("bstack_open"); return 1; }
bstack_push(bs, (const uint8_t *)"[ok] start\n", 11, NULL);
bstack_push(bs, (const uint8_t *)"[ok] login\n", 11, NULL);
bstack_push(bs, (const uint8_t *)"[ok] fetch\n", 11, NULL);
show("initial ", bs);
bstack_replace(bs, 11, uppercase_cb, NULL);
show("after replace", bs);
bstack_atrunc(bs, 11, (const uint8_t *)"[ok] store\n", 11);
show("after atrunc ", bs);
uint8_t removed[11];
bstack_splice(bs, removed, 11, (const uint8_t *)"[ok] flush\n", 11);
printf("splice removed: \"%.*s\"\n", 11, removed);
show("after splice ", bs);
uint64_t snap;
bstack_len(bs, &snap);
int pushed1, pushed2;
bstack_try_extend(bs, snap, (const uint8_t *)"[ok] retry\n", 11, &pushed1);
bstack_try_extend(bs, snap, (const uint8_t *)"[ok] retry\n", 11, &pushed2);
printf("try_extend: first=%d second=%d\n", pushed1, pushed2);
show("after t_ext ", bs);
bstack_len(bs, &snap);
int ok1, ok2;
bstack_try_discard(bs, snap, 11, &ok1);
bstack_try_discard(bs, snap, 11, &ok2);
printf("try_discard: first=%d second=%d\n", ok1, ok2);
show("after t_disc ", bs);
#ifdef BSTACK_FEATURE_SET
uint64_t status_off;
uint8_t zeros[8] = {0};
bstack_push(bs, zeros, 8, &status_off);
printf("status record at offset %llu\n", (unsigned long long)status_off);
uint8_t prev[4];
bstack_swap(bs, status_off, prev, (const uint8_t *)"RUN\x00", 4);
printf("swap wrote 'RUN\\0', got back [%02x %02x %02x %02x]\n",
prev[0], prev[1], prev[2], prev[3]);
int ok_cas1, ok_cas2;
bstack_cas(bs, status_off,
(const uint8_t *)"RUN\x00", (const uint8_t *)"DONE", 4, &ok_cas1);
bstack_cas(bs, status_off,
(const uint8_t *)"RUN\x00", (const uint8_t *)"FAIL", 4, &ok_cas2);
printf("cas: first=%d second=%d\n", ok_cas1, ok_cas2);
uint8_t tag[4];
bstack_get(bs, status_off, status_off + 4, tag);
printf("tag now: \"%.4s\"\n", tag);
bstack_process(bs, status_off, status_off + 8, increment_cb, NULL);
uint8_t record[8];
bstack_get(bs, status_off, status_off + 8, record);
uint32_t counter = (uint32_t)record[4]
| ((uint32_t)record[5] << 8)
| ((uint32_t)record[6] << 16)
| ((uint32_t)record[7] << 24);
printf("after process: tag=\"%.4s\" counter=%u\n", record, counter);
#endif
bstack_close(bs);
return 0;
}