/Users/maurits/Documents/studie/afstuderen/biosphere/common/copy.c

Go to the documentation of this file.
00001 /*
00002  * Author: MA Hartman
00003  * Date: may 1, 2007
00004  * 
00005  * Function:
00006  * Deep copy and deletion routines for pool allocated structures.
00007  * 
00008  * License information:
00009  * 
00010  * Copyright (c) 2006 Maurits Hartman
00011  *
00012  * Permission is hereby granted, free of charge, to any person
00013  * obtaining a copy of this software and associated documentation
00014  * files (the "Software"), to deal in the Software without
00015  * restriction, including without limitation the rights to use,
00016  * copy, modify, merge, publish, distribute, sublicense, and/or sell
00017  * copies of the Software, and to permit persons to whom the
00018  * Software is furnished to do so, subject to the following
00019  * conditions:
00020  * 
00021  * The above copyright notice and this permission notice shall be
00022  * included in all copies or substantial portions of the Software.
00023  * 
00024  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00025  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
00026  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00027  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
00028  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
00029  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00030  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
00031  * OTHER DEALINGS IN THE SOFTWARE.
00032  * 
00033  */
00034  
00035 #include "copy.h"
00036 #include "str.h"
00037 
00038 #include <assert.h>
00039 #include <stdlib.h>
00040 #include <string.h>
00041 
00042 
00046 static inline bs_data_type *copy_data_type(const bs_data_type *orig)
00047 {
00048         bs_data_type *ret;
00049         assert(orig);
00050         
00051         ret = (bs_data_type *) calloc(1, sizeof(bs_data_type));
00052         ret->name = (char *) calloc(1, strlen(orig->name) + 1);
00053         strcpy(ret->name, orig->name);
00054         ret->builtin = ret->builtin;
00055         return ret;
00056 }
00057 
00058 
00064 static void copy_data_types(const bs_definition *orig, bs_definition *cpy){
00065         assert(orig && cpy);
00066         if (orig->num_data_types > 0) {
00067                 unsigned i;
00068                 
00069                 cpy->data_types = (bs_data_type **) calloc(orig->num_data_types,
00070                                 sizeof(bs_data_type *));
00071                 cpy->num_data_types = orig->num_data_types;
00072                 for (i = 0; i < orig->num_data_types; i++)
00073                         cpy->data_types[i] = copy_data_type(orig->data_types[i]);
00074         }
00075 }
00076 
00077 
00086 static bs_message_part *copy_message_part(bs_message_part *orig,
00087                 const bs_definition *curdef)
00088 {
00089         unsigned i;
00090         bs_message_part *cpy;
00091         assert(orig && !curdef->from_mp);
00092         
00093         /* Set name and from_mp: */
00094         cpy = (bs_message_part *) calloc(1, sizeof(bs_message_part));
00095         cpy->name = (char *) calloc(1, strlen(orig->name) + 1);
00096         strcpy(cpy->name, orig->name);
00097         
00098         /* Find the corresponding data type in the current copied bs_definition: */
00099         for (i = 0; i < curdef->num_data_types; i++) {
00100                 bs_data_type *type = curdef->data_types[i];
00101                 if (streq(orig->type->name, type->name)) {
00102                         cpy->type = type;
00103                         break;
00104                 }
00105         }
00106         assert(cpy->type);
00107         return cpy;
00108 }
00109 
00110 
00117 static void copy_message_parts(const bs_message *orig, bs_message *cpy,
00118                 const bs_definition *curdef)
00119 {
00120         assert(orig && cpy);
00121         if (orig->num_parts > 0) {
00122                 unsigned i;
00123                 
00124                 cpy->parts = (bs_message_part **) calloc(orig->num_parts, sizeof(bs_message_part *));
00125                 cpy->num_parts = orig->num_parts;
00126                 for (i = 0; i < orig->num_parts; i++)
00127                         cpy->parts[i] = copy_message_part(orig->parts[i], curdef);
00128         }       
00129 }
00130 
00131 
00137 static void copy_messages(const bs_definition *orig, bs_definition *cpy)
00138 {
00139         assert(orig && cpy);
00140         if (orig->num_messages > 0) {
00141                 unsigned i;
00142                 
00143                 cpy->messages = (bs_message **) calloc(orig->num_messages, sizeof(bs_message *));
00144                 cpy->num_messages = orig->num_messages;
00145                 for (i = 0; i < orig->num_messages; i++) {
00146                         cpy->messages[i] = (bs_message *) calloc(1, sizeof(bs_message));
00147                         cpy->messages[i]->name = (char *) calloc(1, strlen(orig->messages[i]->name) + 1);
00148                         strcpy(cpy->messages[i]->name, orig->messages[i]->name);
00149                         copy_message_parts(orig->messages[i], cpy->messages[i], cpy);   
00150                 }
00151         }       
00152 }
00153 
00154 
00158 static void copy_operation(const bs_operation *orig, bs_operation *cpy,
00159                 const bs_definition *curdef)
00160 {
00161         unsigned i;
00162         assert(orig && cpy);
00163         
00164         /* Set name and from_mp: */
00165         cpy->name = (char *) calloc(1, strlen(orig->name) + 1);
00166         strcpy(cpy->name, orig->name);
00167         
00168         /* Search the current copied bs_definition for the in-, output and fault messages: */
00169         for (i = 0; i < curdef->num_messages; i++) {
00170                 bs_message *msg = curdef->messages[i];
00171                 if (orig->input && streq(orig->input->name, msg->name))
00172                         cpy->input = msg;
00173                 if (orig->output && streq(orig->output->name, msg->name))
00174                         cpy->output = msg;
00175                 if (orig->fault && streq(orig->fault->name, msg->name))
00176                         cpy->fault = msg;
00177         }       
00178 }
00179 
00180 
00184 static void copy_operations(const bs_port_type *orig, bs_port_type *cpy,
00185                 const bs_definition *curdef)
00186 {
00187         assert(orig && cpy && curdef);
00188         if (orig->num_operations > 0) {
00189                 unsigned i;
00190                 
00191                 cpy->operations = (bs_operation **) calloc(orig->num_operations, sizeof(bs_operation *));
00192                 cpy->num_operations = orig->num_operations;
00193                 for (i = 0; i < orig->num_operations; i++) {
00194                         cpy->operations[i] = (bs_operation *) calloc(1, sizeof(bs_operation));
00195                         copy_operation(orig->operations[i], cpy->operations[i], curdef);
00196                 }
00197         }               
00198 }
00199 
00200 
00201 static void copy_port_types(const bs_definition *orig, bs_definition *cpy)
00202 {
00203         assert(orig && cpy);
00204         if (orig->num_port_types > 0) {
00205                 unsigned i;
00206                 
00207                 cpy->port_types = (bs_port_type **) calloc(orig->num_port_types, sizeof(bs_port_type *));
00208                 cpy->num_port_types = orig->num_port_types;
00209                 for (i = 0; i < orig->num_port_types; i++) {
00210                         cpy->port_types[i] = (bs_port_type *) calloc(1, sizeof(bs_port_type));
00211                         cpy->port_types[i]->name = (char *) calloc(1, strlen(orig->port_types[i]->name) + 1);
00212                         strcpy(cpy->port_types[i]->name, orig->port_types[i]->name);
00213                         copy_operations(orig->port_types[i], cpy->port_types[i], cpy);  
00214                 }
00215         }
00216 }
00217 
00218 
00219 static void copy_port(const bs_port *orig, bs_port *cpy, const bs_definition *curdef)
00220 {
00221         unsigned i;
00222         assert(orig && cpy && curdef);
00223         
00224         /* Set name and from_mp: */
00225         cpy->name = (char *) calloc(1, strlen(orig->name) + 1);
00226         strcpy(cpy->name, orig->name);
00227         
00228         /* Find the corresponding port_type in the current copied bs_definition: */
00229         for (i = 0; i < curdef->num_port_types; i++) {
00230                 bs_port_type *type = curdef->port_types[i];
00231                 if (streq(orig->port_type->name, type->name)) {
00232                         cpy->port_type = type;
00233                         break;
00234                 }
00235         }       
00236 }
00237 
00238 
00239 static void copy_ports(const bs_service *orig, bs_service *cpy,
00240                 const bs_definition *curdef)
00241 {
00242         assert(orig && cpy && curdef);
00243         if (orig->num_ports > 0) {
00244                 unsigned i;
00245                 
00246                 cpy->ports = (bs_port **) calloc(orig->num_ports, sizeof(bs_port *));
00247                 cpy->num_ports = orig->num_ports;
00248                 for (i = 0; i < orig->num_ports; i++) {
00249                         cpy->ports[i] = (bs_port *) calloc(1, sizeof(bs_port));
00250                         copy_port(orig->ports[i], cpy->ports[i], curdef);
00251                 }
00252         }       
00253 }
00254 
00255 
00256 static void copy_services(const bs_definition *orig, bs_definition *cpy)
00257 {
00258         assert(orig && cpy);
00259         if (orig->num_services > 0) {
00260                 unsigned i;
00261                 
00262                 cpy->services = (bs_service **) calloc(orig->num_services, sizeof(bs_service *));
00263                 cpy->num_services = orig->num_services;
00264                 for (i = 0; i < orig->num_services; i++) {
00265                         cpy->services[i] = (bs_service *) calloc(1, sizeof(bs_service));
00266                         cpy->services[i]->name = (char *) calloc(1, strlen(orig->services[i]->name) + 1);
00267                         strcpy(cpy->services[i]->name, orig->services[i]->name);
00268                         copy_ports(orig->services[i], cpy->services[i], cpy);   
00269                 }
00270         }
00271 }
00272 
00273 
00274 bs_definition *copy_definition(const bs_definition *def)
00275 {
00276         assert(def);
00277         bs_definition *result;
00278         
00279         /* Allocate and copy name: */
00280         result = (bs_definition *) calloc(1, sizeof(bs_definition));
00281         result->name = (char *) calloc(1, strlen(def->name) + 1);
00282         strcpy(result->name, def->name);
00283         
00284         copy_data_types(def, result);
00285         copy_messages(def, result);
00286         copy_port_types(def, result);
00287         copy_services(def, result);
00288         
00289         return result;
00290 }
00291 
00292 
00293 static bs_part_instance *copy_part_instance(const bs_part_instance *orig)
00294 {
00295         bs_part_instance *cpy;
00296         
00297         cpy = (bs_part_instance *) calloc(1, sizeof(bs_part_instance));
00298         cpy->name = (char *) calloc(1, strlen(orig->name) + 1);
00299         strcpy(cpy->name, orig->name);
00300         cpy->type = copy_data_type(orig->type);
00301         
00302         /* Copy the data: */
00303         cpy->size = orig->size;
00304         cpy->data = calloc(1, cpy->size + 1);
00305         memcpy(cpy->data, orig->data, cpy->size);
00306         return cpy;
00307 }
00308 
00309 
00310 static void copy_message_instance_data(const bs_message_instance *orig,
00311                 bs_message_instance *cpy)
00312 {
00313         if (!orig) return;
00314         cpy->name = (char *) calloc(1, strlen(orig->name) + 1);
00315         strcpy(cpy->name, orig->name);
00316         
00317         if (orig->num_parts > 0) {
00318                 bs_uint16 i;
00319                 cpy->num_parts = orig->num_parts;
00320                 cpy->parts = (bs_part_instance **) calloc(cpy->num_parts, sizeof(bs_part_instance *));
00321                 for (i = 0; i < cpy->num_parts; i++)
00322                         cpy->parts[i] = copy_part_instance(orig->parts[i]);
00323         }
00324 }
00325 
00326 
00327 bs_service_request *copy_request(const bs_service_request *req)
00328 {
00329         bs_service_request *ret;
00330         unsigned i;
00331         
00332         assert(req);
00333         
00334         /* Copy UUID, service, port and operation: */
00335         ret = (bs_service_request *) calloc(1, sizeof(bs_service_request));
00336         for (i = 0; i < sizeof(ret->uuid); i++) ret->uuid[i] = req->uuid[i];
00337         
00338         ret->service = (char *) calloc(1, strlen(req->service) + 1);
00339         strcpy(ret->service, req->service);
00340         
00341         ret->port = (char *) calloc(1, strlen(req->port) + 1);
00342         strcpy(ret->port, req->port);
00343         
00344         ret->operation = (char *) calloc(1, strlen(req->operation) + 1);
00345         strcpy(ret->operation, req->operation);
00346         
00347         /* Copy instance data: */
00348         ret->input = (bs_message_instance *) calloc(1, sizeof(bs_message_instance));
00349         copy_message_instance_data(req->input, ret->input);
00350         return ret;     
00351 }
00352 
00353 
00354 bs_service_response *copy_response(const bs_service_response *resp)
00355 {
00356         bs_service_response *ret;
00357         unsigned i;
00358         
00359         assert(resp);
00360         
00361         /* Copy UUID, service, port and operation: */
00362         ret = (bs_service_response *) calloc(1, sizeof(bs_service_response));
00363         for (i = 0; i < sizeof(ret->uuid); i++) ret->uuid[i] = resp->uuid[i];
00364         
00365         ret->service = (char *) calloc(1, strlen(resp->service) + 1);
00366         strcpy(ret->service, resp->service);
00367         
00368         ret->port = (char *) calloc(1, strlen(resp->port) + 1);
00369         strcpy(ret->port, resp->port);
00370         
00371         ret->operation = (char *) calloc(1, strlen(resp->operation) + 1);
00372         strcpy(ret->operation, resp->operation);
00373         
00374         /* Copy instance data: */
00375         ret->output = (bs_message_instance *) calloc(1, sizeof(bs_message_instance));
00376         ret->fault = (bs_message_instance *) calloc(1, sizeof(bs_message_instance));
00377         copy_message_instance_data(resp->output, ret->output);
00378         copy_message_instance_data(resp->fault, ret->fault);
00379         return ret;
00380 }
00381 
00382 
00383 static void delete_data_types(bs_definition *def)
00384 {
00385         unsigned i;
00386         assert(!def->from_mp);
00387         for (i = 0; i < def->num_data_types; i++) {
00388                 bs_data_type *type = def->data_types[i];
00389                 free(type->name);       
00390         }
00391         free(def->data_types);
00392 }
00393 
00394 
00395 static void delete_message_parts(bs_message *msg)
00396 {
00397         unsigned i;
00398         assert(!msg->from_mp);
00399         for (i = 0; i < msg->num_parts; i++)
00400                 free(msg->parts[i]->name);
00401         free(msg->parts);       
00402 }
00403 
00404 
00405 static void delete_messages(bs_definition *def)
00406 {
00407         unsigned i;
00408         assert(!def->from_mp);
00409         for (i = 0; i < def->num_messages; i++) {
00410                 bs_message *msg = def->messages[i];
00411                 free(msg->name);
00412                 delete_message_parts(msg);
00413         }
00414         free(def->messages);
00415 }
00416 
00417 
00418 static void delete_operations(bs_port_type *type)
00419 {
00420         unsigned i;
00421         assert(!type->from_mp);
00422         for (i = 0; i < type->num_operations; i++)
00423                 free(type->operations[i]->name);
00424         free(type->operations); 
00425 }
00426 
00427 
00428 static void delete_port_types(bs_definition *def)
00429 {
00430         unsigned i;
00431         assert(!def->from_mp);
00432         for (i = 0; i < def->num_port_types; i++) {
00433                 bs_port_type *type = def->port_types[i];
00434                 free(type->name);
00435                 delete_operations(type);
00436         }
00437         free(def->port_types);  
00438 }
00439 
00440 
00441 static void delete_ports(bs_service *svc)
00442 {
00443         unsigned i;
00444         assert(!svc->from_mp);
00445         for (i = 0; i < svc->num_ports; i++)
00446                 free(svc->ports[i]->name);
00447         free(svc->ports);       
00448 }
00449 
00450 
00451 static void delete_services(bs_definition *def)
00452 {
00453         unsigned i;
00454         assert(!def->from_mp);
00455         for (i = 0; i < def->num_services; i++) {
00456                 bs_service *svc = def->services[i];
00457                 free(svc->name);
00458                 delete_ports(svc);
00459         }
00460         free(def->services);            
00461 }
00462 
00463 
00464 void delete_definition(bs_definition *def)
00465 {
00466         if (!def || def->from_mp) return;
00467         
00468         free(def->name);
00469         
00470         /* Delete recursively, top-to-bottom: */
00471         delete_data_types(def);
00472         delete_messages(def);
00473         delete_port_types(def);
00474         delete_services(def);
00475         
00476         free(def);
00477 }
00478 
00479 
00480 static inline void delete_instance_part(bs_part_instance *part)
00481 {
00482         free(part->name);
00483         free(part->data);
00484         free(part->type->name);
00485         free(part->type);
00486         free(part);
00487 }
00488 
00489 
00490 static void delete_message_instance(bs_message_instance *msg)
00491 {
00492         if (!msg || msg->from_mp) return;
00493         
00494         free(msg->name);
00495         if (msg->num_parts) {   
00496                 unsigned i;
00497                 
00498                 for (i = 0; i < msg->num_parts; i++)
00499                         delete_instance_part(msg->parts[i]);
00500                         
00501                 free(msg->parts);
00502         }
00503         free(msg);
00504 }
00505 
00506 
00507 void delete_request(bs_service_request *req)
00508 {
00509         if (!req || req->from_mp) return;
00510         
00511         free(req->service);
00512         free(req->port);
00513         free(req->operation);
00514         
00515         delete_message_instance(req->input);
00516         
00517         free(req);
00518 }
00519 
00520 
00521 void delete_response(bs_service_response *resp)
00522 {
00523         if (!resp || resp->from_mp) return;
00524         
00525         free(resp->service);
00526         free(resp->port);
00527         free(resp->operation);
00528         
00529         delete_message_instance(resp->output);
00530         delete_message_instance(resp->fault);
00531         
00532         free(resp);
00533 }

Generated on Tue Jul 17 09:50:52 2007 for Bio-SPHERE by  doxygen 1.5.1