csd 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (258) hide show
  1. data/COPYING +1 -2
  2. data/README.rdoc +7 -1
  3. data/Rakefile +7 -2
  4. data/VERSION +1 -1
  5. data/csd.gemspec +18 -216
  6. data/lib/csd.rb +6 -16
  7. data/lib/csd/application.rb +2 -2
  8. data/lib/csd/application/default.rb +15 -14
  9. data/lib/csd/application/default/base.rb +1 -1
  10. data/lib/csd/application/minisip.rb +43 -11
  11. data/lib/csd/application/minisip/about.yml +5 -5
  12. data/lib/csd/application/minisip/base.rb +82 -70
  13. data/lib/csd/application/minisip/error.rb +1 -1
  14. data/lib/csd/application/minisip/options/common.rb +1 -1
  15. data/lib/csd/application/minisip/options/compile.rb +1 -1
  16. data/lib/csd/application/minisip/options/package.rb +1 -1
  17. data/lib/csd/application/minisip/unix.rb +40 -27
  18. data/lib/csd/application/minisip/unix/darwin.rb +12 -0
  19. data/lib/csd/application/minisip/unix/linux.rb +1 -11
  20. data/lib/csd/application/minisip/unix/linux/debian.rb +14 -25
  21. data/lib/csd/application/minisip/unix/linux/debian/ubuntu10.rb +12 -13
  22. data/lib/csd/applications.rb +5 -5
  23. data/lib/csd/commands.rb +164 -89
  24. data/lib/csd/container.rb +61 -0
  25. data/lib/csd/error.rb +10 -1
  26. data/lib/csd/extensions.rb +3 -2
  27. data/lib/csd/extensions/core/array.rb +29 -1
  28. data/lib/csd/extensions/core/dir.rb +15 -24
  29. data/lib/csd/extensions/core/object.rb +10 -2
  30. data/lib/csd/extensions/core/option_parser.rb +22 -3
  31. data/lib/csd/extensions/core/pathname.rb +30 -2
  32. data/lib/csd/extensions/core/string.rb +51 -4
  33. data/lib/csd/extensions/gem/platform.rb +18 -3
  34. data/lib/csd/{options.rb → options_parser.rb} +16 -20
  35. data/lib/csd/path_container.rb +24 -0
  36. data/lib/csd/user_interface.rb +2 -0
  37. data/lib/csd/user_interface/base.rb +26 -0
  38. data/lib/csd/user_interface/cli.rb +37 -0
  39. data/lib/csd/vendor/active_support/MIT-LICENSE +20 -0
  40. data/lib/csd/vendor/active_support/inflector.rb +155 -0
  41. data/lib/csd/vendor/term/GPL2-LICENSE +339 -0
  42. data/lib/csd/vendor/term/ansicolor.rb +113 -0
  43. data/lib/csd/version.rb +13 -4
  44. data/test/application/test_minisip.rb +45 -0
  45. data/test/functional/test_applications.rb +10 -16
  46. data/test/functional/test_commands.rb +260 -23
  47. data/test/unit/test_string.rb +1 -1
  48. metadata +18 -216
  49. data/lib/active_support.rb +0 -75
  50. data/lib/active_support/all.rb +0 -3
  51. data/lib/active_support/backtrace_cleaner.rb +0 -94
  52. data/lib/active_support/base64.rb +0 -42
  53. data/lib/active_support/basic_object.rb +0 -21
  54. data/lib/active_support/benchmarkable.rb +0 -60
  55. data/lib/active_support/buffered_logger.rb +0 -132
  56. data/lib/active_support/builder.rb +0 -6
  57. data/lib/active_support/cache.rb +0 -626
  58. data/lib/active_support/cache/compressed_mem_cache_store.rb +0 -13
  59. data/lib/active_support/cache/file_store.rb +0 -188
  60. data/lib/active_support/cache/mem_cache_store.rb +0 -191
  61. data/lib/active_support/cache/memory_store.rb +0 -159
  62. data/lib/active_support/cache/strategy/local_cache.rb +0 -164
  63. data/lib/active_support/cache/synchronized_memory_store.rb +0 -11
  64. data/lib/active_support/callbacks.rb +0 -600
  65. data/lib/active_support/concern.rb +0 -29
  66. data/lib/active_support/configurable.rb +0 -36
  67. data/lib/active_support/core_ext.rb +0 -3
  68. data/lib/active_support/core_ext/array.rb +0 -7
  69. data/lib/active_support/core_ext/array/access.rb +0 -46
  70. data/lib/active_support/core_ext/array/conversions.rb +0 -164
  71. data/lib/active_support/core_ext/array/extract_options.rb +0 -29
  72. data/lib/active_support/core_ext/array/grouping.rb +0 -100
  73. data/lib/active_support/core_ext/array/random_access.rb +0 -20
  74. data/lib/active_support/core_ext/array/uniq_by.rb +0 -17
  75. data/lib/active_support/core_ext/array/wrap.rb +0 -22
  76. data/lib/active_support/core_ext/benchmark.rb +0 -7
  77. data/lib/active_support/core_ext/big_decimal.rb +0 -1
  78. data/lib/active_support/core_ext/big_decimal/conversions.rb +0 -27
  79. data/lib/active_support/core_ext/cgi.rb +0 -1
  80. data/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb +0 -19
  81. data/lib/active_support/core_ext/class.rb +0 -4
  82. data/lib/active_support/core_ext/class/attribute.rb +0 -67
  83. data/lib/active_support/core_ext/class/attribute_accessors.rb +0 -63
  84. data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -44
  85. data/lib/active_support/core_ext/class/inheritable_attributes.rb +0 -232
  86. data/lib/active_support/core_ext/class/subclasses.rb +0 -55
  87. data/lib/active_support/core_ext/date/acts_like.rb +0 -8
  88. data/lib/active_support/core_ext/date/calculations.rb +0 -240
  89. data/lib/active_support/core_ext/date/conversions.rb +0 -99
  90. data/lib/active_support/core_ext/date/freeze.rb +0 -31
  91. data/lib/active_support/core_ext/date_time/acts_like.rb +0 -13
  92. data/lib/active_support/core_ext/date_time/calculations.rb +0 -113
  93. data/lib/active_support/core_ext/date_time/conversions.rb +0 -102
  94. data/lib/active_support/core_ext/date_time/zones.rb +0 -17
  95. data/lib/active_support/core_ext/enumerable.rb +0 -119
  96. data/lib/active_support/core_ext/exception.rb +0 -3
  97. data/lib/active_support/core_ext/file.rb +0 -2
  98. data/lib/active_support/core_ext/file/atomic.rb +0 -41
  99. data/lib/active_support/core_ext/file/path.rb +0 -5
  100. data/lib/active_support/core_ext/float.rb +0 -1
  101. data/lib/active_support/core_ext/float/rounding.rb +0 -19
  102. data/lib/active_support/core_ext/hash.rb +0 -8
  103. data/lib/active_support/core_ext/hash/conversions.rb +0 -150
  104. data/lib/active_support/core_ext/hash/deep_merge.rb +0 -16
  105. data/lib/active_support/core_ext/hash/diff.rb +0 -13
  106. data/lib/active_support/core_ext/hash/except.rb +0 -24
  107. data/lib/active_support/core_ext/hash/indifferent_access.rb +0 -14
  108. data/lib/active_support/core_ext/hash/keys.rb +0 -45
  109. data/lib/active_support/core_ext/hash/reverse_merge.rb +0 -28
  110. data/lib/active_support/core_ext/hash/slice.rb +0 -38
  111. data/lib/active_support/core_ext/integer.rb +0 -3
  112. data/lib/active_support/core_ext/integer/inflections.rb +0 -14
  113. data/lib/active_support/core_ext/integer/multiple.rb +0 -6
  114. data/lib/active_support/core_ext/integer/time.rb +0 -39
  115. data/lib/active_support/core_ext/kernel.rb +0 -5
  116. data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
  117. data/lib/active_support/core_ext/kernel/debugger.rb +0 -16
  118. data/lib/active_support/core_ext/kernel/reporting.rb +0 -62
  119. data/lib/active_support/core_ext/kernel/requires.rb +0 -26
  120. data/lib/active_support/core_ext/kernel/singleton_class.rb +0 -13
  121. data/lib/active_support/core_ext/load_error.rb +0 -23
  122. data/lib/active_support/core_ext/logger.rb +0 -146
  123. data/lib/active_support/core_ext/module.rb +0 -12
  124. data/lib/active_support/core_ext/module/aliasing.rb +0 -70
  125. data/lib/active_support/core_ext/module/anonymous.rb +0 -24
  126. data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +0 -31
  127. data/lib/active_support/core_ext/module/attr_internal.rb +0 -32
  128. data/lib/active_support/core_ext/module/attribute_accessors.rb +0 -66
  129. data/lib/active_support/core_ext/module/delegation.rb +0 -146
  130. data/lib/active_support/core_ext/module/deprecation.rb +0 -9
  131. data/lib/active_support/core_ext/module/introspection.rb +0 -88
  132. data/lib/active_support/core_ext/module/method_names.rb +0 -14
  133. data/lib/active_support/core_ext/module/reachable.rb +0 -10
  134. data/lib/active_support/core_ext/module/remove_method.rb +0 -6
  135. data/lib/active_support/core_ext/module/synchronization.rb +0 -42
  136. data/lib/active_support/core_ext/name_error.rb +0 -18
  137. data/lib/active_support/core_ext/numeric.rb +0 -2
  138. data/lib/active_support/core_ext/numeric/bytes.rb +0 -44
  139. data/lib/active_support/core_ext/numeric/time.rb +0 -77
  140. data/lib/active_support/core_ext/object.rb +0 -14
  141. data/lib/active_support/core_ext/object/acts_like.rb +0 -10
  142. data/lib/active_support/core_ext/object/blank.rb +0 -76
  143. data/lib/active_support/core_ext/object/conversions.rb +0 -4
  144. data/lib/active_support/core_ext/object/duplicable.rb +0 -65
  145. data/lib/active_support/core_ext/object/extending.rb +0 -11
  146. data/lib/active_support/core_ext/object/instance_variables.rb +0 -67
  147. data/lib/active_support/core_ext/object/misc.rb +0 -2
  148. data/lib/active_support/core_ext/object/returning.rb +0 -42
  149. data/lib/active_support/core_ext/object/to_param.rb +0 -49
  150. data/lib/active_support/core_ext/object/to_query.rb +0 -27
  151. data/lib/active_support/core_ext/object/try.rb +0 -36
  152. data/lib/active_support/core_ext/object/with_options.rb +0 -26
  153. data/lib/active_support/core_ext/proc.rb +0 -14
  154. data/lib/active_support/core_ext/process.rb +0 -1
  155. data/lib/active_support/core_ext/process/daemon.rb +0 -23
  156. data/lib/active_support/core_ext/range.rb +0 -4
  157. data/lib/active_support/core_ext/range/blockless_step.rb +0 -29
  158. data/lib/active_support/core_ext/range/conversions.rb +0 -21
  159. data/lib/active_support/core_ext/range/include_range.rb +0 -21
  160. data/lib/active_support/core_ext/range/overlaps.rb +0 -8
  161. data/lib/active_support/core_ext/regexp.rb +0 -5
  162. data/lib/active_support/core_ext/rexml.rb +0 -46
  163. data/lib/active_support/core_ext/string.rb +0 -12
  164. data/lib/active_support/core_ext/string/access.rb +0 -99
  165. data/lib/active_support/core_ext/string/behavior.rb +0 -7
  166. data/lib/active_support/core_ext/string/conversions.rb +0 -61
  167. data/lib/active_support/core_ext/string/encoding.rb +0 -11
  168. data/lib/active_support/core_ext/string/exclude.rb +0 -6
  169. data/lib/active_support/core_ext/string/filters.rb +0 -49
  170. data/lib/active_support/core_ext/string/inflections.rb +0 -149
  171. data/lib/active_support/core_ext/string/interpolation.rb +0 -2
  172. data/lib/active_support/core_ext/string/multibyte.rb +0 -72
  173. data/lib/active_support/core_ext/string/output_safety.rb +0 -109
  174. data/lib/active_support/core_ext/string/starts_ends_with.rb +0 -4
  175. data/lib/active_support/core_ext/string/xchar.rb +0 -18
  176. data/lib/active_support/core_ext/time/acts_like.rb +0 -8
  177. data/lib/active_support/core_ext/time/calculations.rb +0 -282
  178. data/lib/active_support/core_ext/time/conversions.rb +0 -85
  179. data/lib/active_support/core_ext/time/marshal.rb +0 -56
  180. data/lib/active_support/core_ext/time/publicize_conversion_methods.rb +0 -10
  181. data/lib/active_support/core_ext/time/zones.rb +0 -78
  182. data/lib/active_support/core_ext/uri.rb +0 -22
  183. data/lib/active_support/dependencies.rb +0 -628
  184. data/lib/active_support/dependencies/autoload.rb +0 -50
  185. data/lib/active_support/deprecation.rb +0 -18
  186. data/lib/active_support/deprecation/behaviors.rb +0 -38
  187. data/lib/active_support/deprecation/method_wrappers.rb +0 -29
  188. data/lib/active_support/deprecation/proxy_wrappers.rb +0 -74
  189. data/lib/active_support/deprecation/reporting.rb +0 -56
  190. data/lib/active_support/duration.rb +0 -105
  191. data/lib/active_support/gzip.rb +0 -25
  192. data/lib/active_support/hash_with_indifferent_access.rb +0 -145
  193. data/lib/active_support/i18n.rb +0 -8
  194. data/lib/active_support/inflections.rb +0 -56
  195. data/lib/active_support/inflector.rb +0 -7
  196. data/lib/active_support/inflector/inflections.rb +0 -211
  197. data/lib/active_support/inflector/methods.rb +0 -141
  198. data/lib/active_support/inflector/transliterate.rb +0 -97
  199. data/lib/active_support/json.rb +0 -2
  200. data/lib/active_support/json/backends/jsongem.rb +0 -43
  201. data/lib/active_support/json/backends/yajl.rb +0 -40
  202. data/lib/active_support/json/backends/yaml.rb +0 -90
  203. data/lib/active_support/json/decoding.rb +0 -51
  204. data/lib/active_support/json/encoding.rb +0 -254
  205. data/lib/active_support/json/variable.rb +0 -11
  206. data/lib/active_support/lazy_load_hooks.rb +0 -27
  207. data/lib/active_support/locale/en.yml +0 -36
  208. data/lib/active_support/memoizable.rb +0 -103
  209. data/lib/active_support/message_encryptor.rb +0 -71
  210. data/lib/active_support/message_verifier.rb +0 -62
  211. data/lib/active_support/multibyte.rb +0 -44
  212. data/lib/active_support/multibyte/chars.rb +0 -480
  213. data/lib/active_support/multibyte/exceptions.rb +0 -8
  214. data/lib/active_support/multibyte/unicode.rb +0 -393
  215. data/lib/active_support/multibyte/utils.rb +0 -60
  216. data/lib/active_support/notifications.rb +0 -81
  217. data/lib/active_support/notifications/fanout.rb +0 -93
  218. data/lib/active_support/notifications/instrumenter.rb +0 -56
  219. data/lib/active_support/option_merger.rb +0 -25
  220. data/lib/active_support/ordered_hash.rb +0 -158
  221. data/lib/active_support/ordered_options.rb +0 -27
  222. data/lib/active_support/railtie.rb +0 -100
  223. data/lib/active_support/rescuable.rb +0 -114
  224. data/lib/active_support/ruby/shim.rb +0 -22
  225. data/lib/active_support/secure_random.rb +0 -199
  226. data/lib/active_support/string_inquirer.rb +0 -21
  227. data/lib/active_support/test_case.rb +0 -42
  228. data/lib/active_support/testing/assertions.rb +0 -82
  229. data/lib/active_support/testing/declarative.rb +0 -40
  230. data/lib/active_support/testing/default.rb +0 -9
  231. data/lib/active_support/testing/deprecation.rb +0 -55
  232. data/lib/active_support/testing/isolation.rb +0 -154
  233. data/lib/active_support/testing/pending.rb +0 -48
  234. data/lib/active_support/testing/performance.rb +0 -455
  235. data/lib/active_support/testing/setup_and_teardown.rb +0 -111
  236. data/lib/active_support/time.rb +0 -34
  237. data/lib/active_support/time/autoload.rb +0 -5
  238. data/lib/active_support/time_with_zone.rb +0 -341
  239. data/lib/active_support/values/time_zone.rb +0 -377
  240. data/lib/active_support/values/unicode_tables.dat +0 -0
  241. data/lib/active_support/version.rb +0 -10
  242. data/lib/active_support/whiny_nil.rb +0 -60
  243. data/lib/active_support/xml_mini.rb +0 -158
  244. data/lib/active_support/xml_mini/jdom.rb +0 -168
  245. data/lib/active_support/xml_mini/libxml.rb +0 -80
  246. data/lib/active_support/xml_mini/libxmlsax.rb +0 -85
  247. data/lib/active_support/xml_mini/nokogiri.rb +0 -78
  248. data/lib/active_support/xml_mini/nokogirisax.rb +0 -83
  249. data/lib/active_support/xml_mini/rexml.rb +0 -129
  250. data/lib/csd/extensions/core/file.rb +0 -14
  251. data/lib/csd/global_open_struct.rb +0 -19
  252. data/lib/csd/path.rb +0 -32
  253. data/lib/csd/ui.rb +0 -2
  254. data/lib/csd/ui/cli.rb +0 -8
  255. data/lib/csd/ui/ui.rb +0 -45
  256. data/lib/term/ansicolor.rb +0 -102
  257. data/lib/term/ansicolor/.keep +0 -0
  258. data/lib/term/ansicolor/version.rb +0 -10
@@ -1,11 +0,0 @@
1
- module ActiveSupport
2
- module JSON
3
- # A string that returns itself as its JSON-encoded form.
4
- class Variable < String
5
- private
6
- def rails_to_json(*)
7
- self
8
- end
9
- end
10
- end
11
- end
@@ -1,27 +0,0 @@
1
- module ActiveSupport
2
- @load_hooks = Hash.new {|h,k| h[k] = [] }
3
- @loaded = {}
4
-
5
- def self.on_load(name, options = {}, &block)
6
- if base = @loaded[name]
7
- execute_hook(base, options, block)
8
- else
9
- @load_hooks[name] << [block, options]
10
- end
11
- end
12
-
13
- def self.execute_hook(base, options, block)
14
- if options[:yield]
15
- block.call(base)
16
- else
17
- base.instance_eval(&block)
18
- end
19
- end
20
-
21
- def self.run_load_hooks(name, base = Object)
22
- @loaded[name] = base
23
- @load_hooks[name].each do |hook, options|
24
- execute_hook(base, options, hook)
25
- end
26
- end
27
- end
@@ -1,36 +0,0 @@
1
- en:
2
- date:
3
- formats:
4
- # Use the strftime parameters for formats.
5
- # When no format has been given, it uses default.
6
- # You can provide other formats here if you like!
7
- default: "%Y-%m-%d"
8
- short: "%b %d"
9
- long: "%B %d, %Y"
10
-
11
- day_names: [Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday]
12
- abbr_day_names: [Sun, Mon, Tue, Wed, Thu, Fri, Sat]
13
-
14
- # Don't forget the nil at the beginning; there's no such thing as a 0th month
15
- month_names: [~, January, February, March, April, May, June, July, August, September, October, November, December]
16
- abbr_month_names: [~, Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec]
17
- # Used in date_select and datime_select.
18
- order:
19
- - :year
20
- - :month
21
- - :day
22
-
23
- time:
24
- formats:
25
- default: "%a, %d %b %Y %H:%M:%S %z"
26
- short: "%d %b %H:%M"
27
- long: "%B %d, %Y %H:%M"
28
- am: "am"
29
- pm: "pm"
30
-
31
- # Used in array.to_sentence.
32
- support:
33
- array:
34
- words_connector: ", "
35
- two_words_connector: " and "
36
- last_word_connector: ", and "
@@ -1,103 +0,0 @@
1
- require 'active_support/core_ext/kernel/singleton_class'
2
- require 'active_support/core_ext/module/aliasing'
3
-
4
- module ActiveSupport
5
- module Memoizable
6
- def self.memoized_ivar_for(symbol)
7
- "@_memoized_#{symbol.to_s.sub(/\?\Z/, '_query').sub(/!\Z/, '_bang')}".to_sym
8
- end
9
-
10
- module InstanceMethods
11
- def self.included(base)
12
- base.class_eval do
13
- unless base.method_defined?(:freeze_without_memoizable)
14
- alias_method_chain :freeze, :memoizable
15
- end
16
- end
17
- end
18
-
19
- def freeze_with_memoizable
20
- memoize_all unless frozen?
21
- freeze_without_memoizable
22
- end
23
-
24
- def memoize_all
25
- prime_cache ".*"
26
- end
27
-
28
- def unmemoize_all
29
- flush_cache ".*"
30
- end
31
-
32
- def prime_cache(*syms)
33
- syms.each do |sym|
34
- methods.each do |m|
35
- if m.to_s =~ /^_unmemoized_(#{sym})/
36
- if method(m).arity == 0
37
- __send__($1)
38
- else
39
- ivar = ActiveSupport::Memoizable.memoized_ivar_for($1)
40
- instance_variable_set(ivar, {})
41
- end
42
- end
43
- end
44
- end
45
- end
46
-
47
- def flush_cache(*syms)
48
- syms.each do |sym|
49
- (methods + private_methods + protected_methods).each do |m|
50
- if m.to_s =~ /^_unmemoized_(#{sym.to_s.gsub(/\?\Z/, '\?')})/
51
- ivar = ActiveSupport::Memoizable.memoized_ivar_for($1)
52
- instance_variable_get(ivar).clear if instance_variable_defined?(ivar)
53
- end
54
- end
55
- end
56
- end
57
- end
58
-
59
- def memoize(*symbols)
60
- symbols.each do |symbol|
61
- original_method = :"_unmemoized_#{symbol}"
62
- memoized_ivar = ActiveSupport::Memoizable.memoized_ivar_for(symbol)
63
-
64
- class_eval <<-EOS, __FILE__, __LINE__ + 1
65
- include InstanceMethods # include InstanceMethods
66
- #
67
- if method_defined?(:#{original_method}) # if method_defined?(:_unmemoized_mime_type)
68
- raise "Already memoized #{symbol}" # raise "Already memoized mime_type"
69
- end # end
70
- alias #{original_method} #{symbol} # alias _unmemoized_mime_type mime_type
71
- #
72
- if instance_method(:#{symbol}).arity == 0 # if instance_method(:mime_type).arity == 0
73
- def #{symbol}(reload = false) # def mime_type(reload = false)
74
- if reload || !defined?(#{memoized_ivar}) || #{memoized_ivar}.empty? # if reload || !defined?(@_memoized_mime_type) || @_memoized_mime_type.empty?
75
- #{memoized_ivar} = [#{original_method}] # @_memoized_mime_type = [_unmemoized_mime_type]
76
- end # end
77
- #{memoized_ivar}[0] # @_memoized_mime_type[0]
78
- end # end
79
- else # else
80
- def #{symbol}(*args) # def mime_type(*args)
81
- #{memoized_ivar} ||= {} unless frozen? # @_memoized_mime_type ||= {} unless frozen?
82
- reload = args.pop if args.last == true || args.last == :reload # reload = args.pop if args.last == true || args.last == :reload
83
- #
84
- if defined?(#{memoized_ivar}) && #{memoized_ivar} # if defined?(@_memoized_mime_type) && @_memoized_mime_type
85
- if !reload && #{memoized_ivar}.has_key?(args) # if !reload && @_memoized_mime_type.has_key?(args)
86
- #{memoized_ivar}[args] # @_memoized_mime_type[args]
87
- elsif #{memoized_ivar} # elsif @_memoized_mime_type
88
- #{memoized_ivar}[args] = #{original_method}(*args) # @_memoized_mime_type[args] = _unmemoized_mime_type(*args)
89
- end # end
90
- else # else
91
- #{original_method}(*args) # _unmemoized_mime_type(*args)
92
- end # end
93
- end # end
94
- end # end
95
- #
96
- if private_method_defined?(#{original_method.inspect}) # if private_method_defined?(:_unmemoized_mime_type)
97
- private #{symbol.inspect} # private :mime_type
98
- end # end
99
- EOS
100
- end
101
- end
102
- end
103
- end
@@ -1,71 +0,0 @@
1
- require 'openssl'
2
- require 'active_support/base64'
3
-
4
- module ActiveSupport
5
- # MessageEncryptor is a simple way to encrypt values which get stored somewhere
6
- # you don't trust.
7
- #
8
- # The cipher text and initialization vector are base64 encoded and returned to you.
9
- #
10
- # This can be used in situations similar to the MessageVerifier, but where you don't
11
- # want users to be able to determine the value of the payload.
12
- class MessageEncryptor
13
- class InvalidMessage < StandardError; end
14
- OpenSSLCipherError = OpenSSL::Cipher.const_defined?(:CipherError) ? OpenSSL::Cipher::CipherError : OpenSSL::CipherError
15
-
16
- def initialize(secret, cipher = 'aes-256-cbc')
17
- @secret = secret
18
- @cipher = cipher
19
- end
20
-
21
- def encrypt(value)
22
- cipher = new_cipher
23
- # Rely on OpenSSL for the initialization vector
24
- iv = cipher.random_iv
25
-
26
- cipher.encrypt
27
- cipher.key = @secret
28
- cipher.iv = iv
29
-
30
- encrypted_data = cipher.update(Marshal.dump(value))
31
- encrypted_data << cipher.final
32
-
33
- [encrypted_data, iv].map {|v| ActiveSupport::Base64.encode64s(v)}.join("--")
34
- end
35
-
36
- def decrypt(encrypted_message)
37
- cipher = new_cipher
38
- encrypted_data, iv = encrypted_message.split("--").map {|v| ActiveSupport::Base64.decode64(v)}
39
-
40
- cipher.decrypt
41
- cipher.key = @secret
42
- cipher.iv = iv
43
-
44
- decrypted_data = cipher.update(encrypted_data)
45
- decrypted_data << cipher.final
46
-
47
- Marshal.load(decrypted_data)
48
- rescue OpenSSLCipherError, TypeError
49
- raise InvalidMessage
50
- end
51
-
52
- def encrypt_and_sign(value)
53
- verifier.generate(encrypt(value))
54
- end
55
-
56
- def decrypt_and_verify(value)
57
- decrypt(verifier.verify(value))
58
- end
59
-
60
-
61
-
62
- private
63
- def new_cipher
64
- OpenSSL::Cipher::Cipher.new(@cipher)
65
- end
66
-
67
- def verifier
68
- MessageVerifier.new(@secret)
69
- end
70
- end
71
- end
@@ -1,62 +0,0 @@
1
- require 'active_support/base64'
2
- require 'active_support/core_ext/object/blank'
3
-
4
- module ActiveSupport
5
- # MessageVerifier makes it easy to generate and verify messages which are signed
6
- # to prevent tampering.
7
- #
8
- # This is useful for cases like remember-me tokens and auto-unsubscribe links where the
9
- # session store isn't suitable or available.
10
- #
11
- # Remember Me:
12
- # cookies[:remember_me] = @verifier.generate([@user.id, 2.weeks.from_now])
13
- #
14
- # In the authentication filter:
15
- #
16
- # id, time = @verifier.verify(cookies[:remember_me])
17
- # if time < Time.now
18
- # self.current_user = User.find(id)
19
- # end
20
- #
21
- class MessageVerifier
22
- class InvalidSignature < StandardError; end
23
-
24
- def initialize(secret, digest = 'SHA1')
25
- @secret = secret
26
- @digest = digest
27
- end
28
-
29
- def verify(signed_message)
30
- raise InvalidSignature if signed_message.blank?
31
-
32
- data, digest = signed_message.split("--")
33
- if data.present? && digest.present? && secure_compare(digest, generate_digest(data))
34
- Marshal.load(ActiveSupport::Base64.decode64(data))
35
- else
36
- raise InvalidSignature
37
- end
38
- end
39
-
40
- def generate(value)
41
- data = ActiveSupport::Base64.encode64s(Marshal.dump(value))
42
- "#{data}--#{generate_digest(data)}"
43
- end
44
-
45
- private
46
- # constant-time comparison algorithm to prevent timing attacks
47
- def secure_compare(a, b)
48
- return false unless a.bytesize == b.bytesize
49
-
50
- l = a.unpack "C*"
51
-
52
- res = true
53
- b.each_byte { |byte| res = (byte == l.shift) && res }
54
- res
55
- end
56
-
57
- def generate_digest(data)
58
- require 'openssl' unless defined?(OpenSSL)
59
- OpenSSL::HMAC.hexdigest(OpenSSL::Digest.const_get(@digest).new, @secret, data)
60
- end
61
- end
62
- end
@@ -1,44 +0,0 @@
1
- # encoding: utf-8
2
- require 'active_support/core_ext/module/attribute_accessors'
3
-
4
- module ActiveSupport #:nodoc:
5
- module Multibyte
6
- autoload :EncodingError, 'active_support/multibyte/exceptions'
7
- autoload :Chars, 'active_support/multibyte/chars'
8
- autoload :Unicode, 'active_support/multibyte/unicode'
9
-
10
- # The proxy class returned when calling mb_chars. You can use this accessor to configure your own proxy
11
- # class so you can support other encodings. See the ActiveSupport::Multibyte::Chars implementation for
12
- # an example how to do this.
13
- #
14
- # Example:
15
- # ActiveSupport::Multibyte.proxy_class = CharsForUTF32
16
- def self.proxy_class=(klass)
17
- @proxy_class = klass
18
- end
19
-
20
- # Returns the currect proxy class
21
- def self.proxy_class
22
- @proxy_class ||= ActiveSupport::Multibyte::Chars
23
- end
24
-
25
- # Regular expressions that describe valid byte sequences for a character
26
- VALID_CHARACTER = {
27
- # Borrowed from the Kconv library by Shinji KONO - (also as seen on the W3C site)
28
- 'UTF-8' => /\A(?:
29
- [\x00-\x7f] |
30
- [\xc2-\xdf] [\x80-\xbf] |
31
- \xe0 [\xa0-\xbf] [\x80-\xbf] |
32
- [\xe1-\xef] [\x80-\xbf] [\x80-\xbf] |
33
- \xf0 [\x90-\xbf] [\x80-\xbf] [\x80-\xbf] |
34
- [\xf1-\xf3] [\x80-\xbf] [\x80-\xbf] [\x80-\xbf] |
35
- \xf4 [\x80-\x8f] [\x80-\xbf] [\x80-\xbf])\z /xn,
36
- # Quick check for valid Shift-JIS characters, disregards the odd-even pairing
37
- 'Shift_JIS' => /\A(?:
38
- [\x00-\x7e\xa1-\xdf] |
39
- [\x81-\x9f\xe0-\xef] [\x40-\x7e\x80-\x9e\x9f-\xfc])\z /xn
40
- }
41
- end
42
- end
43
-
44
- require 'active_support/multibyte/utils'
@@ -1,480 +0,0 @@
1
- # encoding: utf-8
2
- require 'active_support/core_ext/string/access'
3
- require 'active_support/core_ext/string/behavior'
4
-
5
- module ActiveSupport #:nodoc:
6
- module Multibyte #:nodoc:
7
- # Chars enables you to work transparently with UTF-8 encoding in the Ruby String class without having extensive
8
- # knowledge about the encoding. A Chars object accepts a string upon initialization and proxies String methods in an
9
- # encoding safe manner. All the normal String methods are also implemented on the proxy.
10
- #
11
- # String methods are proxied through the Chars object, and can be accessed through the +mb_chars+ method. Methods
12
- # which would normally return a String object now return a Chars object so methods can be chained.
13
- #
14
- # "The Perfect String ".mb_chars.downcase.strip.normalize #=> "the perfect string"
15
- #
16
- # Chars objects are perfectly interchangeable with String objects as long as no explicit class checks are made.
17
- # If certain methods do explicitly check the class, call +to_s+ before you pass chars objects to them.
18
- #
19
- # bad.explicit_checking_method "T".mb_chars.downcase.to_s
20
- #
21
- # The default Chars implementation assumes that the encoding of the string is UTF-8, if you want to handle different
22
- # encodings you can write your own multibyte string handler and configure it through
23
- # ActiveSupport::Multibyte.proxy_class.
24
- #
25
- # class CharsForUTF32
26
- # def size
27
- # @wrapped_string.size / 4
28
- # end
29
- #
30
- # def self.accepts?(string)
31
- # string.length % 4 == 0
32
- # end
33
- # end
34
- #
35
- # ActiveSupport::Multibyte.proxy_class = CharsForUTF32
36
- class Chars
37
-
38
- attr_reader :wrapped_string
39
- alias to_s wrapped_string
40
- alias to_str wrapped_string
41
-
42
- if RUBY_VERSION >= "1.9"
43
- # Creates a new Chars instance by wrapping _string_.
44
- def initialize(string)
45
- @wrapped_string = string
46
- @wrapped_string.force_encoding(Encoding::UTF_8) unless @wrapped_string.frozen?
47
- end
48
-
49
- undef <=>
50
- else
51
- def initialize(string) #:nodoc:
52
- @wrapped_string = string
53
- end
54
- end
55
-
56
- # Forward all undefined methods to the wrapped string.
57
- def method_missing(method, *args, &block)
58
- if method.to_s =~ /!$/
59
- @wrapped_string.__send__(method, *args, &block)
60
- self
61
- else
62
- result = @wrapped_string.__send__(method, *args, &block)
63
- result.kind_of?(String) ? chars(result) : result
64
- end
65
- end
66
-
67
- # Returns +true+ if _obj_ responds to the given method. Private methods are included in the search
68
- # only if the optional second parameter evaluates to +true+.
69
- def respond_to?(method, include_private=false)
70
- super || @wrapped_string.respond_to?(method, include_private) || false
71
- end
72
-
73
- # Enable more predictable duck-typing on String-like classes. See Object#acts_like?.
74
- def acts_like_string?
75
- true
76
- end
77
-
78
- # Returns +true+ when the proxy class can handle the string. Returns +false+ otherwise.
79
- def self.consumes?(string)
80
- # Unpack is a little bit faster than regular expressions.
81
- string.unpack('U*')
82
- true
83
- rescue ArgumentError
84
- false
85
- end
86
-
87
- include Comparable
88
-
89
- if RUBY_VERSION < "1.9"
90
- # Returns +true+ if the Chars class can and should act as a proxy for the string _string_. Returns
91
- # +false+ otherwise.
92
- def self.wants?(string)
93
- $KCODE == 'UTF8' && consumes?(string)
94
- end
95
-
96
- # Returns <tt>-1</tt>, <tt>0</tt> or <tt>+1</tt> depending on whether the Chars object is to be sorted before,
97
- # equal or after the object on the right side of the operation. It accepts any object that implements +to_s+.
98
- # See <tt>String#<=></tt> for more details.
99
- #
100
- # Example:
101
- # 'é'.mb_chars <=> 'ü'.mb_chars #=> -1
102
- def <=>(other)
103
- @wrapped_string <=> other.to_s
104
- end
105
-
106
- # Returns a new Chars object containing the _other_ object concatenated to the string.
107
- #
108
- # Example:
109
- # ('Café'.mb_chars + ' périferôl').to_s #=> "Café périferôl"
110
- def +(other)
111
- self << other
112
- end
113
-
114
- # Like <tt>String#=~</tt> only it returns the character offset (in codepoints) instead of the byte offset.
115
- #
116
- # Example:
117
- # 'Café périferôl'.mb_chars =~ /ô/ #=> 12
118
- def =~(other)
119
- translate_offset(@wrapped_string =~ other)
120
- end
121
-
122
- # Inserts the passed string at specified codepoint offsets.
123
- #
124
- # Example:
125
- # 'Café'.mb_chars.insert(4, ' périferôl').to_s #=> "Café périferôl"
126
- def insert(offset, fragment)
127
- unpacked = Unicode.u_unpack(@wrapped_string)
128
- unless offset > unpacked.length
129
- @wrapped_string.replace(
130
- Unicode.u_unpack(@wrapped_string).insert(offset, *Unicode.u_unpack(fragment)).pack('U*')
131
- )
132
- else
133
- raise IndexError, "index #{offset} out of string"
134
- end
135
- self
136
- end
137
-
138
- # Returns +true+ if contained string contains _other_. Returns +false+ otherwise.
139
- #
140
- # Example:
141
- # 'Café'.mb_chars.include?('é') #=> true
142
- def include?(other)
143
- # We have to redefine this method because Enumerable defines it.
144
- @wrapped_string.include?(other)
145
- end
146
-
147
- # Returns the position _needle_ in the string, counting in codepoints. Returns +nil+ if _needle_ isn't found.
148
- #
149
- # Example:
150
- # 'Café périferôl'.mb_chars.index('ô') #=> 12
151
- # 'Café périferôl'.mb_chars.index(/\w/u) #=> 0
152
- def index(needle, offset=0)
153
- wrapped_offset = first(offset).wrapped_string.length
154
- index = @wrapped_string.index(needle, wrapped_offset)
155
- index ? (Unicode.u_unpack(@wrapped_string.slice(0...index)).size) : nil
156
- end
157
-
158
- # Returns the position _needle_ in the string, counting in
159
- # codepoints, searching backward from _offset_ or the end of the
160
- # string. Returns +nil+ if _needle_ isn't found.
161
- #
162
- # Example:
163
- # 'Café périferôl'.mb_chars.rindex('é') #=> 6
164
- # 'Café périferôl'.mb_chars.rindex(/\w/u) #=> 13
165
- def rindex(needle, offset=nil)
166
- offset ||= length
167
- wrapped_offset = first(offset).wrapped_string.length
168
- index = @wrapped_string.rindex(needle, wrapped_offset)
169
- index ? (Unicode.u_unpack(@wrapped_string.slice(0...index)).size) : nil
170
- end
171
-
172
- # Returns the number of codepoints in the string
173
- def size
174
- Unicode.u_unpack(@wrapped_string).size
175
- end
176
- alias_method :length, :size
177
-
178
- # Strips entire range of Unicode whitespace from the right of the string.
179
- def rstrip
180
- chars(@wrapped_string.gsub(Unicode::TRAILERS_PAT, ''))
181
- end
182
-
183
- # Strips entire range of Unicode whitespace from the left of the string.
184
- def lstrip
185
- chars(@wrapped_string.gsub(Unicode::LEADERS_PAT, ''))
186
- end
187
-
188
- # Strips entire range of Unicode whitespace from the right and left of the string.
189
- def strip
190
- rstrip.lstrip
191
- end
192
-
193
- # Returns the codepoint of the first character in the string.
194
- #
195
- # Example:
196
- # 'こんにちは'.mb_chars.ord #=> 12371
197
- def ord
198
- Unicode.u_unpack(@wrapped_string)[0]
199
- end
200
-
201
- else
202
- def =~(other)
203
- @wrapped_string =~ other
204
- end
205
- end
206
-
207
- # Works just like <tt>String#split</tt>, with the exception that the items in the resulting list are Chars
208
- # instances instead of String. This makes chaining methods easier.
209
- #
210
- # Example:
211
- # 'Café périferôl'.mb_chars.split(/é/).map { |part| part.upcase.to_s } #=> ["CAF", " P", "RIFERÔL"]
212
- def split(*args)
213
- @wrapped_string.split(*args).map { |i| i.mb_chars }
214
- end
215
-
216
- # Like <tt>String#[]=</tt>, except instead of byte offsets you specify character offsets.
217
- #
218
- # Example:
219
- #
220
- # s = "Müller"
221
- # s.mb_chars[2] = "e" # Replace character with offset 2
222
- # s
223
- # #=> "Müeler"
224
- #
225
- # s = "Müller"
226
- # s.mb_chars[1, 2] = "ö" # Replace 2 characters at character offset 1
227
- # s
228
- # #=> "Möler"
229
- def []=(*args)
230
- replace_by = args.pop
231
- # Indexed replace with regular expressions already works
232
- if args.first.is_a?(Regexp)
233
- @wrapped_string[*args] = replace_by
234
- else
235
- result = Unicode.u_unpack(@wrapped_string)
236
- if args[0].is_a?(Fixnum)
237
- raise IndexError, "index #{args[0]} out of string" if args[0] >= result.length
238
- min = args[0]
239
- max = args[1].nil? ? min : (min + args[1] - 1)
240
- range = Range.new(min, max)
241
- replace_by = [replace_by].pack('U') if replace_by.is_a?(Fixnum)
242
- elsif args.first.is_a?(Range)
243
- raise RangeError, "#{args[0]} out of range" if args[0].min >= result.length
244
- range = args[0]
245
- else
246
- needle = args[0].to_s
247
- min = index(needle)
248
- max = min + Unicode.u_unpack(needle).length - 1
249
- range = Range.new(min, max)
250
- end
251
- result[range] = Unicode.u_unpack(replace_by)
252
- @wrapped_string.replace(result.pack('U*'))
253
- end
254
- end
255
-
256
- # Works just like <tt>String#rjust</tt>, only integer specifies characters instead of bytes.
257
- #
258
- # Example:
259
- #
260
- # "¾ cup".mb_chars.rjust(8).to_s
261
- # #=> " ¾ cup"
262
- #
263
- # "¾ cup".mb_chars.rjust(8, " ").to_s # Use non-breaking whitespace
264
- # #=> "   ¾ cup"
265
- def rjust(integer, padstr=' ')
266
- justify(integer, :right, padstr)
267
- end
268
-
269
- # Works just like <tt>String#ljust</tt>, only integer specifies characters instead of bytes.
270
- #
271
- # Example:
272
- #
273
- # "¾ cup".mb_chars.rjust(8).to_s
274
- # #=> "¾ cup "
275
- #
276
- # "¾ cup".mb_chars.rjust(8, " ").to_s # Use non-breaking whitespace
277
- # #=> "¾ cup   "
278
- def ljust(integer, padstr=' ')
279
- justify(integer, :left, padstr)
280
- end
281
-
282
- # Works just like <tt>String#center</tt>, only integer specifies characters instead of bytes.
283
- #
284
- # Example:
285
- #
286
- # "¾ cup".mb_chars.center(8).to_s
287
- # #=> " ¾ cup "
288
- #
289
- # "¾ cup".mb_chars.center(8, " ").to_s # Use non-breaking whitespace
290
- # #=> " ¾ cup  "
291
- def center(integer, padstr=' ')
292
- justify(integer, :center, padstr)
293
- end
294
-
295
-
296
- # Reverses all characters in the string.
297
- #
298
- # Example:
299
- # 'Café'.mb_chars.reverse.to_s #=> 'éfaC'
300
- def reverse
301
- chars(Unicode.g_unpack(@wrapped_string).reverse.flatten.pack('U*'))
302
- end
303
-
304
- # Implements Unicode-aware slice with codepoints. Slicing on one point returns the codepoints for that
305
- # character.
306
- #
307
- # Example:
308
- # 'こんにちは'.mb_chars.slice(2..3).to_s #=> "にち"
309
- def slice(*args)
310
- if args.size > 2
311
- raise ArgumentError, "wrong number of arguments (#{args.size} for 1)" # Do as if we were native
312
- elsif (args.size == 2 && !(args.first.is_a?(Numeric) || args.first.is_a?(Regexp)))
313
- raise TypeError, "cannot convert #{args.first.class} into Integer" # Do as if we were native
314
- elsif (args.size == 2 && !args[1].is_a?(Numeric))
315
- raise TypeError, "cannot convert #{args[1].class} into Integer" # Do as if we were native
316
- elsif args[0].kind_of? Range
317
- cps = Unicode.u_unpack(@wrapped_string).slice(*args)
318
- result = cps.nil? ? nil : cps.pack('U*')
319
- elsif args[0].kind_of? Regexp
320
- result = @wrapped_string.slice(*args)
321
- elsif args.size == 1 && args[0].kind_of?(Numeric)
322
- character = Unicode.u_unpack(@wrapped_string)[args[0]]
323
- result = character.nil? ? nil : [character].pack('U')
324
- else
325
- result = Unicode.u_unpack(@wrapped_string).slice(*args).pack('U*')
326
- end
327
- result.nil? ? nil : chars(result)
328
- end
329
- alias_method :[], :slice
330
-
331
- # Like <tt>String#slice!</tt>, except instead of byte offsets you specify character offsets.
332
- #
333
- # Example:
334
- # s = 'こんにちは'
335
- # s.mb_chars.slice!(2..3).to_s #=> "にち"
336
- # s #=> "こんは"
337
- def slice!(*args)
338
- slice = self[*args]
339
- self[*args] = ''
340
- slice
341
- end
342
-
343
- # Limit the byte size of the string to a number of bytes without breaking characters. Usable
344
- # when the storage for a string is limited for some reason.
345
- #
346
- # Example:
347
- # s = 'こんにちは'
348
- # s.mb_chars.limit(7) #=> "こに"
349
- def limit(limit)
350
- slice(0...translate_offset(limit))
351
- end
352
-
353
- # Convert characters in the string to uppercase.
354
- #
355
- # Example:
356
- # 'Laurent, où sont les tests ?'.mb_chars.upcase.to_s #=> "LAURENT, OÙ SONT LES TESTS ?"
357
- def upcase
358
- chars(Unicode.apply_mapping @wrapped_string, :uppercase_mapping)
359
- end
360
-
361
- # Convert characters in the string to lowercase.
362
- #
363
- # Example:
364
- # 'VĚDA A VÝZKUM'.mb_chars.downcase.to_s #=> "věda a výzkum"
365
- def downcase
366
- chars(Unicode.apply_mapping @wrapped_string, :lowercase_mapping)
367
- end
368
-
369
- # Converts the first character to uppercase and the remainder to lowercase.
370
- #
371
- # Example:
372
- # 'über'.mb_chars.capitalize.to_s #=> "Über"
373
- def capitalize
374
- (slice(0) || chars('')).upcase + (slice(1..-1) || chars('')).downcase
375
- end
376
-
377
- # Returns the KC normalization of the string by default. NFKC is considered the best normalization form for
378
- # passing strings to databases and validations.
379
- #
380
- # * <tt>form</tt> - The form you want to normalize in. Should be one of the following:
381
- # <tt>:c</tt>, <tt>:kc</tt>, <tt>:d</tt>, or <tt>:kd</tt>. Default is
382
- # ActiveSupport::Multibyte::Unicode.default_normalization_form
383
- def normalize(form = nil)
384
- chars(Unicode.normalize(@wrapped_string, form))
385
- end
386
-
387
- # Performs canonical decomposition on all the characters.
388
- #
389
- # Example:
390
- # 'é'.length #=> 2
391
- # 'é'.mb_chars.decompose.to_s.length #=> 3
392
- def decompose
393
- chars(Unicode.decompose_codepoints(:canonical, Unicode.u_unpack(@wrapped_string)).pack('U*'))
394
- end
395
-
396
- # Performs composition on all the characters.
397
- #
398
- # Example:
399
- # 'é'.length #=> 3
400
- # 'é'.mb_chars.compose.to_s.length #=> 2
401
- def compose
402
- chars(Unicode.compose_codepoints(Unicode.u_unpack(@wrapped_string)).pack('U*'))
403
- end
404
-
405
- # Returns the number of grapheme clusters in the string.
406
- #
407
- # Example:
408
- # 'क्षि'.mb_chars.length #=> 4
409
- # 'क्षि'.mb_chars.g_length #=> 3
410
- def g_length
411
- Unicode.g_unpack(@wrapped_string).length
412
- end
413
-
414
- # Replaces all ISO-8859-1 or CP1252 characters by their UTF-8 equivalent resulting in a valid UTF-8 string.
415
- #
416
- # Passing +true+ will forcibly tidy all bytes, assuming that the string's encoding is entirely CP1252 or ISO-8859-1.
417
- def tidy_bytes(force = false)
418
- chars(Unicode.tidy_bytes(@wrapped_string, force))
419
- end
420
-
421
- %w(lstrip rstrip strip reverse upcase downcase tidy_bytes capitalize).each do |method|
422
- define_method("#{method}!") do |*args|
423
- unless args.nil?
424
- @wrapped_string = send(method, *args).to_s
425
- else
426
- @wrapped_string = send(method).to_s
427
- end
428
- self
429
- end
430
- end
431
-
432
- protected
433
-
434
- def translate_offset(byte_offset) #:nodoc:
435
- return nil if byte_offset.nil?
436
- return 0 if @wrapped_string == ''
437
-
438
- if @wrapped_string.respond_to?(:force_encoding)
439
- @wrapped_string = @wrapped_string.dup.force_encoding(Encoding::ASCII_8BIT)
440
- end
441
-
442
- begin
443
- @wrapped_string[0...byte_offset].unpack('U*').length
444
- rescue ArgumentError => e
445
- byte_offset -= 1
446
- retry
447
- end
448
- end
449
-
450
- def justify(integer, way, padstr=' ') #:nodoc:
451
- raise ArgumentError, "zero width padding" if padstr.length == 0
452
- padsize = integer - size
453
- padsize = padsize > 0 ? padsize : 0
454
- case way
455
- when :right
456
- result = @wrapped_string.dup.insert(0, padding(padsize, padstr))
457
- when :left
458
- result = @wrapped_string.dup.insert(-1, padding(padsize, padstr))
459
- when :center
460
- lpad = padding((padsize / 2.0).floor, padstr)
461
- rpad = padding((padsize / 2.0).ceil, padstr)
462
- result = @wrapped_string.dup.insert(0, lpad).insert(-1, rpad)
463
- end
464
- chars(result)
465
- end
466
-
467
- def padding(padsize, padstr=' ') #:nodoc:
468
- if padsize != 0
469
- chars(padstr * ((padsize / Unicode.u_unpack(padstr).size) + 1)).slice(0, padsize)
470
- else
471
- ''
472
- end
473
- end
474
-
475
- def chars(string) #:nodoc:
476
- self.class.new(string)
477
- end
478
- end
479
- end
480
- end