home *** CD-ROM | disk | FTP | other *** search
/ Chip 2005 February / CMCD0205.ISO / Linux / gimp-2.2.0.tar.gz / gimp-2.2.0.tar / gimp-2.2.0 / libgimpbase / gimpmemsize.c < prev    next >
C/C++ Source or Header  |  2004-07-27  |  7KB  |  248 lines

  1. /* LIBGIMP - The GIMP Library
  2.  * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
  3.  *
  4.  * This library is free software; you can redistribute it and/or
  5.  * modify it under the terms of the GNU Lesser General Public
  6.  * License as published by the Free Software Foundation; either
  7.  * version 2 of the License, or (at your option) any later version.
  8.  *
  9.  * This library is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12.  * Library General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU Lesser General Public
  15.  * License along with this library; if not, write to the
  16.  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  17.  * Boston, MA 02111-1307, USA.
  18.  */
  19.  
  20. #include "config.h"
  21.  
  22. #include <errno.h>
  23.  
  24. #include <glib-object.h>
  25.  
  26. #include "gimpmemsize.h"
  27.  
  28. #include "libgimp/libgimp-intl.h"
  29.  
  30.  
  31. static void   memsize_to_string (const GValue *src_value,
  32.                                  GValue       *dest_value);
  33. static void   string_to_memsize (const GValue *src_value,
  34.                                  GValue       *dest_value);
  35.  
  36.  
  37. GType
  38. gimp_memsize_get_type (void)
  39. {
  40.   static GType memsize_type = 0;
  41.  
  42.   if (!memsize_type)
  43.     {
  44.       static const GTypeInfo type_info = { 0, };
  45.  
  46.       memsize_type = g_type_register_static (G_TYPE_UINT64, "GimpMemsize",
  47.                                              &type_info, 0);
  48.  
  49.       g_value_register_transform_func (memsize_type, G_TYPE_STRING,
  50.                                        memsize_to_string);
  51.       g_value_register_transform_func (G_TYPE_STRING, memsize_type,
  52.                                        string_to_memsize);
  53.     }
  54.  
  55.   return memsize_type;
  56. }
  57.  
  58. /**
  59.  * gimp_memsize_serialize:
  60.  * @memsize: memory size in bytes
  61.  *
  62.  * Creates a string representation of a given memory size. This string
  63.  * can be parsed by gimp_memsize_deserialize() and can thus be used in
  64.  * config files. It should not be displayed to the user. If you need a
  65.  * nice human-readable string please use gimp_memsize_to_string().
  66.  *
  67.  * Return value: A newly allocated string representation of @memsize.
  68.  *
  69.  * Since: GIMP 2.2
  70.  **/
  71. gchar *
  72. gimp_memsize_serialize (guint64 memsize)
  73. {
  74.   if (memsize > (1 << 30) && memsize % (1 << 30) == 0)
  75.     return g_strdup_printf ("%" G_GUINT64_FORMAT "G", memsize >> 30);
  76.   else if (memsize > (1 << 20) && memsize % (1 << 20) == 0)
  77.     return g_strdup_printf ("%" G_GUINT64_FORMAT "M", memsize >> 20);
  78.   else if (memsize > (1 << 10) && memsize % (1 << 10) == 0)
  79.     return g_strdup_printf ("%" G_GUINT64_FORMAT "k", memsize >> 10);
  80.   else
  81.     return g_strdup_printf ("%" G_GUINT64_FORMAT, memsize);
  82. }
  83.  
  84. /**
  85.  * gimp_memsize_deserialize:
  86.  * @string:  a string as returned by gimp_memsize_serialize()
  87.  * @memsize: return location for memory size in bytes
  88.  *
  89.  * Parses a string representation of a memory size as returned by
  90.  * gimp_memsize_serialize().
  91.  *
  92.  * Return value: %TRUE if the @string was successfully parsed and
  93.  *               @memsize has been set, %FALSE otherwise.
  94.  *
  95.  * Since: GIMP 2.2
  96.  **/
  97. gboolean
  98. gimp_memsize_deserialize (const gchar *string,
  99.                           guint64     *memsize)
  100. {
  101.   gchar   *end;
  102.   guint64  size;
  103.  
  104.   g_return_val_if_fail (string != NULL, FALSE);
  105.   g_return_val_if_fail (memsize != NULL, FALSE);
  106.  
  107.   size = g_ascii_strtoull (string, &end, 0);
  108.  
  109.   if (size == G_MAXUINT64 && errno == ERANGE)
  110.     return FALSE;
  111.  
  112.   if (end && *end)
  113.     {
  114.       guint shift;
  115.  
  116.       switch (g_ascii_tolower (*end))
  117.         {
  118.         case 'b':
  119.           shift = 0;
  120.           break;
  121.         case 'k':
  122.           shift = 10;
  123.           break;
  124.         case 'm':
  125.           shift = 20;
  126.           break;
  127.         case 'g':
  128.           shift = 30;
  129.           break;
  130.         default:
  131.           return FALSE;
  132.         }
  133.  
  134.       /* protect against overflow */
  135.       if (shift)
  136.         {
  137.           guint64  limit = G_MAXUINT64 >> shift;
  138.  
  139.           if (size != (size & limit))
  140.             return FALSE;
  141.  
  142.           size <<= shift;
  143.         }
  144.     }
  145.  
  146.   *memsize = size;
  147.  
  148.   return TRUE;
  149. }
  150.  
  151.  
  152. /**
  153.  * gimp_memsize_to_string:
  154.  * @memsize: A memory size in bytes.
  155.  *
  156.  * This function returns a human readable, translated representation
  157.  * of the passed @memsize. Large values are displayed using a
  158.  * reasonable memsize unit, e.g.: "345" becomes "345 Bytes", "4500"
  159.  * becomes "4.4 KB" and so on.
  160.  *
  161.  * Return value: A newly allocated human-readable, translated string.
  162.  **/
  163. gchar *
  164. gimp_memsize_to_string (guint64 memsize)
  165. {
  166. #if defined _MSC_VER && (_MSC_VER < 1300)
  167. /* sorry, error C2520: conversion from unsigned __int64 to double not
  168.  *                     implemented, use signed __int64
  169.  */
  170. #  define CAST_DOUBLE (gdouble)(gint64)
  171. #else
  172. #  define CAST_DOUBLE (gdouble)
  173. #endif
  174.  
  175.   if (memsize < 1024)
  176.     {
  177.       return g_strdup_printf (_("%d Bytes"), (gint) memsize);
  178.     }
  179.  
  180.   if (memsize < 1024 * 10)
  181.     {
  182.       return g_strdup_printf (_("%.2f KB"), CAST_DOUBLE memsize / 1024.0);
  183.     }
  184.   else if (memsize < 1024 * 100)
  185.     {
  186.       return g_strdup_printf (_("%.1f KB"), CAST_DOUBLE memsize / 1024.0);
  187.     }
  188.   else if (memsize < 1024 * 1024)
  189.     {
  190.       return g_strdup_printf (_("%d KB"), (gint) memsize / 1024);
  191.     }
  192.  
  193.   memsize /= 1024;
  194.  
  195.   if (memsize < 1024 * 10)
  196.     {
  197.       return g_strdup_printf (_("%.2f MB"), CAST_DOUBLE memsize / 1024.0);
  198.     }
  199.   else if (memsize < 1024 * 100)
  200.     {
  201.       return g_strdup_printf (_("%.1f MB"), CAST_DOUBLE memsize / 1024.0);
  202.     }
  203.   else if (memsize < 1024 * 1024)
  204.     {
  205.       return g_strdup_printf (_("%d MB"), (gint) memsize / 1024);
  206.     }
  207.  
  208.   memsize /= 1024;
  209.  
  210.   if (memsize < 1024 * 10)
  211.     {
  212.       return g_strdup_printf (_("%.2f GB"), CAST_DOUBLE memsize / 1024.0);
  213.     }
  214.   else if (memsize < 1024 * 100)
  215.     {
  216.       return g_strdup_printf (_("%.1f GB"), CAST_DOUBLE memsize / 1024.0);
  217.     }
  218.   else
  219.     {
  220.       return g_strdup_printf (_("%d GB"), (gint) memsize / 1024);
  221.     }
  222. #undef CAST_DOUBLE
  223. }
  224.  
  225.  
  226. static void
  227. memsize_to_string (const GValue *src_value,
  228.                    GValue       *dest_value)
  229. {
  230.   g_value_take_string (dest_value,
  231.                        gimp_memsize_serialize (g_value_get_uint64 (src_value)));
  232. }
  233.  
  234. static void
  235. string_to_memsize (const GValue *src_value,
  236.                    GValue       *dest_value)
  237. {
  238.   const gchar *str;
  239.   guint64      memsize;
  240.  
  241.   str = g_value_get_string (src_value);
  242.  
  243.   if (! str || ! gimp_memsize_deserialize (str, &memsize))
  244.     g_warning ("Can't convert string to GimpMemsize.");
  245.  
  246.   g_value_set_uint64 (dest_value, memsize);
  247. }
  248.