Changeset 4056ad0 in mainline for uspace/app/bithenge/transform.c


Ignore:
Timestamp:
2012-07-28T01:57:31Z (12 years ago)
Author:
Sean Bartell <wingedtachikoma@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
32eb01b
Parents:
03cad47
Message:

Bithenge: basic parameter passing (integer literals only)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/bithenge/transform.c

    r03cad47 r4056ad0  
    4747 * transform will get its own context with parameters, probably provided by a
    4848 * param_wrapper. If this is zero, the existing outer context will be used with
    49  * whatever parameters it has.
     49 * whatever parameters it has, so they can be passed to any param_wrappers
     50 * within.
    5051 * @return EOK or an error code from errno.h. */
    5152int bithenge_init_transform(bithenge_transform_t *self,
     
    6465{
    6566        assert(false);
     67}
     68
     69typedef struct {
     70        bithenge_transform_t base;
     71        bithenge_transform_t *transform;
     72} param_transform_t;
     73
     74static inline param_transform_t *transform_as_param(
     75    bithenge_transform_t *base)
     76{
     77        return (param_transform_t *)base;
     78}
     79
     80static inline bithenge_transform_t *param_as_transform(
     81    param_transform_t *self)
     82{
     83        return &self->base;
     84}
     85
     86static int param_transform_apply(bithenge_transform_t *base,
     87    bithenge_scope_t *scope, bithenge_node_t *in, bithenge_node_t **out)
     88{
     89        param_transform_t *self = transform_as_param(base);
     90        return bithenge_transform_apply(self->transform, scope, in, out);
     91}
     92
     93static int param_transform_prefix_length(bithenge_transform_t *base,
     94    bithenge_scope_t *scope, bithenge_blob_t *in, aoff64_t *out)
     95{
     96        param_transform_t *self = transform_as_param(base);
     97        return bithenge_transform_prefix_length(self->transform, scope, in,
     98            out);
     99}
     100
     101static void param_transform_destroy(bithenge_transform_t *base)
     102{
     103        param_transform_t *self = transform_as_param(base);
     104        bithenge_transform_dec_ref(self->transform);
     105        free(self);
     106}
     107
     108static const bithenge_transform_ops_t param_transform_ops = {
     109        .apply = param_transform_apply,
     110        .prefix_length = param_transform_prefix_length,
     111        .destroy = param_transform_destroy,
     112};
     113
     114/** Create a wrapper transform with a different number of parameters. Takes a
     115 * reference to @a transform, which it will use for all operations.
     116 * @param[out] out Holds the created transform.
     117 * @param transform The transform to wrap.
     118 * @param num_params The number of parameters to require.
     119 * @return EOK on success or an error code from errno.h. */
     120int bithenge_new_param_transform(bithenge_transform_t **out,
     121    bithenge_transform_t *transform, int num_params)
     122{
     123        assert(transform);
     124        assert(bithenge_transform_num_params(transform) == 0);
     125        assert(num_params != 0);
     126
     127        int rc;
     128        param_transform_t *self = malloc(sizeof(*self));
     129        if (!self) {
     130                rc = ENOMEM;
     131                goto error;
     132        }
     133        rc = bithenge_init_transform(param_as_transform(self),
     134            &param_transform_ops, num_params);
     135        if (rc != EOK)
     136                goto error;
     137        self->transform = transform;
     138        *out = param_as_transform(self);
     139        return EOK;
     140error:
     141        bithenge_transform_dec_ref(transform);
     142        free(self);
     143        return rc;
    66144}
    67145
     
    105183bithenge_transform_t bithenge_ascii_transform = {
    106184        &ascii_ops, 1, 0
     185};
     186
     187static int known_length_apply(bithenge_transform_t *self,
     188    bithenge_scope_t *scope, bithenge_node_t *in, bithenge_node_t **out)
     189{
     190        bithenge_node_t *length_node;
     191        int rc = bithenge_scope_get_param(scope, 0, &length_node);
     192        if (rc != EOK)
     193                return rc;
     194        if (bithenge_node_type(length_node) != BITHENGE_NODE_INTEGER) {
     195                bithenge_node_dec_ref(length_node);
     196                return EINVAL;
     197        }
     198        bithenge_int_t length = bithenge_integer_node_value(length_node);
     199        bithenge_node_dec_ref(length_node);
     200
     201        if (bithenge_node_type(in) != BITHENGE_NODE_BLOB)
     202                return EINVAL;
     203        aoff64_t size;
     204        rc = bithenge_blob_size(bithenge_node_as_blob(in), &size);
     205        if (rc != EOK)
     206                return rc;
     207        if (length != (bithenge_int_t)size)
     208                return EINVAL;
     209
     210        bithenge_node_inc_ref(in);
     211        *out = in;
     212        return EOK;
     213}
     214
     215static int known_length_prefix_length(bithenge_transform_t *self,
     216    bithenge_scope_t *scope, bithenge_blob_t *in, aoff64_t *out)
     217{
     218        bithenge_node_t *length_node;
     219        int rc = bithenge_scope_get_param(scope, 0, &length_node);
     220        if (rc != EOK)
     221                return rc;
     222        if (bithenge_node_type(length_node) != BITHENGE_NODE_INTEGER) {
     223                bithenge_node_dec_ref(length_node);
     224                return EINVAL;
     225        }
     226        bithenge_int_t length = bithenge_integer_node_value(length_node);
     227        bithenge_node_dec_ref(length_node);
     228
     229        *out = (aoff64_t)length;
     230        return EOK;
     231}
     232
     233static const bithenge_transform_ops_t known_length_ops = {
     234        .apply = known_length_apply,
     235        .prefix_length = known_length_prefix_length,
     236        .destroy = transform_indestructible,
     237};
     238
     239/** Pass through a blob, but require its length to equal the first argument. */
     240bithenge_transform_t bithenge_known_length_transform = {
     241        &known_length_ops, 1, 1
    107242};
    108243
     
    232367static bithenge_named_transform_t primitive_transforms[] = {
    233368        {"ascii", &bithenge_ascii_transform},
     369        {"known_length", &bithenge_known_length_transform},
    234370        {"uint8", &bithenge_uint8_transform},
    235371        {"uint16le", &bithenge_uint16le_transform},
Note: See TracChangeset for help on using the changeset viewer.