[giv] Initial introduction of remote control of giv through jsonrpc.



commit b3804807db3224346978be393053abf160c03190
Author: Dov Grobgeld <dov grobgeld gmail com>
Date:   Sun Dec 25 23:19:14 2011 +0200

    Initial introduction of remote control of giv through jsonrpc.

 SConstruct                                         |    5 +-
 configure.in                                       |    2 +-
 giv.wine.nsi.in                                    |    1 +
 src/GivStringArray.c                               |    9 +-
 src/SConscript                                     |    2 +-
 src/giv-win.gob                                    |  155 ++-
 src/givimage.c                                     |   49 +-
 src/givregex.c                                     | 2754 --------------------
 src/givregex.h                                     |  243 --
 src/glib-jsonrpc/SConscript                        |    6 +
 src/glib-jsonrpc/glib-jsonrpc-client.c             |  153 ++
 src/glib-jsonrpc/glib-jsonrpc-client.h             |   48 +
 src/glib-jsonrpc/glib-jsonrpc-json.c               |   90 +
 src/glib-jsonrpc/glib-jsonrpc-json.h               |   44 +
 src/glib-jsonrpc/glib-jsonrpc-server.c             |  377 +++
 src/glib-jsonrpc/glib-jsonrpc-server.h             |   70 +
 .../dcmtk/config/include/dcmtk/config/cfwin32.h    |    1 -
 src/plugins/npy.c                                  |   36 +-
 18 files changed, 986 insertions(+), 3059 deletions(-)
---
diff --git a/SConstruct b/SConstruct
index a34e320..4f9ab96 100644
--- a/SConstruct
+++ b/SConstruct
@@ -120,12 +120,13 @@ env.Append(CPPPATH=[],
            LIBPATH=["#/src/agg",
                     "#/src/plis",
                     "#/src/gtkimageviewer",
+                    "#/src/glib-jsonrpc",
                     ],
            RPATH=["agg/src"],
-           LIBS=['gtkimageviewer_local', 'agg']
+           LIBS=['gtkimageviewer_local', 'agg', 'glib-jsonrpc_local']
            )
 
-env.ParseConfig("${PKGCONFIG} --cflags --libs gtk+-2.0 glib-2.0")
+env.ParseConfig("${PKGCONFIG} --cflags --libs gtk+-2.0 glib-2.0 json-glib-1.0 gio-2.0")
 
 SConscript(['src/SConscript',
             'doc/SConscript',
diff --git a/configure.in b/configure.in
index e384961..1cab855 100644
--- a/configure.in
+++ b/configure.in
@@ -5,7 +5,7 @@ AM_CONFIG_HEADER(config.h)
 PACKAGE=givwidget
 GIVWIDGET_API_VERSION=2.0
 
-AM_INIT_AUTOMAKE(giv, 0.9.20)
+AM_INIT_AUTOMAKE(giv, 0.9.21beta)
 
 dnl Use libtool to get shared libraries
 LT_PREREQ
diff --git a/giv.wine.nsi.in b/giv.wine.nsi.in
index 48fe6f2..c11bd0b 100644
--- a/giv.wine.nsi.in
+++ b/giv.wine.nsi.in
@@ -60,6 +60,7 @@ File \usr\i686-w64-mingw32\sys-root\mingw\bin\libjpeg*.dll
 File \usr\i686-w64-mingw32\sys-root\mingw\bin\libpixman-1-0.dll
 File \usr\i686-w64-mingw32\sys-root\mingw\bin\libfontconfig*.dll
 File \usr\i686-w64-mingw32\sys-root\mingw\bin\libfreetype*.dll
+File \usr\local\mingw32\bin\libjson-glib-1.0-0.dll
 File \usr\i686-w64-mingw32\sys-root\mingw\bin\gdk-pixbuf-query-loaders.exe
 
 SetOutPath $INSTDIR\etc
diff --git a/src/GivStringArray.c b/src/GivStringArray.c
index 428aece..8a8db0e 100644
--- a/src/GivStringArray.c
+++ b/src/GivStringArray.c
@@ -6,7 +6,6 @@
 //----------------------------------------------------------------------
 
 #include "GivStringArray.h"
-#include "givregex.h"
 
 void giv_string_array_free(GPtrArray *string_array)
 {
@@ -21,10 +20,10 @@ int giv_string_array_find(GPtrArray* string_array,
 {
     int i=0;
     for (i =0; i<string_array->len; i++) {
-        if (giv_regex_match_simple(pattern,
-                                   (gchar*)g_ptr_array_index(string_array, i),
-                                   GIV_REGEX_CASELESS,
-                                   (GivRegexMatchFlags)0)) {
+        if (g_regex_match_simple(pattern,
+                                 (gchar*)g_ptr_array_index(string_array, i),
+                                 G_REGEX_CASELESS,
+                                 (GRegexMatchFlags)0)) {
             return i;
         }
     }
diff --git a/src/SConscript b/src/SConscript
index ae862c0..29a1113 100644
--- a/src/SConscript
+++ b/src/SConscript
@@ -23,7 +23,6 @@ def file2c(env, target, source):
     inp.close()
 
 src_giv_image = ['givimage.c',
-                 "givregex.c",
                  'givplugin.c',
                  ]
 
@@ -135,6 +134,7 @@ SConscript(['agg/SConscript',
             'plis/SConscript',
             'gtkimageviewer/SConscript',
             'plugins/SConscript',
+            'glib-jsonrpc/SConscript',
 #            'pcre/SConscript',
             ],
            exports='env')
diff --git a/src/giv-win.gob b/src/giv-win.gob
index 070e7cd..293cd30 100644
--- a/src/giv-win.gob
+++ b/src/giv-win.gob
@@ -13,6 +13,8 @@ requires 2.0.0
 #include "giv-data.h"
 #include "plis/plis.h"
 #include "givimage.h"
+#include "glib-jsonrpc/glib-jsonrpc-server.h"
+#include "glib-jsonrpc/glib-jsonrpc-client.h"
 %}
 
 %{
@@ -44,10 +46,10 @@ requires 2.0.0
 #include "GivStringArray.h"
 #include "time.h"
 #include <sys/stat.h>
-#include "givregex.h"
 #include "giv-calibrate-dialog.h"
 #include "giv-settings.h"
 #include "giv-settings-editor.h"
+#include "glib-jsonrpc/glib-jsonrpc-json.h"
 
 using namespace std;
 using namespace plis;
@@ -87,6 +89,8 @@ enum
     DND_TEXT_URI_LIST
 };
 
+const int GIV_DEFAULT_PORT = 8222;
+
 /* Target types for dropping into the file list */
 static const GtkTargetEntry file_list_dest_targets[] = {
     { (gchar*)"text/uri-list", 0, DND_TEXT_URI_LIST }
@@ -239,6 +243,7 @@ static void
 my_lasso_draw_rectangle(cairo_t *cr,
                         DovtkLassoContext context,
                         gpointer user_data);
+static void create_remote_commands(GivWin *self);
 
 // The following tables contain all the actions for both the menubar
 // and the popup menus.
@@ -546,6 +551,7 @@ class Giv:Win from Gtk:Window
     private gchar *pixelsize_unit = NULL;
     private double last_measure_distance_in_pixels = -1;
     private GivSettings *giv_settings = NULL destroy { g_object_unref(giv_settings); };
+    private GLibJsonRpcServer *jsonrpc_server;
 
     public GtkWidget *
     new (int argc, char *argv[])
@@ -563,6 +569,9 @@ class Giv:Win from Gtk:Window
         double shift_x = 0;
         double shift_y = 0;
         char *export_filename = NULL;
+        int giv_port = GIV_DEFAULT_PORT;
+        gboolean do_remote = FALSE;
+        const gchar *giv_host = "localhost"; // Currently fixed
 
         // Parse command line
         while(argp < argc && argv[argp][0] == '-') {
@@ -605,19 +614,64 @@ class Giv:Win from Gtk:Window
                 shift_y = atof(argv[argp++]);
                 continue;
             }
-            CASE("-export") {
+            CASE("-export")
+              {
                 export_filename = argv[argp++];
                 continue;
-            }
+              }
+            CASE("-port")
+              {
+                giv_port = atoi(argv[argp++]);
+                continue;
+              }
+            CASE("-remote")
+              {
+                do_remote = TRUE;
+                continue;
+              }
 
             printf("Unknown option %s!\n", S_);
             exit(-1);
         }
 
+        // Load an image into a remote instance of giv. If this fails,
+        // then normal loading should take place.
+        if (do_remote)
+          {
+            GLibJsonRpcClient *client = glib_jsonrpc_client_new(giv_host,
+                                                                giv_port);
+
+            if (client)
+              {
+                // assume a single image
+                JsonNode *params = glib_jsonrpc_json_csv_to_json_array(argv[argp++]);
+                JsonNode *response = NULL;
+                int status = glib_jsonrpc_client_call(client,
+                                                      "load_file",
+                                                      params,
+                                                      // output
+                                                      &response);
+                json_node_free(params);
+                if (response)
+                  json_node_free(response);
+                if (status==0)
+                  exit(0);
+              }
+
+            // Fall through and run giv normally!
+          }
+            
+
         selfp->cb_names = g_ptr_array_new();
         selfp->filename_list = g_ptr_array_new();
         selfp->pixelsize_unit = g_strdup("");
 
+        selfp->jsonrpc_server = glib_jsonrpc_server_new(giv_port);
+
+        // Silently ignore failed server
+        if (selfp->jsonrpc_server)
+          create_remote_commands(self);
+
         gchar *settings_file = g_strdup_printf("%s/.config/Giv/giv.conf", g_get_home_dir());
         selfp->giv_settings = GIV_SETTINGS(giv_settings_new(settings_file));
 
@@ -3727,10 +3781,10 @@ bool is_file_ext(const char *filename,
 {
     gchar *pattern = g_strdup_printf("\\.(%s)$",
                                      ext_match);
-    bool res = giv_regex_match_simple(pattern,
-                                      filename,
-                                      GIV_REGEX_CASELESS,
-                                      GivRegexMatchFlags(0));
+    bool res = g_regex_match_simple(pattern,
+                                    filename,
+                                    G_REGEX_CASELESS,
+                                    GRegexMatchFlags(0));
     g_free(pattern);
     return res;
 }
@@ -4001,9 +4055,8 @@ my_lasso_draw_rectangle(cairo_t *cr,
         min_y = end_y;
 
     cairo_rectangle(cr, min_x, min_y,
-                    fabs(end_x-start_x), abs(end_y-start_y));
+                    fabs(end_x-start_x), fabs(end_y-start_y));
 
-    double margin = 0;
     if (context == DOVTK_LASSO_CONTEXT_PAINT)
         cairo_set_source_rgba(cr, 1,0,0,0.6);
     else {
@@ -4017,5 +4070,89 @@ my_lasso_draw_rectangle(cairo_t *cr,
     cairo_stroke(cr);
 }
 
+static int cmd_ping(GLibJsonRpcServer *server,
+                    const char *method,
+                    JsonNode *params,
+                    JsonNode **response,
+                    gpointer user_data)
+{
+  printf("pong!\n");
+
+  *response = json_node_new(JSON_NODE_VALUE);
+  json_node_set_string(*response, "pong");
+  
+  return 0;
+}
+
+static int cmd_load_file(GLibJsonRpcServer *server,
+                         const char *method,
+                         JsonNode *params,
+                         JsonNode **response,
+                         gpointer user_data)
+{
+  GivWin *self = (GivWin*)user_data;
+  *response = json_node_new(JSON_NODE_VALUE);
+  JsonReader *reader = json_reader_new(params);
+  
+  // Assume array at the moment
+  json_reader_read_element(reader, 0);
+  const char *filename = json_reader_get_string_value(reader);
+
+  // The following ugly code is the same as is used in the
+  // open response callback. It should be joined!
+  char *basename = g_path_get_basename(filename);
+  giv_win_read_dir_into_filename_list(self, filename);
+  selfp->filename_list_index = -1;
+  for (int i=0; i<(int)selfp->filename_list->len; i++)
+    {
+      GPtrArray *fn_list = (GPtrArray*)g_ptr_array_index(selfp->filename_list,
+                                                         i);
+      if (g_str_has_suffix((const gchar*)g_ptr_array_index(fn_list, 0),
+                           basename)) {
+        selfp->filename_list_index = i;
+        break;
+      }
+    }
+  g_free(basename);
+  if (selfp->filename_list->len
+      && selfp->filename_list_index < 0) {
+    GPtrArray *fn_list = (GPtrArray*)g_ptr_array_index(selfp->filename_list,
+                                                       0);
+    
+    giv_win_load_file(self, (gchar*)g_ptr_array_index(fn_list, 0));
+    selfp->idle_index = 0;
+    selfp->idle_handle = g_idle_add(cb_load_image_when_idle,
+                                    self);
+  }
+  else
+  {
+    selfp->idle_index = selfp->filename_list_index;
+    selfp->idle_handle = g_idle_add(cb_load_image_when_idle,
+                                    self);
+  }
+
+  if (last_image_path)
+    g_free(last_image_path);
+  last_image_path = strdup(filename);
+
+  g_object_unref(reader);
+  json_node_set_string(*response, "Ok");
+  
+  return 0;
+}
+
+// Define remote commands
+static void create_remote_commands(GivWin *self)
+{
+  glib_jsonrpc_server_register_command(selfp->jsonrpc_server,
+                                       "ping",
+                                       cmd_ping,
+                                       self);
+  glib_jsonrpc_server_register_command(selfp->jsonrpc_server,
+                                       "load_file",
+                                       cmd_load_file,
+                                       self);
+}
+
 %}
 
diff --git a/src/givimage.c b/src/givimage.c
index eadc3cb..d355788 100644
--- a/src/givimage.c
+++ b/src/givimage.c
@@ -10,7 +10,6 @@
 #include "givimage.h"
 #include "givplugin.h"
 #include <gdk-pixbuf/gdk-pixbuf.h>
-#include "givregex.h"
 
 #define GIV_IMAGE_ERROR g_spawn_error_quark ()
 
@@ -88,14 +87,14 @@ GivImage *giv_image_new_from_file(const char *filename,
     }
     else if (*error) {
     }
-    else if (giv_regex_match_simple("png"
+    else if (g_regex_match_simple("png"
                                   "|jpe?g"
                                   "|p[bgp]m"
                                   "|bmp"
                                   "|svg"
                                   ,
                                   extension,
-                                  GIV_REGEX_CASELESS,
+                                  G_REGEX_CASELESS,
                                   0)) {
         GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(filename,
                                                      error);
@@ -166,17 +165,17 @@ GivImage *giv_image_new_from_file(const char *filename,
     }
     // Space separated value. A simple text format parser. Still
     // doesn't support comments. Fix this!
-    else if (giv_regex_match_simple("ssv",
+    else if (g_regex_match_simple("ssv",
                                   extension,
-                                  GIV_REGEX_CASELESS,
+                                  G_REGEX_CASELESS,
                                   0)) {
         gchar *ssv_string;
         guint length;
         
         g_file_get_contents(filename, &ssv_string, &length, error);
-        gchar **lines = giv_regex_split_simple("\r?\n",
-                                               ssv_string,
-                                               0, 0);
+        gchar **lines = g_regex_split_simple("\r?\n",
+                                             ssv_string,
+                                             0, 0);
         int num_lines = g_strv_length(lines);
 
         // Count lines while skipping comments
@@ -203,9 +202,9 @@ GivImage *giv_image_new_from_file(const char *filename,
             // skip whitespace
             while(*p == ' ')
                 p++;
-            gchar **fields = giv_regex_split_simple("(?:,|;|\\s)\\s*",
-                                                    p,
-                                                    0,0);
+            gchar **fields = g_regex_split_simple("(?:,|;|\\s)\\s*",
+                                                  p,
+                                                  0,0);
             if (row_idx==0) {
                 width = g_strv_length(fields);
                 img = giv_image_new(GIVIMAGE_FLOAT,
@@ -222,10 +221,10 @@ GivImage *giv_image_new_from_file(const char *filename,
         g_free(ssv_string);
     }
 #if 0
-    else if (giv_regex_match_simple("npy",
-                                    extension,
-                                    GIV_REGEX_CASELESS,
-                                    0)) {
+    else if (g_regex_match_simple("npy",
+                                  extension,
+                                  G_REGEX_CASELESS,
+                                  0)) {
         gchar *npy_string;
         guint length;
         
@@ -239,7 +238,7 @@ GivImage *giv_image_new_from_file(const char *filename,
 
         // Use regex to parse the header. Should update this to allow
         // user attributes.
-        GivRegex *regex = giv_regex_new ("^\\{\\s*"
+        GivRegex *regex = g_regex_new ("^\\{\\s*"
                                        "'descr':\\s*\\'(.*?)\\'\\s*,\\s*"
                                        "'fortran_order':\\s*(\\w+)\\s*,\\s*"
                                        "'shape':\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\),?\\s*"
@@ -249,13 +248,13 @@ GivImage *giv_image_new_from_file(const char *filename,
             exit(-1);
         }
         GivMatchInfo *match_info = NULL;
-        gboolean is_match = giv_regex_match_full(regex,
-                                                 npy_string+10,
-                                                 header_len,
-                                                 0,
-                                                 (GivRegexMatchFlags)0,
-                                                 &match_info,
-                                                 error);
+        gboolean is_match = g_regex_match_full(regex,
+                                               npy_string+10,
+                                               header_len,
+                                               0,
+                                               (GRegexMatchFlags)0,
+                                               &match_info,
+                                               error);
         gboolean is_supported_type = TRUE;
         gboolean is_fortran_type = FALSE;
         gint width=-1, height = -1;
@@ -293,8 +292,8 @@ GivImage *giv_image_new_from_file(const char *filename,
             g_free(match_string);
         }
 
-        giv_regex_unref(regex);
-        giv_match_info_free(match_info);
+        g_regex_unref(regex);
+        g_match_info_free(match_info);
         
         if  (!is_match
              || !header_ok
diff --git a/src/glib-jsonrpc/SConscript b/src/glib-jsonrpc/SConscript
new file mode 100644
index 0000000..ad65c7a
--- /dev/null
+++ b/src/glib-jsonrpc/SConscript
@@ -0,0 +1,6 @@
+Import('env')
+
+env.Library("glib-jsonrpc_local",
+            ["glib-jsonrpc-json.c",
+             "glib-jsonrpc-server.c",
+             "glib-jsonrpc-client.c"])
diff --git a/src/glib-jsonrpc/glib-jsonrpc-client.c b/src/glib-jsonrpc/glib-jsonrpc-client.c
new file mode 100644
index 0000000..c5ba4c6
--- /dev/null
+++ b/src/glib-jsonrpc/glib-jsonrpc-client.c
@@ -0,0 +1,153 @@
+/* GlibJsonRpcClient
+ * glib-jsonrpc-server.h: A Json RCP client in glib.
+ *
+ * Copyright (C) 2011 Dov Grobgeld <dov grobgeld gmail com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "glib-jsonrpc-client.h"
+#include "glib-jsonrpc-json.h"
+
+typedef struct {
+  GLibJsonRpcClient parent;
+
+  GSocketClient *client;
+  GSocketConnection *connection;
+} GLibJsonRpcClientPrivate; 
+
+GLibJsonRpcClient *glib_jsonrpc_client_new(const char *hostname, int port)
+{
+  GLibJsonRpcClientPrivate *selfp = g_new0(GLibJsonRpcClientPrivate, 1);
+
+  GResolver *resolver = g_resolver_get_default();
+  GList *addresses = g_resolver_lookup_by_name(resolver,hostname,NULL,NULL);
+  if (!addresses)
+    {
+      glib_jsonrpc_client_free((GLibJsonRpcClient*)selfp);
+      return NULL;
+    }
+  GInetAddress *address = (GInetAddress*)g_list_nth_data(addresses, 0);
+
+  selfp->client = g_socket_client_new();
+  GSocketAddress *sockaddr = g_inet_socket_address_new(address, port);
+  selfp->connection = g_socket_client_connect (selfp->client, G_SOCKET_CONNECTABLE(sockaddr), NULL, NULL);
+  g_resolver_free_addresses(addresses);
+
+  if (!selfp->connection)
+    {
+      glib_jsonrpc_client_free((GLibJsonRpcClient*)selfp);
+      return NULL;
+    }
+    
+  return (GLibJsonRpcClient*)selfp;
+}
+
+void glib_jsonrpc_client_free(GLibJsonRpcClient *client)
+{
+  GLibJsonRpcClientPrivate *selfp = (GLibJsonRpcClientPrivate*)client;
+  if (selfp->connection)
+    g_object_unref(G_OBJECT(selfp->connection));
+  if (selfp->client)
+    g_object_unref(G_OBJECT(selfp->client));
+  g_free(client);
+}
+
+int glib_jsonrpc_client_call(GLibJsonRpcClient *client,
+                             const char *method,
+                             JsonNode *params,
+                             // output
+                             JsonNode **response)
+{
+  GLibJsonRpcClientPrivate *selfp = (GLibJsonRpcClientPrivate*)client;
+  GOutputStream *out = g_io_stream_get_output_stream (G_IO_STREAM (selfp->connection));
+  GInputStream *in = g_io_stream_get_input_stream (G_IO_STREAM (selfp->connection));
+
+  GString *http_string = g_string_new("");
+  
+  JsonBuilder *builder = json_builder_new ();
+  json_builder_begin_object (builder);
+  json_builder_set_member_name (builder, "jsonrpc");
+  json_builder_add_string_value (builder, "2.0");
+  json_builder_set_member_name (builder, "method");
+  json_builder_add_string_value (builder, method);
+  json_builder_set_member_name (builder, "params");
+  json_builder_add_value(builder,params);
+  json_builder_set_member_name (builder, "id");
+  json_builder_add_int_value(builder,42);
+  json_builder_end_object (builder);
+  JsonNode *node = json_builder_get_root(builder);
+  char *content_string = glib_jsonrpc_json_to_string(node);
+  if (!content_string)
+    return -1;
+  g_object_unref(builder);
+
+  g_string_append_printf(http_string,
+                         "POST / HTTP/1.1\r\n"
+                         "User-Agent: GlibJsonRpcClient\r\n"
+                         "Host: foo\r\n"
+                         "Content-Type: Content-type: application/x-www-form-urlencoded\r\n"
+                         "Content-Length: %d\r\n"
+                         "\r\n"
+                         ,
+                         strlen(content_string));
+
+  g_string_append(http_string, content_string);
+  g_free(content_string);
+
+  g_output_stream_write (out,
+                         http_string->str,
+                         http_string->len,
+                         NULL,NULL);
+  g_string_free(http_string, TRUE);
+
+  // Read the response
+  char buffer[1024];
+  gssize size;
+  gboolean skip_header = TRUE;
+  GString *json_string = g_string_new("");
+  JsonParser *parser = json_parser_new();
+  GError *error = NULL;
+  while (0 < (size = g_input_stream_read (in, buffer,
+                                          sizeof buffer, NULL, NULL)))
+    {
+      int header_size = 0;
+      
+      if (skip_header)
+        {
+          gchar *head_end = g_strstr_len(buffer, size,
+                                         "\r\n\r\n");
+          if (head_end > 0)
+              header_size = head_end - buffer;
+          else
+              continue;
+        }
+      
+      g_string_append_len(json_string, buffer+header_size, size-header_size);
+      if (json_parser_load_from_data(parser, json_string->str, -1, &error))
+          break;
+      else
+          g_error_free(error);
+    }
+  JsonNode *root_object = json_parser_get_root(parser);
+  *response = json_node_copy(json_object_get_member(json_node_get_object(root_object), "result"));
+  g_object_unref(parser);
+
+  return 0;
+}
diff --git a/src/glib-jsonrpc/glib-jsonrpc-client.h b/src/glib-jsonrpc/glib-jsonrpc-client.h
new file mode 100644
index 0000000..f69f10c
--- /dev/null
+++ b/src/glib-jsonrpc/glib-jsonrpc-client.h
@@ -0,0 +1,48 @@
+/* GlibJsonRpcClient
+ * glib-jsonrpc-server.h: A Json RCP client in glib.
+ *
+ * Copyright (C) 2011 Dov Grobgeld <dov grobgeld gmail com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+#ifndef GLIB_JSONRPC_CLIENT_H
+#define GLIB_JSONRPC_CLIENT_H
+
+#include "json-glib/json-glib.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+} GLibJsonRpcClient; 
+
+GLibJsonRpcClient *glib_jsonrpc_client_new(const char *host, int port);
+void glib_jsonrpc_client_free(GLibJsonRpcClient *client);
+
+int glib_jsonrpc_client_call(GLibJsonRpcClient *client,
+                             const char *method,
+                             JsonNode *params,
+                             // output
+                             JsonNode **response);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GLIB_JSONRPC_CLIENT */
diff --git a/src/glib-jsonrpc/glib-jsonrpc-json.c b/src/glib-jsonrpc/glib-jsonrpc-json.c
new file mode 100644
index 0000000..ee62bfd
--- /dev/null
+++ b/src/glib-jsonrpc/glib-jsonrpc-json.c
@@ -0,0 +1,90 @@
+/* test-glib-jsonrpc-json.c: Utilities for the GlibJsonRPC library.
+ *
+ * Copyright (C) 2011 Dov Grobgeld <dov grobgeld gmail com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+#include <stdio.h>
+#include "glib-jsonrpc-json.h"
+
+/** 
+ * Utility function for turning a json node into a string.
+ */
+gchar *glib_jsonrpc_json_to_string(JsonNode *node)
+{
+  // Serialize response into content_string
+  JsonGenerator *gen = json_generator_new ();
+  gsize len;
+  json_generator_set_root (gen, node);
+  gchar *json_string = json_generator_to_data(gen, &len);
+  g_object_unref (gen);
+  return json_string;
+}
+
+// Parse a json object, a json object stripped of {} or an json array
+// stripped of [] into a JsonNode.
+JsonNode *glib_jsonrpc_json_string_to_json_node(const gchar *str)
+{
+  JsonParser *parser = json_parser_new();
+  GError *error;
+
+  // First try to parse the string
+  if (!json_parser_load_from_data(parser, str, -1, &error))
+    {
+      // Wrap it in a { } pair and try again.
+      g_error_free(error); error = NULL;
+      GString *j_str = g_string_new("");
+      g_string_append_printf(j_str, "{%s}", str);
+
+      // Try parsing it as an object
+      if (!json_parser_load_from_data(parser, j_str->str, -1, &error))
+        {
+          // Still fail, try to parse it as an array
+          g_string_free(j_str, TRUE);
+          g_string_append_printf(j_str, "[%s]", str);
+          if (!json_parser_load_from_data(parser, j_str->str, -1, &error))
+            {
+              // That's it, we give up.
+              g_object_unref(parser);
+              return NULL;
+            }
+        }
+    }
+
+  JsonNode *node = json_node_copy(json_parser_get_root(parser));
+  g_object_unref(parser);
+  return node;
+}
+
+JsonNode *glib_jsonrpc_json_csv_to_json_array(const gchar *str)
+{
+  gchar **str_list = g_strsplit(str, ",", -1);
+
+  JsonArray *array = json_array_new();
+  gchar **p = str_list;
+  while(*p)
+    {
+      JsonNode *node = json_node_new(JSON_NODE_VALUE);
+      json_node_set_string(node, *p);
+      json_array_add_element(array,node);
+      p++;
+    }
+  JsonNode *node = json_node_new(JSON_NODE_ARRAY);
+  json_node_take_array(node, array);
+  g_strfreev(str_list);
+  return node;
+}
diff --git a/src/glib-jsonrpc/glib-jsonrpc-json.h b/src/glib-jsonrpc/glib-jsonrpc-json.h
new file mode 100644
index 0000000..3338324
--- /dev/null
+++ b/src/glib-jsonrpc/glib-jsonrpc-json.h
@@ -0,0 +1,44 @@
+/* test-glib-jsonrpc-json.c: Utilities for the GlibJsonRPC library.
+ *
+ * Copyright (C) 2011 Dov Grobgeld <dov grobgeld gmail com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+#ifndef GLIB_JSONRPC_JSON_H
+#define GLIB_JSONRPC_JSON_H
+
+#include <json-glib/json-glib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Allocate and convert a json node to a string
+gchar *glib_jsonrpc_json_to_string(JsonNode *node);
+
+// Convenience function for turning a string list into a newly allocated json array
+JsonNode *glib_jsonrpc_json_csv_to_json_array(const char *string);
+
+// A general json parser
+JsonNode *glib_jsonrpc_json_string_to_json_node(const gchar *str);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GLIB_JSONRPC_JSON */
diff --git a/src/glib-jsonrpc/glib-jsonrpc-server.c b/src/glib-jsonrpc/glib-jsonrpc-server.c
new file mode 100644
index 0000000..bf26ac7
--- /dev/null
+++ b/src/glib-jsonrpc/glib-jsonrpc-server.c
@@ -0,0 +1,377 @@
+/* GlibJsonRpcServer
+ * glib-jsonrpc-server.c: A Json RCP server in glib.
+ *
+ * Copyright (C) 2011 Dov Grobgeld <dov grobgeld gmail com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include "glib-jsonrpc-server.h"
+
+typedef struct {
+  GLibJsonRpcServer server; 
+
+  GSocketService *service;
+  GHashTable *command_hash;
+  GString *req_string;
+  GMutex *mutex;
+  JsonNode *reply;
+  gboolean allow_non_loopback_connections;
+
+  // This is set whenever an asynchronous command is being run. Only
+  // one asynchronous command can be run at a time.
+  gboolean async_busy;
+} GLibJsonRpcServerPrivate;
+
+typedef struct {
+  GLibJsonRpcCommandCallback *callback;
+  GLibJsonRpcCommandAsyncCallback *async_callback;
+  gpointer user_data;
+  JsonNode *reply;
+} command_hash_value_t;
+
+
+static JsonNode* create_fault_response(int error_num, const char *message, int id)
+{
+  JsonBuilder *builder = json_builder_new ();
+
+  json_builder_begin_object (builder);
+  json_builder_set_member_name (builder, "jsonrpc");
+  json_builder_add_string_value (builder, "2.0");
+  json_builder_set_member_name (builder, "error");
+  json_builder_begin_object(builder);
+  json_builder_set_member_name (builder, "code");
+  json_builder_add_int_value(builder, error_num);
+  json_builder_set_member_name (builder, "message");
+  json_builder_add_string_value (builder, message);
+  json_builder_end_object (builder);
+  json_builder_set_member_name(builder, "id");
+  if (id < 0)
+    json_builder_add_null_value(builder);
+  else
+    json_builder_add_int_value(builder, id);
+  json_builder_end_object (builder);
+  JsonNode *node = json_node_copy(json_builder_get_root (builder));
+  
+  g_object_unref(builder);
+  return node;
+}
+    
+// Creates a response. Transfers ownership of reply.
+static JsonNode* create_response(JsonNode *reply, int id)
+{
+  JsonBuilder *builder = json_builder_new ();
+
+  // {"jsonrpc": "2.0", "result": 19, "id": 1}
+  json_builder_begin_object (builder);
+  json_builder_set_member_name (builder, "jsonrpc");
+  json_builder_add_string_value (builder, "2.0");
+  
+  json_builder_set_member_name (builder, "id");
+  json_builder_add_int_value (builder, id);
+
+  if (reply)
+    {
+      json_builder_set_member_name (builder, "result");
+      json_builder_add_value (builder, reply);
+      json_builder_end_object (builder);
+    }
+  else
+    {
+      // default "ok" message
+      json_builder_set_member_name (builder, "result");
+      json_builder_add_string_value (builder, "ok");
+      json_builder_end_object (builder);
+    }
+  
+  JsonNode *node = json_node_copy(json_builder_get_root (builder));
+
+  g_object_unref(builder);
+  return node;
+}
+    
+
+static gboolean
+handler (GThreadedSocketService *service,
+         GSocketConnection      *connection,
+         GSocketListener        *listener,
+         gpointer                user_data)
+{
+  GLibJsonRpcServerPrivate *jsonrpc_server = (GLibJsonRpcServerPrivate*)user_data;
+  GError *error = NULL;
+  
+  // Check if it is a local connection. - This doesn't work!
+  GSocketAddress *sockaddr
+    = g_socket_connection_get_remote_address(connection,
+                                             &error);
+  GInetAddress *addr = g_inet_socket_address_get_address(G_INET_SOCKET_ADDRESS(sockaddr));
+
+  if (!jsonrpc_server->allow_non_loopback_connections)
+    {
+#if 0
+      // Why doesn't this work?
+      if (!g_inet_address_get_is_loopback(addr))
+        return TRUE; // just fail
+#endif
+      
+      gchar *addr_string = g_inet_address_to_string(addr);
+      gboolean is_local = g_strstr_len(addr_string, -1, "127.0.0.1") != NULL;
+      g_free(addr_string);
+      if (!is_local) 
+        return TRUE; // silently fail
+    }
+
+  GOutputStream *out;
+  GInputStream *in;
+  char buffer[1024];
+  gssize size;
+
+  out = g_io_stream_get_output_stream (G_IO_STREAM (connection));
+  in = g_io_stream_get_input_stream (G_IO_STREAM (connection));
+
+  // Read the http header
+  gboolean skip_header = TRUE;
+  JsonParser *parser = json_parser_new();
+  GString *json_string = g_string_new("");
+  while (0 < (size = g_input_stream_read (in, buffer,
+                                          sizeof buffer, NULL, NULL)))
+    {
+      int header_size = 0;
+      
+      if (skip_header)
+        {
+          gchar *head_end = g_strstr_len(buffer, size,
+                                         "\r\n\r\n");
+          if (head_end > 0)
+            header_size = head_end - buffer;
+          else
+            continue;
+        }
+      
+      g_string_append_len(json_string, buffer+header_size, size-header_size);
+      if (json_parser_load_from_data(parser, json_string->str, -1, &error))
+        break;
+      else
+        g_error_free(error);
+    }
+
+  // TBD:   raise error if there was a syntax error
+  g_string_free(json_string, TRUE);
+
+  // Get params object without the reader 
+  JsonNode *root = json_parser_get_root(parser);
+  JsonObject *root_object = json_node_get_object(root);
+  JsonNode* params = json_object_get_member(root_object, "params");
+
+  // Use reader for method and id
+  JsonReader *reader = json_reader_new(json_parser_get_root(parser));
+  json_reader_read_member (reader, "method");
+  const gchar *method = json_reader_get_string_value (reader);
+  json_reader_end_member (reader);
+  
+  json_reader_read_member (reader, "id");
+  gint64 id = json_reader_get_int_value(reader);
+  json_reader_end_member (reader);
+
+  // Build the response which is either a response object or an error object
+  JsonNode *response = NULL;
+  
+  /* Call the callback */
+  command_hash_value_t *command_val = NULL;
+  if (method)
+    command_val = g_hash_table_lookup(jsonrpc_server->command_hash,
+                                      method);
+  if (!command_val)
+    response = create_fault_response(-2, "No such method!",id);
+  else if (command_val->async_callback)
+    {
+      if (jsonrpc_server->async_busy)
+        response = create_fault_response(-2, "Busy!",id);
+      else
+        {
+          jsonrpc_server->async_busy = TRUE;
+          
+          // Create a secondary main loop
+          (*command_val->async_callback)((GLibJsonRpcServer*)jsonrpc_server,
+                                         method,
+                                         params,
+                                         command_val->user_data);
+          
+          // Lock on a mutex
+          g_mutex_lock(jsonrpc_server->mutex);
+          response = create_response(jsonrpc_server->reply, id);
+          jsonrpc_server->async_busy = FALSE;
+        }
+    }
+  else
+    {
+      JsonNode *reply;
+
+      int ret = (*command_val->callback)((GLibJsonRpcServer*)jsonrpc_server,
+                                         method,
+                                         params,
+                                         &reply,
+                                         command_val->user_data);
+
+      if (ret == 0)
+        response = create_response(reply,id);
+      else 
+        // For faults expect a string response containing the error
+        response = create_fault_response(ret, json_node_get_string(reply),id);
+    }
+
+  if (response)
+    {
+      GString *response_string = g_string_new("");
+  
+      // Serialize response into content_string
+      JsonGenerator *gen = json_generator_new ();
+      gsize len;
+      json_generator_set_root (gen, response);
+      json_node_free(response);
+      gchar *content_string = json_generator_to_data(gen, &len);
+      g_object_unref (gen);
+
+      g_string_append_printf(response_string,
+                             "HTTP/1.1 200 OK\r\n"
+                             "Connection: close\r\n"
+                             "Content-Length: %d\r\n"
+                             "Content-Type: text/xml\r\n"
+                             "Date: Fri, 1 Jan 2000 00:00:00 GMT\r\n"
+                             "Server: GlibJsonRPC server\r\n"
+                             "\r\n"
+                             "%s",
+                             len,
+                             content_string
+                             );
+      g_free(content_string);
+  
+      g_output_stream_write (out,
+                             response_string->str,
+                             response_string->len,
+                             NULL,NULL);
+      g_string_free(response_string, TRUE);
+    }
+
+  g_object_unref(parser);
+
+  return TRUE;
+}
+
+GLibJsonRpcServer *glib_jsonrpc_server_new(int port)
+{
+  GLibJsonRpcServerPrivate *jsonrpc_server = g_new0(GLibJsonRpcServerPrivate, 1);
+  GError *error = NULL;
+  jsonrpc_server->service = g_threaded_socket_service_new (10);
+  jsonrpc_server->async_busy = FALSE;
+  jsonrpc_server->allow_non_loopback_connections = FALSE;
+
+  if (!g_socket_listener_add_inet_port (G_SOCKET_LISTENER (jsonrpc_server->service),
+					port,
+					NULL,
+					&error))
+    {
+      // Ignore the error and return NULL
+      // g_printerr ("%s\n", error->message);
+      g_error_free(error);
+      g_free(jsonrpc_server);
+      return NULL;
+    }
+
+
+  g_signal_connect (jsonrpc_server->service, "run", G_CALLBACK (handler), jsonrpc_server);
+
+  jsonrpc_server->command_hash = g_hash_table_new(g_str_hash,
+                                                  g_str_equal);
+
+  jsonrpc_server->mutex = g_mutex_new();
+  g_mutex_lock(jsonrpc_server->mutex);
+  return (GLibJsonRpcServer*)jsonrpc_server;
+}
+
+void glib_jsonrpc_server_free(GLibJsonRpcServer *_server)
+{
+  GLibJsonRpcServerPrivate *server = (GLibJsonRpcServerPrivate *)_server;
+  
+  g_object_unref(G_OBJECT(server->service));
+  g_free(server);
+}
+
+static int
+glib_jsonrpc_server_register_command_full(GLibJsonRpcServer *_jsonrpc_server,
+                                           const gchar *command,
+                                           GLibJsonRpcCommandCallback *callback,
+                                           GLibJsonRpcCommandAsyncCallback *async_callback,
+                                           gpointer user_data)
+{
+  GLibJsonRpcServerPrivate *jsonrpc_server = (GLibJsonRpcServerPrivate*)_jsonrpc_server;
+  /* TBD - Check if command exist and override it */
+  command_hash_value_t *val = g_new0(command_hash_value_t, 1);
+  val->callback = callback;
+  val->async_callback = async_callback;
+  val->user_data = user_data;
+  g_hash_table_insert(jsonrpc_server->command_hash,
+                      g_strdup(command),
+                      val);
+
+  return 0;
+}
+
+int glib_jsonrpc_server_register_command(GLibJsonRpcServer *jsonrpc_server,
+                                          const gchar *command,
+                                          GLibJsonRpcCommandCallback *callback,
+                                          gpointer user_data)
+{
+  glib_jsonrpc_server_register_command_full(jsonrpc_server,
+                                             command,
+                                             callback,
+                                             NULL, /* async */
+                                             user_data);
+  return 0;
+}
+    
+int glib_jsonrpc_server_register_async_command(GLibJsonRpcServer *jsonrpc_server,
+                                                const gchar *command,
+                                                GLibJsonRpcCommandAsyncCallback *async_callback,
+                                                gpointer user_data)
+{
+  glib_jsonrpc_server_register_command_full(jsonrpc_server,
+                                            command,
+                                            NULL,
+                                            async_callback, /* async */
+                                            user_data);
+  return 0;
+}
+    
+int  glib_jsonrpc_server_send_async_response(GLibJsonRpcServer *_server,
+                                             JsonNode *reply)
+{
+  GLibJsonRpcServerPrivate *server = (GLibJsonRpcServerPrivate *)_server;
+  server->reply = reply;
+
+  g_mutex_unlock(server->mutex);
+
+  return TRUE;
+}
+
+void glib_jsonrpc_server_set_allow_non_loopback_connections(GLibJsonRpcServer *_server,
+                                                            gboolean allow_non_loopback_connections)
+{
+  GLibJsonRpcServerPrivate *server = (GLibJsonRpcServerPrivate *)_server;
+  server->allow_non_loopback_connections = allow_non_loopback_connections;
+}
diff --git a/src/glib-jsonrpc/glib-jsonrpc-server.h b/src/glib-jsonrpc/glib-jsonrpc-server.h
new file mode 100644
index 0000000..d7f2e72
--- /dev/null
+++ b/src/glib-jsonrpc/glib-jsonrpc-server.h
@@ -0,0 +1,70 @@
+/* GlibJsonRpcServer
+ * glib-jsonrpc-server.h: A Json RCP server in glib.
+ *
+ * Copyright (C) 2011 Dov Grobgeld <dov grobgeld gmail com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+#ifndef GLIB_JSON_RPC_SERVER_H
+#define GLIB_JSON_RPC_SERVER_H
+
+#include "json-glib/json-glib.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+} GLibJsonRpcServer; 
+
+typedef int (GLibJsonRpcCommandCallback)(GLibJsonRpcServer *server,
+                                         const char *method,
+                                         JsonNode *params,
+                                         JsonNode **response,
+                                         gpointer user_data);
+
+typedef int (GLibJsonRpcCommandAsyncCallback)(GLibJsonRpcServer *server,
+                                              const char *method,
+                                              JsonNode *params,
+                                              gpointer user_data);
+
+GLibJsonRpcServer *glib_jsonrpc_server_new(int port);
+void glib_jsonrpc_server_free(GLibJsonRpcServer *);
+
+int glib_jsonrpc_server_register_command(GLibJsonRpcServer *jsonrpc_server,
+                                         const gchar *command,
+                                         GLibJsonRpcCommandCallback *callback,
+                                         gpointer user_data);
+
+int glib_jsonrpc_server_register_async_command(GLibJsonRpcServer *jsonrpc_server,
+                                               const gchar *command,
+                                               GLibJsonRpcCommandAsyncCallback *async_callback,
+                                               gpointer user_data);
+// The json node ownershap is transfered.
+int  glib_jsonrpc_server_send_async_response(GLibJsonRpcServer *server,
+                                             JsonNode *response);
+
+
+void glib_jsonrpc_server_set_allow_non_loopback_connections(GLibJsonRpcServer *_server,
+                                                            gboolean allow_non_loop_back_connections);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GLIB-JSON-RPC-SERVER */
diff --git a/src/plugins/dcmtk/config/include/dcmtk/config/cfwin32.h b/src/plugins/dcmtk/config/include/dcmtk/config/cfwin32.h
index 2c00290..430d794 100644
--- a/src/plugins/dcmtk/config/include/dcmtk/config/cfwin32.h
+++ b/src/plugins/dcmtk/config/include/dcmtk/config/cfwin32.h
@@ -355,7 +355,6 @@ typedef unsigned size_t;
 #endif
 
 /* Define `ssize_t' to `long' if <sys/types.h> does not define. */
-#define HAVE_NO_TYPEDEF_SSIZE_T 1
 #ifdef HAVE_NO_TYPEDEF_SSIZE_T
 typedef long ssize_t;
 #endif
diff --git a/src/plugins/npy.c b/src/plugins/npy.c
index d8021c8..8dd6967 100644
--- a/src/plugins/npy.c
+++ b/src/plugins/npy.c
@@ -52,22 +52,22 @@ GivImage *giv_plugin_load_file(const char *filename,
     
     // Use regex to parse the header. Should update this to allow
     // user attributes.
-    GivRegex *regex = giv_regex_new ("^\\{\\s*"
-                                     "'descr':\\s*\\'(.*?)\\'\\s*,\\s*"
-                                     "'fortran_order':\\s*(\\w+)\\s*,\\s*"
-                                     "'shape':\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\),?\\s*"
-                                     "\\}", 0, 0, error);
+    GivRegex *regex = g_regex_new ("^\\{\\s*"
+                                   "'descr':\\s*\\'(.*?)\\'\\s*,\\s*"
+                                   "'fortran_order':\\s*(\\w+)\\s*,\\s*"
+                                   "'shape':\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\),?\\s*"
+                                   "\\}", 0, 0, error);
     if (*error) 
         return NULL;
 
     GivMatchInfo *match_info = NULL;
-    gboolean is_match = giv_regex_match_full(regex,
-                                             npy_string+10,
-                                             header_len,
-                                             0,
-                                             (GivRegexMatchFlags)0,
-                                             &match_info,
-                                             error);
+    gboolean is_match = g_regex_match_full(regex,
+                                           npy_string+10,
+                                           header_len,
+                                           0,
+                                           (GRegexMatchFlags)0,
+                                           &match_info,
+                                           error);
     if (*error) 
         return NULL;
 
@@ -76,7 +76,7 @@ GivImage *giv_plugin_load_file(const char *filename,
     gint width=-1, height = -1;
     GivImageType image_type;
     if (is_match) {
-        gchar *match_string = giv_match_info_fetch(match_info, 1);
+        gchar *match_string = g_match_info_fetch(match_info, 1);
         
         if (strcmp(match_string, "<f8")==0) 
             image_type = GIVIMAGE_DOUBLE;
@@ -95,21 +95,21 @@ GivImage *giv_plugin_load_file(const char *filename,
         
         g_free(match_string);
         
-        match_string = giv_match_info_fetch(match_info, 2);
+        match_string = g_match_info_fetch(match_info, 2);
         is_fortran_type = strcmp(match_string, "True") == 0;
         g_free(match_string);
         
-        match_string = giv_match_info_fetch(match_info, 3);
+        match_string = g_match_info_fetch(match_info, 3);
         height = atoi(match_string);
         g_free(match_string);
         
-        match_string = giv_match_info_fetch(match_info, 4);
+        match_string = g_match_info_fetch(match_info, 4);
         width = atoi(match_string);
         g_free(match_string);
     }
     
-    giv_regex_unref(regex);
-    giv_match_info_free(match_info);
+    g_regex_unref(regex);
+    g_match_info_free(match_info);
     
     if  (!is_match
          || !header_ok



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]