ruby-oci8 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. data/ChangeLog +569 -0
  2. data/Makefile +51 -0
  3. data/NEWS +322 -0
  4. data/README +415 -0
  5. data/VERSION +1 -0
  6. data/dist-files +70 -0
  7. data/doc/api.en.html +527 -0
  8. data/doc/api.en.rd +554 -0
  9. data/doc/api.ja.html +525 -0
  10. data/doc/api.ja.rd +557 -0
  11. data/doc/manual.css +35 -0
  12. data/ext/oci8/MANIFEST +22 -0
  13. data/ext/oci8/attr.c +415 -0
  14. data/ext/oci8/bind.c +194 -0
  15. data/ext/oci8/const.c +165 -0
  16. data/ext/oci8/define.c +53 -0
  17. data/ext/oci8/describe.c +81 -0
  18. data/ext/oci8/descriptor.c +39 -0
  19. data/ext/oci8/env.c +276 -0
  20. data/ext/oci8/error.c +234 -0
  21. data/ext/oci8/extconf.rb +118 -0
  22. data/ext/oci8/handle.c +262 -0
  23. data/ext/oci8/lob.c +386 -0
  24. data/ext/oci8/oci8.c +137 -0
  25. data/ext/oci8/oci8.h +345 -0
  26. data/ext/oci8/ocinumber.c +117 -0
  27. data/ext/oci8/oraconf.rb +1026 -0
  28. data/ext/oci8/oradate.c +426 -0
  29. data/ext/oci8/oranumber.c +445 -0
  30. data/ext/oci8/param.c +37 -0
  31. data/ext/oci8/post-config.rb +5 -0
  32. data/ext/oci8/server.c +182 -0
  33. data/ext/oci8/session.c +99 -0
  34. data/ext/oci8/stmt.c +624 -0
  35. data/ext/oci8/svcctx.c +229 -0
  36. data/lib/DBD/OCI8/OCI8.rb +549 -0
  37. data/lib/oci8.rb.in +1605 -0
  38. data/metaconfig +142 -0
  39. data/pre-distclean.rb +7 -0
  40. data/ruby-oci8.gemspec +54 -0
  41. data/ruby-oci8.spec +62 -0
  42. data/setup.rb +1331 -0
  43. data/support/README +4 -0
  44. data/support/runit/assert.rb +281 -0
  45. data/support/runit/cui/testrunner.rb +101 -0
  46. data/support/runit/error.rb +4 -0
  47. data/support/runit/method_mappable.rb +20 -0
  48. data/support/runit/robserver.rb +25 -0
  49. data/support/runit/setuppable.rb +15 -0
  50. data/support/runit/teardownable.rb +16 -0
  51. data/support/runit/testcase.rb +113 -0
  52. data/support/runit/testfailure.rb +25 -0
  53. data/support/runit/testresult.rb +121 -0
  54. data/support/runit/testsuite.rb +43 -0
  55. data/support/runit/version.rb +3 -0
  56. data/test/README +4 -0
  57. data/test/config.rb +129 -0
  58. data/test/test_all.rb +43 -0
  59. data/test/test_bind_raw.rb +53 -0
  60. data/test/test_bind_time.rb +191 -0
  61. data/test/test_break.rb +81 -0
  62. data/test/test_clob.rb +101 -0
  63. data/test/test_connstr.rb +80 -0
  64. data/test/test_dbi.rb +317 -0
  65. data/test/test_dbi_clob.rb +56 -0
  66. data/test/test_describe.rb +137 -0
  67. data/test/test_metadata.rb +243 -0
  68. data/test/test_oci8.rb +273 -0
  69. data/test/test_oradate.rb +263 -0
  70. data/test/test_oranumber.rb +149 -0
  71. metadata +118 -0
@@ -0,0 +1,426 @@
1
+ /*
2
+ oradate.c - part of ruby-oci8
3
+
4
+ Copyright (C) 2002 KUBO Takehiro <kubo@jiubao.org>
5
+
6
+ =begin
7
+ == OraDate
8
+ date and time between 4712 B.C. and 9999 A.D.
9
+ =end
10
+ */
11
+ #include "oci8.h"
12
+ #include <time.h>
13
+
14
+ #define Set_year(od, y) (od)->century = y / 100 + 100, (od)->year = y % 100 + 100
15
+ #define Set_month(od, m) (od)->month = m
16
+ #define Set_day(od, d) (od)->day = d
17
+ #define Set_hour(od, h) (od)->hour = h + 1
18
+ #define Set_minute(od, m) (od)->minute = m + 1
19
+ #define Set_second(od, s) (od)->second = s + 1
20
+
21
+ #define Get_year(od) (((od)->century - 100) * 100 + ((od)->year - 100))
22
+ #define Get_month(od) ((od)->month)
23
+ #define Get_day(od) ((od)->day)
24
+ #define Get_hour(od) ((od)->hour - 1)
25
+ #define Get_minute(od) ((od)->minute - 1)
26
+ #define Get_second(od) ((od)->second - 1)
27
+
28
+ #define Check_year(year) \
29
+ if (year < -4712 || 9999 < year) \
30
+ rb_raise(rb_eRangeError, "Out of range for year %d (expect -4712 .. 9999)", year)
31
+ #define Check_month(month) \
32
+ if (month < 1 || 12 < month) \
33
+ rb_raise(rb_eRangeError, "Out of range for month %d (expect 1 .. 12)", month)
34
+ #define Check_day(day) \
35
+ if (day < 1 || 31 < day) \
36
+ rb_raise(rb_eRangeError, "Out of range for day %d (expect 1 .. 31)", day)
37
+ #define Check_hour(hour) \
38
+ if (hour < 0 || 23 < hour) \
39
+ rb_raise(rb_eRangeError, "Out of range for hour %d (expect 0 .. 24)", hour)
40
+ #define Check_minute(min) \
41
+ if (min < 0 || 59 < min) \
42
+ rb_raise(rb_eRangeError, "Out of range for minute %d (expect 0 .. 59)", min)
43
+ #define Check_second(sec) \
44
+ if (sec < 0 || 59 < sec) \
45
+ rb_raise(rb_eRangeError, "Out of range for second %d (expect 0 .. 59)", sec)
46
+
47
+
48
+ static VALUE ora_date_s_allocate(VALUE klass)
49
+ {
50
+ ora_date_t *od;
51
+ return Data_Make_Struct(klass, ora_date_t, NULL, xfree, od);
52
+ }
53
+
54
+ #ifndef HAVE_RB_DEFINE_ALLOC_FUNC
55
+ /* ruby 1.6 */
56
+ static VALUE ora_date_s_new(int argc, VALUE *argv, VALUE klass)
57
+ {
58
+ VALUE obj = ora_date_s_allocate(klass);
59
+ rb_obj_call_init(obj, argc, argv);
60
+ return obj;
61
+ }
62
+ #endif
63
+
64
+ /*
65
+ =begin
66
+ --- OraDate.new([year [, month [, day [, hour [, min [,sec]]]]]])
67
+ =end
68
+ */
69
+ static VALUE ora_date_initialize(int argc, VALUE *argv, VALUE self)
70
+ {
71
+ VALUE vyear, vmonth, vday, vhour, vmin, vsec;
72
+ ora_date_t *od;
73
+ int year, month, day, hour, min, sec;
74
+
75
+ rb_scan_args(argc, argv, "06", &vyear, &vmonth, &vday, &vhour, &vmin, &vsec);
76
+ /* set year */
77
+ if (argc > 0) {
78
+ year = NUM2INT(vyear);
79
+ Check_year(year);
80
+ } else {
81
+ year = 1;
82
+ }
83
+ /* set month */
84
+ if (argc > 1) {
85
+ month = NUM2INT(vmonth);
86
+ Check_month(month);
87
+ } else {
88
+ month = 1;
89
+ }
90
+ /* set day */
91
+ if (argc > 2) {
92
+ day = NUM2INT(vday);
93
+ Check_day(day);
94
+ } else {
95
+ day = 1;
96
+ }
97
+ /* set hour */
98
+ if (argc > 3) {
99
+ hour = NUM2INT(vhour);
100
+ Check_hour(hour);
101
+ } else {
102
+ hour = 0;
103
+ }
104
+ /* set minute */
105
+ if (argc > 4) {
106
+ min = NUM2INT(vmin);
107
+ Check_minute(min);
108
+ } else {
109
+ min = 0;
110
+ }
111
+ /* set second */
112
+ if (argc > 5) {
113
+ sec = NUM2INT(vsec);
114
+ Check_second(sec);
115
+ } else {
116
+ sec = 0;
117
+ }
118
+
119
+ Data_Get_Struct(self, ora_date_t, od);
120
+ oci8_set_ora_date(od, year, month, day, hour, min, sec);
121
+ return Qnil;
122
+ }
123
+
124
+ static VALUE ora_date_initialize_copy(VALUE lhs, VALUE rhs)
125
+ {
126
+ ora_date_t *l, *r;
127
+
128
+ #ifdef HAVE_RB_DEFINE_ALLOC_FUNC
129
+ /* ruby 1.8 */
130
+ rb_obj_init_copy(lhs, rhs);
131
+ #endif
132
+ Data_Get_Struct(lhs, ora_date_t, l);
133
+ Data_Get_Struct(rhs, ora_date_t, r);
134
+ memcpy(l, r, sizeof(ora_date_t));
135
+ return lhs;
136
+ }
137
+
138
+ #ifndef HAVE_RB_DEFINE_ALLOC_FUNC
139
+ /* ruby 1.6 */
140
+ static VALUE ora_date_clone(VALUE self)
141
+ {
142
+ VALUE obj = ora_date_s_allocate(CLASS_OF(self));
143
+ return ora_date_initialize_copy(obj, self);
144
+ }
145
+ #endif
146
+
147
+ /*
148
+ =begin
149
+ --- OraDate.now()
150
+ =end
151
+ */
152
+ static VALUE ora_date_s_now(int argc, VALUE *argv)
153
+ {
154
+ ora_date_t *od;
155
+ VALUE obj;
156
+ int year, month, day, hour, min, sec;
157
+ time_t tm;
158
+ struct tm *tp;
159
+
160
+ tm = time(0);
161
+ tp = localtime(&tm);
162
+ year = tp->tm_year + 1900;
163
+ month = tp->tm_mon + 1;
164
+ day = tp->tm_mday;
165
+ hour = tp->tm_hour;
166
+ min = tp->tm_min;
167
+ sec = tp->tm_sec;
168
+
169
+ obj = Data_Make_Struct(cOraDate, ora_date_t, NULL, xfree, od);
170
+ oci8_set_ora_date(od, year, month, day, hour, min, sec);
171
+ return obj;
172
+ }
173
+
174
+ /*
175
+ =begin
176
+ --- OraDate#to_s()
177
+ =end
178
+ */
179
+ static VALUE ora_date_to_s(VALUE self)
180
+ {
181
+ ora_date_t *od;
182
+ char buf[30];
183
+
184
+ Data_Get_Struct(self, ora_date_t, od);
185
+ sprintf(buf, "%04d/%02d/%02d %02d:%02d:%02d", Get_year(od), Get_month(od),
186
+ Get_day(od), Get_hour(od), Get_minute(od), Get_second(od));
187
+ return rb_str_new2(buf);
188
+ }
189
+
190
+ /*
191
+ =begin
192
+ --- OraDate#to_a()
193
+ =end
194
+ */
195
+ static VALUE ora_date_to_a(VALUE self)
196
+ {
197
+ ora_date_t *od;
198
+ VALUE ary[6];
199
+
200
+ Data_Get_Struct(self, ora_date_t, od);
201
+ ary[0] = INT2FIX(Get_year(od));
202
+ ary[1] = INT2FIX(Get_month(od));
203
+ ary[2] = INT2FIX(Get_day(od));
204
+ ary[3] = INT2FIX(Get_hour(od));
205
+ ary[4] = INT2FIX(Get_minute(od));
206
+ ary[5] = INT2FIX(Get_second(od));
207
+ return rb_ary_new4(6, ary);
208
+ }
209
+
210
+ #define DEFINE_GETTER_FUNC(where) \
211
+ static VALUE ora_date_##where(VALUE self) \
212
+ { \
213
+ ora_date_t *od; \
214
+ \
215
+ Data_Get_Struct(self, ora_date_t, od); \
216
+ return INT2FIX(Get_##where(od)); \
217
+ }
218
+
219
+ #define DEFINE_SETTER_FUNC(where) \
220
+ static VALUE ora_date_set_##where(VALUE self, VALUE val) \
221
+ { \
222
+ ora_date_t *od; \
223
+ int v; \
224
+ \
225
+ v = NUM2INT(val); \
226
+ Check_##where(v); \
227
+ Data_Get_Struct(self, ora_date_t, od); \
228
+ Set_##where(od, v); \
229
+ return self; \
230
+ }
231
+
232
+ /*
233
+ =begin
234
+ --- OraDate#year
235
+ =end
236
+ */
237
+ DEFINE_GETTER_FUNC(year)
238
+ DEFINE_SETTER_FUNC(year)
239
+
240
+ /*
241
+ =begin
242
+ --- OraDate#month
243
+ =end
244
+ */
245
+ DEFINE_GETTER_FUNC(month)
246
+ DEFINE_SETTER_FUNC(month)
247
+
248
+ /*
249
+ =begin
250
+ --- OraDate#day
251
+ =end
252
+ */
253
+ DEFINE_GETTER_FUNC(day)
254
+ DEFINE_SETTER_FUNC(day)
255
+
256
+ /*
257
+ =begin
258
+ --- OraDate#hour
259
+ =end
260
+ */
261
+ DEFINE_GETTER_FUNC(hour)
262
+ DEFINE_SETTER_FUNC(hour)
263
+
264
+ /*
265
+ =begin
266
+ --- OraDate#minute
267
+ =end
268
+ */
269
+ DEFINE_GETTER_FUNC(minute)
270
+ DEFINE_SETTER_FUNC(minute)
271
+
272
+ /*
273
+ =begin
274
+ --- OraDate#second
275
+ =end
276
+ */
277
+ DEFINE_GETTER_FUNC(second)
278
+ DEFINE_SETTER_FUNC(second)
279
+
280
+ /*
281
+ =begin
282
+ --- OraDate#trunc()
283
+ =end
284
+ */
285
+ static VALUE ora_date_trunc(VALUE self)
286
+ {
287
+ ora_date_t *od;
288
+
289
+ Data_Get_Struct(self, ora_date_t, od);
290
+ od->hour = 1;
291
+ od->minute = 1;
292
+ od->second = 1;
293
+ return self;
294
+ }
295
+
296
+ static VALUE ora_date_hash(VALUE self)
297
+ {
298
+ ora_date_t *od;
299
+ unsigned int v;
300
+
301
+ Data_Get_Struct(self, ora_date_t, od);
302
+ v = (od->century << 8)
303
+ + (od->year << 15)
304
+ + (od->month << 22)
305
+ + (od->day << 26)
306
+ + (od->hour << 12)
307
+ + (od->minute << 6)
308
+ + (od->second << 0);
309
+ return INT2FIX(v);
310
+ }
311
+
312
+ /*
313
+ =begin
314
+ --- OraDate#<=>(other)
315
+ =end
316
+ */
317
+ static VALUE ora_date_cmp(VALUE self, VALUE val)
318
+ {
319
+ ora_date_t *od1, *od2;
320
+ Data_Get_Struct(self, ora_date_t, od1);
321
+ Data_Get_Struct(val, ora_date_t, od2);
322
+ if (od1->century < od2->century) return INT2FIX(-1);
323
+ if (od1->century > od2->century) return INT2FIX(1);
324
+ if (od1->year < od2->year) return INT2FIX(-1);
325
+ if (od1->year > od2->year) return INT2FIX(1);
326
+ if (od1->month < od2->month) return INT2FIX(-1);
327
+ if (od1->month > od2->month) return INT2FIX(1);
328
+ if (od1->day < od2->day) return INT2FIX(-1);
329
+ if (od1->day > od2->day) return INT2FIX(1);
330
+ if (od1->hour < od2->hour) return INT2FIX(-1);
331
+ if (od1->hour > od2->hour) return INT2FIX(1);
332
+ if (od1->minute < od2->minute) return INT2FIX(-1);
333
+ if (od1->minute > od2->minute) return INT2FIX(1);
334
+ if (od1->second < od2->second) return INT2FIX(-1);
335
+ if (od1->second > od2->second) return INT2FIX(1);
336
+ return INT2FIX(0);
337
+ }
338
+
339
+ static VALUE ora_date_dump(int argc, VALUE *argv, VALUE self)
340
+ {
341
+ ora_date_t *od;
342
+ Data_Get_Struct(self, ora_date_t, od);
343
+ return rb_str_new((const char*)od, sizeof(ora_date_t));
344
+ }
345
+
346
+ static VALUE ora_date_s_load(VALUE klass, VALUE str)
347
+ {
348
+ ora_date_t *od;
349
+ VALUE obj;
350
+
351
+ Check_Type(str, T_STRING);
352
+ if (RSTRING_LEN(str) != sizeof(ora_date_t)) {
353
+ rb_raise(rb_eTypeError, "marshaled OraDate format differ");
354
+ }
355
+ obj = Data_Make_Struct(cOraDate, ora_date_t, NULL, xfree, od);
356
+ memcpy(od, RSTRING_PTR(str), sizeof(ora_date_t));
357
+ return obj;
358
+ }
359
+
360
+ void Init_ora_date(void)
361
+ {
362
+ #ifdef HAVE_RB_DEFINE_ALLOC_FUNC
363
+ /* ruby 1.8 */
364
+ rb_define_alloc_func(cOraDate, RUBY_METHOD_FUNC(ora_date_s_allocate));
365
+ rb_define_method(cOraDate, "initialize", ora_date_initialize, -1);
366
+ rb_define_method(cOraDate, "initialize_copy", ora_date_initialize_copy, 1);
367
+ #else
368
+ /* ruby 1.6 */
369
+ rb_define_singleton_method(cOraDate, "new", ora_date_s_new, -1);
370
+ rb_define_method(cOraDate, "initialize", ora_date_initialize, -1);
371
+ rb_define_method(cOraDate, "clone", ora_date_clone, 0);
372
+ rb_define_method(cOraDate, "dup", ora_date_clone, 0);
373
+ #endif
374
+
375
+ rb_define_singleton_method(cOraDate, "now", ora_date_s_now, 0);
376
+ rb_define_method(cOraDate, "to_s", ora_date_to_s, 0);
377
+ rb_define_method(cOraDate, "to_a", ora_date_to_a, 0);
378
+
379
+ rb_define_method(cOraDate, "year", ora_date_year, 0);
380
+ rb_define_method(cOraDate, "year=", ora_date_set_year, 1);
381
+
382
+ rb_define_method(cOraDate, "month", ora_date_month, 0);
383
+ rb_define_method(cOraDate, "month=", ora_date_set_month, 1);
384
+
385
+ rb_define_method(cOraDate, "day", ora_date_day, 0);
386
+ rb_define_method(cOraDate, "day=", ora_date_set_day, 1);
387
+
388
+ rb_define_method(cOraDate, "hour", ora_date_hour, 0);
389
+ rb_define_method(cOraDate, "hour=", ora_date_set_hour, 1);
390
+
391
+ rb_define_method(cOraDate, "minute", ora_date_minute, 0);
392
+ rb_define_method(cOraDate, "minute=", ora_date_set_minute, 1);
393
+
394
+ rb_define_method(cOraDate, "second", ora_date_second, 0);
395
+ rb_define_method(cOraDate, "second=", ora_date_set_second, 1);
396
+
397
+ rb_define_method(cOraDate, "trunc", ora_date_trunc, 0);
398
+
399
+ rb_define_method(cOraDate, "<=>", ora_date_cmp, 1);
400
+ rb_include_module(cOraDate, rb_mComparable);
401
+
402
+ rb_define_method(cOraDate, "hash", ora_date_hash, 0);
403
+
404
+ rb_define_method(cOraDate, "_dump", ora_date_dump, -1);
405
+ rb_define_singleton_method(cOraDate, "_load", ora_date_s_load, 1);
406
+ }
407
+
408
+ void oci8_set_ora_date(ora_date_t *od, int year, int month, int day, int hour, int minute, int second)
409
+ {
410
+ Set_year(od, year);
411
+ Set_month(od, month);
412
+ Set_day(od, day);
413
+ Set_hour(od, hour);
414
+ Set_minute(od, minute);
415
+ Set_second(od, second);
416
+ }
417
+
418
+ void oci8_get_ora_date(ora_date_t *od, int *year, int *month, int *day, int *hour, int *minute, int *second)
419
+ {
420
+ *year = Get_year(od);
421
+ *month = Get_month(od);
422
+ *day = Get_day(od);
423
+ *hour = Get_hour(od);
424
+ *minute = Get_minute(od);
425
+ *second = Get_second(od);
426
+ }
@@ -0,0 +1,445 @@
1
+ /*
2
+ oranumber.c - part of ruby-oci8
3
+
4
+ Copyright (C) 2002 KUBO Takehiro <kubo@jiubao.org>
5
+
6
+ =begin
7
+ == OraNumber
8
+ This is not a numeric class, so algebra operations and setter methods
9
+ are not permitted, but a place to hold fetched date from Oracle server.
10
+
11
+ In fact as matter, this is a test class to check the algorithm to
12
+ convert Oracle internal number format to Ruby's number, which is internally used by,
13
+ for example, ((<OCIStmt#attrGet|OCIHandle#attrGet>))(((<OCI_ATTR_MIN>))).
14
+ =end
15
+ */
16
+ #include "oci8.h"
17
+ #include "math.h"
18
+
19
+ #define Get_Sign(on) ((on)->exponent & 0x80)
20
+ #define Get_Exp_Part(on) ((on)->exponent & 0x7F)
21
+ #define Get_Exponent(on) (Get_Sign(on) ? (Get_Exp_Part(on) - 65) : (~(Get_Exp_Part(on)) + 63))
22
+ #define Get_Mantissa_At(on, i) (Get_Sign(on) ? (on)->mantissa[i] - 1 : 101 - (on)->mantissa[i])
23
+
24
+ static int ora_number_from_str(ora_vnumber_t *ovn, unsigned char *buf, size_t len);
25
+
26
+ static ora_vnumber_t *get_ora_number(VALUE self)
27
+ {
28
+ ora_vnumber_t *ovn;
29
+ Data_Get_Struct(self, ora_vnumber_t, ovn);
30
+ return ovn;
31
+ }
32
+
33
+ static VALUE ora_number_s_allocate(VALUE klass)
34
+ {
35
+ ora_vnumber_t *ovn;
36
+ return Data_Make_Struct(klass, ora_vnumber_t, NULL, xfree, ovn);
37
+ }
38
+
39
+ #ifndef HAVE_RB_DEFINE_ALLOC_FUNC
40
+ /* ruby 1.6 */
41
+ static VALUE ora_number_s_new(int argc, VALUE *argv, VALUE klass)
42
+ {
43
+ VALUE obj = ora_number_s_allocate(klass);
44
+ rb_obj_call_init(obj, argc, argv);
45
+ return obj;
46
+ }
47
+ #endif
48
+
49
+ /*
50
+ =begin
51
+ --- OraNumber.new()
52
+ =end
53
+ */
54
+ static VALUE ora_number_initialize(int argc, VALUE *argv, VALUE self)
55
+ {
56
+ ora_vnumber_t *ovn = get_ora_number(self);
57
+ volatile VALUE arg;
58
+
59
+ rb_scan_args(argc, argv, "01", &arg);
60
+ ovn->size = 1;
61
+ ovn->num.exponent = 0x80;
62
+ memset(ovn->num.mantissa, 0, sizeof(ovn->num.mantissa));
63
+ if (argc == 1) {
64
+ if (TYPE(arg) != T_STRING) {
65
+ arg = rb_obj_as_string(arg);
66
+ }
67
+ if (ora_number_from_str(ovn, RSTRING_ORATEXT(arg), RSTRING_LEN(arg)) != 0) {
68
+ rb_raise(rb_eArgError, "could not convert '%s' to OraNumber", RSTRING_PTR(arg));
69
+ }
70
+ }
71
+ return Qnil;
72
+ }
73
+
74
+ static VALUE ora_number_initialize_copy(VALUE lhs, VALUE rhs)
75
+ {
76
+ ora_vnumber_t *l, *r;
77
+
78
+ #ifdef HAVE_RB_DEFINE_ALLOC_FUNC
79
+ /* ruby 1.8 */
80
+ rb_obj_init_copy(lhs, rhs);
81
+ #endif
82
+ Data_Get_Struct(lhs, ora_vnumber_t, l);
83
+ Data_Get_Struct(rhs, ora_vnumber_t, r);
84
+ memcpy(l, r, sizeof(ora_vnumber_t));
85
+ return lhs;
86
+ }
87
+
88
+ static VALUE ora_number_clone(VALUE self)
89
+ {
90
+ VALUE obj = ora_number_s_allocate(CLASS_OF(self));
91
+ return ora_number_initialize_copy(obj, self);
92
+ }
93
+
94
+ /*
95
+ =begin
96
+ --- OraNumber#to_i()
97
+ =end
98
+ */
99
+ static VALUE ora_number_to_i(VALUE self)
100
+ {
101
+ ora_vnumber_t *ovn = get_ora_number(self);
102
+ unsigned char buf[ORA_NUMBER_BUF_SIZE];
103
+
104
+ ora_number_to_str(buf, NULL, &(ovn->num), ovn->size);
105
+ return rb_cstr2inum(TO_CHARPTR(buf), 10);
106
+ }
107
+
108
+ /*
109
+ =begin
110
+ --- OraNumber#to_f()
111
+ =end
112
+ */
113
+ static VALUE ora_number_to_f(VALUE self)
114
+ {
115
+ ora_vnumber_t *ovn = get_ora_number(self);
116
+ unsigned char buf[ORA_NUMBER_BUF_SIZE];
117
+
118
+ ora_number_to_str(buf, NULL, &(ovn->num), ovn->size);
119
+ return rb_float_new(rb_cstr_to_dbl(TO_CHARPTR(buf), Qfalse));
120
+ }
121
+
122
+ /*
123
+ =begin
124
+ --- OraNumber#to_s()
125
+ =end
126
+ */
127
+ static VALUE ora_number_to_s(VALUE self)
128
+ {
129
+ ora_vnumber_t *ovn = get_ora_number(self);
130
+ unsigned char buf[ORA_NUMBER_BUF_SIZE];
131
+ size_t len;
132
+
133
+ ora_number_to_str(buf, &len, &(ovn->num), ovn->size);
134
+ return rb_str_new(TO_CHARPTR(buf), len);
135
+ }
136
+
137
+ static VALUE ora_number_uminus(VALUE self)
138
+ {
139
+ ora_vnumber_t *ovn = get_ora_number(self);
140
+ VALUE obj;
141
+ int i;
142
+
143
+ if (ovn->num.exponent == 0x80)
144
+ return self;
145
+ obj = ora_number_clone(self);
146
+ ovn = get_ora_number(obj);
147
+ ovn->num.exponent = ~(ovn->num.exponent);
148
+ for (i = 0;i < ovn->size - 1;i++)
149
+ ovn->num.mantissa[i] = 102 - ovn->num.mantissa[i];
150
+ if (Get_Sign(&(ovn->num))) {
151
+ if (ovn->size != 21 || ovn->num.mantissa[19] == 0x00) {
152
+ ovn->size--;
153
+ }
154
+ } else {
155
+ if (ovn->size != 21) {
156
+ ovn->num.mantissa[ovn->size - 1] = 102;
157
+ ovn->size++;
158
+ }
159
+ }
160
+ return obj;
161
+ }
162
+
163
+ static VALUE ora_number_dump(int argc, VALUE *argv, VALUE self)
164
+ {
165
+ ora_vnumber_t *ovn = get_ora_number(self);
166
+ unsigned char i;
167
+ for (i = ovn->size - 1; i < 20; i++) {
168
+ ovn->num.mantissa[i] = 0;
169
+ }
170
+ return rb_str_new((const char*)ovn, sizeof(ora_vnumber_t));
171
+ }
172
+
173
+ static VALUE ora_number_s_load(VALUE klass, VALUE str)
174
+ {
175
+ ora_vnumber_t *ovn;
176
+ VALUE obj;
177
+
178
+ Check_Type(str, T_STRING);
179
+ if (RSTRING_LEN(str) != sizeof(ora_vnumber_t)) {
180
+ rb_raise(rb_eTypeError, "marshaled OraNumber format differ");
181
+ }
182
+ obj = ora_number_s_allocate(klass);
183
+ ovn = get_ora_number(obj);
184
+ memcpy(ovn, RSTRING_PTR(str), sizeof(ora_vnumber_t));
185
+ return obj;
186
+ }
187
+
188
+ void Init_ora_number(void)
189
+ {
190
+ #ifdef HAVE_RB_DEFINE_ALLOC_FUNC
191
+ /* ruby 1.8 */
192
+ rb_define_alloc_func(cOraNumber, RUBY_METHOD_FUNC(ora_number_s_allocate));
193
+ rb_define_method(cOraNumber, "initialize", ora_number_initialize, -1);
194
+ rb_define_method(cOraNumber, "initialize_copy", ora_number_initialize_copy, 1);
195
+ #else
196
+ /* ruby 1.6 */
197
+ rb_define_singleton_method(cOraNumber, "new", ora_number_s_new, -1);
198
+ rb_define_method(cOraNumber, "initialize", ora_number_initialize, -1);
199
+ rb_define_method(cOraNumber, "clone", ora_number_clone, 0);
200
+ rb_define_method(cOraNumber, "dup", ora_number_clone, 0);
201
+ #endif
202
+
203
+ rb_define_method(cOraNumber, "to_i", ora_number_to_i, 0);
204
+ rb_define_method(cOraNumber, "to_f", ora_number_to_f, 0);
205
+ rb_define_method(cOraNumber, "to_s", ora_number_to_s, 0);
206
+ rb_define_method(cOraNumber, "-@", ora_number_uminus, 0);
207
+
208
+ rb_define_method(cOraNumber, "_dump", ora_number_dump, -1);
209
+ rb_define_singleton_method(cOraNumber, "_load", ora_number_s_load, 1);
210
+ }
211
+
212
+ void ora_number_to_str(unsigned char *buf, size_t *lenp, ora_number_t *on, unsigned char size)
213
+ {
214
+ int exponent;
215
+ int len = 0;
216
+ int mentissa_size;
217
+ int i, j;
218
+
219
+ if (on->exponent == 0x80) {
220
+ buf[0] = '0';
221
+ buf[1] = '\0';
222
+ if (lenp != NULL)
223
+ *lenp = 1;
224
+ return;
225
+ }
226
+
227
+ if (Get_Sign(on)) {
228
+ mentissa_size = size - 1;
229
+ } else {
230
+ if (size == 21 && on->mantissa[19] != 102)
231
+ mentissa_size = 20;
232
+ else
233
+ mentissa_size = size - 2;
234
+ buf[len++] = '-';
235
+ }
236
+ exponent = Get_Exponent(on);
237
+ if (exponent < 0) {
238
+ buf[len++] = '0';
239
+ buf[len++] = '.';
240
+ for (i = exponent * 2;i < -2;i++)
241
+ buf[len++] = '0';
242
+ for (i = 0;i < mentissa_size;i++) {
243
+ j = Get_Mantissa_At(on, i);
244
+ buf[len++] = j / 10 + '0';
245
+ if (i != mentissa_size - 1 || j % 10 != 0)
246
+ buf[len++] = j % 10 + '0';
247
+ }
248
+ } else {
249
+ for (i = 0;i < mentissa_size;i++) {
250
+ j = Get_Mantissa_At(on, i);
251
+ if (i == exponent + 1) {
252
+ buf[len++] = '.';
253
+ }
254
+ if (i != 0 || j / 10 != 0)
255
+ buf[len++] = j / 10 + '0';
256
+ if ((i < exponent + 1) /* integer part */
257
+ || (i != mentissa_size - 1 || j % 10 != 0) /* decimal fraction */)
258
+ buf[len++] = j % 10 + '0';
259
+ }
260
+ for (;i <= exponent;i++) {
261
+ buf[len++] = '0';
262
+ buf[len++] = '0';
263
+ }
264
+ }
265
+ buf[len] = '\0';
266
+ if (lenp != NULL)
267
+ *lenp = len;
268
+ }
269
+
270
+ static int ora_number_from_str(ora_vnumber_t *ovn, unsigned char *buf, size_t len)
271
+ {
272
+ unsigned char work[80];
273
+ int sign = 1;
274
+ int state = 0;
275
+ int i, j;
276
+ int iidx; /* index of integer part */
277
+ int fidx; /* index of fraction part */
278
+ unsigned char *p;
279
+ int mantissa_size;
280
+ int exponent;
281
+
282
+ if (len > ORA_NUMBER_BUF_SIZE) {
283
+ return 1;
284
+ }
285
+ /* [ \t]*(+|-)[0-9]*(.[0-9]*) */
286
+ for (i = iidx = fidx = 0; i < len; i++) {
287
+ unsigned char uc = buf[i];
288
+ switch (state) {
289
+ case 0:
290
+ /* [ \t]*(+|-)[0-9]*(.[0-9]*) */
291
+ /* ^ */
292
+ switch (uc) {
293
+ case ' ':
294
+ case '\t':
295
+ /* [ \t]*(+|-)[0-9]*(.[0-9]*) */
296
+ /* ^ */
297
+ break;
298
+ case '-':
299
+ sign = -1;
300
+ state = 1;
301
+ /* [ \t]*(+|-)[0-9]*(.[0-9]*) */
302
+ /* ^ */
303
+ break;
304
+ case '+':
305
+ case '0':
306
+ state = 1;
307
+ /* [ \t]*(+|-)[0-9]*(.[0-9]*) */
308
+ /* ^ */
309
+ break;
310
+ case '1':
311
+ case '2':
312
+ case '3':
313
+ case '4':
314
+ case '5':
315
+ case '6':
316
+ case '7':
317
+ case '8':
318
+ case '9':
319
+ work[iidx++] = uc - '0';
320
+ state = 1;
321
+ /* [ \t]*(+|-)[0-9]*(.[0-9]*) */
322
+ /* ^ */
323
+ break;
324
+ case '.':
325
+ state = 2;
326
+ /* [ \t]*(+|-)[0-9]*(.[0-9]*) */
327
+ /* ^ */
328
+ break;
329
+ default:
330
+ return 1;
331
+ }
332
+ break;
333
+ case 1:
334
+ /* [ \t]*(+|-)[0-9]*(.[0-9]*) */
335
+ /* ^ */
336
+ switch (uc) {
337
+ case '0':
338
+ case '1':
339
+ case '2':
340
+ case '3':
341
+ case '4':
342
+ case '5':
343
+ case '6':
344
+ case '7':
345
+ case '8':
346
+ case '9':
347
+ if (iidx > sizeof(work))
348
+ return 1;
349
+ work[iidx++] = uc - '0';
350
+ /* [ \t]*(+|-)[0-9]*(.[0-9]*) */
351
+ /* ^ */
352
+ break;
353
+ case '.':
354
+ state = 2;
355
+ /* [ \t]*(+|-)[0-9]*(.[0-9]*) */
356
+ /* ^ */
357
+ break;
358
+ default:
359
+ return 1;
360
+ }
361
+ break;
362
+ case 2:
363
+ /* [ \t]*(+|-)[0-9]*(.[0-9]*) */
364
+ /* ^ */
365
+ switch (uc) {
366
+ case '0':
367
+ case '1':
368
+ case '2':
369
+ case '3':
370
+ case '4':
371
+ case '5':
372
+ case '6':
373
+ case '7':
374
+ case '8':
375
+ case '9':
376
+ if (iidx + fidx > sizeof(work))
377
+ return 1;
378
+ work[iidx + fidx++] = uc - '0';
379
+ /* [ \t]*(+|-)[0-9]*(.[0-9]*) */
380
+ /* ^ */
381
+ break;
382
+ default:
383
+ return 1;
384
+ }
385
+ break;
386
+ }
387
+ }
388
+ /* convert to 100-base number */
389
+ if (iidx & 1) {
390
+ i = j = 1;
391
+ } else {
392
+ i = j = 0;
393
+ }
394
+ if (fidx & 1) {
395
+ if (iidx + fidx > sizeof(work))
396
+ return 1;
397
+ work[iidx + fidx++] = 0;
398
+ }
399
+ while (i < iidx + fidx) {
400
+ work[j++] = work[i] * 10 + work[i + 1];
401
+ i += 2;
402
+ }
403
+ iidx = (iidx + 1) >> 1;
404
+ fidx >>= 1;
405
+ /* ... */
406
+ p = work;
407
+ mantissa_size = iidx + fidx;
408
+ exponent = (int)iidx - 1;
409
+ /* delete leading zeros */
410
+ while (mantissa_size > 0 && p[0] == 0) {
411
+ mantissa_size--;
412
+ exponent--;
413
+ p++;
414
+ }
415
+ /* delete trailing zeros */
416
+ while (mantissa_size > 0 && p[mantissa_size - 1] == 0) {
417
+ mantissa_size--;
418
+ }
419
+ /* check size */
420
+ if (mantissa_size > sizeof(ovn->num.mantissa))
421
+ return 1;
422
+ if (mantissa_size == 0) {
423
+ ovn->size = 1;
424
+ ovn->num.exponent = 0x80;
425
+ return 0;
426
+ }
427
+ if (sign > 0) {
428
+ ovn->size = mantissa_size + 1;
429
+ ovn->num.exponent = 0x80 + exponent + 65;
430
+ for (i = 0; i < mantissa_size; i++) {
431
+ ovn->num.mantissa[i] = p[i] + 1;
432
+ }
433
+ } else {
434
+ ovn->size = mantissa_size + 1;
435
+ ovn->num.exponent = 62 - exponent;
436
+ for (i = 0; i < mantissa_size; i++) {
437
+ ovn->num.mantissa[i] = 101 - p[i];
438
+ }
439
+ if (mantissa_size < 20) {
440
+ ovn->size++;
441
+ ovn->num.mantissa[i] = 102;
442
+ }
443
+ }
444
+ return 0;
445
+ }