jansson 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c598ba8c9095b975416770702210cf3b4a9ff2e8
4
+ data.tar.gz: caae966170fd3e8bb687bd3760360a6b5b7e907f
5
+ SHA512:
6
+ metadata.gz: 87dd4fc546d63a84193bbb4ec0640764dd17cbffc5f3daa34c75907fd62808e99ad9425e81d5e08ae0a313cf77ec59e916fd1d2c507ef618cfc207813dd8e16e
7
+ data.tar.gz: 94016e54878b8d3eaae2c683a5c9c0551876e81d341a0def49ea18586a7c228ca24e6b6e1e4356f22b6e0d5b5d9cb248a7e7e5af973fad6002b26db3d2152964
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Joe McIlvain
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,9 @@
1
+ # jansson
2
+
3
+ [![Build Status](https://circleci.com/gh/jemc/ruby-jansson/tree/master.svg?style=svg)](https://circleci.com/gh/jemc/ruby-jansson/tree/master) 
4
+ [![Gem Version](https://badge.fury.io/rb/jansson.png)](http://badge.fury.io/rb/jansson) 
5
+ [![Join the chat at https://gitter.im/jemc/ruby-jansson](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/jemc/ruby-jansson?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
6
+
7
+ A Ruby JSON library based on [FFI](https://github.com/ffi/ffi/wiki) bindings for [libjansson](https://github.com/akheron/jansson).
8
+
9
+ ##### `$ gem install jansson`
@@ -0,0 +1,47 @@
1
+
2
+ require 'rake/clean'
3
+ require 'ffi'
4
+
5
+ FILES = {}
6
+
7
+ task :default => :build
8
+
9
+ def self.file_task(filename, opts, &block)
10
+ name, dep = opts.is_a?(Hash) ? opts.to_a.first : [opts, nil]
11
+
12
+ FILES[name] = filename
13
+ CLEAN.include filename
14
+ task name => filename
15
+
16
+ if dep
17
+ file filename => FILES[dep], &block
18
+ else
19
+ file filename, &block
20
+ end
21
+ end
22
+
23
+ def cmd(string)
24
+ fail "Command failed: #{string}" unless system(string)
25
+ end
26
+
27
+ file_task 'jansson.tar.gz', :download_tarball do
28
+ version = "2.7"
29
+ release = "https://github.com/akheron/jansson/archive/v#{version}.tar.gz"
30
+ cmd "wget #{release}"
31
+ cmd "mv #{File.basename(release)} #{FILES[:download_tarball]}"
32
+ end
33
+
34
+ file_task 'jansson', :download => :download_tarball do
35
+ cmd "tar -xf #{FILES[:download_tarball]}"
36
+ cmd "mv jansson-* #{FILES[:download]}"
37
+ end
38
+
39
+ file_task 'config.status', :configure => :download do
40
+ cmd "bash -c 'cd #{FILES[:download]} && autoreconf -fi && ./configure'"
41
+ cmd "cp #{FILES[:download]}/#{FILES[:configure]} ./"
42
+ end
43
+
44
+ file_task "libjansson.#{::FFI::Platform::LIBSUFFIX}", :build => :configure do
45
+ cmd "bash -c 'cd #{FILES[:download]} && make'"
46
+ cmd "cp #{FILES[:download]}/src/.libs/#{FILES[:build]} ."
47
+ end
@@ -0,0 +1,32 @@
1
+
2
+ require_relative 'jansson/ffi'
3
+ require_relative 'jansson/ffi/ext'
4
+
5
+ module Jansson
6
+ class DumpError < RuntimeError; end
7
+
8
+ def self.dump(value)
9
+ res = Jansson::FFI::Entity.from(value)
10
+ raise Jansson::DumpError, "can't encode #{value}" unless res
11
+ string = res.to_s
12
+ res.free!
13
+ string
14
+ end
15
+
16
+ class LoadError < RuntimeError; end
17
+
18
+ def self.load(string)
19
+ res = Jansson::FFI::Entity.from_s(string)
20
+ case res
21
+ when Jansson::FFI::Entity
22
+ value = res.to_ruby
23
+ res.free!
24
+ value
25
+ when Jansson::FFI::Error
26
+ raise Jansson::LoadError, res.description(string)
27
+ else
28
+ raise Jansson::LoadError
29
+ end
30
+ end
31
+
32
+ end
@@ -0,0 +1,169 @@
1
+
2
+ require 'ffi'
3
+
4
+
5
+ module Jansson
6
+
7
+ # Bindings and wrappers for the native functions and structures exposed by
8
+ # the libjansson C library. This module is for internal use only so that
9
+ # all dependencies on the implementation of the C library are abstracted.
10
+ # @api private
11
+ module FFI
12
+ extend ::FFI::Library
13
+
14
+ libfile = "libjansson.#{::FFI::Platform::LIBSUFFIX}"
15
+
16
+ ffi_lib ::FFI::Library::LIBC
17
+ ffi_lib \
18
+ File.expand_path("../../ext/jansson/#{libfile}", File.dirname(__FILE__))
19
+
20
+ opts = {
21
+ blocking: true # only necessary on MRI to deal with the GIL.
22
+ }
23
+
24
+ attach_function :free, [:pointer], :void, **opts
25
+ attach_function :malloc, [:size_t], :pointer, **opts
26
+
27
+ EntityType = enum [
28
+ :object,
29
+ :array,
30
+ :string,
31
+ :integer,
32
+ :real,
33
+ :true,
34
+ :false,
35
+ :null,
36
+ ]
37
+
38
+ class Entity < ::FFI::Struct
39
+ layout :type, EntityType,
40
+ :refcount, :size_t
41
+ end
42
+
43
+ INTEGER_IS_LONG_LONG = true
44
+ typedef (INTEGER_IS_LONG_LONG ? :long_long : :long), :json_int
45
+
46
+ ##
47
+ # Construction, destruction, reference counting
48
+
49
+ attach_function :json_object, [], Entity.ptr, **opts
50
+ attach_function :json_array, [], Entity.ptr, **opts
51
+ attach_function :json_string, [:string], Entity.ptr, **opts
52
+ attach_function :json_stringn, [:string, :size_t], Entity.ptr, **opts
53
+ attach_function :json_string_nocheck, [:string], Entity.ptr, **opts
54
+ attach_function :json_stringn_nocheck, [:string, :size_t], Entity.ptr, **opts
55
+ attach_function :json_integer, [:json_int], Entity.ptr, **opts
56
+ attach_function :json_real, [:double], Entity.ptr, **opts
57
+ attach_function :json_true, [], Entity.ptr, **opts
58
+ attach_function :json_false, [], Entity.ptr, **opts
59
+ attach_function :json_null, [], Entity.ptr, **opts
60
+
61
+ attach_function :json_delete, [Entity.ptr], :void, **opts
62
+
63
+ ##
64
+ # Error reporting
65
+
66
+ ERROR_SOURCE_LENGTH = 160
67
+ ERROR_TEXT_LENGTH = 80
68
+
69
+ class Error < ::FFI::Struct
70
+ layout :line, :int,
71
+ :column, :int,
72
+ :position, :int,
73
+ :source, [:char, ERROR_SOURCE_LENGTH],
74
+ :text, [:char, ERROR_TEXT_LENGTH]
75
+ end
76
+
77
+ ##
78
+ # Getters, setters, manipulation
79
+
80
+ attach_function :json_object_seed, [:size_t], :void, **opts
81
+ attach_function :json_object_size, [Entity.ptr], :size_t, **opts
82
+ attach_function :json_object_get, [Entity.ptr, :string], Entity.ptr, **opts
83
+ attach_function :json_object_set_new, [Entity.ptr, :string, Entity.ptr], :int, **opts
84
+ attach_function :json_object_set_new_nocheck, [Entity.ptr, :string, Entity.ptr], :int, **opts
85
+ attach_function :json_object_del, [Entity.ptr, :string], :int, **opts
86
+ attach_function :json_object_clear, [Entity.ptr], :int, **opts
87
+ attach_function :json_object_update, [Entity.ptr, Entity.ptr], :int, **opts
88
+ attach_function :json_object_update_existing, [Entity.ptr, Entity.ptr], :int, **opts
89
+ attach_function :json_object_update_missing, [Entity.ptr, Entity.ptr], :int, **opts
90
+ attach_function :json_object_iter, [Entity.ptr], :pointer, **opts
91
+ attach_function :json_object_iter_at, [Entity.ptr, :string], :pointer, **opts
92
+ attach_function :json_object_key_to_iter, [:string], :pointer, **opts
93
+ attach_function :json_object_iter_next, [Entity.ptr, :pointer], :pointer, **opts
94
+ attach_function :json_object_iter_key, [:pointer], :string, **opts
95
+ attach_function :json_object_iter_value, [:pointer], Entity.ptr, **opts
96
+ attach_function :json_object_iter_set_new, [Entity.ptr, :pointer, Entity.ptr], :int, **opts
97
+
98
+ attach_function :json_array_size, [Entity.ptr], :size_t, **opts
99
+ attach_function :json_array_get, [Entity.ptr, :size_t], Entity.ptr, **opts
100
+ attach_function :json_array_set_new, [Entity.ptr, :size_t, Entity.ptr], :int, **opts
101
+ attach_function :json_array_append_new, [Entity.ptr, Entity.ptr], :int, **opts
102
+ attach_function :json_array_insert_new, [Entity.ptr, :size_t, Entity.ptr], :int, **opts
103
+ attach_function :json_array_remove, [Entity.ptr, :size_t], :int, **opts
104
+ attach_function :json_array_clear, [Entity.ptr], :int, **opts
105
+ attach_function :json_array_extend, [Entity.ptr, Entity.ptr], :int, **opts
106
+
107
+ attach_function :json_string_value, [Entity.ptr], :pointer, **opts
108
+ attach_function :json_string_length, [Entity.ptr], :size_t, **opts
109
+ attach_function :json_integer_value, [Entity.ptr], :json_int, **opts
110
+ attach_function :json_real_value, [Entity.ptr], :double, **opts
111
+ attach_function :json_number_value, [Entity.ptr], :double, **opts
112
+
113
+ attach_function :json_string_set, [Entity.ptr, :string], :int, **opts
114
+ attach_function :json_string_setn, [Entity.ptr, :pointer, :size_t], :int, **opts
115
+ attach_function :json_string_set_nocheck, [Entity.ptr, :string], :int, **opts
116
+ attach_function :json_string_setn_nocheck, [Entity.ptr, :pointer, :size_t], :int, **opts
117
+ attach_function :json_integer_set, [Entity.ptr, :json_int], :int, **opts
118
+ attach_function :json_real_set, [Entity.ptr, :double], :int, **opts
119
+
120
+ ##
121
+ # Pack, unpack
122
+
123
+ PACK_VALIDATE_ONLY = 0x1
124
+ PACK_STRICT = 0x2
125
+
126
+ attach_function :json_pack, [:string, :varargs], Entity.ptr, **opts
127
+ attach_function :json_pack_ex, [Error.ptr, :size_t, :string, :varargs], Entity.ptr, **opts
128
+
129
+ attach_function :json_unpack, [Entity.ptr, :string, :varargs], :int, **opts
130
+ attach_function :json_unpack_ex, [Entity.ptr, Error.ptr, :size_t, :string, :varargs], :int, **opts
131
+
132
+ ##
133
+ # Equality
134
+
135
+ attach_function :json_equal, [Entity.ptr, Entity.ptr], :int
136
+
137
+ ##
138
+ # Copying
139
+
140
+ attach_function :json_copy, [Entity.ptr], Entity.ptr
141
+ attach_function :json_deep_copy, [Entity.ptr], Entity.ptr
142
+
143
+ ##
144
+ # Decoding
145
+
146
+ LOAD_REJECT_DUPLICATES = 0x1
147
+ LOAD_DISABLE_EOF_CHECK = 0x2
148
+ LOAD_DECODE_ANY = 0x4
149
+ LOAD_DECODE_INT_AS_REAL = 0x8
150
+ LOAD_ALLOW_NUL = 0x10
151
+
152
+ attach_function :json_loads, [:string, :size_t, Error.ptr], Entity.ptr
153
+
154
+ ##
155
+ # Encoding
156
+
157
+ def self.DUMP_INDENT(n) n & 0x1F end
158
+ DUMP_COMPACT = 0x20
159
+ DUMP_ENSURE_ASCII = 0x40
160
+ DUMP_SORT_KEYS = 0x80
161
+ DUMP_PRESERVE_ORDER = 0x100
162
+ DUMP_ENCODE_ANY = 0x200
163
+ DUMP_ESCAPE_SLASH = 0x400
164
+ def self.DUMP_REAL_PRECISION(n) (n & 0x1F) << 11 end
165
+
166
+ attach_function :json_dumps, [Entity.ptr, :size_t], :pointer
167
+
168
+ end
169
+ end
@@ -0,0 +1,3 @@
1
+
2
+ require_relative 'ext/entity'
3
+ require_relative 'ext/error'
@@ -0,0 +1,93 @@
1
+
2
+ module Jansson
3
+ module FFI
4
+ class Entity
5
+
6
+ def free!
7
+ FFI.json_delete(self) if 0 >= (self[:refcount] -= 1)
8
+ end
9
+
10
+ def to_s(flags = DUMP_ENCODE_ANY | DUMP_PRESERVE_ORDER)
11
+ ptr = FFI.json_dumps(self, flags)
12
+ str = ptr.read_string
13
+ FFI.free(ptr)
14
+ str
15
+ end
16
+
17
+ def self.from_s(string, flags = LOAD_DECODE_ANY | LOAD_ALLOW_NUL)
18
+ error = FFI::Error.new
19
+ entity = FFI.json_loads(string, flags, error)
20
+ entity.pointer.null? ? error : entity
21
+ end
22
+
23
+ def type
24
+ self[:type]
25
+ end
26
+
27
+ def to_ruby
28
+ case type
29
+ when :null
30
+ nil
31
+ when :true
32
+ true
33
+ when :false
34
+ false
35
+ when :integer
36
+ FFI.json_integer_value(self)
37
+ when :real
38
+ FFI.json_real_value(self)
39
+ when :string
40
+ FFI.json_string_value(self).read_string(FFI.json_string_length(self))
41
+ when :array
42
+ FFI.json_array_size(self).times.map do |index|
43
+ FFI.json_array_get(self, index).to_ruby
44
+ end
45
+ when :object
46
+ object = {}
47
+ iter = FFI.json_object_iter(self)
48
+ while (key = FFI.json_object_iter_key(iter)) && \
49
+ (value = FFI.json_object_iter_value(iter))
50
+ object[key] = value.to_ruby
51
+ iter = FFI.json_object_iter_next(self, iter)
52
+ end
53
+ object
54
+ else raise NotImplementedError
55
+ end
56
+ end
57
+
58
+ def self.from(value)
59
+ case value
60
+ when NilClass
61
+ FFI.json_null
62
+ when TrueClass
63
+ FFI.json_true
64
+ when FalseClass
65
+ FFI.json_false
66
+ when Integer
67
+ FFI.json_integer(value)
68
+ when Float
69
+ FFI.json_real(value)
70
+ when String
71
+ value = value.force_encoding(Encoding::UTF_8)
72
+ FFI.json_stringn_nocheck(value, value.bytesize)
73
+ when Symbol
74
+ value = value.to_s.force_encoding(Encoding::UTF_8)
75
+ FFI.json_stringn_nocheck(value, value.bytesize)
76
+ when Array
77
+ array = FFI.json_array
78
+ value.each do |item|
79
+ FFI.json_array_append_new(array, from(item))
80
+ end
81
+ array
82
+ when Hash
83
+ object = FFI.json_object
84
+ value.each do |key, value|
85
+ FFI.json_object_set_new(object, key.to_s, from(value))
86
+ end
87
+ object
88
+ end
89
+ end
90
+
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,29 @@
1
+
2
+ module Jansson
3
+ module FFI
4
+ class Error
5
+
6
+ def description(source_string)
7
+ row = self[:line]
8
+ col = self[:column]
9
+ msg = self[:text].to_s
10
+
11
+ source = source_string.each_line.to_a[row - 1].strip
12
+ arrow = ' ' * (col - 1) + '^'
13
+
14
+ if source.length > 40
15
+ if col >= 20
16
+ source = '... ' + source.slice(col - 20, 40) + ' ...'
17
+ arrow = ' ' + arrow .slice(col - 20, 40)
18
+ else
19
+ source = source.slice(0, 40) + ' ...'
20
+ arrow = arrow .slice(0, 40)
21
+ end
22
+ end
23
+
24
+ "near line: #{row}, column: #{col}: #{msg}\n#{source}\n#{arrow}"
25
+ end
26
+
27
+ end
28
+ end
29
+ end
metadata ADDED
@@ -0,0 +1,156 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jansson
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Joe McIlvain
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-07-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ type: :runtime
15
+ name: ffi
16
+ prerelease: false
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - "~>"
20
+ - !ruby/object:Gem::Version
21
+ version: '1.9'
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: 1.9.8
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '1.9'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 1.9.8
33
+ - !ruby/object:Gem::Dependency
34
+ type: :development
35
+ name: bundler
36
+ prerelease: false
37
+ requirement: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '1.6'
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '1.6'
47
+ - !ruby/object:Gem::Dependency
48
+ type: :development
49
+ name: rake
50
+ prerelease: false
51
+ requirement: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '10.3'
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '10.3'
61
+ - !ruby/object:Gem::Dependency
62
+ type: :development
63
+ name: pry
64
+ prerelease: false
65
+ requirement: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '0.9'
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '0.9'
75
+ - !ruby/object:Gem::Dependency
76
+ type: :development
77
+ name: rspec
78
+ prerelease: false
79
+ requirement: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: '3.0'
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '3.0'
89
+ - !ruby/object:Gem::Dependency
90
+ type: :development
91
+ name: rspec-its
92
+ prerelease: false
93
+ requirement: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: '1.0'
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '1.0'
103
+ - !ruby/object:Gem::Dependency
104
+ type: :development
105
+ name: fivemat
106
+ prerelease: false
107
+ requirement: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - "~>"
110
+ - !ruby/object:Gem::Version
111
+ version: '1.3'
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: '1.3'
117
+ description: A Ruby JSON library based on FFI bindings for libjansson.
118
+ email: joe.eli.mac@gmail.com
119
+ executables: []
120
+ extensions:
121
+ - ext/jansson/Rakefile
122
+ extra_rdoc_files: []
123
+ files:
124
+ - LICENSE
125
+ - README.md
126
+ - ext/jansson/Rakefile
127
+ - lib/jansson.rb
128
+ - lib/jansson/ffi.rb
129
+ - lib/jansson/ffi/ext.rb
130
+ - lib/jansson/ffi/ext/entity.rb
131
+ - lib/jansson/ffi/ext/error.rb
132
+ homepage: https://github.com/jemc/ruby-jansson
133
+ licenses:
134
+ - MIT
135
+ metadata: {}
136
+ post_install_message:
137
+ rdoc_options: []
138
+ require_paths:
139
+ - lib
140
+ required_ruby_version: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ required_rubygems_version: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - ">="
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ requirements: []
151
+ rubyforge_project:
152
+ rubygems_version: 2.4.8
153
+ signing_key:
154
+ specification_version: 4
155
+ summary: jansson
156
+ test_files: []