tox 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 1ab3125d380817a144ee66674764101ec8e86754
4
- data.tar.gz: 2b4f4c0e20c4bec09f30a15db7414926a9eff90e
2
+ SHA256:
3
+ metadata.gz: 9367ed9e38a09dccb4ff7e1f75ca32f92905923787c30b7024d4d34c178f6a0a
4
+ data.tar.gz: eefe7bec29169dd32706f5bea1a4f38898fa3f2a4b3de8e43e177c2f862420bd
5
5
  SHA512:
6
- metadata.gz: 560228cc65e59acace9c3e56b36582124ca7372719ecb7b68fadee22eaf7869a88abebb51e0eb459a94066609ddb1ec802a1cc60d96c9d72c319104bdb6c93f7
7
- data.tar.gz: 7d441fa2149a92729b072c7716ed3cec8a33968c92550c12caf715ee0b1a714efa5985c3ef348cf1e8869713726d31f82a079111f3bf4ade1d65ac5ec6c02d6d
6
+ metadata.gz: 7fc56ef3915fa04ed359e8acd1a48091477163c0886ef9098b3e1c421f927a68afb03c29d4b05def5c8be0702355d8f740d9646d7b3b86d1aef4e733f34f41ab
7
+ data.tar.gz: d5b7f0da8e46e010ebabd8108722368958b2e193d0dfeb3a594877b79589057760c769ddfbc035c8df0dabd00c36e9a19cfd7c5b81eac2dbabc19572e556948d
data/.gitignore CHANGED
@@ -7,6 +7,7 @@
7
7
  *.gem
8
8
  *.rbc
9
9
  /.config
10
+ /.rake_tasks~
10
11
  /coverage/
11
12
  /InstalledFiles
12
13
  /pkg/
@@ -42,3 +43,7 @@
42
43
 
43
44
  # Rake-compiled extension files:
44
45
  /lib/tox/tox.so
46
+
47
+ # Vendored dependencies:
48
+ /vendor/*
49
+ !/vendor/src/
@@ -1,6 +1,6 @@
1
1
  [submodule "vendor/libtoxcore"]
2
- path = vendor/libtoxcore
2
+ path = vendor/src/libtoxcore
3
3
  url = https://github.com/TokTok/c-toxcore.git
4
4
  [submodule "vendor/libsodium"]
5
- path = vendor/libsodium
5
+ path = vendor/src/libsodium
6
6
  url = https://github.com/jedisct1/libsodium.git
@@ -17,6 +17,7 @@ Lint/InheritException:
17
17
 
18
18
  Metrics/BlockLength:
19
19
  Exclude:
20
+ - 'Rakefile'
20
21
  - '**/*.gemspec'
21
22
  - 'spec/**/*'
22
23
 
@@ -29,6 +30,11 @@ Style/DoubleNegation:
29
30
  Style/GlobalVars:
30
31
  Exclude:
31
32
  - 'ext/**/*'
33
+ - 'spec/network_helper.rb'
34
+
35
+ Style/PredicateName:
36
+ Exclude:
37
+ - 'ext/tox/extconf.rb'
32
38
 
33
39
  Style/TrailingCommaInArguments:
34
40
  EnforcedStyleForMultiline: comma
@@ -3,17 +3,12 @@ language: ruby
3
3
  rvm:
4
4
  - 2.3
5
5
  - 2.4
6
+ - 2.5
7
+ - 2.6
6
8
 
7
9
  before_install:
8
10
  - sudo apt-get update
9
- - sudo apt-get install -y build-essential libtool autotools-dev automake checkinstall check git yasm
10
-
11
- - sudo ./bin/build/libsodium
12
- - sudo ./bin/build/libtoxcore
13
-
14
- - sudo mkdir -p '/etc/ld.so.conf.d/'
15
- - echo '/usr/local/lib/' | sudo tee -a '/etc/ld.so.conf.d/locallib.conf'
16
- - sudo ldconfig
11
+ - sudo apt-get install -y yasm libconfig-dev
17
12
 
18
13
  before_script:
19
- - rake compile
14
+ - rake ext
data/README.md CHANGED
@@ -4,8 +4,17 @@
4
4
  [![Gem Version](https://badge.fury.io/rb/tox.svg)](http://badge.fury.io/rb/tox)
5
5
  [![Build Status](https://travis-ci.org/toxon/tox.rb.svg)](https://travis-ci.org/toxon/tox.rb)
6
6
  [![Coverage Status](https://coveralls.io/repos/github/toxon/tox.rb/badge.svg)](https://coveralls.io/github/toxon/tox.rb)
7
+ [![Inline docs](http://inch-ci.org/github/toxon/tox.rb.svg?branch=master)](http://inch-ci.org/github/toxon/tox.rb)
7
8
 
8
9
  Ruby interface for [libtoxcore](https://github.com/TokTok/c-toxcore).
9
10
  It can be used to create [Tox chat](https://tox.chat) client or bot.
10
11
  The interface is object-oriented instead of C-style (raises exceptions
11
12
  instead of returning error codes, uses classes to represent primitives, etc.)
13
+
14
+
15
+
16
+ Table of contents
17
+ -----------------
18
+
19
+ * [Overview](#tox)
20
+ * [Table of contents](#table-of-contents)
data/Rakefile CHANGED
@@ -2,17 +2,31 @@
2
2
 
3
3
  require 'bundler/gem_tasks'
4
4
 
5
- GEMSPEC = Gem::Specification.load 'lita-tox.gemspec'
5
+ VENDOR_PREFIX = File.expand_path('vendor', __dir__).freeze
6
6
 
7
- task default: %i[compile spec lint]
7
+ VENDOR_PKG_CONFIG_PATH = File.join(VENDOR_PREFIX, 'lib', 'pkgconfig').freeze
8
8
 
9
+ desc 'Run all checks (test, lint...)'
10
+ task default: %i[test lint]
11
+
12
+ desc 'Run all tests (specs, benchmarks...)'
13
+ task test: :spec
14
+
15
+ desc 'Run all code analysis tools (RuboCop...)'
9
16
  task lint: :rubocop
10
17
 
18
+ desc 'Fix code style (rubocop --auto-correct)'
11
19
  task fix: 'rubocop:auto_correct'
12
20
 
21
+ desc 'Compile all extensions (and their dependencies)'
22
+ task ext: %i[ext:tox]
23
+
24
+ require 'pry'
25
+
13
26
  begin
14
27
  require 'rspec/core/rake_task'
15
28
  RSpec::Core::RakeTask.new
29
+ Rake::Task[:spec].enhance %i[ext]
16
30
  rescue LoadError
17
31
  nil
18
32
  end
@@ -34,9 +48,104 @@ end
34
48
  begin
35
49
  require 'rake/extensiontask'
36
50
 
37
- Rake::ExtensionTask.new 'tox', GEMSPEC do |ext|
51
+ Rake::ExtensionTask.new 'tox' do |ext|
38
52
  ext.lib_dir = 'lib/tox'
53
+ ext.config_options << "--with-opt-dir=#{VENDOR_PREFIX.shellescape}"
39
54
  end
55
+
56
+ Rake::Task[:compile].clear_comments
57
+ Rake::Task['compile:tox'].clear_comments
40
58
  rescue LoadError
41
59
  nil
42
60
  end
61
+
62
+ namespace :ext do
63
+ desc 'Compile "tox" extension (and it\'s dependencies)'
64
+ task tox: %i[
65
+ vendor/lib/pkgconfig/libtoxcore.pc
66
+ compile:tox
67
+ ]
68
+ end
69
+
70
+ namespace :vendor do
71
+ desc 'Install vendored dependencies into "./vendor/{bin,include,lib}/"'
72
+ task install: %i[install:libsodium install:libtoxcore]
73
+
74
+ desc 'Uninstall vendored dependencies from "./vendor/{bin,include,lib}/"'
75
+ task :uninstall do
76
+ rm_rf File.join VENDOR_PREFIX, 'bin'
77
+ rm_rf File.join VENDOR_PREFIX, 'include'
78
+ rm_rf File.join VENDOR_PREFIX, 'lib'
79
+ end
80
+
81
+ desc 'Delete compiled vendored dependencies from "./vendor/"'
82
+ task clean: %i[uninstall clean:libsodium clean:libtoxcore]
83
+
84
+ namespace :install do
85
+ task libsodium: 'vendor/lib/pkgconfig/libsodium.pc'
86
+ task libtoxcore: 'vendor/lib/pkgconfig/libtoxcore.pc'
87
+ end
88
+
89
+ namespace :clean do
90
+ task :libsodium do
91
+ chdir 'vendor/src/libsodium' do
92
+ sh 'make clean'
93
+ end
94
+ end
95
+
96
+ task :libtoxcore do
97
+ chdir 'vendor/src/libtoxcore' do
98
+ sh 'make clean'
99
+ end
100
+ end
101
+ end
102
+ end
103
+
104
+ file 'vendor/lib/pkgconfig/libsodium.pc': 'vendor/src/libsodium/Makefile' do
105
+ chdir 'vendor/src/libsodium' do
106
+ sh 'make install'
107
+ end
108
+ end
109
+
110
+ file 'vendor/lib/pkgconfig/libtoxcore.pc': 'vendor/src/libtoxcore/Makefile' do
111
+ chdir 'vendor/src/libtoxcore' do
112
+ sh 'make install'
113
+ end
114
+ end
115
+
116
+ file 'vendor/src/libsodium/Makefile': 'vendor/src/libsodium/configure' do |t|
117
+ chdir File.dirname t.name do
118
+ sh(
119
+ { 'PKG_CONFIG_PATH' => VENDOR_PKG_CONFIG_PATH },
120
+ './configure',
121
+ '--prefix',
122
+ VENDOR_PREFIX,
123
+ )
124
+ end
125
+ end
126
+
127
+ file 'vendor/src/libtoxcore/Makefile':
128
+ %i[vendor/src/libtoxcore/configure
129
+ vendor/lib/pkgconfig/libsodium.pc] do |t|
130
+ chdir File.dirname t.name do
131
+ sh(
132
+ { 'PKG_CONFIG_PATH' => VENDOR_PKG_CONFIG_PATH },
133
+ './configure',
134
+ '--prefix',
135
+ VENDOR_PREFIX,
136
+ '--enable-daemon',
137
+ )
138
+ end
139
+ end
140
+
141
+ file 'vendor/src/libsodium/configure' do |t|
142
+ chdir File.dirname t.name do
143
+ sh './autogen.sh'
144
+ end
145
+ end
146
+
147
+ file 'vendor/src/libtoxcore/configure' do |t|
148
+ chdir File.dirname t.name do
149
+ sh './autogen.sh'
150
+ end
151
+ end
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # This wrapper ensures than child process is terminated/killed
5
+ # if parent process does not exist anymore.
6
+
7
+ require 'English'
8
+
9
+ TRAPS = %i[HUP INT QUIT TRAP ABRT TERM USR1 USR2].freeze
10
+
11
+ pid = spawn(*ARGV, in: :in, out: :out, err: :err)
12
+
13
+ signal = lambda do |signo|
14
+ begin
15
+ Process.kill signo, pid
16
+ rescue
17
+ nil
18
+ end
19
+ end
20
+
21
+ TRAPS.each do |signame|
22
+ trap signame, &signal
23
+ end
24
+
25
+ Thread.start pid do |pid| # rubocop:disable Lint/ShadowingOuterLocalVariable
26
+ loop do
27
+ begin
28
+ sleep 1
29
+ Process.kill 0, Process.ppid
30
+ rescue
31
+ begin
32
+ Process.kill :SIGTERM, pid
33
+ sleep 2
34
+ Process.kill :SIGKILL, pid
35
+ rescue
36
+ nil
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ Process.wait pid
43
+
44
+ exit $CHILD_STATUS.exitstatus || 1
@@ -31,7 +31,7 @@ tox_client.status = Tox::UserStatus::NONE
31
31
  tox_client.status_message = STATUS_MESSAGE
32
32
 
33
33
  puts
34
- puts "Address: #{tox_client.address.to_hex}"
34
+ puts "Address: #{tox_client.address}"
35
35
  puts "Name: #{tox_client.name}"
36
36
  puts "Status: #{tox_client.status}"
37
37
  puts "Status message: #{tox_client.status_message}"
@@ -40,9 +40,10 @@ puts
40
40
  puts 'Connecting to the nodes from official list...'
41
41
  tox_client.bootstrap_official
42
42
 
43
- tox_client.on_friend_request do |public_key|
44
- puts "Got friend request with public key #{public_key.to_hex}. " \
45
- 'Adding to contacts...'
43
+ tox_client.on_friend_request do |public_key, text|
44
+ puts 'Friend request. Adding to contacts...'
45
+ puts "Public key: #{public_key}"
46
+ puts "Text: #{text.inspect}"
46
47
  puts
47
48
 
48
49
  tox_client.friend_add_norequest public_key
@@ -52,10 +53,10 @@ tox_client.on_friend_message do |friend, text|
52
53
  puts 'Message from friend'
53
54
  puts "Number: #{friend.number}"
54
55
  puts "Name: #{friend.name}"
55
- puts "Public key: #{friend.public_key.to_hex}"
56
+ puts "Public key: #{friend.public_key}"
56
57
  puts "Status: #{friend.status}"
57
58
  puts "Status message: #{friend.status_message}"
58
- puts text.inspect
59
+ puts "Text: #{text.inspect}"
59
60
  puts
60
61
 
61
62
  friend.send_message text
@@ -66,7 +67,10 @@ puts 'Running. Send me friend request, I\'ll accept it immediately. ' \
66
67
 
67
68
  begin
68
69
  puts
69
- tox_client.run
70
+ loop do
71
+ sleep tox_client.iteration_interval
72
+ tox_client.iterate
73
+ end
70
74
  puts
71
75
  rescue SignalException
72
76
  puts
@@ -1,21 +1,3 @@
1
- /*
2
- * tox.rb - Ruby interface for libtoxcore
3
- * Copyright (C) 2015-2017 Braiden Vasco
4
- *
5
- * This program is free software: you can redistribute it and/or modify
6
- * it under the terms of the GNU General Public License as published by
7
- * the Free Software Foundation, either version 3 of the License, or
8
- * (at your option) any later version.
9
- *
10
- * This program is distributed in the hope that it will be useful,
11
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
- * GNU General Public License for more details.
14
- *
15
- * You should have received a copy of the GNU General Public License
16
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
17
- */
18
-
19
1
  #include "tox.h"
20
2
 
21
3
  #include <time.h>
@@ -26,29 +8,38 @@ static void mTox_cClient_free(mTox_cClient_CDATA *free_cdata);
26
8
 
27
9
  // Public methods
28
10
 
11
+ static VALUE mTox_cClient_iteration_interval(VALUE self);
12
+ static VALUE mTox_cClient_iterate(VALUE self);
13
+
14
+ static VALUE mTox_cClient_connection_status(VALUE self);
29
15
  static VALUE mTox_cClient_public_key(VALUE self);
30
16
  static VALUE mTox_cClient_address(VALUE self);
17
+ static VALUE mTox_cClient_nospam(VALUE self);
18
+ static VALUE mTox_cClient_nospam_ASSIGN(VALUE self, VALUE nospam);
31
19
  static VALUE mTox_cClient_savedata(VALUE self);
20
+ static VALUE mTox_cClient_udp_port(VALUE self);
21
+ static VALUE mTox_cClient_tcp_port(VALUE self);
32
22
 
33
- static VALUE mTox_cClient_bootstrap(VALUE self, VALUE node);
23
+ static VALUE mTox_cClient_bootstrap(VALUE self, VALUE address, VALUE port, VALUE public_key);
24
+ static VALUE mTox_cClient_add_tcp_relay(VALUE self, VALUE address, VALUE port, VALUE public_key);
34
25
 
35
26
  static VALUE mTox_cClient_name(VALUE self);
36
- static VALUE mTox_cClient_name_EQUALS(VALUE self, VALUE name);
27
+ static VALUE mTox_cClient_name_ASSIGN(VALUE self, VALUE name);
37
28
 
38
29
  static VALUE mTox_cClient_status(VALUE self);
39
- static VALUE mTox_cClient_status_EQUALS(VALUE self, VALUE status);
30
+ static VALUE mTox_cClient_status_ASSIGN(VALUE self, VALUE status);
40
31
 
41
32
  static VALUE mTox_cClient_status_message(VALUE self);
42
- static VALUE mTox_cClient_status_message_EQUALS(VALUE self, VALUE status_message);
33
+ static VALUE mTox_cClient_status_message_ASSIGN(VALUE self, VALUE status_message);
43
34
 
44
35
  static VALUE mTox_cClient_friend_numbers(VALUE self);
45
36
 
46
37
  static VALUE mTox_cClient_friend_add_norequest(VALUE self, VALUE public_key);
38
+ static VALUE mTox_cClient_friend_add(VALUE self, VALUE address, VALUE text);
47
39
 
48
40
  // Private methods
49
41
 
50
42
  static VALUE mTox_cClient_initialize_with(VALUE self, VALUE options);
51
- static VALUE mTox_cClient_run_loop(VALUE self);
52
43
 
53
44
  // Callbacks
54
45
 
@@ -103,29 +94,38 @@ void mTox_cClient_INIT()
103
94
 
104
95
  // Public methods
105
96
 
106
- rb_define_method(mTox_cClient, "public_key", mTox_cClient_public_key, 0);
107
- rb_define_method(mTox_cClient, "address", mTox_cClient_address, 0);
108
- rb_define_method(mTox_cClient, "savedata", mTox_cClient_savedata, 0);
97
+ rb_define_method(mTox_cClient, "iteration_interval", mTox_cClient_iteration_interval, 0);
98
+ rb_define_method(mTox_cClient, "iterate", mTox_cClient_iterate, 0);
99
+
100
+ rb_define_method(mTox_cClient, "connection_status", mTox_cClient_connection_status, 0);
101
+ rb_define_method(mTox_cClient, "public_key", mTox_cClient_public_key, 0);
102
+ rb_define_method(mTox_cClient, "address", mTox_cClient_address, 0);
103
+ rb_define_method(mTox_cClient, "nospam", mTox_cClient_nospam, 0);
104
+ rb_define_method(mTox_cClient, "nospam=", mTox_cClient_nospam_ASSIGN, 1);
105
+ rb_define_method(mTox_cClient, "savedata", mTox_cClient_savedata, 0);
106
+ rb_define_method(mTox_cClient, "udp_port", mTox_cClient_udp_port, 0);
107
+ rb_define_method(mTox_cClient, "tcp_port", mTox_cClient_tcp_port, 0);
109
108
 
110
- rb_define_method(mTox_cClient, "bootstrap", mTox_cClient_bootstrap, 1);
109
+ rb_define_method(mTox_cClient, "bootstrap", mTox_cClient_bootstrap, 3);
110
+ rb_define_method(mTox_cClient, "add_tcp_relay", mTox_cClient_add_tcp_relay, 3);
111
111
 
112
112
  rb_define_method(mTox_cClient, "name", mTox_cClient_name, 0);
113
- rb_define_method(mTox_cClient, "name=", mTox_cClient_name_EQUALS, 1);
113
+ rb_define_method(mTox_cClient, "name=", mTox_cClient_name_ASSIGN, 1);
114
114
 
115
115
  rb_define_method(mTox_cClient, "status", mTox_cClient_status, 0);
116
- rb_define_method(mTox_cClient, "status=", mTox_cClient_status_EQUALS, 1);
116
+ rb_define_method(mTox_cClient, "status=", mTox_cClient_status_ASSIGN, 1);
117
117
 
118
118
  rb_define_method(mTox_cClient, "status_message", mTox_cClient_status_message, 0);
119
- rb_define_method(mTox_cClient, "status_message=", mTox_cClient_status_message_EQUALS, 1);
119
+ rb_define_method(mTox_cClient, "status_message=", mTox_cClient_status_message_ASSIGN, 1);
120
120
 
121
121
  rb_define_method(mTox_cClient, "friend_numbers", mTox_cClient_friend_numbers, 0);
122
122
 
123
123
  rb_define_method(mTox_cClient, "friend_add_norequest", mTox_cClient_friend_add_norequest, 1);
124
+ rb_define_method(mTox_cClient, "friend_add", mTox_cClient_friend_add, 2);
124
125
 
125
126
  // Private methods
126
127
 
127
128
  rb_define_private_method(mTox_cClient, "initialize_with", mTox_cClient_initialize_with, 1);
128
- rb_define_private_method(mTox_cClient, "run_loop", mTox_cClient_run_loop, 0);
129
129
  }
130
130
 
131
131
  /*************************************************************
@@ -154,84 +154,257 @@ void mTox_cClient_free(mTox_cClient_CDATA *const free_cdata)
154
154
  * Public methods
155
155
  *************************************************************/
156
156
 
157
+ // Tox::Client#iteration_interval
158
+ VALUE mTox_cClient_iteration_interval(const VALUE self)
159
+ {
160
+ CDATA(self, mTox_cClient_CDATA, self_cdata);
161
+
162
+ uint32_t iteration_interval_msec_data =
163
+ tox_iteration_interval(self_cdata->tox);
164
+
165
+ const double iteration_interval_sec_data =
166
+ ((double)iteration_interval_msec_data) * 0.001;
167
+
168
+ const VALUE iteration_interval_sec = DBL2NUM(iteration_interval_sec_data);
169
+
170
+ return iteration_interval_sec;
171
+ }
172
+
173
+ // Tox::Client#iterate
174
+ VALUE mTox_cClient_iterate(const VALUE self)
175
+ {
176
+ CDATA(self, mTox_cClient_CDATA, self_cdata);
177
+
178
+ tox_iterate(self_cdata->tox, self);
179
+
180
+ return Qnil;
181
+ }
182
+
183
+ // Tox::Client#connection_status
184
+ VALUE mTox_cClient_connection_status(const VALUE self)
185
+ {
186
+ CDATA(self, mTox_cClient_CDATA, self_cdata);
187
+
188
+ TOX_CONNECTION connection_status_data =
189
+ tox_self_get_connection_status(self_cdata->tox);
190
+
191
+ const VALUE connection_status =
192
+ mTox_mConnectionStatus_FROM_DATA(connection_status_data);
193
+
194
+ return connection_status;
195
+ }
196
+
157
197
  // Tox::Client#public_key
158
198
  VALUE mTox_cClient_public_key(const VALUE self)
159
199
  {
160
- mTox_cClient_CDATA *self_cdata;
200
+ CDATA(self, mTox_cClient_CDATA, self_cdata);
161
201
 
162
- Data_Get_Struct(self, mTox_cClient_CDATA, self_cdata);
202
+ char public_key_data[TOX_PUBLIC_KEY_SIZE];
163
203
 
164
- char public_key[TOX_PUBLIC_KEY_SIZE];
204
+ tox_self_get_public_key(self_cdata->tox, public_key_data);
165
205
 
166
- tox_self_get_public_key(self_cdata->tox, (uint8_t*)public_key);
206
+ const VALUE public_key_value =
207
+ rb_str_new(public_key_data, TOX_PUBLIC_KEY_SIZE);
167
208
 
168
- return rb_funcall(
169
- mTox_cPublicKey,
170
- rb_intern("new"),
171
- 1,
172
- rb_str_new(public_key, TOX_PUBLIC_KEY_SIZE)
173
- );
209
+ const VALUE public_key = rb_funcall(mTox_cPublicKey, rb_intern("new"), 1,
210
+ public_key_value);
211
+
212
+ return public_key;
174
213
  }
175
214
 
176
215
  // Tox::Client#address
177
216
  VALUE mTox_cClient_address(const VALUE self)
178
217
  {
179
- mTox_cClient_CDATA *self_cdata;
218
+ CDATA(self, mTox_cClient_CDATA, self_cdata);
219
+
220
+ char address_data[TOX_ADDRESS_SIZE];
221
+
222
+ tox_self_get_address(self_cdata->tox, address_data);
223
+
224
+ const VALUE address_value = rb_str_new(address_data, TOX_ADDRESS_SIZE);
225
+
226
+ const VALUE address = rb_funcall(mTox_cAddress, rb_intern("new"), 1,
227
+ address_value);
228
+
229
+ return address;
230
+ }
231
+
232
+ // Tox::Client#nospam
233
+ VALUE mTox_cClient_nospam(const VALUE self)
234
+ {
235
+ CDATA(self, mTox_cClient_CDATA, self_cdata);
236
+
237
+ uint32_t nospam_data = tox_self_get_nospam(self_cdata->tox);
238
+
239
+ const VALUE nospam_as_integer = LONG2FIX(nospam_data);
240
+
241
+ const VALUE nospam = rb_funcall(mTox_cNospam, rb_intern("new"), 1,
242
+ nospam_as_integer);
243
+
244
+ return nospam;
245
+ }
180
246
 
181
- Data_Get_Struct(self, mTox_cClient_CDATA, self_cdata);
247
+ // Tox::Client#nospam
248
+ VALUE mTox_cClient_nospam_ASSIGN(const VALUE self, const VALUE nospam)
249
+ {
250
+ if (!rb_funcall(nospam, rb_intern("is_a?"), 1, mTox_cNospam)) {
251
+ RAISE_TYPECHECK("Tox::Client#nospam=", "nospam", "Tox::Nospam");
252
+ }
182
253
 
183
- char address[TOX_ADDRESS_SIZE];
254
+ CDATA(self, mTox_cClient_CDATA, self_cdata);
184
255
 
185
- tox_self_get_address(self_cdata->tox, (uint8_t*)address);
256
+ const VALUE nospam_as_integer = rb_funcall(nospam, rb_intern("to_i"), 0);
186
257
 
187
- return rb_funcall(
188
- mTox_cAddress,
189
- rb_intern("new"),
190
- 1,
191
- rb_str_new(address, TOX_ADDRESS_SIZE)
258
+ tox_self_set_nospam(
259
+ self_cdata->tox,
260
+ FIX2LONG(nospam_as_integer)
192
261
  );
262
+
263
+ return Qnil;
193
264
  }
194
265
 
195
266
  // Tox::Client#savedata
196
267
  VALUE mTox_cClient_savedata(const VALUE self)
197
268
  {
198
- mTox_cClient_CDATA *self_cdata;
269
+ CDATA(self, mTox_cClient_CDATA, self_cdata);
270
+
271
+ size_t data_size = tox_get_savedata_size(self_cdata->tox);
272
+ char *data = ALLOC_N(char, data_size);
273
+
274
+ tox_get_savedata(self_cdata->tox, data);
275
+
276
+ const VALUE savedata = rb_str_new(data, data_size);
277
+
278
+ return savedata;
279
+ }
280
+
281
+ // Tox::Client#udp_port
282
+ VALUE mTox_cClient_udp_port(const VALUE self)
283
+ {
284
+ CDATA(self, mTox_cClient_CDATA, self_cdata);
285
+
286
+ TOX_ERR_GET_PORT error;
287
+
288
+ const uint16_t udp_port_data = tox_self_get_udp_port(self_cdata->tox, &error);
289
+
290
+ switch (error) {
291
+ case TOX_ERR_GET_PORT_OK:
292
+ break;
293
+ case TOX_ERR_GET_PORT_NOT_BOUND:
294
+ return Qnil;
295
+ default:
296
+ return Qnil;
297
+ }
298
+
299
+ const VALUE udp_port = LONG2FIX(udp_port_data);
300
+
301
+ return udp_port;
302
+ }
303
+
304
+ // Tox::Client#tcp_port
305
+ VALUE mTox_cClient_tcp_port(const VALUE self)
306
+ {
307
+ CDATA(self, mTox_cClient_CDATA, self_cdata);
199
308
 
200
- size_t data_size;
201
- char *data;
309
+ TOX_ERR_GET_PORT error;
202
310
 
203
- Data_Get_Struct(self, mTox_cClient_CDATA, self_cdata);
311
+ const uint16_t tcp_port_data = tox_self_get_tcp_port(self_cdata->tox, &error);
204
312
 
205
- data_size = tox_get_savedata_size(self_cdata->tox);
206
- data = ALLOC_N(char, data_size);
313
+ switch (error) {
314
+ case TOX_ERR_GET_PORT_OK:
315
+ break;
316
+ case TOX_ERR_GET_PORT_NOT_BOUND:
317
+ return Qnil;
318
+ default:
319
+ return Qnil;
320
+ }
207
321
 
208
- tox_get_savedata(self_cdata->tox, (uint8_t*)data);
322
+ const VALUE tcp_port = LONG2FIX(tcp_port_data);
209
323
 
210
- return rb_str_new(data, data_size);
324
+ return tcp_port;
211
325
  }
212
326
 
213
327
  // Tox::Client#bootstrap
214
- VALUE mTox_cClient_bootstrap(const VALUE self, const VALUE node)
328
+ VALUE mTox_cClient_bootstrap(const VALUE self, const VALUE address, const VALUE port, const VALUE public_key)
329
+ {
330
+ Check_Type(address, T_STRING);
331
+
332
+ if (!rb_funcall(public_key, rb_intern("is_a?"), 1, mTox_cPublicKey)) {
333
+ RAISE_TYPECHECK("Tox::Client#bootstrap", "public_key", "Tox::PublicKey");
334
+ }
335
+
336
+ StringValueCStr(address);
337
+
338
+ CDATA(self, mTox_cClient_CDATA, self_cdata);
339
+
340
+ const VALUE public_key_value = rb_funcall(public_key, rb_intern("value"), 0);
341
+
342
+ const char *address_data = RSTRING_PTR(address);
343
+ const uint16_t port_data = NUM2USHORT(port);
344
+ const char *public_key_data = RSTRING_PTR(public_key_value);
345
+
346
+ TOX_ERR_BOOTSTRAP error;
347
+
348
+ const bool result = tox_bootstrap(
349
+ self_cdata->tox,
350
+ address_data,
351
+ port_data,
352
+ public_key_data,
353
+ &error
354
+ );
355
+
356
+ switch (error) {
357
+ case TOX_ERR_BOOTSTRAP_OK:
358
+ break;
359
+ case TOX_ERR_BOOTSTRAP_NULL:
360
+ return Qfalse;
361
+ case TOX_ERR_BOOTSTRAP_BAD_HOST:
362
+ return Qfalse;
363
+ case TOX_ERR_BOOTSTRAP_BAD_PORT:
364
+ return Qfalse;
365
+ default:
366
+ return Qfalse;
367
+ }
368
+
369
+ if (!result) {
370
+ return Qfalse;
371
+ }
372
+
373
+ return Qtrue;
374
+ }
375
+
376
+ // Tox::Client#add_tcp_relay
377
+ VALUE mTox_cClient_add_tcp_relay(const VALUE self, const VALUE address, const VALUE port, const VALUE public_key)
215
378
  {
216
- if (!rb_funcall(node, rb_intern("is_a?"), 1, mTox_cNode)) {
217
- rb_raise(rb_eTypeError, "expected argument 1 to be a Tox::Node");
379
+ Check_Type(address, T_STRING);
380
+
381
+ if (!rb_funcall(public_key, rb_intern("is_a?"), 1, mTox_cPublicKey)) {
382
+ RAISE_TYPECHECK("Tox::Client#bootstrap", "public_key", "Tox::PublicKey");
218
383
  }
219
384
 
220
- mTox_cClient_CDATA *self_cdata;
385
+ StringValueCStr(address);
221
386
 
222
- Data_Get_Struct(self, mTox_cClient_CDATA, self_cdata);
387
+ CDATA(self, mTox_cClient_CDATA, self_cdata);
388
+
389
+ const VALUE public_key_value = rb_funcall(public_key, rb_intern("value"), 0);
390
+
391
+ const char *address_data = RSTRING_PTR(address);
392
+ const uint16_t port_data = NUM2USHORT(port);
393
+ const char *public_key_data = RSTRING_PTR(public_key_value);
223
394
 
224
395
  TOX_ERR_BOOTSTRAP error;
225
396
 
226
- tox_bootstrap(self_cdata->tox,
227
- RSTRING_PTR(rb_funcall(node, rb_intern("resolv_ipv4"), 0)),
228
- NUM2INT(rb_funcall(node, rb_intern("port"), 0)),
229
- RSTRING_PTR(rb_funcall(node, rb_intern("public_key"), 0)),
230
- &error);
397
+ const bool result = tox_add_tcp_relay(
398
+ self_cdata->tox,
399
+ address_data,
400
+ port_data,
401
+ public_key_data,
402
+ &error
403
+ );
231
404
 
232
405
  switch (error) {
233
406
  case TOX_ERR_BOOTSTRAP_OK:
234
- return Qtrue;
407
+ break;
235
408
  case TOX_ERR_BOOTSTRAP_NULL:
236
409
  return Qfalse;
237
410
  case TOX_ERR_BOOTSTRAP_BAD_HOST:
@@ -241,40 +414,44 @@ VALUE mTox_cClient_bootstrap(const VALUE self, const VALUE node)
241
414
  default:
242
415
  return Qfalse;
243
416
  }
417
+
418
+ if (!result) {
419
+ return Qfalse;
420
+ }
421
+
422
+ return Qtrue;
244
423
  }
245
424
 
246
425
  // Tox::Client#name
247
426
  VALUE mTox_cClient_name(const VALUE self)
248
427
  {
249
- mTox_cClient_CDATA *self_cdata;
250
-
251
- Data_Get_Struct(self, mTox_cClient_CDATA, self_cdata);
428
+ CDATA(self, mTox_cClient_CDATA, self_cdata);
252
429
 
253
- const size_t name_size = tox_self_get_name_size(self_cdata->tox);
430
+ const size_t name_size_data = tox_self_get_name_size(self_cdata->tox);
254
431
 
255
- char name[name_size];
432
+ char name_data[name_size_data];
256
433
 
257
- if (name_size > 0) {
258
- tox_self_get_name(self_cdata->tox, (uint8_t*)name);
434
+ if (name_size_data > 0) {
435
+ tox_self_get_name(self_cdata->tox, name_data);
259
436
  }
260
437
 
261
- return rb_str_new(name, name_size);
438
+ const VALUE name = rb_str_new(name_data, name_size_data);
439
+
440
+ return name;
262
441
  }
263
442
 
264
443
  // Tox::Client#name=
265
- VALUE mTox_cClient_name_EQUALS(const VALUE self, const VALUE name)
444
+ VALUE mTox_cClient_name_ASSIGN(const VALUE self, const VALUE name)
266
445
  {
267
446
  Check_Type(name, T_STRING);
268
447
 
269
- mTox_cClient_CDATA *self_cdata;
270
-
271
- Data_Get_Struct(self, mTox_cClient_CDATA, self_cdata);
448
+ CDATA(self, mTox_cClient_CDATA, self_cdata);
272
449
 
273
450
  TOX_ERR_SET_INFO error;
274
451
 
275
452
  const bool result = tox_self_set_name(
276
453
  self_cdata->tox,
277
- (uint8_t**)RSTRING_PTR(name),
454
+ RSTRING_PTR(name),
278
455
  RSTRING_LEN(name),
279
456
  &error
280
457
  );
@@ -283,15 +460,23 @@ VALUE mTox_cClient_name_EQUALS(const VALUE self, const VALUE name)
283
460
  case TOX_ERR_SET_INFO_OK:
284
461
  break;
285
462
  case TOX_ERR_SET_INFO_NULL:
286
- rb_raise(mTox_eNullError, "tox_self_set_name() failed with TOX_ERR_SET_INFO_NULL");
463
+ RAISE_FUNC_ERROR(
464
+ "tox_self_set_name",
465
+ mTox_eNullError,
466
+ "TOX_ERR_SET_INFO_NULL"
467
+ );
287
468
  case TOX_ERR_SET_INFO_TOO_LONG:
288
- rb_raise(rb_eRuntimeError, "tox_self_set_name() failed with TOX_ERR_SET_INFO_TOO_LONG");
469
+ RAISE_FUNC_ERROR(
470
+ "tox_self_set_name",
471
+ rb_eRuntimeError,
472
+ "TOX_ERR_SET_INFO_TOO_LONG"
473
+ );
289
474
  default:
290
- rb_raise(mTox_eUnknownError, "tox_self_set_name() failed");
475
+ RAISE_FUNC_ERROR_DEFAULT("tox_self_set_name");
291
476
  }
292
477
 
293
478
  if (!result) {
294
- rb_raise(mTox_eUnknownError, "tox_self_set_name() failed");
479
+ RAISE_FUNC_RESULT("tox_self_set_name");
295
480
  }
296
481
 
297
482
  return name;
@@ -300,43 +485,23 @@ VALUE mTox_cClient_name_EQUALS(const VALUE self, const VALUE name)
300
485
  // Tox::Client#status
301
486
  VALUE mTox_cClient_status(const VALUE self)
302
487
  {
303
- mTox_cClient_CDATA *self_cdata;
488
+ CDATA(self, mTox_cClient_CDATA, self_cdata);
304
489
 
305
- Data_Get_Struct(self, mTox_cClient_CDATA, self_cdata);
490
+ const TOX_USER_STATUS status_data = tox_self_get_status(self_cdata->tox);
306
491
 
307
- const TOX_USER_STATUS result = tox_self_get_status(self_cdata->tox);
492
+ const VALUE status = mTox_mUserStatus_FROM_DATA(status_data);
308
493
 
309
- switch (result) {
310
- case TOX_USER_STATUS_NONE:
311
- return mTox_mUserStatus_NONE;
312
- case TOX_USER_STATUS_AWAY:
313
- return mTox_mUserStatus_AWAY;
314
- case TOX_USER_STATUS_BUSY:
315
- return mTox_mUserStatus_BUSY;
316
- default:
317
- rb_raise(rb_eNotImpError, "Tox::Client#status has unknown value");
318
- }
494
+ return status;
319
495
  }
320
496
 
321
497
  // Tox::Client#status=
322
- VALUE mTox_cClient_status_EQUALS(const VALUE self, const VALUE status)
498
+ VALUE mTox_cClient_status_ASSIGN(const VALUE self, const VALUE status)
323
499
  {
324
- mTox_cClient_CDATA *self_cdata;
500
+ CDATA(self, mTox_cClient_CDATA, self_cdata);
325
501
 
326
- Data_Get_Struct(self, mTox_cClient_CDATA, self_cdata);
502
+ const TOX_USER_STATUS status_data = mTox_mUserStatus_TO_DATA(status);
327
503
 
328
- if (rb_funcall(mTox_mUserStatus_NONE, rb_intern("=="), 1, status)) {
329
- tox_self_set_status(self_cdata->tox, TOX_USER_STATUS_NONE);
330
- }
331
- else if (rb_funcall(mTox_mUserStatus_AWAY, rb_intern("=="), 1, status)) {
332
- tox_self_set_status(self_cdata->tox, TOX_USER_STATUS_AWAY);
333
- }
334
- else if (rb_funcall(mTox_mUserStatus_BUSY, rb_intern("=="), 1, status)) {
335
- tox_self_set_status(self_cdata->tox, TOX_USER_STATUS_BUSY);
336
- }
337
- else {
338
- rb_raise(rb_eArgError, "invalid value for Tox::Client#status=");
339
- }
504
+ tox_self_set_status(self_cdata->tox, status_data);
340
505
 
341
506
  return status;
342
507
  }
@@ -344,35 +509,35 @@ VALUE mTox_cClient_status_EQUALS(const VALUE self, const VALUE status)
344
509
  // Tox::Client#status_message
345
510
  VALUE mTox_cClient_status_message(const VALUE self)
346
511
  {
347
- mTox_cClient_CDATA *self_cdata;
512
+ CDATA(self, mTox_cClient_CDATA, self_cdata);
348
513
 
349
- Data_Get_Struct(self, mTox_cClient_CDATA, self_cdata);
514
+ const size_t status_message_size_data =
515
+ tox_self_get_status_message_size(self_cdata->tox);
350
516
 
351
- const size_t status_message_size = tox_self_get_status_message_size(self_cdata->tox);
517
+ char status_message_data[status_message_size_data];
352
518
 
353
- char status_message[status_message_size];
354
-
355
- if (status_message_size > 0) {
356
- tox_self_get_status_message(self_cdata->tox, (uint8_t*)status_message);
519
+ if (status_message_size_data > 0) {
520
+ tox_self_get_status_message(self_cdata->tox, status_message_data);
357
521
  }
358
522
 
359
- return rb_str_new(status_message, status_message_size);
523
+ const VALUE status_message =
524
+ rb_str_new(status_message_data, status_message_size_data);
525
+
526
+ return status_message;
360
527
  }
361
528
 
362
529
  // Tox::Client#status_message=
363
- VALUE mTox_cClient_status_message_EQUALS(const VALUE self, const VALUE status_message)
530
+ VALUE mTox_cClient_status_message_ASSIGN(const VALUE self, const VALUE status_message)
364
531
  {
365
532
  Check_Type(status_message, T_STRING);
366
533
 
367
- mTox_cClient_CDATA *self_cdata;
368
-
369
- Data_Get_Struct(self, mTox_cClient_CDATA, self_cdata);
534
+ CDATA(self, mTox_cClient_CDATA, self_cdata);
370
535
 
371
536
  TOX_ERR_SET_INFO error;
372
537
 
373
538
  const bool result = tox_self_set_status_message(
374
539
  self_cdata->tox,
375
- (uint8_t**)RSTRING_PTR(status_message),
540
+ RSTRING_PTR(status_message),
376
541
  RSTRING_LEN(status_message),
377
542
  &error
378
543
  );
@@ -381,15 +546,23 @@ VALUE mTox_cClient_status_message_EQUALS(const VALUE self, const VALUE status_me
381
546
  case TOX_ERR_SET_INFO_OK:
382
547
  break;
383
548
  case TOX_ERR_SET_INFO_NULL:
384
- rb_raise(mTox_eNullError, "tox_self_set_status_message() failed with TOX_ERR_SET_INFO_NULL");
549
+ RAISE_FUNC_ERROR(
550
+ "tox_self_set_status_message",
551
+ mTox_eNullError,
552
+ "TOX_ERR_SET_INFO_NULL"
553
+ );
385
554
  case TOX_ERR_SET_INFO_TOO_LONG:
386
- rb_raise(rb_eRuntimeError, "tox_self_set_status_message() failed with TOX_ERR_SET_INFO_TOO_LONG");
555
+ RAISE_FUNC_ERROR(
556
+ "tox_self_set_status_message",
557
+ rb_eRuntimeError,
558
+ "TOX_ERR_SET_INFO_TOO_LONG"
559
+ );
387
560
  default:
388
- rb_raise(mTox_eUnknownError, "tox_self_set_status_message() failed");
561
+ RAISE_FUNC_ERROR_DEFAULT("tox_self_set_status_message");
389
562
  }
390
563
 
391
564
  if (!result) {
392
- rb_raise(mTox_eUnknownError, "tox_self_set_status_message() failed");
565
+ RAISE_FUNC_RESULT("tox_self_set_status_message");
393
566
  }
394
567
 
395
568
  return status_message;
@@ -398,14 +571,13 @@ VALUE mTox_cClient_status_message_EQUALS(const VALUE self, const VALUE status_me
398
571
  // Tox::Client#friend_numbers
399
572
  VALUE mTox_cClient_friend_numbers(const VALUE self)
400
573
  {
401
- mTox_cClient_CDATA *self_cdata;
402
-
403
- Data_Get_Struct(self, mTox_cClient_CDATA, self_cdata);
574
+ CDATA(self, mTox_cClient_CDATA, self_cdata);
404
575
 
405
576
  const size_t friend_numbers_size = tox_self_get_friend_list_size(self_cdata->tox);
406
577
 
407
578
  if (friend_numbers_size == 0) {
408
- return rb_ary_new();
579
+ const VALUE friends = rb_ary_new();
580
+ return friends;
409
581
  }
410
582
 
411
583
  uint32_t friend_numbers[friend_numbers_size];
@@ -418,30 +590,159 @@ VALUE mTox_cClient_friend_numbers(const VALUE self)
418
590
  friend_number_values[i] = LONG2NUM(friend_numbers[i]);
419
591
  }
420
592
 
421
- return rb_ary_new4(friend_numbers_size, friend_number_values);
593
+ const VALUE friends = rb_ary_new4(friend_numbers_size, friend_number_values);
594
+
595
+ return friends;
422
596
  }
423
597
 
424
598
  // Tox::Client#friend_add_norequest
425
599
  VALUE mTox_cClient_friend_add_norequest(const VALUE self, const VALUE public_key)
426
600
  {
427
- Check_Type(public_key, T_STRING);
601
+ if (!rb_funcall(public_key, rb_intern("is_a?"), 1, mTox_cPublicKey)) {
602
+ RAISE_TYPECHECK("Tox::Client#friend_add_norequest", "public_key", "Tox::PublicKey");
603
+ }
604
+
605
+ CDATA(self, mTox_cClient_CDATA, self_cdata);
428
606
 
429
- mTox_cClient_CDATA *self_cdata;
607
+ const VALUE public_key_value = rb_funcall(public_key, rb_intern("value"), 0);
430
608
 
431
- Data_Get_Struct(self, mTox_cClient_CDATA, self_cdata);
609
+ TOX_ERR_FRIEND_ADD error;
432
610
 
433
611
  const VALUE friend_number = LONG2FIX(tox_friend_add_norequest(
434
612
  self_cdata->tox,
435
- (uint8_t*)RSTRING_PTR(public_key),
436
- NULL
613
+ RSTRING_PTR(public_key_value),
614
+ &error
437
615
  ));
438
616
 
439
- return rb_funcall(
440
- self,
441
- rb_intern("friend"),
442
- 1,
443
- friend_number
444
- );
617
+ switch (error) {
618
+ case TOX_ERR_FRIEND_ADD_OK:
619
+ break;
620
+ case TOX_ERR_FRIEND_ADD_NULL:
621
+ RAISE_FUNC_ERROR(
622
+ "tox_friend_add_norequest",
623
+ mTox_eNullError,
624
+ "TOX_ERR_FRIEND_ADD_NULL"
625
+ );
626
+ case TOX_ERR_FRIEND_ADD_OWN_KEY:
627
+ RAISE_FUNC_ERROR(
628
+ "tox_friend_add_norequest",
629
+ rb_eRuntimeError,
630
+ "TOX_ERR_FRIEND_ADD_OWN_KEY"
631
+ );
632
+ case TOX_ERR_FRIEND_ADD_ALREADY_SENT:
633
+ RAISE_FUNC_ERROR(
634
+ "tox_friend_add_norequest",
635
+ rb_eRuntimeError,
636
+ "TOX_ERR_FRIEND_ADD_ALREADY_SENT"
637
+ );
638
+ case TOX_ERR_FRIEND_ADD_BAD_CHECKSUM:
639
+ RAISE_FUNC_ERROR(
640
+ "tox_friend_add_norequest",
641
+ rb_eRuntimeError,
642
+ "TOX_ERR_FRIEND_ADD_BAD_CHECKSUM"
643
+ );
644
+ case TOX_ERR_FRIEND_ADD_SET_NEW_NOSPAM:
645
+ RAISE_FUNC_ERROR(
646
+ "tox_friend_add_norequest",
647
+ rb_eRuntimeError,
648
+ "TOX_ERR_FRIEND_ADD_SET_NEW_NOSPAM"
649
+ );
650
+ case TOX_ERR_FRIEND_ADD_MALLOC:
651
+ RAISE_FUNC_ERROR(
652
+ "tox_friend_add_norequest",
653
+ rb_eNoMemError,
654
+ "TOX_ERR_FRIEND_ADD_MALLOC"
655
+ );
656
+ default:
657
+ RAISE_FUNC_ERROR_DEFAULT("tox_friend_add_norequest");
658
+ }
659
+
660
+ const VALUE friend = rb_funcall(self, rb_intern("friend"), 1,
661
+ friend_number);
662
+
663
+ return friend;
664
+ }
665
+
666
+ // Tox::Client#friend_add
667
+ VALUE mTox_cClient_friend_add(const VALUE self, const VALUE address, const VALUE text)
668
+ {
669
+ if (!rb_funcall(address, rb_intern("is_a?"), 1, mTox_cAddress)) {
670
+ RAISE_TYPECHECK("Tox::Client#friend_add", "address", "Tox::Address");
671
+ }
672
+
673
+ Check_Type(text, T_STRING);
674
+
675
+ CDATA(self, mTox_cClient_CDATA, self_cdata);
676
+
677
+ TOX_ERR_FRIEND_ADD error;
678
+
679
+ const VALUE address_value = rb_funcall(address, rb_intern("value"), 0);
680
+
681
+ const VALUE friend_number = LONG2FIX(tox_friend_add(
682
+ self_cdata->tox,
683
+ RSTRING_PTR(address_value),
684
+ RSTRING_PTR(text),
685
+ RSTRING_LEN(text),
686
+ &error
687
+ ));
688
+
689
+ switch (error) {
690
+ case TOX_ERR_FRIEND_ADD_OK:
691
+ break;
692
+ case TOX_ERR_FRIEND_ADD_NULL:
693
+ RAISE_FUNC_ERROR(
694
+ "tox_friend_add",
695
+ mTox_eNullError,
696
+ "TOX_ERR_FRIEND_ADD_NULL"
697
+ );
698
+ case TOX_ERR_FRIEND_ADD_NO_MESSAGE:
699
+ RAISE_FUNC_ERROR(
700
+ "tox_friend_add",
701
+ mTox_eNullError,
702
+ "TOX_ERR_FRIEND_ADD_NO_MESSAGE"
703
+ );
704
+ case TOX_ERR_FRIEND_ADD_TOO_LONG:
705
+ RAISE_FUNC_ERROR(
706
+ "tox_friend_add",
707
+ mTox_eNullError,
708
+ "TOX_ERR_FRIEND_ADD_TOO_LONG"
709
+ );
710
+ case TOX_ERR_FRIEND_ADD_OWN_KEY:
711
+ RAISE_FUNC_ERROR(
712
+ "tox_friend_add",
713
+ rb_eRuntimeError,
714
+ "TOX_ERR_FRIEND_ADD_OWN_KEY"
715
+ );
716
+ case TOX_ERR_FRIEND_ADD_ALREADY_SENT:
717
+ RAISE_FUNC_ERROR(
718
+ "tox_friend_add",
719
+ rb_eRuntimeError,
720
+ "TOX_ERR_FRIEND_ADD_ALREADY_SENT"
721
+ );
722
+ case TOX_ERR_FRIEND_ADD_BAD_CHECKSUM:
723
+ RAISE_FUNC_ERROR(
724
+ "tox_friend_add",
725
+ rb_eRuntimeError,
726
+ "TOX_ERR_FRIEND_ADD_BAD_CHECKSUM"
727
+ );
728
+ case TOX_ERR_FRIEND_ADD_SET_NEW_NOSPAM:
729
+ RAISE_FUNC_ERROR(
730
+ "tox_friend_add",
731
+ rb_eRuntimeError,
732
+ "TOX_ERR_FRIEND_ADD_SET_NEW_NOSPAM"
733
+ );
734
+ case TOX_ERR_FRIEND_ADD_MALLOC:
735
+ RAISE_FUNC_ERROR(
736
+ "tox_friend_add",
737
+ rb_eNoMemError,
738
+ "TOX_ERR_FRIEND_ADD_MALLOC"
739
+ );
740
+ }
741
+
742
+ const VALUE friend = rb_funcall(self, rb_intern("friend"), 1,
743
+ friend_number);
744
+
745
+ return friend;
445
746
  }
446
747
 
447
748
  /*************************************************************
@@ -451,43 +752,80 @@ VALUE mTox_cClient_friend_add_norequest(const VALUE self, const VALUE public_key
451
752
  // Tox::Client#initialize_with
452
753
  VALUE mTox_cClient_initialize_with(const VALUE self, const VALUE options)
453
754
  {
454
- mTox_cClient_CDATA *self_cdata;
455
- mTox_cOptions_CDATA *options_cdata;
456
-
457
755
  if (!rb_funcall(options, rb_intern("is_a?"), 1, mTox_cOptions)) {
458
- rb_raise(rb_eTypeError, "expected options to be a Tox::Options");
756
+ RAISE_TYPECHECK("Tox::Client#initialize_with", "options", "Tox::Options");
459
757
  }
460
758
 
461
- Data_Get_Struct(self, mTox_cClient_CDATA, self_cdata);
462
- Data_Get_Struct(options, mTox_cOptions_CDATA, options_cdata);
759
+ CDATA(self, mTox_cClient_CDATA, self_cdata);
760
+ CDATA(options, mTox_cOptions_CDATA, options_cdata);
463
761
 
464
762
  TOX_ERR_NEW error;
465
763
 
466
- self_cdata->tox = tox_new(options_cdata, &error);
764
+ self_cdata->tox = tox_new(options_cdata->tox_options, &error);
467
765
 
468
766
  switch (error) {
469
767
  case TOX_ERR_NEW_OK:
470
768
  break;
471
769
  case TOX_ERR_NEW_NULL:
472
- rb_raise(mTox_eNullError, "tox_new() failed with TOX_ERR_NEW_NULL");
770
+ RAISE_FUNC_ERROR(
771
+ "tox_new",
772
+ mTox_eNullError,
773
+ "TOX_ERR_NEW_NULL"
774
+ );
473
775
  case TOX_ERR_NEW_MALLOC:
474
- rb_raise(rb_eNoMemError, "tox_new() failed with TOX_ERR_NEW_MALLOC");
776
+ RAISE_FUNC_ERROR(
777
+ "tox_new",
778
+ rb_eNoMemError,
779
+ "TOX_ERR_NEW_MALLOC"
780
+ );
475
781
  case TOX_ERR_NEW_PORT_ALLOC:
476
- rb_raise(rb_eRuntimeError, "tox_new() failed with TOX_ERR_NEW_PORT_ALLOC");
782
+ RAISE_FUNC_ERROR(
783
+ "tox_new",
784
+ rb_eRuntimeError,
785
+ "TOX_ERR_NEW_PORT_ALLOC"
786
+ );
477
787
  case TOX_ERR_NEW_PROXY_BAD_TYPE:
478
- rb_raise(rb_eRuntimeError, "tox_new() failed with TOX_ERR_NEW_PROXY_BAD_TYPE");
788
+ RAISE_FUNC_ERROR(
789
+ "tox_new",
790
+ rb_eRuntimeError,
791
+ "TOX_ERR_NEW_PROXY_BAD_TYPE"
792
+ );
479
793
  case TOX_ERR_NEW_PROXY_BAD_HOST:
480
- rb_raise(rb_eRuntimeError, "tox_new() failed with TOX_ERR_NEW_PROXY_BAD_HOST");
794
+ RAISE_FUNC_ERROR(
795
+ "tox_new",
796
+ rb_eRuntimeError,
797
+ "TOX_ERR_NEW_PROXY_BAD_HOST"
798
+ );
481
799
  case TOX_ERR_NEW_PROXY_BAD_PORT:
482
- rb_raise(rb_eRuntimeError, "tox_new() failed with TOX_ERR_NEW_PROXY_BAD_PORT");
800
+ RAISE_FUNC_ERROR(
801
+ "tox_new",
802
+ rb_eRuntimeError,
803
+ "TOX_ERR_NEW_PROXY_BAD_PORT"
804
+ );
483
805
  case TOX_ERR_NEW_PROXY_NOT_FOUND:
484
- rb_raise(rb_eRuntimeError, "tox_new() failed with TOX_ERR_NEW_PROXY_NOT_FOUND");
806
+ RAISE_FUNC_ERROR(
807
+ "tox_new",
808
+ rb_eRuntimeError,
809
+ "TOX_ERR_NEW_PROXY_NOT_FOUND"
810
+ );
485
811
  case TOX_ERR_NEW_LOAD_ENCRYPTED:
486
- rb_raise(rb_eRuntimeError, "tox_new() failed with TOX_ERR_NEW_LOAD_ENCRYPTED");
812
+ RAISE_FUNC_ERROR(
813
+ "tox_new",
814
+ rb_eRuntimeError,
815
+ "TOX_ERR_NEW_LOAD_ENCRYPTED"
816
+ );
487
817
  case TOX_ERR_NEW_LOAD_BAD_FORMAT:
488
- rb_raise(mTox_cClient_eBadSavedataError, "tox_new() failed with TOX_ERR_NEW_LOAD_BAD_FORMAT");
818
+ RAISE_FUNC_ERROR(
819
+ "tox_new",
820
+ mTox_cClient_eBadSavedataError,
821
+ "TOX_ERR_NEW_LOAD_BAD_FORMAT"
822
+ );
489
823
  default:
490
- rb_raise(mTox_eUnknownError, "tox_new() failed");
824
+ RAISE_FUNC_ERROR_DEFAULT("tox_new");
825
+ }
826
+
827
+ if (!self_cdata->tox) {
828
+ RAISE_FUNC_RESULT("tox_new");
491
829
  }
492
830
 
493
831
  tox_callback_friend_request (self_cdata->tox, on_friend_request);
@@ -499,42 +837,15 @@ VALUE mTox_cClient_initialize_with(const VALUE self, const VALUE options)
499
837
  return self;
500
838
  }
501
839
 
502
- // Tox::Client#run_loop
503
- VALUE mTox_cClient_run_loop(const VALUE self)
504
- {
505
- mTox_cClient_CDATA *self_cdata;
506
-
507
- Data_Get_Struct(self, mTox_cClient_CDATA, self_cdata);
508
-
509
- struct timespec delay;
510
-
511
- delay.tv_sec = 0;
512
-
513
- const VALUE ivar_on_iteration = rb_iv_get(self, "@on_iteration");
514
-
515
- while (rb_funcall(self, rb_intern("running?"), 0)) {
516
- delay.tv_nsec = tox_iteration_interval(self_cdata->tox) * 1000000;
517
- nanosleep(&delay, NULL);
518
-
519
- tox_iterate(self_cdata->tox, self);
520
-
521
- if (Qnil != ivar_on_iteration) {
522
- rb_funcall(ivar_on_iteration, rb_intern("call"), 0);
523
- }
524
- }
525
-
526
- return self;
527
- }
528
-
529
840
  /*************************************************************
530
841
  * Callbacks
531
842
  *************************************************************/
532
843
 
533
844
  void on_friend_request(
534
845
  Tox *const tox,
535
- const uint8_t *const public_key,
536
- const uint8_t *const data,
537
- const size_t length,
846
+ const uint8_t *const public_key_data,
847
+ const uint8_t *const text_data,
848
+ const size_t text_length_data,
538
849
  const VALUE self
539
850
  )
540
851
  {
@@ -544,26 +855,25 @@ void on_friend_request(
544
855
  return;
545
856
  }
546
857
 
547
- rb_funcall(
548
- ivar_on_friend_request,
549
- rb_intern("call"),
550
- 2,
551
- rb_funcall(
552
- mTox_cPublicKey,
553
- rb_intern("new"),
554
- 1,
555
- rb_str_new(public_key, TOX_PUBLIC_KEY_SIZE)
556
- ),
557
- rb_str_new((char*)data, length)
558
- );
858
+ const VALUE public_key_value =
859
+ rb_str_new(public_key_data, TOX_PUBLIC_KEY_SIZE);
860
+
861
+ const VALUE public_key = rb_funcall(mTox_cPublicKey, rb_intern("new"), 1,
862
+ public_key_value);
863
+
864
+ const VALUE text = rb_str_new(text_data, text_length_data);
865
+
866
+ rb_funcall(ivar_on_friend_request, rb_intern("call"), 2,
867
+ public_key,
868
+ text);
559
869
  }
560
870
 
561
871
  void on_friend_message(
562
872
  Tox *const tox,
563
- const uint32_t friend_number,
873
+ const uint32_t friend_number_data,
564
874
  const TOX_MESSAGE_TYPE type,
565
- const uint8_t *const text,
566
- const size_t length,
875
+ const uint8_t *const text_data,
876
+ const size_t text_length_data,
567
877
  const VALUE self
568
878
  )
569
879
  {
@@ -573,119 +883,103 @@ void on_friend_message(
573
883
  return;
574
884
  }
575
885
 
576
- rb_funcall(
577
- ivar_on_friend_message,
578
- rb_intern("call"),
579
- 2,
580
- rb_funcall(
581
- mTox_cFriend,
582
- rb_intern("new"),
583
- 2,
584
- self,
585
- LONG2FIX(friend_number)
586
- ),
587
- rb_str_new((char*)text, length)
588
- );
886
+ const VALUE friend_number = LONG2FIX(friend_number_data);
887
+
888
+ const VALUE friend = rb_funcall(mTox_cFriend, rb_intern("new"), 2,
889
+ self,
890
+ friend_number);
891
+
892
+ const VALUE text = rb_str_new(text_data, text_length_data);
893
+
894
+ rb_funcall(ivar_on_friend_message, rb_intern("call"), 2,
895
+ friend,
896
+ text);
589
897
  }
590
898
 
591
899
  void on_friend_name_change(
592
900
  Tox *const tox,
593
- const uint32_t friend_number,
594
- const uint8_t *const name,
595
- const size_t length,
901
+ const uint32_t friend_number_data,
902
+ const uint8_t *const name_data,
903
+ const size_t name_length_data,
596
904
  const VALUE self
597
905
  )
598
906
  {
599
- const VALUE ivar_on_friend_name_change = rb_iv_get(self, "@on_friend_name_change");
907
+ const VALUE ivar_on_friend_name_change =
908
+ rb_iv_get(self, "@on_friend_name_change");
600
909
 
601
910
  if (Qnil == ivar_on_friend_name_change) {
602
911
  return;
603
912
  }
604
913
 
605
- rb_funcall(
606
- ivar_on_friend_name_change,
607
- rb_intern("call"),
608
- 2,
609
- rb_funcall(
610
- mTox_cFriend,
611
- rb_intern("new"),
612
- 2,
613
- self,
614
- LONG2FIX(friend_number)
615
- ),
616
- rb_str_new(name, length)
617
- );
914
+ const VALUE friend_number = LONG2FIX(friend_number_data);
915
+
916
+ const VALUE friend = rb_funcall(mTox_cFriend, rb_intern("new"), 2,
917
+ self,
918
+ friend_number);
919
+
920
+ const VALUE name = rb_str_new(name_data, name_length_data);
921
+
922
+ rb_funcall(ivar_on_friend_name_change, rb_intern("call"), 2,
923
+ friend,
924
+ name);
618
925
  }
619
926
 
620
927
  void on_friend_status_message_change(
621
928
  Tox *const tox,
622
- const uint32_t friend_number,
623
- const uint8_t *const status_message,
624
- size_t length,
929
+ const uint32_t friend_number_data,
930
+ const uint8_t *const status_message_data,
931
+ size_t status_message_length_data,
625
932
  const VALUE self
626
933
  )
627
934
  {
628
- const VALUE ivar_on_friend_status_message_change = rb_iv_get(self, "@on_friend_status_message_change");
935
+ const VALUE ivar_on_friend_status_message_change =
936
+ rb_iv_get(self, "@on_friend_status_message_change");
629
937
 
630
938
  if (Qnil == ivar_on_friend_status_message_change) {
631
939
  return;
632
940
  }
633
941
 
634
- rb_funcall(
635
- ivar_on_friend_status_message_change,
636
- rb_intern("call"),
637
- 2,
638
- rb_funcall(
639
- mTox_cFriend,
640
- rb_intern("new"),
641
- 2,
642
- self,
643
- LONG2FIX(friend_number)
644
- ),
645
- rb_str_new(status_message, length)
646
- );
942
+ const VALUE friend_number = LONG2FIX(friend_number_data);
943
+
944
+ const VALUE friend = rb_funcall(mTox_cFriend, rb_intern("new"), 2,
945
+ self,
946
+ friend_number);
947
+
948
+ const VALUE status_message =
949
+ rb_str_new(status_message_data, status_message_length_data);
950
+
951
+ rb_funcall(ivar_on_friend_status_message_change, rb_intern("call"), 2,
952
+ friend,
953
+ status_message);
647
954
  }
648
955
 
649
956
  void on_friend_status_change(
650
957
  Tox *const tox,
651
- const uint32_t friend_number,
652
- const TOX_USER_STATUS status,
958
+ const uint32_t friend_number_data,
959
+ const TOX_USER_STATUS status_data,
653
960
  const VALUE self
654
961
  )
655
962
  {
656
- const VALUE ivar_on_friend_status_change = rb_iv_get(self, "@on_friend_status_change");
963
+ const VALUE ivar_on_friend_status_change =
964
+ rb_iv_get(self, "@on_friend_status_change");
657
965
 
658
966
  if (Qnil == ivar_on_friend_status_change) {
659
967
  return;
660
968
  }
661
969
 
662
- VALUE status_value;
970
+ const VALUE status = mTox_mUserStatus_TRY_DATA(status_data);
663
971
 
664
- switch (status) {
665
- case TOX_USER_STATUS_NONE:
666
- status_value = mTox_mUserStatus_NONE;
667
- break;
668
- case TOX_USER_STATUS_AWAY:
669
- status_value = mTox_mUserStatus_AWAY;
670
- break;
671
- case TOX_USER_STATUS_BUSY:
672
- status_value = mTox_mUserStatus_BUSY;
673
- break;
674
- default:
675
- return;
972
+ if (status == Qnil) {
973
+ return;
676
974
  }
677
975
 
678
- rb_funcall(
679
- ivar_on_friend_status_change,
680
- rb_intern("call"),
681
- 2,
682
- rb_funcall(
683
- mTox_cFriend,
684
- rb_intern("new"),
685
- 2,
686
- self,
687
- LONG2FIX(friend_number)
688
- ),
689
- status_value
690
- );
976
+ const VALUE friend_number = LONG2FIX(friend_number_data);
977
+
978
+ const VALUE friend = rb_funcall(mTox_cFriend, rb_intern("new"), 2,
979
+ self,
980
+ friend_number);
981
+
982
+ rb_funcall(ivar_on_friend_status_change, rb_intern("call"), 2,
983
+ friend,
984
+ status);
691
985
  }