idn-ruby 0.1.0

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.
@@ -0,0 +1,60 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/clean'
4
+ require 'rake/testtask'
5
+ require 'rake/rdoctask'
6
+ require 'rake/extensiontask'
7
+
8
+ CLEAN << FileList[ 'ext/Makefile', 'ext/*.so', 'ext/*.o' ]
9
+
10
+ begin
11
+ require 'jeweler'
12
+ rescue LoadError
13
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
14
+ end
15
+
16
+ Jeweler::Tasks.new do |gem|
17
+ gem.name = 'idn-ruby'
18
+ gem.summary = 'LibIDN Ruby Bindings.'
19
+ gem.description = %q{
20
+ Ruby Bindings for the GNU LibIDN library, an implementation of the
21
+ Stringprep, Punycode and IDNA specifications defined by the IETF
22
+ Internationalized Domain Names (IDN) working group.
23
+
24
+ Included are the most important parts of the Stringprep, Punycode
25
+ and IDNA APIs like performing Stringprep processings, encoding to
26
+ and decoding from Punycode strings and converting entire domain names
27
+ to and from the ACE encoded form.
28
+ }
29
+ gem.email = 'deepfryed@gmail.com'
30
+ gem.homepage = 'http://github.com/deepfryed/idn-ruby'
31
+ gem.authors = ['Erik Abele', 'Bharanee Rathna']
32
+ gem.files = FileList['CHANGES', 'LICENSE', 'NOTICE', 'Rakefile', 'README', 'ext/*.{c,h}']
33
+ gem.extensions = FileList[ 'ext/**/extconf.rb' ]
34
+ gem.test_files = FileList[ 'test/*.rb' ]
35
+ end
36
+
37
+ Jeweler::GemcutterTasks.new
38
+
39
+ Rake::ExtensionTask.new do |ext|
40
+ ext.name = 'idn'
41
+ ext.ext_dir = 'ext'
42
+ ext.lib_dir = 'ext'
43
+ end
44
+
45
+ Rake::RDocTask.new do |rdoc|
46
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
47
+ rdoc.rdoc_dir = 'rdoc'
48
+ rdoc.title = "idn-ruby #{version}"
49
+ rdoc.rdoc_files.include('README*')
50
+ rdoc.rdoc_files.include('lib/**/*.rb')
51
+ end
52
+
53
+ Rake::TestTask.new(:test) do |test|
54
+ test.libs << 'ext'
55
+ test.pattern = 'test/*.rb'
56
+ test.verbose = true
57
+ end
58
+
59
+ task :test => [ :compile, :check_dependencies ]
60
+ task :default => :test
@@ -0,0 +1,56 @@
1
+ # Makefile configuration for LibIDN Ruby Bindings.
2
+ #
3
+ # Copyright (c) 2005 Erik Abele. All rights reserved.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # Please see the file called LICENSE for further details.
8
+ #
9
+ # You may also obtain a copy of the License at
10
+ #
11
+ # * http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+ # This software is OSI Certified Open Source Software.
20
+ # OSI Certified is a certification mark of the Open Source Initiative.
21
+
22
+ require 'mkmf'
23
+
24
+ @libs = ['idn']
25
+ @headers = ['idna.h', 'punycode.h', 'stringprep.h']
26
+
27
+ INFO_NOTE = <<EOL
28
+ Please install the GNU IDN library or alternatively specify at least one
29
+ of the following options if the library can only be found in a non-standard
30
+ location:
31
+ --with-idn-dir=/path/to/non/standard/location
32
+ or
33
+ --with-idn-lib=/path/to/non/standard/location/lib
34
+ --with-idn-include=/path/to/non/standard/location/include
35
+ EOL
36
+
37
+ dir_config('idn')
38
+
39
+ @libs.each do |lib|
40
+ unless have_library(lib)
41
+ STDERR.puts "ERROR: could not find #{lib} library!\n" +
42
+ "\n#{INFO_NOTE}\n"
43
+ exit 1
44
+ end
45
+ end
46
+
47
+ @headers.each do |header|
48
+ unless have_header(header)
49
+ STDERR.puts "ERROR: could not find #{header} header file!\n" +
50
+ "\n#{INFO_NOTE}\n"
51
+ exit 1
52
+ end
53
+ end
54
+
55
+ $CFLAGS += ' -Wall' unless $CFLAGS.split.include? '-Wall'
56
+ create_makefile('idn')
@@ -0,0 +1,59 @@
1
+ /*
2
+ * Copyright (c) 2005 Erik Abele. All rights reserved.
3
+ * Portions Copyright (c) 2005 Yuki Mitsui. All rights reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * Please see the file called LICENSE for further details.
8
+ *
9
+ * You may also obtain a copy of the License at
10
+ *
11
+ * * http://www.apache.org/licenses/LICENSE-2.0
12
+ *
13
+ * Unless required by applicable law or agreed to in writing, software
14
+ * distributed under the License is distributed on an "AS IS" BASIS,
15
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ * See the License for the specific language governing permissions and
17
+ * limitations under the License.
18
+ *
19
+ * This software is OSI Certified Open Source Software.
20
+ * OSI Certified is a certification mark of the Open Source Initiative.
21
+ */
22
+
23
+ #include <ruby.h>
24
+ #include "idn.h"
25
+
26
+ /*
27
+ * Document-class: IDN
28
+ * The main module of LibIDN Ruby Bindings.
29
+ *
30
+ * === Example usage
31
+ *
32
+ * require 'idn'
33
+ * include IDN
34
+ *
35
+ * ...
36
+ */
37
+
38
+ VALUE mIDN;
39
+
40
+ /*
41
+ * Document-class: IDN::IDNError
42
+ * The superclass for all exceptions raised by the IDN extension.
43
+ */
44
+
45
+ VALUE eIDNError;
46
+
47
+ /*
48
+ * Module Initialization.
49
+ */
50
+
51
+ void Init_idn(void)
52
+ {
53
+ mIDN = rb_define_module("IDN");
54
+ eIDNError = rb_define_class_under(mIDN, "IDNError", rb_eStandardError);
55
+
56
+ init_idna();
57
+ init_punycode();
58
+ init_stringprep();
59
+ }
@@ -0,0 +1,59 @@
1
+ /*
2
+ * Copyright (c) 2005 Erik Abele. All rights reserved.
3
+ * Portions Copyright (c) 2005 Yuki Mitsui. All rights reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * Please see the file called LICENSE for further details.
8
+ *
9
+ * You may also obtain a copy of the License at
10
+ *
11
+ * * http://www.apache.org/licenses/LICENSE-2.0
12
+ *
13
+ * Unless required by applicable law or agreed to in writing, software
14
+ * distributed under the License is distributed on an "AS IS" BASIS,
15
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ * See the License for the specific language governing permissions and
17
+ * limitations under the License.
18
+ *
19
+ * This software is OSI Certified Open Source Software.
20
+ * OSI Certified is a certification mark of the Open Source Initiative.
21
+ */
22
+
23
+ #ifndef ___IDN_IDN_H_
24
+ #define ___IDN_IDN_H_
25
+
26
+ #include <ruby.h>
27
+ #include <ruby/encoding.h>
28
+
29
+ /*
30
+ * idn.c
31
+ */
32
+ extern VALUE mIDN;
33
+ extern VALUE eIDNError;
34
+
35
+ /*
36
+ * idna.c
37
+ */
38
+ extern VALUE mIdna;
39
+ extern VALUE eIdnaError;
40
+
41
+ void init_idna(void);
42
+
43
+ /*
44
+ * punycode.c
45
+ */
46
+ extern VALUE mPunycode;
47
+ extern VALUE ePunycodeError;
48
+
49
+ void init_punycode(void);
50
+
51
+ /*
52
+ * stringprep.c
53
+ */
54
+ extern VALUE mStringprep;
55
+ extern VALUE eStringprepError;
56
+
57
+ void init_stringprep(void);
58
+
59
+ #endif /* ___IDN_IDN_H_ */
@@ -0,0 +1,164 @@
1
+ /*
2
+ * Copyright (c) 2005 Erik Abele. All rights reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * Please see the file called LICENSE for further details.
7
+ *
8
+ * You may also obtain a copy of the License at
9
+ *
10
+ * * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ *
18
+ * This software is OSI Certified Open Source Software.
19
+ * OSI Certified is a certification mark of the Open Source Initiative.
20
+ */
21
+
22
+ #include <stdlib.h>
23
+ #include <ruby.h>
24
+ #include <idna.h>
25
+ #include "idn.h"
26
+
27
+ /*
28
+ * Document-class: IDN::Idna
29
+ * The Idna module of LibIDN Ruby Bindings.
30
+ *
31
+ * === Example usage
32
+ *
33
+ * require 'idn'
34
+ * include IDN
35
+ *
36
+ * puts 'ACE-Prefix: ' + Idna::ACE_PREFIX
37
+ *
38
+ * domain = Idna.toUnicode('xn--rksmrgs-5wao1o.josefsson.org',
39
+ * Idna::USE_STD3_ASCII_RULES | Idna::ALLOW_UNASSIGNED)
40
+ *
41
+ * === Constants
42
+ *
43
+ * <b>ACE_PREFIX</b>
44
+ * - The ACE prefix: 'xn--'.
45
+ *
46
+ * <b>ALLOW_UNASSIGNED</b>
47
+ * - Used as flag for toASCII/toUnicode.
48
+ *
49
+ * <b>USE_STD3_ASCII_RULES</b>
50
+ * - Used as flag for toASCII/toUnicode.
51
+ */
52
+
53
+ VALUE mIdna;
54
+
55
+ /*
56
+ * Document-class: IDN::Idna::IdnaError
57
+ * The base class for all exceptions raised by the IDN::Idna module.
58
+ */
59
+
60
+ VALUE eIdnaError;
61
+
62
+ /*
63
+ * call-seq:
64
+ * IDN::Idna.toASCII(string, flags=nil) => string
65
+ *
66
+ * Converts a domain name in UTF-8 format into an ASCII string. The domain
67
+ * name may contain several labels, separated by dots.
68
+ *
69
+ * Raises IDN::Idna::IdnaError on failure.
70
+ */
71
+
72
+ static VALUE toASCII(int argc, VALUE argv[], VALUE self)
73
+ {
74
+ int rc;
75
+ char *buf;
76
+ VALUE str, flags, retv;
77
+
78
+ rb_scan_args(argc, argv, "11", &str, &flags);
79
+ str = rb_check_convert_type(str, T_STRING, "String", "to_s");
80
+
81
+ if (flags != Qnil) {
82
+ Check_Type(flags, T_FIXNUM);
83
+ flags = FIX2INT(flags);
84
+ } else {
85
+ flags = 0x0000;
86
+ }
87
+
88
+ rc = idna_to_ascii_8z(RSTRING_PTR(str), &buf, flags);
89
+
90
+ if (rc != IDNA_SUCCESS) {
91
+ xfree(buf);
92
+ rb_raise(eIdnaError, "%s (%d)", idna_strerror(rc), rc);
93
+ return Qnil;
94
+ }
95
+
96
+ retv = rb_str_new2(buf);
97
+ xfree(buf);
98
+ return retv;
99
+ }
100
+
101
+ /*
102
+ * call-seq:
103
+ * IDN::Idna.toUnicode(string, flags=nil) => string
104
+ *
105
+ * Converts a possibly ACE encoded domain name in UTF-8 format into an
106
+ * UTF-8 string. The domain name may contain several labels, separated
107
+ * by dots.
108
+ *
109
+ * Raises IDN::Idna::IdnaError on failure.
110
+ */
111
+
112
+ static VALUE toUnicode(int argc, VALUE argv[], VALUE self)
113
+ {
114
+ int rc;
115
+ char *buf;
116
+ VALUE str, flags, retv;
117
+
118
+ rb_scan_args(argc, argv, "11", &str, &flags);
119
+ str = rb_check_convert_type(str, T_STRING, "String", "to_s");
120
+
121
+ if (flags != Qnil) {
122
+ Check_Type(flags, T_FIXNUM);
123
+ flags = FIX2INT(flags);
124
+ } else {
125
+ flags = 0x0000;
126
+ }
127
+
128
+ rc = idna_to_unicode_8z8z(RSTRING_PTR(str), &buf, flags);
129
+
130
+ if (rc != IDNA_SUCCESS) {
131
+ xfree(buf);
132
+ rb_raise(eIdnaError, "%s (%d)", idna_strerror(rc), rc);
133
+ return Qnil;
134
+ }
135
+
136
+ retv = rb_enc_str_new(buf, strlen(buf), rb_utf8_encoding());
137
+ xfree(buf);
138
+ return retv;
139
+ }
140
+
141
+ /*
142
+ * Module Initialization.
143
+ */
144
+
145
+ void init_idna(void)
146
+ {
147
+ #ifdef mIDN_RDOC_HACK
148
+ mIDN = rb_define_module("IDN");
149
+ eIDNError = rb_define_class_under(mIDN, "IDNError", rb_eStandardError);
150
+ #endif
151
+
152
+ mIdna = rb_define_module_under(mIDN, "Idna");
153
+ eIdnaError = rb_define_class_under(mIdna, "IdnaError", eIDNError);
154
+
155
+ rb_define_const(mIdna, "ACE_PREFIX",
156
+ rb_str_new2(IDNA_ACE_PREFIX));
157
+ rb_define_const(mIdna, "ALLOW_UNASSIGNED",
158
+ INT2FIX(IDNA_ALLOW_UNASSIGNED));
159
+ rb_define_const(mIdna, "USE_STD3_ASCII_RULES",
160
+ INT2FIX(IDNA_USE_STD3_ASCII_RULES));
161
+
162
+ rb_define_singleton_method(mIdna, "toASCII", toASCII, -1);
163
+ rb_define_singleton_method(mIdna, "toUnicode", toUnicode, -1);
164
+ }
@@ -0,0 +1,160 @@
1
+ /*
2
+ * Copyright (c) 2005 Erik Abele. All rights reserved.
3
+ * Portions Copyright (c) 2005 Yuki Mitsui. All rights reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * Please see the file called LICENSE for further details.
8
+ *
9
+ * You may also obtain a copy of the License at
10
+ *
11
+ * * http://www.apache.org/licenses/LICENSE-2.0
12
+ *
13
+ * Unless required by applicable law or agreed to in writing, software
14
+ * distributed under the License is distributed on an "AS IS" BASIS,
15
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ * See the License for the specific language governing permissions and
17
+ * limitations under the License.
18
+ *
19
+ * This software is OSI Certified Open Source Software.
20
+ * OSI Certified is a certification mark of the Open Source Initiative.
21
+ */
22
+
23
+ #include <stdlib.h>
24
+ #include <ruby.h>
25
+ #include <stringprep.h>
26
+ #include <punycode.h>
27
+ #include "idn.h"
28
+
29
+ /*
30
+ * Document-class: IDN::Punycode
31
+ * The Punycode module of LibIDN Ruby Bindings.
32
+ *
33
+ * === Example usage
34
+ *
35
+ * require 'idn'
36
+ * include IDN
37
+ *
38
+ * str = Punycode.decode('egbpdaj6bu4bxfgehfvwxn')
39
+ */
40
+
41
+ VALUE mPunycode;
42
+
43
+ /*
44
+ * Document-class: IDN::Punycode::PunycodeError
45
+ * The base class for all exceptions raised by the IDN::Punycode module.
46
+ */
47
+
48
+ VALUE ePunycodeError;
49
+
50
+ /*
51
+ * call-seq:
52
+ * IDN::Punycode.encode(string) => string
53
+ *
54
+ * Converts a string in UTF-8 format to Punycode.
55
+ *
56
+ * Raises IDN::Punycode::PunycodeError on failure.
57
+ */
58
+
59
+ static VALUE encode(VALUE self, VALUE str)
60
+ {
61
+ int rc;
62
+ punycode_uint *ustr;
63
+ size_t len;
64
+ size_t buflen = 0x100;
65
+ char *buf = NULL;
66
+ VALUE retv;
67
+
68
+ str = rb_check_convert_type(str, T_STRING, "String", "to_s");
69
+ ustr = stringprep_utf8_to_ucs4(RSTRING_PTR(str), RSTRING_LEN(str), &len);
70
+
71
+ while (1) {
72
+ buf = realloc(buf, buflen);
73
+
74
+ if (buf == NULL) {
75
+ xfree(ustr);
76
+ rb_raise(rb_eNoMemError, "cannot allocate memory (%d bytes)", (uint32_t)buflen);
77
+ return Qnil;
78
+ }
79
+
80
+ rc = punycode_encode(len, ustr, NULL, &buflen, buf);
81
+
82
+ if (rc == PUNYCODE_SUCCESS) {
83
+ break;
84
+ } else if (rc == PUNYCODE_BIG_OUTPUT) {
85
+ buflen += 0x100;
86
+ } else {
87
+ xfree(ustr);
88
+ xfree(buf);
89
+ rb_raise(ePunycodeError, "%s (%d)", punycode_strerror(rc), rc);
90
+ return Qnil;
91
+ }
92
+ }
93
+
94
+ retv = rb_str_new(buf, buflen);
95
+ xfree(ustr);
96
+ xfree(buf);
97
+ return retv;
98
+ }
99
+
100
+ /*
101
+ * call-seq:
102
+ * IDN::Punycode.decode(string) => string
103
+ *
104
+ * Converts Punycode to a string in UTF-8 format.
105
+ *
106
+ * Raises IDN::Punycode::PunycodeError on failure.
107
+ */
108
+
109
+ static VALUE decode(VALUE self, VALUE str)
110
+ {
111
+ int rc;
112
+ punycode_uint *ustr;
113
+ size_t len;
114
+ char *buf = NULL;
115
+ VALUE retv;
116
+
117
+ str = rb_check_convert_type(str, T_STRING, "String", "to_s");
118
+
119
+ len = RSTRING_LEN(str);
120
+ ustr = malloc(len * sizeof(punycode_uint));
121
+
122
+ if (ustr == NULL) {
123
+ rb_raise(rb_eNoMemError, "cannot allocate memory (%d bytes)", (uint32_t)len);
124
+ return Qnil;
125
+ }
126
+
127
+ rc = punycode_decode(RSTRING_LEN(str), RSTRING_PTR(str),
128
+ &len, ustr, NULL);
129
+
130
+ if (rc != PUNYCODE_SUCCESS) {
131
+ xfree(ustr);
132
+ rb_raise(ePunycodeError, "%s (%d)", punycode_strerror(rc), rc);
133
+ return Qnil;
134
+ }
135
+
136
+ buf = stringprep_ucs4_to_utf8(ustr, len, NULL, &len);
137
+ retv = rb_enc_str_new(buf, len, rb_utf8_encoding());
138
+ xfree(ustr);
139
+ xfree(buf);
140
+ return retv;
141
+ }
142
+
143
+ /*
144
+ * Module Initialization.
145
+ */
146
+
147
+ void init_punycode(void)
148
+ {
149
+ #ifdef mIDN_RDOC_HACK
150
+ mIDN = rb_define_module("IDN");
151
+ eIDNError = rb_define_class_under(mIDN, "IDNError", rb_eStandardError);
152
+ #endif
153
+
154
+ mPunycode = rb_define_module_under(mIDN, "Punycode");
155
+ ePunycodeError = rb_define_class_under(mPunycode, "PunycodeError",
156
+ eIDNError);
157
+
158
+ rb_define_singleton_method(mPunycode, "encode", encode, 1);
159
+ rb_define_singleton_method(mPunycode, "decode", decode, 1);
160
+ }