ffi-fasttext 0.1.1 → 0.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2733c8705d35255f1f65e87fa0247da4d0f83a03
4
- data.tar.gz: e7e1917a8b172641441b039d147e1a9d83f217cc
3
+ metadata.gz: e68696e8ae484cfe2860a7c3d8b4d6ff82fa1634
4
+ data.tar.gz: 8d83b24e1d3a6f4088958e247576f27ecbf92075
5
5
  SHA512:
6
- metadata.gz: bc1eed1ab1a402a9b6541e1737626f01c630c08e6666a9f0d8505e02edc0e1178bda200eefc133fa0fb6201c88987ec6d860459cf51f979053ac28ef8a825c85
7
- data.tar.gz: a5fcd1bd377d33c4de336299a83ca7d06c7e93b2fcd51afa08363257776ea366e886cd0ea8faaf4ebd2c9964316e18f2be0c96d083f437a75d5dfe337f1c2519
6
+ metadata.gz: 2452d6825201de150eb467414551e847926407bbc29a92aaa560a3e59189ddee8747343cfd9429626147365e02522be8f1d4bda1133e2c2cc94fd04a3754c66c
7
+ data.tar.gz: e60d98a450292187fa566e5fe9a49a7534155440f20a9450bd9ce5364c6bd720c8e54422c38250b2a94d1832399ae0e977c3a0846c84c91e9e8451a045df973a
@@ -49,18 +49,19 @@ task :compile_fasttext do
49
49
  FASTTEXT_DIR = ::File.join(CWD, "..", "..", "..", "vendor", "fasttext")
50
50
 
51
51
  ::Dir.chdir(FASTTEXT_DIR) do
52
- sys("g++ -c -O3 -fPIC -pthread -std=c++0x -c args.cc") unless ::File.exist?("args.o")
53
- sys("g++ -c -O3 -fPIC -pthread -std=c++0x -c dictionary.cc") unless ::File.exist?("dictionary.o")
54
- sys("g++ -c -O3 -fPIC -pthread -std=c++0x -c productquantizer.cc") unless ::File.exist?("productquantizer.o")
55
- sys("g++ -c -O3 -fPIC -pthread -std=c++0x -c matrix.cc") unless ::File.exist?("matrix.o")
56
- sys("g++ -c -O3 -fPIC -pthread -std=c++0x -c qmatrix.cc") unless ::File.exist?("qmatrix.o")
57
- sys("g++ -c -O3 -fPIC -pthread -std=c++0x -c vector.cc") unless ::File.exist?("vector.o")
58
- sys("g++ -c -O3 -fPIC -pthread -std=c++0x -c model.cc") unless ::File.exist?("model.o")
59
- sys("g++ -c -O3 -fPIC -pthread -std=c++0x -c utils.cc") unless ::File.exist?("utils.o")
60
- sys("g++ -c -O3 -fPIC -pthread -std=c++0x -c fasttext.cc") unless ::File.exist?("fasttext.o")
61
- sys("g++ -c -O3 -fPIC -pthread -std=c++0x -c ffi_fasttext.cc")
62
- sys("g++ -fPIC -pthread -std=c++0x args.o dictionary.o productquantizer.o matrix.o qmatrix.o vector.o model.o utils.o fasttext.o main.cc -o fasttext") unless ::File.exist?("fasttext")
63
- sys("g++ -fPIC -pthread -std=c++0x args.o dictionary.o productquantizer.o matrix.o qmatrix.o vector.o model.o utils.o fasttext.o ffi_fasttext.o -shared -o libfasttext.#{::FFI::Platform::LIBSUFFIX}")
52
+ sys("g++ -c -O3 -fPIC -pthread -std=c++14 -c args.cc") unless ::File.exist?("args.o")
53
+ sys("g++ -c -O3 -fPIC -pthread -std=c++14 -c dictionary.cc") unless ::File.exist?("dictionary.o")
54
+ sys("g++ -c -O3 -fPIC -pthread -std=c++14 -c productquantizer.cc") unless ::File.exist?("productquantizer.o")
55
+ sys("g++ -c -O3 -fPIC -pthread -std=c++14 -c matrix.cc") unless ::File.exist?("matrix.o")
56
+ sys("g++ -c -O3 -fPIC -pthread -std=c++14 -c qmatrix.cc") unless ::File.exist?("qmatrix.o")
57
+ sys("g++ -c -O3 -fPIC -pthread -std=c++14 -c vector.cc") unless ::File.exist?("vector.o")
58
+ sys("g++ -c -O3 -fPIC -pthread -std=c++14 -c model.cc") unless ::File.exist?("model.o")
59
+ sys("g++ -c -O3 -fPIC -pthread -std=c++14 -c utils.cc") unless ::File.exist?("utils.o")
60
+ sys("g++ -c -O3 -fPIC -pthread -std=c++14 -c fasttext.cc") unless ::File.exist?("fasttext.o")
61
+ sys("g++ -c -O3 -fPIC -pthread -std=c++14 -c ffi_fasttext.cc")
62
+ sys("g++ -c -O3 -fPIC -pthread -std=c++14 -c curlstream.cc")
63
+ sys("g++ -fPIC -pthread -std=c++14 args.o dictionary.o productquantizer.o matrix.o qmatrix.o vector.o model.o utils.o fasttext.o main.cc -o fasttext") unless ::File.exist?("fasttext")
64
+ sys("g++ -fPIC -pthread -std=c++14 args.o dictionary.o productquantizer.o matrix.o qmatrix.o vector.o model.o utils.o fasttext.o ffi_fasttext.o curlstream.o -lcurl -shared -o libfasttext.#{::FFI::Platform::LIBSUFFIX}")
64
65
  end
65
66
 
66
67
  unless ::File.exist?(::File.join(FASTTEXT_DIR, "libfasttext.#{::FFI::Platform::LIBSUFFIX}"))
@@ -34,7 +34,7 @@ Gem::Specification.new do |spec|
34
34
  spec.add_dependency "ffi"
35
35
 
36
36
  spec.add_development_dependency "pry"
37
- spec.add_development_dependency "bundler", "~> 1.16"
38
- spec.add_development_dependency "rake", "~> 10.0"
39
- spec.add_development_dependency "minitest", "~> 5.0"
37
+ spec.add_development_dependency "bundler"
38
+ spec.add_development_dependency "rake"
39
+ spec.add_development_dependency "minitest"
40
40
  end
@@ -72,14 +72,15 @@ module FFI
72
72
  end
73
73
 
74
74
  attach_function :create, [:string], :pointer
75
+ attach_function :create_from_url, [:string], :pointer
75
76
  attach_function :destroy, [:pointer], :void
76
77
  attach_function :predict_string_free, [:pointer], :void
77
78
  attach_function :predict, [:pointer, :string, :int32_t], :strptr
78
79
 
79
80
  class Predictor
80
- def initialize(model_filename)
81
- raise "File does not exist" unless ::File.exist?(model_filename)
82
- @ptr = ::FFI::Fasttext.create(model_filename)
81
+ def initialize(model_name)
82
+ @ptr = ::File.exist?(model_name) ? ::FFI::Fasttext.create(model_name) : ::FFI::Fasttext.create_from_url(model_name)
83
+ raise "Error loading model" if @ptr.null?
83
84
  end
84
85
 
85
86
  def destroy!
@@ -1,5 +1,5 @@
1
1
  module FFI
2
2
  module Fasttext
3
- VERSION = "0.1.1"
3
+ VERSION = "0.3.0"
4
4
  end
5
5
  end
@@ -0,0 +1,132 @@
1
+ #include <memory>
2
+ #include <chrono>
3
+ #include <thread>
4
+ #include <streambuf>
5
+ #include "./curlstream.h"
6
+
7
+ class curl_global_initializer {
8
+ public:
9
+ curl_global_initializer() { curl_global_init(CURL_GLOBAL_DEFAULT); }
10
+ ~curl_global_initializer() { curl_global_cleanup(); }
11
+ };
12
+
13
+ namespace {
14
+ bool curl_initialized()
15
+ {
16
+ static std::unique_ptr<curl_global_initializer> initializer = std::make_unique<curl_global_initializer>();
17
+ return initializer != nullptr;
18
+ }
19
+ }
20
+
21
+ CurlStreambuff::CurlStreambuff(const std::string& url)
22
+ {
23
+ if (curl_initialized()) {
24
+ m_http_handle = curl_easy_init();
25
+ curl_easy_setopt(m_http_handle, CURLOPT_URL, url.c_str());
26
+ curl_easy_setopt(m_http_handle, CURLOPT_FOLLOWLOCATION, 1L);
27
+ curl_easy_setopt(m_http_handle, CURLOPT_SSL_VERIFYPEER, 0L);
28
+ curl_easy_setopt(m_http_handle, CURLOPT_WRITEFUNCTION, &CurlStreambuff::writer_callback);
29
+ curl_easy_setopt(m_http_handle, CURLOPT_WRITEDATA, this);
30
+
31
+ m_multi_handle = curl_multi_init();
32
+ curl_multi_add_handle(m_multi_handle, m_http_handle);
33
+ }
34
+ }
35
+
36
+ CurlStreambuff::~CurlStreambuff()
37
+ {
38
+ if (m_multi_handle && m_http_handle) {
39
+ curl_multi_remove_handle(m_multi_handle, m_http_handle);
40
+ }
41
+ if (m_http_handle) {
42
+ curl_easy_cleanup(m_http_handle);
43
+ }
44
+ if (m_multi_handle) {
45
+ curl_multi_cleanup(m_multi_handle);
46
+ }
47
+ }
48
+
49
+ std::streamsize CurlStreambuff::xsgetn(char *s, std::streamsize n)
50
+ {
51
+ auto remaining = n;
52
+ while (remaining > 0) {
53
+ if (m_pos >= m_size) {
54
+ if (fillbuffer() == 0) {
55
+ break;
56
+ }
57
+ }
58
+ auto to_copy = std::min<size_t>(remaining, m_size - m_pos);
59
+ memcpy(s, &m_buffer[m_pos], to_copy);
60
+ s += to_copy;
61
+ m_pos += to_copy;
62
+ remaining -= to_copy;
63
+ }
64
+ return n - remaining;
65
+ }
66
+
67
+ int CurlStreambuff::underflow()
68
+ {
69
+ if (m_pos >= m_size) {
70
+ if (fillbuffer() == 0) {
71
+ return traits_type::eof();
72
+ }
73
+ }
74
+ return traits_type::to_int_type(m_buffer[m_pos]);
75
+ }
76
+
77
+ int CurlStreambuff::uflow()
78
+ {
79
+ if (m_pos >= m_size) {
80
+ if (fillbuffer() == 0) {
81
+ return traits_type::eof();
82
+ }
83
+ }
84
+ return traits_type::to_int_type(m_buffer[m_pos++]);
85
+ }
86
+
87
+ int CurlStreambuff::writer_callback(char *data, size_t size, size_t count, void* ptr)
88
+ {
89
+ auto self = static_cast<CurlStreambuff*>(ptr);
90
+ auto bytes = size * count;
91
+ if(bytes > sizeof(m_buffer) || bytes == 0) {
92
+ return 0;
93
+ }
94
+ memcpy(&self->m_buffer[0], data, bytes);
95
+ self->m_size = bytes;
96
+ self->m_pos = 0;
97
+ return bytes;
98
+ }
99
+
100
+ size_t CurlStreambuff::fillbuffer()
101
+ {
102
+ using namespace std::chrono_literals;
103
+ m_size = 0;
104
+ int still_running_count = 1, repeats = 0;
105
+ while (still_running_count > 0) {
106
+ auto mc = curl_multi_perform(m_multi_handle, &still_running_count);
107
+ if (mc != CURLM_OK) {
108
+ return 0;
109
+ }
110
+ if (m_size > 0) {
111
+ break;
112
+ }
113
+ /* wait for activity, timeout or "nothing" */
114
+ int numfds;
115
+ mc = curl_multi_wait(m_multi_handle, nullptr, 0, 1000, &numfds);
116
+ if(mc != CURLM_OK) {
117
+ return 0;
118
+ }
119
+
120
+ /* 'numfds' being zero means either a timeout or no file descriptors to
121
+ wait for. Try timeout on first occurrence, then assume no file
122
+ descriptors and no file descriptors to wait for means wait for 100
123
+ milliseconds. */
124
+ if(numfds == 0) {
125
+ if (++repeats > 1) {
126
+ std::this_thread::sleep_for(100ms);
127
+ }
128
+ }
129
+ }
130
+ return m_size;
131
+ }
132
+
@@ -0,0 +1,39 @@
1
+ #include <iostream>
2
+ #include <streambuf>
3
+ #include <curl/curl.h>
4
+ #include <string.h>
5
+
6
+ class CurlStreambuff : public std::streambuf {
7
+ public:
8
+ explicit CurlStreambuff(const std::string& url);
9
+ ~CurlStreambuff();
10
+
11
+ // Copy and move prohibited
12
+ CurlStreambuff(const CurlStreambuff&) = delete;
13
+ CurlStreambuff& operator = (const CurlStreambuff&) = delete;
14
+ CurlStreambuff(CurlStreambuff && src) = delete;
15
+ CurlStreambuff& operator = (CurlStreambuff && rhs) = delete;
16
+
17
+ protected:
18
+ std::streamsize xsgetn(char *s, std::streamsize n) override;
19
+ int underflow() override;
20
+ int uflow() override;
21
+
22
+ private:
23
+ static int writer_callback(char *data, size_t size, size_t count, void* ptr);
24
+ size_t fillbuffer();
25
+
26
+ CURL *m_http_handle = nullptr;
27
+ CURLM *m_multi_handle = nullptr;
28
+ char m_buffer[CURL_MAX_WRITE_SIZE];
29
+ size_t m_pos = 0, m_size = 0;
30
+ };
31
+
32
+ class CurlStream : private CurlStreambuff, public std::istream {
33
+ public:
34
+ explicit CurlStream(const std::string& url)
35
+ : CurlStreambuff(url), std::istream(this)
36
+ {
37
+ }
38
+ };
39
+
@@ -43,8 +43,7 @@ void FastText::getVector(Vector& vec, const std::string& word) const {
43
43
  void FastText::saveVectors() {
44
44
  std::ofstream ofs(args_->output + ".vec");
45
45
  if (!ofs.is_open()) {
46
- std::cerr << "Error opening file for saving vectors." << std::endl;
47
- exit(EXIT_FAILURE);
46
+ throw std::runtime_error("Error opening file for saving vectors.");
48
47
  }
49
48
  ofs << dict_->nwords() << " " << args_->dim << std::endl;
50
49
  Vector vec(args_->dim);
@@ -59,8 +58,7 @@ void FastText::saveVectors() {
59
58
  void FastText::saveOutput() {
60
59
  std::ofstream ofs(args_->output + ".output");
61
60
  if (!ofs.is_open()) {
62
- std::cerr << "Error opening file for saving vectors." << std::endl;
63
- exit(EXIT_FAILURE);
61
+ throw std::runtime_error("Error opening file for saving vectors.");
64
62
  }
65
63
  if (quant_) {
66
64
  std::cerr << "Option -saveOutput is not supported for quantized models."
@@ -110,8 +108,7 @@ void FastText::saveModel() {
110
108
  }
111
109
  std::ofstream ofs(fn, std::ofstream::binary);
112
110
  if (!ofs.is_open()) {
113
- std::cerr << "Model file cannot be opened for saving!" << std::endl;
114
- exit(EXIT_FAILURE);
111
+ throw std::runtime_error("Model file cannot be opened for saving!");
115
112
  }
116
113
  signModel(ofs);
117
114
  args_->save(ofs);
@@ -137,18 +134,16 @@ void FastText::saveModel() {
137
134
  void FastText::loadModel(const std::string& filename) {
138
135
  std::ifstream ifs(filename, std::ifstream::binary);
139
136
  if (!ifs.is_open()) {
140
- std::cerr << "Model file cannot be opened for loading!" << std::endl;
141
- exit(EXIT_FAILURE);
142
- }
143
- if (!checkModel(ifs)) {
144
- std::cerr << "Model file has wrong file format!" << std::endl;
145
- exit(EXIT_FAILURE);
137
+ throw std::runtime_error("Model file cannot be opened for loading!");
146
138
  }
147
139
  loadModel(ifs);
148
140
  ifs.close();
149
141
  }
150
142
 
151
143
  void FastText::loadModel(std::istream& in) {
144
+ if (!checkModel(in)) {
145
+ throw std::runtime_error("Model file has wrong file format!");
146
+ }
152
147
  args_ = std::make_shared<Args>();
153
148
  dict_ = std::make_shared<Dictionary>(args_);
154
149
  input_ = std::make_shared<Matrix>();
@@ -172,10 +167,7 @@ void FastText::loadModel(std::istream& in) {
172
167
  }
173
168
 
174
169
  if (!quant_input && dict_->isPruned()) {
175
- std::cerr << "Invalid model file.\n"
176
- << "Please download the updated model from www.fasttext.cc.\n"
177
- << "See issue #332 on Github for more information.\n";
178
- exit(1);
170
+ throw std::runtime_error("Invalid model file");
179
171
  }
180
172
 
181
173
  in.read((char*) &args_->qout, sizeof(bool));
@@ -228,8 +220,7 @@ std::vector FastText::selectEmbeddings(int32_t cutoff) const {
228
220
 
229
221
  void FastText::quantize(std::shared_ptr<Args> qargs) {
230
222
  if (qargs->output.empty()) {
231
- std::cerr<<"No model provided!"<<std::endl;
232
- exit(1);
223
+ throw std::runtime_error("No model provided!");
233
224
  }
234
225
  loadModel(qargs->output + ".bin");
235
226
 
@@ -600,14 +591,11 @@ void FastText::loadVectors(std::string filename) {
600
591
  std::shared_ptr<Matrix> mat; // temp. matrix for pretrained vectors
601
592
  int64_t n, dim;
602
593
  if (!in.is_open()) {
603
- std::cerr << "Pretrained vectors file cannot be opened!" << std::endl;
604
- exit(EXIT_FAILURE);
594
+ throw std::runtime_error("Pretrained vectors file cannot be opened!");
605
595
  }
606
596
  in >> n >> dim;
607
597
  if (dim != args_->dim) {
608
- std::cerr << "Dimension of pretrained vectors does not match -dim option"
609
- << std::endl;
610
- exit(EXIT_FAILURE);
598
+ throw std::runtime_error("Dimension of pretrained vectors does not match -dim option");
611
599
  }
612
600
  mat = std::make_shared<Matrix>(n, dim);
613
601
  for (size_t i = 0; i < n; i++) {
@@ -639,13 +627,11 @@ void FastText::train(std::shared_ptr args) {
639
627
  dict_ = std::make_shared<Dictionary>(args_);
640
628
  if (args_->input == "-") {
641
629
  // manage expectations
642
- std::cerr << "Cannot use stdin for training!" << std::endl;
643
- exit(EXIT_FAILURE);
630
+ throw std::runtime_error("Cannot use stdin for training!");
644
631
  }
645
632
  std::ifstream ifs(args_->input);
646
633
  if (!ifs.is_open()) {
647
- std::cerr << "Input file cannot be opened!" << std::endl;
648
- exit(EXIT_FAILURE);
634
+ throw std::runtime_error("Input file cannot be opened!");
649
635
  }
650
636
  dict_->readFromFile(ifs);
651
637
  ifs.close();
@@ -8,6 +8,7 @@
8
8
 
9
9
  #include "real.h"
10
10
  #include "fasttext.h"
11
+ #include "curlstream.h"
11
12
 
12
13
  #ifdef __cplusplus
13
14
  #define EXTERN_C extern "C"
@@ -20,9 +21,27 @@
20
21
  #endif
21
22
 
22
23
  EXTERN_C_BEGIN
23
- fasttext::FastText* create(const char* model_name) {
24
+ fasttext::FastText* create(const char* model_filename) {
24
25
  fasttext::FastText* new_fasttext = new fasttext::FastText();
25
- new_fasttext->loadModel(std::string(model_name));
26
+ try {
27
+ new_fasttext->loadModel(model_filename);
28
+ } catch(std::exception&) {
29
+ delete new_fasttext;
30
+ return nullptr;
31
+ }
32
+
33
+ return new_fasttext;
34
+ }
35
+
36
+ fasttext::FastText* create_from_url(const char* model_url) {
37
+ fasttext::FastText* new_fasttext = new fasttext::FastText();
38
+ try {
39
+ CurlStream curlstream{model_url};
40
+ new_fasttext->loadModel(curlstream);
41
+ } catch(std::exception&) {
42
+ delete new_fasttext;
43
+ return nullptr;
44
+ }
26
45
 
27
46
  return new_fasttext;
28
47
  }
metadata CHANGED
@@ -1,85 +1,85 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ffi-fasttext
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brandon Dewitt
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-06-28 00:00:00.000000000 Z
11
+ date: 2020-07-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: ffi
15
14
  requirement: !ruby/object:Gem::Requirement
16
15
  requirements:
17
16
  - - ">="
18
17
  - !ruby/object:Gem::Version
19
18
  version: '0'
20
- type: :runtime
19
+ name: ffi
21
20
  prerelease: false
21
+ type: :runtime
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: pry
29
28
  requirement: !ruby/object:Gem::Requirement
30
29
  requirements:
31
30
  - - ">="
32
31
  - !ruby/object:Gem::Version
33
32
  version: '0'
34
- type: :development
33
+ name: pry
35
34
  prerelease: false
35
+ type: :development
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: bundler
43
42
  requirement: !ruby/object:Gem::Requirement
44
43
  requirements:
45
- - - "~>"
44
+ - - ">="
46
45
  - !ruby/object:Gem::Version
47
- version: '1.16'
48
- type: :development
46
+ version: '0'
47
+ name: bundler
49
48
  prerelease: false
49
+ type: :development
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '1.16'
54
+ version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: rake
57
56
  requirement: !ruby/object:Gem::Requirement
58
57
  requirements:
59
- - - "~>"
58
+ - - ">="
60
59
  - !ruby/object:Gem::Version
61
- version: '10.0'
62
- type: :development
60
+ version: '0'
61
+ name: rake
63
62
  prerelease: false
63
+ type: :development
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - "~>"
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: '10.0'
68
+ version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: minitest
71
70
  requirement: !ruby/object:Gem::Requirement
72
71
  requirements:
73
- - - "~>"
72
+ - - ">="
74
73
  - !ruby/object:Gem::Version
75
- version: '5.0'
76
- type: :development
74
+ version: '0'
75
+ name: minitest
77
76
  prerelease: false
77
+ type: :development
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - "~>"
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
- version: '5.0'
82
+ version: '0'
83
83
  description: " FFI bindings for Facebook's FastText text classification library "
84
84
  email:
85
85
  - brandonsdewitt+rubygems@gmail.com
@@ -104,6 +104,8 @@ files:
104
104
  - vendor/fasttext/PATENTS
105
105
  - vendor/fasttext/args.cc
106
106
  - vendor/fasttext/args.h
107
+ - vendor/fasttext/curlstream.cc
108
+ - vendor/fasttext/curlstream.h
107
109
  - vendor/fasttext/dictionary.cc
108
110
  - vendor/fasttext/dictionary.h
109
111
  - vendor/fasttext/fasttext.cc
@@ -128,7 +130,7 @@ licenses:
128
130
  - MIT
129
131
  metadata:
130
132
  allowed_push_host: https://rubygems.org
131
- post_install_message:
133
+ post_install_message:
132
134
  rdoc_options: []
133
135
  require_paths:
134
136
  - lib
@@ -143,9 +145,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
143
145
  - !ruby/object:Gem::Version
144
146
  version: '0'
145
147
  requirements: []
146
- rubyforge_project:
147
- rubygems_version: 2.6.13
148
- signing_key:
148
+ rubyforge_project:
149
+ rubygems_version: 2.6.14.1
150
+ signing_key:
149
151
  specification_version: 4
150
152
  summary: FFI bindings for Facebook's FastText text classification library
151
153
  test_files: []