home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2002 April / pcpro0402.iso / essentials / graphics / Gimp / gimp-src-20001226.exe / src / gimp / libgimp / gimpwire.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-08-24  |  9.2 KB  |  494 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. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #ifdef HAVE_SYS_PARAM_H
  27. #include <sys/param.h>
  28. #endif
  29. #include <sys/types.h>
  30. #ifdef HAVE_UNISTD_H
  31. #include <unistd.h>
  32. #endif
  33.  
  34. #ifdef G_OS_WIN32
  35. #include <process.h>
  36. #include <io.h>
  37. #endif
  38.  
  39. #include <glib.h>
  40.  
  41. #include "gimpwire.h"
  42.  
  43.  
  44. typedef struct _WireHandler  WireHandler;
  45.  
  46. struct _WireHandler
  47. {
  48.   guint32         type;
  49.   WireReadFunc    read_func;
  50.   WireWriteFunc   write_func;
  51.   WireDestroyFunc destroy_func;
  52. };
  53.  
  54.  
  55. static void      wire_init    (void);
  56. static guint     wire_hash    (guint32 *key);
  57. static gboolean  wire_compare (guint32 *a,
  58.                    guint32 *b);
  59.  
  60.  
  61. static GHashTable    *wire_ht = NULL;
  62. static WireIOFunc     wire_read_func = NULL;
  63. static WireIOFunc     wire_write_func = NULL;
  64. static WireFlushFunc  wire_flush_func = NULL;
  65. static gboolean       wire_error_val = FALSE;
  66.  
  67.  
  68. void
  69. wire_register (guint32         type,
  70.            WireReadFunc    read_func,
  71.            WireWriteFunc   write_func,
  72.            WireDestroyFunc destroy_func)
  73. {
  74.   WireHandler *handler;
  75.  
  76.   if (!wire_ht)
  77.     wire_init ();
  78.  
  79.   handler = g_hash_table_lookup (wire_ht, &type);
  80.   if (!handler)
  81.     handler = g_new (WireHandler, 1);
  82.  
  83.   handler->type         = type;
  84.   handler->read_func    = read_func;
  85.   handler->write_func   = write_func;
  86.   handler->destroy_func = destroy_func;
  87.  
  88.   g_hash_table_insert (wire_ht, &handler->type, handler);
  89. }
  90.  
  91. void
  92. wire_set_reader (WireIOFunc read_func)
  93. {
  94.   wire_read_func = read_func;
  95. }
  96.  
  97. void
  98. wire_set_writer (WireIOFunc write_func)
  99. {
  100.   wire_write_func = write_func;
  101. }
  102.  
  103. void
  104. wire_set_flusher (WireFlushFunc flush_func)
  105. {
  106.   wire_flush_func = flush_func;
  107. }
  108.  
  109. gboolean
  110. wire_read (GIOChannel *channel,
  111.        guint8     *buf,
  112.        gulong      count)
  113. {
  114.   if (wire_read_func)
  115.     {
  116.       if (!(* wire_read_func) (channel, buf, count))
  117.     {
  118.       g_warning ("%s: wire_read: error", g_get_prgname ());
  119.       wire_error_val = TRUE;
  120.       return FALSE;
  121.     }
  122.     }
  123.   else
  124.     {
  125.       GIOError error;
  126.       guint    bytes;
  127.  
  128.       while (count > 0)
  129.     {
  130.       do
  131.         {
  132.           bytes = 0;
  133.           error = g_io_channel_read (channel, (char*) buf, count, &bytes);
  134.         }
  135.       while ((error == G_IO_ERROR_AGAIN) ||
  136.          (error == G_IO_ERROR_UNKNOWN && errno == EINTR));
  137.  
  138.       if (error != G_IO_ERROR_NONE)
  139.         {
  140.           g_warning ("%s: wire_read: error", g_get_prgname ());
  141.           wire_error_val = TRUE;
  142.           return FALSE;
  143.         }
  144.  
  145.       if (bytes == 0)
  146.         {
  147.           g_warning ("%s: wire_read: unexpected EOF", g_get_prgname ());
  148.           wire_error_val = TRUE;
  149.           return FALSE;
  150.         }
  151.  
  152.       count -= bytes;
  153.       buf += bytes;
  154.     }
  155.     }
  156.  
  157.   return TRUE;
  158. }
  159.  
  160. gboolean
  161. wire_write (GIOChannel *channel,
  162.         guint8     *buf,
  163.         gulong      count)
  164. {
  165.   if (wire_write_func)
  166.     {
  167.       if (!(* wire_write_func) (channel, buf, count))
  168.     {
  169.       g_warning ("%s: wire_write: error", g_get_prgname ());
  170.       wire_error_val = TRUE;
  171.       return FALSE;
  172.     }
  173.     }
  174.   else
  175.     {
  176.       GIOError error;
  177.       guint    bytes;
  178.  
  179.       while (count > 0)
  180.     {
  181.       do
  182.         {
  183.           bytes = 0;
  184.           error = g_io_channel_write (channel, (char*) buf, count, &bytes);
  185.         }
  186.       while ((error == G_IO_ERROR_AGAIN) ||
  187.          (error == G_IO_ERROR_UNKNOWN && errno == EINTR));
  188.  
  189.       if (error != G_IO_ERROR_NONE)
  190.         {
  191.           g_warning ("%s: wire_write: error", g_get_prgname ());
  192.           wire_error_val = TRUE;
  193.           return FALSE;
  194.         }
  195.  
  196.       count -= bytes;
  197.       buf += bytes;
  198.     }
  199.     }
  200.  
  201.   return TRUE;
  202. }
  203.  
  204. gboolean
  205. wire_flush (GIOChannel *channel)
  206. {
  207.   if (wire_flush_func)
  208.     return (* wire_flush_func) (channel);
  209.  
  210.   return FALSE;
  211. }
  212.  
  213. gboolean
  214. wire_error (void)
  215. {
  216.   return wire_error_val;
  217. }
  218.  
  219. void
  220. wire_clear_error (void)
  221. {
  222.   wire_error_val = FALSE;
  223. }
  224.  
  225. gboolean
  226. wire_read_msg (GIOChannel  *channel,
  227.            WireMessage *msg)
  228. {
  229.   WireHandler *handler;
  230.  
  231.   if (wire_error_val)
  232.     return !wire_error_val;
  233.  
  234.   if (!wire_read_int32 (channel, &msg->type, 1))
  235.     return FALSE;
  236.  
  237.   handler = g_hash_table_lookup (wire_ht, &msg->type);
  238.   if (!handler)
  239.     g_error ("could not find handler for message: %d", msg->type);
  240.  
  241.   (* handler->read_func) (channel, msg);
  242.  
  243.   return !wire_error_val;
  244. }
  245.  
  246. gboolean
  247. wire_write_msg (GIOChannel  *channel,
  248.         WireMessage *msg)
  249. {
  250.   WireHandler *handler;
  251.  
  252.   if (wire_error_val)
  253.     return !wire_error_val;
  254.  
  255.   handler = g_hash_table_lookup (wire_ht, &msg->type);
  256.   if (!handler)
  257.     g_error ("could not find handler for message: %d", msg->type);
  258.  
  259.   if (!wire_write_int32 (channel, &msg->type, 1))
  260.     return FALSE;
  261.  
  262.   (* handler->write_func) (channel, msg);
  263.  
  264.   return !wire_error_val;
  265. }
  266.  
  267. void
  268. wire_destroy (WireMessage *msg)
  269. {
  270.   WireHandler *handler;
  271.  
  272.   handler = g_hash_table_lookup (wire_ht, &msg->type);
  273.   if (!handler)
  274.     g_error ("could not find handler for message: %d\n", msg->type);
  275.  
  276.   (* handler->destroy_func) (msg);
  277. }
  278.  
  279. gboolean
  280. wire_read_int32 (GIOChannel *channel,
  281.          guint32    *data,
  282.          gint        count)
  283. {
  284.   if (count > 0)
  285.     {
  286.       if (!wire_read_int8 (channel, (guint8*) data, count * 4))
  287.     return FALSE;
  288.  
  289.       while (count--)
  290.     {
  291.       *data = g_ntohl (*data);
  292.       data++;
  293.     }
  294.     }
  295.  
  296.   return TRUE;
  297. }
  298.  
  299. gboolean
  300. wire_read_int16 (GIOChannel *channel,
  301.          guint16    *data,
  302.          gint        count)
  303. {
  304.   if (count > 0)
  305.     {
  306.       if (!wire_read_int8 (channel, (guint8*) data, count * 2))
  307.     return FALSE;
  308.  
  309.       while (count--)
  310.     {
  311.       *data = g_ntohs (*data);
  312.       data++;
  313.     }
  314.     }
  315.  
  316.   return TRUE;
  317. }
  318.  
  319. gboolean
  320. wire_read_int8 (GIOChannel *channel,
  321.         guint8     *data,
  322.         gint        count)
  323. {
  324.   return wire_read (channel, data, count);
  325. }
  326.  
  327. gboolean
  328. wire_read_double (GIOChannel *channel,
  329.           gdouble    *data,
  330.           gint        count)
  331. {
  332.   gchar *str;
  333.   gint   i;
  334.  
  335.   for (i = 0; i < count; i++)
  336.     {
  337.       if (!wire_read_string (channel, &str, 1))
  338.     return FALSE;
  339.       sscanf (str, "%le", &data[i]);
  340.       g_free (str);
  341.     }
  342.  
  343.   return TRUE;
  344. }
  345.  
  346. gboolean
  347. wire_read_string (GIOChannel  *channel,
  348.           gchar      **data,
  349.           gint         count)
  350. {
  351.   guint32 tmp;
  352.   gint    i;
  353.  
  354.   for (i = 0; i < count; i++)
  355.     {
  356.       if (!wire_read_int32 (channel, &tmp, 1))
  357.     return FALSE;
  358.  
  359.       if (tmp > 0)
  360.     {
  361.       data[i] = g_new (gchar, tmp);
  362.       if (!wire_read_int8 (channel, (guint8*) data[i], tmp))
  363.         {
  364.           g_free (data[i]);
  365.           return FALSE;
  366.         }
  367.     }
  368.       else
  369.     {
  370.       data[i] = NULL;
  371.     }
  372.     }
  373.  
  374.   return TRUE;
  375. }
  376.  
  377. gboolean
  378. wire_write_int32 (GIOChannel *channel,
  379.           guint32    *data,
  380.           gint        count)
  381. {
  382.   guint32 tmp;
  383.   gint    i;
  384.  
  385.   if (count > 0)
  386.     {
  387.       for (i = 0; i < count; i++)
  388.     {
  389.       tmp = g_htonl (data[i]);
  390.       if (!wire_write_int8 (channel, (guint8*) &tmp, 4))
  391.         return FALSE;
  392.     }
  393.     }
  394.  
  395.   return TRUE;
  396. }
  397.  
  398. gboolean
  399. wire_write_int16 (GIOChannel *channel,
  400.           guint16    *data,
  401.           gint        count)
  402. {
  403.   guint16 tmp;
  404.   gint    i;
  405.  
  406.   if (count > 0)
  407.     {
  408.       for (i = 0; i < count; i++)
  409.     {
  410.       tmp = g_htons (data[i]);
  411.       if (!wire_write_int8 (channel, (guint8*) &tmp, 2))
  412.         return FALSE;
  413.     }
  414.     }
  415.  
  416.   return TRUE;
  417. }
  418.  
  419. gboolean
  420. wire_write_int8 (GIOChannel *channel,
  421.          guint8     *data,
  422.          gint        count)
  423. {
  424.   return wire_write (channel, data, count);
  425. }
  426.  
  427. gboolean
  428. wire_write_double (GIOChannel *channel,
  429.            gdouble    *data,
  430.            gint        count)
  431. {
  432.   gchar *t;
  433.   gchar  buf[128];
  434.   gint   i;
  435.  
  436.   t = buf;
  437.   for (i = 0; i < count; i++)
  438.     {
  439.       g_snprintf (buf, sizeof (buf), "%0.50e", data[i]);
  440.       if (!wire_write_string (channel, &t, 1))
  441.     return FALSE;
  442.     }
  443.  
  444.   return TRUE;
  445. }
  446.  
  447. gboolean
  448. wire_write_string (GIOChannel  *channel,
  449.            gchar      **data,
  450.            gint         count)
  451. {
  452.   guint32 tmp;
  453.   gint    i;
  454.  
  455.   for (i = 0; i < count; i++)
  456.     {
  457.       if (data[i])
  458.     tmp = strlen (data[i]) + 1;
  459.       else
  460.     tmp = 0;
  461.  
  462.       if (!wire_write_int32 (channel, &tmp, 1))
  463.     return FALSE;
  464.       if (tmp > 0)
  465.     if (!wire_write_int8 (channel, (guint8*) data[i], tmp))
  466.       return FALSE;
  467.     }
  468.  
  469.   return TRUE;
  470. }
  471.  
  472. static void
  473. wire_init (void)
  474. {
  475.   if (!wire_ht)
  476.     {
  477.       wire_ht = g_hash_table_new ((GHashFunc) wire_hash,
  478.                   (GCompareFunc) wire_compare);
  479.     }
  480. }
  481.  
  482. static guint
  483. wire_hash (guint32 *key)
  484. {
  485.   return *key;
  486. }
  487.  
  488. static gboolean
  489. wire_compare (guint32 *a,
  490.           guint32 *b)
  491. {
  492.   return (*a == *b);
  493. }
  494.