/*
 * Copyright (C) 2018 Richard Hughes <richard@hughsie.com>
 *
 * SPDX-License-Identifier: LGPL-2.1+
 */

#pragma once

#include <string.h>

#include "xb-opcode.h"

G_BEGIN_DECLS

/* maximum number of tokens supported for each element -- this is a compromise
 * between making the _XbOpcode struct too large and search results */
#define XB_OPCODE_TOKEN_MAX 32

struct _XbOpcode {
	XbOpcodeKind kind;
	guint32 val;
	gpointer ptr;
	guint8 tokens_len;
	const gchar *tokens[XB_OPCODE_TOKEN_MAX + 1];
	GDestroyNotify destroy_func;
};

#define XB_OPCODE_INIT()                                                                           \
	{                                                                                          \
		0, 0, NULL, 0, {NULL}, NULL                                                        \
	}

/**
 * xb_opcode_steal:
 * @op_ptr: (transfer full): pointer to an #XbOpcode to steal
 *
 * Steal the stack-allocated #XbOpcode pointed to by @op_ptr, returning its
 * value and clearing its previous storage location using `memset()`.
 *
 * Returns: the value of @op_ptr
 * Since: 0.2.0
 */
static inline XbOpcode
xb_opcode_steal(XbOpcode *op_ptr)
{
	XbOpcode op = *op_ptr;
	memset(op_ptr, 0, sizeof(XbOpcode));
	return op;
}

void
xb_opcode_init(XbOpcode *opcode,
	       XbOpcodeKind kind,
	       const gchar *str,
	       guint32 val,
	       GDestroyNotify destroy_func);
void
xb_opcode_clear(XbOpcode *opcode);
void
xb_opcode_bind_init(XbOpcode *opcode);
gboolean
xb_opcode_is_binding(XbOpcode *self);
G_DEPRECATED_FOR(xb_value_bindings_bind_str)
void
xb_opcode_bind_str(XbOpcode *self, gchar *str, GDestroyNotify destroy_func);
G_DEPRECATED_FOR(xb_value_bindings_bind_val)
void
xb_opcode_bind_val(XbOpcode *self, guint32 val);
void
xb_opcode_set_kind(XbOpcode *self, XbOpcodeKind kind);
void
xb_opcode_set_val(XbOpcode *self, guint32 val);
gboolean
xb_opcode_append_token(XbOpcode *self, const gchar *val);
const gchar **
xb_opcode_get_tokens(XbOpcode *self);
gchar *
xb_opcode_get_sig(XbOpcode *self);
void
xb_opcode_bool_init(XbOpcode *opcode, gboolean val);
gboolean
xb_opcode_has_flag(XbOpcode *self, XbOpcodeFlags flag);
void
xb_opcode_add_flag(XbOpcode *self, XbOpcodeFlags flag);

G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(XbOpcode, xb_opcode_clear)

G_END_DECLS
