[aravis/dom] genicam: ArvGcRegister is now an interface, implemented by ArvGcRegisterNode and ArvGcStructEntryNod
- From: Emmanuel Pacaud <emmanuel src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [aravis/dom] genicam: ArvGcRegister is now an interface, implemented by ArvGcRegisterNode and ArvGcStructEntryNod
- Date: Sun, 4 Mar 2012 22:38:36 +0000 (UTC)
commit d7f432cdaa25ef0163d916f186b726858e6b8f52
Author: Emmanuel Pacaud <emmanuel gnome org>
Date: Sun Mar 4 23:37:37 2012 +0100
genicam: ArvGcRegister is now an interface, implemented by ArvGcRegisterNode and ArvGcStructEntryNode.
docs/reference/aravis/aravis-docs.xml | 3 +-
docs/reference/aravis/aravis-sections.txt | 65 ++-
docs/reference/aravis/aravis.types | 2 +-
src/Makefile.am | 6 +-
src/arv.h | 3 +-
src/arvfakecamera.c | 2 +-
src/arvgc.c | 12 +-
src/arvgcregister.c | 704 +--------------------------
src/arvgcregister.h | 93 +---
src/arvgcregisternode.c | 771 +++++++++++++++++++++++++++++
src/arvgcregisternode.h | 116 +++++
src/arvgcstructentrynode.c | 61 +++-
src/arvtypes.h | 3 +-
tests/fake.c | 11 +
14 files changed, 1038 insertions(+), 814 deletions(-)
---
diff --git a/docs/reference/aravis/aravis-docs.xml b/docs/reference/aravis/aravis-docs.xml
index ae949ee..4a723c8 100644
--- a/docs/reference/aravis/aravis-docs.xml
+++ b/docs/reference/aravis/aravis-docs.xml
@@ -56,6 +56,7 @@
<xi:include href="xml/arvgcfeaturenode.xml"/>
<xi:include href="xml/arvgcregisterdescriptionnode.xml"/>
<xi:include href="xml/arvgcgroupnode.xml"/>
+ <xi:include href="xml/arvgcregister.xml"/>
<xi:include href="xml/arvgcinteger.xml"/>
<xi:include href="xml/arvgcfloat.xml"/>
<xi:include href="xml/arvgcstring.xml"/>
@@ -64,7 +65,7 @@
<xi:include href="xml/arvgcboolean.xml"/>
<xi:include href="xml/arvgcintegernode.xml"/>
<xi:include href="xml/arvgcfloatnode.xml"/>
- <xi:include href="xml/arvgcregister.xml"/>
+ <xi:include href="xml/arvgcregisternode.xml"/>
<xi:include href="xml/arvgcstructentrynode.xml"/>
<xi:include href="xml/arvgcenumeration.xml"/>
<xi:include href="xml/arvgcenumentry.xml"/>
diff --git a/docs/reference/aravis/aravis-sections.txt b/docs/reference/aravis/aravis-sections.txt
index 13de108..39cc854 100644
--- a/docs/reference/aravis/aravis-sections.txt
+++ b/docs/reference/aravis/aravis-sections.txt
@@ -455,6 +455,25 @@ ArvGcIntegerInterface
</SECTION>
<SECTION>
+<FILE>arvgcregister</FILE>
+<TITLE>ArvGcRegister</TITLE>
+arv_gc_register_get
+arv_gc_register_get_address
+arv_gc_register_get_length
+arv_gc_register_get_type
+arv_gc_register_set
+<SUBSECTION Standard>
+ARV_GC_REGISTER
+ARV_GC_REGISTER_GET_CLASS
+ARV_GC_REGISTER_GET_INTERFACE
+ARV_IS_GC_REGISTER
+ARV_TYPE_GC_REGISTER
+ArvGcRegister
+ArvGcRegisterInterface
+ArvGcRegisterType
+</SECTION>
+
+<SECTION>
<FILE>arvgcconverter</FILE>
<TITLE>ArvGcConverter</TITLE>
ArvGcConverter
@@ -776,33 +795,29 @@ ArvFakeCameraFillPattern
</SECTION>
<SECTION>
-<FILE>arvgcregister</FILE>
-<TITLE>ArvGcRegister</TITLE>
+<FILE>arvgcregisternode</FILE>
+<TITLE>ArvGcRegisterNode</TITLE>
ArvGcSign
-ArvGcRegisterType
-ArvGcRegister
-arv_gc_register_new
-arv_gc_register_new_integer
-arv_gc_register_new_masked_integer
-arv_gc_register_new_float
-arv_gc_register_new_string
-arv_gc_register_new_struct_register
-arv_gc_register_get
-arv_gc_register_set
-arv_gc_register_get_address
-arv_gc_register_get_length
-arv_gc_register_get_masked_integer_value
-arv_gc_register_set_masked_integer_value
+ArvGcRegisterNode
+ArvGcRegisterNodeType
+arv_gc_register_node_new
+arv_gc_register_node_new_integer
+arv_gc_register_node_new_masked_integer
+arv_gc_register_node_new_float
+arv_gc_register_node_new_string
+arv_gc_register_node_new_struct_register
+arv_gc_register_node_get_masked_integer_value
+arv_gc_register_node_set_masked_integer_value
<SUBSECTION Standard>
-ARV_GC_REGISTER
-ARV_IS_GC_REGISTER
-ARV_TYPE_GC_REGISTER
-arv_gc_register_get_type
-ARV_GC_REGISTER_CLASS
-ARV_IS_GC_REGISTER_CLASS
-ARV_GC_REGISTER_GET_CLASS
+ARV_GC_REGISTER_NODE
+ARV_IS_GC_REGISTER_NODE
+ARV_TYPE_GC_REGISTER_NODE
+arv_gc_register_node_get_type
+ARV_GC_REGISTER_NODE_CLASS
+ARV_IS_GC_REGISTER_NODE_CLASS
+ARV_GC_REGISTER_NODE_GET_CLASS
<SUBSECTION Private>
-ArvGcRegisterClass
+ArvGcRegisterNodeClass
</SECTION>
<SECTION>
diff --git a/docs/reference/aravis/aravis.types b/docs/reference/aravis/aravis.types
index aafbed8..73b849c 100644
--- a/docs/reference/aravis/aravis.types
+++ b/docs/reference/aravis/aravis.types
@@ -19,7 +19,7 @@ arv_gc_integer_get_type
arv_gc_integer_node_get_type
arv_gc_feature_node_get_type
arv_gc_port_get_type
-arv_gc_register_get_type
+arv_gc_register_node_get_type
arv_gc_string_get_type
arv_gc_swiss_knife_get_type
arv_gv_device_get_type
diff --git a/src/Makefile.am b/src/Makefile.am
index b9e077e..44691ca 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -59,12 +59,13 @@ ARAVIS_SRCS = \
arvgcenumentry.c \
arvgcintegernode.c \
arvgcfloatnode.c \
- arvgcregister.c \
+ arvgcregisternode.c \
arvgcstructentrynode.c \
arvgccommand.c \
arvgcswissknife.c \
arvgcconverter.c \
arvgcport.c \
+ arvgcregister.c \
arvgcinteger.c \
arvgcstring.c \
arvgcfloat.c \
@@ -120,12 +121,13 @@ ARAVIS_HDRS = \
arvgcenumentry.h \
arvgcintegernode.h \
arvgcfloatnode.h \
- arvgcregister.h \
+ arvgcregisternode.h \
arvgcstructentrynode.h \
arvgccommand.h \
arvgcswissknife.h \
arvgcconverter.h \
arvgcport.h \
+ arvgcregister.h \
arvgcinteger.h \
arvgcstring.h \
arvgcfloat.h \
diff --git a/src/arv.h b/src/arv.h
index e4d2f3f..5e6eaf0 100644
--- a/src/arv.h
+++ b/src/arv.h
@@ -49,11 +49,12 @@
#include <arvgcenumentry.h>
#include <arvgcintegernode.h>
#include <arvgcfloatnode.h>
-#include <arvgcregister.h>
+#include <arvgcregisternode.h>
#include <arvgccommand.h>
#include <arvgcswissknife.h>
#include <arvgcconverter.h>
#include <arvgcport.h>
+#include <arvgcregister.h>
#include <arvgcinteger.h>
#include <arvgcfloat.h>
#include <arvgcstring.h>
diff --git a/src/arvfakecamera.c b/src/arvfakecamera.c
index e9397d0..fbad89a 100644
--- a/src/arvfakecamera.c
+++ b/src/arvfakecamera.c
@@ -32,7 +32,7 @@
#include <arvfakecamera.h>
#include <arvgc.h>
-#include <arvgcregister.h>
+#include <arvgcregisternode.h>
#include <arvgvcp.h>
#include <arvbuffer.h>
#include <arvdebug.h>
diff --git a/src/arvgc.c b/src/arvgc.c
index 90e9e9e..8d929c8 100644
--- a/src/arvgc.c
+++ b/src/arvgc.c
@@ -42,7 +42,7 @@
#include <arvgcenumentry.h>
#include <arvgcintegernode.h>
#include <arvgcfloatnode.h>
-#include <arvgcregister.h>
+#include <arvgcregisternode.h>
#include <arvgcstructentrynode.h>
#include <arvgccommand.h>
#include <arvgcinteger.h>
@@ -81,15 +81,15 @@ arv_gc_create_element (ArvDomDocument *document, const char *tag_name)
else if (strcmp (tag_name, "IntConverter") == 0)
node = arv_gc_converter_new_integer ();
else if (strcmp (tag_name, "IntReg") == 0)
- node = arv_gc_register_new_integer ();
+ node = arv_gc_register_node_new_integer ();
else if (strcmp (tag_name, "MaskedIntReg") == 0)
- node = arv_gc_register_new_masked_integer ();
+ node = arv_gc_register_node_new_masked_integer ();
else if (strcmp (tag_name, "FloatReg") == 0)
- node = arv_gc_register_new_float ();
+ node = arv_gc_register_node_new_float ();
else if (strcmp (tag_name, "StringReg") == 0)
- node = arv_gc_register_new_string ();
+ node = arv_gc_register_node_new_string ();
else if (strcmp (tag_name, "StructReg") == 0)
- node = arv_gc_register_new_struct_register ();
+ node = arv_gc_register_node_new_struct_register ();
else if (strcmp (tag_name, "StructEntry") == 0)
node = arv_gc_struct_entry_node_new ();
else if (strcmp (tag_name, "Integer") == 0)
diff --git a/src/arvgcregister.c b/src/arvgcregister.c
index bbf78c8..d4e6d80 100644
--- a/src/arvgcregister.c
+++ b/src/arvgcregister.c
@@ -22,372 +22,45 @@
/**
* SECTION: arvgcregister
- * @short_description: Class for Register, IntReg, MaskedIntReg, FloatReg and StringReg nodes
+ * @short_description: Register interface
*/
#include <arvgcregister.h>
-#include <arvgcindexnode.h>
-#include <arvgcinvalidatornode.h>
-#include <arvgcinteger.h>
-#include <arvgcfloat.h>
-#include <arvgcstring.h>
-#include <arvgcport.h>
-#include <arvgc.h>
#include <arvmisc.h>
-#include <arvdebug.h>
-#include <stdlib.h>
-#include <string.h>
-
-static GObjectClass *parent_class = NULL;
-
-/* ArvDomNode implementation */
-
-static const char *
-arv_gc_register_get_node_name (ArvDomNode *node)
-{
- ArvGcRegister *gc_register = ARV_GC_REGISTER (node);
-
- switch (gc_register->type) {
- case ARV_GC_REGISTER_TYPE_REGISTER:
- return "Register";
- case ARV_GC_REGISTER_TYPE_INTEGER:
- return "IntReg";
- case ARV_GC_REGISTER_TYPE_MASKED_INTEGER:
- return "MaskedIntReg";
- case ARV_GC_REGISTER_TYPE_FLOAT:
- return "FloatReg";
- case ARV_GC_REGISTER_TYPE_STRING:
- return "StringReg";
- case ARV_GC_REGISTER_TYPE_STRUCT_REGISTER:
- return "StuctReg";
- }
-
- return NULL;
-}
-
-static void
-arv_gc_register_post_new_child (ArvDomNode *self, ArvDomNode *child)
-{
- ArvGcRegister *node = ARV_GC_REGISTER (self);
-
- if (ARV_IS_GC_PROPERTY_NODE (child)) {
- ArvGcPropertyNode *property_node = ARV_GC_PROPERTY_NODE (child);
-
- switch (arv_gc_property_node_get_node_type (property_node)) {
- case ARV_GC_PROPERTY_NODE_TYPE_ADDRESS:
- case ARV_GC_PROPERTY_NODE_TYPE_P_ADDRESS:
- node->addresses = g_slist_prepend (node->addresses, child);
- break;
- case ARV_GC_PROPERTY_NODE_TYPE_P_INDEX:
- node->index = property_node;
- break;
- case ARV_GC_PROPERTY_NODE_TYPE_LENGTH:
- case ARV_GC_PROPERTY_NODE_TYPE_P_LENGTH:
- node->length = property_node;
- break;
- case ARV_GC_PROPERTY_NODE_TYPE_P_PORT:
- node->port = property_node;
- break;
- case ARV_GC_PROPERTY_NODE_TYPE_ACCESS_MODE:
- /* TODO */
- node->access_mode = property_node;
- break;
- case ARV_GC_PROPERTY_NODE_TYPE_CACHABLE:
- node->cachable = property_node;
- break;
- case ARV_GC_PROPERTY_NODE_TYPE_POLLING_TIME:
- /* TODO */
- node->polling_time = property_node;
- break;
- case ARV_GC_PROPERTY_NODE_TYPE_ENDIANESS:
- node->endianess = property_node;
- break;
- case ARV_GC_PROPERTY_NODE_TYPE_SIGN:
- /* TODO */
- node->sign = property_node;
- break;
- case ARV_GC_PROPERTY_NODE_TYPE_LSB:
- node->lsb = property_node;
- break;
- case ARV_GC_PROPERTY_NODE_TYPE_MSB:
- node->msb = property_node;
- break;
- case ARV_GC_PROPERTY_NODE_TYPE_BIT:
- node->msb = property_node;
- node->lsb = property_node;
- break;
- case ARV_GC_PROPERTY_NODE_TYPE_P_INVALIDATOR:
- node->invalidators = g_slist_prepend (node->invalidators, property_node);
- break;
- default:
- ARV_DOM_NODE_CLASS (parent_class)->post_new_child (self, child);
- break;
- }
- }
-}
-
-static void
-arv_gc_register_pre_remove_child (ArvDomNode *self, ArvDomNode *child)
-{
- g_assert_not_reached ();
-}
-
-/* ArvGcFeatureNode implementation */
-
-static GType
-arv_gc_register_get_value_type (ArvGcFeatureNode *node)
-{
- ArvGcRegister *gc_register = ARV_GC_REGISTER (node);
-
- return gc_register->value_type;
-}
-
-static void
-arv_gc_register_set_value_from_string (ArvGcFeatureNode *node, const char *string)
-{
- ArvGcRegister *gc_register = ARV_GC_REGISTER (node);
-
- switch (gc_register->value_type) {
- case G_TYPE_INT64:
- arv_gc_integer_set_value (ARV_GC_INTEGER (node), g_ascii_strtoll (string, NULL, 0));
- break;
- case G_TYPE_DOUBLE:
- arv_gc_float_set_value (ARV_GC_FLOAT (node), g_ascii_strtod (string, NULL));
- break;
- case G_TYPE_STRING:
- arv_gc_string_set_value (ARV_GC_STRING (node), string);
- break;
- default:
- break;
- }
-}
-
-static const char *
-arv_gc_register_get_value_as_string (ArvGcFeatureNode *node)
-{
- ArvGcRegister *gc_register = ARV_GC_REGISTER (node);
-
- switch (gc_register->value_type) {
- case G_TYPE_INT64:
- g_snprintf (gc_register->v_string, G_ASCII_DTOSTR_BUF_SIZE,
- "0x%08" G_GINT64_MODIFIER "x", arv_gc_integer_get_value (ARV_GC_INTEGER (node)));
- return gc_register->v_string;
- case G_TYPE_DOUBLE:
- g_ascii_dtostr (gc_register->v_string, G_ASCII_DTOSTR_BUF_SIZE,
- arv_gc_float_get_value (ARV_GC_FLOAT (node)));
- return gc_register->v_string;
- case G_TYPE_STRING:
- return arv_gc_string_get_value (ARV_GC_STRING (node));
- default:
- break;
- }
-
- return NULL;
-}
-
-/* ArvGcRegister implementation */
-
-gboolean
-_get_cache_validity (ArvGcRegister *gc_register)
-{
- GSList *iter;
- gint modification_count;
- gint feature_modification_count;
- gboolean is_cache_valid = gc_register->is_cache_valid;
-
- for (iter = gc_register->invalidators; iter != NULL; iter = iter->next) {
- ArvGcInvalidatorNode *invalidator = iter->data;
- ArvGcNode *node;
-
- modification_count = arv_gc_invalidator_node_get_modification_count (invalidator);
- node = arv_gc_property_node_get_linked_node (ARV_GC_PROPERTY_NODE (invalidator));
- feature_modification_count = arv_gc_feature_node_get_modification_count (ARV_GC_FEATURE_NODE (node));
- arv_gc_invalidator_node_set_modification_count (invalidator, feature_modification_count);
- if (modification_count != feature_modification_count)
- is_cache_valid = FALSE;
- }
-
- return is_cache_valid;
-}
-
-static gint64
-_get_length (ArvGcRegister *gc_register)
-{
- if (gc_register->length == NULL)
- return 4;
-
- return arv_gc_property_node_get_int64 (gc_register->length);
-}
static void
-_update_cache_size (ArvGcRegister *gc_register)
+arv_gc_register_default_init (ArvGcRegisterInterface *gc_register_iface)
{
- gint64 length;
-
- length = _get_length (gc_register);
- if (length != gc_register->cache_size) {
- g_free (gc_register->cache);
- gc_register->cache = g_malloc (length);
- gc_register->cache_size = length;
- }
-
-}
-
-static ArvGcCachable
-_get_cachable (ArvGcRegister *gc_register)
-{
- const char *cachable;
-
- if (gc_register->cachable == NULL)
- return ARV_GC_CACHABLE_NO_CACHE;
-
- cachable = arv_gc_property_node_get_string (gc_register->cachable);
- if (g_strcmp0 (cachable, "WriteThrough") == 0)
- return ARV_GC_CACHABLE_WRITE_TRHOUGH;
- else if (strcmp (cachable, "WriteAround") == 0)
- return ARV_GC_CACHABLE_WRITE_AROUND;
-
- return ARV_GC_CACHABLE_NO_CACHE;
}
-/* Set default to read only 32 bits little endian integer register */
-
-static ArvGcCachable
-_get_endianess (ArvGcRegister *gc_register)
-{
- const char *endianess;
-
- if (gc_register->endianess == NULL)
- return G_LITTLE_ENDIAN;
-
- endianess = arv_gc_property_node_get_string (gc_register->endianess);
- if (g_strcmp0 (endianess, "BigEndian") == 0)
- return G_BIG_ENDIAN;
-
- return G_LITTLE_ENDIAN;
-}
-
-static ArvGcCachable
-_get_lsb (ArvGcRegister *gc_register)
-{
- if (gc_register->lsb == NULL)
- return 0;
-
- return arv_gc_property_node_get_int64 (gc_register->lsb);
-}
-
-static ArvGcCachable
-_get_msb (ArvGcRegister *gc_register)
-{
- if (gc_register->msb == NULL)
- return 31;
-
- return arv_gc_property_node_get_int64 (gc_register->msb);
-}
-
-static void
-_read_cache (ArvGcRegister *gc_register)
-{
- ArvGcNode *port;
-
- if (gc_register->is_cache_valid == TRUE) {
- arv_log_genicam ("[GcRegister::read_cache] Cache is valid");
- return;
- }
-
- port = arv_gc_property_node_get_linked_node (gc_register->port);
- if (!ARV_IS_GC_PORT (port))
- return;
-
- _update_cache_size (gc_register);
-
- arv_gc_port_read (ARV_GC_PORT (port),
- gc_register->cache,
- arv_gc_register_get_address (gc_register),
- gc_register->cache_size);
-
- if (_get_cachable (gc_register) != ARV_GC_CACHABLE_NO_CACHE)
- gc_register->is_cache_valid = TRUE;
- else
- gc_register->is_cache_valid = FALSE;
-}
-
-static void
-_write_cache (ArvGcRegister *gc_register)
-{
- ArvGcNode *port;
-
- arv_gc_feature_node_inc_modification_count (ARV_GC_FEATURE_NODE (gc_register));
-
- port = arv_gc_property_node_get_linked_node (gc_register->port);
- if (!ARV_IS_GC_PORT (port))
- return;
-
- _update_cache_size (gc_register);
-
- arv_gc_port_write (ARV_GC_PORT (port),
- gc_register->cache,
- arv_gc_register_get_address (gc_register),
- gc_register->cache_size);
-
- if (_get_cachable (gc_register) == ARV_GC_CACHABLE_WRITE_TRHOUGH)
- gc_register->is_cache_valid = TRUE;
- else
- gc_register->is_cache_valid = FALSE;
-}
+G_DEFINE_INTERFACE (ArvGcRegister, arv_gc_register, G_TYPE_OBJECT)
void
arv_gc_register_get (ArvGcRegister *gc_register, void *buffer, guint64 length)
{
g_return_if_fail (ARV_IS_GC_REGISTER (gc_register));
+ g_return_if_fail (buffer != NULL);
+ g_return_if_fail (length > 0);
- _read_cache (gc_register);
-
- if (length > gc_register->cache_size) {
- memcpy (buffer, gc_register->cache, gc_register->cache_size);
- memset (buffer + gc_register->cache_size, 0, length - gc_register->cache_size);
- } else
- memcpy (buffer, gc_register->cache, length);
-
- arv_log_genicam ("[GcRegister::get] 0x%Lx,%Ld",
- arv_gc_register_get_address (gc_register), length);
+ ARV_GC_REGISTER_GET_INTERFACE (gc_register)->get (gc_register, buffer, length);
}
void
arv_gc_register_set (ArvGcRegister *gc_register, void *buffer, guint64 length)
{
g_return_if_fail (ARV_IS_GC_REGISTER (gc_register));
+ g_return_if_fail (buffer != NULL);
+ g_return_if_fail (length > 0);
- if (gc_register->cache_size > length) {
- memcpy (gc_register->cache, buffer, length);
- memset (gc_register->cache + length, 0, gc_register->cache_size - length);
- } else
- memcpy (gc_register->cache, buffer, gc_register->cache_size);
-
- _write_cache (gc_register);
-
- arv_log_genicam ("[GcRegister::set] 0x%Lx,%Ld", arv_gc_register_get_address (gc_register), length);
+ ARV_GC_REGISTER_GET_INTERFACE (gc_register)->set (gc_register, buffer, length);
}
guint64
arv_gc_register_get_address (ArvGcRegister *gc_register)
{
- ArvGc *genicam;
- GSList *iter;
- guint64 value = 0;
-
g_return_val_if_fail (ARV_IS_GC_REGISTER (gc_register), 0);
- genicam = arv_gc_node_get_genicam (ARV_GC_NODE (gc_register));
- g_return_val_if_fail (ARV_IS_GC (genicam), 0);
-
- for (iter = gc_register->addresses; iter != NULL; iter = iter->next)
- value += arv_gc_property_node_get_int64 (iter->data);
- if (gc_register->index != NULL)
- value += arv_gc_index_node_get_index (ARV_GC_INDEX_NODE (gc_register->index),
- arv_gc_register_get_length (gc_register));
-
- return value;
+ return ARV_GC_REGISTER_GET_INTERFACE (gc_register)->get_address (gc_register);
}
guint64
@@ -395,360 +68,5 @@ arv_gc_register_get_length (ArvGcRegister *gc_register)
{
g_return_val_if_fail (ARV_IS_GC_REGISTER (gc_register), 0);
- return _get_length (gc_register);
-}
-
-ArvGcNode *
-arv_gc_register_new (void)
-{
- ArvGcRegister *gc_register;
-
- gc_register = g_object_new (ARV_TYPE_GC_REGISTER, NULL);
- gc_register->type = ARV_GC_REGISTER_TYPE_REGISTER;
- gc_register->value_type = G_TYPE_BYTE_ARRAY;
-
- return ARV_GC_NODE (gc_register);
-}
-
-ArvGcNode *
-arv_gc_register_new_integer (void)
-{
- ArvGcRegister *gc_register;
-
- gc_register = g_object_new (ARV_TYPE_GC_REGISTER, NULL);
- gc_register->type = ARV_GC_REGISTER_TYPE_INTEGER;
- gc_register->value_type = G_TYPE_INT64;
-
- return ARV_GC_NODE (gc_register);
-}
-
-ArvGcNode *
-arv_gc_register_new_masked_integer (void)
-{
- ArvGcRegister *gc_register;
-
- gc_register = g_object_new (ARV_TYPE_GC_REGISTER, NULL);
- gc_register->type = ARV_GC_REGISTER_TYPE_MASKED_INTEGER;
- gc_register->value_type = G_TYPE_INT64;
-
- return ARV_GC_NODE (gc_register);
-}
-
-ArvGcNode *
-arv_gc_register_new_float (void)
-{
- ArvGcRegister *gc_register;
-
- gc_register = g_object_new (ARV_TYPE_GC_REGISTER, NULL);
- gc_register->type = ARV_GC_REGISTER_TYPE_FLOAT;
- gc_register->value_type = G_TYPE_DOUBLE;
-
- return ARV_GC_NODE (gc_register);
-}
-
-ArvGcNode *
-arv_gc_register_new_string (void)
-{
- ArvGcRegister *gc_register;
-
- gc_register = g_object_new (ARV_TYPE_GC_REGISTER, NULL);
- gc_register->type = ARV_GC_REGISTER_TYPE_STRING;
- gc_register->value_type = G_TYPE_STRING;
-
- return ARV_GC_NODE (gc_register);
+ return ARV_GC_REGISTER_GET_INTERFACE (gc_register)->get_length (gc_register);
}
-
-ArvGcNode *
-arv_gc_register_new_struct_register (void)
-{
- ArvGcRegister *gc_register;
-
- gc_register = g_object_new (ARV_TYPE_GC_REGISTER, NULL);
- gc_register->type = ARV_GC_REGISTER_TYPE_STRUCT_REGISTER;
- gc_register->value_type = G_TYPE_INT64;
-
- return ARV_GC_NODE (gc_register);
-}
-
-static void
-arv_gc_register_init (ArvGcRegister *gc_register)
-{
- gc_register->cache = g_malloc0(4);
- gc_register->cache_size = 4;
- gc_register->is_cache_valid = FALSE;
-}
-
-static void
-arv_gc_register_finalize (GObject *object)
-{
- ArvGcRegister *gc_register = ARV_GC_REGISTER (object);
-
- g_slist_free (gc_register->addresses);
- g_free (gc_register->cache);
- g_slist_free (gc_register->invalidators);
-
- parent_class->finalize (object);
-}
-
-static void
-arv_gc_register_class_init (ArvGcRegisterClass *this_class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (this_class);
- ArvDomNodeClass *dom_node_class = ARV_DOM_NODE_CLASS (this_class);
- ArvGcFeatureNodeClass *gc_feature_node_class = ARV_GC_FEATURE_NODE_CLASS (this_class);
-
- parent_class = g_type_class_peek_parent (this_class);
-
- object_class->finalize = arv_gc_register_finalize;
- dom_node_class->get_node_name = arv_gc_register_get_node_name;
- dom_node_class->post_new_child = arv_gc_register_post_new_child;
- dom_node_class->pre_remove_child = arv_gc_register_pre_remove_child;
- gc_feature_node_class->get_value_type = arv_gc_register_get_value_type;
- gc_feature_node_class->set_value_from_string = arv_gc_register_set_value_from_string;
- gc_feature_node_class->get_value_as_string = arv_gc_register_get_value_as_string;
-}
-
-/* ArvGcInteger interface implementation */
-
-static gint64
-_get_integer_value (ArvGcRegister *gc_register, guint register_lsb, guint register_msb)
-{
- gint64 value;
- guint lsb;
- guint msb;
- guint endianess;
-
- endianess = _get_endianess (gc_register);
-
- _read_cache (gc_register);
-
- arv_copy_memory_with_endianess (&value, sizeof (value), G_BYTE_ORDER,
- gc_register->cache, gc_register->cache_size, endianess);
-
- if (gc_register->type == ARV_GC_REGISTER_TYPE_MASKED_INTEGER ||
- gc_register->type == ARV_GC_REGISTER_TYPE_STRUCT_REGISTER) {
- guint64 mask;
-
- if (endianess == G_BYTE_ORDER) {
- msb = register_msb;
- lsb = register_lsb;
- } else {
- lsb = 8 * gc_register->cache_size - register_lsb - 1;
- msb = 8 * gc_register->cache_size - register_msb - 1;
- }
-
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
- if (msb - lsb < 63)
- mask = ((((guint64) 1) << (msb - lsb + 1)) - 1) << lsb;
- else
- mask = G_MAXUINT64;
-
- value = (value & mask) >> lsb;
-#else
- g_assert_not_reached ();
-#endif
- }
-
- arv_log_genicam ("[GcRegister::_get_integer_value] address = 0x%Lx, value = 0x%Lx",
- arv_gc_register_get_address (gc_register),
- value);
-
- return value;
-}
-
-gint64
-arv_gc_register_get_masked_integer_value (ArvGcRegister *gc_register, guint lsb, guint msb)
-{
- g_return_val_if_fail (ARV_IS_GC_REGISTER (gc_register), 0);
-
- return _get_integer_value (gc_register, lsb, msb);
-}
-
-static gint64
-arv_gc_register_get_integer_value (ArvGcInteger *gc_integer)
-{
- ArvGcRegister *gc_register = ARV_GC_REGISTER (gc_integer);
-
- return _get_integer_value (gc_register, _get_lsb (gc_register), _get_msb (gc_register));
-}
-
-static void
-_set_integer_value (ArvGcRegister *gc_register, guint register_lsb, guint register_msb, gint64 value)
-{
- guint lsb;
- guint msb;
- guint endianess;
-
- endianess = _get_endianess (gc_register);
-
- if (gc_register->type == ARV_GC_REGISTER_TYPE_MASKED_INTEGER ||
- gc_register->type == ARV_GC_REGISTER_TYPE_STRUCT_REGISTER) {
- gint64 current_value;
- guint64 mask;
-
- _read_cache (gc_register);
-
- arv_copy_memory_with_endianess (¤t_value, sizeof (current_value), G_BYTE_ORDER,
- gc_register->cache, gc_register->cache_size, endianess);
-
- if (endianess == G_BYTE_ORDER) {
- msb = register_msb;
- lsb = register_lsb;
- } else {
- lsb = 8 * gc_register->cache_size - register_lsb - 1;
- msb = 8 * gc_register->cache_size - register_msb - 1;
- }
-
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
- if (msb - lsb < 63)
- mask = ((((guint64) 1) << (msb - lsb + 1)) - 1) << lsb;
- else
- mask = G_MAXUINT64;
-
- value = ((value << lsb) & mask) | (current_value & ~mask);
-#else
- g_assert_not_reached ();
-#endif
- }
-
- arv_log_genicam ("[GcRegister::_set_integer_value] address = 0x%Lx, value = 0x%Lx",
- arv_gc_register_get_address (gc_register),
- value);
-
- arv_copy_memory_with_endianess (gc_register->cache, gc_register->cache_size, endianess,
- &value, sizeof (value), G_BYTE_ORDER);
-
- _write_cache (gc_register);
-}
-
-void
-arv_gc_register_set_masked_integer_value (ArvGcRegister *gc_register, guint lsb, guint msb, gint64 value)
-{
- g_return_if_fail (ARV_IS_GC_REGISTER (gc_register));
-
- _set_integer_value (gc_register, lsb, msb, value);
-}
-
-static void
-arv_gc_register_set_integer_value (ArvGcInteger *gc_integer, gint64 value)
-{
- ArvGcRegister *gc_register = ARV_GC_REGISTER (gc_integer);
-
- _set_integer_value (gc_register, _get_lsb (gc_register), _get_msb (gc_register), value);
-}
-
-static void
-arv_gc_register_integer_interface_init (ArvGcIntegerInterface *interface)
-{
- interface->get_value = arv_gc_register_get_integer_value;
- interface->set_value = arv_gc_register_set_integer_value;
-}
-
-static double
-arv_gc_register_get_float_value (ArvGcFloat *gc_float)
-{
- ArvGcRegister *gc_register = ARV_GC_REGISTER (gc_float);
- guint endianess;
-
- endianess = _get_endianess (gc_register);
-
- _read_cache (gc_register);
-
- if (gc_register->cache_size == 4) {
- float v_float;
- arv_copy_memory_with_endianess (&v_float, sizeof (v_float), G_BYTE_ORDER,
- gc_register->cache, gc_register->cache_size, endianess);
-
- return v_float;
- } else if (gc_register->cache_size == 8) {
- double v_double;
- arv_copy_memory_with_endianess (&v_double, sizeof (v_double), G_BYTE_ORDER,
- gc_register->cache, gc_register->cache_size, endianess);
-
- return v_double;
- } else {
- arv_warning_genicam ("[GcFloatReg::get_value] Invalid register size");
- return 0.0;
- }
-}
-
-static void
-arv_gc_register_set_float_value (ArvGcFloat *gc_float, double v_double)
-{
- ArvGcRegister *gc_register = ARV_GC_REGISTER (gc_float);
- guint endianess;
-
- endianess = _get_endianess (gc_register);
-
- _update_cache_size (gc_register);
-
- if (gc_register->cache_size == 4) {
- float v_float = v_double;
- arv_copy_memory_with_endianess (gc_register->cache, gc_register->cache_size, endianess,
- &v_float, sizeof (v_float), G_BYTE_ORDER);
- } else if (gc_register->cache_size == 8) {
- arv_copy_memory_with_endianess (gc_register->cache, gc_register->cache_size, endianess,
- &v_double, sizeof (v_double), G_BYTE_ORDER);
- } else {
- arv_warning_genicam ("[GcFloatReg::set_value] Invalid register size");
- return;
- }
-
- _write_cache (gc_register);
-}
-
-static void
-arv_gc_register_float_interface_init (ArvGcFloatInterface *interface)
-{
- interface->get_value = arv_gc_register_get_float_value;
- interface->set_value = arv_gc_register_set_float_value;
-}
-
-static const char *
-arv_gc_register_get_string_value (ArvGcString *gc_string)
-{
- ArvGcRegister *gc_register = ARV_GC_REGISTER (gc_string);
-
- _read_cache (gc_register);
-
- if (gc_register->cache_size > 0)
- ((char *) gc_register->cache)[gc_register->cache_size - 1] = '\0';
-
- return gc_register->cache;
-}
-
-static void
-arv_gc_register_set_string_value (ArvGcString *gc_string, const char *value)
-{
- ArvGcRegister *gc_register = ARV_GC_REGISTER (gc_string);
-
- _update_cache_size (gc_register);
-
- if (gc_register->cache_size > 0) {
- strncpy (gc_register->cache, value, gc_register->cache_size);
- ((char *) gc_register->cache)[gc_register->cache_size - 1] = '\0';
-
- _write_cache (gc_register);
- }
-}
-
-static gint64
-arv_gc_register_get_max_string_length (ArvGcString *gc_string)
-{
- ArvGcRegister *gc_register = ARV_GC_REGISTER (gc_string);
-
- return arv_gc_register_get_length (gc_register);
-}
-
-static void
-arv_gc_register_string_interface_init (ArvGcStringInterface *interface)
-{
- interface->get_value = arv_gc_register_get_string_value;
- interface->set_value = arv_gc_register_set_string_value;
- interface->get_max_length = arv_gc_register_get_max_string_length;
-}
-
-G_DEFINE_TYPE_WITH_CODE (ArvGcRegister, arv_gc_register, ARV_TYPE_GC_FEATURE_NODE,
- G_IMPLEMENT_INTERFACE (ARV_TYPE_GC_INTEGER, arv_gc_register_integer_interface_init)
- G_IMPLEMENT_INTERFACE (ARV_TYPE_GC_FLOAT, arv_gc_register_float_interface_init)
- G_IMPLEMENT_INTERFACE (ARV_TYPE_GC_STRING, arv_gc_register_string_interface_init))
diff --git a/src/arvgcregister.h b/src/arvgcregister.h
index 930aa3c..b49bcf4 100644
--- a/src/arvgcregister.h
+++ b/src/arvgcregister.h
@@ -24,97 +24,32 @@
#define ARV_GC_REGISTER_H
#include <arvtypes.h>
-#include <arvgcfeaturenode.h>
-#include <arvgcpropertynode.h>
G_BEGIN_DECLS
-/**
- * ArvGcSign:
- * @ARV_GC_SIGN_SIGNED: signed integer
- * @ARV_GC_SIGN_UNSIGNED: unsigned integer
- */
-
-typedef enum
-{
- ARV_GC_SIGN_SIGNED,
- ARV_GC_SIGN_UNSIGNED
-} ArvGcSign;
-
-/**
- * ArvGcRegisterType:
- * @ARV_GC_REGISTER_TYPE_REGISTER: Register node
- * @ARV_GC_REGISTER_TYPE_INTEGER: IntReg node
- * @ARV_GC_REGISTER_TYPE_MASKED_INTEGER: MaskedIntReg node
- * @ARV_GC_REGISTER_TYPE_FLOAT: FloatReg node
- * @ARV_GC_REGISTER_TYPE_STRING: StringReg node
- * @ARV_GC_REGISTER_TYPE_STRUCT_REGISTER: StructReg node
- */
-
-typedef enum {
- ARV_GC_REGISTER_TYPE_REGISTER,
- ARV_GC_REGISTER_TYPE_INTEGER,
- ARV_GC_REGISTER_TYPE_MASKED_INTEGER,
- ARV_GC_REGISTER_TYPE_FLOAT,
- ARV_GC_REGISTER_TYPE_STRING,
- ARV_GC_REGISTER_TYPE_STRUCT_REGISTER
-} ArvGcRegisterType;
-
-#define ARV_TYPE_GC_REGISTER (arv_gc_register_get_type ())
-#define ARV_GC_REGISTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ARV_TYPE_GC_REGISTER, ArvGcRegister))
-#define ARV_GC_REGISTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ARV_TYPE_GC_REGISTER, ArvGcRegisterClass))
-#define ARV_IS_GC_REGISTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ARV_TYPE_GC_REGISTER))
-#define ARV_IS_GC_REGISTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), ARV_TYPE_GC_REGISTER))
-#define ARV_GC_REGISTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), ARV_TYPE_GC_REGISTER, ArvGcRegisterClass))
+#define ARV_TYPE_GC_REGISTER (arv_gc_register_get_type ())
+#define ARV_GC_REGISTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ARV_TYPE_GC_REGISTER, ArvGcRegister))
+#define ARV_IS_GC_REGISTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ARV_TYPE_GC_REGISTER))
+#define ARV_GC_REGISTER_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE((obj), ARV_TYPE_GC_REGISTER, ArvGcRegisterInterface))
-typedef struct _ArvGcRegisterClass ArvGcRegisterClass;
+typedef struct _ArvGcRegisterInterface ArvGcRegisterInterface;
-struct _ArvGcRegister {
- ArvGcFeatureNode node;
+struct _ArvGcRegisterInterface {
+ GTypeInterface parent;
- ArvGcRegisterType type;
- GType value_type;
-
- GSList *addresses;
- ArvGcPropertyNode *index;
- ArvGcPropertyNode *length;
- ArvGcPropertyNode *port;
- ArvGcPropertyNode *access_mode;
- ArvGcPropertyNode *cachable;
- ArvGcPropertyNode *polling_time;
- ArvGcPropertyNode *endianess;
- ArvGcPropertyNode *sign;
- ArvGcPropertyNode *lsb;
- ArvGcPropertyNode *msb;
-
- GSList *invalidators; /* ArvGcPropertyNode list */
-
- void *cache;
- size_t cache_size;
- gboolean is_cache_valid;
-
- char v_string[G_ASCII_DTOSTR_BUF_SIZE];
+ void (*get) (ArvGcRegister *gc_register, void *buffer, guint64 length);
+ void (*set) (ArvGcRegister *gc_register, void *buffer, guint64 length);
+ guint64 (*get_address) (ArvGcRegister *gc_register);
+ guint64 (*get_length) (ArvGcRegister *gc_register);
};
-struct _ArvGcRegisterClass {
- ArvGcFeatureNodeClass parent_class;
-};
+GType arv_gc_register_get_type (void);
-GType arv_gc_register_get_type (void);
-ArvGcNode * arv_gc_register_new (void);
-ArvGcNode * arv_gc_register_new_integer (void);
-ArvGcNode * arv_gc_register_new_masked_integer (void);
-ArvGcNode * arv_gc_register_new_float (void);
-ArvGcNode * arv_gc_register_new_string (void);
-ArvGcNode * arv_gc_register_new_struct_register (void);
-void arv_gc_register_get (ArvGcRegister *gc_register, void *buffer, guint64 Length);
-void arv_gc_register_set (ArvGcRegister *gc_register, void *buffer, guint64 Length);
+void arv_gc_register_get (ArvGcRegister *gc_register, void *buffer, guint64 length);
+void arv_gc_register_set (ArvGcRegister *gc_register, void *buffer, guint64 length);
guint64 arv_gc_register_get_address (ArvGcRegister *gc_register);
guint64 arv_gc_register_get_length (ArvGcRegister *gc_register);
-gint64 arv_gc_register_get_masked_integer_value (ArvGcRegister *gc_register, guint lsb, guint msb);
-void arv_gc_register_set_masked_integer_value (ArvGcRegister *gc_register, guint lsb, guint msb, gint64 value);
-
G_END_DECLS
#endif
diff --git a/src/arvgcregisternode.c b/src/arvgcregisternode.c
new file mode 100644
index 0000000..605bdc6
--- /dev/null
+++ b/src/arvgcregisternode.c
@@ -0,0 +1,771 @@
+/* Aravis - Digital camera library
+ *
+ * Copyright  2009-2012 Emmanuel Pacaud
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+/**
+ * SECTION: arvgcregisternode
+ * @short_description: Class for Register, IntReg, MaskedIntReg, FloatReg and StringReg nodes
+ */
+
+#include <arvgcregisternode.h>
+#include <arvgcindexnode.h>
+#include <arvgcinvalidatornode.h>
+#include <arvgcregister.h>
+#include <arvgcinteger.h>
+#include <arvgcfloat.h>
+#include <arvgcstring.h>
+#include <arvgcport.h>
+#include <arvgc.h>
+#include <arvmisc.h>
+#include <arvdebug.h>
+#include <stdlib.h>
+#include <string.h>
+
+static GObjectClass *parent_class = NULL;
+
+/* ArvDomNode implementation */
+
+static const char *
+arv_gc_register_node_get_node_name (ArvDomNode *node)
+{
+ ArvGcRegisterNode *gc_register_node = ARV_GC_REGISTER_NODE (node);
+
+ switch (gc_register_node->type) {
+ case ARV_GC_REGISTER_NODE_TYPE_REGISTER:
+ return "Register";
+ case ARV_GC_REGISTER_NODE_TYPE_INTEGER:
+ return "IntReg";
+ case ARV_GC_REGISTER_NODE_TYPE_MASKED_INTEGER:
+ return "MaskedIntReg";
+ case ARV_GC_REGISTER_NODE_TYPE_FLOAT:
+ return "FloatReg";
+ case ARV_GC_REGISTER_NODE_TYPE_STRING:
+ return "StringReg";
+ case ARV_GC_REGISTER_NODE_TYPE_STRUCT_REGISTER:
+ return "StuctReg";
+ }
+
+ return NULL;
+}
+
+static void
+arv_gc_register_node_post_new_child (ArvDomNode *self, ArvDomNode *child)
+{
+ ArvGcRegisterNode *node = ARV_GC_REGISTER_NODE (self);
+
+ if (ARV_IS_GC_PROPERTY_NODE (child)) {
+ ArvGcPropertyNode *property_node = ARV_GC_PROPERTY_NODE (child);
+
+ switch (arv_gc_property_node_get_node_type (property_node)) {
+ case ARV_GC_PROPERTY_NODE_TYPE_ADDRESS:
+ case ARV_GC_PROPERTY_NODE_TYPE_P_ADDRESS:
+ node->addresses = g_slist_prepend (node->addresses, child);
+ break;
+ case ARV_GC_PROPERTY_NODE_TYPE_P_INDEX:
+ node->index = property_node;
+ break;
+ case ARV_GC_PROPERTY_NODE_TYPE_LENGTH:
+ case ARV_GC_PROPERTY_NODE_TYPE_P_LENGTH:
+ node->length = property_node;
+ break;
+ case ARV_GC_PROPERTY_NODE_TYPE_P_PORT:
+ node->port = property_node;
+ break;
+ case ARV_GC_PROPERTY_NODE_TYPE_ACCESS_MODE:
+ /* TODO */
+ node->access_mode = property_node;
+ break;
+ case ARV_GC_PROPERTY_NODE_TYPE_CACHABLE:
+ node->cachable = property_node;
+ break;
+ case ARV_GC_PROPERTY_NODE_TYPE_POLLING_TIME:
+ /* TODO */
+ node->polling_time = property_node;
+ break;
+ case ARV_GC_PROPERTY_NODE_TYPE_ENDIANESS:
+ node->endianess = property_node;
+ break;
+ case ARV_GC_PROPERTY_NODE_TYPE_SIGN:
+ /* TODO */
+ node->sign = property_node;
+ break;
+ case ARV_GC_PROPERTY_NODE_TYPE_LSB:
+ node->lsb = property_node;
+ break;
+ case ARV_GC_PROPERTY_NODE_TYPE_MSB:
+ node->msb = property_node;
+ break;
+ case ARV_GC_PROPERTY_NODE_TYPE_BIT:
+ node->msb = property_node;
+ node->lsb = property_node;
+ break;
+ case ARV_GC_PROPERTY_NODE_TYPE_P_INVALIDATOR:
+ node->invalidators = g_slist_prepend (node->invalidators, property_node);
+ break;
+ default:
+ ARV_DOM_NODE_CLASS (parent_class)->post_new_child (self, child);
+ break;
+ }
+ }
+}
+
+static void
+arv_gc_register_node_pre_remove_child (ArvDomNode *self, ArvDomNode *child)
+{
+ g_assert_not_reached ();
+}
+
+/* ArvGcFeatureNode implementation */
+
+static GType
+arv_gc_register_node_get_value_type (ArvGcFeatureNode *node)
+{
+ ArvGcRegisterNode *gc_register_node = ARV_GC_REGISTER_NODE (node);
+
+ return gc_register_node->value_type;
+}
+
+static void
+arv_gc_register_node_set_value_from_string (ArvGcFeatureNode *node, const char *string)
+{
+ ArvGcRegisterNode *gc_register_node = ARV_GC_REGISTER_NODE (node);
+
+ switch (gc_register_node->value_type) {
+ case G_TYPE_INT64:
+ arv_gc_integer_set_value (ARV_GC_INTEGER (node), g_ascii_strtoll (string, NULL, 0));
+ break;
+ case G_TYPE_DOUBLE:
+ arv_gc_float_set_value (ARV_GC_FLOAT (node), g_ascii_strtod (string, NULL));
+ break;
+ case G_TYPE_STRING:
+ arv_gc_string_set_value (ARV_GC_STRING (node), string);
+ break;
+ default:
+ break;
+ }
+}
+
+static const char *
+arv_gc_register_node_get_value_as_string (ArvGcFeatureNode *node)
+{
+ ArvGcRegisterNode *gc_register_node = ARV_GC_REGISTER_NODE (node);
+
+ switch (gc_register_node->value_type) {
+ case G_TYPE_INT64:
+ g_snprintf (gc_register_node->v_string, G_ASCII_DTOSTR_BUF_SIZE,
+ "0x%08" G_GINT64_MODIFIER "x", arv_gc_integer_get_value (ARV_GC_INTEGER (node)));
+ return gc_register_node->v_string;
+ case G_TYPE_DOUBLE:
+ g_ascii_dtostr (gc_register_node->v_string, G_ASCII_DTOSTR_BUF_SIZE,
+ arv_gc_float_get_value (ARV_GC_FLOAT (node)));
+ return gc_register_node->v_string;
+ case G_TYPE_STRING:
+ return arv_gc_string_get_value (ARV_GC_STRING (node));
+ default:
+ break;
+ }
+
+ return NULL;
+}
+
+/* ArvGcRegisterNode implementation */
+
+gboolean
+_get_cache_validity (ArvGcRegisterNode *gc_register_node)
+{
+ GSList *iter;
+ gint modification_count;
+ gint feature_modification_count;
+ gboolean is_cache_valid = gc_register_node->is_cache_valid;
+
+ for (iter = gc_register_node->invalidators; iter != NULL; iter = iter->next) {
+ ArvGcInvalidatorNode *invalidator = iter->data;
+ ArvGcNode *node;
+
+ modification_count = arv_gc_invalidator_node_get_modification_count (invalidator);
+ node = arv_gc_property_node_get_linked_node (ARV_GC_PROPERTY_NODE (invalidator));
+ feature_modification_count = arv_gc_feature_node_get_modification_count (ARV_GC_FEATURE_NODE (node));
+ arv_gc_invalidator_node_set_modification_count (invalidator, feature_modification_count);
+ if (modification_count != feature_modification_count)
+ is_cache_valid = FALSE;
+ }
+
+ return is_cache_valid;
+}
+
+static gint64
+_get_length (ArvGcRegisterNode *gc_register_node)
+{
+ if (gc_register_node->length == NULL)
+ return 4;
+
+ return arv_gc_property_node_get_int64 (gc_register_node->length);
+}
+
+static guint64
+_get_address (ArvGcRegisterNode *gc_register_node)
+{
+ ArvGc *genicam;
+ GSList *iter;
+ guint64 value = 0;
+
+ genicam = arv_gc_node_get_genicam (ARV_GC_NODE (gc_register_node));
+ g_return_val_if_fail (ARV_IS_GC (genicam), 0);
+
+ for (iter = gc_register_node->addresses; iter != NULL; iter = iter->next)
+ value += arv_gc_property_node_get_int64 (iter->data);
+
+ if (gc_register_node->index != NULL)
+ value += arv_gc_index_node_get_index (ARV_GC_INDEX_NODE (gc_register_node->index),
+ _get_length (gc_register_node));
+
+ return value;
+}
+
+static void
+_update_cache_size (ArvGcRegisterNode *gc_register_node)
+{
+ gint64 length;
+
+ length = _get_length (gc_register_node);
+ if (length != gc_register_node->cache_size) {
+ g_free (gc_register_node->cache);
+ gc_register_node->cache = g_malloc (length);
+ gc_register_node->cache_size = length;
+ }
+
+}
+
+static ArvGcCachable
+_get_cachable (ArvGcRegisterNode *gc_register_node)
+{
+ const char *cachable;
+
+ if (gc_register_node->cachable == NULL)
+ return ARV_GC_CACHABLE_NO_CACHE;
+
+ cachable = arv_gc_property_node_get_string (gc_register_node->cachable);
+ if (g_strcmp0 (cachable, "WriteThrough") == 0)
+ return ARV_GC_CACHABLE_WRITE_TRHOUGH;
+ else if (strcmp (cachable, "WriteAround") == 0)
+ return ARV_GC_CACHABLE_WRITE_AROUND;
+
+ return ARV_GC_CACHABLE_NO_CACHE;
+}
+
+/* Set default to read only 32 bits little endian integer register */
+
+static ArvGcCachable
+_get_endianess (ArvGcRegisterNode *gc_register_node)
+{
+ const char *endianess;
+
+ if (gc_register_node->endianess == NULL)
+ return G_LITTLE_ENDIAN;
+
+ endianess = arv_gc_property_node_get_string (gc_register_node->endianess);
+ if (g_strcmp0 (endianess, "BigEndian") == 0)
+ return G_BIG_ENDIAN;
+
+ return G_LITTLE_ENDIAN;
+}
+
+static ArvGcCachable
+_get_lsb (ArvGcRegisterNode *gc_register_node)
+{
+ if (gc_register_node->lsb == NULL)
+ return 0;
+
+ return arv_gc_property_node_get_int64 (gc_register_node->lsb);
+}
+
+static ArvGcCachable
+_get_msb (ArvGcRegisterNode *gc_register_node)
+{
+ if (gc_register_node->msb == NULL)
+ return 31;
+
+ return arv_gc_property_node_get_int64 (gc_register_node->msb);
+}
+
+static void
+_read_cache (ArvGcRegisterNode *gc_register_node)
+{
+ ArvGcNode *port;
+
+ if (gc_register_node->is_cache_valid == TRUE) {
+ arv_log_genicam ("[GcRegisterNode::read_cache] Cache is valid");
+ return;
+ }
+
+ port = arv_gc_property_node_get_linked_node (gc_register_node->port);
+ if (!ARV_IS_GC_PORT (port))
+ return;
+
+ _update_cache_size (gc_register_node);
+
+ arv_gc_port_read (ARV_GC_PORT (port),
+ gc_register_node->cache,
+ _get_address (gc_register_node),
+ gc_register_node->cache_size);
+
+ if (_get_cachable (gc_register_node) != ARV_GC_CACHABLE_NO_CACHE)
+ gc_register_node->is_cache_valid = TRUE;
+ else
+ gc_register_node->is_cache_valid = FALSE;
+}
+
+static void
+_write_cache (ArvGcRegisterNode *gc_register_node)
+{
+ ArvGcNode *port;
+
+ arv_gc_feature_node_inc_modification_count (ARV_GC_FEATURE_NODE (gc_register_node));
+
+ port = arv_gc_property_node_get_linked_node (gc_register_node->port);
+ if (!ARV_IS_GC_PORT (port))
+ return;
+
+ _update_cache_size (gc_register_node);
+
+ arv_gc_port_write (ARV_GC_PORT (port),
+ gc_register_node->cache,
+ _get_address (gc_register_node),
+ gc_register_node->cache_size);
+
+ if (_get_cachable (gc_register_node) == ARV_GC_CACHABLE_WRITE_TRHOUGH)
+ gc_register_node->is_cache_valid = TRUE;
+ else
+ gc_register_node->is_cache_valid = FALSE;
+}
+
+ArvGcNode *
+arv_gc_register_node_new (void)
+{
+ ArvGcRegisterNode *gc_register_node;
+
+ gc_register_node = g_object_new (ARV_TYPE_GC_REGISTER_NODE, NULL);
+ gc_register_node->type = ARV_GC_REGISTER_NODE_TYPE_REGISTER;
+ gc_register_node->value_type = G_TYPE_BYTE_ARRAY;
+
+ return ARV_GC_NODE (gc_register_node);
+}
+
+ArvGcNode *
+arv_gc_register_node_new_integer (void)
+{
+ ArvGcRegisterNode *gc_register_node;
+
+ gc_register_node = g_object_new (ARV_TYPE_GC_REGISTER_NODE, NULL);
+ gc_register_node->type = ARV_GC_REGISTER_NODE_TYPE_INTEGER;
+ gc_register_node->value_type = G_TYPE_INT64;
+
+ return ARV_GC_NODE (gc_register_node);
+}
+
+ArvGcNode *
+arv_gc_register_node_new_masked_integer (void)
+{
+ ArvGcRegisterNode *gc_register_node;
+
+ gc_register_node = g_object_new (ARV_TYPE_GC_REGISTER_NODE, NULL);
+ gc_register_node->type = ARV_GC_REGISTER_NODE_TYPE_MASKED_INTEGER;
+ gc_register_node->value_type = G_TYPE_INT64;
+
+ return ARV_GC_NODE (gc_register_node);
+}
+
+ArvGcNode *
+arv_gc_register_node_new_float (void)
+{
+ ArvGcRegisterNode *gc_register_node;
+
+ gc_register_node = g_object_new (ARV_TYPE_GC_REGISTER_NODE, NULL);
+ gc_register_node->type = ARV_GC_REGISTER_NODE_TYPE_FLOAT;
+ gc_register_node->value_type = G_TYPE_DOUBLE;
+
+ return ARV_GC_NODE (gc_register_node);
+}
+
+ArvGcNode *
+arv_gc_register_node_new_string (void)
+{
+ ArvGcRegisterNode *gc_register_node;
+
+ gc_register_node = g_object_new (ARV_TYPE_GC_REGISTER_NODE, NULL);
+ gc_register_node->type = ARV_GC_REGISTER_NODE_TYPE_STRING;
+ gc_register_node->value_type = G_TYPE_STRING;
+
+ return ARV_GC_NODE (gc_register_node);
+}
+
+ArvGcNode *
+arv_gc_register_node_new_struct_register (void)
+{
+ ArvGcRegisterNode *gc_register_node;
+
+ gc_register_node = g_object_new (ARV_TYPE_GC_REGISTER_NODE, NULL);
+ gc_register_node->type = ARV_GC_REGISTER_NODE_TYPE_STRUCT_REGISTER;
+ gc_register_node->value_type = G_TYPE_INT64;
+
+ return ARV_GC_NODE (gc_register_node);
+}
+
+static void
+arv_gc_register_node_init (ArvGcRegisterNode *gc_register_node)
+{
+ gc_register_node->cache = g_malloc0(4);
+ gc_register_node->cache_size = 4;
+ gc_register_node->is_cache_valid = FALSE;
+}
+
+static void
+arv_gc_register_node_finalize (GObject *object)
+{
+ ArvGcRegisterNode *gc_register_node = ARV_GC_REGISTER_NODE (object);
+
+ g_slist_free (gc_register_node->addresses);
+ g_free (gc_register_node->cache);
+ g_slist_free (gc_register_node->invalidators);
+
+ parent_class->finalize (object);
+}
+
+static void
+arv_gc_register_node_class_init (ArvGcRegisterNodeClass *this_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (this_class);
+ ArvDomNodeClass *dom_node_class = ARV_DOM_NODE_CLASS (this_class);
+ ArvGcFeatureNodeClass *gc_feature_node_class = ARV_GC_FEATURE_NODE_CLASS (this_class);
+
+ parent_class = g_type_class_peek_parent (this_class);
+
+ object_class->finalize = arv_gc_register_node_finalize;
+ dom_node_class->get_node_name = arv_gc_register_node_get_node_name;
+ dom_node_class->post_new_child = arv_gc_register_node_post_new_child;
+ dom_node_class->pre_remove_child = arv_gc_register_node_pre_remove_child;
+ gc_feature_node_class->get_value_type = arv_gc_register_node_get_value_type;
+ gc_feature_node_class->set_value_from_string = arv_gc_register_node_set_value_from_string;
+ gc_feature_node_class->get_value_as_string = arv_gc_register_node_get_value_as_string;
+}
+
+/* ArvGcRegister interface implementation */
+
+static void
+arv_gc_register_node_get (ArvGcRegister *gc_register, void *buffer, guint64 length)
+{
+ ArvGcRegisterNode *gc_register_node = ARV_GC_REGISTER_NODE (gc_register);
+
+ _read_cache (gc_register_node);
+
+ if (length > gc_register_node->cache_size) {
+ memcpy (buffer, gc_register_node->cache, gc_register_node->cache_size);
+ memset (buffer + gc_register_node->cache_size, 0, length - gc_register_node->cache_size);
+ } else
+ memcpy (buffer, gc_register_node->cache, length);
+
+ arv_log_genicam ("[GcRegisterNode::get] 0x%Lx,%Ld", _get_address (gc_register_node), length);
+}
+
+static void
+arv_gc_register_node_set (ArvGcRegister *gc_register, void *buffer, guint64 length)
+{
+ ArvGcRegisterNode *gc_register_node = ARV_GC_REGISTER_NODE (gc_register);
+
+ if (gc_register_node->cache_size > length) {
+ memcpy (gc_register_node->cache, buffer, length);
+ memset (gc_register_node->cache + length, 0, gc_register_node->cache_size - length);
+ } else
+ memcpy (gc_register_node->cache, buffer, gc_register_node->cache_size);
+
+ _write_cache (gc_register_node);
+
+ arv_log_genicam ("[GcRegisterNode::set] 0x%Lx,%Ld", _get_address (gc_register_node), length);
+}
+
+static guint64
+arv_gc_register_node_get_address (ArvGcRegister *gc_register)
+{
+ ArvGcRegisterNode *gc_register_node = ARV_GC_REGISTER_NODE (gc_register);
+
+ return _get_address (gc_register_node);
+}
+
+static guint64
+arv_gc_register_node_get_length (ArvGcRegister *gc_register)
+{
+ ArvGcRegisterNode *gc_register_node = ARV_GC_REGISTER_NODE (gc_register);
+
+ return _get_length (gc_register_node);
+}
+
+static void
+arv_gc_register_node_register_interface_init (ArvGcRegisterInterface *interface)
+{
+ interface->get = arv_gc_register_node_get;
+ interface->set = arv_gc_register_node_set;
+ interface->get_address = arv_gc_register_node_get_address;
+ interface->get_length = arv_gc_register_node_get_length;
+}
+
+/* ArvGcInteger interface implementation */
+
+static gint64
+_get_integer_value (ArvGcRegisterNode *gc_register_node, guint register_lsb, guint register_msb)
+{
+ gint64 value;
+ guint lsb;
+ guint msb;
+ guint endianess;
+
+ endianess = _get_endianess (gc_register_node);
+
+ _read_cache (gc_register_node);
+
+ arv_copy_memory_with_endianess (&value, sizeof (value), G_BYTE_ORDER,
+ gc_register_node->cache, gc_register_node->cache_size, endianess);
+
+ if (gc_register_node->type == ARV_GC_REGISTER_NODE_TYPE_MASKED_INTEGER ||
+ gc_register_node->type == ARV_GC_REGISTER_NODE_TYPE_STRUCT_REGISTER) {
+ guint64 mask;
+
+ if (endianess == G_BYTE_ORDER) {
+ msb = register_msb;
+ lsb = register_lsb;
+ } else {
+ lsb = 8 * gc_register_node->cache_size - register_lsb - 1;
+ msb = 8 * gc_register_node->cache_size - register_msb - 1;
+ }
+
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+ if (msb - lsb < 63)
+ mask = ((((guint64) 1) << (msb - lsb + 1)) - 1) << lsb;
+ else
+ mask = G_MAXUINT64;
+
+ value = (value & mask) >> lsb;
+#else
+ g_assert_not_reached ();
+#endif
+ }
+
+ arv_log_genicam ("[GcRegisterNode::_get_integer_value] address = 0x%Lx, value = 0x%Lx",
+ _get_address (gc_register_node), value);
+
+ return value;
+}
+
+gint64
+arv_gc_register_node_get_masked_integer_value (ArvGcRegisterNode *gc_register_node, guint lsb, guint msb)
+{
+ g_return_val_if_fail (ARV_IS_GC_REGISTER_NODE (gc_register_node), 0);
+
+ return _get_integer_value (gc_register_node, lsb, msb);
+}
+
+static gint64
+arv_gc_register_node_get_integer_value (ArvGcInteger *gc_integer)
+{
+ ArvGcRegisterNode *gc_register_node = ARV_GC_REGISTER_NODE (gc_integer);
+
+ return _get_integer_value (gc_register_node, _get_lsb (gc_register_node), _get_msb (gc_register_node));
+}
+
+static void
+_set_integer_value (ArvGcRegisterNode *gc_register_node, guint register_lsb, guint register_msb, gint64 value)
+{
+ guint lsb;
+ guint msb;
+ guint endianess;
+
+ endianess = _get_endianess (gc_register_node);
+
+ if (gc_register_node->type == ARV_GC_REGISTER_NODE_TYPE_MASKED_INTEGER ||
+ gc_register_node->type == ARV_GC_REGISTER_NODE_TYPE_STRUCT_REGISTER) {
+ gint64 current_value;
+ guint64 mask;
+
+ _read_cache (gc_register_node);
+
+ arv_copy_memory_with_endianess (¤t_value, sizeof (current_value), G_BYTE_ORDER,
+ gc_register_node->cache, gc_register_node->cache_size, endianess);
+
+ if (endianess == G_BYTE_ORDER) {
+ msb = register_msb;
+ lsb = register_lsb;
+ } else {
+ lsb = 8 * gc_register_node->cache_size - register_lsb - 1;
+ msb = 8 * gc_register_node->cache_size - register_msb - 1;
+ }
+
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+ if (msb - lsb < 63)
+ mask = ((((guint64) 1) << (msb - lsb + 1)) - 1) << lsb;
+ else
+ mask = G_MAXUINT64;
+
+ value = ((value << lsb) & mask) | (current_value & ~mask);
+#else
+ g_assert_not_reached ();
+#endif
+ }
+
+ arv_log_genicam ("[GcRegisterNode::_set_integer_value] address = 0x%Lx, value = 0x%Lx",
+ _get_address (gc_register_node), value);
+
+ arv_copy_memory_with_endianess (gc_register_node->cache, gc_register_node->cache_size, endianess,
+ &value, sizeof (value), G_BYTE_ORDER);
+
+ _write_cache (gc_register_node);
+}
+
+void
+arv_gc_register_node_set_masked_integer_value (ArvGcRegisterNode *gc_register_node, guint lsb, guint msb, gint64 value)
+{
+ g_return_if_fail (ARV_IS_GC_REGISTER_NODE (gc_register_node));
+
+ _set_integer_value (gc_register_node, lsb, msb, value);
+}
+
+static void
+arv_gc_register_node_set_integer_value (ArvGcInteger *gc_integer, gint64 value)
+{
+ ArvGcRegisterNode *gc_register_node = ARV_GC_REGISTER_NODE (gc_integer);
+
+ _set_integer_value (gc_register_node, _get_lsb (gc_register_node), _get_msb (gc_register_node), value);
+}
+
+static void
+arv_gc_register_node_integer_interface_init (ArvGcIntegerInterface *interface)
+{
+ interface->get_value = arv_gc_register_node_get_integer_value;
+ interface->set_value = arv_gc_register_node_set_integer_value;
+}
+
+static double
+arv_gc_register_node_get_float_value (ArvGcFloat *gc_float)
+{
+ ArvGcRegisterNode *gc_register_node = ARV_GC_REGISTER_NODE (gc_float);
+ guint endianess;
+
+ endianess = _get_endianess (gc_register_node);
+
+ _read_cache (gc_register_node);
+
+ if (gc_register_node->cache_size == 4) {
+ float v_float;
+ arv_copy_memory_with_endianess (&v_float, sizeof (v_float), G_BYTE_ORDER,
+ gc_register_node->cache, gc_register_node->cache_size, endianess);
+
+ return v_float;
+ } else if (gc_register_node->cache_size == 8) {
+ double v_double;
+ arv_copy_memory_with_endianess (&v_double, sizeof (v_double), G_BYTE_ORDER,
+ gc_register_node->cache, gc_register_node->cache_size, endianess);
+
+ return v_double;
+ } else {
+ arv_warning_genicam ("[GcFloatReg::get_value] Invalid register size");
+ return 0.0;
+ }
+}
+
+static void
+arv_gc_register_node_set_float_value (ArvGcFloat *gc_float, double v_double)
+{
+ ArvGcRegisterNode *gc_register_node = ARV_GC_REGISTER_NODE (gc_float);
+ guint endianess;
+
+ endianess = _get_endianess (gc_register_node);
+
+ _update_cache_size (gc_register_node);
+
+ if (gc_register_node->cache_size == 4) {
+ float v_float = v_double;
+ arv_copy_memory_with_endianess (gc_register_node->cache, gc_register_node->cache_size, endianess,
+ &v_float, sizeof (v_float), G_BYTE_ORDER);
+ } else if (gc_register_node->cache_size == 8) {
+ arv_copy_memory_with_endianess (gc_register_node->cache, gc_register_node->cache_size, endianess,
+ &v_double, sizeof (v_double), G_BYTE_ORDER);
+ } else {
+ arv_warning_genicam ("[GcFloatReg::set_value] Invalid register size");
+ return;
+ }
+
+ _write_cache (gc_register_node);
+}
+
+static void
+arv_gc_register_node_float_interface_init (ArvGcFloatInterface *interface)
+{
+ interface->get_value = arv_gc_register_node_get_float_value;
+ interface->set_value = arv_gc_register_node_set_float_value;
+}
+
+static const char *
+arv_gc_register_node_get_string_value (ArvGcString *gc_string)
+{
+ ArvGcRegisterNode *gc_register_node = ARV_GC_REGISTER_NODE (gc_string);
+
+ _read_cache (gc_register_node);
+
+ if (gc_register_node->cache_size > 0)
+ ((char *) gc_register_node->cache)[gc_register_node->cache_size - 1] = '\0';
+
+ return gc_register_node->cache;
+}
+
+static void
+arv_gc_register_node_set_string_value (ArvGcString *gc_string, const char *value)
+{
+ ArvGcRegisterNode *gc_register_node = ARV_GC_REGISTER_NODE (gc_string);
+
+ _update_cache_size (gc_register_node);
+
+ if (gc_register_node->cache_size > 0) {
+ strncpy (gc_register_node->cache, value, gc_register_node->cache_size);
+ ((char *) gc_register_node->cache)[gc_register_node->cache_size - 1] = '\0';
+
+ _write_cache (gc_register_node);
+ }
+}
+
+static gint64
+arv_gc_register_node_get_max_string_length (ArvGcString *gc_string)
+{
+ ArvGcRegisterNode *gc_register_node = ARV_GC_REGISTER_NODE (gc_string);
+
+ return _get_length (gc_register_node);
+}
+
+static void
+arv_gc_register_node_string_interface_init (ArvGcStringInterface *interface)
+{
+ interface->get_value = arv_gc_register_node_get_string_value;
+ interface->set_value = arv_gc_register_node_set_string_value;
+ interface->get_max_length = arv_gc_register_node_get_max_string_length;
+}
+
+G_DEFINE_TYPE_WITH_CODE (ArvGcRegisterNode, arv_gc_register_node, ARV_TYPE_GC_FEATURE_NODE,
+ G_IMPLEMENT_INTERFACE (ARV_TYPE_GC_REGISTER, arv_gc_register_node_register_interface_init)
+ G_IMPLEMENT_INTERFACE (ARV_TYPE_GC_INTEGER, arv_gc_register_node_integer_interface_init)
+ G_IMPLEMENT_INTERFACE (ARV_TYPE_GC_FLOAT, arv_gc_register_node_float_interface_init)
+ G_IMPLEMENT_INTERFACE (ARV_TYPE_GC_STRING, arv_gc_register_node_string_interface_init))
diff --git a/src/arvgcregisternode.h b/src/arvgcregisternode.h
new file mode 100644
index 0000000..c73d2e8
--- /dev/null
+++ b/src/arvgcregisternode.h
@@ -0,0 +1,116 @@
+/* Aravis - Digital camera library
+ *
+ * Copyright  2009-2012 Emmanuel Pacaud
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+#ifndef ARV_GC_REGISTER_NODE_H
+#define ARV_GC_REGISTER_NODE_H
+
+#include <arvtypes.h>
+#include <arvgcfeaturenode.h>
+#include <arvgcpropertynode.h>
+
+G_BEGIN_DECLS
+
+/**
+ * ArvGcSign:
+ * @ARV_GC_SIGN_SIGNED: signed integer
+ * @ARV_GC_SIGN_UNSIGNED: unsigned integer
+ */
+
+typedef enum
+{
+ ARV_GC_SIGN_SIGNED,
+ ARV_GC_SIGN_UNSIGNED
+} ArvGcSign;
+
+/**
+ * ArvGcRegisterNodeType:
+ * @ARV_GC_REGISTER_NODE_TYPE_REGISTER: Register node
+ * @ARV_GC_REGISTER_NODE_TYPE_INTEGER: IntReg node
+ * @ARV_GC_REGISTER_NODE_TYPE_MASKED_INTEGER: MaskedIntReg node
+ * @ARV_GC_REGISTER_NODE_TYPE_FLOAT: FloatReg node
+ * @ARV_GC_REGISTER_NODE_TYPE_STRING: StringReg node
+ * @ARV_GC_REGISTER_NODE_TYPE_STRUCT_REGISTER: StructReg node
+ */
+
+typedef enum {
+ ARV_GC_REGISTER_NODE_TYPE_REGISTER,
+ ARV_GC_REGISTER_NODE_TYPE_INTEGER,
+ ARV_GC_REGISTER_NODE_TYPE_MASKED_INTEGER,
+ ARV_GC_REGISTER_NODE_TYPE_FLOAT,
+ ARV_GC_REGISTER_NODE_TYPE_STRING,
+ ARV_GC_REGISTER_NODE_TYPE_STRUCT_REGISTER
+} ArvGcRegisterNodeType;
+
+#define ARV_TYPE_GC_REGISTER_NODE (arv_gc_register_node_get_type ())
+#define ARV_GC_REGISTER_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ARV_TYPE_GC_REGISTER_NODE, ArvGcRegisterNode))
+#define ARV_GC_REGISTER_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ARV_TYPE_GC_REGISTER_NODE, ArvGcRegisterNodeClass))
+#define ARV_IS_GC_REGISTER_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ARV_TYPE_GC_REGISTER_NODE))
+#define ARV_IS_GC_REGISTER_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), ARV_TYPE_GC_REGISTER_NODE))
+#define ARV_GC_REGISTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), ARV_TYPE_GC_REGISTER_NODE, ArvGcRegisterNodeClass))
+
+typedef struct _ArvGcRegisterNodeClass ArvGcRegisterNodeClass;
+
+struct _ArvGcRegisterNode {
+ ArvGcFeatureNode node;
+
+ ArvGcRegisterNodeType type;
+ GType value_type;
+
+ GSList *addresses;
+ ArvGcPropertyNode *index;
+ ArvGcPropertyNode *length;
+ ArvGcPropertyNode *port;
+ ArvGcPropertyNode *access_mode;
+ ArvGcPropertyNode *cachable;
+ ArvGcPropertyNode *polling_time;
+ ArvGcPropertyNode *endianess;
+ ArvGcPropertyNode *sign;
+ ArvGcPropertyNode *lsb;
+ ArvGcPropertyNode *msb;
+
+ GSList *invalidators; /* ArvGcPropertyNode list */
+
+ void *cache;
+ size_t cache_size;
+ gboolean is_cache_valid;
+
+ char v_string[G_ASCII_DTOSTR_BUF_SIZE];
+};
+
+struct _ArvGcRegisterNodeClass {
+ ArvGcFeatureNodeClass parent_class;
+};
+
+GType arv_gc_register_node_get_type (void);
+ArvGcNode * arv_gc_register_node_new (void);
+ArvGcNode * arv_gc_register_node_new_integer (void);
+ArvGcNode * arv_gc_register_node_new_masked_integer (void);
+ArvGcNode * arv_gc_register_node_new_float (void);
+ArvGcNode * arv_gc_register_node_new_string (void);
+ArvGcNode * arv_gc_register_node_new_struct_register (void);
+
+gint64 arv_gc_register_node_get_masked_integer_value (ArvGcRegisterNode *gc_register_node, guint lsb, guint msb);
+void arv_gc_register_node_set_masked_integer_value (ArvGcRegisterNode *gc_register_node, guint lsb, guint msb, gint64 value);
+
+G_END_DECLS
+
+#endif
diff --git a/src/arvgcstructentrynode.c b/src/arvgcstructentrynode.c
index 909c0b2..3dc5c3c 100644
--- a/src/arvgcstructentrynode.c
+++ b/src/arvgcstructentrynode.c
@@ -26,6 +26,7 @@
*/
#include <arvgcstructentrynode.h>
+#include <arvgcregisternode.h>
#include <arvgcregister.h>
#include <arvgcinteger.h>
#include <arvgcport.h>
@@ -174,6 +175,57 @@ arv_gc_struct_entry_node_class_init (ArvGcStructEntryNodeClass *this_class)
gc_feature_node_class->get_value_as_string = arv_gc_struct_entry_node_get_value_as_string;
}
+/* ArvGcRegister interface implementation */
+
+static void
+arv_gc_struct_entry_node_get (ArvGcRegister *gc_register, void *buffer, guint64 length)
+{
+ ArvDomNode *struct_register = arv_dom_node_get_parent_node (ARV_DOM_NODE (gc_register));
+
+ if (ARV_IS_GC_REGISTER (struct_register))
+ arv_gc_register_get (ARV_GC_REGISTER (struct_register), buffer, length);
+}
+
+static void
+arv_gc_struct_entry_node_set (ArvGcRegister *gc_register, void *buffer, guint64 length)
+{
+ ArvDomNode *struct_register = arv_dom_node_get_parent_node (ARV_DOM_NODE (gc_register));
+
+ if (ARV_IS_GC_REGISTER (struct_register))
+ return arv_gc_register_set (ARV_GC_REGISTER (struct_register), buffer, length);
+}
+
+static guint64
+arv_gc_struct_entry_node_get_address (ArvGcRegister *gc_register)
+{
+ ArvDomNode *struct_register = arv_dom_node_get_parent_node (ARV_DOM_NODE (gc_register));
+
+ if (ARV_IS_GC_REGISTER (struct_register))
+ return arv_gc_register_get_address (ARV_GC_REGISTER (struct_register));
+
+ return 0;
+}
+
+static guint64
+arv_gc_struct_entry_node_get_length (ArvGcRegister *gc_register)
+{
+ ArvDomNode *struct_register = arv_dom_node_get_parent_node (ARV_DOM_NODE (gc_register));
+
+ if (ARV_IS_GC_REGISTER (struct_register))
+ return arv_gc_register_get_length (ARV_GC_REGISTER (struct_register));
+
+ return 0;
+}
+
+static void
+arv_gc_struct_entry_node_register_interface_init (ArvGcRegisterInterface *interface)
+{
+ interface->get = arv_gc_struct_entry_node_get;
+ interface->set = arv_gc_struct_entry_node_set;
+ interface->get_address = arv_gc_struct_entry_node_get_address;
+ interface->get_length = arv_gc_struct_entry_node_get_length;
+}
+
/* ArvGcInteger interface implementation */
static gint64
@@ -185,13 +237,13 @@ arv_gc_struct_entry_node_get_integer_value (ArvGcInteger *gc_integer)
guint msb;
struct_register = arv_dom_node_get_parent_node (ARV_DOM_NODE (gc_integer));
- if (!ARV_IS_GC_REGISTER (struct_register))
+ if (!ARV_IS_GC_REGISTER_NODE (struct_register))
return 0;
lsb = _get_lsb (struct_entry);
msb = _get_msb (struct_entry);
- return arv_gc_register_get_masked_integer_value (ARV_GC_REGISTER (struct_register), lsb, msb);
+ return arv_gc_register_node_get_masked_integer_value (ARV_GC_REGISTER_NODE (struct_register), lsb, msb);
}
static void
@@ -203,13 +255,13 @@ arv_gc_struct_entry_node_set_integer_value (ArvGcInteger *gc_integer, gint64 val
guint msb;
struct_register = arv_dom_node_get_parent_node (ARV_DOM_NODE (gc_integer));
- if (!ARV_IS_GC_REGISTER (struct_register))
+ if (!ARV_IS_GC_REGISTER_NODE (struct_register))
return;
lsb = _get_lsb (struct_entry);
msb = _get_msb (struct_entry);
- arv_gc_register_set_masked_integer_value (ARV_GC_REGISTER (struct_register), lsb, msb, value);
+ arv_gc_register_node_set_masked_integer_value (ARV_GC_REGISTER_NODE (struct_register), lsb, msb, value);
}
static void
@@ -220,4 +272,5 @@ arv_gc_struct_entry_node_integer_interface_init (ArvGcIntegerInterface *interfac
}
G_DEFINE_TYPE_WITH_CODE (ArvGcStructEntryNode, arv_gc_struct_entry_node, ARV_TYPE_GC_FEATURE_NODE,
+ G_IMPLEMENT_INTERFACE (ARV_TYPE_GC_REGISTER, arv_gc_struct_entry_node_register_interface_init)
G_IMPLEMENT_INTERFACE (ARV_TYPE_GC_INTEGER, arv_gc_struct_entry_node_integer_interface_init))
diff --git a/src/arvtypes.h b/src/arvtypes.h
index 0b503ea..b7da15d 100644
--- a/src/arvtypes.h
+++ b/src/arvtypes.h
@@ -56,13 +56,14 @@ typedef struct _ArvGcEnumeration ArvGcEnumeration;
typedef struct _ArvGcEnumEntry ArvGcEnumEntry;
typedef struct _ArvGcIntegerNode ArvGcIntegerNode;
typedef struct _ArvGcFloatNode ArvGcFloatNode;
-typedef struct _ArvGcRegister ArvGcRegister;
+typedef struct _ArvGcRegisterNode ArvGcRegisterNode;
typedef struct _ArvGcStructEntryNode ArvGcStructEntryNode;
typedef struct _ArvGcCommand ArvGcCommand;
typedef struct _ArvGcSwissKnife ArvGcSwissKnife;
typedef struct _ArvGcConverter ArvGcConverter;
typedef struct _ArvGcPort ArvGcPort;
+typedef struct _ArvGcRegister ArvGcRegister;
typedef struct _ArvGcInteger ArvGcInteger;
typedef struct _ArvGcFloat ArvGcFloat;
typedef struct _ArvGcString ArvGcString;
diff --git a/tests/fake.c b/tests/fake.c
index 1c84a0c..4865ec6 100644
--- a/tests/fake.c
+++ b/tests/fake.c
@@ -62,6 +62,7 @@ registers_test (void)
ArvGcNode *node_b;
ArvGcNode *node_c;
gint64 value;
+ gint64 address;
device = arv_fake_device_new ("TEST0");
g_assert (ARV_IS_FAKE_DEVICE (device));
@@ -72,6 +73,9 @@ registers_test (void)
node = arv_gc_get_node (genicam, "TestRegister");
g_assert (ARV_IS_GC_NODE (node));
+ address = arv_gc_register_get_address (ARV_GC_REGISTER (node));
+ g_assert_cmpint (address, ==, 0x1f0);
+
arv_gc_integer_set_value (ARV_GC_INTEGER (node), 0x12345678);
value = arv_gc_integer_get_value (ARV_GC_INTEGER (node));
g_assert_cmpint (value, ==, 0x12345678);
@@ -83,6 +87,13 @@ registers_test (void)
node_c = arv_gc_get_node (genicam, "StructEntry_16");
g_assert (ARV_IS_GC_NODE (node_c));
+ value = arv_gc_register_get_address (ARV_GC_REGISTER (node_a));
+ g_assert_cmpint (value, ==, address);
+ value = arv_gc_register_get_address (ARV_GC_REGISTER (node_b));
+ g_assert_cmpint (value, ==, address);
+ value = arv_gc_register_get_address (ARV_GC_REGISTER (node_c));
+ g_assert_cmpint (value, ==, address);
+
value = arv_gc_integer_get_value (ARV_GC_INTEGER (node_a));
g_assert_cmpint (value, ==, 0x5678);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]