python-pickle 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog.md +12 -0
  3. data/README.md +2 -1
  4. data/lib/python/pickle/deserializer.rb +142 -80
  5. data/lib/python/pickle/instructions/bin_persid.rb +31 -0
  6. data/lib/python/pickle/instructions/global.rb +11 -41
  7. data/lib/python/pickle/instructions/has_namespace_and_name.rb +61 -0
  8. data/lib/python/pickle/instructions/inst.rb +34 -0
  9. data/lib/python/pickle/instructions/next_buffer.rb +5 -1
  10. data/lib/python/pickle/instructions/obj.rb +30 -0
  11. data/lib/python/pickle/instructions/persid.rb +31 -0
  12. data/lib/python/pickle/instructions/readonly_buffer.rb +4 -0
  13. data/lib/python/pickle/instructions.rb +64 -0
  14. data/lib/python/pickle/protocol0.rb +313 -68
  15. data/lib/python/pickle/protocol1.rb +225 -93
  16. data/lib/python/pickle/protocol2.rb +205 -124
  17. data/lib/python/pickle/protocol3.rb +92 -123
  18. data/lib/python/pickle/protocol4.rb +188 -165
  19. data/lib/python/pickle/protocol5.rb +98 -166
  20. data/lib/python/pickle/version.rb +1 -1
  21. data/lib/python/pickle.rb +38 -32
  22. data/spec/deserializer_spec.rb +308 -0
  23. data/spec/fixtures/set_v0.pkl +11 -0
  24. data/spec/fixtures/set_v1.pkl +0 -0
  25. data/spec/fixtures/set_v2.pkl +0 -0
  26. data/spec/fixtures/set_v3.pkl +0 -0
  27. data/spec/fixtures/set_v4.pkl +0 -0
  28. data/spec/fixtures/set_v5.pkl +0 -0
  29. data/spec/generate_pickles2.py +1 -0
  30. data/spec/generate_pickles3.py +1 -0
  31. data/spec/integration/load/protocol0_spec.rb +10 -0
  32. data/spec/integration/load/protocol1_spec.rb +10 -0
  33. data/spec/integration/load/protocol2_spec.rb +10 -0
  34. data/spec/integration/load/protocol3_spec.rb +10 -0
  35. data/spec/integration/load/protocol4_spec.rb +10 -0
  36. data/spec/integration/load/protocol5_spec.rb +10 -0
  37. data/spec/protocol0_read_instruction_examples.rb +44 -0
  38. metadata +14 -2
@@ -33,22 +33,96 @@ module Python
33
33
  #
34
34
  class Protocol1 < Protocol0
35
35
 
36
- # Opcodes for Pickle protocol version 1.
37
- #
38
- # @see https://github.com/python/cpython/blob/main/Lib/pickletools.py
39
- OPCODES = Protocol0::OPCODES + Set[
40
- 41, # EMPTY_TUPLE
41
- 71, # BINFLOAT
42
- 75, # BININT1
43
- 84, # BINSTRING
44
- 85, # SHORT_BINSTRING
45
- 88, # BINUNICODE
46
- 93, # EMPTY_LIST
47
- 101, # APPENDS
48
- 113, # BINPUT
49
- 117, # SETITEMS
50
- 125 # EMPTY_DICT
51
- ]
36
+ # The `EMPTY_TUPLE` opcode.
37
+ #
38
+ # @since 0.2.0
39
+ #
40
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L140
41
+ EMPTY_TUPLE = 41
42
+
43
+ # The `BINFLOAT` opcode.
44
+ #
45
+ # @since 0.2.0
46
+ #
47
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L142
48
+ BINFLOAT = 71
49
+
50
+ # The `BININT1` opcode.
51
+ #
52
+ # @since 0.2.0
53
+ #
54
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L110
55
+ BININT1 = 75
56
+
57
+ # The `BINSTRING` opcode.
58
+ #
59
+ # @since 0.2.0
60
+ #
61
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L118
62
+ BINSTRING = 84
63
+
64
+ # The `SHORT_BINSTRING` opcode.
65
+ #
66
+ # @since 0.2.0
67
+ #
68
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L119
69
+ SHORT_BINSTRING = 85
70
+
71
+ # The `BINUNICODE` opcode.
72
+ #
73
+ # @since 0.2.0
74
+ #
75
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L121
76
+ BINUNICODE = 88
77
+
78
+ # The `EMPTY_LIST` opcode.
79
+ #
80
+ # @since 0.2.0
81
+ #
82
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L133
83
+ EMPTY_LIST = 93
84
+
85
+ # The `APPENDS` opcode.
86
+ #
87
+ # @since 0.2.0
88
+ #
89
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L127
90
+ APPENDS = 101
91
+
92
+ # The `BINGET` opcode.
93
+ #
94
+ # @since 0.2.0
95
+ #
96
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L138
97
+ BINGET = 104
98
+
99
+ # The `LONG_BINGET` opcode.
100
+ #
101
+ # @since 0.2.0
102
+ #
103
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L140
104
+ LONG_BINGET = 106
105
+
106
+ # The `BINPUT` opcode.
107
+ #
108
+ # @since 0.2.0
109
+ #
110
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L145
111
+ BINPUT = 113
112
+
113
+ # The `SETITEMS` opcode.
114
+ #
115
+ # @since 0.2.0
116
+ #
117
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L141
118
+ SETITEMS = 117
119
+
120
+ # The `EMPTY_DICT` opcode.
121
+ #
122
+ # @since 0.2.0
123
+ #
124
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L126
125
+ EMPTY_DICT = 125
52
126
 
53
127
  #
54
128
  # Reads an instruction from the pickle stream.
@@ -64,86 +138,47 @@ module Python
64
138
  #
65
139
  # Protocol 0 instructions
66
140
  #
67
- when 40 # MARK
68
- Instructions::MARK
69
- when 46 # STOP
70
- Instructions::STOP
71
- when 48 # POP
72
- Instructions::POP
73
- when 49 # POP_MARK
74
- Instructions::POP_MARK
75
- when 50 # DUP
76
- Instructions::DUP
77
- when 70 # FLOAT
78
- Instructions::Float.new(read_float)
79
- when 73 # INT
80
- Instructions::Int.new(read_int)
81
- when 76 # LONG
82
- Instructions::Long.new(read_long)
83
- when 78 # NONE
84
- Instructions::NONE
85
- when 82 # REDUCE
86
- Instructions::REDUCE
87
- when 83 # STRING
88
- Instructions::String.new(read_string)
89
- when 86 # UNICODE
90
- Instructions::String.new(read_unicode_string)
91
- when 97 # APPEND
92
- Instructions::APPEND
93
- when 98 # BUILD
94
- Instructions::BUILD
95
- when 99 # GLOBAL
96
- Instructions::Global.new(read_nl_string,read_nl_string)
97
- when 100 # DICT
98
- Instructions::DICT
99
- when 103 # GET
100
- Instructions::Get.new(read_int)
101
- when 108 # LIST
102
- Instructions::LIST
103
- when 112 # PUT
104
- Instructions::Put.new(read_int)
105
- when 115 # SETITEM
106
- Instructions::SETITEM
107
- when 116 # TUPLE
108
- Instructions::TUPLE
141
+ when MARK then Instructions::MARK
142
+ when STOP then Instructions::STOP
143
+ when POP then Instructions::POP
144
+ when POP_MARK then Instructions::POP_MARK
145
+ when DUP then Instructions::DUP
146
+ when FLOAT then read_float_instruction
147
+ when INT then read_int_instruction
148
+ when LONG then read_long_instruction
149
+ when NONE then Instructions::NONE
150
+ when REDUCE then Instructions::REDUCE
151
+ when STRING then read_string_instruction
152
+ when UNICODE then read_unicode_instruction
153
+ when APPEND then Instructions::APPEND
154
+ when BUILD then Instructions::BUILD
155
+ when GLOBAL then read_global_instruction
156
+ when DICT then Instructions::DICT
157
+ when GET then read_get_instruction
158
+ when LIST then Instructions::LIST
159
+ when PUT then read_put_instruction
160
+ when SETITEM then Instructions::SETITEM
161
+ when TUPLE then Instructions::TUPLE
162
+ when INST then read_inst_instruction
163
+ when OBJ then Instructions::OBJ
164
+ when PERSID then read_persid_instruction
165
+ when BINPERSID then Instructions::BINPERSID
109
166
  #
110
167
  # Protocol 1 instructions
111
168
  #
112
- when 41 # EMPTY_TUPLE
113
- Instructions::EMPTY_TUPLE
114
- when 71 # BINFLOAT
115
- Instructions::BinFloat.new(read_float64_be)
116
- when 75 # BININT1
117
- Instructions::BinInt1.new(read_uint8)
118
- when 84 # BINSTRING
119
- length = read_uint32_le
120
- string = @io.read(length)
121
-
122
- Instructions::BinString.new(length,string)
123
- when 85 # SHORT_BINSTRING
124
- length = read_uint8
125
- string = @io.read(length)
126
-
127
- Instructions::ShortBinString.new(length,string)
128
- when 88 # BINUNICODE
129
- length = read_uint32_le
130
- string = @io.read(length).force_encoding(Encoding::UTF_8)
131
-
132
- Instructions::BinUnicode.new(length,string)
133
- when 93 # EMPTY_LIST
134
- Instructions::EMPTY_LIST
135
- when 101 # APPENDS
136
- Instructions::APPENDS
137
- when 104 # BINGET
138
- Instructions::BinGet.new(read_uint8)
139
- when 106 # LONG_BINGET
140
- Instructions::LongBinGet.new(read_uint32_le)
141
- when 113 # BINPUT
142
- Instructions::BinPut.new(read_uint8)
143
- when 117 # SETITEMS
144
- Instructions::SETITEMS
145
- when 125 # EMPTY_DICT
146
- Instructions::EMPTY_DICT
169
+ when EMPTY_TUPLE then Instructions::EMPTY_TUPLE
170
+ when BINFLOAT then read_binfloat_instruction
171
+ when BININT1 then read_binint1_instruction
172
+ when BINSTRING then read_binstring_instruction
173
+ when SHORT_BINSTRING then read_short_binstring_instruction
174
+ when BINUNICODE then read_binunicode_instruction
175
+ when EMPTY_LIST then Instructions::EMPTY_LIST
176
+ when APPENDS then Instructions::APPENDS
177
+ when BINGET then read_binget_instruction
178
+ when LONG_BINGET then read_long_binget_instruction
179
+ when BINPUT then read_binput_instruction
180
+ when SETITEMS then Instructions::SETITEMS
181
+ when EMPTY_DICT then Instructions::EMPTY_DICT
147
182
  else
148
183
  raise(InvalidFormat,"invalid opcode (#{opcode.inspect}) for protocol 1")
149
184
  end
@@ -178,6 +213,103 @@ module Python
178
213
  @io.read(4).unpack1('L<')
179
214
  end
180
215
 
216
+ #
217
+ # Reads a `BINFLOAT` instruction.
218
+ #
219
+ # @return [Instructions::BinFloat]
220
+ #
221
+ # @since 0.2.0
222
+ #
223
+ def read_binfloat_instruction
224
+ Instructions::BinFloat.new(read_float64_be)
225
+ end
226
+
227
+ #
228
+ # Reads a `BININT1` instruction.
229
+ #
230
+ # @return [Instructions::BinInt1]
231
+ #
232
+ # @since 0.2.0
233
+ #
234
+ def read_binint1_instruction
235
+ Instructions::BinInt1.new(read_uint8)
236
+ end
237
+
238
+ #
239
+ # Reads a `BINSTRING` instruction.
240
+ #
241
+ # @return [Instructions::BinString]
242
+ #
243
+ # @since 0.2.0
244
+ #
245
+ def read_binstring_instruction
246
+ length = read_uint32_le
247
+ string = @io.read(length)
248
+
249
+ Instructions::BinString.new(length,string)
250
+ end
251
+
252
+ #
253
+ # Reads a `SHORT_BINSTRING` instruction.
254
+ #
255
+ # @return [Instructions::ShortBinString]
256
+ #
257
+ # @since 0.2.0
258
+ #
259
+ def read_short_binstring_instruction
260
+ length = read_uint8
261
+ string = @io.read(length)
262
+
263
+ Instructions::ShortBinString.new(length,string)
264
+ end
265
+
266
+ #
267
+ # Reads a `BINUNICODE` instruction.
268
+ #
269
+ # @return [Instructions::BinUnicode]
270
+ #
271
+ # @since 0.2.0
272
+ #
273
+ def read_binunicode_instruction
274
+ length = read_uint32_le
275
+ string = @io.read(length).force_encoding(Encoding::UTF_8)
276
+
277
+ Instructions::BinUnicode.new(length,string)
278
+ end
279
+
280
+ #
281
+ # Reads a `BINGET` instruction.
282
+ #
283
+ # @return [Instructions::BinGet]
284
+ #
285
+ # @since 0.2.0
286
+ #
287
+ def read_binget_instruction
288
+ Instructions::BinGet.new(read_uint8)
289
+ end
290
+
291
+ #
292
+ # Reads a `LONG_BINGET` instruction.
293
+ #
294
+ # @return [Instructions::LongBinGet]
295
+ #
296
+ # @since 0.2.0
297
+ #
298
+ def read_long_binget_instruction
299
+ Instructions::LongBinGet.new(read_uint32_le)
300
+ end
301
+
302
+ #
303
+ # Reads a `BINPUT` instruction.
304
+ #
305
+ # @return [Instructions::BinPut]
306
+ #
307
+ # @since 0.2.0
308
+ #
309
+ def read_binput_instruction
310
+ Instructions::BinPut.new(read_uint8)
311
+ end
312
+
181
313
  end
182
314
  end
183
315
  end
@@ -16,23 +16,89 @@ module Python
16
16
  module Pickle
17
17
  class Protocol2 < Protocol1
18
18
 
19
- # Opcodes for Pickle protocol version 2.
20
- #
21
- # @see https://github.com/python/cpython/blob/main/Lib/pickletools.py
22
- OPCODES = Protocol1::OPCODES + Set[
23
- 128, # PROTO
24
- 129, # NEWOBJ
25
- 130, # EXT1
26
- 131, # EXT2
27
- 132, # EXT4
28
- 133, # TUPLE1
29
- 134, # TUPLE2
30
- 135, # TUPLE3
31
- 136, # NEWTRUE
32
- 137, # NEWFALSE
33
- 138, # LONG1
34
- 139 # LONG4
35
- ]
19
+ # The `PROTO` opcode.
20
+ #
21
+ # @since 0.2.0
22
+ #
23
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L149
24
+ PROTO = 128
25
+
26
+ # The `NEWOBJ` opcode.
27
+ #
28
+ # @since 0.2.0
29
+ #
30
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L150
31
+ NEWOBJ = 129
32
+
33
+ # The `EXT1` opcode.
34
+ #
35
+ # @since 0.2.0
36
+ #
37
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L151
38
+ EXT1 = 130
39
+
40
+ # The `EXT2` opcode.
41
+ #
42
+ # @since 0.2.0
43
+ #
44
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L152
45
+ EXT2 = 131
46
+
47
+ # The `EXT4` opcode.
48
+ #
49
+ # @since 0.2.0
50
+ #
51
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L153
52
+ EXT4 = 132
53
+
54
+ # The `TUPLE1` opcode.
55
+ #
56
+ # @since 0.2.0
57
+ #
58
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L154
59
+ TUPLE1 = 133
60
+
61
+ # The `TUPLE2` opcode.
62
+ #
63
+ # @since 0.2.0
64
+ #
65
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L155
66
+ TUPLE2 = 134
67
+
68
+ # The `TUPLE3` opcode.
69
+ #
70
+ # @since 0.2.0
71
+ #
72
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L156
73
+ TUPLE3 = 135
74
+
75
+ # The `NEWTRUE` opcode.
76
+ #
77
+ # @since 0.2.0
78
+ #
79
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L157
80
+ NEWTRUE = 136
81
+
82
+ # The `NEWFALSE` opcode.
83
+ #
84
+ # @since 0.2.0
85
+ #
86
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L158
87
+ NEWFALSE = 137
88
+
89
+ # The `LONG1` opcode.
90
+ #
91
+ # @since 0.2.0
92
+ #
93
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L159
94
+ LONG1 = 138
95
+
96
+ # The `LONG4` opcode.
97
+ #
98
+ # @since 0.2.0
99
+ #
100
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L160
101
+ LONG4 = 139
36
102
 
37
103
  #
38
104
  # Reads an instruction from the pickle stream.
@@ -48,119 +114,62 @@ module Python
48
114
  #
49
115
  # Protocol 0 instructions
50
116
  #
51
- when 40 # MARK
52
- Instructions::MARK
53
- when 46 # STOP
54
- Instructions::STOP
55
- when 48 # POP
56
- Instructions::POP
57
- when 49 # POP_MARK
58
- Instructions::POP_MARK
59
- when 50 # DUP
60
- Instructions::DUP
61
- when 70 # FLOAT
62
- Instructions::Float.new(read_float)
63
- when 73 # INT
64
- Instructions::Int.new(read_int)
65
- when 76 # LONG
66
- Instructions::Long.new(read_long)
67
- when 78 # NONE
68
- Instructions::NONE
69
- when 82 # REDUCE
70
- Instructions::REDUCE
71
- when 83 # STRING
72
- Instructions::String.new(read_string)
73
- when 86 # UNICODE
74
- Instructions::String.new(read_unicode_string)
75
- when 97 # APPEND
76
- Instructions::APPEND
77
- when 98 # BUILD
78
- Instructions::BUILD
79
- when 99 # GLOBAL
80
- Instructions::Global.new(read_nl_string,read_nl_string)
81
- when 100 # DICT
82
- Instructions::DICT
83
- when 103 # GET
84
- Instructions::Get.new(read_int)
85
- when 108 # LIST
86
- Instructions::LIST
87
- when 112 # PUT
88
- Instructions::Put.new(read_int)
89
- when 115 # SETITEM
90
- Instructions::SETITEM
91
- when 116 # TUPLE
92
- Instructions::TUPLE
117
+ when MARK then Instructions::MARK
118
+ when STOP then Instructions::STOP
119
+ when POP then Instructions::POP
120
+ when POP_MARK then Instructions::POP_MARK
121
+ when DUP then Instructions::DUP
122
+ when FLOAT then read_float_instruction
123
+ when INT then read_int_instruction
124
+ when LONG then read_long_instruction
125
+ when NONE then Instructions::NONE
126
+ when REDUCE then Instructions::REDUCE
127
+ when STRING then read_string_instruction
128
+ when UNICODE then read_unicode_instruction
129
+ when APPEND then Instructions::APPEND
130
+ when BUILD then Instructions::BUILD
131
+ when GLOBAL then read_global_instruction
132
+ when DICT then Instructions::DICT
133
+ when GET then read_get_instruction
134
+ when LIST then Instructions::LIST
135
+ when PUT then read_put_instruction
136
+ when SETITEM then Instructions::SETITEM
137
+ when TUPLE then Instructions::TUPLE
138
+ when INST then read_inst_instruction
139
+ when OBJ then Instructions::OBJ
140
+ when PERSID then read_persid_instruction
141
+ when BINPERSID then Instructions::BINPERSID
93
142
  #
94
143
  # Protocol 1 instructions
95
144
  #
96
- when 41 # EMPTY_TUPLE
97
- Instructions::EMPTY_TUPLE
98
- when 71 # BINFLOAT
99
- Instructions::BinFloat.new(read_float64_be)
100
- when 75 # BININT1
101
- Instructions::BinInt1.new(read_uint8)
102
- when 84 # BINSTRING
103
- length = read_uint32_le
104
- string = @io.read(length)
105
-
106
- Instructions::BinString.new(length,string)
107
- when 85 # SHORT_BINSTRING
108
- length = read_uint8
109
- string = @io.read(length)
110
-
111
- Instructions::ShortBinString.new(length,string)
112
- when 88 # BINUNICODE
113
- length = read_uint32_le
114
- string = @io.read(length).force_encoding(Encoding::UTF_8)
115
-
116
- Instructions::BinUnicode.new(length,string)
117
- when 93 # EMPTY_LIST
118
- Instructions::EMPTY_LIST
119
- when 101 # APPENDS
120
- Instructions::APPENDS
121
- when 104 # BINGET
122
- Instructions::BinGet.new(read_uint8)
123
- when 106 # LONG_BINGET
124
- Instructions::LongBinGet.new(read_uint32_le)
125
- when 113 # BINPUT
126
- Instructions::BinPut.new(read_uint8)
127
- when 117 # SETITEMS
128
- Instructions::SETITEMS
129
- when 125 # EMPTY_DICT
130
- Instructions::EMPTY_DICT
145
+ when EMPTY_TUPLE then Instructions::EMPTY_TUPLE
146
+ when BINFLOAT then read_binfloat_instruction
147
+ when BININT1 then read_binint1_instruction
148
+ when BINSTRING then read_binstring_instruction
149
+ when SHORT_BINSTRING then read_short_binstring_instruction
150
+ when BINUNICODE then read_binunicode_instruction
151
+ when EMPTY_LIST then Instructions::EMPTY_LIST
152
+ when APPENDS then Instructions::APPENDS
153
+ when BINGET then read_binget_instruction
154
+ when LONG_BINGET then read_long_binget_instruction
155
+ when BINPUT then read_binput_instruction
156
+ when SETITEMS then Instructions::SETITEMS
157
+ when EMPTY_DICT then Instructions::EMPTY_DICT
131
158
  #
132
159
  # Protocol 2 instructions
133
160
  #
134
- when 128 # PROT
135
- Instructions::Proto.new(read_uint8)
136
- when 129 # NEWOBJ
137
- Instructions::NEWOBJ
138
- when 130 # EXT1
139
- Instructions::Ext1.new(read_uint8)
140
- when 131 # EXT2
141
- Instructions::Ext2.new(read_uint16_le)
142
- when 132 # EXT4
143
- Instructions::Ext4.new(read_uint32_le)
144
- when 133 # TUPLE1
145
- Instructions::TUPLE1
146
- when 134 # TUPLE2
147
- Instructions::TUPLE2
148
- when 135 # TUPLE3
149
- Instructions::TUPLE3
150
- when 136 # NEWTRUE
151
- Instructions::NEWTRUE
152
- when 137 # NEWFALSE
153
- Instructions::NEWFALSE
154
- when 138 # LONG1
155
- length = read_uint8
156
- long = read_int_le(length)
157
-
158
- Instructions::Long1.new(length,long)
159
- when 139 # LONG4
160
- length = read_uint32_le
161
- long = read_int_le(length)
162
-
163
- Instructions::Long4.new(length,long)
161
+ when PROTO then read_proto_instruction
162
+ when NEWOBJ then Instructions::NEWOBJ
163
+ when EXT1 then read_ext1_instruction
164
+ when EXT2 then read_ext2_instruction
165
+ when EXT4 then read_ext4_instruction
166
+ when TUPLE1 then Instructions::TUPLE1
167
+ when TUPLE2 then Instructions::TUPLE2
168
+ when TUPLE3 then Instructions::TUPLE3
169
+ when NEWTRUE then Instructions::NEWTRUE
170
+ when NEWFALSE then Instructions::NEWFALSE
171
+ when LONG1 then read_long1_instruction
172
+ when LONG4 then read_long4_instruction
164
173
  else
165
174
  raise(InvalidFormat,"invalid opcode (#{opcode.inspect}) for protocol 2")
166
175
  end
@@ -224,6 +233,78 @@ module Python
224
233
  return long
225
234
  end
226
235
 
236
+ #
237
+ # Reads a `PROTO` instruction.
238
+ #
239
+ # @return [Instructions::Proto]
240
+ #
241
+ # @since 0.2.0
242
+ #
243
+ def read_proto_instruction
244
+ Instructions::Proto.new(read_uint8)
245
+ end
246
+
247
+ #
248
+ # Reads a `EXT1` instruction.
249
+ #
250
+ # @return [Instructions::Ext1]
251
+ #
252
+ # @since 0.2.0
253
+ #
254
+ def read_ext1_instruction
255
+ Instructions::Ext1.new(read_uint8)
256
+ end
257
+
258
+ #
259
+ # Reads a `EXT2` instruction.
260
+ #
261
+ # @return [Instructions::Ext2]
262
+ #
263
+ # @since 0.2.0
264
+ #
265
+ def read_ext2_instruction
266
+ Instructions::Ext2.new(read_uint16_le)
267
+ end
268
+
269
+ #
270
+ # Reads a `EXT4` instruction.
271
+ #
272
+ # @return [Instructions::Ext4]
273
+ #
274
+ # @since 0.2.0
275
+ #
276
+ def read_ext4_instruction
277
+ Instructions::Ext4.new(read_uint32_le)
278
+ end
279
+
280
+ #
281
+ # Reads a `LONG1` instruction.
282
+ #
283
+ # @return [Instructions::Long1]
284
+ #
285
+ # @since 0.2.0
286
+ #
287
+ def read_long1_instruction
288
+ length = read_uint8
289
+ long = read_int_le(length)
290
+
291
+ Instructions::Long1.new(length,long)
292
+ end
293
+
294
+ #
295
+ # Reads a `LONG4` instruction.
296
+ #
297
+ # @return [Instructions::Long4]
298
+ #
299
+ # @since 0.2.0
300
+ #
301
+ def read_long4_instruction
302
+ length = read_uint32_le
303
+ long = read_int_le(length)
304
+
305
+ Instructions::Long4.new(length,long)
306
+ end
307
+
227
308
  end
228
309
  end
229
310
  end