Class: Python::Pickle::Protocol4

Inherits:
Protocol3 show all
Defined in:
lib/python/pickle/protocol4.rb

Overview

Implements Python Pickle protocol 4.

Direct Known Subclasses

Protocol5

Constant Summary collapse

SHORT_BINUNICODE =

The SHORT_BINUNICODE opcode.

140
BINUNICODE8 =

The BINUNICODE8 opcode.

141
BINBYTES8 =

The BINBYTES opcode.

142
EMPTY_SET =

The EMPTY_SET opcode.

143
ADDITEMS =

The ADDITEMS opcode.

144
FROZENSET =

The FROZENSET opcode.

145
NEWOBJ_EX =

The NEWOBJ_EX opcode.

146
STACK_GLOBAL =

The STACK_GLOBAL opcode.

147
MEMOIZE =

The MEMOIZE opcode.

148
FRAME =

The FRAME opcode.

149

Constants inherited from Protocol3

Python::Pickle::Protocol3::BINBYTES, Python::Pickle::Protocol3::SHORT_BINBYTES

Constants inherited from Protocol2

Python::Pickle::Protocol2::EXT1, Python::Pickle::Protocol2::EXT2, Python::Pickle::Protocol2::EXT4, Python::Pickle::Protocol2::LONG1, Python::Pickle::Protocol2::LONG4, Python::Pickle::Protocol2::NEWFALSE, Python::Pickle::Protocol2::NEWOBJ, Python::Pickle::Protocol2::NEWTRUE, Python::Pickle::Protocol2::PROTO, Python::Pickle::Protocol2::TUPLE1, Python::Pickle::Protocol2::TUPLE2, Python::Pickle::Protocol2::TUPLE3

Constants inherited from Protocol1

Python::Pickle::Protocol1::APPENDS, Python::Pickle::Protocol1::BINFLOAT, Python::Pickle::Protocol1::BINGET, Python::Pickle::Protocol1::BININT1, Python::Pickle::Protocol1::BINPUT, Python::Pickle::Protocol1::BINSTRING, Python::Pickle::Protocol1::BINUNICODE, Python::Pickle::Protocol1::EMPTY_DICT, Python::Pickle::Protocol1::EMPTY_LIST, Python::Pickle::Protocol1::EMPTY_TUPLE, Python::Pickle::Protocol1::LONG_BINGET, Python::Pickle::Protocol1::SETITEMS, Python::Pickle::Protocol1::SHORT_BINSTRING

Constants inherited from Protocol0

Python::Pickle::Protocol0::APPEND, Python::Pickle::Protocol0::BINPERSID, Python::Pickle::Protocol0::BUILD, Python::Pickle::Protocol0::DICT, Python::Pickle::Protocol0::DUP, Python::Pickle::Protocol0::FLOAT, Python::Pickle::Protocol0::GET, Python::Pickle::Protocol0::GLOBAL, Python::Pickle::Protocol0::INST, Python::Pickle::Protocol0::INT, Python::Pickle::Protocol0::LIST, Python::Pickle::Protocol0::LONG, Python::Pickle::Protocol0::MARK, Python::Pickle::Protocol0::NONE, Python::Pickle::Protocol0::OBJ, Python::Pickle::Protocol0::PERSID, Python::Pickle::Protocol0::POP, Python::Pickle::Protocol0::POP_MARK, Python::Pickle::Protocol0::PUT, Python::Pickle::Protocol0::REDUCE, Python::Pickle::Protocol0::SETITEM, Python::Pickle::Protocol0::STOP, Python::Pickle::Protocol0::STRING, Python::Pickle::Protocol0::TUPLE, Python::Pickle::Protocol0::UNICODE

Instance Attribute Summary

Attributes inherited from Protocol

#io

Instance Method Summary collapse

Methods inherited from Protocol3

#read_binbytes_instruction, #read_short_binbytes_instruction

Methods inherited from Protocol2

#read_ext1_instruction, #read_ext2_instruction, #read_ext4_instruction, #read_int_le, #read_long1_instruction, #read_long4_instruction, #read_proto_instruction, #read_uint16_le, #unpack_int_le

Methods inherited from Protocol1

#read_binfloat_instruction, #read_binget_instruction, #read_binint1_instruction, #read_binput_instruction, #read_binstring_instruction, #read_binunicode_instruction, #read_float64_be, #read_long_binget_instruction, #read_short_binstring_instruction, #read_uint32_le, #read_uint8

Methods inherited from Protocol0

#read_escaped_char, #read_float, #read_float_instruction, #read_get_instruction, #read_global_instruction, #read_hex_escaped_char, #read_inst_instruction, #read_int, #read_int_instruction, #read_long, #read_long_instruction, #read_nl_string, #read_persid_instruction, #read_put_instruction, #read_string, #read_string_instruction, #read_unicode_escaped_char, #read_unicode_escaped_char16, #read_unicode_escaped_char32, #read_unicode_instruction, #read_unicode_string

Methods inherited from Protocol

#read

Constructor Details

#initialize(io) ⇒ Protocol4

Initializes the protocol 4 reader/writer.



23
24
25
26
27
# File 'lib/python/pickle/protocol4.rb', line 23

def initialize(io)
  super(io)

  @io_stack = []
end

Instance Method Details

#enter_frame(frame) ⇒ Object

Enters a new data frame.

Parameters:

  • frame (String)

    The contents of the data frame.



237
238
239
240
# File 'lib/python/pickle/protocol4.rb', line 237

def enter_frame(frame)
  @io_stack.push(@io)
  @io = StringIO.new(frame)
end

#leave_frameObject

Leaves a data frame and restores Python::Pickle::Protocol#io.



245
246
247
# File 'lib/python/pickle/protocol4.rb', line 245

def leave_frame
  @io = @io_stack.pop
end

#read_binbytes8_instructionInstructions::BinBytes8

Reads a BINBYTES8 instruction.

Returns:

Since:

  • 0.2.0



284
285
286
287
288
289
# File 'lib/python/pickle/protocol4.rb', line 284

def read_binbytes8_instruction
  length = read_uint64_le
  bytes  = @io.read(length)

  Instructions::BinBytes8.new(length,bytes)
end

#read_binunicode8_instructionInstructions::BinUnicode8

Reads a BINUNICODE8 instruction.

Returns:

Since:

  • 0.2.0



270
271
272
273
274
275
# File 'lib/python/pickle/protocol4.rb', line 270

def read_binunicode8_instruction
  length = read_uint64_le
  string = read_utf8_string(length)

  Instructions::BinUnicode8.new(length,string)
end

#read_frame(length) ⇒ String

Reads a data frame of the given length.

Parameters:

  • length (Integer)

    The desired length of the frame.

Returns:

  • (String)

    The read data frame.



227
228
229
# File 'lib/python/pickle/protocol4.rb', line 227

def read_frame(length)
  @io.read(length)
end

#read_frame_instructionInstructions::Frame

Reads a FRAME instruction.

Returns:

Since:

  • 0.2.0



298
299
300
301
302
303
304
# File 'lib/python/pickle/protocol4.rb', line 298

def read_frame_instruction
  length = read_uint64_le

  enter_frame(read_frame(length))

  Instructions::Frame.new(length)
end

#read_instructionInstruction

Reads an instruction from the pickle stream.

Returns:

Raises:



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/python/pickle/protocol4.rb', line 108

def read_instruction
  case (opcode = @io.getbyte)
  #
  # Protocol 0 instructions
  #
  when MARK      then Instructions::MARK
  when STOP      then Instructions::STOP
  when POP       then Instructions::POP
  when POP_MARK  then Instructions::POP_MARK
  when DUP       then Instructions::DUP
  when FLOAT     then read_float_instruction
  when INT       then read_int_instruction
  when LONG      then read_long_instruction
  when NONE      then Instructions::NONE
  when REDUCE    then Instructions::REDUCE
  when STRING    then read_string_instruction
  when UNICODE   then read_unicode_instruction
  when APPEND    then Instructions::APPEND
  when BUILD     then Instructions::BUILD
  when GLOBAL    then read_global_instruction
  when DICT      then Instructions::DICT
  when GET       then read_get_instruction
  when LIST      then Instructions::LIST
  when PUT       then read_put_instruction
  when SETITEM   then Instructions::SETITEM
  when TUPLE     then Instructions::TUPLE
  when INST      then read_inst_instruction
  when OBJ       then Instructions::OBJ
  when PERSID    then read_persid_instruction
  when BINPERSID then Instructions::BINPERSID
  #
  # Protocol 1 instructions
  #
  when EMPTY_TUPLE     then Instructions::EMPTY_TUPLE
  when BINFLOAT        then read_binfloat_instruction
  when BININT1         then read_binint1_instruction
  when BINSTRING       then read_binstring_instruction
  when SHORT_BINSTRING then read_short_binstring_instruction
  when BINUNICODE      then read_binunicode_instruction
  when EMPTY_LIST      then Instructions::EMPTY_LIST
  when APPENDS         then Instructions::APPENDS
  when BINGET          then read_binget_instruction
  when LONG_BINGET     then read_long_binget_instruction
  when BINPUT          then read_binput_instruction
  when SETITEMS        then Instructions::SETITEMS
  when EMPTY_DICT      then Instructions::EMPTY_DICT
  #
  # Protocol 2 instructions
  #
  when PROTO    then read_proto_instruction
  when NEWOBJ   then Instructions::NEWOBJ
  when EXT1     then read_ext1_instruction
  when EXT2     then read_ext2_instruction
  when EXT4     then read_ext4_instruction
  when TUPLE1   then Instructions::TUPLE1
  when TUPLE2   then Instructions::TUPLE2
  when TUPLE3   then Instructions::TUPLE3
  when NEWTRUE  then Instructions::NEWTRUE
  when NEWFALSE then Instructions::NEWFALSE
  when LONG1    then read_long1_instruction
  when LONG4    then read_long4_instruction
  #
  # Protocol 3 instructions
  #
  when BINBYTES       then read_binbytes_instruction
  when SHORT_BINBYTES then read_short_binbytes_instruction
  #
  # Protocol 4 instructions
  #
  when SHORT_BINUNICODE then read_short_binunicode_instruction
  when BINUNICODE8      then read_binunicode8_instruction
  when BINBYTES8        then read_binbytes8_instruction
  when EMPTY_SET        then Instructions::EMPTY_SET
  when ADDITEMS         then Instructions::ADDITEMS
  when FROZENSET        then Instructions::FROZENSET
  when NEWOBJ_EX        then Instructions::NEWOBJ_EX
  when STACK_GLOBAL     then Instructions::STACK_GLOBAL
  when MEMOIZE          then Instructions::MEMOIZE
  when FRAME            then read_frame_instruction
  else
    raise(InvalidFormat,"invalid opcode (#{opcode.inspect}) for protocol 4")
  end
ensure
  if @io.eof? && !@io_stack.empty?
    leave_frame
  end
end

#read_short_binunicode_instructionInstructions::ShortBinUnicode

Reads a SHORT_BINUNICODE instruction.

Returns:

Since:

  • 0.2.0



256
257
258
259
260
261
# File 'lib/python/pickle/protocol4.rb', line 256

def read_short_binunicode_instruction
  length = read_uint8
  string = read_utf8_string(length)

  Instructions::ShortBinUnicode.new(length,string)
end

#read_uint64_leInteger

Reads an unsigned 64bit integer, in little-endian byte-order.

Returns:

  • (Integer)


201
202
203
# File 'lib/python/pickle/protocol4.rb', line 201

def read_uint64_le
  @io.read(8).unpack1('Q<')
end

#read_utf8_string(length) ⇒ String

Reads a UTF-8 string of the desired length.

Parameters:

  • length (Integer)

    The desired length to read.

Returns:

  • (String)

    The read UTF-8 string.



214
215
216
# File 'lib/python/pickle/protocol4.rb', line 214

def read_utf8_string(length)
  @io.read(length).force_encoding(Encoding::UTF_8)
end