tsparser 0.0.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.
@@ -0,0 +1,202 @@
1
+ # -*- coding: utf-8 -*-
2
+ module TSparser
3
+ class Binary < ::String
4
+
5
+ class BinaryException < StandardError; end
6
+
7
+ def self.from_int(*integers)
8
+ return new(integers.pack("C*"))
9
+ end
10
+
11
+ # "byte_string" is string encoded as ASCII_8BIT (BINARY).
12
+ def initialize(byte_string=nil)
13
+ byte_string ||= "".encode(Encoding::ASCII_8BIT)
14
+ if byte_string.encoding != Encoding::ASCII_8BIT
15
+ raise BinaryException.new("byte_string's encoding should be ASCII_8BIT(BINARY) " +
16
+ "(this is #{byte_string.encoding})")
17
+ end
18
+ super(byte_string)
19
+ end
20
+
21
+ # Return Integer that is converted from bits specified by "bit_range" (arg2) in
22
+ # byte specified by "byte_index" (arg1).
23
+ #
24
+ # *Warning*: Bit index is from right to left. So, LSB's position is 0, MSB's is 7
25
+ def b(byte_index, bit_range=nil)
26
+ byte_num = self[byte_index].unpack("C")[0]
27
+ return byte_num unless bit_range
28
+ return sub_integer(byte_num, bit_range)
29
+ end
30
+
31
+ # Get sub-bit of specified integer.
32
+ # == Example:
33
+ # binary = Binary.new(something_byte_string)
34
+ # binary.sub_integer(0b11111100, 1..2) # => 2 (0b10)
35
+ #
36
+ def sub_integer(integer, bit_range)
37
+ bit_range = bit_range..bit_range if bit_range.kind_of?(Integer)
38
+ num = 0
39
+ bit_range.reverse_each do |i|
40
+ num = num << 1
41
+ num += integer[i]
42
+ end
43
+ return num
44
+ end
45
+
46
+ # Return Integer that is converted from Byte at specified position.
47
+ def to_i(byte_position)
48
+ return self[byte_position].unpack("C")[0]
49
+ end
50
+
51
+ # Comparator to Integer
52
+ def <=>(integer)
53
+ return super unless integer.is_a?(Integer)
54
+ unless self.length == 1
55
+ raise BinaryException.new("Can't compare non-single byte with integer.")
56
+ end
57
+ return self.to_i(0) <=> integer
58
+ end
59
+
60
+ # Generate new Binary instance that is subsequence of self (from specified position to end).
61
+ def from(start_position)
62
+ unless start_position < self.length
63
+ raise BinaryException.new("starting point must should be less than length")
64
+ end
65
+ return self[start_position, self.length - start_position]
66
+ end
67
+
68
+ # Generate new Binary instance that is joined from "self", "arg1", "arg2", ... (in order).
69
+ def join(*binaries)
70
+ return binaries.inject(self) do |combined, binary|
71
+ Binary.new(combined + binary)
72
+ end
73
+ end
74
+
75
+ def &(byte_integer)
76
+ if byte_integer < 0x00 || byte_integer > 0xFF
77
+ raise BinaryException.new("Can't apply operator& with integer #{byte_integer}.")
78
+ end
79
+ if self.length != 1
80
+ raise BinaryException.new("Can't apply operator& on bytes #{self}.")
81
+ end
82
+ return Binary.from_int(self.to_i(0) & byte_integer)
83
+ end
84
+
85
+ def dump
86
+ bytes = []
87
+ each_byte do |byte|
88
+ bytes << sprintf("%02X", byte)
89
+ end
90
+ return bytes.join(" ")
91
+ end
92
+
93
+ # ----------------------------------------------------------------
94
+ # :section: Read methods
95
+ # These methods have access pointer similar to IO#read.
96
+ # ----------------------------------------------------------------
97
+
98
+ # Read specified length of bits and return as Integer instance.
99
+ # Bit pointer proceed for that length.
100
+ def read_bit_as_integer(bitlen)
101
+ if self.length * 8 - bit_pointer < bitlen
102
+ raise BinaryException.new("Rest of self length(#{self.length * 8 - bit_pointer}bit) "+
103
+ "is shorter than specified bit length(#{bitlen}bit).")
104
+ end
105
+ if bit_pointer % 8 == 0 && bitlen % 8 == 0
106
+ return read_byte_as_integer(bitlen/8)
107
+ else
108
+ response = 0
109
+ bitlen.times do
110
+ response = response << 1
111
+ response += read_one_bit
112
+ end
113
+ return response
114
+ end
115
+ end
116
+
117
+ # Read specified length of bytes and return as Integer instance.
118
+ # Bit pointer proceed for that length.
119
+ def read_byte_as_integer(bytelen)
120
+ unless bit_pointer % 8 == 0
121
+ raise BinaryException.new("Bit pointer must be pointing start of byte. " +
122
+ "But now pointing #{bit_pointer}.")
123
+ end
124
+ if self.length - bit_pointer/8 < bytelen
125
+ raise BinaryException.new("Rest of self length(#{self.length - bit_pointer/8}byte) " +
126
+ "is shorter than specified byte length(#{bytelen}byte).")
127
+ end
128
+ response = 0
129
+ bytelen.times do |i|
130
+ response = response << 8
131
+ response += to_i(bit_pointer/8 + i)
132
+ end
133
+ bit_pointer_inc(bytelen * 8)
134
+ return response
135
+ end
136
+
137
+ # Read one bit and return as 0 or 1.
138
+ # Bit pointer proceed for one.
139
+ def read_one_bit
140
+ unless self.length * 8 - bit_pointer > 0
141
+ raise BinaryException.new("Readable buffer doesn't exist" +
142
+ "(#{self.length * 8 - bit_pointer}bit exists).")
143
+ end
144
+ response = to_i(bit_pointer/8)[7 - bit_pointer%8]
145
+ bit_pointer_inc(1)
146
+ return response
147
+ end
148
+
149
+ # Read specified length of bits and return as Binary instance.
150
+ # Bit pointer proceed for that length.
151
+ #
152
+ # *Warning*: "bitlen" must be integer of multiple of 8, and bit pointer must be pointing
153
+ # start of byte.
154
+ def read_bit_as_binary(bitlen)
155
+ unless bit_pointer % 8 == 0
156
+ raise BinaryException.new("Bit pointer must be pointing start of byte. " +
157
+ "But now pointing #{bit_pointer}.")
158
+ end
159
+ unless bitlen % 8 == 0
160
+ raise BinaryException.new("Arg must be integer of multiple of 8. " +
161
+ "But you specified #{bitlen}.")
162
+ end
163
+ if self.length - bit_pointer/8 < bitlen/8
164
+ raise BinaryException.new("Rest of self length(#{self.length - bit_pointer/8}byte)" +
165
+ " is shorter than specified byte length(#{bitlen/8}byte).")
166
+ end
167
+ response = self[bit_pointer/8, bitlen/8]
168
+ bit_pointer_inc(bitlen)
169
+ return response
170
+ end
171
+
172
+ def read_byte_as_binary(bytelen)
173
+ return read_bit_as_binary(bytelen*8)
174
+ end
175
+
176
+ def last_read_byte
177
+ return Binary.new(self[bit_pointer-1])
178
+ end
179
+
180
+ # Return whether bit pointer reached end or not (true/false).
181
+ def readable?
182
+ return bit_pointer < self.length * 8
183
+ end
184
+
185
+ # Return length of rest readable bit
186
+ def rest_readable_bit_length
187
+ return self.length * 8 - bit_pointer
188
+ end
189
+
190
+ def bit_pointer
191
+ @bit_pointer ||= 0
192
+ return @bit_pointer
193
+ end
194
+
195
+ private
196
+
197
+ def bit_pointer_inc(n)
198
+ @bit_pointer ||= 0
199
+ @bit_pointer += n
200
+ end
201
+ end
202
+ end
@@ -0,0 +1,19 @@
1
+ # -*- coding: utf-8 -*-
2
+ module TSparser
3
+ class AribDuration
4
+
5
+ def initialize(binary)
6
+ @hour = binary.read_bit_as_integer(4) * 10 + binary.read_bit_as_integer(4)
7
+ @min = binary.read_bit_as_integer(4) * 10 + binary.read_bit_as_integer(4)
8
+ @sec = binary.read_bit_as_integer(4) * 10 + binary.read_bit_as_integer(4)
9
+ end
10
+
11
+ def to_s
12
+ return sprintf("%2d:%2d:%2", @hour, @min, @sec)
13
+ end
14
+
15
+ def to_sec
16
+ return @hour * 3600 + @min * 60 + @sec
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,327 @@
1
+ # -*- coding: utf-8 -*-
2
+ module TSparser
3
+
4
+ # ARIB String class.
5
+ # This is following ARIB STD-B24, 2-7
6
+ class AribString
7
+ include AribStringDecoder
8
+
9
+ def initialize(binary)
10
+ @binary = binary
11
+ end
12
+
13
+ def to_utf_8
14
+ return @utf_8_string ||= decode(@binary)
15
+ end
16
+
17
+ # ------------------------------------------------------------
18
+ # Define default setting.
19
+ # This is following definition of ARIB STD-B24, 2-7 Table8-2.
20
+ # Note: G3 in group_map seems to be KATAKANA although this is defined to be MACRO on Table8-2.
21
+ # ------------------------------------------------------------
22
+
23
+ def_default_group_map do
24
+ {
25
+ :G0 => :KANJI,
26
+ :G1 => :ALPHABET,
27
+ :G2 => :HIRAGANA,
28
+ :G3 => :KATAKANA
29
+ }
30
+ end
31
+
32
+ def_default_region_map do
33
+ {
34
+ :GL => :G0,
35
+ :GR => :G2
36
+ }
37
+ end
38
+
39
+ # ------------------------------------------------------------
40
+ # Define C0 and C1 control code.
41
+ # This is following definition of ARIB STD-B24, 2-7 Table7-14.
42
+ # ------------------------------------------------------------
43
+
44
+ def_control_code(:C0) do
45
+ set :NUL, 0x00, :nothing
46
+ set :BEL, 0x07, :putstr, "[BEL]"
47
+ set :APB, 0x08, :putstr, "[APB]"
48
+ set :APF, 0x09, :putstr, " "
49
+ set :APD, 0x0A, :putstr, "\n"
50
+ set :APU, 0x0B, :putstr, "APU"
51
+ set :CS, 0x0C, :putstr, "[CLS]"
52
+ set :APR, 0x0D, :putstr, "\n"
53
+ set :PAPF, 0x16, :exec, 1, Proc.new{|p1| putstr("[PAPF:#{p1}")}
54
+ set :CAN, 0x18, :putstr, "[CAN]"
55
+ set :APS, 0x1C, :exec, 2, Proc.new{|p1, p2| putstr("[APS:#{p1}-#{p2}")}
56
+ set :RS, 0x1E, :nothing
57
+ set :US, 0x1F, :nothing
58
+ set :SP, 0x20, :putstr, " "
59
+ end
60
+
61
+ def_control_code(:C1) do
62
+ set :DEL, 0x7F, :nothing
63
+ set :BKF, 0x80, :putstr, "[BKF]"
64
+ set :RDF, 0x81, :putstr, "[RDF]"
65
+ set :GRF, 0x82, :putstr, "[GRF]"
66
+ set :YLF, 0x83, :putstr, "[YLF]"
67
+ set :BLF, 0x84, :putstr, "[BLF]"
68
+ set :MGF, 0x85, :putstr, "[MGF]"
69
+ set :CNF, 0x86, :putstr, "[CNF]"
70
+ set :WHF, 0x87, :putstr, "[WHF]"
71
+ set :SSZ, 0x88, :putstr, "[SSZ]"
72
+ set :MSZ, 0x89, :putstr, "[MSZ]"
73
+ set :NSZ, 0x8A, :putstr, "[NSZ]"
74
+ set :SZX, 0x8B, :exec, 1, Proc.new{|p1| putstr("[SZX:#{p1}]")}
75
+ set :COL, 0x90, :exec, 1, Proc.new{|p1| putstr(p1 == 0x20 ? "[COL:#{p1}-#{read_one}]" : "[COL:#{p1}]")}
76
+ set :FLC, 0x91, :exec, 1, Proc.new{|p1| putstr("[FLC:#{p1}]")}
77
+ set :CDC, 0x92, :exec, 1, Proc.new{|p1| putstr(p1 == 0x20 ? "[CDC:#{p1}-#{read_one}]" : "[CDC:#{p1}]")}
78
+ set :POL, 0x93, :exec, 1, Proc.new{|p1| putstr("[POL:#{p1}")}
79
+ set :WMM, 0x94, :putstr, "[WMM]"
80
+ set :MACRO, 0x95, :exec, 1, Proc.new{|p1|
81
+ mc = read_one
82
+ mc_bytes = []
83
+ mc_bytes << byte until (byte = read_one) == 0x95
84
+ putstr("[MACRO:#{p1}][MC:#{mc}-#{mc_bytes.join(" ")}][MACRO:#{read_one}]")
85
+ }
86
+ set :HLC, 0x97, :exec, 1, Proc.new{|p1| putstr("[HLC:#{p1}]")}
87
+ set :RPC, 0x98, :exec, 1, Proc.new{|p1| putstr("[RPC:#{p1}]")}
88
+ set :SPL, 0x99, :putstr, "[SPL]"
89
+ set :STL, 0x9A, :putstr, "[STL]"
90
+ set :CSI, 0x9B, :putstr, "[CSI]"
91
+ set :TIME, 0x9D, :exec, 2, Proc.new{|p1, p2| putstr("[TIME:#{p1}-#{p2}")}
92
+ set :SP2, 0xA0, :putstr, " "
93
+ set :DEL2, 0xFF, :nothing
94
+ end
95
+
96
+ # ------------------------------------------------------------
97
+ # Define code-call.
98
+ # This is following definition of ARIB STD-B24, 2-7 Table7-1.
99
+ # ------------------------------------------------------------
100
+
101
+ def_code_call do
102
+ set :LS0, [0x0F], :G0, :GL, :locking
103
+ set :LS1, [0x0E], :G1, :GL, :locking
104
+ set :LS2, [ESC, 0x6E], :G2, :GL, :locking
105
+ set :LS3, [ESC, 0x6F], :G3, :GL, :locking
106
+ set :LS1R, [ESC, 0x7E], :G1, :GR, :locking
107
+ set :LS2R, [ESC, 0x7D], :G2, :GR, :locking
108
+ set :LS3R, [ESC, 0x7C], :G3, :GR, :locking
109
+ set :SS2, [0x19], :G2, :GL, :single
110
+ set :SS3, [0x1D], :G3, :GL, :single
111
+ end
112
+
113
+
114
+ # ------------------------------------------------------------
115
+ # Define code-operation.
116
+ # This is following definition of ARIB STD-B24, 2-7 Table7-2.
117
+ # ------------------------------------------------------------
118
+
119
+ def_code_operation do
120
+ set [ESC, 0x28, :F], :G_SET, :G0
121
+ set [ESC, 0x29, :F], :G_SET, :G1
122
+ set [ESC, 0x2A, :F], :G_SET, :G2
123
+ set [ESC, 0x2B, :F], :G_SET, :G3
124
+
125
+ set [ESC, 0x24, :F], :G_SET, :G0
126
+ set [ESC, 0x24, 0x29, :F], :G_SET, :G1
127
+ set [ESC, 0x24, 0x2A, :F], :G_SET, :G2
128
+ set [ESC, 0x24, 0x2B, :F], :G_SET, :G3
129
+
130
+ set [ESC, 0x28, 0x20, :F], :DRCS, :G0
131
+ set [ESC, 0x29, 0x20, :F], :DRCS, :G1
132
+ set [ESC, 0x2A, 0x20, :F], :DRCS, :G2
133
+ set [ESC, 0x2B, 0x20, :F], :DRCS, :G3
134
+
135
+ set [ESC, 0x24, 0x28, 0x20, :F], :DRCS, :G0
136
+ set [ESC, 0x24, 0x29, 0x20, :F], :DRCS, :G1
137
+ set [ESC, 0x24, 0x2A, 0x20, :F], :DRCS, :G2
138
+ set [ESC, 0x24, 0x2B, 0x20, :F], :DRCS, :G3
139
+ end
140
+
141
+
142
+ # ------------------------------------------------------------
143
+ # Define code-set.
144
+ # This is following definition of ARIB STD-B24, 2-7 Table7-3.
145
+ # ------------------------------------------------------------
146
+
147
+ def_code_set(:G_SET) do
148
+ set :KANJI, 0x42, 2
149
+ set :ALPHABET, 0x4A, 1
150
+ set :HIRAGANA, 0x30, 1
151
+ set :KATAKANA, 0x31, 1
152
+ set :MOSAIC_A, 0x32, 1
153
+ set :MOSAIC_B, 0x33, 1
154
+ set :MOSAIC_C, 0x34, 1
155
+ set :MOSAIC_D, 0x35, 1
156
+ set :PROPORTIONAL_ALPHABET, 0x36, 1
157
+ set :PROPORTIONAL_HIRAGANA, 0x37, 1
158
+ set :PROPORTIONAL_KATAKANA, 0x38, 1
159
+ set :JIS_X0201_KATAKANA, 0x49, 1
160
+ set :JIS_KANJI_1, 0x39, 2
161
+ set :JIS_KANJI_2, 0x3A, 2
162
+ set :ADDITIONAL_SYMBOL, 0x3B, 2
163
+ end
164
+
165
+ def_code_set(:DRCS) do
166
+ set :DRCS_0, 0x40, 2
167
+ set :DRCS_1, 0x41, 1
168
+ set :DRCS_2, 0x42, 1
169
+ set :DRCS_3, 0x43, 1
170
+ set :DRCS_4, 0x44, 1
171
+ set :DRCS_5, 0x45, 1
172
+ set :DRCS_6, 0x46, 1
173
+ set :DRCS_7, 0x47, 1
174
+ set :DRCS_8, 0x48, 1
175
+ set :DRCS_9, 0x49, 1
176
+ set :DRCS_10, 0x4A, 1
177
+ set :DRCS_11, 0x4B, 1
178
+ set :DRCS_12, 0x4C, 1
179
+ set :DRCS_13, 0x4D, 1
180
+ set :DRCS_14, 0x4E, 1
181
+ set :DRCS_15, 0x4F, 1
182
+ set :MACRO, 0x70, 1
183
+ end
184
+
185
+
186
+ # ------------------------------------------------------------
187
+ # Define code.
188
+ # This is following definition of ARIB STD-B24, 2-7
189
+ # ------------------------------------------------------------
190
+
191
+ def_code(2, :KANJI) do |byte1, byte2|
192
+ output_jis_zenkaku(byte1, byte2)
193
+ end
194
+
195
+ def_code(1, :ALPHABET) do |byte|
196
+ output_jis_ascii(byte)
197
+ end
198
+
199
+ def_code(1, :HIRAGANA) do |byte|
200
+ if byte >= 0x77 && alter_byte = HIRAGANA_ARIB_MAP[byte.to_i(0)]
201
+ output_jis_zenkaku(0x21, alter_byte)
202
+ else
203
+ output_jis_zenkaku(0x24, byte)
204
+ end
205
+ end
206
+
207
+ def_code(1, :KATAKANA) do |byte|
208
+ if byte >= 0x77 && alter_byte = KATAKANA_ARIB_MAP[byte.to_i(0)]
209
+ output_jis_zenkaku(0x21, alter_byte)
210
+ else
211
+ output_jis_zenkaku(0x25, byte)
212
+ end
213
+ end
214
+
215
+ def_code(1, :MOSAIC_A, :MOSAIC_B, :MOSAIC_C, :MOSAIC_D) do
216
+ output_str("??")
217
+ end
218
+
219
+ def_code(1, :PROPORTIONAL_ALPHABET) do |byte|
220
+ assign :ALPHABET, byte
221
+ end
222
+
223
+ def_code(1, :PROPORTIONAL_HIRAGANA) do |byte|
224
+ assign :HIRAGANA, byte
225
+ end
226
+
227
+ def_code(1, :PROPORTIONAL_KATAKANA) do |byte|
228
+ assign :KATAKANA, byte
229
+ end
230
+
231
+ def_code(1, :JIS_X0201_KATAKANA) do |byte|
232
+ output_jis_hankaku(byte)
233
+ end
234
+
235
+ def_code(2, :JIS_KANJI_1, :JIS_KANJI_2) do |byte1, byte2|
236
+ assign :KANJI, byte1, byte2
237
+ end
238
+
239
+ def_code(2, :ADDITIONAL_SYMBOL) do |*bytes|
240
+ if alter_str = ADDITIONAL_SYMBOL_MAP[bytes.map{|b| b.to_i(0)}]
241
+ output_str(alter_str)
242
+ else
243
+ output_str("[unknown: 0x#{bytes[0].dump}, 0x#{bytes[1].dump}]")
244
+ end
245
+ end
246
+
247
+ def_code(2, :DRCS_0) do
248
+ output_str("??")
249
+ end
250
+
251
+ def_code(1, :DRCS_1, :DRCS_2, :DRCS_3, :DRCS_4, :DRCS_5, :DRCS_6, :DRCS_7, :DRCS_8,
252
+ :DRCS_9, :DRCS_10, :DRCS_11, :DRCS_12, :DRCS_13, :DRCS_14, :DRCS_15, :MACRO) do
253
+ output_str("??")
254
+ end
255
+
256
+ # ------------------------------------------------------------
257
+ # Define mapping.
258
+ # ------------------------------------------------------------
259
+
260
+ def_mapping(:HIRAGANA_ARIB_MAP) do
261
+ {
262
+ 0x77 => 0x35,
263
+ 0x78 => 0x36,
264
+ 0x79 => 0x3C,
265
+ 0x7A => 0x23,
266
+ 0x7B => 0x56,
267
+ 0x7C => 0x57,
268
+ 0x7D => 0x22,
269
+ 0x7E => 0x26
270
+ }
271
+ end
272
+
273
+ def_mapping(:KATAKANA_ARIB_MAP) do
274
+ {
275
+ 0x77 => 0x33,
276
+ 0x78 => 0x34,
277
+ 0x79 => 0x3C,
278
+ 0x7A => 0x23,
279
+ 0x7B => 0x56,
280
+ 0x7C => 0x57,
281
+ 0x7D => 0x22,
282
+ 0x7E => 0x26
283
+ }
284
+ end
285
+
286
+ def_mapping(:ADDITIONAL_SYMBOL_MAP) do
287
+ {
288
+ [0x7A, 0x50] => "【HV】",
289
+ [0x7a, 0x51] => "【SD】",
290
+ [0x7a, 0x52] => "【P】",
291
+ [0x7a, 0x53] => "【W】",
292
+ [0x7a, 0x54] => "【MV】",
293
+ [0x7a, 0x55] => "【手】",
294
+ [0x7a, 0x56] => "【字】",
295
+ [0x7a, 0x57] => "【双】",
296
+ [0x7a, 0x58] => "【デ】",
297
+ [0x7a, 0x59] => "【S】",
298
+ [0x7a, 0x5A] => "【二】",
299
+ [0x7a, 0x5B] => "【多】",
300
+ [0x7a, 0x5C] => "【解】",
301
+ [0x7a, 0x5D] => "【SS】",
302
+ [0x7a, 0x5E] => "【B】",
303
+ [0x7a, 0x5F] => "【N】",
304
+ [0x7a, 0x60] => "■",
305
+ [0x7a, 0x61] => "●",
306
+ [0x7a, 0x62] => "【天】",
307
+ [0x7a, 0x63] => "【交】",
308
+ [0x7a, 0x64] => "【映】",
309
+ [0x7a, 0x65] => "【無】",
310
+ [0x7a, 0x66] => "【料】",
311
+ [0x7a, 0x67] => "【鍵】",
312
+ [0x7a, 0x68] => "【前】",
313
+ [0x7a, 0x69] => "【後】",
314
+ [0x7a, 0x6A] => "【再】",
315
+ [0x7a, 0x6B] => "【新】",
316
+ [0x7a, 0x6C] => "【初】",
317
+ [0x7a, 0x6D] => "【終】",
318
+ [0x7a, 0x6E] => "【生】",
319
+ [0x7a, 0x6F] => "【販】",
320
+ [0x7a, 0x70] => "【声】",
321
+ [0x7a, 0x71] => "【吹】",
322
+ [0x7a, 0x72] => "【PPV】",
323
+ }
324
+ end
325
+ end
326
+ end
327
+