shp 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +34 -0
  3. data/.travis.yml +4 -0
  4. data/Gemfile +3 -0
  5. data/LICENSE +28 -0
  6. data/README.md +30 -0
  7. data/Rakefile +23 -0
  8. data/ext/shp/base.hpp +113 -0
  9. data/ext/shp/dbf.cpp +381 -0
  10. data/ext/shp/dbf.hpp +44 -0
  11. data/ext/shp/extconf.rb +13 -0
  12. data/ext/shp/shape_object.cpp +58 -0
  13. data/ext/shp/shape_object.hpp +27 -0
  14. data/ext/shp/shapefile.cpp +299 -0
  15. data/ext/shp/shapefile.hpp +35 -0
  16. data/ext/shp/shapelib/.cvsignore +15 -0
  17. data/ext/shp/shapelib/ChangeLog +450 -0
  18. data/ext/shp/shapelib/HOWTO-RELEASE +16 -0
  19. data/ext/shp/shapelib/LICENSE.LGPL +483 -0
  20. data/ext/shp/shapelib/Makefile +113 -0
  21. data/ext/shp/shapelib/README +41 -0
  22. data/ext/shp/shapelib/README.tree +172 -0
  23. data/ext/shp/shapelib/contrib/.cvsignore +12 -0
  24. data/ext/shp/shapelib/contrib/Makefile +66 -0
  25. data/ext/shp/shapelib/contrib/ShapeFileII.pas +234 -0
  26. data/ext/shp/shapelib/contrib/Shape_PointInPoly.cpp +238 -0
  27. data/ext/shp/shapelib/contrib/Shape_PointInPoly_README.txt +59 -0
  28. data/ext/shp/shapelib/contrib/csv2shp.c +558 -0
  29. data/ext/shp/shapelib/contrib/dbfcat.c +166 -0
  30. data/ext/shp/shapelib/contrib/dbfinfo.c +106 -0
  31. data/ext/shp/shapelib/contrib/makefile.vc +34 -0
  32. data/ext/shp/shapelib/contrib/my_nan.h +46 -0
  33. data/ext/shp/shapelib/contrib/shpcat.c +100 -0
  34. data/ext/shp/shapelib/contrib/shpcentrd.c +159 -0
  35. data/ext/shp/shapelib/contrib/shpdata.c +129 -0
  36. data/ext/shp/shapelib/contrib/shpdxf.c +340 -0
  37. data/ext/shp/shapelib/contrib/shpfix.c +110 -0
  38. data/ext/shp/shapelib/contrib/shpgeo.c +1595 -0
  39. data/ext/shp/shapelib/contrib/shpgeo.h +154 -0
  40. data/ext/shp/shapelib/contrib/shpinfo.c +113 -0
  41. data/ext/shp/shapelib/contrib/shpproj.c +260 -0
  42. data/ext/shp/shapelib/contrib/shpsort.c +605 -0
  43. data/ext/shp/shapelib/contrib/shpsort.txt +44 -0
  44. data/ext/shp/shapelib/contrib/shpwkb.c +123 -0
  45. data/ext/shp/shapelib/contrib/tests/shpproj.sh +38 -0
  46. data/ext/shp/shapelib/dbfopen.c +2221 -0
  47. data/ext/shp/shapelib/makefile.vc +86 -0
  48. data/ext/shp/shapelib/makeshape.sh +21 -0
  49. data/ext/shp/shapelib/mkdist.sh +37 -0
  50. data/ext/shp/shapelib/mkinstalldirs +38 -0
  51. data/ext/shp/shapelib/mkrelease.sh +55 -0
  52. data/ext/shp/shapelib/safileio.c +286 -0
  53. data/ext/shp/shapelib/shapefil.h +647 -0
  54. data/ext/shp/shapelib/shapelib.def +46 -0
  55. data/ext/shp/shapelib/shpopen.c +2388 -0
  56. data/ext/shp/shapelib/shptree.c +1187 -0
  57. data/ext/shp/shapelib/shputils.c +1072 -0
  58. data/ext/shp/shapelib/stream1.out +1465 -0
  59. data/ext/shp/shapelib/stream1.sh +28 -0
  60. data/ext/shp/shapelib/stream2.out +530 -0
  61. data/ext/shp/shapelib/stream2.sh +11 -0
  62. data/ext/shp/shapelib/stream3.out +37 -0
  63. data/ext/shp/shapelib/web/.cvsignore +2 -0
  64. data/ext/shp/shapelib/web/codepage.html +403 -0
  65. data/ext/shp/shapelib/web/dbf_api.html +436 -0
  66. data/ext/shp/shapelib/web/index.html +235 -0
  67. data/ext/shp/shapelib/web/license.html +78 -0
  68. data/ext/shp/shapelib/web/manifest.html +87 -0
  69. data/ext/shp/shapelib/web/release.html +80 -0
  70. data/ext/shp/shapelib/web/shapelib-tools.html +352 -0
  71. data/ext/shp/shapelib/web/shp_api.html +376 -0
  72. data/ext/shp/shp.cpp +19 -0
  73. data/ext/shp/shp.hpp +47 -0
  74. data/lib/shp.rb +35 -0
  75. data/lib/shp/version.rb +3 -0
  76. data/shp.gemspec +23 -0
  77. data/spec/shp_spec.rb +127 -0
  78. metadata +176 -0
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZmM2OGJlZGRjZWFjYjJiY2VlNjBkMGJjNDM1NTU1MTJkZTRmZmMwZQ==
5
+ data.tar.gz: !binary |-
6
+ ODliN2NiZmI1OWUzYmEwNTYzNTgzZTlhYjdjMjhlNzA0ZTU5OWU1Yg==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ NjhiMzMwYmE1NWI2NTFjNWY4NzkyMmI3OGVkY2UzZDMzODdjMjVjMzEzMmUz
10
+ MDE4YzcxMDYzMDYzZmVhNjIxYjE2Njc4MDY5YWQwYTA5MDViMjRhNmY5MDZk
11
+ NzZlNjQ3YjdhZWY1NDNlZDdlOWIwNmE0ZWQwNTVjYjYxM2Q4YTQ=
12
+ data.tar.gz: !binary |-
13
+ ZjZkMThlYTE1NDE1ZGEwOGEyMDI2NzEwOGUyZTIyMmY4ZDhlN2Q4ZDc1ZTU0
14
+ ZmU3MzAzNWRkMTM4ODRhM2JhYTE5M2RjOTdhNmI5YjViYjkwMTIwY2NkNmJh
15
+ ZDFlNzQxOGUxMzE0MjhjYTcxNWM3NzUxNjVmNjE1YzA0NzU2ZWY=
data/.gitignore ADDED
@@ -0,0 +1,34 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ *.so
5
+ *.o
6
+ *.bundle
7
+ .config
8
+ .yardoc
9
+ Gemfile.lock
10
+ InstalledFiles
11
+ _yardoc
12
+ coverage
13
+ doc/
14
+ lib/bundler/man
15
+ pkg
16
+ rdoc
17
+ spec/reports
18
+ test/tmp
19
+ test/version_tmp
20
+ tmp
21
+ *dbfadd*
22
+ *dbfcreate*
23
+ *dbfdump*
24
+ *shpadd*
25
+ *shpcreate*
26
+ *shpdump*
27
+ *shprewind*
28
+ *shptest*
29
+ *shptreedump*
30
+ ext/shp/Makefile
31
+ test/testfile*
32
+ testfile*
33
+ ext/shp/mkmf.log
34
+ ext/shp/shapelib/libshp.a
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.2
4
+ - 1.9.3
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,28 @@
1
+ Copyright (c) 2013, Spatial Networks
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are
6
+ met:
7
+
8
+ * Redistributions of source code must retain the above copyright
9
+ notice, this list of conditions and the following disclaimer.
10
+ * Redistributions in binary form must reproduce the above
11
+ copyright notice, this list of conditions and the following
12
+ disclaimer in the documentation and/or other materials provided
13
+ with the distribution.
14
+ * Neither the name of the author nor the names of other
15
+ contributors may be used to endorse or promote products derived
16
+ from this software without specific prior written permission.
17
+
18
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,30 @@
1
+ # shp-ruby [![Build Status](https://secure.travis-ci.org/spatialnetworks/shp-ruby.png)](http://travis-ci.org/spatialnetworks/shp-ruby)
2
+
3
+ Native bindings for Shapelib. This gem includes an embedded copy of Shapelib so it doesn't require any
4
+ system libraries to be installed and can be installed with just gem/bundler.
5
+
6
+ This gem is intentionally low level and aims to be a 1:1 mapping of the native C API. It does not
7
+ add any Ruby sugar on top of Shapelib. A more Ruby-like API can be implemented *in ruby* on top of this core API.
8
+
9
+ Docs for the native API:
10
+
11
+ * [SHP](http://shapelib.maptools.org/shp_api.html)
12
+ * [DBF](http://shapelib.maptools.org/dbf_api.html)
13
+
14
+ ## Installation
15
+
16
+ Add this to your `Gemfile`
17
+
18
+ ```rb
19
+ gem 'shp'
20
+ ```
21
+
22
+ - OR install manually -
23
+
24
+ ```sh
25
+ gem install shp
26
+ ```
27
+
28
+ ## License
29
+
30
+ BSD
data/Rakefile ADDED
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env rake
2
+ require 'rubygems'
3
+ require 'bundler'
4
+ require 'bundler/gem_tasks'
5
+ require 'rake/testtask'
6
+ require 'rake'
7
+ require 'rake/extensiontask'
8
+ require 'rspec/core'
9
+ require 'rspec/core/rake_task'
10
+
11
+ Bundler.setup
12
+
13
+ Rake::ExtensionTask.new('shp') do |ext|
14
+ ext.name = 'shp'
15
+ ext.lib_dir = "lib/shp"
16
+ end
17
+
18
+ RSpec::Core::RakeTask.new(:spec) do |spec|
19
+ Rake::Task['compile'].invoke
20
+ spec.pattern = FileList['spec/**/*_spec.rb']
21
+ end
22
+
23
+ task :default => :spec
data/ext/shp/base.hpp ADDED
@@ -0,0 +1,113 @@
1
+ #ifndef __SHP_BASE_HPP__
2
+ #define __SHP_BASE_HPP__
3
+
4
+ #include <vector>
5
+ #include <algorithm>
6
+ #include "shp.hpp"
7
+
8
+ namespace shp {
9
+ template <typename T> class base {
10
+ public:
11
+ base<T>() : _value(0), dependencies() {}
12
+
13
+ static VALUE initialize_instance(int argc, VALUE *argv, VALUE self) {
14
+ return unwrap(self)->initialize(argc, argv);
15
+ }
16
+
17
+ static VALUE new_instance(int argc, VALUE *argv, VALUE klass) {
18
+ T *instance = new T();
19
+ VALUE rvalue = instance->wrapped();
20
+ rb_obj_call_init(rvalue, argc, argv);
21
+ return rvalue;
22
+ }
23
+
24
+ static VALUE new_instance_not_allowed(int argc, VALUE *argv, VALUE klass) {
25
+ rb_raise(rb_eRuntimeError, "You cannot use #new on this class.");
26
+ return Qnil;
27
+ }
28
+
29
+ static VALUE initialize_instance_not_allowed(int argc, VALUE *argv, VALUE klass) {
30
+ rb_raise(rb_eRuntimeError, "You cannot use #initialize on this class.");
31
+ return Qnil;
32
+ }
33
+
34
+ VALUE wrapped() {
35
+ if (!_value) {
36
+ _value = Data_Wrap_Struct(klass(), base<T>::mark_dependencies, base<T>::dispose, this);
37
+ }
38
+ return _value;
39
+ }
40
+
41
+ void gc_mark() {
42
+ if (_value) {
43
+ rb_gc_mark(_value);
44
+ }
45
+ }
46
+
47
+ virtual void mark_dependencies() {
48
+ for (typename std::vector<base *>::iterator it = dependencies.begin(); it != dependencies.end(); ++it) {
49
+ (*it)->gc_mark();
50
+ }
51
+ }
52
+
53
+ virtual void dispose() {}
54
+ virtual VALUE initialize(int argc, VALUE *argv) { return wrapped(); }
55
+
56
+ virtual VALUE klass() {
57
+ return Qnil;
58
+ }
59
+
60
+ virtual ~base() {}
61
+
62
+ static T *unwrap(VALUE self) {
63
+ T *obj = NULL;
64
+ Data_Get_Struct(self, T, obj);
65
+ return obj;
66
+ }
67
+
68
+ void add_dependency(base *dep) {
69
+ dependencies.push(dep);
70
+ }
71
+
72
+ void remove_dependency(base *dep) {
73
+ dependencies.erase(std::remove(dependencies.begin(), dependencies.end(), dep), dependencies.end());
74
+ }
75
+
76
+ protected:
77
+ VALUE _value;
78
+
79
+ std::vector<base *> dependencies;
80
+
81
+ static T *object(void *ptr) {
82
+ return static_cast<T *>(ptr);
83
+ }
84
+
85
+ static void mark_dependencies(void *ptr) {
86
+ base::object(ptr)->mark_dependencies();
87
+ }
88
+
89
+ static void dispose(void *ptr) {
90
+ delete base::object(ptr);
91
+ }
92
+
93
+ static void define(VALUE klass, bool allowNew) {
94
+ if (allowNew) {
95
+ rb_define_singleton_method(klass, "new", SHP_METHOD(base<T>::new_instance), -1);
96
+ rb_define_method(klass, "initialize", SHP_METHOD(base<T>::initialize_instance), -1);
97
+ }
98
+ else {
99
+ rb_define_singleton_method(klass, "new", SHP_METHOD(base<T>::new_instance_not_allowed), -1);
100
+ rb_define_method(klass, "initialize", SHP_METHOD(base<T>::initialize_instance_not_allowed), -1);
101
+ }
102
+ }
103
+
104
+ VALUE initialize_not_allowed()
105
+ {
106
+ rb_raise(rb_eRuntimeError, "You cannot use #new on this class.");
107
+ return Qnil;
108
+ }
109
+
110
+ };
111
+ }
112
+
113
+ #endif
data/ext/shp/dbf.cpp ADDED
@@ -0,0 +1,381 @@
1
+
2
+ #include "dbf.hpp"
3
+
4
+ namespace shp {
5
+
6
+ VALUE dbf::_klass = Qnil;
7
+
8
+ VALUE dbf::klass() {
9
+ return dbf::_klass;
10
+ }
11
+
12
+ dbf::dbf(DBFHandle handle)
13
+ : _handle(handle)
14
+ {
15
+ }
16
+
17
+ dbf::~dbf() {
18
+ if (_handle) {
19
+ DBFClose(_handle);
20
+ _handle = NULL;
21
+ }
22
+ }
23
+
24
+ VALUE dbf::create(VALUE klass, VALUE filename)
25
+ {
26
+ CHECK_ARGUMENT_STRING(filename);
27
+
28
+ DBFHandle handle = DBFCreate(RSTRING_PTR(filename));
29
+
30
+ if (handle == NULL) {
31
+ SHP_FATAL("Failed to create dbf file.");
32
+ return Qnil;
33
+ }
34
+
35
+ dbf *file = new dbf(handle);
36
+
37
+ return file->wrapped();
38
+ }
39
+
40
+ VALUE dbf::open(VALUE klass, VALUE filename, VALUE access)
41
+ {
42
+ CHECK_ARGUMENT_STRING(filename);
43
+ CHECK_ARGUMENT_STRING(access);
44
+
45
+ DBFHandle handle = DBFOpen(RSTRING_PTR(filename), RSTRING_PTR(access));
46
+
47
+ if (handle == NULL) {
48
+ SHP_FATAL("Failed to open dbf file.");
49
+ return Qnil;
50
+ }
51
+
52
+ dbf *file = new dbf(handle);
53
+
54
+ return file->wrapped();
55
+ }
56
+
57
+ VALUE dbf::add_field(VALUE self, VALUE fieldName, VALUE fieldType, VALUE fieldWidth, VALUE fieldDecimals)
58
+ {
59
+ CHECK_ARGUMENT_STRING(fieldName);
60
+ CHECK_ARGUMENT_FIXNUM(fieldType);
61
+ CHECK_ARGUMENT_FIXNUM(fieldWidth);
62
+ CHECK_ARGUMENT_FIXNUM(fieldDecimals);
63
+
64
+ dbf *db = unwrap(self);
65
+
66
+ CHECK_VALID_HANDLE(db->value());
67
+
68
+ std::string theFieldName(RSTRING_PTR(fieldName));
69
+
70
+ int result = DBFAddField(db->value(),
71
+ theFieldName.c_str(),
72
+ (DBFFieldType)FIX2INT(fieldType),
73
+ FIX2INT(fieldWidth),
74
+ FIX2INT(fieldDecimals));
75
+
76
+ if (result == -1) {
77
+ SHP_FATAL("Failed to add new field");
78
+ return Qnil;
79
+ }
80
+
81
+ return INT2FIX(result);
82
+ }
83
+
84
+ VALUE dbf::write_integer_attribute(VALUE self, VALUE recordNumber, VALUE fieldIndex, VALUE fieldValue)
85
+ {
86
+ CHECK_ARGUMENT_FIXNUM(recordNumber);
87
+ CHECK_ARGUMENT_FIXNUM(fieldIndex);
88
+ CHECK_ARGUMENT_FIXNUM(fieldValue);
89
+
90
+ dbf *db = unwrap(self);
91
+
92
+ CHECK_VALID_HANDLE(db->value());
93
+
94
+ int result = DBFWriteIntegerAttribute(db->value(),
95
+ FIX2INT(recordNumber),
96
+ FIX2INT(fieldIndex),
97
+ FIX2INT(fieldValue));
98
+
99
+ if (result == 0) {
100
+ SHP_FATAL("Failed to write new attribute.");
101
+ return Qnil;
102
+ }
103
+
104
+ return INT2FIX(result);
105
+ }
106
+
107
+ VALUE dbf::write_double_attribute(VALUE self, VALUE recordNumber, VALUE fieldIndex, VALUE fieldValue)
108
+ {
109
+ CHECK_ARGUMENT_FIXNUM(recordNumber);
110
+ CHECK_ARGUMENT_FIXNUM(fieldIndex);
111
+ CHECK_ARGUMENT_FLOAT(fieldValue);
112
+
113
+ dbf *db = unwrap(self);
114
+
115
+ CHECK_VALID_HANDLE(db->value());
116
+
117
+ int result = DBFWriteDoubleAttribute(db->value(),
118
+ FIX2INT(recordNumber),
119
+ FIX2INT(fieldIndex),
120
+ NUM2DBL(fieldValue));
121
+
122
+ if (result == 0) {
123
+ SHP_FATAL("Failed to write new attribute.");
124
+ return Qnil;
125
+ }
126
+
127
+ return INT2FIX(result);
128
+ }
129
+
130
+ VALUE dbf::write_string_attribute(VALUE self, VALUE recordNumber, VALUE fieldIndex, VALUE fieldValue)
131
+ {
132
+ CHECK_ARGUMENT_FIXNUM(recordNumber);
133
+ CHECK_ARGUMENT_FIXNUM(fieldIndex);
134
+ CHECK_ARGUMENT_STRING(fieldValue);
135
+
136
+ dbf *db = unwrap(self);
137
+
138
+ CHECK_VALID_HANDLE(db->value());
139
+
140
+ int result = DBFWriteStringAttribute(db->value(),
141
+ FIX2INT(recordNumber),
142
+ FIX2INT(fieldIndex),
143
+ RSTRING_PTR(fieldValue));
144
+
145
+ if (result == 0) {
146
+ SHP_FATAL("Failed to write new attribute.");
147
+ return Qnil;
148
+ }
149
+
150
+ return INT2FIX(result);
151
+ }
152
+
153
+ VALUE dbf::write_null_attribute(VALUE self, VALUE recordNumber, VALUE fieldIndex)
154
+ {
155
+ CHECK_ARGUMENT_FIXNUM(recordNumber);
156
+ CHECK_ARGUMENT_FIXNUM(fieldIndex);
157
+
158
+ dbf *db = unwrap(self);
159
+
160
+ CHECK_VALID_HANDLE(db->value());
161
+
162
+ int result = DBFWriteNULLAttribute(db->value(),
163
+ FIX2INT(recordNumber),
164
+ FIX2INT(fieldIndex));
165
+
166
+ if (result == 0) {
167
+ SHP_FATAL("Failed to write new attribute.");
168
+ return Qnil;
169
+ }
170
+
171
+ return INT2FIX(result);
172
+ }
173
+
174
+ VALUE dbf::read_integer_attribute(VALUE self, VALUE recordIndex, VALUE fieldIndex)
175
+ {
176
+ CHECK_ARGUMENT_FIXNUM(recordIndex);
177
+ CHECK_ARGUMENT_FIXNUM(fieldIndex);
178
+
179
+ dbf *db = unwrap(self);
180
+
181
+ CHECK_VALID_HANDLE(db->value());
182
+
183
+ int result = DBFReadIntegerAttribute(db->value(),
184
+ FIX2INT(recordIndex),
185
+ FIX2INT(fieldIndex));
186
+
187
+ return INT2FIX(result);
188
+ }
189
+
190
+ VALUE dbf::read_double_attribute(VALUE self, VALUE recordIndex, VALUE fieldIndex)
191
+ {
192
+ CHECK_ARGUMENT_FIXNUM(recordIndex);
193
+ CHECK_ARGUMENT_FIXNUM(fieldIndex);
194
+
195
+ dbf *db = unwrap(self);
196
+
197
+ CHECK_VALID_HANDLE(db->value());
198
+
199
+ double result = DBFReadDoubleAttribute(db->value(),
200
+ FIX2INT(recordIndex),
201
+ FIX2INT(fieldIndex));
202
+
203
+ return rb_float_new(result);
204
+ }
205
+
206
+ VALUE dbf::read_string_attribute(VALUE self, VALUE recordIndex, VALUE fieldIndex)
207
+ {
208
+ CHECK_ARGUMENT_FIXNUM(recordIndex);
209
+ CHECK_ARGUMENT_FIXNUM(fieldIndex);
210
+
211
+ dbf *db = unwrap(self);
212
+
213
+ CHECK_VALID_HANDLE(db->value());
214
+
215
+ const char *result = DBFReadStringAttribute(db->value(),
216
+ FIX2INT(recordIndex),
217
+ FIX2INT(fieldIndex));
218
+
219
+ return rb_str_new2(result);
220
+ }
221
+
222
+ VALUE dbf::is_attribute_null(VALUE self, VALUE recordIndex, VALUE fieldIndex)
223
+ {
224
+ CHECK_ARGUMENT_FIXNUM(recordIndex);
225
+ CHECK_ARGUMENT_FIXNUM(fieldIndex);
226
+
227
+ dbf *db = unwrap(self);
228
+
229
+ CHECK_VALID_HANDLE(db->value());
230
+
231
+ int result = DBFIsAttributeNULL(db->value(),
232
+ FIX2INT(recordIndex),
233
+ FIX2INT(fieldIndex));
234
+
235
+ return INT2NUM(result);
236
+ }
237
+
238
+ VALUE dbf::close(VALUE self)
239
+ {
240
+ dbf *db = unwrap(self);
241
+
242
+ CHECK_VALID_HANDLE(db->value());
243
+
244
+ DBFClose(db->value());
245
+
246
+ db->_handle = NULL;
247
+
248
+ return Qnil;
249
+ }
250
+
251
+ VALUE dbf::get_field_count(VALUE self)
252
+ {
253
+ dbf *db = unwrap(self);
254
+
255
+ CHECK_VALID_HANDLE(db->value());
256
+
257
+ int fieldCount = DBFGetFieldCount(db->value());
258
+
259
+ return INT2FIX(fieldCount);
260
+ }
261
+
262
+ VALUE dbf::get_record_count(VALUE self)
263
+ {
264
+ dbf *db = unwrap(self);
265
+
266
+ CHECK_VALID_HANDLE(db->value());
267
+
268
+ int recordCount = DBFGetRecordCount(db->value());
269
+
270
+ return INT2FIX(recordCount);
271
+ }
272
+
273
+ VALUE dbf::get_field_index(VALUE self, VALUE fieldName)
274
+ {
275
+ CHECK_ARGUMENT_STRING(fieldName);
276
+
277
+ dbf *db = unwrap(self);
278
+
279
+ CHECK_VALID_HANDLE(db->value());
280
+
281
+ int fieldIndex = DBFGetFieldIndex(db->value(), RSTRING_PTR(fieldName));
282
+
283
+ return INT2FIX(fieldIndex);
284
+ }
285
+
286
+ VALUE dbf::get_field_info(VALUE self, VALUE fieldIndex)
287
+ {
288
+ CHECK_ARGUMENT_FIXNUM(fieldIndex);
289
+
290
+ dbf *db = unwrap(self);
291
+
292
+ CHECK_VALID_HANDLE(db->value());
293
+
294
+ char fieldName[12];
295
+ int fieldWidth = -1;
296
+ int fieldDecimals = -1;
297
+
298
+ DBFFieldType type = DBFGetFieldInfo(db->value(),
299
+ FIX2INT(fieldIndex),
300
+ fieldName,
301
+ &fieldWidth,
302
+ &fieldDecimals);
303
+
304
+ VALUE hash = rb_hash_new();
305
+
306
+ rb_hash_aset(hash, ID2SYM(rb_intern("name")), rb_str_new2(fieldName));
307
+ rb_hash_aset(hash, ID2SYM(rb_intern("type")), INT2FIX((int)type));
308
+ rb_hash_aset(hash, ID2SYM(rb_intern("width")), INT2FIX(fieldWidth));
309
+ rb_hash_aset(hash, ID2SYM(rb_intern("decimals")), INT2FIX(fieldDecimals));
310
+
311
+ return hash;
312
+ }
313
+
314
+ VALUE dbf::is_record_deleted(VALUE self, VALUE recordIndex)
315
+ {
316
+ CHECK_ARGUMENT_FIXNUM(recordIndex);
317
+
318
+ dbf *db = unwrap(self);
319
+
320
+ CHECK_VALID_HANDLE(db->value());
321
+
322
+ int result = DBFIsRecordDeleted(db->value(), FIX2INT(recordIndex));
323
+
324
+ return INT2FIX(result);
325
+ }
326
+
327
+ VALUE dbf::mark_record_deleted(VALUE self, VALUE recordIndex, VALUE isDeleted)
328
+ {
329
+ CHECK_ARGUMENT_FIXNUM(recordIndex);
330
+
331
+ dbf *db = unwrap(self);
332
+
333
+ CHECK_VALID_HANDLE(db->value());
334
+
335
+ int result = DBFMarkRecordDeleted(db->value(), FIX2INT(recordIndex), FIX2INT(isDeleted));
336
+
337
+ return INT2FIX(result);
338
+ }
339
+
340
+ VALUE dbf::get_native_field_type(VALUE self, VALUE fieldIndex)
341
+ {
342
+ CHECK_ARGUMENT_FIXNUM(fieldIndex);
343
+
344
+ dbf *db = unwrap(self);
345
+
346
+ CHECK_VALID_HANDLE(db->value());
347
+
348
+ char result = DBFGetNativeFieldType(db->value(), FIX2INT(fieldIndex));
349
+
350
+ char resultAsString[2] = { result, '\0' };
351
+
352
+ return rb_str_new2(resultAsString);
353
+ }
354
+
355
+ void dbf::define(VALUE module)
356
+ {
357
+ dbf::_klass = rb_define_class_under(module, "DBF", rb_cObject);
358
+ base::define(dbf::_klass, false);
359
+ rb_define_singleton_method(dbf::_klass, "create", SHP_METHOD(dbf::create), 1);
360
+ rb_define_singleton_method(dbf::_klass, "open", SHP_METHOD(dbf::open), 2);
361
+ rb_define_method(dbf::_klass, "add_field", SHP_METHOD(dbf::add_field), 4);
362
+ rb_define_method(dbf::_klass, "write_integer_attribute", SHP_METHOD(dbf::write_integer_attribute), 3);
363
+ rb_define_method(dbf::_klass, "write_double_attribute", SHP_METHOD(dbf::write_double_attribute), 3);
364
+ rb_define_method(dbf::_klass, "write_string_attribute", SHP_METHOD(dbf::write_string_attribute), 3);
365
+ rb_define_method(dbf::_klass, "write_null_attribute", SHP_METHOD(dbf::write_null_attribute), 2);
366
+ rb_define_method(dbf::_klass, "read_integer_attribute", SHP_METHOD(dbf::read_integer_attribute), 2);
367
+ rb_define_method(dbf::_klass, "read_double_attribute", SHP_METHOD(dbf::read_double_attribute), 2);
368
+ rb_define_method(dbf::_klass, "read_string_attribute", SHP_METHOD(dbf::read_string_attribute), 2);
369
+ rb_define_method(dbf::_klass, "is_attribute_null", SHP_METHOD(dbf::is_attribute_null), 2);
370
+ rb_define_method(dbf::_klass, "close", SHP_METHOD(dbf::close), 0);
371
+ rb_define_method(dbf::_klass, "get_field_count", SHP_METHOD(dbf::get_field_count), 0);
372
+ rb_define_method(dbf::_klass, "get_record_count", SHP_METHOD(dbf::get_record_count), 0);
373
+ rb_define_method(dbf::_klass, "get_field_index", SHP_METHOD(dbf::get_field_index), 1);
374
+ rb_define_method(dbf::_klass, "get_field_info", SHP_METHOD(dbf::get_field_info), 1);
375
+ rb_define_method(dbf::_klass, "is_record_deleted", SHP_METHOD(dbf::is_record_deleted), 1);
376
+ rb_define_method(dbf::_klass, "mark_record_deleted", SHP_METHOD(dbf::mark_record_deleted), 2);
377
+ rb_define_method(dbf::_klass, "get_native_field_type", SHP_METHOD(dbf::get_native_field_type), 1);
378
+ }
379
+
380
+ }
381
+