/* This is -*- C -*- */ /* $Id: guppi-seq-integer.c,v 1.19 2002/01/14 05:01:17 trow Exp $ */ /* * guppi-seq-integer.c * * Copyright (C) 2000 EMC Capital Management, Inc. * * 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.h" /* #include */ #include #include #include #include #include #include #include static GtkObjectClass *parent_class = NULL; static void guppi_seq_integer_finalize (GtkObject *obj) { if (parent_class->finalize) parent_class->finalize (obj); } static xmlNodePtr export_xml_element (GuppiSeq *seq, gint i, GuppiXMLDocument *doc) { gint j; xmlNodePtr node; gchar buf[64]; j = guppi_seq_integer_get (GUPPI_SEQ_INTEGER (seq), i); g_snprintf (buf, 64, "%d", j); node = xmlNewNode (doc->ns, "int"); xmlAddChild (node, xmlNewText (buf)); return node; } static gboolean import_xml_element (GuppiSeq *seq, GuppiXMLDocument *doc, xmlNodePtr node) { gchar *value; gint x = 0; gboolean ok = TRUE; g_return_val_if_fail (!strcmp (node->name, "int"), FALSE); value = xmlNodeListGetString (doc->doc, node->xmlChildrenNode, 1); if (sscanf (value, "%d", &x) == 1) guppi_seq_integer_append ((GuppiSeqInteger *) seq, x); else { g_warning ("bad value \"%s\"", value); ok = FALSE; } free (value); return ok; } /***************************************************************************/ /* Sequence Operation Stuff */ typedef struct _GuppiDataOp_Int GuppiDataOp_Int; struct _GuppiDataOp_Int { GuppiDataOp op; gint i; gsize N; gint x; const gint *in_ptr; }; static void op_set (GuppiData *d, GuppiDataOp *op) { GuppiDataOp_Int *int_op = (GuppiDataOp_Int *) op; GuppiSeqIntegerClass *klass; klass = GUPPI_SEQ_INTEGER_CLASS (GTK_OBJECT (d)->klass); g_assert (klass->set); klass->set (GUPPI_SEQ_INTEGER (d), int_op->i, int_op->x); } static void op_set_many (GuppiData *d, GuppiDataOp *op) { GuppiDataOp_Int *int_op = (GuppiDataOp_Int *) op; GuppiSeqIntegerClass *klass; gint k; klass = GUPPI_SEQ_INTEGER_CLASS (GTK_OBJECT (d)->klass); g_assert (klass->set); /* Needs optimization */ for (k = 0; k < int_op->N; ++k) klass->set (GUPPI_SEQ_INTEGER (d), int_op->i + k, int_op->x); } static void op_insert (GuppiData *d, GuppiDataOp *op) { GuppiDataOp_Int *int_op = (GuppiDataOp_Int *) op; GuppiSeqIntegerClass *klass; klass = GUPPI_SEQ_INTEGER_CLASS (GTK_OBJECT (d)->klass); g_assert (klass->insert); klass->insert (GUPPI_SEQ_INTEGER (d), int_op->i, int_op->in_ptr, int_op->N); } /* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */ static void insert_generic (GuppiSeq *seq, gint i, gsize N) { /* FIXME: needs optimization */ gint j; for (j = 0; j < (gint)N; ++j) guppi_seq_integer_insert (GUPPI_SEQ_INTEGER (seq), i, 0); if (GUPPI_SEQ_CLASS (parent_class)->insert_generic) GUPPI_SEQ_CLASS (parent_class)->insert_generic (seq, i, N); } static void set (GuppiSeqInteger *si, gint i, gint val) { GUPPI_SEQ_CLASS (GTK_OBJECT (si)->klass)->set_missing (GUPPI_SEQ (si), i, FALSE); } static void insert (GuppiSeqInteger *si, gint i, const gint *ptr, gsize N) { GUPPI_SEQ_CLASS (GTK_OBJECT (si)->klass)->insert_missing (GUPPI_SEQ (si), i, FALSE, N); } /* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */ gint guppi_seq_integer_get (const GuppiSeqInteger *gsi, gint i) { GuppiSeqIntegerClass *klass; g_return_val_if_fail (gsi != NULL, 0); g_return_val_if_fail (guppi_seq_in_bounds (GUPPI_SEQ (gsi), i), 0); klass = GUPPI_SEQ_INTEGER_CLASS (GTK_OBJECT (gsi)->klass); g_assert (klass->get); return klass->get ((GuppiSeqInteger *) gsi, i); } void guppi_seq_integer_get_many (const GuppiSeqInteger *gsi, gint first, gint last, gint *dest) { gint i; g_return_if_fail (gsi != NULL); g_return_if_fail (dest != NULL); g_return_if_fail (guppi_seq_in_bounds (GUPPI_SEQ (gsi), first)); g_return_if_fail (guppi_seq_in_bounds (GUPPI_SEQ (gsi), last)); /* This can be optimized later. */ for (i = first; i <= last; ++i) dest[i - first] = guppi_seq_integer_get (gsi, i); } void guppi_seq_integer_set (GuppiSeqInteger *gsi, gint i, gint val) { GuppiDataOp_Int op; g_return_if_fail (gsi != NULL); g_return_if_fail (guppi_data_can_change (GUPPI_DATA (gsi))); g_return_if_fail (guppi_seq_in_bounds (GUPPI_SEQ (gsi), i)); if (guppi_seq_missing (GUPPI_SEQ (gsi), i) || guppi_seq_integer_get (gsi, i) != val) { op.op.op = op_set; op.i = i; op.x = val; guppi_seq_changed_set (GUPPI_SEQ (gsi), i, i, (GuppiDataOp *) & op); } } void guppi_seq_integer_set_many_dup (GuppiSeqInteger *gsi, gint first, gint last, gint val) { GuppiDataOp_Int op; g_return_if_fail (gsi != NULL); g_return_if_fail (guppi_seq_in_bounds (GUPPI_SEQ (gsi), first)); g_return_if_fail (guppi_seq_in_bounds (GUPPI_SEQ (gsi), last)); g_return_if_fail (guppi_data_can_change (GUPPI_DATA (gsi))); guppi_2sort_i (&first, &last); op.op.op = op_set_many; op.i = first; op.N = last - first + 1; op.x = val; guppi_seq_changed_set (GUPPI_SEQ (gsi), first, last, (GuppiDataOp *) & op); } void guppi_seq_integer_set_all (GuppiSeqInteger *gsi, gint val) { gint i0, i1; g_return_if_fail (gsi != NULL); g_return_if_fail (guppi_data_can_change (GUPPI_DATA (gsi))); guppi_seq_indices (GUPPI_SEQ (gsi), &i0, &i1); guppi_seq_integer_set_many_dup (gsi, i0, i1, val); } void guppi_seq_integer_prepend (GuppiSeqInteger *gsi, gint val) { gint first; g_return_if_fail (gsi != NULL); g_return_if_fail (guppi_data_can_change (GUPPI_DATA (gsi))); first = guppi_seq_min_index (GUPPI_SEQ (gsi)); guppi_seq_integer_insert (gsi, first, val); } void guppi_seq_integer_prepend_many (GuppiSeqInteger *gsi, const gint *ptr, gsize N) { gint first; g_return_if_fail (gsi != NULL); g_return_if_fail (guppi_data_can_change (GUPPI_DATA (gsi))); g_return_if_fail (ptr != NULL); if (N == 0) return; first = guppi_seq_min_index (GUPPI_SEQ (gsi)); guppi_seq_integer_insert_many (gsi, first, ptr, N); } void guppi_seq_integer_append (GuppiSeqInteger *gsi, gint val) { gint last; g_return_if_fail (gsi != NULL); g_return_if_fail (guppi_data_can_change (GUPPI_DATA (gsi))); last = guppi_seq_max_index (GUPPI_SEQ (gsi)); guppi_seq_integer_insert (gsi, last + 1, val); } void guppi_seq_integer_append_many (GuppiSeqInteger *gsi, const gint *ptr, gsize N) { gint last; g_return_if_fail (gsi != NULL); g_return_if_fail (guppi_data_can_change (GUPPI_DATA (gsi))); g_return_if_fail (ptr != NULL); if (N == 0) return; last = guppi_seq_max_index (GUPPI_SEQ (gsi)); guppi_seq_integer_insert_many (gsi, last + 1, ptr, N); } void guppi_seq_integer_insert (GuppiSeqInteger *gsi, gint i, gint val) { g_return_if_fail (gsi != NULL); g_return_if_fail (guppi_data_can_change (GUPPI_DATA (gsi))); guppi_seq_integer_insert_many (gsi, i, &val, 1); } void guppi_seq_integer_insert_many (GuppiSeqInteger *gsi, gint i, const gint *ptr, gsize N) { GuppiDataOp_Int op; g_return_if_fail (gsi != NULL && GUPPI_IS_SEQ_INTEGER (gsi)); g_return_if_fail (ptr != NULL); if (N == 0) return; op.op.op = op_insert; op.i = i; op.N = N; op.in_ptr = ptr; guppi_seq_changed_insert (GUPPI_SEQ (gsi), i, N, (GuppiDataOp *) & op); } gint guppi_seq_integer_min (const GuppiSeqInteger *gsi) { gint i, i0, i1, x = 0, a; GuppiSeqIntegerClass *klass; g_return_val_if_fail (gsi != NULL, 0); klass = GUPPI_SEQ_INTEGER_CLASS (GTK_OBJECT (gsi)->klass); if (klass->range) { klass->range ((GuppiSeqInteger *) gsi, &x, NULL); } else if (!guppi_seq_empty (GUPPI_SEQ (gsi))) { guppi_seq_indices (GUPPI_SEQ (gsi), &i0, &i1); x = guppi_seq_integer_get (gsi, i0); for (i = i0 + 1; i <= i1; ++i) { a = guppi_seq_integer_get (gsi, i); if (a < x) x = a; } } return x; } gint guppi_seq_integer_max (const GuppiSeqInteger *gsi) { gint i, i0, i1, x = 0, a; GuppiSeqIntegerClass *klass; g_return_val_if_fail (gsi != NULL, 0); klass = GUPPI_SEQ_INTEGER_CLASS (GTK_OBJECT (gsi)->klass); if (klass->range) { klass->range ((GuppiSeqInteger *) gsi, NULL, &x); } else if (!guppi_seq_empty (GUPPI_SEQ (gsi))) { guppi_seq_indices (GUPPI_SEQ (gsi), &i0, &i1); x = guppi_seq_integer_get (gsi, i0); for (i = i0 + 1; i <= i1; ++i) { a = guppi_seq_integer_get (gsi, i); if (a > x) x = a; } } return x; } gint guppi_seq_integer_frequency (const GuppiSeqInteger *gsi, gint k) { gint min, max, i, i0, i1, count = 0; GuppiSeqIntegerClass *klass; g_return_val_if_fail (gsi != NULL, 0); klass = GUPPI_SEQ_INTEGER_CLASS (GTK_OBJECT (gsi)->klass); min = guppi_seq_integer_min (gsi); max = guppi_seq_integer_max (gsi); if (k < min || k > max) return 0; if (klass->frequency) { return klass->frequency ((GuppiSeqInteger *) gsi, k); } else { guppi_seq_indices (GUPPI_SEQ (gsi), &i0, &i1); for (i = i0; i <= i1; ++i) if (guppi_seq_integer_get (gsi, i) == k) ++count; return count; } } /* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */ static void guppi_seq_integer_class_init (GuppiSeqIntegerClass *klass) { GtkObjectClass *object_class = (GtkObjectClass *) klass; GuppiSeqClass *seq_class = GUPPI_SEQ_CLASS (klass); parent_class = gtk_type_class (GUPPI_TYPE_SEQ); klass->set = set; klass->insert = insert; seq_class->insert_generic = insert_generic; seq_class->export_xml_element = export_xml_element; seq_class->import_xml_element = import_xml_element; object_class->finalize = guppi_seq_integer_finalize; } static void guppi_seq_integer_init (GuppiSeqInteger *obj) { } GtkType guppi_seq_integer_get_type (void) { static GtkType guppi_seq_integer_type = 0; if (!guppi_seq_integer_type) { static const GtkTypeInfo guppi_seq_integer_info = { "GuppiSeqInteger", sizeof (GuppiSeqInteger), sizeof (GuppiSeqIntegerClass), (GtkClassInitFunc) guppi_seq_integer_class_init, (GtkObjectInitFunc) guppi_seq_integer_init, NULL, NULL, (GtkClassInitFunc) NULL }; guppi_seq_integer_type = gtk_type_unique (GUPPI_TYPE_SEQ, &guppi_seq_integer_info); } return guppi_seq_integer_type; } /* $Id: guppi-seq-integer.c,v 1.19 2002/01/14 05:01:17 trow Exp $ */