Implement config_item_set_from()
This commit is contained in:
		
							parent
							
								
									d4deb31a17
								
							
						
					
					
						commit
						b4dab3489d
					
				
							
								
								
									
										110
									
								
								common.c
									
									
									
									
									
								
							
							
						
						
									
										110
									
								
								common.c
									
									
									
									
									
								
							| @ -534,7 +534,7 @@ struct config_schema | ||||
| 	bool (*validate) (struct config_item_ *, const struct config_item_ *); | ||||
| 
 | ||||
| 	/// The value has changed. Only appliable to objects.
 | ||||
| 	bool (*on_changed) (struct config_item_ *); | ||||
| 	void (*on_changed) (struct config_item_ *); | ||||
| 
 | ||||
| 	/// Free any resources located in "item->user_data"
 | ||||
| 	void (*on_destroy) (struct config_item_ *item); | ||||
| @ -542,12 +542,33 @@ struct config_schema | ||||
| 
 | ||||
| // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 | ||||
| 
 | ||||
| static void | ||||
| config_item_destroy (struct config_item_ *self) | ||||
| static const char * | ||||
| config_item_type_name (enum config_item_type type) | ||||
| { | ||||
| 	if (self->schema && self->schema->on_destroy) | ||||
| 		self->schema->on_destroy (self); | ||||
| 	switch (type) | ||||
| 	{ | ||||
| 	case CONFIG_ITEM_NULL:          return "null"; | ||||
| 	case CONFIG_ITEM_BOOLEAN:       return "boolean"; | ||||
| 	case CONFIG_ITEM_INTEGER:       return "integer"; | ||||
| 	case CONFIG_ITEM_STRING:        return "string"; | ||||
| 	case CONFIG_ITEM_STRING_ARRAY:  return "string array"; | ||||
| 
 | ||||
| 	default: | ||||
| 		hard_assert (!"invalid config item type value"); | ||||
| 		return NULL; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static bool | ||||
| config_item_type_is_string (enum config_item_type type) | ||||
| { | ||||
| 	return type == CONFIG_ITEM_STRING | ||||
| 		|| type == CONFIG_ITEM_STRING_ARRAY; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| config_item_free (struct config_item_ *self) | ||||
| { | ||||
| 	switch (self->type) | ||||
| 	{ | ||||
| 	case CONFIG_ITEM_STRING: | ||||
| @ -559,9 +580,32 @@ config_item_destroy (struct config_item_ *self) | ||||
| 	default: | ||||
| 		break; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| config_item_destroy (struct config_item_ *self) | ||||
| { | ||||
| 	if (self->schema && self->schema->on_destroy) | ||||
| 		self->schema->on_destroy (self); | ||||
| 
 | ||||
| 	config_item_free (self); | ||||
| 	free (self); | ||||
| } | ||||
| 
 | ||||
| /// Doesn't do any validations or handle schemas, just moves source data
 | ||||
| /// to the target item and destroys the source item
 | ||||
| static void | ||||
| config_item_move (struct config_item_ *self, struct config_item_ *source) | ||||
| { | ||||
| 	// Not quite sure how to handle that
 | ||||
| 	hard_assert (!source->schema); | ||||
| 
 | ||||
| 	config_item_free (self); | ||||
| 	self->type = source->type; | ||||
| 	memcpy (&self->value, &source->value, sizeof source->value); | ||||
| 	free (source); | ||||
| } | ||||
| 
 | ||||
| static struct config_item_ * | ||||
| config_item_new (enum config_item_type type) | ||||
| { | ||||
| @ -618,19 +662,59 @@ config_item_object (void) | ||||
| 	return self; | ||||
| } | ||||
| 
 | ||||
| /// Doesn't do any validations or such, only moves source data to the item
 | ||||
| static void | ||||
| config_item_move (struct config_item_ *self, struct config_item_ *source) | ||||
| static bool | ||||
| config_schema_accepts_type | ||||
| 	(struct config_schema *self, enum config_item_type type) | ||||
| { | ||||
| 	// TODO
 | ||||
| 	if (self->type == type) | ||||
| 		return true; | ||||
| 	// This is a bit messy but it has its purpose
 | ||||
| 	if (config_item_type_is_string (self->type) | ||||
| 	 && config_item_type_is_string (type)) | ||||
| 		return true; | ||||
| 	return self->is_nullable && type == CONFIG_ITEM_NULL; | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| static bool | ||||
| config_item_set_from (struct config_item_ *self, | ||||
| 	struct config_item_ *source, struct error **e) | ||||
| config_item_set_from (struct config_item_ *self, struct config_item_ *source, | ||||
| 	struct error **e) | ||||
| { | ||||
| 	hard_assert (self->type == CONFIG_ITEM_OBJECT); | ||||
| 	// TODO
 | ||||
| 	struct config_schema *schema = self->schema; | ||||
| 	if (!schema) | ||||
| 	{ | ||||
| 		// Easy, we don't know what this item is
 | ||||
| 		config_item_move (self, source); | ||||
| 		return true; | ||||
| 	} | ||||
| 
 | ||||
| 	// Otherwise we check the type and validate the item
 | ||||
| 	if (!config_schema_accepts_type (schema, source->type)) | ||||
| 	{ | ||||
| 		error_set (e, "invalid type of value, expected: %s%s", | ||||
| 			config_item_type_name (schema->type), | ||||
| 			schema->is_nullable ? " (or null)" : ""); | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	if (schema->validate && !schema->validate (self, source)) | ||||
| 	{ | ||||
| 		// XXX: perhaps "schema->validate" could provide a message for us?
 | ||||
| 		error_set (e, "invalid value"); | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	// Make sure the string subtype fits the schema
 | ||||
| 	if (config_item_type_is_string (self->type) | ||||
| 	 && config_item_type_is_string (source->type)) | ||||
| 		source->type = self->type; | ||||
| 
 | ||||
| 	config_item_move (self, source); | ||||
| 
 | ||||
| 	// Notify owner about the change so that they can apply it
 | ||||
| 	if (schema->on_changed) | ||||
| 		schema->on_changed (self); | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| static struct config_item_ * | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user