| 187 | } |
| 188 | |
| 189 | CipClass *CreateCipClass(const EipUint32 class_id, |
| 190 | const int number_of_class_attributes, |
| 191 | const EipUint32 highest_class_attribute_number, |
| 192 | const int number_of_class_services, |
| 193 | const int number_of_instance_attributes, |
| 194 | const EipUint32 highest_instance_attribute_number, |
| 195 | const int number_of_instance_services, |
| 196 | const int number_of_instances, |
| 197 | char *name, |
| 198 | const EipUint16 revision, |
| 199 | void (*InitializeCipClass)(CipClass *) ) { |
| 200 | |
| 201 | OPENER_TRACE_INFO("creating class '%s' with id: 0x%" PRIX32 "\n", name, |
| 202 | class_id); |
| 203 | |
| 204 | OPENER_ASSERT(NULL == GetCipClass(class_id) ) /* check if an class with the ClassID already exists */ |
| 205 | /* should never try to redefine a class*/ |
| 206 | |
| 207 | /* a metaClass is a class that holds the class attributes and services |
| 208 | CIP can talk to an instance, therefore an instance has a pointer to its class |
| 209 | CIP can talk to a class, therefore a class struct is a subclass of the instance struct, |
| 210 | and contains a pointer to a metaclass |
| 211 | CIP never explicitly addresses a metaclass*/ |
| 212 | |
| 213 | CipClass * const class = (CipClass *) CipCalloc(1, sizeof(CipClass) ); /* create the class object*/ |
| 214 | CipClass *const meta_class = (CipClass *) CipCalloc(1, sizeof(CipClass) ); /* create the metaclass object*/ |
| 215 | |
| 216 | /* initialize the class-specific fields of the Class struct*/ |
| 217 | class->class_id = class_id; /* the class remembers the class ID */ |
| 218 | class->revision = revision; /* the class remembers the class ID */ |
| 219 | class->number_of_instances = 0; /* the number of instances initially zero (more created below) */ |
| 220 | class->instances = 0; |
| 221 | class->number_of_attributes = number_of_instance_attributes; /* the class remembers the number of instances of that class */ |
| 222 | class->highest_attribute_number = highest_instance_attribute_number; /* indicate which attributes are included in instance getAttributeAll */ |
| 223 | class->number_of_services = number_of_instance_services; /* the class manages the behavior of the instances */ |
| 224 | class->services = 0; |
| 225 | class->class_name = name; /* initialize the class-specific fields of the metaClass struct */ |
| 226 | meta_class->class_id = 0xffffffff; /* set metaclass ID (this should never be referenced) */ |
| 227 | meta_class->number_of_instances = 1; /* the class object is the only instance of the metaclass */ |
| 228 | meta_class->instances = (CipInstance *) class; |
| 229 | meta_class->number_of_attributes = number_of_class_attributes + 7; /* the metaclass remembers how many class attributes exist*/ |
| 230 | meta_class->highest_attribute_number = highest_class_attribute_number; /* indicate which attributes are included in class getAttributeAll*/ |
| 231 | meta_class->number_of_services = number_of_class_services; /* the metaclass manages the behavior of the class itself */ |
| 232 | meta_class->class_name = (char *) CipCalloc(1, strlen(name) + 6); /* fabricate the name "meta<classname>"*/ |
| 233 | snprintf(meta_class->class_name, strlen(name) + 6, "meta-%s", name); |
| 234 | |
| 235 | /* initialize the instance-specific fields of the Class struct*/ |
| 236 | class->class_instance.instance_number = 0; /* the class object is instance zero of the class it describes (weird, but that's the spec)*/ |
| 237 | class->class_instance.attributes = 0; /* this will later point to the class attibutes*/ |
| 238 | class->class_instance.cip_class = meta_class; /* the class's class is the metaclass (like SmallTalk)*/ |
| 239 | class->class_instance.next = 0; /* the next link will always be zero, sinc there is only one instance of any particular class object */ |
| 240 | |
| 241 | meta_class->class_instance.instance_number = 0xffffffff; /*the metaclass object does not really have a valid instance number*/ |
| 242 | meta_class->class_instance.attributes = 0; /* the metaclass has no attributes*/ |
| 243 | meta_class->class_instance.cip_class = 0; /* the metaclass has no class*/ |
| 244 | meta_class->class_instance.next = 0; /* the next link will always be zero, since there is only one instance of any particular metaclass object*/ |
| 245 | |
| 246 | /* further initialization of the class object*/ |
no test coverage detected