derived1.c
Go to the documentation of this file.
00001 
00024 #include "derived1_friend.h"
00025 
00027 #define DERIVED1_STR_SIZE 256
00028 
00033 typedef struct derived1_private_st_ {
00035     const derived1_vtable_st *vtable;
00036 } derived1_private_st;
00037 
00038 /*
00039  * This is C, we need explicit casts to each of an object's parent classes.
00040  */
00041 
00048 static derived1_handle
00049 base1_cast_to_derived1 (base1_handle base1_h)
00050 {
00051     derived1_handle derived1_h = NULL;
00052 
00053     if (NULL != base1_h) {
00054         derived1_h = (derived1_handle) ((uint8_t *) base1_h -
00055                                         offsetof(derived1_st, base1));
00056     }
00057 
00058     return (derived1_h);
00059 }
00060 
00067 static derived1_handle
00068 base2_cast_to_derived1 (base2_handle base2_h)
00069 {
00070     derived1_handle derived1_h = NULL;
00071 
00072     if (NULL != base2_h) {
00073         derived1_h = (derived1_handle) ((uint8_t *) base2_h -
00074                                         offsetof(derived1_st, base2));
00075     }
00076 
00077     return (derived1_h);
00078 }
00079 
00088 static my_rc_e
00089 derived1_base2_increase_val1 (base2_handle base2_h)
00090 {
00091     if (NULL == base2_h) {
00092         LOG_ERR("Invalid input, base2_h(%p)", base2_h);
00093         return (MY_RC_E_EINVAL);
00094     }
00095 
00096     base2_h->val1 += 5;
00097 
00098     return (MY_RC_E_SUCCESS);
00099 }
00100 
00112 static my_rc_e
00113 derived1_string_size_internal (derived1_handle derived1_h, size_t *buffer_size)
00114 {
00115     if ((NULL == derived1_h) || (NULL == buffer_size)) {
00116         LOG_ERR("Invalid input, derived1_h(%p) buffer_size(%p)",
00117                 derived1_h, buffer_size);
00118         return (MY_RC_E_EINVAL);
00119     }
00120     *buffer_size = DERIVED1_STR_SIZE;
00121 
00122     return (MY_RC_E_SUCCESS);
00123 }
00124 
00132 static my_rc_e
00133 derived1_base1_string_size (base1_handle base1_h, size_t *buffer_size)
00134 {
00135     return (derived1_string_size_internal(base1_cast_to_derived1(base1_h), 
00136                                           buffer_size));
00137 }
00138 
00146 static my_rc_e
00147 derived1_base2_string_size (base2_handle base2_h, size_t *buffer_size)
00148 {
00149     return (derived1_string_size_internal(base2_cast_to_derived1(base2_h), 
00150                                           buffer_size));
00151 }
00152 
00160 static const char *
00161 derived1_type_string_internal (derived1_handle derived1_h)
00162 {
00163     return ("derived1");
00164 }
00165 
00172 static const char *
00173 derived1_base1_type_string (base1_handle base1_h)
00174 {
00175     return (derived1_type_string_internal(base1_cast_to_derived1(base1_h)));
00176 }
00177 
00184 static const char *
00185 derived1_base2_type_string (base2_handle base2_h)
00186 {
00187     return (derived1_type_string_internal(base2_cast_to_derived1(base2_h)));
00188 }
00189 
00199 static my_rc_e
00200 derived1_string_internal (derived1_handle derived1_h, 
00201                           char *buffer, size_t buffer_size)
00202 {
00203     size_t min_size;
00204     my_rc_e rc = MY_RC_E_SUCCESS;
00205 
00206     if ((NULL == derived1_h) || (NULL == buffer)) {
00207         LOG_ERR("Invalid input, derived1_h(%p) buffer(%p) buffer_size(%zu)",
00208                 derived1_h, buffer, buffer_size);
00209         return (MY_RC_E_EINVAL);
00210     }
00211 
00212     rc = derived1_string_size_internal(derived1_h, &min_size);
00213     if (my_rc_e_is_notok(rc)) {
00214         return (rc);
00215     }
00216 
00217     if (buffer_size < min_size) {
00218         LOG_ERR("Invalid input, buffer_size(%zu)", buffer_size);
00219         return (MY_RC_E_EINVAL);
00220     }
00221 
00222     snprintf(buffer, buffer_size, "b1_val1(%u) b1_val2(%u) b1_val3(%u) "
00223              "b2_val1(%u) d1_val4(%u)", derived1_h->base1.public_data.val1,
00224              derived1_h->base1.public_data.val2, derived1_h->base1.val3,
00225              derived1_h->base2.val1, derived1_h->val4);
00226 
00227     return (MY_RC_E_SUCCESS);
00228 }
00229 
00238 static my_rc_e
00239 derived1_base1_string (base1_handle base1_h, char *buffer, size_t buffer_size)
00240 {
00241     return (derived1_string_internal(base1_cast_to_derived1(base1_h), buffer,
00242                                      buffer_size));
00243 }
00244 
00253 static my_rc_e
00254 derived1_base2_string (base2_handle base2_h, char *buffer, size_t buffer_size)
00255 {
00256     return (derived1_string_internal(base2_cast_to_derived1(base2_h), buffer,
00257                                      buffer_size));
00258 }
00259 
00268 static my_rc_e
00269 derived1_increase_val4_internal (derived1_handle derived1_h)
00270 {
00271     if (NULL == derived1_h) {
00272         LOG_ERR("Invalid input, derived1_h(%p)", derived1_h);
00273         return (MY_RC_E_EINVAL);
00274     }
00275 
00276     derived1_h->val4 *= 3;
00277 
00278     return (MY_RC_E_SUCCESS);
00279 }
00280 
00287 my_rc_e
00288 derived1_increase_val4 (derived1_handle derived1_h)
00289 {
00290     my_rc_e rc = MY_RC_E_SUCCESS;
00291 
00292     VALIDATE_VTABLE_FN(derived1_h, private_h, vtable, increase_val4_fn, rc);
00293     if (my_rc_e_is_notok(rc)) {
00294         return (rc);
00295     }
00296 
00297     return (derived1_h->private_h->vtable->increase_val4_fn(derived1_h));
00298 }
00299 
00311 static void
00312 derived1_delete_internal (derived1_handle derived1_h, bool free_derived1_h)
00313 {
00314     if (NULL == derived1_h) {
00315         return;
00316     }
00317 
00318     base1_friend_delete(&(derived1_h->base1));
00319     base2_friend_delete(&(derived1_h->base2));
00320 
00321     if (NULL != derived1_h->private_h) {
00322         free(derived1_h->private_h);
00323         derived1_h->private_h = NULL;
00324     }
00325 
00326     if (free_derived1_h) {
00327         free(derived1_h);
00328     }
00329 }
00330 
00341 void
00342 derived1_friend_delete (derived1_handle derived1_h)
00343 {
00344     derived1_delete_internal(derived1_h, false);
00345 }
00346 
00355 static void
00356 derived1_private_delete (derived1_handle derived1_h)
00357 {
00358     derived1_delete_internal(derived1_h, true);
00359 }
00360 
00367 void
00368 derived1_delete (derived1_handle derived1_h)
00369 {
00370     my_rc_e rc = MY_RC_E_SUCCESS;
00371 
00372     VALIDATE_VTABLE_FN(derived1_h, private_h, vtable, delete_fn, rc);
00373     if (my_rc_e_is_notok(rc)) {
00374         return;
00375     }
00376 
00377     return (derived1_h->private_h->vtable->delete_fn(derived1_h));
00378 }
00379 
00386 static void
00387 derived1_base1_delete (base1_handle base1_h)
00388 {
00389     return (derived1_delete(base1_cast_to_derived1(base1_h)));
00390 }
00391 
00398 static void
00399 derived1_base2_delete (base2_handle base2_h)
00400 {
00401     return (derived1_delete(base2_cast_to_derived1(base2_h)));
00402 }
00403 
00409 static base1_vtable_st base1_vtable = {
00410     derived1_base1_delete,
00411     derived1_base1_type_string,
00412     derived1_base1_string,
00413     derived1_base1_string_size,
00414     NULL
00415 };
00416 
00422 static base2_vtable_st base2_vtable = {
00423     derived1_base2_delete,
00424     derived1_base2_type_string,
00425     derived1_base2_string,
00426     derived1_base2_string_size,
00427     derived1_base2_increase_val1
00428 };
00429 
00435 static derived1_vtable_st derived1_vtable = {
00436     &base1_vtable,
00437     &base2_vtable,
00438     derived1_private_delete,
00439     derived1_increase_val4_internal
00440 };
00441 
00448 base1_handle
00449 derived1_cast_to_base1 (derived1_handle derived1_h)
00450 {
00451     base1_handle base1_h = NULL;
00452 
00453     if (NULL != derived1_h) {
00454         base1_h = &(derived1_h->base1);
00455     }
00456 
00457     return (base1_h);
00458 }
00459 
00466 base2_handle
00467 derived1_cast_to_base2 (derived1_handle derived1_h)
00468 {
00469     base2_handle base2_h = NULL;
00470 
00471     if (NULL != derived1_h) {
00472         base2_h = &(derived1_h->base2);
00473     }
00474 
00475     return (base2_h);
00476 }
00477 
00487 my_rc_e
00488 derived1_inherit_vtable (const derived1_vtable_st *parent_vtable,
00489                          derived1_vtable_st *child_vtable,
00490                          bool do_null_check)
00491 {
00492     my_rc_e rc = MY_RC_E_SUCCESS;
00493 
00494     /* Always add a new check here if functions are added. */
00495     CT_ASSERT(4 == (sizeof(derived1_vtable_st)/sizeof(void*)));
00496 
00497     if ((NULL == parent_vtable) || (NULL == child_vtable)) {
00498         LOG_ERR("Invalid input, parent_vtable(%p) "
00499                 "child_vtable(%p)", parent_vtable, child_vtable);
00500         return (MY_RC_E_EINVAL);
00501     }
00502 
00503     rc = base1_inherit_vtable(&base1_vtable, child_vtable->base1_vtable, false);
00504     if (my_rc_e_is_notok(rc)) {
00505         return (rc);
00506     }
00507 
00508     rc = base2_inherit_vtable(&base2_vtable, child_vtable->base2_vtable, false);
00509     if (my_rc_e_is_notok(rc)) {
00510         return (rc);
00511     }
00512 
00513     INHERIT_VTABLE_FN(parent_vtable, child_vtable, delete_fn, do_null_check,
00514                       rc);
00515     INHERIT_VTABLE_FN(parent_vtable, child_vtable, increase_val4_fn, 
00516                       do_null_check, rc);
00517 
00518     return (MY_RC_E_SUCCESS);
00519 
00520 err_exit:
00521 
00522     return (rc);
00523 }
00524 
00534 my_rc_e
00535 derived1_set_vtable (derived1_handle derived1_h, derived1_vtable_st *vtable)
00536 {
00537     my_rc_e rc;
00538 
00539     if ((NULL == derived1_h) || (NULL == vtable)) {
00540         LOG_ERR("Invalid input, derived1_h(%p) vtable(%p)", derived1_h, vtable);
00541         return (MY_RC_E_EINVAL);
00542     }
00543 
00544     if (NULL == derived1_h->private_h) {
00545         LOG_ERR("Invalid input, derived1_h(%p)->private_h(%p)", derived1_h,
00546                 derived1_h->private_h);
00547         return (MY_RC_E_EINVAL);
00548     }
00549 
00550     rc = derived1_inherit_vtable(&derived1_vtable, vtable, true);
00551     if (my_rc_e_is_notok(rc)) {
00552         return (rc);
00553     }
00554 
00555     rc = base1_set_vtable(&(derived1_h->base1), vtable->base1_vtable);
00556     if (my_rc_e_is_notok(rc)) {
00557         return (rc);
00558     }
00559 
00560     rc = base2_set_vtable(&(derived1_h->base2), vtable->base2_vtable);
00561     if (my_rc_e_is_notok(rc)) {
00562         return (rc);
00563     }
00564 
00565     derived1_h->private_h->vtable = vtable;
00566 
00567     return (MY_RC_E_SUCCESS);
00568 }
00569 
00579 my_rc_e
00580 derived1_init (derived1_handle derived1_h)
00581 {
00582     bool did_base1_init = false;
00583     bool did_base2_init = false;
00584     my_rc_e rc = MY_RC_E_SUCCESS;
00585 
00586     if (NULL == derived1_h) {
00587         LOG_ERR("Invalid input, derived1_h(%p)", derived1_h);
00588         return (MY_RC_E_EINVAL);
00589     }
00590 
00591     rc = base1_init(&(derived1_h->base1));
00592     if (my_rc_e_is_notok(rc)) {
00593         return (rc);
00594     }
00595     did_base1_init = true;
00596 
00597     rc = base1_set_vtable(&(derived1_h->base1), &base1_vtable);
00598     if (my_rc_e_is_notok(rc)) {
00599         return (rc);
00600     }
00601 
00602     rc = base2_init(&(derived1_h->base2));
00603     if (my_rc_e_is_notok(rc)) {
00604         return (rc);
00605     }
00606     did_base2_init = true;
00607 
00608     rc = base2_set_vtable(&(derived1_h->base2), &base2_vtable);
00609     if (my_rc_e_is_notok(rc)) {
00610         return (rc);
00611     }
00612 
00613     derived1_h->private_h = calloc(1, sizeof(*derived1_h->private_h));
00614     if (NULL == derived1_h->private_h) {
00615         rc = MY_RC_E_ENOMEM;
00616         goto err_exit;
00617     }
00618 
00619     derived1_h->private_h->vtable = &derived1_vtable;
00620     derived1_h->val4 = 500;
00621 
00622     return (MY_RC_E_SUCCESS);
00623 
00624 err_exit:
00625 
00626     if (NULL != derived1_h->private_h) {
00627         free(derived1_h->private_h);
00628         derived1_h->private_h = NULL;
00629     }
00630 
00631     if (did_base2_init) {
00632         base2_friend_delete(&(derived1_h->base2));
00633     }
00634 
00635     if (did_base1_init) {
00636         base1_friend_delete(&(derived1_h->base1));
00637     }
00638 
00639     return (rc);
00640 }
00641 
00647 derived1_handle
00648 derived1_new1 (void)
00649 {
00650     derived1_st *derived1 = NULL;
00651     my_rc_e rc;
00652 
00653     derived1 = calloc(1, sizeof(*derived1));
00654     if (NULL != derived1) {
00655         rc = derived1_init(derived1);
00656         if (my_rc_e_is_notok(rc)) {
00657             LOG_ERR("Init failed, rc(%s)", my_rc_e_get_string(rc));
00658             goto err_exit;
00659         }
00660     }
00661 
00662     return (derived1);
00663 
00664 err_exit:
00665 
00666     derived1_delete(derived1);
00667 
00668     return (NULL);
00669 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines