[ipxe-devel] [PATCH ipxe v1 3/4] [uuid] parse uuid

David Decotigny ddecotig at gmail.com
Mon Nov 14 07:13:18 UTC 2016


considering I'll send an updated version of the AF_PACKET patch, I'll
also add a unit test for this one as a 2nd version.

On Fri, Nov 11, 2016 at 12:23 PM, David Decotigny <ddecotig at gmail.com> wrote:
> Tested:
>   valgrind ./tap.linux --settings uuid=$(uuidgen) ...
>
>
> ---
>  src/core/settings.c     | 28 +++++++++++++++++++++++
>  src/core/uuid.c         | 60 +++++++++++++++++++++++++++++++++++++++++++++++++
>  src/include/ipxe/uuid.h |  1 +
>  3 files changed, 89 insertions(+)
>
> diff --git a/src/core/settings.c b/src/core/settings.c
> index b4ccedf..5db73b8 100644
> --- a/src/core/settings.c
> +++ b/src/core/settings.c
> @@ -2200,6 +2200,33 @@ const struct setting_type setting_type_base64 __setting_type = {
>  };
>
>  /**
> + * Parse UUID setting value (canonical form)
> + *
> + * @v type             Setting type
> + * @v value            Formatted setting value
> + * @v buf              Buffer to contain raw value
> + * @v len              Length of buffer
> + * @ret len            Length of raw value, or negative error
> + */
> +static int parse_uuid_setting ( const struct setting_type *type __unused,
> +                                const char *value, void *buf, size_t len )
> +{
> +       union uuid * result = ( union uuid * ) buf;
> +
> +       if ( !len && !buf ) {
> +               return sizeof( *result );
> +       } else if ( len != sizeof( *result ) ) {
> +               return -EINVAL;
> +       }
> +
> +       if ( uuid_aton(result, value) ) {
> +               return -EINVAL;
> +       }
> +
> +       return len;
> +}
> +
> +/**
>   * Format UUID setting value
>   *
>   * @v type             Setting type
> @@ -2225,6 +2252,7 @@ static int format_uuid_setting ( const struct setting_type *type __unused,
>  /** UUID setting type */
>  const struct setting_type setting_type_uuid __setting_type = {
>         .name = "uuid",
> +       .parse = parse_uuid_setting,
>         .format = format_uuid_setting,
>  };
>
> diff --git a/src/core/uuid.c b/src/core/uuid.c
> index c43d421..1c0f2a5 100644
> --- a/src/core/uuid.c
> +++ b/src/core/uuid.c
> @@ -53,3 +53,63 @@ const char * uuid_ntoa ( const union uuid *uuid ) {
>                   uuid->canonical.e[4], uuid->canonical.e[5] );
>         return buf;
>  }
> +
> +
> +/**
> + * Parse UUID from formatted string
> + *
> + * @v suuid            UUID in canonical form (expecting the trailing \0)
> + * @ret string UUID
> + */
> +int uuid_aton ( union uuid * uuid, const char * s ) {
> +       static const char pattern[] = "00000000-0000-0000-0000-000000000000";
> +       uint8_t s_idx, nibble_idx;
> +
> +       if ( !s || !uuid ) {
> +               return -1;
> +       }
> +
> +       for ( s_idx = nibble_idx = 0 ;
> +             *s && ( s_idx < ( sizeof(pattern) - 1 ) ) ;
> +             ++s, ++s_idx ) {
> +               uint8_t * uuid_byte = & uuid->raw[ nibble_idx >> 1 ];
> +
> +               if ( pattern[s_idx] != '0' ) {
> +                       /* we were expecting a separator */
> +                       if ( *s != pattern[s_idx] ) {
> +                               return -1;
> +                       }
> +
> +                       /* skip to next input char */
> +                       continue;
> +               }
> +
> +               /* code below is assuming clean roll-over with the
> +                * shift operator, ie. for any initial value of uint8_t x,
> +                * { x <<= 4 ; x <<= 4 } leads to x == 0
> +                */
> +               ( *uuid_byte ) <<= 4;
> +               if ( ( *s >= '0' ) && ( *s <= '9' ) ) {
> +                       ( *uuid_byte ) |= ( *s - '0' );
> +               } else if ( ( *s >= 'a' ) && ( *s <= 'f' ) ) {
> +                       ( *uuid_byte ) |= ( 0xa + ( *s - 'a' ) );
> +               } else if ( ( *s >= 'A' ) && ( *s <= 'F' ) ) {
> +                       ( *uuid_byte ) |= ( 0xa + ( *s - 'A' ) );
> +               } else {
> +                       return -1;
> +               }
> +               nibble_idx ++;
> +       }
> +
> +       if ( *s ) {
> +               /* chars remaining after UUID string */
> +               return -1;
> +       }
> +
> +       if ( s_idx != ( sizeof( pattern ) - 1 ) ) {
> +               /* UUID string was too short */
> +               return -1;
> +       }
> +
> +       return 0;
> +}
> diff --git a/src/include/ipxe/uuid.h b/src/include/ipxe/uuid.h
> index 24c46ac..75f9b78 100644
> --- a/src/include/ipxe/uuid.h
> +++ b/src/include/ipxe/uuid.h
> @@ -48,5 +48,6 @@ static inline void uuid_mangle ( union uuid *uuid ) {
>  }
>
>  extern const char * uuid_ntoa ( const union uuid *uuid );
> +extern int uuid_aton ( union uuid * uuid, const char * s );
>
>  #endif /* _IPXE_UUID_H */
> --
> 2.8.0.rc3.226.g39d4020
>



More information about the ipxe-devel mailing list