/* This is -*- C -*- */ /* $Id: guppi-seq-integer-core.c,v 1.1 2002/01/08 06:29:00 trow Exp $ */ /* * guppi-seq-integer-core-impl.c * * Copyright (C) 2000 EMC Capital Management, Inc. * Copyright (C) 2001 The Free Software Foundation * * Developed by Jon Trowbridge and * Havoc Pennington . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA */ #include #include "guppi-seq-integer-core.h" #include #include #include #include #include #include static GtkObjectClass *parent_class = NULL; enum { ARG_0 }; static void guppi_seq_integer_core_get_arg (GtkObject *obj, GtkArg *arg, guint arg_id) { switch (arg_id) { default: break; }; } static void guppi_seq_integer_core_set_arg (GtkObject *obj, GtkArg *arg, guint arg_id) { switch (arg_id) { default: break; }; } static void guppi_seq_integer_core_destroy (GtkObject *obj) { if (parent_class->destroy) parent_class->destroy (obj); } static void guppi_seq_integer_core_finalize (GtkObject *obj) { GuppiSeqIntegerCore *core = GUPPI_SEQ_INTEGER_CORE (obj); guppi_unref0 (core->garray); if (parent_class->finalize) parent_class->finalize (obj); } /***************************************************************************/ static void v_seq_integer_range (GuppiSeqInteger *si, gint *min, gint *max) { GuppiSeqIntegerCore *core = GUPPI_SEQ_INTEGER_CORE (si); gint x0 = 0, x1 = 0, i, a; const gint *ptr = (const gint *) guppi_garray_data (core->garray); if (!core->cached_minmax) { if (core->size) { x0 = x1 = ptr[0]; for (i = 1; i < core->size; ++i) { a = ptr[i]; if (a < x0) x0 = a; if (a > x1) x1 = a; } } core->min = x0; core->max = x1; core->cached_minmax = TRUE; } if (min) *min = core->min; if (max) *max = core->max; } static gint v_seq_integer_frequency (GuppiSeqInteger *si, gint k) { GuppiSeqIntegerCore *core = GUPPI_SEQ_INTEGER_CORE (si); gint count = 0, i; const gint *ptr = (const gint *) guppi_garray_data (core->garray); for (i = 0; i < core->size; ++i) if (k == ptr[i]) ++count; return count; } static gint v_seq_integer_get (GuppiSeqInteger *si, gint i) { GuppiSeqIntegerCore *core = GUPPI_SEQ_INTEGER_CORE (si); const gint *ptr = (const gint *) guppi_garray_data (core->garray); return ptr[i - core->index_basis]; } static void v_seq_integer_set (GuppiSeqInteger *si, gint i, gint val) { GuppiSeqIntegerCore *core = GUPPI_SEQ_INTEGER_CORE (si); gint *ptr = (gint *) guppi_garray_data (core->garray); gint old_val; i -= core->index_basis; old_val = ptr[i]; if (core->cached_minmax) { if (val < core->min) core->min = val; if (val > core->max) core->max = val; if ((old_val == core->min && val != core->min) || (old_val == core->max && val != core->max)) core->cached_minmax = FALSE; } ptr[i] = val; if (GUPPI_SEQ_INTEGER_CLASS (parent_class)->set) GUPPI_SEQ_INTEGER_CLASS (parent_class)->set (si, i + core->index_basis, val); } static void v_seq_integer_insert (GuppiSeqInteger *si, gint i, const gint *ptr, gsize N) { GuppiSeqIntegerCore *core = GUPPI_SEQ_INTEGER_CORE (si); gint *data; gint a, j; i -= core->index_basis; if (guppi_garray_size (core->garray) <= core->size) guppi_garray_set_size (core->garray, MAX (MAX (20, 2 *core->size), core->size + 2 * N)); if (core->cached_minmax) { for (j = 0; j < N; ++j) { a = ptr[j]; if (a < core->min) core->min = a; if (a > core->max) core->max = a; } } data = (gint *) guppi_garray_data (core->garray); for (j = core->size - N; i <= j; --j) data[j + N] = data[j]; for (j = 0; j < N; ++j) data[i + j] = ptr[j]; core->size += N; if (GUPPI_SEQ_INTEGER_CLASS (parent_class)->insert) GUPPI_SEQ_INTEGER_CLASS (parent_class)->insert (si, i + core->index_basis, ptr, N); } static void v_seq_size_hint (GuppiSeq *seq, gsize N) { GuppiSeqIntegerCore *core = GUPPI_SEQ_INTEGER_CORE (seq); if (guppi_garray_size (core->garray) < N) guppi_garray_set_size (core->garray, N); if (GUPPI_SEQ_CLASS (parent_class)->size_hint) GUPPI_SEQ_CLASS (parent_class)->size_hint (seq, N); } static void v_seq_get_bounds (GuppiSeq *seq, gint *min, gint *max) { GuppiSeqIntegerCore *core = GUPPI_SEQ_INTEGER_CORE (seq); if (min) *min = core->index_basis; if (max) *max = core->index_basis - 1 + core->size; } static void v_seq_shift_indices (GuppiSeq *seq, gint delta) { GuppiSeqIntegerCore *core = GUPPI_SEQ_INTEGER_CORE (seq); core->index_basis += delta; if (GUPPI_SEQ_CLASS (parent_class)->shift_indices) GUPPI_SEQ_CLASS (parent_class)->shift_indices (seq, delta); } static void v_seq_delete_many (GuppiSeq *seq, gint i, gsize N) { GuppiSeqIntegerCore *core = GUPPI_SEQ_INTEGER_CORE (seq); gint *data; gint j; /* This could be optimized. */ core->cached_minmax = FALSE; data = (gint *) guppi_garray_data (core->garray); i -= core->index_basis; for (j = i; j + N < core->size; ++j) data[j] = data[j + N]; core->size -= N; if (GUPPI_SEQ_CLASS (parent_class)->delete_many) GUPPI_SEQ_CLASS (parent_class)->delete_many (seq, i + core->index_basis, N); } static GuppiData * v_data_copy (GuppiData *d) { GuppiSeqIntegerCore *core = GUPPI_SEQ_INTEGER_CORE (d); GuppiSeqIntegerCore *copy; gint i; gint *data; gint *copy_data; copy = GUPPI_SEQ_INTEGER_CORE (guppi_type_new (GUPPI_TYPE_SEQ_INTEGER_CORE)); copy->index_basis = core->index_basis; copy->size = core->size; guppi_garray_set_size (copy->garray, core->size); data = (gint *) guppi_garray_data (core->garray); copy_data = (gint *) guppi_garray_data (copy->garray); for (i = 0; i < core->size; ++i) copy_data[i] = data[i]; return GUPPI_DATA (copy); } static gint v_data_size_in_bytes (GuppiData *d) { GuppiSeqIntegerCore *core = GUPPI_SEQ_INTEGER_CORE (d); gint sz; sz = guppi_garray_size (core->garray) * sizeof (double) + sizeof (GuppiSeqIntegerCore); if (GUPPI_DATA_CLASS (parent_class)->get_size_in_bytes) sz += GUPPI_DATA_CLASS (parent_class)->get_size_in_bytes (d); return sz; } /***************************************************************************/ static void guppi_seq_integer_core_class_init (GuppiSeqIntegerCoreClass *klass) { GtkObjectClass *object_class = (GtkObjectClass *) klass; GuppiDataClass *data_class = GUPPI_DATA_CLASS (klass); GuppiSeqClass *seq_class = GUPPI_SEQ_CLASS (klass); GuppiSeqIntegerClass *seq_integer_class = GUPPI_SEQ_INTEGER_CLASS (klass); parent_class = gtk_type_class (GUPPI_TYPE_SEQ_INTEGER); object_class->get_arg = guppi_seq_integer_core_get_arg; object_class->set_arg = guppi_seq_integer_core_set_arg; object_class->destroy = guppi_seq_integer_core_destroy; object_class->finalize = guppi_seq_integer_core_finalize; seq_integer_class->range = v_seq_integer_range; seq_integer_class->frequency = v_seq_integer_frequency; seq_integer_class->get = v_seq_integer_get; seq_integer_class->set = v_seq_integer_set; seq_integer_class->insert = v_seq_integer_insert; seq_class->size_hint = v_seq_size_hint; seq_class->get_bounds = v_seq_get_bounds; seq_class->shift_indices = v_seq_shift_indices; seq_class->delete_many = v_seq_delete_many; seq_class->support_missing_values = TRUE; data_class->copy = v_data_copy; data_class->get_size_in_bytes = v_data_size_in_bytes; data_class->is_leaf_type = TRUE; } static void guppi_seq_integer_core_init (GuppiSeqIntegerCore *obj) { obj->index_basis = 0; obj->size = 0; obj->garray = guppi_garray_new (sizeof (gint)); } GtkType guppi_seq_integer_core_get_type (void) { static GtkType guppi_seq_integer_core_type = 0; if (!guppi_seq_integer_core_type) { static const GtkTypeInfo guppi_seq_integer_core_info = { "GuppiSeqIntegerCore", sizeof (GuppiSeqIntegerCore), sizeof (GuppiSeqIntegerCoreClass), (GtkClassInitFunc) guppi_seq_integer_core_class_init, (GtkObjectInitFunc) guppi_seq_integer_core_init, NULL, NULL, (GtkClassInitFunc) NULL }; guppi_seq_integer_core_type = gtk_type_unique (GUPPI_TYPE_SEQ_INTEGER, &guppi_seq_integer_core_info); } return guppi_seq_integer_core_type; } GuppiSeqInteger * guppi_seq_integer_core_new (void) { return GUPPI_SEQ_INTEGER (guppi_type_new (guppi_seq_integer_core_get_type ())); } /* $Id: guppi-seq-integer-core.c,v 1.1 2002/01/08 06:29:00 trow Exp $ */