|
- #include "igraph.h"
- #include "ruby.h"
- #include "cIGraph.h"
-
- #ifdef __APPLE__
- #else
- /* call-seq:
- * IGraph::FileRead.read_graph_edgelist(file,mode) -> IGraph
- *
- * Reads an edge list from a File (or any IO) and creates a graph.
- *
- * This format is simply a series of even number integers separated by
- * whitespace. The one edge (ie. two integers) per line format is thus not
- * required (but recommended for readability). Edges of directed graphs are
- * assumed to be in from, to order.
- */
- VALUE cIGraph_read_graph_edgelist(VALUE self, VALUE file, VALUE directed){
-
- VALUE string;
- FILE *stream;
- VALUE new_graph;
- VALUE v_ary;
- igraph_t *graph;
- igraph_bool_t directed_b = 0;
-
- igraph_vs_t vs;
- igraph_vit_t vit;
-
- int vid;
-
- if(directed)
- directed_b = 1;
-
- new_graph = cIGraph_alloc(cIGraph);
- Data_Get_Struct(new_graph, igraph_t, graph);
-
- string = rb_funcall(file, rb_intern("read"), 0);
- stream = fmemopen(RSTRING_PTR(string),RSTRING_LEN(string), "r");
-
- igraph_read_graph_edgelist(graph, stream, 0, directed_b);
-
- fclose(stream);
-
- igraph_vs_all(&vs);
- igraph_vit_create(graph, vs, &vit);
-
- v_ary = ((VALUE*)graph->attr)[0];
-
- while (!IGRAPH_VIT_END(vit)) {
- vid = IGRAPH_VIT_GET(vit);
- rb_ary_push(v_ary,INT2NUM(vid));
- IGRAPH_VIT_NEXT(vit);
- }
-
- igraph_vit_destroy(&vit);
- igraph_vs_destroy(&vs);
-
- return new_graph;
-
- }
-
- /* call-seq:
- * graph.write_graph_edgelist(file) -> Integer
- *
- * Writes an edge list to an IO
- *
- * This format is simply a series of even number integers separated by
- * whitespace. The one edge (ie. two integers) per line format is thus not
- * required (but recommended for readability). Edges of directed graphs are
- * assumed to be in from, to order.
- */
- VALUE cIGraph_write_graph_edgelist(VALUE self, VALUE file){
-
- char *buf;
- size_t size;
- FILE *stream;
- igraph_t *graph;
- int e;
-
- Data_Get_Struct(self, igraph_t, graph);
-
- stream = open_memstream(&buf,&size);
- e = igraph_write_graph_edgelist(graph, stream);
- fflush(stream);
-
- rb_funcall(file, rb_intern("write"), 1, rb_str_new(buf,size));
-
- fclose(stream);
-
- return e;
-
- }
-
- /* call-seq:
- * IGraph::FileRead.read_graph_ncol(file,predefnames,names,weights,directed) -> IGraph
- *
- * Reads a .ncol file used by LGL, also useful for creating graphs from
- * 'named' (and optionally weighted) edge lists.
- *
- * This format is used by the Large Graph Layout program
- * (http://bioinformatics.icmb.utexas.edu/lgl/), and it is simply a symbolic
- * weighted edge list. It is a simple text file with one edge per line. An
- * edge is defined by two symbolic vertex names separated by whitespace.
- * (The symbolic vertex names themselves cannot contain whitespace. They
- * might follow by an optional number, this will be the weight of the edge;
- * the number can be negative and can be in scientific notation. If there is
- * no weight specified to an edge it is assumed to be zero.
- *
- * The resulting graph is always undirected. LGL cannot deal with files which
- * contain multiple or loop edges, this is however not checked here, as
- * igraph is happy with these.
- *
- * file: A File or IO object to read from.
- *
- * predefnames: Array of the symbolic names of the vertices in the file.
- * If empty then vertex ids will be assigned to vertex names in the order of
- * their appearence in the .ncol file.
- *
- * names: Logical value, if TRUE the symbolic names of the vertices will be
- * added to the graph as a vertex attribute called 'name'.
- *
- * weights: Logical value, if TRUE the weights of the edges is added to the
- * graph as an edge attribute called 'weight'.
- *
- * directed: Whether to create a directed graph. As this format was originally
- * used only for undirected graphs there is no information in the file about
- * the directedness of the graph. Set this parameter to IGRAPH_DIRECTED or
- * IGRAPH_UNDIRECTED to create a directed or undirected graph.
- */
- VALUE cIGraph_read_graph_ncol(VALUE self, VALUE file, VALUE predefnames, VALUE names, VALUE weights, VALUE directed){
-
- VALUE string;
- FILE *stream;
- VALUE new_graph;
- VALUE v_ary;
- VALUE e_ary;
- VALUE new_ary;
-
- igraph_t *graph;
- igraph_strvector_t names_vec;
- igraph_bool_t directed_b = 0;
- igraph_bool_t weights_b = 0;
- igraph_bool_t names_b = 0;
-
- int i;
-
- if(directed)
- directed_b = 1;
-
- if(names)
- names_b = 1;
-
- if(weights)
- weights_b = 1;
-
- new_graph = cIGraph_alloc(cIGraph);
- Data_Get_Struct(new_graph, igraph_t, graph);
-
- igraph_strvector_init(&names_vec,RARRAY_LEN(predefnames));
-
- for(i=0;i<RARRAY_LEN(predefnames);i++){
- igraph_strvector_set(&names_vec, i, RSTRING_PTR(RARRAY_PTR(predefnames)[i]));
- }
-
- string = rb_funcall(file, rb_intern("read"), 0);
- stream = fmemopen(RSTRING_PTR(string),RSTRING_LEN(string), "r");
-
- if (RARRAY_LEN(predefnames) == 0){
- igraph_read_graph_ncol(graph, stream, NULL, names_b, weights_b, directed_b);
- } else {
- igraph_read_graph_ncol(graph, stream, &names_vec, names_b, weights_b, directed_b);
- }
-
- fclose(stream);
-
- //Convert the Hash of names to Strings instead
- if(names){
- v_ary = ((VALUE*)graph->attr)[0];
- new_ary = rb_ary_new();
- for(i=0;i<RARRAY_LEN(v_ary);i++){
- rb_ary_push(new_ary, rb_hash_aref(RARRAY_PTR(v_ary)[i], rb_str_new2("name")));
- }
- ((VALUE*)graph->attr)[0] = new_ary;
- }
- //Convert the Hash of weights to floats instead
- if(weights){
- e_ary = ((VALUE*)graph->attr)[1];
- new_ary = rb_ary_new();
- for(i=0;i<RARRAY_LEN(e_ary);i++){
- rb_ary_push(new_ary, rb_hash_aref(RARRAY_PTR(e_ary)[i], rb_str_new2("weight")));
- }
- ((VALUE*)graph->attr)[1] = new_ary;
- }
-
- igraph_strvector_destroy(&names_vec);
-
- return new_graph;
-
- }
-
- /* call-seq:
- * graph.write_graph_ncol(file,names,weights) -> Integer
- *
- * Writes the graph to a file in .ncol format
- *
- * .ncol is a format used by LGL, see igraph_read_graph_ncol() for details.
- *
- * Note that having multiple or loop edges in an .ncol file breaks the LGL
- * software but igraph does not check for this condition.
- *
- * file: The file object to write to, it should be writable.
- *
- * names: The name of the vertex attribute, if symbolic names are to be
- * written to the file.
- *
- * weights: The name of the edge attribute, if they are also written to the
- * file.
- */
- VALUE cIGraph_write_graph_ncol(VALUE self, VALUE file, VALUE names, VALUE weights){
-
- char *buf;
- size_t size;
- FILE *stream;
- igraph_t *graph;
- int e, i;
-
- VALUE v_ary = Qnil;
- VALUE e_ary = Qnil;
- VALUE new_v_ary;
- VALUE new_e_ary;
-
- VALUE vertex_h;
- VALUE edge_h;
-
- char *weights_b = "0";
- char *names_b = "0";
-
- if(names)
- names_b = "name";
-
- if(weights)
- weights_b = "weight";
-
- Data_Get_Struct(self, igraph_t, graph);
-
- //Convert each object to it's String representation and each edge to
- //it's Float
- if(names){
- v_ary = ((VALUE*)graph->attr)[0];
- new_v_ary = rb_ary_new();
- for(i=0;i<RARRAY_LEN(v_ary);i++){
- vertex_h = rb_hash_new();
- rb_hash_aset(vertex_h, rb_str_new2("name"), StringValue(RARRAY_PTR(v_ary)[i]));
- rb_ary_push(new_v_ary, vertex_h);
- }
- ((VALUE*)graph->attr)[0] = new_v_ary;
- }
- if(weights){
- e_ary = ((VALUE*)graph->attr)[1];
- new_e_ary = rb_ary_new();
- for(i=0;i<RARRAY_LEN(e_ary);i++){
- edge_h = rb_hash_new();
- rb_hash_aset(edge_h, rb_str_new2("weight"), rb_funcall(RARRAY_PTR(e_ary)[i],rb_intern("to_f"),0));
- rb_ary_push(new_e_ary, edge_h);
- }
- ((VALUE*)graph->attr)[1] = new_e_ary;
- }
-
- stream = open_memstream(&buf,&size);
- e = igraph_write_graph_ncol(graph, stream, names_b, weights_b);
- fflush(stream);
- rb_funcall(file, rb_intern("write"), 1, rb_str_new(buf,size));
- fclose(stream);
-
- //Replace initital vertices and edges
- if(names){
- ((VALUE*)graph->attr)[0] = v_ary;
- }
- if(weights){
- ((VALUE*)graph->attr)[0] = e_ary;
- }
-
- return e;
-
- }
-
- /* call-seq:
- * IGraph::FileRead.read_graph_lgl(file,predefnames,names,weights) -> IGraph
- *
- * Reads a graph from an .lgl file
- *
- * The .lgl format is used by the Large Graph Layout visualization software
- * (http://bioinformatics.icmb.utexas.edu/lgl/), it can describe undirected
- * optionally weighted graphs. From the LGL manual:
- *
- * The second format is the LGL file format ( .lgl file suffix). This is yet
- * another graph file format that tries to be as stingy as possible with
- * space, yet keeping the edge file in a human readable (not binary) format.
- * The format itself is like the following:
- *
- * # vertex1name
- * vertex2name [optionalWeight]
- * vertex3name [optionalWeight]
- *
- * Here, the first vertex of an edge is preceded with a pound sign '#'.
- * Then each vertex that shares an edge with that vertex is listed one per
- * line on subsequent lines.
- *
- * LGL cannot handle loop and multiple edges or directed graphs, but in
- * igraph it is not an error to have multiple and loop edges.
- *
- * file: A File or IO object to read from.
- *
- * names: Logical value, if TRUE the symbolic names of the vertices will be
- * added to the graph as a vertex attribute called $B!H(Bname$B!I(B.
- *
- * weights: Logical value, if TRUE the weights of the edges is added to the
- * graph as an edge attribute called $B!H(Bweight$B!I(B.
- */
- VALUE cIGraph_read_graph_lgl(VALUE self, VALUE file, VALUE names, VALUE weights){
-
- VALUE string;
- FILE *stream;
- VALUE new_graph;
- VALUE v_ary;
- VALUE e_ary;
- VALUE new_ary;
-
- igraph_t *graph;
- igraph_bool_t weights_b = 0;
- igraph_bool_t names_b = 0;
-
- int i;
-
- if(names)
- names_b = 1;
-
- if(weights)
- weights_b = 1;
-
- new_graph = cIGraph_alloc(cIGraph);
- Data_Get_Struct(new_graph, igraph_t, graph);
-
- string = rb_funcall(file, rb_intern("read"), 0);
- stream = fmemopen(RSTRING_PTR(string),RSTRING_LEN(string), "r");
-
- igraph_read_graph_lgl(graph, stream, names_b, weights_b);
-
- fclose(stream);
-
- //Convert the Hash of names to Strings instead
- if(names){
- v_ary = ((VALUE*)graph->attr)[0];
- new_ary = rb_ary_new();
- for(i=0;i<RARRAY_LEN(v_ary);i++){
- rb_ary_push(new_ary, rb_hash_aref(RARRAY_PTR(v_ary)[i], rb_str_new2("name")));
- }
- ((VALUE*)graph->attr)[0] = new_ary;
- }
- //Convert the Hash of weights to floats instead
- if(weights){
- e_ary = ((VALUE*)graph->attr)[1];
- new_ary = rb_ary_new();
- for(i=0;i<RARRAY_LEN(e_ary);i++){
- rb_ary_push(new_ary, rb_hash_aref(RARRAY_PTR(e_ary)[i], rb_str_new2("weight")));
- }
- ((VALUE*)graph->attr)[1] = new_ary;
- }
-
- return new_graph;
-
- }
-
- /* call-seq:
- * graph.write_graph_lgl(file,names,weights,isolates) -> Integer
- *
- * Writes the graph to a file in .lgl format
- *
- * .lgl is a format used by LGL, see read_graph_lgl() for details.
- *
- * Note that having multiple or loop edges in an .lgl file breaks the LGL
- * software but igraph does not check for this condition.
- *
- * file: The File object to write to, it should be writable.
- *
- * names: The name of the vertex attribute, if symbolic names are written to
- * the file.
- *
- * weights: The name of the edge attribute, if they are also written to the
- * file.
- *
- * isolates: Logical, if TRUE isolated vertices are also written to the file.
- * If FALSE they will be omitted.
- */
- VALUE cIGraph_write_graph_lgl(VALUE self, VALUE file, VALUE names, VALUE weights, VALUE isolates){
-
- char *buf;
- size_t size;
- FILE *stream;
- igraph_t *graph;
- int e, i;
-
- VALUE v_ary = Qnil;
- VALUE e_ary = Qnil;
- VALUE new_v_ary;
- VALUE new_e_ary;
-
- VALUE vertex_h;
- VALUE edge_h;
-
- char *weights_b = "0";
- char *names_b = "0";
-
- igraph_bool_t isolates_b;
-
- if(names)
- names_b = "name";
-
- if(weights)
- weights_b = "weight";
-
- if(isolates)
- isolates_b = 1;
-
- Data_Get_Struct(self, igraph_t, graph);
-
- //Convert each object to it's String representation and each edge to
- //it's Float
- if(names){
- v_ary = ((VALUE*)graph->attr)[0];
- new_v_ary = rb_ary_new();
- for(i=0;i<RARRAY_LEN(v_ary);i++){
- vertex_h = rb_hash_new();
- rb_hash_aset(vertex_h, rb_str_new2("name"), StringValue(RARRAY_PTR(v_ary)[i]));
- rb_ary_push(new_v_ary, vertex_h);
- }
- ((VALUE*)graph->attr)[0] = new_v_ary;
- }
- if(weights){
- e_ary = ((VALUE*)graph->attr)[1];
- new_e_ary = rb_ary_new();
- for(i=0;i<RARRAY_LEN(e_ary);i++){
- edge_h = rb_hash_new();
- rb_hash_aset(edge_h, rb_str_new2("weight"), rb_funcall(RARRAY_PTR(e_ary)[i],rb_intern("to_f"),0));
- rb_ary_push(new_e_ary, edge_h);
- }
- ((VALUE*)graph->attr)[1] = new_e_ary;
- }
-
- stream = open_memstream(&buf,&size);
- e = igraph_write_graph_lgl(graph, stream, names_b, weights_b, isolates);
- fflush(stream);
- rb_funcall(file, rb_intern("write"), 1, rb_str_new(buf,size));
- fclose(stream);
-
- //Replace initital vertices and edges
- if(names){
- ((VALUE*)graph->attr)[0] = v_ary;
- }
- if(weights){
- ((VALUE*)graph->attr)[0] = e_ary;
- }
-
- return e;
-
- }
-
- /* call-seq:
- * IGraph::FileRead.read_graph_dimacs(file,directed) -> IGraph
- *
- * This function reads the DIMACS file format, more specifically the version
- * for network flow problems, see the files at
- * ftp://dimacs.rutgers.edu/pub/netflow/general-info/
- *
- * This is a line-oriented text file (ASCII) format. The first character of
- * each line defines the type of the line. If the first character is c the
- * line is a comment line and it is ignored. There is one problem line ( p in
- * the file, it must appear before any node and arc descriptor lines. The
- * problem line has three fields separated by spaces: the problem type
- * ( min , max or asn ), the number of vertices and number of edges in the
- * graph. Exactly two node identification lines are expected ( n ), one for
- * the source, one for the target vertex. These have two fields: the id of
- * the vertex and the type of the vertex, either s (=source) or t (=target).
- * Arc lines start with a and have three fields: the source vertex, the
- * target vertex and the edge capacity.
- *
- * Vertex ids are numbered from 1. The source, target vertices and edge
- * capacities are added as attributes of the graph.
- * I.e: g.attributes['source'].
- *
- * file: The File to read from.
- *
- * directed: Boolean, whether to create a directed graph.
- */
- VALUE cIGraph_read_graph_dimacs(VALUE self, VALUE file, VALUE directed){
-
- VALUE string;
- FILE *stream;
- VALUE new_graph;
-
- igraph_integer_t source;
- igraph_integer_t target;
- igraph_vector_t capacity;
- igraph_vector_t label;
- igraph_strvector_t problem;
-
- igraph_t *graph;
- igraph_bool_t directed_b = 0;
-
- igraph_vs_t vs;
- igraph_vit_t vit;
-
- VALUE v_ary;
- VALUE g_hsh;
-
- int i;
- int vid;
-
- if(directed)
- directed_b = 1;
-
- igraph_vector_init(&capacity, 0);
- igraph_vector_init(&label, 0);
- igraph_strvector_init(&problem, 0);
-
- new_graph = cIGraph_alloc(cIGraph);
- Data_Get_Struct(new_graph, igraph_t, graph);
-
- string = rb_funcall(file, rb_intern("read"), 0);
- stream = fmemopen(RSTRING_PTR(string),RSTRING_LEN(string), "r");
-
- igraph_read_graph_dimacs(graph, stream, &problem, &label, &source, &target, &capacity, directed_b);
-
- fclose(stream);
-
- igraph_vs_all(&vs);
- igraph_vit_create(graph, vs, &vit);
-
- //Push Integer onto vertex array
- v_ary = ((VALUE*)graph->attr)[0];
-
- while (!IGRAPH_VIT_END(vit)) {
- vid = IGRAPH_VIT_GET(vit);
- rb_ary_push(v_ary,INT2NUM(vid));
- IGRAPH_VIT_NEXT(vit);
- }
-
- g_hsh = ((VALUE*)graph->attr)[2];
-
- rb_hash_aset(g_hsh, rb_str_new2("source"), INT2NUM(source));
- rb_hash_aset(g_hsh, rb_str_new2("target"), INT2NUM(target));
- rb_hash_aset(g_hsh, rb_str_new2("capacity"), rb_ary_new());
-
- for(i=0;i<igraph_vector_size(&capacity);i++){
- rb_ary_push(rb_hash_aref(g_hsh, rb_str_new2("capacity")), rb_float_new(VECTOR(capacity)[i]));
- }
-
- igraph_vit_destroy(&vit);
- igraph_vs_destroy(&vs);
-
- return new_graph;
-
- }
-
- /* call-seq:
- * graph.write_graph_dimacs(file,source,target,capacity) -> Integer
- *
- * This function writes a graph to an output stream in DIMACS format,
- * describing a maximum flow problem. See
- * ftp://dimacs.rutgers.edu/pub/netflow/general-info/
- *
- * This file format is discussed in the documentation of read_graph_dimacs(),
- * see that for more information.
- *
- * file: IO object to write to.
- *
- * source: The source vertex for the maximum flow.
- *
- * target: The target vertex.
- *
- * capacity: Array containing the edge capacity values.
- */
- VALUE cIGraph_write_graph_dimacs(VALUE self, VALUE file, VALUE source, VALUE target, VALUE capacity){
-
- char *buf;
- size_t size;
- FILE *stream;
- igraph_t *graph;
- int e, i;
-
- igraph_vector_t capacity_v;
-
- Data_Get_Struct(self, igraph_t, graph);
-
- igraph_vector_init(&capacity_v,0);
-
- for(i=0;i<RARRAY_LEN(capacity);i++){
- igraph_vector_push_back(&capacity_v,NUM2DBL(RARRAY_PTR(capacity)[i]));
- }
-
- stream = open_memstream(&buf,&size);
- e = igraph_write_graph_dimacs(graph, stream, NUM2INT(source), NUM2INT(target), &capacity_v);
- fflush(stream);
- rb_funcall(file, rb_intern("write"), 1, rb_str_new(buf,size));
- fclose(stream);
-
- return e;
-
- }
-
- /* call-seq:
- * IGraph::FileRead.read_graph_graphdb(file,directed) -> IGraph
- *
- * Read a graph in the binary graph database format.
- *
- * file: The IO object to read from.
- *
- * directed: Boolean, whether to create a directed graph.
- */
- VALUE cIGraph_read_graph_graphdb(VALUE self, VALUE file, VALUE directed){
-
- VALUE string;
- FILE *stream;
- VALUE new_graph;
-
- VALUE v_ary;
-
- igraph_t *graph;
- igraph_bool_t directed_b = 0;
-
- igraph_vs_t vs;
- igraph_vit_t vit;
-
- int vid;
-
- if(directed)
- directed_b = 1;
-
- new_graph = cIGraph_alloc(cIGraph);
- Data_Get_Struct(new_graph, igraph_t, graph);
-
- string = rb_funcall(file, rb_intern("read"), 0);
- stream = fmemopen(RSTRING_PTR(string),RSTRING_LEN(string), "r");
-
- igraph_read_graph_graphdb(graph, stream, directed_b);
-
- fclose(stream);
-
- igraph_vs_all(&vs);
- igraph_vit_create(graph, vs, &vit);
-
- //Push Integer onto vertex array
- v_ary = ((VALUE*)graph->attr)[0];
-
- while (!IGRAPH_VIT_END(vit)) {
- vid = IGRAPH_VIT_GET(vit);
- rb_ary_push(v_ary,INT2NUM(vid));
- IGRAPH_VIT_NEXT(vit);
- }
-
- igraph_vit_destroy(&vit);
- igraph_vs_destroy(&vs);
-
- return new_graph;
-
- }
-
- /* call-seq:
- * IGraph::FileRead.read_graph_graphml(file,index) -> IGraph
- *
- * Reads a graph from a GraphML file specified as the File object file.
- *
- * GraphML is an XML-based file format for representing various types of
- * graphs. Currently only the most basic import functionality is implemented
- * in igraph: it can read GraphML files without nested graphs and hyperedges.
- *
- * If the GraphML file contains more than one graph, the one specified by
- * this index will be loaded. Indices start from zero, so supply zero here
- * if your GraphML file contains only a single graph.
- */
- VALUE cIGraph_read_graph_graphml(VALUE self, VALUE file, VALUE index){
-
- VALUE string;
- FILE *stream;
- VALUE new_graph;
- igraph_t *graph;
-
- new_graph = cIGraph_alloc(cIGraph);
- Data_Get_Struct(new_graph, igraph_t, graph);
-
- string = rb_funcall(file, rb_intern("read"), 0);
- stream = fmemopen(RSTRING_PTR(string),RSTRING_LEN(string), "r");
-
- igraph_read_graph_graphml(graph, stream, NUM2INT(index));
-
- fclose(stream);
-
- return new_graph;
-
- }
-
- /* call-seq:
- * graph.write_graph_graphml(file) -> Integer
- *
- * Writes the graph to a File in GraphML format
- *
- * GraphML is an XML-based file format for representing various types of
- * graphs. See the GraphML Primer
- * (http://graphml.graphdrawing.org/primer/graphml-primer.html) for detailed
- * format description.
- */
- VALUE cIGraph_write_graph_graphml(VALUE self, VALUE file){
-
- char *buf;
- size_t size;
- FILE *stream;
- igraph_t *graph;
- int e;
-
- Data_Get_Struct(self, igraph_t, graph);
-
- stream = open_memstream(&buf,&size);
- e = igraph_write_graph_graphml(graph, stream);
- fflush(stream);
-
- rb_funcall(file, rb_intern("write"), 1, rb_str_new(buf,size));
-
- fclose(stream);
-
- return e;
-
- }
-
- /* call-seq:
- * IGraph::FileRead.read_graph_gml(file) -> IGraph
- *
- * Reads a graph from a GraphML file.
- *
- * GraphML is an XML-based file format for representing various types of
- * graphs. Currently only the most basic import functionality is implemented
- * in igraph: it can read GraphML files without nested graphs and hyperedges.
- *
- * file: IO object to read from
- */
- VALUE cIGraph_read_graph_gml(VALUE self, VALUE file){
-
- VALUE string;
- FILE *stream;
- VALUE new_graph;
- igraph_t *graph;
-
- new_graph = cIGraph_alloc(cIGraph);
- Data_Get_Struct(new_graph, igraph_t, graph);
-
- string = rb_funcall(file, rb_intern("read"), 0);
- stream = fmemopen(RSTRING_PTR(string),RSTRING_LEN(string), "r");
-
- igraph_read_graph_gml(graph, stream);
-
- fclose(stream);
-
- return new_graph;
-
- }
-
- /* call-seq:
- * graph.write_graph_gml(file) -> IGraph
- *
- * Writes the graph to a file in GraphML format.
- *
- * file: IO object to write to
- */
- VALUE cIGraph_write_graph_gml(VALUE self, VALUE file){
-
- char *buf;
- size_t size;
- FILE *stream;
- igraph_t *graph;
- int e;
-
- Data_Get_Struct(self, igraph_t, graph);
-
- stream = open_memstream(&buf,&size);
- e = igraph_write_graph_gml(graph, stream, NULL, 0);
- fflush(stream);
-
- rb_funcall(file, rb_intern("write"), 1, rb_str_new(buf,size));
-
- fclose(stream);
-
- return e;
-
- }
-
- /* call-seq:
- * IGraph::FileRead.read_graph_pajek(file) -> IGraph
- *
- * Reads a file in Pajek format
- *
- * Only a subset of the Pajek format is implemented. This is partially
- * because this format is not very well documented, but also because
- * igraph does not support some Pajek features, like multigraphs.
- */
- VALUE cIGraph_read_graph_pajek(VALUE self, VALUE file){
-
- VALUE string;
- FILE *stream;
- VALUE new_graph;
- igraph_t *graph;
-
- new_graph = cIGraph_alloc(cIGraph);
- Data_Get_Struct(new_graph, igraph_t, graph);
-
- string = rb_funcall(file, rb_intern("read"), 0);
- stream = fmemopen(RSTRING_PTR(string),RSTRING_LEN(string), "r");
-
- IGRAPH_CHECK(igraph_read_graph_pajek(graph, stream));
-
- fclose(stream);
-
- return new_graph;
-
- }
-
- /* call-seq:
- * graph.write_graph_pajek(file) -> Integer
- *
- * Writes a graph to a file in Pajek format.
- */
- VALUE cIGraph_write_graph_pajek(VALUE self, VALUE file){
-
- char *buf;
- size_t size;
- FILE *stream;
- igraph_t *graph;
- int e;
-
- Data_Get_Struct(self, igraph_t, graph);
-
- stream = open_memstream(&buf,&size);
- e = igraph_write_graph_pajek(graph, stream);
- fflush(stream);
-
- rb_funcall(file, rb_intern("write"), 1, rb_str_new(buf,size));
-
- fclose(stream);
-
- return e;
-
- }
- #endif
|