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
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
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 }