]> git.alsa-project.org Git - alsa-lib.git/commitdiff
Added INTEGER64 support by Paul Davis
authorJaroslav Kysela <perex@perex.cz>
Mon, 13 May 2002 09:34:08 +0000 (09:34 +0000)
committerJaroslav Kysela <perex@perex.cz>
Mon, 13 May 2002 09:34:08 +0000 (09:34 +0000)
include/conf.h
include/control.h
src/conf.c
src/control/control.c

index 87ae3f7f43d180f819859b19d9c5b5c3847c0214..fe529f53dd04f95ccfb602e79296831b91448fbb 100644 (file)
@@ -47,6 +47,8 @@ extern "C" {
 typedef enum _snd_config_type {
        /** Integer number */
         SND_CONFIG_TYPE_INTEGER,
+       /** 64 bit Integer number */
+        SND_CONFIG_TYPE_INTEGER64,
        /** Real number */
         SND_CONFIG_TYPE_REAL,
        /** Character string */
@@ -98,12 +100,14 @@ int snd_config_copy(snd_config_t **dst, snd_config_t *src);
 int snd_config_make(snd_config_t **config, const char *key,
                    snd_config_type_t type);
 int snd_config_make_integer(snd_config_t **config, const char *key);
+int snd_config_make_integer64(snd_config_t **config, const char *key);
 int snd_config_make_real(snd_config_t **config, const char *key);
 int snd_config_make_string(snd_config_t **config, const char *key);
 int snd_config_make_pointer(snd_config_t **config, const char *key);
 int snd_config_make_compound(snd_config_t **config, const char *key, int join);
 
 int snd_config_imake_integer(snd_config_t **config, const char *key, const long value);
+int snd_config_imake_integer64(snd_config_t **config, const char *key, const long long value);
 int snd_config_imake_real(snd_config_t **config, const char *key, const double value);
 int snd_config_imake_string(snd_config_t **config, const char *key, const char *ascii);
 int snd_config_imake_pointer(snd_config_t **config, const char *key, const void *ptr);
@@ -112,12 +116,14 @@ snd_config_type_t snd_config_get_type(const snd_config_t *config);
 
 int snd_config_set_id(snd_config_t *config, const char *id);
 int snd_config_set_integer(snd_config_t *config, long value);
+int snd_config_set_integer64(snd_config_t *config, long long value);
 int snd_config_set_real(snd_config_t *config, double value);
 int snd_config_set_string(snd_config_t *config, const char *value);
 int snd_config_set_ascii(snd_config_t *config, const char *ascii);
 int snd_config_set_pointer(snd_config_t *config, const void *ptr);
 int snd_config_get_id(const snd_config_t *config, const char **value);
 int snd_config_get_integer(const snd_config_t *config, long *value);
+int snd_config_get_integer64(const snd_config_t *config, long long *value);
 int snd_config_get_real(const snd_config_t *config, double *value);
 int snd_config_get_ireal(const snd_config_t *config, double *value);
 int snd_config_get_string(const snd_config_t *config, const char **value);
index b3001a3af295346956f68cd30e4f15846d6a60e8..49ef4fbcba990b01617cc970ccc1071873ba211d 100644 (file)
@@ -343,6 +343,9 @@ unsigned int snd_ctl_elem_info_get_count(const snd_ctl_elem_info_t *obj);
 long snd_ctl_elem_info_get_min(const snd_ctl_elem_info_t *obj);
 long snd_ctl_elem_info_get_max(const snd_ctl_elem_info_t *obj);
 long snd_ctl_elem_info_get_step(const snd_ctl_elem_info_t *obj);
+long long snd_ctl_elem_info_get_min64(const snd_ctl_elem_info_t *obj);
+long long snd_ctl_elem_info_get_max64(const snd_ctl_elem_info_t *obj);
+long long snd_ctl_elem_info_get_step64(const snd_ctl_elem_info_t *obj);
 unsigned int snd_ctl_elem_info_get_items(const snd_ctl_elem_info_t *obj);
 void snd_ctl_elem_info_set_item(snd_ctl_elem_info_t *obj, unsigned int val);
 const char *snd_ctl_elem_info_get_item_name(const snd_ctl_elem_info_t *obj);
index e00ab7c359870d2645bceeed2f09d89c582667b4..11822b4ca834aad393f86b8f6f875aab13d8bbe3 100644 (file)
@@ -415,6 +415,7 @@ compound node.</P>
 #include <stdarg.h>
 #include <wordexp.h>
 #include <dlfcn.h>
+#include <limits.h>
 #include <sys/stat.h>
 #include <pthread.h>
 #include "local.h"
@@ -426,6 +427,7 @@ struct _snd_config {
        snd_config_type_t type;
        union {
                long integer;
+               long long integer64;
                char *string;
                double real;
                const void *ptr;
@@ -458,6 +460,18 @@ typedef struct {
        int ch;
 } input_t;
 
+int safe_strtoll(const char *str, long long *val)
+{
+       long long v;
+       if (!*str)
+               return -EINVAL;
+       errno = 0;
+       if (sscanf(str, "%Ld", &v) != 1)
+               return -EINVAL;
+       *val = v;
+       return 0;
+}
+
 int safe_strtol(const char *str, long *val)
 {
        char *end;
@@ -882,9 +896,9 @@ static int parse_value(snd_config_t **_n, snd_config_t *father, input_t *input,
                return 0;
        }
        if (err == 0 && ((s[0] >= '0' && s[0] <= '9') || s[0] == '-')) {
-               long i;
+               long long i;
                errno = 0;
-               err = safe_strtol(s, &i);
+               err = safe_strtoll(s, &i);
                if (err < 0) {
                        double r;
                        err = safe_strtod(s, &r);
@@ -907,16 +921,22 @@ static int parse_value(snd_config_t **_n, snd_config_t *father, input_t *input,
                } else {
                        free(s);
                        if (n) {
-                               if (n->type != SND_CONFIG_TYPE_INTEGER) {
+                               if (n->type != SND_CONFIG_TYPE_INTEGER && n->type != SND_CONFIG_TYPE_INTEGER64) {
                                        SNDERR("%s is not an integer", *id);
                                        return -EINVAL;
                                }
                        } else {
-                               err = _snd_config_make_add(&n, id, SND_CONFIG_TYPE_INTEGER, father);
+                               if (i <= INT_MAX) 
+                                       err = _snd_config_make_add(&n, id, SND_CONFIG_TYPE_INTEGER, father);
+                               else
+                                       err = _snd_config_make_add(&n, id, SND_CONFIG_TYPE_INTEGER64, father);
                                if (err < 0)
                                        return err;
                        }
-                       n->u.integer = i;
+                       if (n->type == SND_CONFIG_TYPE_INTEGER) 
+                               n->u.integer = (long) i;
+                       else 
+                               n->u.integer64 = i;
                        *_n = n;
                        return 0;
                }
@@ -1291,6 +1311,9 @@ static int _snd_config_save_leaf(snd_config_t *n, snd_output_t *out,
        case SND_CONFIG_TYPE_INTEGER:
                snd_output_printf(out, "%ld", n->u.integer);
                break;
+       case SND_CONFIG_TYPE_INTEGER64:
+               snd_output_printf(out, "%Ld", n->u.integer64);
+               break;
        case SND_CONFIG_TYPE_REAL:
                snd_output_printf(out, "%-16g", n->u.real);
                break;
@@ -1414,6 +1437,10 @@ int snd_config_get_type_ascii(const char *ascii, snd_config_type_t *type)
                *type = SND_CONFIG_TYPE_INTEGER;
                return 0;
        }
+       if (!strcmp(ascii, "integer64")) {
+               *type = SND_CONFIG_TYPE_INTEGER64;
+               return 0;
+       }
        if (!strcmp(ascii, "real")) {
                *type = SND_CONFIG_TYPE_REAL;
                return 0;
@@ -1689,6 +1716,17 @@ int snd_config_make_integer(snd_config_t **config, const char *id)
        return snd_config_make(config, id, SND_CONFIG_TYPE_INTEGER);
 }
 
+/**
+ * \brief Build an integer64 config node
+ * \param config Returned config node handle pointer
+ * \param id Node id
+ * \return 0 on success otherwise a negative error code
+ */
+int snd_config_make_integer64(snd_config_t **config, const char *id)
+{
+       return snd_config_make(config, id, SND_CONFIG_TYPE_INTEGER64);
+}
+
 /**
  * \brief Build a real config node
  * \param config Returned config node handle pointer
@@ -1758,6 +1796,24 @@ int snd_config_imake_integer(snd_config_t **config, const char *id, const long v
        return 0;
 }
 
+/**
+ * \brief Build an integer64 config node and use given initial value
+ * \param config Returned config node handle pointer
+ * \param id Node id
+ * \param value Initial value
+ * \return 0 on success otherwise a negative error code
+ */
+int snd_config_imake_integer64(snd_config_t **config, const char *id, const long long value)
+{
+       int err;
+       
+       err = snd_config_make(config, id, SND_CONFIG_TYPE_INTEGER64);
+       if (err < 0)
+               return err;
+       (*config)->u.integer64 = value;
+       return 0;
+}
+
 /**
  * \brief Build a real config node and use given initial value
  * \param config Returned config node handle pointer
@@ -1837,6 +1893,21 @@ int snd_config_set_integer(snd_config_t *config, long value)
        return 0;
 }
 
+/**
+ * \brief Change the value of an integer64 config node
+ * \param config Config node handle
+ * \param value Value
+ * \return 0 on success otherwise a negative error code
+ */
+int snd_config_set_integer64(snd_config_t *config, long long value)
+{
+       assert(config);
+       if (config->type != SND_CONFIG_TYPE_INTEGER64)
+               return -EINVAL;
+       config->u.integer64 = value;
+       return 0;
+}
+
 /**
  * \brief Change the value of a real config node
  * \param config Config node handle
@@ -1909,6 +1980,15 @@ int snd_config_set_ascii(snd_config_t *config, const char *ascii)
                        config->u.integer = i;
                }
                break;
+       case SND_CONFIG_TYPE_INTEGER64:
+               {
+                       long long i;
+                       int err = safe_strtoll(ascii, &i);
+                       if (err < 0)
+                               return err;
+                       config->u.integer64 = i;
+               }
+               break;
        case SND_CONFIG_TYPE_REAL:
                {
                        double d;
@@ -1947,6 +2027,21 @@ int snd_config_get_integer(const snd_config_t *config, long *ptr)
        return 0;
 }
 
+/**
+ * \brief Get the value of an integer64 config node
+ * \param config Config node handle
+ * \param ptr Returned value pointer
+ * \return 0 on success otherwise a negative error code
+ */
+int snd_config_get_integer64(const snd_config_t *config, long long *ptr)
+{
+       assert(config && ptr);
+       if (config->type != SND_CONFIG_TYPE_INTEGER64)
+               return -EINVAL;
+       *ptr = config->u.integer64;
+       return 0;
+}
+
 /**
  * \brief Get the value of a real config node
  * \param config Config node handle
@@ -1968,7 +2063,7 @@ int snd_config_get_real(const snd_config_t *config, double *ptr)
  * \param ptr Returned value pointer
  * \return 0 on success otherwise a negative error code
  *
- * Note: If the config type is integer, it is converted
+ * Note: If the config type is integer/integer64, it is converted
  * to the double type on the fly.
  */
 int snd_config_get_ireal(const snd_config_t *config, double *ptr)
@@ -1978,6 +2073,8 @@ int snd_config_get_ireal(const snd_config_t *config, double *ptr)
                *ptr = config->u.real;
        else if (config->type == SND_CONFIG_TYPE_INTEGER)
                *ptr = config->u.integer;
+       else if (config->type == SND_CONFIG_TYPE_INTEGER64)
+               *ptr = config->u.integer64;
        else
                return -EINVAL;
        return 0;
@@ -2035,6 +2132,18 @@ int snd_config_get_ascii(const snd_config_t *config, char **ascii)
                        *ascii = strdup(res);
                }
                break;
+       case SND_CONFIG_TYPE_INTEGER64:
+               {
+                       char res[32];
+                       int err;
+                       err = snprintf(res, sizeof(res), "%Li", config->u.integer64);
+                       if (err < 0 || err == sizeof(res)) {
+                               assert(0);
+                               return -ENOMEM;
+                       }
+                       *ascii = strdup(res);
+               }
+               break;
        case SND_CONFIG_TYPE_REAL:
                {
                        char res[32];
@@ -3054,6 +3163,14 @@ static int _snd_config_copy(snd_config_t *src,
                        snd_config_set_integer(*dst, v);
                        break;
                }
+               case SND_CONFIG_TYPE_INTEGER64:
+               {
+                       long long v;
+                       err = snd_config_get_integer64(src, &v);
+                       assert(err >= 0);
+                       snd_config_set_integer64(*dst, v);
+                       break;
+               }
                case SND_CONFIG_TYPE_REAL:
                {
                        double v;
@@ -3124,6 +3241,16 @@ static int _snd_config_expand(snd_config_t *src,
                                return err;
                        break;
                }
+               case SND_CONFIG_TYPE_INTEGER64:
+               {
+                       long long v;
+                       err = snd_config_get_integer64(src, &v);
+                       assert(err >= 0);
+                       err = snd_config_imake_integer64(dst, id, v);
+                       if (err < 0)
+                               return err;
+                       break;
+               }
                case SND_CONFIG_TYPE_REAL:
                {
                        double v;
@@ -3613,6 +3740,19 @@ static int parse_args(snd_config_t *subs, const char *str, snd_config_t *defs)
                        err = snd_config_set_integer(sub, v);
                        if (err < 0)
                                goto _err;
+               } else if (strcmp(tmp, "integer64") == 0) {
+                       long long v;
+                       err = snd_config_make(&sub, var, SND_CONFIG_TYPE_INTEGER64);
+                       if (err < 0)
+                               goto _err;
+                       err = safe_strtoll(val, &v);
+                       if (err < 0) {
+                               SNDERR("Parameter %s must be an integer", var);
+                               goto _err;
+                       }
+                       err = snd_config_set_integer64(sub, v);
+                       if (err < 0)
+                               goto _err;
                } else if (strcmp(tmp, "real") == 0) {
                        double v;
                        err = snd_config_make(&sub, var, SND_CONFIG_TYPE_REAL);
index 4281059e512ac1bd95f56d76d0b399b1e4e9deed..7a65ce30bfe7fb9fa5104c5eeeeb8136eb904f22 100644 (file)
@@ -666,6 +666,7 @@ static const char *snd_ctl_elem_type_names[] = {
        TYPE(ENUMERATED),
        TYPE(BYTES),
        TYPE(IEC958),
+       TYPE(INTEGER64),
 };
 
 static const char *snd_ctl_elem_iface_names[] = {
@@ -1599,6 +1600,42 @@ long snd_ctl_elem_info_get_step(const snd_ctl_elem_info_t *obj)
        return obj->value.integer.step;
 }
 
+/**
+ * \brief Get minimum value from a #SND_CTL_ELEM_TYPE_INTEGER64 CTL element id/info
+ * \param obj CTL element id/info
+ * \return Minimum value
+ */
+long long snd_ctl_elem_info_get_min64(const snd_ctl_elem_info_t *obj)
+{
+       assert(obj);
+       assert(obj->type == SND_CTL_ELEM_TYPE_INTEGER64);
+       return obj->value.integer64.min;
+}
+
+/**
+ * \brief Get maximum value from a #SND_CTL_ELEM_TYPE_INTEGER64 CTL element id/info
+ * \param obj CTL element id/info
+ * \return Maximum value
+ */
+long long snd_ctl_elem_info_get_max64(const snd_ctl_elem_info_t *obj)
+{
+       assert(obj);
+       assert(obj->type == SND_CTL_ELEM_TYPE_INTEGER64);
+       return obj->value.integer64.max;
+}
+
+/**
+ * \brief Get value step from a #SND_CTL_ELEM_TYPE_INTEGER64 CTL element id/info
+ * \param obj CTL element id/info
+ * \return Step
+ */
+long long snd_ctl_elem_info_get_step64(const snd_ctl_elem_info_t *obj)
+{
+       assert(obj);
+       assert(obj->type == SND_CTL_ELEM_TYPE_INTEGER64);
+       return obj->value.integer64.step;
+}
+
 /**
  * \brief Get number of items available from a #SND_CTL_ELEM_TYPE_ENUMERATED CTL element id/info
  * \param obj CTL element id/info