shapelib 0.7.2 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,17 +3,21 @@ require 'mkmf'
3
3
 
4
4
  HEADER_DIRS = [
5
5
  '/opt/local/include',
6
+ '/opt/homebrew/include',
6
7
  '/usr/local/include',
7
8
  '/usr/include',
8
9
  ]
9
10
 
10
11
  LIB_DIRS = [
11
12
  '/opt/local/lib',
13
+ '/opt/homebrew/lib',
12
14
  '/usr/local/lib',
13
15
  '/usr/lib',
14
16
  ]
15
17
 
16
18
  dir_config('shapelib', HEADER_DIRS, LIB_DIRS)
17
- have_header('shapefil.h') or have_header('libshp/shapefil.h') or raise 'shapefil.h not found'
19
+ header = %w[shapefil.h libshp/shapefil.h].find { |name| have_header(name) }
20
+ raise 'shapefil.h not found' unless header
18
21
  have_library('shp') or raise 'libshp not found'
22
+ have_const('FTDate', header)
19
23
  create_makefile('shapelib_ext')
@@ -45,6 +45,7 @@ static void shape_free(void *ptr)
45
45
  static void shapefile_free(void *ptr)
46
46
  {
47
47
  shapefile_close(ptr);
48
+ xfree(ptr);
48
49
  }
49
50
 
50
51
  static const rb_data_type_t shape_data_type = {
@@ -55,6 +56,8 @@ static const rb_data_type_t shapefile_data_type = {
55
56
  "Shapelib::ShapeFile", { 0, shapefile_free, 0 }
56
57
  };
57
58
 
59
+ static VALUE WrapShape(VALUE klass, shape_t *shape);
60
+
58
61
  #include "valconv.h"
59
62
  #include "sfcode.h"
60
63
  #include "sflist.h"
@@ -19,7 +19,7 @@ static VALUE sf_add_field(int argc, VALUE *args, VALUE obj)
19
19
  rb_raise(rb_eArgError, "specify decimal places for Float attribute");
20
20
  }
21
21
  TypedData_Get_Struct(obj, shapefile_t, &shapefile_data_type, self);
22
- r = shapefile_add_field(self, RSTRING_PTR(name), atype, width, wdeci);
22
+ r = shapefile_add_field(self, StringValueCStr(name), atype, width, wdeci);
23
23
  return obj;
24
24
  }
25
25
 
@@ -44,7 +44,7 @@ static int Ruby2FieldIndex(shapefile_t *sfile, VALUE field)
44
44
  if (FIXNUM_P(field)) {
45
45
  return FIX2INT(field);
46
46
  } else {
47
- return shapefile_field_index(sfile, StringValuePtr(field));
47
+ return shapefile_field_index(sfile, StringValueCStr(field));
48
48
  }
49
49
  }
50
50
 
@@ -129,7 +129,7 @@ static VALUE sf_maxbound(VALUE obj)
129
129
  z = bound[2];
130
130
  bound[2] = bound[3];
131
131
  bound[3] = z;
132
- return DoubleUnpack(bound, 4);
132
+ return DoubleUnpackM(bound, 4, 2);
133
133
  }
134
134
 
135
135
  static VALUE sf_minbound(VALUE obj)
@@ -142,14 +142,14 @@ static VALUE sf_minbound(VALUE obj)
142
142
  z = bound[2];
143
143
  bound[2] = bound[3];
144
144
  bound[3] = z;
145
- return DoubleUnpack(bound, 4);
145
+ return DoubleUnpackM(bound, 4, 2);
146
146
  }
147
147
 
148
148
  static VALUE sf_read(int argc, VALUE *args, VALUE obj)
149
149
  {
150
150
  shapefile_t *self;
151
151
  shape_t *s;
152
- VALUE ishape, r;
152
+ VALUE ishape;
153
153
  int irec;
154
154
  rb_scan_args(argc, args, "01", &ishape);
155
155
  TypedData_Get_Struct(obj, shapefile_t, &shapefile_data_type, self);
@@ -157,8 +157,7 @@ static VALUE sf_read(int argc, VALUE *args, VALUE obj)
157
157
  s = shapefile_read(self, irec);
158
158
  if (s == NULL)
159
159
  return Qnil;
160
- r = TypedData_Wrap_Struct(cShape, &shape_data_type, s);
161
- return r;
160
+ return WrapShape(cShape, s);
162
161
  }
163
162
 
164
163
  static VALUE sf_rewind(VALUE obj)
@@ -210,7 +209,7 @@ static VALUE sf_write(int argc, VALUE *args, VALUE obj)
210
209
  }
211
210
  TypedData_Get_Struct(obj, shapefile_t, &shapefile_data_type, self);
212
211
  TypedData_Get_Struct(args[0], shape_t, &shape_data_type, shape);
213
- irec = ((argc == 2) ? NUM2INT(args[1]) : -1);
212
+ irec = (argc == 2 && !NIL_P(args[1])) ? NUM2INT(args[1]) : -1;
214
213
  r = shapefile_write(self, irec, shape);
215
214
  return INT2FIX(r);
216
215
  }
@@ -219,12 +218,41 @@ static VALUE sf_write(int argc, VALUE *args, VALUE obj)
219
218
  * constructor
220
219
  */
221
220
 
221
+ struct shapefile_wrap_args {
222
+ VALUE klass;
223
+ shapefile_t *sfile;
224
+ };
225
+
226
+ static VALUE WrapShapeFileProtected(VALUE ptr)
227
+ {
228
+ struct shapefile_wrap_args *args = (struct shapefile_wrap_args *)ptr;
229
+ return TypedData_Wrap_Struct(args->klass, &shapefile_data_type, args->sfile);
230
+ }
231
+
232
+ static VALUE WrapShapeFile(VALUE klass, shapefile_t *sfile)
233
+ {
234
+ struct shapefile_wrap_args args = { klass, sfile };
235
+ int state;
236
+ VALUE sf = rb_protect(WrapShapeFileProtected, (VALUE)&args, &state);
237
+ if (state) {
238
+ shapefile_free(sfile);
239
+ rb_jump_tag(state);
240
+ }
241
+ return sf;
242
+ }
243
+
244
+ static VALUE CallShapeFileBlock(VALUE args)
245
+ {
246
+ rb_funcall(rb_ary_entry(args, 0), rb_intern("call"), 1,
247
+ rb_ary_entry(args, 1));
248
+ return Qnil;
249
+ }
250
+
222
251
  static VALUE YieldIfPossible(VALUE proc, VALUE sf)
223
252
  {
224
253
  if (!NIL_P(proc)) {
225
- rb_funcall(proc, rb_intern("call"), 1, sf);
226
- sf_close(sf);
227
- return Qnil;
254
+ return rb_ensure(CallShapeFileBlock, rb_ary_new_from_args(2, proc, sf),
255
+ sf_close, sf);
228
256
  } else {
229
257
  return sf;
230
258
  }
@@ -235,10 +263,14 @@ static VALUE sf_s_open(int argc, VALUE *argv, VALUE klass)
235
263
  VALUE fnam, mode, sf, proc;
236
264
  shapefile_t *sfile;
237
265
  rb_scan_args(argc, argv, "11&", &fnam, &mode, &proc);
238
- sfile = shapefile_open(StringValuePtr(fnam),
239
- (NIL_P(mode) ? "rb" : StringValuePtr(mode))
266
+ /* Finish Ruby callbacks before taking pointers into either string. */
267
+ StringValue(fnam);
268
+ if (!NIL_P(mode))
269
+ StringValue(mode);
270
+ sfile = shapefile_open(StringValueCStr(fnam),
271
+ (NIL_P(mode) ? "rb" : StringValueCStr(mode))
240
272
  );
241
- sf = TypedData_Wrap_Struct(klass, &shapefile_data_type, sfile);
273
+ sf = WrapShapeFile(klass, sfile);
242
274
  return YieldIfPossible(proc, sf);
243
275
  }
244
276
 
@@ -250,7 +282,7 @@ static VALUE sf_s_new(int argc, VALUE *argv, VALUE klass)
250
282
  int i;
251
283
  if (argc > 3 || argc < 2) {
252
284
  rb_raise(rb_eArgError,
253
- "usage: ShapeLib::Shapefile.new filename, shapetype, attrs = []");
285
+ "usage: Shapelib::ShapeFile.new filename, shapetype, attrs = []");
254
286
  return Qnil;
255
287
  }
256
288
  rb_scan_args(argc, argv, "21&", &fnam, &shapetype, &attrs, &proc);
@@ -262,11 +294,11 @@ static VALUE sf_s_new(int argc, VALUE *argv, VALUE klass)
262
294
  rb_raise(rb_eArgError, "attrs must be Array");
263
295
  }
264
296
  }
265
- sfile = shapefile_new(StringValuePtr(fnam), stype);
297
+ sfile = shapefile_new(StringValueCStr(fnam), stype);
266
298
  if (sfile == NULL) {
267
299
  rb_raise(rb_eRuntimeError, "shapefile_new failed");
268
300
  }
269
- sf = TypedData_Wrap_Struct(klass, &shapefile_data_type, sfile);
301
+ sf = WrapShapeFile(klass, sfile);
270
302
  if (argc > 2) {
271
303
  for (i = 0; i < RARRAY_LEN(attrs); i++) {
272
304
  VALUE p = RARRAY_PTR(attrs)[i];
@@ -1,21 +1,21 @@
1
1
  static method_table_entry sf_methods[] = {
2
- { "add_field", sf_add_field, -1 },
3
- { "close", sf_close, 0 },
4
- { "delete_shape", sf_delete_shape, 1 },
5
- { "each", sf_each, 0 },
6
- { "field_count", sf_field_count, 0 },
7
- { "field_index", sf_field_index, 1 },
8
- { "field_name", sf_field_name, 1 },
9
- { "field_type", sf_field_type, 1 },
10
- { "field_width", sf_field_width, 1 },
11
- { "field_decimals", sf_field_decimals, 1 },
12
- { "fields", sf_fields, 0 },
13
- { "minbound", sf_minbound, 0 },
14
- { "maxbound", sf_maxbound, 0 },
15
- { "read", sf_read, -1 },
16
- { "rewind", sf_rewind, 0 },
17
- { "shape_type", sf_shape_type, 0 },
18
- { "size", sf_size, 0 },
19
- { "write", sf_write, -1 },
2
+ { "add_field", RUBY_METHOD_FUNC(sf_add_field), -1 },
3
+ { "close", RUBY_METHOD_FUNC(sf_close), 0 },
4
+ { "delete_shape", RUBY_METHOD_FUNC(sf_delete_shape), 1 },
5
+ { "each", RUBY_METHOD_FUNC(sf_each), 0 },
6
+ { "field_count", RUBY_METHOD_FUNC(sf_field_count), 0 },
7
+ { "field_index", RUBY_METHOD_FUNC(sf_field_index), 1 },
8
+ { "field_name", RUBY_METHOD_FUNC(sf_field_name), 1 },
9
+ { "field_type", RUBY_METHOD_FUNC(sf_field_type), 1 },
10
+ { "field_width", RUBY_METHOD_FUNC(sf_field_width), 1 },
11
+ { "field_decimals", RUBY_METHOD_FUNC(sf_field_decimals), 1 },
12
+ { "fields", RUBY_METHOD_FUNC(sf_fields), 0 },
13
+ { "minbound", RUBY_METHOD_FUNC(sf_minbound), 0 },
14
+ { "maxbound", RUBY_METHOD_FUNC(sf_maxbound), 0 },
15
+ { "read", RUBY_METHOD_FUNC(sf_read), -1 },
16
+ { "rewind", RUBY_METHOD_FUNC(sf_rewind), 0 },
17
+ { "shape_type", RUBY_METHOD_FUNC(sf_shape_type), 0 },
18
+ { "size", RUBY_METHOD_FUNC(sf_size), 0 },
19
+ { "write", RUBY_METHOD_FUNC(sf_write), -1 },
20
20
  { NULL, NULL, 0 }
21
21
  };