ray 0.0.1 → 0.1.0.pre1

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.
Files changed (188) hide show
  1. data/.gemtest +0 -0
  2. data/.yardopts +4 -0
  3. data/README.md +17 -21
  4. data/Rakefile +18 -139
  5. data/VERSION +1 -1
  6. data/ext/audio.cpp +723 -0
  7. data/ext/{color.c → color.cpp} +25 -13
  8. data/ext/drawable.cpp +91 -0
  9. data/ext/event.cpp +460 -0
  10. data/ext/extconf.rb +5 -104
  11. data/ext/font.cpp +190 -0
  12. data/ext/image.cpp +733 -0
  13. data/ext/input.cpp +74 -0
  14. data/ext/ray.cpp +168 -0
  15. data/ext/ray.hpp +356 -0
  16. data/ext/{rect.c → rect.cpp} +51 -37
  17. data/ext/shader.cpp +169 -0
  18. data/ext/shape.cpp +409 -0
  19. data/ext/sprite.cpp +306 -0
  20. data/ext/text.cpp +181 -0
  21. data/ext/vector.cpp +215 -0
  22. data/guide.md +619 -0
  23. data/lib/ray/audio.rb +0 -41
  24. data/lib/ray/color.rb +32 -10
  25. data/lib/ray/drawable.rb +16 -0
  26. data/lib/ray/dsl/event_listener.rb +25 -2
  27. data/lib/ray/dsl/event_runner.rb +33 -5
  28. data/lib/ray/dsl/event_translator.rb +66 -30
  29. data/lib/ray/dsl/handler.rb +3 -2
  30. data/lib/ray/dsl/matcher.rb +58 -14
  31. data/lib/ray/font.rb +38 -96
  32. data/lib/ray/font_set.rb +8 -8
  33. data/lib/ray/game.rb +87 -66
  34. data/lib/ray/helper.rb +105 -10
  35. data/lib/ray/image.rb +150 -24
  36. data/lib/ray/image_set.rb +3 -1
  37. data/lib/ray/input.rb +10 -0
  38. data/lib/ray/music_set.rb +5 -3
  39. data/lib/ray/ray.rb +21 -9
  40. data/lib/ray/rect.rb +48 -7
  41. data/lib/ray/rmagick.rb +41 -0
  42. data/lib/ray/scene.rb +99 -43
  43. data/lib/ray/scene_list.rb +67 -0
  44. data/lib/ray/shape.rb +132 -0
  45. data/lib/ray/sound_set.rb +4 -2
  46. data/lib/ray/sprite.rb +49 -111
  47. data/lib/ray/text.rb +101 -0
  48. data/lib/ray/text_helper.rb +37 -0
  49. data/lib/ray/turtle.rb +215 -0
  50. data/lib/ray/vector.rb +226 -0
  51. data/samples/audio/spacial.rb +44 -0
  52. data/samples/hello_world/hello.rb +9 -13
  53. data/samples/hello_world/hello_dsl.rb +8 -12
  54. data/samples/hello_world/text.rb +15 -0
  55. data/samples/opengl/binding.rb +38 -0
  56. data/samples/opengl/image.rb +32 -0
  57. data/samples/opengl/opengl.rb +34 -0
  58. data/samples/opengl/shader.rb +42 -0
  59. data/samples/pong/pong.rb +14 -10
  60. data/samples/run_scene.rb +53 -0
  61. data/samples/shaders/scene.rb +40 -0
  62. data/samples/shaders/shaders.rb +42 -0
  63. data/samples/shaders/shape.rb +34 -0
  64. data/samples/sokoban/sokoban.rb +18 -18
  65. data/samples/test/actual_scene.rb +41 -0
  66. data/samples/test/scene_riot.rb +39 -0
  67. data/samples/test/scene_spec.rb +32 -0
  68. data/samples/test/scene_test_unit.rb +25 -0
  69. data/samples/turtle/byzantium.rb +45 -0
  70. data/samples/turtle/hilbert.rb +48 -0
  71. data/samples/turtle/koch.rb +55 -0
  72. data/samples/turtle/mandala.rb +61 -0
  73. data/samples/turtle/tree.rb +57 -0
  74. data/test/audio_test.rb +69 -0
  75. data/test/color_test.rb +77 -0
  76. data/test/drawable_test.rb +19 -0
  77. data/test/dsl_test.rb +93 -0
  78. data/test/font_test.rb +57 -0
  79. data/test/helpers.rb +94 -0
  80. data/test/image_test.rb +82 -0
  81. data/test/ray_test.rb +25 -0
  82. data/test/rect_test.rb +121 -0
  83. data/{spec → test}/res/VeraMono.ttf +0 -0
  84. data/{spec → test}/res/aqua.bmp +0 -0
  85. data/{spec → test}/res/aqua.png +0 -0
  86. data/{spec → test}/res/aqua2.bmp +0 -0
  87. data/{spec → test}/res/not_a_jpeg.jpeg +0 -0
  88. data/{spec → test}/res/pop.wav +0 -0
  89. data/test/resource_set_test.rb +99 -0
  90. data/test/run_all.rb +7 -0
  91. data/test/shape_test.rb +101 -0
  92. data/test/sprite_test.rb +89 -0
  93. data/test/text_test.rb +78 -0
  94. data/test/turtle_test.rb +176 -0
  95. data/test/vector_test.rb +111 -0
  96. data/yard_ext.rb +0 -28
  97. metadata +95 -139
  98. data/.gitignore +0 -23
  99. data/.gitmodules +0 -3
  100. data/.rspec +0 -3
  101. data/ext/audio.c +0 -473
  102. data/ext/event.c +0 -557
  103. data/ext/font.c +0 -287
  104. data/ext/image.c +0 -933
  105. data/ext/joystick.c +0 -145
  106. data/ext/ray.c +0 -489
  107. data/ext/ray.h +0 -245
  108. data/ext/ray_osx.m +0 -161
  109. data/lib/ray/joystick.rb +0 -30
  110. data/psp/SDL_psp_main.c +0 -84
  111. data/psp/bigdecimal/README +0 -60
  112. data/psp/bigdecimal/bigdecimal.c +0 -4697
  113. data/psp/bigdecimal/bigdecimal.h +0 -216
  114. data/psp/bigdecimal/lib/bigdecimal/jacobian.rb +0 -85
  115. data/psp/bigdecimal/lib/bigdecimal/ludcmp.rb +0 -84
  116. data/psp/bigdecimal/lib/bigdecimal/math.rb +0 -235
  117. data/psp/bigdecimal/lib/bigdecimal/newton.rb +0 -77
  118. data/psp/bigdecimal/lib/bigdecimal/util.rb +0 -65
  119. data/psp/digest/bubblebabble/bubblebabble.c +0 -142
  120. data/psp/digest/defs.h +0 -20
  121. data/psp/digest/digest.c +0 -643
  122. data/psp/digest/digest.h +0 -32
  123. data/psp/digest/lib/digest.rb +0 -50
  124. data/psp/digest/lib/md5.rb +0 -27
  125. data/psp/digest/lib/sha1.rb +0 -27
  126. data/psp/digest/md5/md5.c +0 -420
  127. data/psp/digest/md5/md5.h +0 -80
  128. data/psp/digest/md5/md5init.c +0 -40
  129. data/psp/digest/rmd160/rmd160.c +0 -457
  130. data/psp/digest/rmd160/rmd160.h +0 -56
  131. data/psp/digest/rmd160/rmd160init.c +0 -40
  132. data/psp/digest/sha1/sha1.c +0 -269
  133. data/psp/digest/sha1/sha1.h +0 -39
  134. data/psp/digest/sha1/sha1init.c +0 -40
  135. data/psp/digest/sha2/lib/sha2.rb +0 -73
  136. data/psp/digest/sha2/sha2.c +0 -919
  137. data/psp/digest/sha2/sha2.h +0 -109
  138. data/psp/digest/sha2/sha2init.c +0 -52
  139. data/psp/enumerator/enumerator.c +0 -298
  140. data/psp/etc/etc.c +0 -559
  141. data/psp/ext.c +0 -289
  142. data/psp/fcntl/fcntl.c +0 -187
  143. data/psp/lib/rbconfig.rb +0 -178
  144. data/psp/nkf/lib/kconv.rb +0 -367
  145. data/psp/nkf/nkf-utf8/config.h +0 -88
  146. data/psp/nkf/nkf-utf8/nkf.c +0 -6040
  147. data/psp/nkf/nkf-utf8/utf8tbl.c +0 -8500
  148. data/psp/nkf/nkf-utf8/utf8tbl.h +0 -34
  149. data/psp/nkf/nkf.c +0 -654
  150. data/psp/socket/addrinfo.h +0 -173
  151. data/psp/socket/getaddrinfo.c +0 -676
  152. data/psp/socket/getnameinfo.c +0 -270
  153. data/psp/socket/pspsocket.c +0 -71
  154. data/psp/socket/pspsocket.h +0 -28
  155. data/psp/socket/socket.c +0 -4662
  156. data/psp/socket/sockport.h +0 -76
  157. data/psp/stringio/stringio.c +0 -1306
  158. data/psp/strscan/strscan.c +0 -1320
  159. data/psp/syck/bytecode.c +0 -1166
  160. data/psp/syck/emitter.c +0 -1242
  161. data/psp/syck/gram.c +0 -1894
  162. data/psp/syck/gram.h +0 -79
  163. data/psp/syck/handler.c +0 -174
  164. data/psp/syck/implicit.c +0 -2990
  165. data/psp/syck/node.c +0 -408
  166. data/psp/syck/rubyext.c +0 -2367
  167. data/psp/syck/syck.c +0 -504
  168. data/psp/syck/syck.h +0 -456
  169. data/psp/syck/token.c +0 -2725
  170. data/psp/syck/yaml2byte.c +0 -257
  171. data/psp/syck/yamlbyte.h +0 -170
  172. data/psp/thread/thread.c +0 -1175
  173. data/psp/zlib/zlib.c +0 -3547
  174. data/script.rb +0 -10
  175. data/spec/ray/audio_spec.rb +0 -146
  176. data/spec/ray/color_spec.rb +0 -57
  177. data/spec/ray/event_spec.rb +0 -80
  178. data/spec/ray/font_spec.rb +0 -93
  179. data/spec/ray/image_set_spec.rb +0 -48
  180. data/spec/ray/image_spec.rb +0 -162
  181. data/spec/ray/joystick_spec.rb +0 -21
  182. data/spec/ray/matcher_spec.rb +0 -50
  183. data/spec/ray/ray_spec.rb +0 -88
  184. data/spec/ray/rect_spec.rb +0 -154
  185. data/spec/ray/resource_set_spec.rb +0 -105
  186. data/spec/ray/sprite_spec.rb +0 -163
  187. data/spec/spec.opts +0 -4
  188. data/spec/spec_helper.rb +0 -8
@@ -1,77 +0,0 @@
1
- #
2
- # newton.rb
3
- #
4
- # Solves the nonlinear algebraic equation system f = 0 by Newton's method.
5
- # This program is not dependent on BigDecimal.
6
- #
7
- # To call:
8
- # n = nlsolve(f,x)
9
- # where n is the number of iterations required,
10
- # x is the initial value vector
11
- # f is an Object which is used to compute the values of the equations to be solved.
12
- # It must provide the following methods:
13
- #
14
- # f.values(x):: returns the values of all functions at x
15
- #
16
- # f.zero:: returns 0.0
17
- # f.one:: returns 1.0
18
- # f.two:: returns 1.0
19
- # f.ten:: returns 10.0
20
- #
21
- # f.eps:: returns the convergence criterion (epsilon value) used to determine whether two values are considered equal. If |a-b| < epsilon, the two values are considered equal.
22
- #
23
- # On exit, x is the solution vector.
24
- #
25
- require "bigdecimal/ludcmp"
26
- require "bigdecimal/jacobian"
27
-
28
- module Newton
29
- include LUSolve
30
- include Jacobian
31
-
32
- def norm(fv,zero=0.0)
33
- s = zero
34
- n = fv.size
35
- for i in 0...n do
36
- s += fv[i]*fv[i]
37
- end
38
- s
39
- end
40
-
41
- def nlsolve(f,x)
42
- nRetry = 0
43
- n = x.size
44
-
45
- f0 = f.values(x)
46
- zero = f.zero
47
- one = f.one
48
- two = f.two
49
- p5 = one/two
50
- d = norm(f0,zero)
51
- minfact = f.ten*f.ten*f.ten
52
- minfact = one/minfact
53
- e = f.eps
54
- while d >= e do
55
- nRetry += 1
56
- # Not yet converged. => Compute Jacobian matrix
57
- dfdx = jacobian(f,f0,x)
58
- # Solve dfdx*dx = -f0 to estimate dx
59
- dx = lusolve(dfdx,f0,ludecomp(dfdx,n,zero,one),zero)
60
- fact = two
61
- xs = x.dup
62
- begin
63
- fact *= p5
64
- if fact < minfact then
65
- raise "Failed to reduce function values."
66
- end
67
- for i in 0...n do
68
- x[i] = xs[i] - dx[i]*fact
69
- end
70
- f0 = f.values(x)
71
- dn = norm(f0,zero)
72
- end while(dn>=d)
73
- d = dn
74
- end
75
- nRetry
76
- end
77
- end
@@ -1,65 +0,0 @@
1
- #
2
- # BigDecimal utility library.
3
- #
4
- # To use these functions, require 'bigdecimal/util'
5
- #
6
- # The following methods are provided to convert other types to BigDecimals:
7
- #
8
- # String#to_d -> BigDecimal
9
- # Float#to_d -> BigDecimal
10
- # Rational#to_d -> BigDecimal
11
- #
12
- # The following method is provided to convert BigDecimals to other types:
13
- #
14
- # BigDecimal#to_r -> Rational
15
- #
16
- # ----------------------------------------------------------------------
17
- #
18
- class Float < Numeric
19
- def to_d
20
- BigDecimal(self.to_s)
21
- end
22
- end
23
-
24
- class String
25
- def to_d
26
- BigDecimal(self)
27
- end
28
- end
29
-
30
- class BigDecimal < Numeric
31
- # Converts a BigDecimal to a String of the form "nnnnnn.mmm".
32
- # This method is deprecated; use BigDecimal#to_s("F") instead.
33
- def to_digits
34
- if self.nan? || self.infinite? || self.zero?
35
- self.to_s
36
- else
37
- i = self.to_i.to_s
38
- s,f,y,z = self.frac.split
39
- i + "." + ("0"*(-z)) + f
40
- end
41
- end
42
-
43
- # Converts a BigDecimal to a Rational.
44
- def to_r
45
- sign,digits,base,power = self.split
46
- numerator = sign*digits.to_i
47
- denomi_power = power - digits.size # base is always 10
48
- if denomi_power < 0
49
- Rational(numerator,base ** (-denomi_power))
50
- else
51
- Rational(numerator * (base ** denomi_power),1)
52
- end
53
- end
54
- end
55
-
56
- class Rational < Numeric
57
- # Converts a Rational to a BigDecimal
58
- def to_d(nFig=0)
59
- num = self.numerator.to_s
60
- if nFig<=0
61
- nFig = BigDecimal.double_fig*2+1
62
- end
63
- BigDecimal.new(num).div(self.denominator,nFig)
64
- end
65
- end
@@ -1,142 +0,0 @@
1
- /************************************************
2
-
3
- bubblebabble.c - BubbleBabble encoding support
4
-
5
- $Author: shyouhei $
6
- created at: Fri Oct 13 18:31:42 JST 2006
7
-
8
- Copyright (C) 2006 Akinori MUSHA
9
-
10
- $Id: bubblebabble.c 11708 2007-02-12 23:01:19Z shyouhei $
11
-
12
- ************************************************/
13
-
14
- #include <ruby/ruby.h>
15
- #include "../digest.h"
16
-
17
- static ID id_digest;
18
-
19
- static VALUE
20
- bubblebabble_str_new(VALUE str_digest)
21
- {
22
- char *digest;
23
- size_t digest_len;
24
- VALUE str;
25
- char *p;
26
- int i, j, seed = 1;
27
- static const char vowels[] = {
28
- 'a', 'e', 'i', 'o', 'u', 'y'
29
- };
30
- static const char consonants[] = {
31
- 'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm', 'n',
32
- 'p', 'r', 's', 't', 'v', 'z', 'x'
33
- };
34
-
35
- StringValue(str_digest);
36
- digest = RSTRING_PTR(str_digest);
37
- digest_len = RSTRING_LEN(str_digest);
38
-
39
- if ((LONG_MAX - 2) / 3 < (digest_len | 1)) {
40
- rb_raise(rb_eRuntimeError, "digest string too long");
41
- }
42
-
43
- str = rb_str_new(0, (digest_len | 1) * 3 + 2);
44
- p = RSTRING_PTR(str);
45
-
46
- i = j = 0;
47
- p[j++] = 'x';
48
-
49
- for (;;) {
50
- unsigned char byte1, byte2;
51
-
52
- if (i >= digest_len) {
53
- p[j++] = vowels[seed % 6];
54
- p[j++] = consonants[16];
55
- p[j++] = vowels[seed / 6];
56
- break;
57
- }
58
-
59
- byte1 = digest[i++];
60
- p[j++] = vowels[(((byte1 >> 6) & 3) + seed) % 6];
61
- p[j++] = consonants[(byte1 >> 2) & 15];
62
- p[j++] = vowels[((byte1 & 3) + (seed / 6)) % 6];
63
-
64
- if (i >= digest_len) {
65
- break;
66
- }
67
-
68
- byte2 = digest[i++];
69
- p[j++] = consonants[(byte2 >> 4) & 15];
70
- p[j++] = '-';
71
- p[j++] = consonants[byte2 & 15];
72
-
73
- seed = (seed * 5 + byte1 * 7 + byte2) % 36;
74
- }
75
-
76
- p[j] = 'x';
77
-
78
- return str;
79
- }
80
-
81
- /*
82
- * call-seq:
83
- * Digest.bubblebabble(string) -> bubblebabble_string
84
- *
85
- * Returns a BubbleBabble encoded version of a given _string_.
86
- */
87
- static VALUE
88
- rb_digest_s_bubblebabble(VALUE klass, VALUE str)
89
- {
90
- return bubblebabble_str_new(str);
91
- }
92
-
93
- /*
94
- * call-seq:
95
- * Digest::Class.bubblebabble(string, ...) -> hash_string
96
- *
97
- * Returns the BubbleBabble encoded hash value of a given _string_.
98
- */
99
- static VALUE
100
- rb_digest_class_s_bubblebabble(int argc, VALUE *argv, VALUE klass)
101
- {
102
- return bubblebabble_str_new(rb_funcall2(klass, id_digest, argc, argv));
103
- }
104
-
105
- /*
106
- * call-seq:
107
- * digest_obj.bubblebabble -> hash_string
108
- *
109
- * Returns the resulting hash value in a Bubblebabble encoded form.
110
- */
111
- static VALUE
112
- rb_digest_instance_bubblebabble(VALUE self)
113
- {
114
- return bubblebabble_str_new(rb_funcall(self, id_digest, 0));
115
- }
116
-
117
- /*
118
- * This module adds some methods to Digest classes to perform
119
- * BubbleBabble encoding.
120
- */
121
- void
122
- Init_bubblebabble(void)
123
- {
124
- VALUE mDigest, mDigest_Instance, cDigest_Class;
125
-
126
- // rb_require("digest"); (Commenting this avoids strange errors)
127
-
128
- mDigest = rb_path2class("Digest");
129
- mDigest_Instance = rb_path2class("Digest::Instance");
130
- cDigest_Class = rb_path2class("Digest::Class");
131
-
132
- /* Digest::bubblebabble() */
133
- rb_define_module_function(mDigest, "bubblebabble", rb_digest_s_bubblebabble, 1);
134
-
135
- /* Digest::Class::bubblebabble() */
136
- rb_define_singleton_method(cDigest_Class, "bubblebabble", rb_digest_class_s_bubblebabble, -1);
137
-
138
- /* Digest::Instance#bubblebabble() */
139
- rb_define_method(mDigest_Instance, "bubblebabble", rb_digest_instance_bubblebabble, 0);
140
-
141
- id_digest = rb_intern("digest");
142
- }
@@ -1,20 +0,0 @@
1
- /* -*- C -*-
2
- * $Id: defs.h 11708 2007-02-12 23:01:19Z shyouhei $
3
- */
4
-
5
- #ifndef DEFS_H
6
- #define DEFS_H
7
-
8
- #include <ruby/ruby.h>
9
- #include <sys/types.h>
10
-
11
- #include <sys/cdefs.h>
12
-
13
- #if !defined(__BEGIN_DECLS)
14
- # define __BEGIN_DECLS
15
- # define __END_DECLS
16
- #endif
17
-
18
- #include <inttypes.h>
19
-
20
- #endif /* DEFS_H */
@@ -1,643 +0,0 @@
1
- /************************************************
2
-
3
- digest.c -
4
-
5
- $Author: knu $
6
- created at: Fri May 25 08:57:27 JST 2001
7
-
8
- Copyright (C) 1995-2001 Yukihiro Matsumoto
9
- Copyright (C) 2001-2006 Akinori MUSHA
10
-
11
- $RoughId: digest.c,v 1.16 2001/07/13 15:38:27 knu Exp $
12
- $Id: digest.c 11950 2007-02-28 18:42:47Z knu $
13
-
14
- ************************************************/
15
-
16
- #include "digest.h"
17
-
18
- static VALUE rb_mDigest;
19
- static VALUE rb_mDigest_Instance;
20
- static VALUE rb_cDigest_Class;
21
- static VALUE rb_cDigest_Base;
22
-
23
- static ID id_reset, id_update, id_finish, id_digest, id_hexdigest, id_digest_length;
24
- static ID id_metadata;
25
-
26
- RUBY_EXTERN void Init_digest_base(void);
27
-
28
- /*
29
- * Document-module: Digest
30
- *
31
- * This module provides a framework for message digest libraries.
32
- */
33
-
34
- static VALUE
35
- hexencode_str_new(VALUE str_digest)
36
- {
37
- char *digest;
38
- size_t digest_len;
39
- int i;
40
- VALUE str;
41
- char *p;
42
- static const char hex[] = {
43
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
44
- 'a', 'b', 'c', 'd', 'e', 'f'
45
- };
46
-
47
- StringValue(str_digest);
48
- digest = RSTRING_PTR(str_digest);
49
- digest_len = RSTRING_LEN(str_digest);
50
-
51
- if (LONG_MAX / 2 < digest_len) {
52
- rb_raise(rb_eRuntimeError, "digest string too long");
53
- }
54
-
55
- str = rb_str_new(0, digest_len * 2);
56
-
57
- for (i = 0, p = RSTRING_PTR(str); i < digest_len; i++) {
58
- unsigned char byte = digest[i];
59
-
60
- p[i + i] = hex[byte >> 4];
61
- p[i + i + 1] = hex[byte & 0x0f];
62
- }
63
-
64
- return str;
65
- }
66
-
67
- /*
68
- * call-seq:
69
- * Digest.hexencode(string) -> hexencoded_string
70
- *
71
- * Generates a hex-encoded version of a given _string_.
72
- */
73
- static VALUE
74
- rb_digest_s_hexencode(VALUE klass, VALUE str)
75
- {
76
- return hexencode_str_new(str);
77
- }
78
-
79
- /*
80
- * Document-module: Digest::Instance
81
- *
82
- * This module provides instance methods for a digest implementation
83
- * object to calculate message digest values.
84
- */
85
-
86
- /*
87
- * call-seq:
88
- * digest_obj.update(string) -> digest_obj
89
- * digest_obj << string -> digest_obj
90
- *
91
- * Updates the digest using a given _string_ and returns self.
92
- *
93
- * The update() method and the left-shift operator are overridden by
94
- * each implementation subclass. (One should be an alias for the
95
- * other)
96
- */
97
- static VALUE
98
- rb_digest_instance_update(VALUE self, VALUE str)
99
- {
100
- rb_raise(rb_eRuntimeError, "%s does not implement update()", rb_inspect(self));
101
- }
102
-
103
- /*
104
- * call-seq:
105
- * digest_obj.instance_eval { finish } -> digest_obj
106
- *
107
- * Finishes the digest and returns the resulting hash value.
108
- *
109
- * This method is overridden by each implementation subclass and often
110
- * made private, because some of those subclasses may leave internal
111
- * data uninitialized. Do not call this method from outside. Use
112
- * #digest!() instead, which ensures that internal data be reset for
113
- * security reasons.
114
- */
115
- static VALUE
116
- rb_digest_instance_finish(VALUE self)
117
- {
118
- rb_raise(rb_eRuntimeError, "%s does not implement finish()", rb_inspect(self));
119
- }
120
-
121
- /*
122
- * call-seq:
123
- * digest_obj.reset -> digest_obj
124
- *
125
- * Resets the digest to the initial state and returns self.
126
- *
127
- * This method is overridden by each implementation subclass.
128
- */
129
- static VALUE
130
- rb_digest_instance_reset(VALUE self)
131
- {
132
- rb_raise(rb_eRuntimeError, "%s does not implement reset()", rb_inspect(self));
133
- }
134
-
135
- /*
136
- * call-seq:
137
- * digest_obj.new -> another_digest_obj
138
- *
139
- * Returns a new, initialized copy of the digest object. Equivalent
140
- * to digest_obj.clone().reset().
141
- */
142
- static VALUE
143
- rb_digest_instance_new(VALUE self)
144
- {
145
- VALUE clone = rb_obj_clone(self);
146
- rb_funcall(clone, id_reset, 0);
147
- return clone;
148
- }
149
-
150
- /*
151
- * call-seq:
152
- * digest_obj.digest -> string
153
- * digest_obj.digest(string) -> string
154
- *
155
- * If none is given, returns the resulting hash value of the digest,
156
- * keeping the digest's state.
157
- *
158
- * If a _string_ is given, returns the hash value for the given
159
- * _string_, resetting the digest to the initial state before and
160
- * after the process.
161
- */
162
- static VALUE
163
- rb_digest_instance_digest(int argc, VALUE *argv, VALUE self)
164
- {
165
- VALUE str, value;
166
-
167
- if (rb_scan_args(argc, argv, "01", &str) > 0) {
168
- rb_funcall(self, id_reset, 0);
169
- rb_funcall(self, id_update, 1, str);
170
- value = rb_funcall(self, id_finish, 0);
171
- rb_funcall(self, id_reset, 0);
172
- } else {
173
- VALUE clone = rb_obj_clone(self);
174
-
175
- value = rb_funcall(clone, id_finish, 0);
176
- rb_funcall(clone, id_reset, 0);
177
- }
178
-
179
- return value;
180
- }
181
-
182
- /*
183
- * call-seq:
184
- * digest_obj.digest! -> string
185
- *
186
- * Returns the resulting hash value and resets the digest to the
187
- * initial state.
188
- */
189
- static VALUE
190
- rb_digest_instance_digest_bang(VALUE self)
191
- {
192
- VALUE value = rb_funcall(self, id_finish, 0);
193
- rb_funcall(self, id_reset, 0);
194
-
195
- return value;
196
- }
197
-
198
- /*
199
- * call-seq:
200
- * digest_obj.hexdigest -> string
201
- * digest_obj.hexdigest(string) -> string
202
- *
203
- * If none is given, returns the resulting hash value of the digest in
204
- * a hex-encoded form, keeping the digest's state.
205
- *
206
- * If a _string_ is given, returns the hash value for the given
207
- * _string_ in a hex-encoded form, resetting the digest to the initial
208
- * state before and after the process.
209
- */
210
- static VALUE
211
- rb_digest_instance_hexdigest(int argc, VALUE *argv, VALUE self)
212
- {
213
- VALUE str, value;
214
-
215
- if (rb_scan_args(argc, argv, "01", &str) > 0) {
216
- rb_funcall(self, id_reset, 0);
217
- rb_funcall(self, id_update, 1, str);
218
- value = rb_funcall(self, id_finish, 0);
219
- rb_funcall(self, id_reset, 0);
220
- } else {
221
- VALUE clone = rb_obj_clone(self);
222
-
223
- value = rb_funcall(clone, id_finish, 0);
224
- rb_funcall(clone, id_reset, 0);
225
- }
226
-
227
- return hexencode_str_new(value);
228
- }
229
-
230
- /*
231
- * call-seq:
232
- * digest_obj.hexdigest! -> string
233
- *
234
- * Returns the resulting hash value and resets the digest to the
235
- * initial state.
236
- */
237
- static VALUE
238
- rb_digest_instance_hexdigest_bang(VALUE self)
239
- {
240
- VALUE value = rb_funcall(self, id_finish, 0);
241
- rb_funcall(self, id_reset, 0);
242
-
243
- return hexencode_str_new(value);
244
- }
245
-
246
- /*
247
- * call-seq:
248
- * digest_obj.to_s -> string
249
- *
250
- * Returns digest_obj.hexdigest().
251
- */
252
- static VALUE
253
- rb_digest_instance_to_s(VALUE self)
254
- {
255
- return rb_funcall(self, id_hexdigest, 0);
256
- }
257
-
258
- /*
259
- * call-seq:
260
- * digest_obj.inspect -> string
261
- *
262
- * Creates a printable version of the digest object.
263
- */
264
- static VALUE
265
- rb_digest_instance_inspect(VALUE self)
266
- {
267
- VALUE str;
268
- size_t digest_len = 32; /* about this size at least */
269
- char *cname;
270
-
271
- cname = rb_obj_classname(self);
272
-
273
- /* #<Digest::ClassName: xxxxx...xxxx> */
274
- str = rb_str_buf_new(2 + strlen(cname) + 2 + digest_len * 2 + 1);
275
- rb_str_buf_cat2(str, "#<");
276
- rb_str_buf_cat2(str, cname);
277
- rb_str_buf_cat2(str, ": ");
278
- rb_str_buf_append(str, rb_digest_instance_hexdigest(0, 0, self));
279
- rb_str_buf_cat2(str, ">");
280
- return str;
281
- }
282
-
283
- /*
284
- * call-seq:
285
- * digest_obj == another_digest_obj -> boolean
286
- * digest_obj == string -> boolean
287
- *
288
- * If a string is given, checks whether it is equal to the hex-encoded
289
- * hash value of the digest object. If another digest instance is
290
- * given, checks whether they have the same hash value. Otherwise
291
- * returns false.
292
- */
293
- static VALUE
294
- rb_digest_instance_equal(VALUE self, VALUE other)
295
- {
296
- VALUE str1, str2;
297
-
298
- if (rb_obj_is_kind_of(other, rb_mDigest_Instance) == Qtrue) {
299
- str1 = rb_digest_instance_digest(0, 0, self);
300
- str2 = rb_digest_instance_digest(0, 0, other);
301
- } else {
302
- str1 = rb_digest_instance_to_s(self);
303
- str2 = other;
304
- }
305
-
306
- /* never blindly assume that subclass methods return strings */
307
- StringValue(str1);
308
- StringValue(str2);
309
-
310
- if (RSTRING_LEN(str1) == RSTRING_LEN(str2) &&
311
- rb_str_cmp(str1, str2) == 0) {
312
- return Qtrue;
313
- }
314
- return Qfalse;
315
- }
316
-
317
- /*
318
- * call-seq:
319
- * digest_obj.digest_length -> integer
320
- *
321
- * Returns the length of the hash value of the digest.
322
- *
323
- * This method should be overridden by each implementation subclass.
324
- * If not, digest_obj.digest().length() is returned.
325
- */
326
- static VALUE
327
- rb_digest_instance_digest_length(VALUE self)
328
- {
329
- /* subclasses really should redefine this method */
330
- VALUE digest = rb_digest_instance_digest(0, 0, self);
331
-
332
- /* never blindly assume that #digest() returns a string */
333
- StringValue(digest);
334
- return INT2NUM(RSTRING_LEN(digest));
335
- }
336
-
337
- /*
338
- * call-seq:
339
- * digest_obj.length -> integer
340
- * digest_obj.size -> integer
341
- *
342
- * Returns digest_obj.digest_length().
343
- */
344
- static VALUE
345
- rb_digest_instance_length(VALUE self)
346
- {
347
- return rb_funcall(self, id_digest_length, 0);
348
- }
349
-
350
- /*
351
- * call-seq:
352
- * digest_obj.block_length -> integer
353
- *
354
- * Returns the block length of the digest.
355
- *
356
- * This method is overridden by each implementation subclass.
357
- */
358
- static VALUE
359
- rb_digest_instance_block_length(VALUE self)
360
- {
361
- rb_raise(rb_eRuntimeError, "%s does not implement block_length()", rb_inspect(self));
362
- }
363
-
364
- /*
365
- * Document-class: Digest::Class
366
- *
367
- * This module stands as a base class for digest implementation
368
- * classes.
369
- */
370
-
371
- /*
372
- * call-seq:
373
- * Digest::Class.digest(string, *parameters) -> hash_string
374
- *
375
- * Returns the hash value of a given _string_. This is equivalent to
376
- * Digest::Class.new(*parameters).digest(string), where extra
377
- * _parameters_, if any, are passed through to the constructor and the
378
- * _string_ is passed to #digest().
379
- */
380
- static VALUE
381
- rb_digest_class_s_digest(int argc, VALUE *argv, VALUE klass)
382
- {
383
- VALUE str;
384
- void *pctx;
385
- volatile VALUE obj;
386
-
387
- if (argc < 1) {
388
- rb_raise(rb_eArgError, "no data given");
389
- }
390
-
391
- str = *argv++;
392
- argc--;
393
-
394
- StringValue(str);
395
-
396
- obj = rb_obj_alloc(klass);
397
- rb_obj_call_init(obj, argc, argv);
398
-
399
- return rb_funcall(obj, id_digest, 1, str);
400
- }
401
-
402
- /*
403
- * call-seq:
404
- * Digest::Class.hexdigest(string[, ...]) -> hash_string
405
- *
406
- * Returns the hex-encoded hash value of a given _string_. This is
407
- * almost equivalent to
408
- * Digest.hexencode(Digest::Class.new(*parameters).digest(string)).
409
- */
410
- static VALUE
411
- rb_digest_class_s_hexdigest(int argc, VALUE *argv, VALUE klass)
412
- {
413
- return hexencode_str_new(rb_funcall2(klass, id_digest, argc, argv));
414
- }
415
-
416
- /*
417
- * Document-class: Digest::Base
418
- *
419
- * This abstract class provides a common interface to message digest
420
- * implementation classes written in C.
421
- */
422
-
423
- static rb_digest_metadata_t *
424
- get_digest_base_metadata(VALUE klass)
425
- {
426
- VALUE p;
427
- VALUE obj;
428
- rb_digest_metadata_t *algo;
429
-
430
- for (p = klass; p; p = RCLASS(p)->super) {
431
- if (rb_ivar_defined(p, id_metadata)) {
432
- obj = rb_ivar_get(p, id_metadata);
433
- break;
434
- }
435
- }
436
-
437
- if (!p)
438
- rb_raise(rb_eRuntimeError, "Digest::Base cannot be directly inherited in Ruby");
439
-
440
- Data_Get_Struct(obj, rb_digest_metadata_t, algo);
441
-
442
- switch (algo->api_version) {
443
- case 2:
444
- break;
445
-
446
- /*
447
- * put conversion here if possible when API is updated
448
- */
449
-
450
- default:
451
- rb_raise(rb_eRuntimeError, "Incompatible digest API version");
452
- }
453
-
454
- return algo;
455
- }
456
-
457
- static VALUE
458
- rb_digest_base_alloc(VALUE klass)
459
- {
460
- rb_digest_metadata_t *algo;
461
- VALUE obj;
462
- void *pctx;
463
-
464
- if (klass == rb_cDigest_Base) {
465
- rb_raise(rb_eNotImpError, "Digest::Base is an abstract class");
466
- }
467
-
468
- algo = get_digest_base_metadata(klass);
469
-
470
- pctx = xmalloc(algo->ctx_size);
471
- algo->init_func(pctx);
472
-
473
- obj = Data_Wrap_Struct(klass, 0, free, pctx);
474
-
475
- return obj;
476
- }
477
-
478
- /* :nodoc: */
479
- static VALUE
480
- rb_digest_base_copy(VALUE copy, VALUE obj)
481
- {
482
- rb_digest_metadata_t *algo;
483
- void *pctx1, *pctx2;
484
-
485
- if (copy == obj) return copy;
486
-
487
- rb_check_frozen(copy);
488
-
489
- algo = get_digest_base_metadata(rb_obj_class(copy));
490
-
491
- Data_Get_Struct(obj, void, pctx1);
492
- Data_Get_Struct(copy, void, pctx2);
493
- memcpy(pctx2, pctx1, algo->ctx_size);
494
-
495
- return copy;
496
- }
497
-
498
- /* :nodoc: */
499
- static VALUE
500
- rb_digest_base_reset(VALUE self)
501
- {
502
- rb_digest_metadata_t *algo;
503
- void *pctx;
504
-
505
- algo = get_digest_base_metadata(rb_obj_class(self));
506
-
507
- Data_Get_Struct(self, void, pctx);
508
-
509
- algo->init_func(pctx);
510
-
511
- return self;
512
- }
513
-
514
- /* :nodoc: */
515
- static VALUE
516
- rb_digest_base_update(VALUE self, VALUE str)
517
- {
518
- rb_digest_metadata_t *algo;
519
- void *pctx;
520
-
521
- algo = get_digest_base_metadata(rb_obj_class(self));
522
-
523
- Data_Get_Struct(self, void, pctx);
524
-
525
- StringValue(str);
526
- algo->update_func(pctx, (unsigned char *)RSTRING_PTR(str), RSTRING_LEN(str));
527
-
528
- return self;
529
- }
530
-
531
- /* :nodoc: */
532
- static VALUE
533
- rb_digest_base_finish(VALUE self)
534
- {
535
- rb_digest_metadata_t *algo;
536
- void *pctx;
537
- VALUE str;
538
-
539
- algo = get_digest_base_metadata(rb_obj_class(self));
540
-
541
- Data_Get_Struct(self, void, pctx);
542
-
543
- str = rb_str_new(0, algo->digest_len);
544
- algo->finish_func(pctx, (unsigned char *)RSTRING_PTR(str));
545
-
546
- /* avoid potential coredump caused by use of a finished context */
547
- algo->init_func(pctx);
548
-
549
- return str;
550
- }
551
-
552
- /* :nodoc: */
553
- static VALUE
554
- rb_digest_base_digest_length(VALUE self)
555
- {
556
- rb_digest_metadata_t *algo;
557
-
558
- algo = get_digest_base_metadata(rb_obj_class(self));
559
-
560
- return INT2NUM(algo->digest_len);
561
- }
562
-
563
- /* :nodoc: */
564
- static VALUE
565
- rb_digest_base_block_length(VALUE self)
566
- {
567
- rb_digest_metadata_t *algo;
568
-
569
- algo = get_digest_base_metadata(rb_obj_class(self));
570
-
571
- return INT2NUM(algo->block_len);
572
- }
573
-
574
- void
575
- Init_digest(void)
576
- {
577
- id_reset = rb_intern("reset");
578
- id_update = rb_intern("update");
579
- id_finish = rb_intern("finish");
580
- id_digest = rb_intern("digest");
581
- id_hexdigest = rb_intern("hexdigest");
582
- id_digest_length = rb_intern("digest_length");
583
-
584
- /*
585
- * module Digest
586
- */
587
- rb_mDigest = rb_define_module("Digest");
588
-
589
- /* module functions */
590
- rb_define_module_function(rb_mDigest, "hexencode", rb_digest_s_hexencode, 1);
591
-
592
- /*
593
- * module Digest::Instance
594
- */
595
- rb_mDigest_Instance = rb_define_module_under(rb_mDigest, "Instance");
596
-
597
- /* instance methods that should be overridden */
598
- rb_define_method(rb_mDigest_Instance, "update", rb_digest_instance_update, 1);
599
- rb_define_method(rb_mDigest_Instance, "<<", rb_digest_instance_update, 1);
600
- rb_define_private_method(rb_mDigest_Instance, "finish", rb_digest_instance_finish, 0);
601
- rb_define_method(rb_mDigest_Instance, "reset", rb_digest_instance_reset, 0);
602
- rb_define_method(rb_mDigest_Instance, "digest_length", rb_digest_instance_digest_length, 0);
603
- rb_define_method(rb_mDigest_Instance, "block_length", rb_digest_instance_block_length, 0);
604
-
605
- /* instance methods that may be overridden */
606
- rb_define_method(rb_mDigest_Instance, "==", rb_digest_instance_equal, 1);
607
- rb_define_method(rb_mDigest_Instance, "inspect", rb_digest_instance_inspect, 0);
608
-
609
- /* instance methods that need not usually be overridden */
610
- rb_define_method(rb_mDigest_Instance, "new", rb_digest_instance_new, 0);
611
- rb_define_method(rb_mDigest_Instance, "digest", rb_digest_instance_digest, -1);
612
- rb_define_method(rb_mDigest_Instance, "digest!", rb_digest_instance_digest_bang, 0);
613
- rb_define_method(rb_mDigest_Instance, "hexdigest", rb_digest_instance_hexdigest, -1);
614
- rb_define_method(rb_mDigest_Instance, "hexdigest!", rb_digest_instance_hexdigest_bang, 0);
615
- rb_define_method(rb_mDigest_Instance, "to_s", rb_digest_instance_to_s, 0);
616
- rb_define_method(rb_mDigest_Instance, "length", rb_digest_instance_length, 0);
617
- rb_define_method(rb_mDigest_Instance, "size", rb_digest_instance_length, 0);
618
-
619
- /*
620
- * class Digest::Class
621
- */
622
- rb_cDigest_Class = rb_define_class_under(rb_mDigest, "Class", rb_cObject);
623
- rb_include_module(rb_cDigest_Class, rb_mDigest_Instance);
624
-
625
- /* class methods */
626
- rb_define_singleton_method(rb_cDigest_Class, "digest", rb_digest_class_s_digest, -1);
627
- rb_define_singleton_method(rb_cDigest_Class, "hexdigest", rb_digest_class_s_hexdigest, -1);
628
-
629
- id_metadata = rb_intern("metadata");
630
-
631
- /* class Digest::Base < Digest::Class */
632
- rb_cDigest_Base = rb_define_class_under(rb_mDigest, "Base", rb_cDigest_Class);
633
-
634
- rb_define_alloc_func(rb_cDigest_Base, rb_digest_base_alloc);
635
-
636
- rb_define_method(rb_cDigest_Base, "initialize_copy", rb_digest_base_copy, 1);
637
- rb_define_method(rb_cDigest_Base, "reset", rb_digest_base_reset, 0);
638
- rb_define_method(rb_cDigest_Base, "update", rb_digest_base_update, 1);
639
- rb_define_method(rb_cDigest_Base, "<<", rb_digest_base_update, 1);
640
- rb_define_private_method(rb_cDigest_Base, "finish", rb_digest_base_finish, 0);
641
- rb_define_method(rb_cDigest_Base, "digest_length", rb_digest_base_digest_length, 0);
642
- rb_define_method(rb_cDigest_Base, "block_length", rb_digest_base_block_length, 0);
643
- }