+int
+device_write_from_connection(
+ Device *self,
+ guint64 size,
+ guint64 *actual_size,
+ int *cancelled,
+ GMutex *abort_mutex,
+ GCond *abort_cond)
+{
+ DeviceClass *klass;
+
+ klass = DEVICE_GET_CLASS(self);
+
+ g_assert(self->in_file);
+ g_assert(IS_WRITABLE_ACCESS_MODE(self->access_mode));
+
+ if(klass->write_from_connection) {
+ return (klass->write_from_connection)(self, size, actual_size,
+ cancelled,
+ abort_mutex, abort_cond);
+ } else {
+ device_set_error(self,
+ stralloc(_("Unimplemented method")),
+ DEVICE_STATUS_DEVICE_ERROR);
+ return 1;
+ }
+}
+
+int
+device_read_to_connection(
+ Device *self,
+ guint64 size,
+ guint64 *actual_size,
+ int *cancelled,
+ GMutex *abort_mutex,
+ GCond *abort_cond)
+{
+ DeviceClass *klass;
+
+ g_assert(self->in_file);
+ g_assert(self->access_mode == ACCESS_READ);
+
+ klass = DEVICE_GET_CLASS(self);
+ if(klass->read_to_connection) {
+ return (klass->read_to_connection)(self, size, actual_size,
+ cancelled, abort_mutex, abort_cond);
+ } else {
+ device_set_error(self,
+ stralloc(_("Unimplemented method")),
+ DEVICE_STATUS_DEVICE_ERROR);
+ return 1;
+ }
+}
+
+gboolean
+device_use_connection(
+ Device *self,
+ DirectTCPConnection *conn)
+{
+ DeviceClass *klass;
+
+ g_assert(self->access_mode == ACCESS_NULL);
+
+ klass = DEVICE_GET_CLASS(self);
+ if(klass->use_connection) {
+ return (klass->use_connection)(self, conn);
+ } else {
+ device_set_error(self,
+ stralloc(_("Unimplemented method")),
+ DEVICE_STATUS_DEVICE_ERROR);
+ return FALSE;
+ }
+}
+
+/* Property handling */
+
+void
+device_class_register_property(
+ DeviceClass *klass,
+ DevicePropertyId id,
+ PropertyAccessFlags access,
+ PropertyGetFn getter,
+ PropertySetFn setter)
+{
+ DevicePropertyBase *base;
+ DeviceProperty *prop;
+ GSList *proplist;
+ guint i;
+
+ g_assert(klass != NULL);
+
+ base = device_property_get_by_id(id);
+ g_assert(base != NULL);
+
+ if (klass->class_properties->len <= id) {
+ g_array_set_size(klass->class_properties, id+1);
+ }
+
+ prop = &g_array_index(klass->class_properties, DeviceProperty, id);
+ prop->base = base;
+ prop->access = access;
+ prop->getter = getter;
+ prop->setter = setter;
+
+ /* completely rewrite the list of prop pointers, as they may have changed,
+ * or we may have replaced an existing property*/
+
+ if (klass->class_properties_list) {
+ g_slist_free(klass->class_properties_list);
+ }
+
+ proplist = NULL;
+ for (i = 0; i < klass->class_properties->len; i++) {
+ prop = &g_array_index(klass->class_properties, DeviceProperty, i);
+ if (!prop->base)
+ continue;
+ proplist = g_slist_prepend(proplist, prop);
+ }
+
+ klass->class_properties_list = proplist;
+}
+
+gboolean
+device_set_simple_property(
+ Device *self,
+ DevicePropertyId id,
+ GValue *val,
+ PropertySurety surety,
+ PropertySource source)
+{
+ SimpleProperty *simp;
+ DeviceProperty *prop;
+
+ prop = &g_array_index(DEVICE_GET_CLASS(self)->class_properties,
+ DeviceProperty, id);
+
+ /* these assertions should already be checked, but let's be sure */
+ g_assert(prop->base != NULL); /* prop must be registered with device */
+ g_assert(G_VALUE_HOLDS(val, prop->base->type));
+
+ simp = g_new0(SimpleProperty, 1);
+ simp->prop = prop;
+ g_value_unset_copy(val, &(simp->response));
+ simp->surety = surety;
+ simp->source = source;
+
+ g_hash_table_insert(selfp->simple_properties,
+ GINT_TO_POINTER(id),
+ simp);
+
+ return TRUE;
+}
+
+gboolean
+device_simple_property_set_fn(
+ Device *self,
+ DevicePropertyBase *base,
+ GValue *val,
+ PropertySurety surety,
+ PropertySource source)
+{
+ return device_set_simple_property(self, base->ID, val, surety, source);
+}
+
+gboolean
+device_get_simple_property(
+ Device *self,
+ DevicePropertyId id,
+ GValue *val,
+ PropertySurety *surety,
+ PropertySource *source)
+{
+ SimpleProperty *simp =
+ g_hash_table_lookup(selfp->simple_properties,
+ GINT_TO_POINTER(id));
+
+ if (!simp)
+ return FALSE;
+
+ if (val)
+ g_value_unset_copy(&(simp->response), val);
+
+ if (surety)
+ *surety = simp->surety;
+
+ if (source)
+ *source = simp->source;
+
+ return TRUE;
+}
+
+gboolean
+device_simple_property_get_fn(
+ Device *self,
+ DevicePropertyBase *base,
+ GValue *val,
+ PropertySurety *surety,
+ PropertySource *source)
+{
+ return device_get_simple_property(self, base->ID, val, surety, source);
+}