Re: [libvirt] [PATCHv2 03/15] util: new function for scaling numbers

2012-03-06 Thread Peter Krempa

On 03/06/2012 01:34 AM, Eric Blake wrote:

Scaling an integer based on a suffix is something we plan on reusing
in several contexts: XML parsing, virsh CLI parsing, and possibly
elsewhere.  Make it easy to reuse, as well as adding in support for
powers of 1000.

* src/util/util.h (virScaleInteger): New function.
* src/util/util.c (virScaleInteger): Implement it.
* src/libvirt_private.syms (util.h): Export it.
---

v2: new, but borrows ideas from memory v1 3/3

  src/libvirt_private.syms |1 +
  src/util/util.c  |   66 ++
  src/util/util.h  |4 +++
  3 files changed, 71 insertions(+), 0 deletions(-)

diff --git a/src/util/util.c b/src/util/util.c
index 7c58c7b..1b71680 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -1632,6 +1632,72 @@ virHexToBin(unsigned char c)
  }
  }

+/* Scale an integer VALUE by an optional SUFFIX in-place, defaulting
+ * to SCALE if no suffix is present.  Ensure that the result does not
+ * exceed LIMIT.  Return 0 on success, -1 with error message raised on
+ * failure.  */


I'd write a little bit more on how the base selection works depending on 
the argument. Something like:


For power-of-two scaling use the binary prefixes (i.e. KiB, MiB), for
power of ten scaling use the SI prefixes (i.e. KB, Mb, ...).


+int
+virScaleInteger(unsigned long long *value, const char *suffix,
+unsigned long long scale, unsigned long long limit)


Looks good. ACK

Peter

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCHv2 03/15] util: new function for scaling numbers

2012-03-05 Thread Eric Blake
Scaling an integer based on a suffix is something we plan on reusing
in several contexts: XML parsing, virsh CLI parsing, and possibly
elsewhere.  Make it easy to reuse, as well as adding in support for
powers of 1000.

* src/util/util.h (virScaleInteger): New function.
* src/util/util.c (virScaleInteger): Implement it.
* src/libvirt_private.syms (util.h): Export it.
---

v2: new, but borrows ideas from memory v1 3/3

 src/libvirt_private.syms |1 +
 src/util/util.c  |   66 ++
 src/util/util.h  |4 +++
 3 files changed, 71 insertions(+), 0 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index a104e70..a6d053b 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1121,6 +1121,7 @@ virKillProcess;
 virParseNumber;
 virParseVersionString;
 virPipeReadUntilEOF;
+virScaleInteger;
 virSetBlocking;
 virSetCloseExec;
 virSetInherit;
diff --git a/src/util/util.c b/src/util/util.c
index 7c58c7b..1b71680 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -1632,6 +1632,72 @@ virHexToBin(unsigned char c)
 }
 }

+/* Scale an integer VALUE by an optional SUFFIX in-place, defaulting
+ * to SCALE if no suffix is present.  Ensure that the result does not
+ * exceed LIMIT.  Return 0 on success, -1 with error message raised on
+ * failure.  */
+int
+virScaleInteger(unsigned long long *value, const char *suffix,
+unsigned long long scale, unsigned long long limit)
+{
+if (!suffix || !*suffix) {
+if (!scale) {
+virUtilError(VIR_ERR_INTERNAL_ERROR,
+ _("invalid scale %llu"), scale);
+return -1;
+}
+suffix = "";
+} else if (STRCASEEQ(suffix, "b") || STRCASEEQ(suffix, "byte") ||
+   STRCASEEQ(suffix, "bytes")) {
+scale = 1;
+} else {
+int base;
+
+if (!suffix[1] || STRCASEEQ(suffix + 1, "iB")) {
+base = 1024;
+} else if (c_tolower(suffix[1]) == 'b' && !suffix[2]) {
+base = 1000;
+} else {
+virUtilError(VIR_ERR_INVALID_ARG,
+ _("unknown suffix '%s'"), suffix);
+return -1;
+}
+scale = 1;
+switch (c_tolower(*suffix)) {
+case 'e':
+scale *= base;
+/* fallthrough */
+case 'p':
+scale *= base;
+/* fallthrough */
+case 't':
+scale *= base;
+/* fallthrough */
+case 'g':
+scale *= base;
+/* fallthrough */
+case 'm':
+scale *= base;
+/* fallthrough */
+case 'k':
+scale *= base;
+break;
+default:
+virUtilError(VIR_ERR_INVALID_ARG,
+ _("unknown suffix '%s'"), suffix);
+return -1;
+}
+}
+
+if (*value >= (limit / scale)) {
+virUtilError(VIR_ERR_OVERFLOW, _("value too large: %llu%s"),
+ *value, suffix);
+return -1;
+}
+*value *= scale;
+return 0;
+}
+
 /**
  * virSkipSpaces:
  * @str: pointer to the char pointer used
diff --git a/src/util/util.h b/src/util/util.h
index 5c945cc..85e8bd6 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -157,6 +157,10 @@ int virStrToDouble(char const *s,
char **end_ptr,
double *result);

+int virScaleInteger(unsigned long long *value, const char *suffix,
+unsigned long long scale, unsigned long long limit)
+ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
+
 int virHexToBin(unsigned char c);

 void virSkipSpaces(const char **str) ATTRIBUTE_NONNULL(1);
-- 
1.7.7.6

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list