musicbeeipc 2.0.0.1

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,282 @@
1
+ #----------------------------------------------------------#
2
+ #- MusicBeeIPCSDK Rb v2.0.0 -#
3
+ #- Copyright © Kerli Low 2014 -#
4
+ #- This file is licensed under the -#
5
+ #- BSD 2-Clause License -#
6
+ #- See LICENSE_MusicBeeIPCSDK for more information. -#
7
+ #----------------------------------------------------------#
8
+
9
+ require_relative "constants.rb"
10
+ require_relative "structs.rb"
11
+
12
+
13
+ class MusicBeeIPC
14
+ private
15
+
16
+ # ----------------------------------------------------------------------------
17
+ # All strings are encoded in UTF-16 little endian
18
+ # ----------------------------------------------------------------------------
19
+
20
+ # -Int32: 32 bit integer
21
+ # -Int32: 32 bit integer
22
+ # -...
23
+ def pack_i(*int32s)
24
+ cds = COPYDATASTRUCT.new
25
+ cds[:dwData] = 0
26
+
27
+ num = int32s.length
28
+
29
+ cds[:cbData] = MBIPC_SIZEOFINT * num
30
+
31
+ data = int32s.pack("l" + num.to_s)
32
+
33
+ cds[:lpData] = FFI::MemoryPointer.from_string(data)
34
+
35
+ return cds.to_ptr.address
36
+ end
37
+
38
+ # -Int32: Byte count of string
39
+ # -byte[]: String data
40
+ # -Int32: Byte count of string
41
+ # -byte[]: String data
42
+ # -...
43
+ def pack_s(*strings)
44
+ cds = COPYDATASTRUCT.new
45
+ cds[:dwData] = 0
46
+
47
+ num = strings.length
48
+
49
+ cds[:cbData] = MBIPC_SIZEOFINT * num
50
+
51
+ encoded = strings.map do |s|
52
+ e = s.encode("UTF-16LE").force_encoding("BINARY")
53
+ cds[:cbData] += e.length
54
+ e
55
+ end
56
+
57
+ data = ""
58
+ encoded.each { |e| data += [e.length].pack("l") + e }
59
+
60
+ cds[:lpData] = FFI::MemoryPointer.from_string(data)
61
+
62
+ return cds.to_ptr.address
63
+ end
64
+
65
+ # -Int32: Byte count of string
66
+ # -byte[]: String data
67
+ # -Int32: 32 bit integer
68
+ # -Int32: 32 bit integer
69
+ # -...
70
+ def pack_si(string_1, *int32s)
71
+ cds = COPYDATASTRUCT.new
72
+ cds[:dwData] = 0
73
+
74
+ encoded = string_1.encode("UTF-16LE").force_encoding("BINARY")
75
+ byte_count = encoded.length
76
+
77
+ num = int32s.length
78
+
79
+ cds[:cbData] = MBIPC_SIZEOFINT * (num + 1) + byte_count
80
+
81
+ data = [byte_count].pack("l") + encoded +
82
+ int32s.pack("l" + int32s.length.to_s)
83
+
84
+ cds[:lpData] = FFI::MemoryPointer.from_string(data)
85
+
86
+ return cds.to_ptr.address
87
+ end
88
+
89
+ # -Int32: Byte count of string
90
+ # -byte[]: String data
91
+ # -Int32: bool
92
+ # -Int32: bool
93
+ # -...
94
+ def pack_sb(string_1, *bools)
95
+ cds = COPYDATASTRUCT.new
96
+ cds[:dwData] = 0
97
+
98
+ encoded = string_1.encode("UTF-16LE").force_encoding("BINARY")
99
+ byte_count = encoded.length
100
+
101
+ bools_i = bools.map { |b| b ? 1 : 0 }
102
+
103
+ num = bools_i.length
104
+
105
+ cds[:cbData] = MBIPC_SIZEOFINT * (num + 1) + byte_count
106
+
107
+ data = [byte_count].pack("l") + encoded +
108
+ bools_i.pack("l" + bools_i.length.to_s)
109
+
110
+ cds[:lpData] = FFI::MemoryPointer.from_string(data)
111
+
112
+ return cds.to_ptr.address
113
+ end
114
+
115
+ # -Int32: Byte count of string
116
+ # -byte[]: String data
117
+ # -double: 64-bit floating-point value
118
+ # -double: 64-bit floating-point value
119
+ # -...
120
+ def pack_sd(string_1, *doubles)
121
+ cds = COPYDATASTRUCT.new
122
+ cds[:dwData] = 0
123
+
124
+ encoded = string_1.encode("UTF-16LE").force_encoding("BINARY")
125
+ byte_count = encoded.length
126
+
127
+ num = doubles.length
128
+
129
+ cds[:cbData] = MBIPC_SIZEOFDOUBLE * num + MBIPC_SIZEOFINT + byte_count
130
+
131
+ data = [byte_count].pack("l") + encoded +
132
+ doubles.pack("d" + doubles.length.to_s)
133
+
134
+ cds[:lpData] = FFI::MemoryPointer.from_string(data)
135
+
136
+ return cds.to_ptr.address
137
+ end
138
+
139
+ # -Int32: Byte count of string
140
+ # -byte[]: String data
141
+ # -Int32: Number of strings in string array
142
+ # -Int32: Byte count of string in string array
143
+ # -byte[]: String data in string array
144
+ # -Int32: Byte count of string in string array
145
+ # -byte[]: String data in string array
146
+ # -...
147
+ def pack_ssa(string_1, strings)
148
+ cds = COPYDATASTRUCT.new
149
+ cds[:dwData] = 0
150
+
151
+ encoded_1 = string_1.encode("UTF-16LE").force_encoding("BINARY")
152
+ byte_count_1 = encoded_1.length
153
+
154
+ num = strings.length
155
+
156
+ cds[:cbData] = MBIPC_SIZEOFINT * (num + 2) + byte_count_1
157
+
158
+ encoded = strings.map do |s|
159
+ e = s.encode("UTF-16LE").force_encoding("BINARY")
160
+ cds[:cbData] += e.length
161
+ e
162
+ end
163
+
164
+ data = [byte_count_1].pack("l") + encoded_1 + [num].pack("l")
165
+ encoded.each { |e| data += [e.length].pack("l") + e }
166
+
167
+ cds[:lpData] = FFI::MemoryPointer.from_string(data)
168
+
169
+ return cds.to_ptr.address
170
+ end
171
+
172
+ # -Int32: Byte count of string
173
+ # -byte[]: String data
174
+ # -Int32: Byte count of string
175
+ # -byte[]: String data
176
+ # -Int32: Number of strings in string array
177
+ # -Int32: Byte count of string in string array
178
+ # -byte[]: String data in string array
179
+ # -Int32: Byte count of string in string array
180
+ # -byte[]: String data in string array
181
+ # -...
182
+ def pack_sssa(string_1, string_2, strings)
183
+ cds = COPYDATASTRUCT.new
184
+ cds[:dwData] = 0
185
+
186
+ encoded_1 = string_1.encode("UTF-16LE").force_encoding("BINARY")
187
+ byte_count_1 = encoded_1.length
188
+
189
+ encoded_2 = string_2.encode("UTF-16LE").force_encoding("BINARY")
190
+ byte_count_2 = encoded_2.length
191
+
192
+ num = strings.length
193
+
194
+ cds[:cbData] = MBIPC_SIZEOFINT * (num + 3) + byte_count_1 + byte_count_2
195
+
196
+ encoded = strings.map do |s|
197
+ e = s.encode("UTF-16LE").force_encoding("BINARY")
198
+ cds[:cbData] += e.length
199
+ e
200
+ end
201
+
202
+ data = [byte_count_1].pack("l") + encoded_1 +
203
+ [byte_count_2].pack("l") + encoded_2 + [num].pack("l")
204
+ encoded.each { |e| data += [e.length].pack("l") + e }
205
+
206
+ cds[:lpData] = FFI::MemoryPointer.from_string(data)
207
+
208
+ return cds.to_ptr.address
209
+ end
210
+
211
+ # -Int32: Byte count of string
212
+ # -byte[]: String data
213
+ # -Int32: 32 bit integer
214
+ # -Int32: Byte count of string
215
+ # -byte[]: String data
216
+ # -...
217
+ def pack_sis(string_1, int32_1, string_2)
218
+ cds = COPYDATASTRUCT.new
219
+ cds[:dwData] = 0
220
+
221
+ encoded_1 = string_1.encode("UTF-16LE").force_encoding("BINARY")
222
+ byte_count_1 = encoded_1.length
223
+
224
+ encoded_2 = string_2.encode("UTF-16LE").force_encoding("BINARY")
225
+ byte_count_2 = encoded_2.length
226
+
227
+ cds[:cbData] = MBIPC_SIZEOFINT * 3 + byte_count_1 + byte_count_2
228
+
229
+ data = [byte_count_1].pack("l") + encoded_1 +
230
+ [int32_1, byte_count_2].pack("ll") + encoded_2
231
+
232
+ cds[:lpData] = FFI::MemoryPointer.from_string(data)
233
+
234
+ return cds.to_ptr.address
235
+ end
236
+
237
+ # -Int32: Number of integers in integer array
238
+ # -Int32: 32 bit integer
239
+ # -Int32: 32 bit integer
240
+ # -...
241
+ # -Int32: 32 bit integer
242
+ def pack_iai(int32s, int32_1)
243
+ cds = COPYDATASTRUCT.new
244
+ cds[:dwData] = 0
245
+
246
+ num = int32s.length
247
+
248
+ cds[:cbData] = MBIPC_SIZEOFINT * (num + 2)
249
+
250
+ data = ([num] + int32s + [int32_1]).pack("l" + (num + 2).to_s)
251
+
252
+ cds[:lpData] = FFI::MemoryPointer.from_string(data)
253
+
254
+ return cds.to_ptr.address
255
+ end
256
+
257
+ # -Int32: Byte count of string
258
+ # -byte[]: String data
259
+ # -Int32: Number of integers in integer array
260
+ # -Int32: 32 bit integer
261
+ # -Int32: 32 bit integer
262
+ # -...
263
+ # -Int32: 32 bit integer
264
+ def pack_siai(string_1, int32s, int32_1)
265
+ cds = COPYDATASTRUCT.new
266
+ cds[:dwData] = 0
267
+
268
+ encoded = string_1.encode("UTF-16LE").force_encoding("BINARY")
269
+ byte_count = encoded.length
270
+
271
+ num = int32s.length
272
+
273
+ cds[:cbData] = MBIPC_SIZEOFINT * (num + 3) + byte_count
274
+
275
+ data = [byte_count].pack("l") + encoded +
276
+ ([num] + int32s + [int32_1]).pack("l" + (num + 2).to_s)
277
+
278
+ cds[:lpData] = FFI::MemoryPointer.from_string(data)
279
+
280
+ return cds.to_ptr.address
281
+ end
282
+ end
@@ -0,0 +1,40 @@
1
+ #----------------------------------------------------------#
2
+ #- MusicBeeIPCSDK Rb v2.0.0 -#
3
+ #- Copyright © Kerli Low 2014 -#
4
+ #- This file is licensed under the -#
5
+ #- BSD 2-Clause License -#
6
+ #- See LICENSE_MusicBeeIPCSDK for more information. -#
7
+ #----------------------------------------------------------#
8
+
9
+ require "ffi"
10
+
11
+
12
+ class FloatInt < FFI::Union
13
+ layout :f, :float,
14
+ :i, :int
15
+
16
+ def initialize(opts={}, *args)
17
+ self[:f] = opts[:f] if opts[:f]
18
+ self[:i] = opts[:i] if opts[:i]
19
+ super(*args)
20
+ end
21
+ end
22
+
23
+
24
+ class LRUShort < FFI::Union
25
+ layout :lr, :long,
26
+ :low, :ushort,
27
+ :high, :ushort, 2
28
+
29
+ def initialize(lr=0, *args)
30
+ self[:lr] = lr
31
+ super(*args)
32
+ end
33
+ end
34
+
35
+
36
+ class COPYDATASTRUCT < FFI::Struct
37
+ layout :dwData, :pointer,
38
+ :cbData, :uint32,
39
+ :lpData, :pointer
40
+ end
@@ -0,0 +1,204 @@
1
+ #----------------------------------------------------------#
2
+ #- MusicBeeIPCSDK Rb v2.0.0 -#
3
+ #- Copyright © Kerli Low 2014 -#
4
+ #- This file is licensed under the -#
5
+ #- BSD 2-Clause License -#
6
+ #- See LICENSE_MusicBeeIPCSDK for more information. -#
7
+ #----------------------------------------------------------#
8
+
9
+ require_relative "constants.rb"
10
+ require_relative "structs.rb"
11
+
12
+
13
+ class MusicBeeIPC
14
+ private
15
+
16
+ # ----------------------------------------------------------------------------
17
+ # All strings are encoded in UTF-16 little endian
18
+ # ----------------------------------------------------------------------------
19
+
20
+ # -Int32: Byte count of the string
21
+ # -byte[]: String data
22
+ # Free lr after use
23
+ #
24
+ # @return [String]
25
+ def unpack_s(lr)
26
+ string_1 = ""
27
+
28
+ begin
29
+ mmf = open_mmf(lr)
30
+ raise "Failed to open MMF." if !mmf
31
+
32
+ view, ptr = map_mmf_view(mmf, lr)
33
+ raise "Failed to map MMF view." if !view
34
+ rescue
35
+ return ""
36
+ ensure
37
+ close_mmf(mmf) if mmf
38
+ end
39
+
40
+ begin
41
+ byte_count = ptr.read_string(MBIPC_SIZEOFINT).unpack("l")[0]
42
+ ptr += MBIPC_SIZEOFINT
43
+
44
+ if byte_count > 0
45
+ string_1 = ptr.read_string(byte_count).force_encoding("UTF-16LE").
46
+ encode(__ENCODING__)
47
+ end
48
+ rescue
49
+ return ""
50
+ ensure
51
+ unmap_mmf_view(view)
52
+ close_mmf(mmf)
53
+ end
54
+
55
+ return string_1
56
+ end
57
+
58
+ # -Int32: Number of strings
59
+ # -Int32: Byte count of 1st string
60
+ # -byte[]: 1st string data
61
+ # -Int32: Byte count of 2nd string
62
+ # -byte[]: 2nd string data
63
+ # -...
64
+ # Free lr after use
65
+ #
66
+ # @return [Array<String>]
67
+ def unpack_sa(lr)
68
+ begin
69
+ mmf = open_mmf(lr)
70
+ raise "Failed to open MMF." if !mmf
71
+
72
+ view, ptr = map_mmf_view(mmf, lr)
73
+ raise "Failed to map MMF view." if !view
74
+ rescue
75
+ return []
76
+ ensure
77
+ close_mmf(mmf) if mmf
78
+ end
79
+
80
+ begin
81
+ str_count = ptr.read_string(MBIPC_SIZEOFINT).unpack("l")[0]
82
+ ptr += MBIPC_SIZEOFINT
83
+
84
+ strings = Array.new(str_count)
85
+
86
+ strings.map! do |s|
87
+ byte_count = ptr.read_string(MBIPC_SIZEOFINT).unpack("l")[0]
88
+ ptr += MBIPC_SIZEOFINT
89
+
90
+ if byte_count > 0
91
+ s = ptr.read_string(byte_count).force_encoding("UTF-16LE").
92
+ encode(__ENCODING__)
93
+ ptr += byte_count
94
+ s
95
+ end
96
+ end
97
+ rescue
98
+ return []
99
+ ensure
100
+ unmap_mmf_view(view)
101
+ close_mmf(mmf)
102
+ end
103
+
104
+ return strings
105
+ end
106
+
107
+ # -Int32: 1st 32 bit integer
108
+ # -Int32: 2nd 32 bit integer
109
+ # Free lr after use
110
+ #
111
+ # @return [Array<int>]
112
+ def unpack_ii(lr)
113
+ begin
114
+ mmf = open_mmf(lr)
115
+ raise "Failed to open MMF." if !mmf
116
+
117
+ view, ptr = map_mmf_view(mmf, lr)
118
+ raise "Failed to map MMF view." if !view
119
+ rescue
120
+ return [-1, -1]
121
+ ensure
122
+ close_mmf(mmf) if mmf
123
+ end
124
+
125
+ begin
126
+ ints = ptr.read_string(MBIPC_SIZEOFINT * 2).unpack("ll")
127
+ rescue
128
+ return [-1, -1]
129
+ ensure
130
+ unmap_mmf_view(view)
131
+ close_mmf(mmf)
132
+ end
133
+
134
+ return ints
135
+ end
136
+
137
+ # -Int32: Number of integers
138
+ # -Int32: 1st 32 bit integer
139
+ # -Int32: 2nd 32 bit integer
140
+ # -...
141
+ # Free lr after use
142
+ #
143
+ # @return [Array<int>]
144
+ def unpack_ia(lr)
145
+ begin
146
+ mmf = open_mmf(lr)
147
+ raise "Failed to open MMF." if !mmf
148
+
149
+ view, ptr = map_mmf_view(mmf, lr)
150
+ raise "Failed to map MMF view." if !view
151
+ rescue
152
+ return []
153
+ ensure
154
+ close_mmf(mmf) if mmf
155
+ end
156
+
157
+ begin
158
+ int_count = ptr.read_string(MBIPC_SIZEOFINT).unpack("l")[0]
159
+ ptr += MBIPC_SIZEOFINT
160
+
161
+ ints = ptr.read_string(MBIPC_SIZEOFINT * int_count).
162
+ unpack("l" + int_count.to_s)
163
+ rescue
164
+ return []
165
+ ensure
166
+ unmap_mmf_view(view)
167
+ close_mmf(mmf)
168
+ end
169
+
170
+ return ints
171
+ end
172
+
173
+
174
+ def open_mmf(lr)
175
+ return nil if !lr || lr == 0
176
+
177
+ ls = LRUShort.new(lr)
178
+
179
+ name = ("mbipc_mmf_" + ls[:low].to_s + "\0").encode("UTF-16LE")
180
+
181
+ # FILE_MAP_READ = 0x0004 = 4
182
+ # FALSE = 0
183
+ open_file_mapping(4, 0, name)
184
+ end
185
+
186
+ def close_mmf(mmf)
187
+ close_handle(mmf)
188
+ end
189
+
190
+ def map_mmf_view(mmf, lr)
191
+ ls = LRUShort.new(lr)
192
+
193
+ # FILE_MAP_READ = 0x0004 = 4
194
+ view = map_view_of_file(mmf, 4, 0, 0, 0)
195
+
196
+ ptr = FFI::Pointer.new(:char, view + ls[:high] + MBIPC_SIZEOFLONG)
197
+
198
+ return [view, ptr]
199
+ end
200
+
201
+ def unmap_mmf_view(view)
202
+ unmap_view_of_file(view)
203
+ end
204
+ end