musicbeeipc 2.0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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