Class: Java::ObjectInputStream

Inherits:
Object
  • Object
show all
Includes:
ObjectStream
Defined in:
lib/javaobs.rb

Constant Summary

Constants included from ObjectStream

Java::ObjectStream::PRIM_ARRAY, Java::ObjectStream::PRIM_BOOL, Java::ObjectStream::PRIM_BYTE, Java::ObjectStream::PRIM_CHAR, Java::ObjectStream::PRIM_DOUBLE, Java::ObjectStream::PRIM_FLOAT, Java::ObjectStream::PRIM_INT, Java::ObjectStream::PRIM_LONG, Java::ObjectStream::PRIM_OBJECT, Java::ObjectStream::PRIM_SHORT, Java::ObjectStream::SC_BLOCKDATA, Java::ObjectStream::SC_EXTERNALIZABLE, Java::ObjectStream::SC_SERIALIZABLE, Java::ObjectStream::SC_WRITE_METHOD, Java::ObjectStream::STREAM_MAGIC, Java::ObjectStream::STREAM_VERSION, Java::ObjectStream::TC_ARRAY, Java::ObjectStream::TC_BLOCKDATA, Java::ObjectStream::TC_BLOCKDATALONG, Java::ObjectStream::TC_CLASS, Java::ObjectStream::TC_CLASSDESC, Java::ObjectStream::TC_ENDBLOCKDATA, Java::ObjectStream::TC_EXCEPTION, Java::ObjectStream::TC_LONGSTRING, Java::ObjectStream::TC_NULL, Java::ObjectStream::TC_OBJECT, Java::ObjectStream::TC_PROXYCLASSDESC, Java::ObjectStream::TC_REFERENCE, Java::ObjectStream::TC_RESET, Java::ObjectStream::TC_STRING

Instance Method Summary collapse

Constructor Details

#initialize(str) ⇒ ObjectInputStream

Returns a new instance of ObjectInputStream.



322
323
324
325
326
327
328
329
330
331
# File 'lib/javaobs.rb', line 322

def initialize(str)
  @str = str
  magic =  readUShort
  streamVersion = readShort
  @objects = []

  raise "Bad stream #{magic.to_s(16)}:#{streamVersion.to_s(16)}" if magic != STREAM_MAGIC ||
  streamVersion != STREAM_VERSION

end

Instance Method Details

#readArray(klass) ⇒ Object



218
219
220
221
222
223
224
225
226
# File 'lib/javaobs.rb', line 218

def readArray(klass)
  size = readInt
  a = klass.rubyClass.new
  type = klass.arrayType
  1.upto(size) do
    a << readType(type)
  end
  a
end

#readBlockDataObject



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/javaobs.rb', line 128

def readBlockData
  byte = readByte
  size = nil
  case byte
  when TC_BLOCKDATA
    size = readByte
    
  when TC_BLOCKDATALONG
    size = readInt
    
  else
    raise "Expecting TC_BLOCKDATA" unless byte == TC_BLOCKDATA
  end
  
  data = @str.read(size)
  byte = readByte
  raise "Unexpected byte #{byte}" unless byte == TC_ENDBLOCKDATA
  data
end

#readBoolObject



124
# File 'lib/javaobs.rb', line 124

def readBool; @str.read(1)[0] != 0; end

#readByteObject



117
# File 'lib/javaobs.rb', line 117

def readByte; @str.read(1)[0]; end

#readClassAnnotationObject



163
164
165
166
# File 'lib/javaobs.rb', line 163

def readClassAnnotation
  ebd = readByte
  raise "We do not handle annotations!" unless ebd == TC_ENDBLOCKDATA
end

#readClassData(klass, object = nil) ⇒ Object



262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
# File 'lib/javaobs.rb', line 262

def readClassData(klass, object = nil)
  # Handle special case for Date
  if object == nil
    if (klass.javaName == 'java.util.Date')
      object = Java::Date.new
    else
      object = klass.rubyClass.new()
    end
    @objects << object
  end
  
  readClassData(klass.superClass, object) if (klass.superClass)
  
  if klass.flags == SC_SERIALIZABLE
    klass.fields.each do |f|
      v = readType(f.type, f.subtype, f)
      object.send((f.name + '=').intern, v)
    end
  else
    data = readBlockData
    object.time = data
  end
  
  object
end

#readClassDescObject



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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# File 'lib/javaobs.rb', line 168

def readClassDesc
  name = readString
  uid = readUID
  flags = readByte
  klass = JavaClass.new(name, uid, flags)
  
  @objects << klass
  
  readFields(klass)
  readClassAnnotation
  
  klass.superClass = readObject

  # Create Ruby object representing class
  if name == 'java.util.Date'
    rclass = Java::Date
    rclass.class_eval "@javaClass = klass"
    klass.rubyClass = rclass
  elsif name =~ /^[A-Z.]+/i
    unless Java.constants.index(klass.name)
      rclass = Java.module_eval "#{klass.name} = Class.new(#{klass.superClass.to_s})"
    else
      rclass = Java.const_get(klass.name)
    end

    unless rclass.methods.index('javaClass')
      rclass.class_eval "extend JavaObject"
    end
    
    rclass.class_eval "@javaClass = klass"
    vars = klass.fields.map do |f|
      ':' + f.name
    end
    rclass.class_eval "attr_accessor #{vars.join(',')}"
    klass.rubyClass = rclass
  else
    # Arrays
    newName = 'JavaArray' + klass.name[1..klass.name.length]
    unless Java.constants.index(newName)
      rclass = Java.module_eval "#{newName} = Class.new(JavaArray)"
    else
      rclass = Java.const_get(newName)
    end
    rclass.class_eval "@javaClass = klass"
    klass.rubyClass = rclass
  end
  
  klass
end

#readDoubleObject



121
# File 'lib/javaobs.rb', line 121

def readDouble; @str.read(8).unpack("G")[0]; end

#readFields(klass) ⇒ Object



148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/javaobs.rb', line 148

def readFields(klass)
  fieldCount = readShort
  1.upto(fieldCount) do
    type = readByte
    name = readString
    field = JavaField.new(name, type)
    
    # Check for array and object types
    if type == PRIM_OBJECT || type == PRIM_ARRAY
      field.subtype = readObject
    end
    klass.addField(field)
  end
end

#readFloatObject



122
# File 'lib/javaobs.rb', line 122

def readFloat; @str.read(4).unpack("g")[0]; end

#readIntObject



120
# File 'lib/javaobs.rb', line 120

def readInt; @str.read(4).unpack("i")[0]; end

#readLongObject



126
# File 'lib/javaobs.rb', line 126

def readLong; @str.read(8).unpack("Q").first; end

#readObjectObject



288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
# File 'lib/javaobs.rb', line 288

def readObject
  object = nil
  byte = readByte
  case byte
  when TC_OBJECT
    klass = readObject
    object = readClassData(klass)
    
  when TC_REFERENCE
    readShort
    object = @objects[readShort]
    
  when TC_ARRAY
    klass = readObject
    object = readArray(klass)
    @objects << object
    
  when TC_STRING
    object = readString
    @objects << object

  when TC_CLASSDESC
    object = readClassDesc

  when TC_NULL
    object = nil
    
  else
    raise "Unexpected byte #{byte} at #{@str.pos}"
  end

  object
end

#readObjectsObject



333
334
335
336
337
338
339
# File 'lib/javaobs.rb', line 333

def readObjects
  objs = []
  until (@str.eof)
    objs << readObject
  end
  objs
end

#readShortObject



119
# File 'lib/javaobs.rb', line 119

def readShort; @str.read(2).unpack("s")[0]; end

#readStringObject



123
# File 'lib/javaobs.rb', line 123

def readString; @str.read(readShort); end

#readType(type, arrayType = nil, field = nil) ⇒ Object



228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
# File 'lib/javaobs.rb', line 228

def readType(type, arrayType = nil, field = nil)
  case type
  when PRIM_BYTE
    readByte
    
  when PRIM_CHAR
    readByte
    
  when PRIM_DOUBLE
    readDouble
    
  when PRIM_FLOAT
    readFloat
    
  when PRIM_INT
    readInt
    
  when PRIM_LONG
    readLong
    
  when PRIM_SHORT
    readShort
    
  when PRIM_BOOL
    readBool
    
  when PRIM_OBJECT, PRIM_ARRAY
    readObject
    
  else
    raise "Unknown type #{type}"
  end
end

#readUIDObject



125
# File 'lib/javaobs.rb', line 125

def readUID; @str.read(8); end

#readUShortObject



118
# File 'lib/javaobs.rb', line 118

def readUShort; @str.read(2).unpack("n")[0]; end