]> rtime.felk.cvut.cz Git - frescor/frsh.git/commitdiff
Added some container handling function
authorMichal Sojka <sojkam1@fel.cvut.cz>
Wed, 15 Apr 2009 10:30:21 +0000 (12:30 +0200)
committerMichal Sojka <sojkam1@fel.cvut.cz>
Thu, 23 Apr 2009 11:19:40 +0000 (13:19 +0200)
fres/contract/fres_container.c
fres/contract/fres_container.h
fres/contract/fres_container_internal.h
fres/contract/fres_contract.h
fres/contract/fres_error.c
fres/contract/fres_error.h

index 66100285ecbc25bd160b08a0f3360a7dffe31065..daf8f8d7da5638b44f8bff2edba1b0ab48e9ba14 100644 (file)
@@ -254,6 +254,52 @@ fres_container_destroy(struct fres_container *container)
        free(container);
 }
 
+/** 
+ * Duplicates a contract block of a given type. Calls duplication
+ * method registered with the block.
+ * 
+ * @param dest Where to store the copy
+ * @param source What to copy
+ * 
+ * @return Zero on success, non-zero error code on error.
+ */
+int
+fres_block_duplicate(struct fres_block *dest,
+                    const struct fres_block *source,
+                    enum fres_block_type type)
+{
+       dest->state = FRES_BLOCK_EMPTY;
+       switch (source->state) {
+               case FRES_BLOCK_EMPTY:
+                       /* nothing to do */
+                       break;
+               case FRES_BLOCK_DATA: {
+                       void *dup;
+                       dup = block_registry[type]->duplicate(
+                               type, source->u.data);
+                       if (!dup) {
+                               return FRES_ERR_BLOCK_DUP;
+                       }
+                       dest->u.data = dup;
+                       dest->state = FRES_BLOCK_DATA;
+                       break;
+               }
+               case FRES_BLOCK_STREAM:
+                       dest->state = FRES_BLOCK_STREAM;
+                       dest->u.stream = source->u.stream;
+                       dest->u.stream.data = malloc(source->u.stream.length);
+                       if (!dest->u.stream.data) {
+                               return errno;
+                       }
+                       memcpy(dest->u.stream.data, source->u.stream.data,
+                              source->u.stream.length);
+                       break;
+       }
+       return 0;
+}
+                    
+
+
 /** 
  * Duplicates a container
  * 
@@ -267,37 +313,15 @@ fres_container_duplicate(const struct fres_container *source)
 {
        struct fres_container *dest;
        enum fres_block_type type;
-
+       int ret;
        if (!source) return NULL;
        
        dest = fres_container_new();
        if (!dest) return NULL;
 
        for (type=0; type<FRES_NUM_BLOCKS; type++) {
-               const struct fres_block *sb = &source->blocks[type];
-               struct fres_block *db = &dest->blocks[type];
-               db->state = FRES_BLOCK_EMPTY;
-               switch (sb->state) {
-                       case FRES_BLOCK_EMPTY:
-                               /* nothing to do */
-                               break;
-                       case FRES_BLOCK_DATA: {
-                               void *dup;
-                               dup = block_registry[type]->duplicate(
-                                       type, sb->u.data);
-                               if (!dup) goto free_dest_err;
-                               fres_container_add_block(dest, type, dup);
-                               break;
-                       case FRES_BLOCK_STREAM:
-                               db->state = FRES_BLOCK_STREAM;
-                               db->u.stream = sb->u.stream;
-                               db->u.stream.data = malloc(sb->u.stream.length);
-                               if (!db->u.stream.data) goto free_dest_err;
-                               memcpy(db->u.stream.data, sb->u.stream.data,
-                                      sb->u.stream.length);
-                               break;
-                       }
-               }
+               ret = fres_block_duplicate(&dest->blocks[type], &source->blocks[type], type);
+               if (ret) goto free_dest_err;
        }
        return dest;
 free_dest_err:
@@ -599,3 +623,25 @@ fres_container_to_string(char *dest, size_t size, const struct fres_container *c
 err:
        return ret;
 }
+
+
+/** 
+ * Returns the number of non-empty blocks in a container.
+ * 
+ * @param c Container
+ * 
+ * @return Number of non-empty blocks in container @a c.
+ */
+int
+fres_container_get_num_blocks(const struct fres_container *c)
+{
+       int num = 0;
+       enum fres_block_type type;
+       
+       for (type=0; type<FRES_NUM_BLOCKS; type++) {
+               if (c->blocks[type].state != FRES_BLOCK_EMPTY) {
+                       num++;
+               }
+       }
+       return num;
+}
index f41883c42967f43cc275d8fa87324f6bd8adc4a9..7308b0cac2cfd5a2ffbe2ba5495c23d84f0275e6 100644 (file)
@@ -178,6 +178,9 @@ fres_block_duplicate_default(enum fres_block_type type, const void *block_data);
 int
 fres_container_to_string(char *dest, size_t size, const struct fres_container *c);
 
+int
+fres_container_get_num_blocks(const struct fres_container *c);
+
 #ifdef __cplusplus
 } /* extern "C"*/
 #endif
index 7684471122a4e7ed6339bb90624b39ca40651a85..8612541756115ec351359df63682f7145a82ca94 100644 (file)
@@ -113,5 +113,9 @@ struct fres_container {
        ((type) < FRES_NUM_BLOCKS &&    \
         (type) >= 0)
 
+int
+fres_block_duplicate(struct fres_block *dest,
+                    const struct fres_block *source,
+                    enum fres_block_type type);
 
 #endif
index 699ac1677f53bb3a4a58a41729cb6169475674bd..79607fae25f1dad8f4d3949e9ed9a6297682486b 100644 (file)
@@ -155,6 +155,12 @@ fres_contract_get_deadline(const frsh_contract_t *contract,
 void
 fres_contract_print(char *prefix, const struct fres_contract *c);
 
+static inline int
+fres_contract_get_num_blocks(const struct fres_contract *c)
+{
+       return fres_container_get_num_blocks(c->container);
+}
+
 /**
  * Macro which defines type-safe contract "accessor" functions for
  * various blocks.
index 8204511a06cbd8e282f3c4671b7d7039b33046fd..4bddb9c567a5ca43745cf52067903a3dccaa2c84 100644 (file)
@@ -96,6 +96,7 @@ int fres_strerror (int error, char *message, size_t size)
                MSG(FORB_EXCEPTION);
                MSG(BLOCK_NOT_REGISTERED);
                MSG(NEEDS_MORE_DATA_IN_CONTRACT);
+               MSG(BLOCK_DUP);
        }
 
        if (s == NULL) return FRSH_ERR_BAD_ARGUMENT;
index 6402d3c6092a7306e43d136dac53c8816604d7a5..58b1d7b26fa3e0d0a64757072182cfcd3330589f 100644 (file)
@@ -63,6 +63,7 @@ enum fres_error {
        FRES_ERR_FORB_EXCEPTION,
        FRES_ERR_BLOCK_NOT_REGISTERED,
        FRES_ERR_NEEDS_MORE_DATA_IN_CONTRACT,
+       FRES_ERR_BLOCK_DUP,
 };
 
 int fres_strerror (int error, char *message, size_t size);