shapelib 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,71 @@
1
+
2
+ static VALUE sp_to_h(VALUE obj)
3
+ {
4
+ VALUE h;
5
+ h = rb_hash_new();
6
+ rb_hash_aset(h, CSTR2SYM("shape_type"), sp_shape_type(obj));
7
+ rb_hash_aset(h, CSTR2SYM("shape_id"), sp_shape_id(obj));
8
+ rb_hash_aset(h, CSTR2SYM("maxbound"), sp_maxbound(obj));
9
+ rb_hash_aset(h, CSTR2SYM("minbound"), sp_minbound(obj));
10
+ rb_hash_aset(h, CSTR2SYM("mvals"), sp_mvals(obj));
11
+ rb_hash_aset(h, CSTR2SYM("n_parts"), sp_n_parts(obj));
12
+ rb_hash_aset(h, CSTR2SYM("n_vertices"), sp_n_vertices(obj));
13
+ rb_hash_aset(h, CSTR2SYM("part_start"), sp_part_start(obj));
14
+ rb_hash_aset(h, CSTR2SYM("part_type"), sp_part_type(obj));
15
+ rb_hash_aset(h, CSTR2SYM("shape_id"), sp_shape_id(obj));
16
+ rb_hash_aset(h, CSTR2SYM("shape_type"), sp_shape_type(obj));
17
+ rb_hash_aset(h, CSTR2SYM("xvals"), sp_xvals(obj));
18
+ rb_hash_aset(h, CSTR2SYM("yvals"), sp_yvals(obj));
19
+ rb_hash_aset(h, CSTR2SYM("zvals"), sp_zvals(obj));
20
+ Attr_to_Hash(h, obj);
21
+ return h;
22
+ }
23
+
24
+ static VALUE sp_inspect(VALUE obj)
25
+ {
26
+ VALUE tos;
27
+ static ID inspect = 0;
28
+ static ID id_plus, id_class, id_to_s;
29
+ static VALUE classnm;
30
+ if (inspect == 0) {
31
+ inspect = rb_intern("inspect");
32
+ id_plus = rb_intern("+");
33
+ id_class = rb_intern("class");
34
+ id_to_s = rb_intern("to_s");
35
+ }
36
+ classnm = rb_funcall(rb_funcall(obj, id_class, 0), id_to_s, 0);
37
+ tos = rb_funcall(sp_to_h(obj), inspect, 0);
38
+ return rb_funcall(classnm, id_plus, 1, tos);
39
+ }
40
+
41
+ static method_table_entry sp_methods[] = {
42
+ { "[]", sp_field_get, 1 },
43
+ { "[]=", sp_field_set, 2 },
44
+ { "inspect", sp_inspect, 0 },
45
+ { "maxbound", sp_maxbound, 0 },
46
+ { "minbound", sp_minbound, 0 },
47
+ { "mvals", sp_mvals, 0 },
48
+ { "n_parts", sp_n_parts, 0 },
49
+ { "n_vertices", sp_n_vertices, 0 },
50
+ { "part_start", sp_part_start, 0 },
51
+ { "part_type", sp_part_type, 0 },
52
+ { "shape_type", sp_shape_type, 0 },
53
+ { "shape_id", sp_shape_id, 0 },
54
+ { "to_h", sp_to_h, 0 },
55
+ { "to_s", sp_wkt, 0 },
56
+ { "rewind_polygon", sp_rewind, 0 },
57
+ { "wkt", sp_wkt, 0 },
58
+ { "xvals", sp_xvals, 0 },
59
+ { "yvals", sp_yvals, 0 },
60
+ { "zvals", sp_zvals, 0 },
61
+ { NULL, NULL, 0 }
62
+ };
63
+
64
+ static method_table_entry pt_methods[] = {
65
+ { "m", pt_m, 0 },
66
+ { "wkt", pt_wkt, 0 },
67
+ { "x", pt_x, 0 },
68
+ { "y", pt_y, 0 },
69
+ { "z", pt_z, 0 },
70
+ { NULL, NULL, 0 }
71
+ };
@@ -0,0 +1,219 @@
1
+
2
+ /* safer substitute of strcat(3). I believe strcat is too dangerous.
3
+ */
4
+ static char *StringCat(char *buf, char *src, char *stop)
5
+ {
6
+ if (*buf)
7
+ buf = buf + strlen(buf);
8
+ strncpy(buf, src, stop - buf);
9
+ *stop = '\0';
10
+ return buf + strlen(buf);
11
+ }
12
+
13
+ /* 123..........45678 */
14
+ /* -0.1234567890e-100 */
15
+ static int wkt_dlen = 18;
16
+ static char wkt_dfmt[16] = "%1.10g";
17
+
18
+ static char *DblFmtCat(char *buf, double x, char *stop)
19
+ {
20
+ char fbuf[512];
21
+ sprintf(fbuf, wkt_dfmt, x);
22
+ return StringCat(buf, fbuf, stop);
23
+ }
24
+
25
+ static VALUE pt_wkt(VALUE obj)
26
+ {
27
+ shape_t *self;
28
+ size_t buflen;
29
+ char *buf, *cur, *stop;
30
+ VALUE wkt;
31
+ Data_Get_Struct(obj, shape_t, self);
32
+ buflen = wkt_dlen * 2 + 9;
33
+ cur = buf = xmalloc(buflen + 1);
34
+ stop = buf + buflen;
35
+ strcpy(cur, "POINT(");
36
+ cur = DblFmtCat(cur, self->obj->padfX[0], stop);
37
+ cur = StringCat(cur, " ", stop);
38
+ cur = DblFmtCat(cur, self->obj->padfY[0], stop);
39
+ cur = StringCat(cur, ")", stop);
40
+ wkt = rb_str_new(buf, strlen(buf));
41
+ free(buf);
42
+ return wkt;
43
+ }
44
+
45
+ static VALUE mp_wkt(VALUE obj)
46
+ {
47
+ shape_t *self;
48
+ VALUE wkt;
49
+ size_t buflen;
50
+ char *buf, *cur, *stop;
51
+ int iv;
52
+ Data_Get_Struct(obj, shape_t, self);
53
+ buflen = (2 * wkt_dlen + 3) * self->obj->nVertices + 11;
54
+ cur = buf = xmalloc(buflen + 1);
55
+ stop = buf + buflen;
56
+ strcpy(buf, "MULTIPOINT(");
57
+ for (iv = 0; iv < self->obj->nVertices; iv++) {
58
+ if (iv)
59
+ StringCat(cur, ", ", stop);
60
+ cur = DblFmtCat(cur, self->obj->padfX[iv], stop);
61
+ cur = StringCat(cur, " ", stop);
62
+ cur = DblFmtCat(cur, self->obj->padfY[iv], stop);
63
+ }
64
+ StringCat(cur, ")", stop);
65
+ wkt = rb_str_new(buf, strlen(buf));
66
+ free(buf);
67
+ return wkt;
68
+ }
69
+
70
+ static VALUE WKTSinglePolygon(SHPObject *obj)
71
+ {
72
+ size_t buflen;
73
+ VALUE wkt;
74
+ char *buf, *cur, *stop;
75
+ int ipart, endvert, ivert;
76
+ buflen = (2 * wkt_dlen + 3) * obj->nVertices + obj->nParts * 2 + 9;
77
+ cur = buf = xmalloc(buflen + 1);
78
+ stop = cur + buflen;
79
+ strcpy(buf, "POLYGON(");
80
+ for (ipart = 0; ipart < obj->nParts; ipart++) {
81
+ if (ipart == obj->nParts - 1) {
82
+ endvert = obj->nVertices;
83
+ } else {
84
+ endvert = obj->panPartStart[ipart + 1];
85
+ }
86
+ if (ipart)
87
+ cur = StringCat(cur, ", ", stop);
88
+ cur = StringCat(cur, "(", stop);
89
+ for (ivert = obj->panPartStart[ipart]; ivert < endvert; ivert++) {
90
+ if (ivert > obj->panPartStart[ipart])
91
+ cur = StringCat(cur, ", ", stop);
92
+ cur = DblFmtCat(cur, obj->padfX[ivert], stop);
93
+ cur = StringCat(cur, " ", stop);
94
+ cur = DblFmtCat(cur, obj->padfY[ivert], stop);
95
+ }
96
+ cur = StringCat(cur, ")", stop);
97
+ }
98
+ cur = StringCat(cur, ")", stop);
99
+ wkt = rb_str_new(buf, strlen(buf));
100
+ free(buf);
101
+ return wkt;
102
+ }
103
+
104
+ static VALUE pl_wkt(VALUE obj)
105
+ {
106
+ shape_t *self;
107
+ Data_Get_Struct(obj, shape_t, self);
108
+ /* === BUG ===
109
+ * following code doesn't consider the possibilities:
110
+ * - there may be multiple outer loop in a Polygon Shape.
111
+ * in such a case, it must generate MULTIPOLYGON WKT.
112
+ * - inner loop (hole) may come before outer loop.
113
+ */
114
+ return WKTSinglePolygon(self->obj);
115
+ #if 0
116
+ return WKTMultiPolygon(self->obj);
117
+ #endif
118
+ }
119
+
120
+ static VALUE WKTSingleArc(SHPObject *obj)
121
+ {
122
+ size_t buflen;
123
+ VALUE wkt;
124
+ char *buf, *cur, *stop;
125
+ int ivert;
126
+ buflen = (2 * wkt_dlen + 3) * obj->nVertices + 10;
127
+ cur = buf = xmalloc(buflen + 1);
128
+ stop = cur + buflen;
129
+ strcpy(buf, "LINESTRING(");
130
+ for (ivert = 0; ivert < obj->nVertices; ivert++) {
131
+ if (ivert)
132
+ cur = StringCat(cur, ", ", stop);
133
+ cur = DblFmtCat(cur, obj->padfX[ivert], stop);
134
+ cur = StringCat(cur, " ", stop);
135
+ cur = DblFmtCat(cur, obj->padfY[ivert], stop);
136
+ }
137
+ cur = StringCat(cur, ")", stop);
138
+ wkt = rb_str_new(buf, strlen(buf));
139
+ free(buf);
140
+ return wkt;
141
+ }
142
+
143
+ static VALUE WKTMultiArc(SHPObject *obj)
144
+ {
145
+ size_t buflen;
146
+ VALUE wkt;
147
+ char *buf, *cur, *stop;
148
+ int ipart, endvert, ivert;
149
+ buflen = (2 * wkt_dlen + 3) * obj->nVertices + obj->nParts * 1 + 16;
150
+ cur = buf = xmalloc(buflen + 1);
151
+ stop = cur + buflen;
152
+ strcpy(buf, "MULTILINESTRING(");
153
+ for (ipart = 0; ipart < obj->nParts; ipart++) {
154
+ if (ipart == obj->nParts - 1) {
155
+ endvert = obj->nVertices;
156
+ } else {
157
+ endvert = obj->panPartStart[ipart + 1];
158
+ }
159
+ if (ipart)
160
+ cur = StringCat(cur, ", ", stop);
161
+ cur = StringCat(cur, "(", stop);
162
+ for (ivert = obj->panPartStart[ipart]; ivert < endvert; ivert++) {
163
+ if (ivert > obj->panPartStart[ipart])
164
+ cur = StringCat(cur, ", ", stop);
165
+ cur = DblFmtCat(cur, obj->padfX[ivert], stop);
166
+ cur = StringCat(cur, " ", stop);
167
+ cur = DblFmtCat(cur, obj->padfY[ivert], stop);
168
+ }
169
+ cur = StringCat(cur, ")", stop);
170
+ }
171
+ cur = StringCat(cur, ")", stop);
172
+ wkt = rb_str_new(buf, strlen(buf));
173
+ free(buf);
174
+ return wkt;
175
+ }
176
+
177
+ static VALUE arc_wkt(VALUE obj)
178
+ {
179
+ shape_t *self;
180
+ Data_Get_Struct(obj, shape_t, self);
181
+ if (self->obj->nParts > 1) {
182
+ return WKTMultiArc(self->obj);
183
+ } else {
184
+ return WKTSingleArc(self->obj);
185
+ }
186
+ }
187
+
188
+ static VALUE sp_wkt(VALUE obj)
189
+ {
190
+ shape_t *self;
191
+ Data_Get_Struct(obj, shape_t, self);
192
+ switch (self->obj->nSHPType) {
193
+ case SHPT_POINT:
194
+ case SHPT_POINTM:
195
+ case SHPT_POINTZ:
196
+ return pt_wkt(obj);
197
+ break;
198
+ case SHPT_ARC:
199
+ case SHPT_ARCM:
200
+ case SHPT_ARCZ:
201
+ return arc_wkt(obj);
202
+ break;
203
+ case SHPT_POLYGON:
204
+ case SHPT_POLYGONM:
205
+ case SHPT_POLYGONZ:
206
+ return pl_wkt(obj);
207
+ break;
208
+ case SHPT_MULTIPOINT:
209
+ case SHPT_MULTIPOINTM:
210
+ case SHPT_MULTIPOINTZ:
211
+ return mp_wkt(obj);
212
+ break;
213
+ case SHPT_MULTIPATCH:
214
+ return pl_wkt(obj);
215
+ break;
216
+ }
217
+ rb_bug("invalid shape type %d", self->obj->nSHPType);
218
+ return Qnil;
219
+ }
@@ -0,0 +1,313 @@
1
+ /* valconv.h */
2
+
3
+ #define SECURE(obj) SecureObject((obj), #obj)
4
+
5
+ #define SHP_NODATA_LIM -1.0e-38
6
+ #define SHP_NODATA -2.0e-38
7
+ #define SHP_NUM2DBL(value) (NIL_P(value) ? SHP_NODATA : NUM2DBL(value))
8
+ #define SHP_FLOAT_NEW(f) (((f) < SHP_NODATA_LIM) ? Qnil : rb_float_new((f)))
9
+ #define CSTR2SYM(s) (ID2SYM(rb_intern((s))))
10
+ static int NUM2INT_nil(VALUE v) { return NIL_P(v) ? -1 : NUM2INT(v); }
11
+
12
+ static const_table_entry sl_consts[] = {
13
+ { "String", INT2FIX((int)FTString) },
14
+ { "Integer", INT2FIX((int)FTInteger) },
15
+ { "Float", INT2FIX((int)FTDouble) },
16
+ { "Logical", INT2FIX((int)FTLogical) },
17
+ { NULL, Qnil }
18
+ };
19
+
20
+ static ID *ShapeTypeNameTable(void)
21
+ {
22
+ static ID ids[SHPT_MULTIPATCH + 1];
23
+ if (ids[SHPT_NULL] != 0) {
24
+ return ids;
25
+ }
26
+ ids[SHPT_NULL] = rb_intern("Null");
27
+ ids[SHPT_POINT] = rb_intern("Point");
28
+ ids[SHPT_POINTM] = rb_intern("PointM");
29
+ ids[SHPT_POINTZ] = rb_intern("PointZ");
30
+ ids[SHPT_ARC] = rb_intern("Arc");
31
+ ids[SHPT_ARCM] = rb_intern("ArcM");
32
+ ids[SHPT_ARCZ] = rb_intern("ArcZ");
33
+ ids[SHPT_POLYGON] = rb_intern("Polygon");
34
+ ids[SHPT_POLYGONM] = rb_intern("PolygonM");
35
+ ids[SHPT_POLYGONZ] = rb_intern("PolygonZ");
36
+ ids[SHPT_MULTIPOINT] = rb_intern("MultiPoint");
37
+ ids[SHPT_MULTIPOINTM] = rb_intern("MultiPointM");
38
+ ids[SHPT_MULTIPOINTZ] = rb_intern("MultiPointZ");
39
+ ids[SHPT_MULTIPATCH] = rb_intern("MultiPatch");
40
+ return ids;
41
+ }
42
+
43
+ static ID *FieldTypeNameTable(void)
44
+ {
45
+ static ID ids[FTInvalid + 1];
46
+ if (ids[FTString] != 0) {
47
+ return ids;
48
+ }
49
+ ids[FTString] = rb_intern("String");
50
+ ids[FTInteger] = rb_intern("Integer");
51
+ ids[FTDouble] = rb_intern("Float");
52
+ ids[FTLogical] = rb_intern("Logical");
53
+ ids[FTInvalid] = rb_intern("Invalid");
54
+ return ids;
55
+ }
56
+
57
+ #define SHPP_RING 5
58
+
59
+ static ID *PartTypeNameTable(void)
60
+ {
61
+ static ID ids[6];
62
+ if (ids[0] != 0) {
63
+ return ids;
64
+ }
65
+ ids[0] = rb_intern("TriangleStrip");
66
+ ids[1] = rb_intern("TriangleFan");
67
+ ids[2] = rb_intern("OuterRing");
68
+ ids[3] = rb_intern("InnerRing");
69
+ ids[4] = rb_intern("FirstRing");
70
+ ids[5] = rb_intern("Ring");
71
+ return ids;
72
+ }
73
+
74
+ static int Ruby2PartType(VALUE ptype)
75
+ {
76
+ ID given, *ids;
77
+ int i;
78
+ switch (TYPE(ptype)) {
79
+ case T_STRING:
80
+ case T_SYMBOL:
81
+ given = rb_to_id(ptype);
82
+ ids = PartTypeNameTable();
83
+ for (i = 0; i < 6; i++) {
84
+ if (ids[i] == given)
85
+ return i;
86
+ }
87
+ return -1;
88
+ break;
89
+ case T_FIXNUM:
90
+ return FIX2INT(ptype);
91
+ default:
92
+ return NUM2INT(ptype);
93
+ }
94
+ }
95
+
96
+ static VALUE PartType2Ruby(int part_type)
97
+ {
98
+ if (part_type < 0 || part_type > 5) {
99
+ return INT2NUM(part_type);
100
+ } else {
101
+ ID *ids;
102
+ ids = PartTypeNameTable();
103
+ return ID2SYM(ids[part_type]);
104
+ }
105
+ }
106
+
107
+ static DBFFieldType Ruby2FieldType(VALUE obj)
108
+ {
109
+ if (FIXNUM_P(obj)) {
110
+ int ft = FIX2INT(obj);
111
+ switch (ft) {
112
+ case FTString:
113
+ case FTInteger:
114
+ case FTDouble:
115
+ case FTLogical:
116
+ case FTInvalid:
117
+ return ft;
118
+ default:
119
+ rb_raise(rb_eArgError, "bad field_type %d", ft);
120
+ }
121
+ } else if (TYPE(obj) == T_STRING || TYPE(obj) == T_SYMBOL) {
122
+ ID given, *table;
123
+ int i;
124
+ given = rb_to_id(obj);
125
+ table = FieldTypeNameTable();
126
+ for (i = 0; i < FTInvalid; i++) {
127
+ if (given == table[i])
128
+ return i;
129
+ }
130
+ }
131
+ rb_raise(rb_eArgError, "bad field_type");
132
+ }
133
+
134
+ static VALUE FieldType2Ruby(DBFFieldType ftype)
135
+ {
136
+ int ft;
137
+ ft = ftype;
138
+ if (ft < 0 || ft >= FTInvalid)
139
+ return INT2FIX(ft);
140
+ return ID2SYM(FieldTypeNameTable()[ft]);
141
+ }
142
+
143
+ static VALUE ShapeType2Class(int nSHPType, VALUE klass)
144
+ {
145
+ switch (nSHPType) {
146
+ case SHPT_POINT: return cPoint;
147
+ case SHPT_POINTM: return cPointM;
148
+ case SHPT_POINTZ: return cPointZ;
149
+ case SHPT_ARC: return cArc;
150
+ case SHPT_ARCM: return cArcM;
151
+ case SHPT_ARCZ: return cArcZ;
152
+ case SHPT_POLYGON: return cPolygon;
153
+ case SHPT_POLYGONM: return cPolygonM;
154
+ case SHPT_POLYGONZ: return cPolygonZ;
155
+ case SHPT_MULTIPOINT: return cMultiPoint;
156
+ case SHPT_MULTIPOINTM: return cMultiPointM;
157
+ case SHPT_MULTIPOINTZ: return cMultiPointZ;
158
+ case SHPT_MULTIPATCH: return cMultiPatch;
159
+ case SHPT_NULL:
160
+ default:
161
+ return klass;
162
+ }
163
+ }
164
+
165
+ static VALUE ShapeType2Ruby(int nSHPType)
166
+ {
167
+ ID *ids;
168
+ switch (nSHPType) {
169
+ case SHPT_NULL:
170
+ case SHPT_POINT: case SHPT_POINTM: case SHPT_POINTZ:
171
+ case SHPT_ARC: case SHPT_ARCM: case SHPT_ARCZ:
172
+ case SHPT_POLYGON: case SHPT_POLYGONM: case SHPT_POLYGONZ:
173
+ case SHPT_MULTIPOINT: case SHPT_MULTIPOINTM: case SHPT_MULTIPOINTZ:
174
+ case SHPT_MULTIPATCH:
175
+ ids = ShapeTypeNameTable();
176
+ return ID2SYM(ids[nSHPType]);
177
+ default:
178
+ return INT2FIX(nSHPType);
179
+ }
180
+ }
181
+
182
+ static int ClassIs(VALUE a, VALUE b)
183
+ {
184
+ VALUE r;
185
+ static ID le = 0;
186
+ if (le == 0) {
187
+ le = rb_intern("<=");
188
+ }
189
+ r = rb_funcall(a, le, 1, b);
190
+ switch (TYPE(r)) {
191
+ case T_TRUE:
192
+ return 1;
193
+ case T_FALSE:
194
+ case T_NIL:
195
+ return 0;
196
+ default:
197
+ return -1;
198
+ }
199
+ }
200
+
201
+ static int ShapeClass_to_Int(VALUE klass)
202
+ {
203
+ if (ClassIs(klass, cPoint)) {
204
+ if (ClassIs(klass, cPointZ)) {
205
+ return SHPT_POINTZ;
206
+ } else if (ClassIs(klass, cPointM)) {
207
+ return SHPT_POINTM;
208
+ }
209
+ return SHPT_POINT;
210
+ } else if (ClassIs(klass, cArc)) {
211
+ if (ClassIs(klass, cArcZ)) {
212
+ return SHPT_ARCZ;
213
+ } else if (ClassIs(klass, cArcM)) {
214
+ return SHPT_ARCM;
215
+ }
216
+ return SHPT_ARC;
217
+ } else if (ClassIs(klass, cPolygon)) {
218
+ if (ClassIs(klass, cPolygonZ)) {
219
+ return SHPT_POLYGONZ;
220
+ } else if (ClassIs(klass, cPolygonM)) {
221
+ return SHPT_POLYGONM;
222
+ }
223
+ return SHPT_POLYGON;
224
+ } else if (ClassIs(klass, cMultiPoint)) {
225
+ if (ClassIs(klass, cMultiPointZ)) {
226
+ return SHPT_MULTIPOINTZ;
227
+ } else if (ClassIs(klass, cMultiPointM)) {
228
+ return SHPT_MULTIPOINTM;
229
+ }
230
+ return SHPT_MULTIPOINT;
231
+ } else if (ClassIs(klass, cMultiPatch)) {
232
+ return SHPT_MULTIPATCH;
233
+ } else {
234
+ rb_raise(rb_eArgError, "invalid class");
235
+ }
236
+ }
237
+
238
+ static int ShapeSym_to_Int(VALUE stype)
239
+ {
240
+ ID arg, *ids;
241
+ int i;
242
+ ids = ShapeTypeNameTable();
243
+ arg = rb_to_id(stype);
244
+ for (i = 0; i <= SHPT_MULTIPATCH; i++) {
245
+ if (arg == ids[i])
246
+ return i;
247
+ }
248
+ rb_raise(rb_eArgError, "invalid shape class name");
249
+ return -1;
250
+ }
251
+
252
+ static int Ruby2ShapeType(VALUE stype)
253
+ {
254
+ switch (TYPE(stype)) {
255
+ case T_FIXNUM:
256
+ return FIX2INT(stype);
257
+ case T_CLASS:
258
+ return ShapeClass_to_Int(stype);
259
+ case T_STRING:
260
+ case T_SYMBOL:
261
+ return ShapeSym_to_Int(stype);
262
+ default:
263
+ rb_raise(rb_eArgError, "shape_type is Integer/String/Symbol/Class");
264
+ }
265
+ }
266
+
267
+ static VALUE DoubleUnpack(double *dp, unsigned num)
268
+ {
269
+ VALUE ary;
270
+ int i;
271
+ ary = rb_ary_new2(num);
272
+ for (i = 0; i < num; i++) {
273
+ rb_ary_push(ary, rb_float_new(dp[i]));
274
+ }
275
+ return ary;
276
+ }
277
+
278
+ static VALUE DoubleUnpackM(double *dp, unsigned num, int mpos)
279
+ {
280
+ VALUE ary;
281
+ int i;
282
+ ary = rb_ary_new2(num);
283
+ for (i = 0; i < num; i++) {
284
+ if ((mpos == -1) || (i == mpos)) {
285
+ rb_ary_push(ary, SHP_FLOAT_NEW(dp[i]));
286
+ } else {
287
+ rb_ary_push(ary, rb_float_new(dp[i]));
288
+ }
289
+ }
290
+ return ary;
291
+ }
292
+
293
+ static VALUE IntUnpack(int *up, unsigned num)
294
+ {
295
+ static ID unpackid;
296
+ static VALUE unpackfmt = 0;
297
+ VALUE buf;
298
+ if (unpackfmt == 0) {
299
+ unpackid = rb_intern("unpack");
300
+ unpackfmt = rb_str_new2("i*");
301
+ rb_global_variable(&unpackfmt);
302
+ }
303
+ buf = rb_str_new((char *)up, sizeof(int) * num);
304
+ return rb_funcall(buf, unpackid, 1, unpackfmt);
305
+ }
306
+
307
+ static VALUE SecureObject(VALUE obj, const char *name) {
308
+ if (OBJ_TAINTED(obj) && rb_safe_level() >= 1) {
309
+ rb_raise(rb_eSecurityError, "tainted %s", name);
310
+ }
311
+ return obj;
312
+ }
313
+