20

Object Layer

The Object Layer implements the containers for So-o classes and instances and all the functions needed by the Object class.

The data types are defined in the file OL.h. All the code is in the file OL.c.

  1. #include "list.h"
  2. #include "alist.h"

So-o uses simple lists and associative lists. The files list.h and alist.h declare the data types list and alist and the functions to manage them. The code is in the files list.c and alist.c. It's compiled in the library libso-o.a.

  1. typedef char *property;
  2. typedef char *message;
  3.  
  4. typedef union _value {
  5.     int i;
  6.     long l;
  7.     float f;
  8.     double d;
  9.     void *p;
  10. } value;
  11.  
  12. typedef value (*method)();
  13.  
  14. #define METHOD(f) (value (*)())f
  15.  
  16. typedef struct _selector {
  17.     message msg;
  18.     method func;
  19. } selector;
  20.  
  21. typedef struct _attribute {
  22.     property name;
  23.     value value;
  24. } attribute;

A property or a message is a character string terminated by a '\0'.

The data type value is a union which is used to contain all the different values a method can return. Sending a message always returns a type value. To assign the value returned by a message or pass it to another function, access the appropriate member of the union.

A method is a pointer to a function with a return type value. The macron METHOD is used to cast a function which implements a message.

A selector associates a message to a method. An attribute is a property with a value.

  1. #define CLASS       'C'
  2. #define INSTANCE    'I'
  3.  
  4. typedef struct _class {
  5.     char type;
  6.     const char *name;
  7.     unsigned int revision;
  8.     struct _class *superclass;
  9.     list c_properties;
  10.     list i_properties;
  11.     alist c_messages;
  12.     alist i_messages;
  13.     alist attributes;
  14. } *class;
  15.  
  16. typedef struct _instance {
  17.     char type;
  18.     class class;
  19.     alist attributes;
  20. } *instance;

A class has a name and a revision number. It inherits its behavior from a superclass, except the Object class. It has properties. It implements class messages. The instances of a class have properties. They implement instance messages. The properties of a class which have a value are its attributes.

An instance belongs to a class. The properties of an instance which have a value are its attributes.

The field type is used by the interface to determine whether the object which receives a message is a class or an instance. A class has the type CLASS. An instance has the type INSTANCE.

The Object class is the only class with a NULL superclass. All the other classes inherit, at least, from the class Object.

All lists can be NULL.

The rest of the file OL.h declares all the functions of the Object Layer. The functions which start with class_ deal with a class. The functions which start with object_ deal with an instance.

IMPORTANT: In principle, all the functions of the Object Layer are private. Only the functions of the class Object and the functions of the interface of So-o can call them.

  1. #define CNAMEMAXLEN 64
  2. #define CNAMEREGEXP "^[:alpha:]?[[:alnum:]_-]{0,62}[:alnum:]?$"

CNAMEMAXLEN specifies the maximum length of a class name. CNAMEREGEXP defines the regular expression used to validate a class name.

  1. class class_alloc( void ) {
  2.     return (class)calloc( 1, sizeof ( struct _class ));
  3. }

class_alloc allocates the space necessary to hold a class and returns it.

  1. class class_init( class self, const char *cname, class superclass, unsigned int rev, property *c_props, property *i_props, selector *c_msgs, selector *i_msgs ) {
  2.     static regex_t regexp;
  3.  
  4.     regcomp(&regexp, CNAMEREGEXP, REG_EXTENDED | REG_NOSUB);
  5.  
  6.     if ( regexec(&regexp, cname, 0, 0, 0) != 0 )
  7.         return 0;
  8.  
  9.     extern class Object;
  10.  
  11.     self->type = CLASS;
  12.     self->name = cname;
  13.     self->revision = rev;
  14.  
  15.     self->superclass = strcmp("Object", cname) != 0 ? (superclass ? superclass : Object) : 0;
  16.  
  17.     if ( c_msgs )
  18.         class_set_class_messages(self, c_msgs);
  19.  
  20.     if ( i_msgs )
  21.         class_set_instance_messages(self, i_msgs);
  22.  
  23.     if ( c_props )
  24.         class_set_class_properties(self, c_props);
  25.  
  26.     if ( i_props )
  27.         class_set_instance_properties(self, i_props);
  28.  
  29.     return self;
  30. }

class_init initializes the definition of the class self.

name speficies the name of the class. name is validated with the regular expression CNAMEREGEXP.

superclass is the global reference of the superclass of the new class. If superclass is 0, the new class inherits by default from the Object class defined by the global variable Object. IMPORTANT: superclass must contain the address of the definiton of a constructed class.

rev gives the revision number of the class. rev is an int > 0 which can be used to differentiate successive versions of the class.

class_properties and instance_properties list the properties of the class and instances of the class. A property is a string terminated by a '\0'. A list of properties is an array terminated by a NULL pointer. A NULL array defines an empty list.

class_messages and instance_messages are associative lists of messages and methods of the class and instances of the class. A message is a string terminated by a '\0'. A method is a function pointer cast with the macro METHOD defined in OL.h. A selector associates a method to a message. A list of messages and methods is an array terminated by two NULL pointers. A NULL array defines an empty list.

  1. class class_new( const char *name, class superclass, unsigned revision, property *class_properties, property *instance_properties, selector *class_messages, selector *instance_messages ) {
  2.     return class_init( class_alloc(), name, superclass, revision, class_properties, instance_properties, class_messages, instance_messages );
  3. }

class_new allocates the space necessary for the definition of a class, initializes it and returns it.

  1. void class_free( class self ) {
  2.     if (self->c_properties)
  3.         list_free( self->c_properties );
  4.     if (self->i_properties)
  5.         list_free( self->i_properties );
  6.     if (self->c_messages)
  7.         alist_free( self->c_messages );
  8.     if (self->i_messages)
  9.         alist_free( self->i_messages );
  10.     if (self->attributes)
  11.         alist_free( self->attributes );
  12.     free( self );
  13. }

class_free frees the space allocated by self, i.e. all the lists allocated by the class and the container of the class. IMPORTANT: class_free doesn't free the space which might be allocated for the values of the attributes of the class.

  1. char *class_tostring( class self ) {
  2.     static char s[CNAMEMAXLEN+7+1];
  3.  
  4.     sprintf(s, "class(%s)", self->name);
  5.  
  6.     return s;
  7. }

class_tostring returns a string representation of self, i.e. the word class followed by the name of the class between parenthesis. IMPORTANT: The string is formatted in a static area. It must be used before this method is called again.

  1. instance class_make(class self) {
  2.     return object_new( self );
  3. }

class_make returns of new instance of self.

  1. instance object_alloc( void ) {
  2.     return (instance)calloc( 1, sizeof ( struct _instance ));
  3. }

object_alloc allocates the space necessary to hold an instance and returns it.

  1. instance object_init( instance self, class c ) {
  2.     self->type = INSTANCE;
  3.     self->class = c;
  4.  
  5.     return self;
  6. }

object_init initializes the definition of the instance self. c is the global reference of the class of self.

  1. instance object_new( class c ) {
  2.     return object_init(object_alloc(), c);
  3. }

object_new allocates the space necessary for the definition of an instance, initializes it and returns it.

  1. void object_free( instance self ) {
  2.     if (self->attributes)
  3.         alist_free( self->attributes );
  4.     free( self );
  5. }

object_free frees the space allocated by self, i.e. the list of attributes allocated by the instance and the container of the instance. IMPORTANT: object_free doesn't free the space which might be allocated for the values of the attributes of the instance.

  1. instance object_copy(instance self) {
  2.     instance newself = object_new(object_class(self));
  3.  
  4.     if (self->attributes)
  5.         newself->attributes = alist_copy(self->attributes);
  6.  
  7.     return newself;
  8. }

object_copy returns a copy of self. IMPORTANT: object_copy doesn't duplicate the space which might be allocated for the values of the attributes of the instance; self and its copy have independent lists of attributes which share the same values.

  1. char *object_tostring( instance self ) {
  2.     static char s[CNAMEMAXLEN+8+1];
  3.  
  4.     sprintf(s, "object(%s)", self->class->name);
  5.  
  6.     return s;
  7. }

object_tostring returns a string representation of self, i.e. the word object followed by the name of the instance between parenthesis. IMPORTANT: The string is formatted in a static area. It must be used before this method is called again.

The rest of the code implements all the functions of the Object Layer which are needed by the Object class.

class_name
Returns the name of a class.
class_revision
Returns the revision number of a class.
class_superclass
Returns the superclass of a class.
class_class_properties
Returns the class properties defined by a class.
class_instance_properties
Returns the instance properties defined by a class.
class_class_messages
Returns the class messages defined by a class.
class_instance_messages
Returns the instance messages defined by a class.
class_set_class_properties
Initializes the class properties of a class.
class_set_instance_properties
Initializes the instance properties of a class.
class_set_class_messages
Initializes the class messages of a class.
class_set_instance_messages
Initializes the instance messages of a class.
class_add_class_message
Adds a class message to a class.
class_remove_class_message
Removes a class message from a class.
class_add_instance_message
Adds an instance message to a class.
class_remove_instance_message
Removes an instance message from a class.
class_add_class_property
Adds a class property to a class.
class_remove_class_property
Removes a class property from a class.
class_add_instance_property
Adds an instance property to a class.
class_remove_instance_property
Removes an instance property from a class.
class_attributes
Returns the values of the properties of a class.
class_set_attributes
Initializes the values of the properties of a class.
class_is_kind_of
Checks if a class is a subclass of another class.
class_get
Returns the value of a property of a class.
class_set
Modifies the value of a property of a class.
object_class
Returns the class of an instance.
object_superclass
Returns the superclass of an instance.
object_assume
Changes the class of an instance.
object_attributes
Returns the values of the properties of an instance.
object_set_attributes
Initializes the values of the properties of an instance.
object_get
Returns the value of a property of an instance.
object_set
Initializes the value of a property of an instance.
class_find_class_property
Checks if a class property of a class exists.
class_find_instance_property
Checks if an instance property of a class exists.
class_find_class_method_class
Returns the class which implements a class message.
class_find_class_method
Returns the function which implements a class message.
class_find_instance_method_class
Returns the class which implements an instance message.
class_find_instance_method
Returns the function which implements an instance message.
class_send_message
Executes a class message.
class_super_send_message
Executes a class message inherited from a superclass.
object_send_message
Executes an instance message.
object_super_send_message
Executes an instance message inherited from a superclass.
SEE ALSO

Interface, Object

Comments

Your comment:
[p] [b] [i] [u] [s] [quote] [pre] [br] [code] [url] [email] strip help 2000

Enter a maximum of 2000 characters.
Improve the presentation of your text with the following formatting tags:
[p]paragraph[/p], [b]bold[/b], [i]italics[/i], [u]underline[/u], [s]strike[/s], [quote]citation[/quote], [pre]as is[/pre], [br]line break,
[url]http://www.izend.org[/url], [url=http://www.izend.org]site[/url], [email]izend@izend.org[/email], [email=izend@izend.org]izend[/email],
[code]command[/code], [code=language]source code in c, java, php, html, javascript, xml, css, sql, bash, dos, make, etc.[/code].