/* This is -*- C -*- */ /* $Id: guppi-seq-string-core.c,v 1.1 2002/01/08 06:29:00 trow Exp $ */ /* * guppi-seq-string-core.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-string-core.h" /* #include */ #include #include #include #include #include #include static GtkObjectClass *parent_class = NULL; static void guppi_seq_string_core_destroy (GtkObject *obj) { if (parent_class->destroy) parent_class->destroy (obj); } static void guppi_seq_string_core_finalize (GtkObject *obj) { GuppiSeqStringCore *core = GUPPI_SEQ_STRING_CORE (obj); gchar **data; gint i; data = (gchar **) guppi_garray_data (core->garray); for (i=0; isize; ++i) guppi_free (data[i]); guppi_unref0 (core->garray); if (parent_class->finalize) parent_class->finalize (obj); } /***************************************************************************/ static const gchar * v_seq_string_get (GuppiSeqString *seq, gint i) { const GuppiSeqStringCore *core = GUPPI_SEQ_STRING_CORE (seq); gchar **data; data = (gchar **) guppi_garray_data (core->garray); i -= core->index_basis; return data[i]; } static void v_seq_string_set (GuppiSeqString *seq, gint i, gchar *str) { GuppiSeqStringCore *core = GUPPI_SEQ_STRING_CORE (seq); gchar **data; data = (gchar **) guppi_garray_data (core->garray); i -= core->index_basis; if (data[i]) guppi_free (data[i]); data[i] = str; if (GUPPI_SEQ_STRING_CLASS (parent_class)->set) { i += core->index_basis; GUPPI_SEQ_STRING_CLASS (parent_class)->set (seq, i, str); } } static void v_seq_string_insert (GuppiSeqString *seq, gint i, gchar *str) { GuppiSeqStringCore *core = GUPPI_SEQ_STRING_CORE (seq); gchar **data; gint j; if (core->size == 0) core->index_basis = i; i -= core->index_basis; if (guppi_garray_size (core->garray) <= core->size) guppi_garray_set_size (core->garray, MAX (20, 2 *core->size)); data = (gchar **) guppi_garray_data (core->garray); for (j = core->size - 1; i <= j; --j) data[j + 1] = data[j]; data[i] = str; ++core->size; if (GUPPI_SEQ_STRING_CLASS (parent_class)->insert) { i += core->index_basis; GUPPI_SEQ_STRING_CLASS (parent_class)->insert (seq, i, str); } } static void v_seq_size_hint (GuppiSeq *seq, gsize n) { GuppiSeqStringCore *core = GUPPI_SEQ_STRING_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) { const GuppiSeqStringCore *core = GUPPI_SEQ_STRING_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) { GuppiSeqStringCore *core = GUPPI_SEQ_STRING_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) { GuppiSeqStringCore *core = GUPPI_SEQ_STRING_CORE (seq); gchar **data; gint j; data = (gchar **) guppi_garray_data (core->garray); i -= core->index_basis; for (j = i; j < i + N; ++j) { guppi_free (data[j]); } for (j = i; j + N < core->size; ++j) { data[j] = data[j + N]; } core->size -= N; if (GUPPI_SEQ_CLASS (parent_class)->delete_many) { i += core->index_basis; GUPPI_SEQ_CLASS (parent_class)->delete_many (seq, i, N); } } static GuppiData * v_data_copy (GuppiData *seq) { GuppiSeqStringCore *core = GUPPI_SEQ_STRING_CORE (seq); GuppiSeqStringCore *copy; gint i; gchar **data; gchar **copy_data; copy = GUPPI_SEQ_STRING_CORE (guppi_type_new (GUPPI_TYPE_SEQ_STRING_CORE)); copy->index_basis = core->index_basis; copy->size = core->size; copy->garray = guppi_garray_new (sizeof (gchar *)); guppi_garray_set_size (copy->garray, copy->size); data = (gchar **) guppi_garray_data (core->garray); copy_data = (gchar **) guppi_garray_data (copy->garray); for (i = 0; i < core->size; ++i) copy_data[i] = guppi_strdup (data[i]); return GUPPI_DATA (copy); } static gint v_data_size_in_bytes (GuppiData *seq) { GuppiSeqStringCore *core = GUPPI_SEQ_STRING_CORE (seq); gint i, sum = 0; gchar **data = (gchar **) guppi_garray_data (core->garray); sum += sizeof (GuppiSeqStringCore); sum += core->size *sizeof (gchar *); for (i = 0; i < core->size; ++i) if (data[i]) sum += 1 + strlen (data[i]); if (GUPPI_DATA_CLASS (parent_class)->get_size_in_bytes) sum += GUPPI_DATA_CLASS (parent_class)->get_size_in_bytes (seq); return sum; } /***************************************************************************/ static void guppi_seq_string_core_class_init (GuppiSeqStringCoreClass *klass) { GtkObjectClass *object_class = (GtkObjectClass *) klass; GuppiDataClass *data_class = GUPPI_DATA_CLASS (klass); GuppiSeqClass *seq_class = GUPPI_SEQ_CLASS (klass); GuppiSeqStringClass *seq_string_class = GUPPI_SEQ_STRING_CLASS (klass); parent_class = gtk_type_class (GUPPI_TYPE_SEQ_STRING); object_class->destroy = guppi_seq_string_core_destroy; object_class->finalize = guppi_seq_string_core_finalize; seq_string_class->get = v_seq_string_get; seq_string_class->set = v_seq_string_set; seq_string_class->insert = v_seq_string_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_string_core_init (GuppiSeqStringCore *obj) { obj->index_basis = 0; obj->size = 0; obj->garray = guppi_garray_new (sizeof (gchar *)); } GtkType guppi_seq_string_core_get_type (void) { static GtkType guppi_seq_string_core_type = 0; if (!guppi_seq_string_core_type) { static const GtkTypeInfo guppi_seq_string_core_info = { "GuppiSeqStringCore", sizeof (GuppiSeqStringCore), sizeof (GuppiSeqStringCoreClass), (GtkClassInitFunc) guppi_seq_string_core_class_init, (GtkObjectInitFunc) guppi_seq_string_core_init, NULL, NULL, (GtkClassInitFunc) NULL }; guppi_seq_string_core_type = gtk_type_unique (GUPPI_TYPE_SEQ_STRING, &guppi_seq_string_core_info); } return guppi_seq_string_core_type; } /* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */ GuppiSeqString * guppi_seq_string_core_new (void) { return GUPPI_SEQ_STRING (guppi_type_new (guppi_seq_string_core_get_type ())); } /* $Id: guppi-seq-string-core.c,v 1.1 2002/01/08 06:29:00 trow Exp $ */