summaryrefslogtreecommitdiff
path: root/src/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util.c')
-rw-r--r--src/util.c261
1 files changed, 261 insertions, 0 deletions
diff --git a/src/util.c b/src/util.c
new file mode 100644
index 0000000..1ca2a15
--- /dev/null
+++ b/src/util.c
@@ -0,0 +1,261 @@
+/*
+ * transmission-remote-gtk - A GTK RPC client to Transmission
+ * Copyright (C) 2010 Alan Fitton
+
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+
+#include <glib-object.h>
+#include <glib.h>
+#include <glib/gprintf.h>
+#include <gtk/gtk.h>
+
+#include "util.h"
+
+char *tr_strlpercent(char *buf, double x, size_t buflen)
+{
+ return tr_strpercent(buf, x, buflen);
+}
+
+char *tr_strpercent(char *buf, double x, size_t buflen)
+{
+ int precision;
+ if (x < 10.0)
+ precision = 2;
+ else if (x < 100.0)
+ precision = 1;
+ else
+ precision = 0;
+
+ tr_snprintf(buf, buflen, "%.*f%%", precision, tr_truncd(x, precision));
+ return buf;
+}
+
+double tr_truncd(double x, int decimal_places)
+{
+ const int i = (int) pow(10, decimal_places);
+ double x2 = (int) (x * i);
+ return x2 / i;
+}
+
+char *tr_strratio(char *buf, size_t buflen, double ratio,
+ const char *infinity)
+{
+ if ((int) ratio == TR_RATIO_NA)
+ tr_strlcpy(buf, "None", buflen);
+ else if ((int) ratio == TR_RATIO_INF)
+ tr_strlcpy(buf, infinity, buflen);
+ else if (ratio < 10.0)
+ tr_snprintf(buf, buflen, "%.2f", tr_truncd(ratio, 2));
+ else if (ratio < 100.0)
+ tr_snprintf(buf, buflen, "%.1f", tr_truncd(ratio, 1));
+ else
+ tr_snprintf(buf, buflen, "%'.0f", ratio);
+ return buf;
+}
+
+char *tr_strlratio(char *buf, double ratio, size_t buflen)
+{
+ return tr_strratio(buf, buflen, ratio, "\xE2\x88\x9E");
+}
+
+char *tr_strlsize(char *buf, guint64 size, size_t buflen)
+{
+ if (!size)
+ g_strlcpy(buf, "None", buflen);
+#if GLIB_CHECK_VERSION( 2, 16, 0 )
+ else {
+ char *tmp = g_format_size_for_display(size);
+ g_strlcpy(buf, tmp, buflen);
+ g_free(tmp);
+ }
+#else
+ else if (size < (guint64) KILOBYTE_FACTOR)
+ g_snprintf(buf, buflen,
+ ngettext("%'u byte", "%'u bytes", (guint) size),
+ (guint) size);
+ else {
+ gdouble displayed_size;
+ if (size < (guint64) MEGABYTE_FACTOR) {
+ displayed_size = (gdouble) size / KILOBYTE_FACTOR;
+ g_snprintf(buf, buflen, _("%'.1f KB"), displayed_size);
+ } else if (size < (guint64) GIGABYTE_FACTOR) {
+ displayed_size = (gdouble) size / MEGABYTE_FACTOR;
+ g_snprintf(buf, buflen, _("%'.1f MB"), displayed_size);
+ } else {
+ displayed_size = (gdouble) size / GIGABYTE_FACTOR;
+ g_snprintf(buf, buflen, _("%'.1f GB"), displayed_size);
+ }
+ }
+#endif
+ return buf;
+}
+
+char *tr_strlspeed(char *buf, double kb_sec, size_t buflen)
+{
+ const double speed = kb_sec;
+
+ if (speed < 1000.0) /* 0.0 KB to 999.9 KB */
+ g_snprintf(buf, buflen, "%.1f KB/s", speed);
+ else if (speed < 102400.0) /* 0.98 MB to 99.99 MB */
+ g_snprintf(buf, buflen, "%.2f MB/s", (speed / KILOBYTE_FACTOR));
+ else if (speed < 1024000.0) /* 100.0 MB to 999.9 MB */
+ g_snprintf(buf, buflen, "%.1f MB/s", (speed / MEGABYTE_FACTOR));
+ else /* insane speeds */
+ g_snprintf(buf, buflen, "%.2f GB/s", (speed / GIGABYTE_FACTOR));
+
+ return buf;
+}
+
+char *tr_strltime_short(char *buf, gint64 seconds, size_t buflen)
+{
+ int hours, minutes;
+
+ if (seconds < 0)
+ seconds = 0;
+
+ hours = seconds / 3600;
+ minutes = (seconds % 3600) / 60;
+ seconds = (seconds % 3600) % 60;
+
+ g_snprintf(buf, buflen, "%02d:%02d:%02ld", hours, minutes, seconds);
+
+ return buf;
+}
+
+char *tr_strltime_long(char *buf, gint64 seconds, size_t buflen)
+{
+ int days, hours, minutes;
+ char d[128], h[128], m[128], s[128];
+
+ if (seconds < 0)
+ seconds = 0;
+
+ days = seconds / 86400;
+ hours = (seconds % 86400) / 3600;
+ minutes = (seconds % 3600) / 60;
+ seconds = (seconds % 3600) % 60;
+
+ g_snprintf(d, sizeof(d), days > 1 ? "%d days" : "%d day", days);
+ g_snprintf(h, sizeof(h), hours > 1 ? "%d hours" : "%d hour", hours);
+ g_snprintf(m, sizeof(m), minutes > 1 ? "%d minutes" : "%d minute",
+ minutes);
+ g_snprintf(s, sizeof(s),
+ seconds > 1 ? "%ld seconds" : "%ld second", seconds);
+
+ if (days) {
+ if (days >= 4 || !hours) {
+ g_strlcpy(buf, d, buflen);
+ } else {
+ g_snprintf(buf, buflen, "%s, %s", d, h);
+ }
+ } else if (hours) {
+ if (hours >= 4 || !minutes) {
+ g_strlcpy(buf, h, buflen);
+ } else {
+ g_snprintf(buf, buflen, "%s, %s", h, m);
+ }
+ } else if (minutes) {
+ if (minutes >= 4 || !seconds) {
+ g_strlcpy(buf, m, buflen);
+ } else {
+ g_snprintf(buf, buflen, "%s, %s", m, s);
+ }
+ } else {
+ g_strlcpy(buf, s, buflen);
+ }
+
+ return buf;
+}
+
+char *gtr_localtime(time_t time)
+{
+ const struct tm tm = *localtime(&time);
+ char buf[256], *eoln;
+
+ g_strlcpy(buf, asctime(&tm), sizeof(buf));
+ if ((eoln = strchr(buf, '\n')))
+ *eoln = '\0';
+
+ return g_locale_to_utf8(buf, -1, NULL, NULL, NULL);
+}
+
+char *gtr_localtime2(char *buf, time_t time, size_t buflen)
+{
+ char *tmp = gtr_localtime(time);
+ g_strlcpy(buf, tmp, buflen);
+ g_free(tmp);
+ return buf;
+}
+
+int tr_snprintf(char *buf, size_t buflen, const char *fmt, ...)
+{
+ int len;
+ va_list args;
+
+ va_start(args, fmt);
+ len = evutil_vsnprintf(buf, buflen, fmt, args);
+ va_end(args);
+ return len;
+}
+
+size_t tr_strlcpy(char *dst, const void *src, size_t siz)
+{
+#ifdef HAVE_STRLCPY
+ return strlcpy(dst, src, siz);
+#else
+ char *d = dst;
+ const char *s = src;
+ size_t n = siz;
+
+ /* Copy as many bytes as will fit */
+ if (n != 0) {
+ while (--n != 0) {
+ if ((*d++ = *s++) == '\0')
+ break;
+ }
+ }
+
+ /* Not enough room in dst, add NUL and traverse rest of src */
+ if (n == 0) {
+ if (siz != 0)
+ *d = '\0'; /* NUL-terminate dst */
+ while (*s++);
+ }
+
+ return s - (char *) src - 1; /* count does not include NUL */
+#endif
+}
+
+int
+evutil_vsnprintf(char *buf, size_t buflen, const char *format, va_list ap)
+{
+#ifdef _MSC_VER
+ int r = _vsnprintf(buf, buflen, format, ap);
+ buf[buflen - 1] = '\0';
+ if (r >= 0)
+ return r;
+ else
+ return _vscprintf(format, ap);
+#else
+ int r = vsnprintf(buf, buflen, format, ap);
+ buf[buflen - 1] = '\0';
+ return r;
+#endif
+}