[giv] Initial introduction of remote control of giv through jsonrpc.
- From: Dov Grobgeld <dov src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [giv] Initial introduction of remote control of giv through jsonrpc.
- Date: Sun, 25 Dec 2011 21:38:18 +0000 (UTC)
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]