Class: Java::ObjectInputStream
- Inherits:
-
Object
- Object
- Java::ObjectInputStream
- Includes:
- ObjectStream
- Defined in:
- lib/javaobs.rb
Overview
The Ruby version of the Java ObjectInputStream. Creates a Ruby proxy class for each Java Class.
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
-
#defaultReadObject(object) ⇒ Object
Cover method for java method.
-
#initialize(str) ⇒ ObjectInputStream
constructor
Initialize from a stream.
-
#readArray(klass) ⇒ Object
Read an array of objects.
-
#readBlockData ⇒ Object
Read a Java block of data with a size and then the following data.
- #readBlockEnd ⇒ Object
- #readBlockStart ⇒ Object
- #readBool ⇒ Object
- #readByte ⇒ Object
-
#readClassAnnotation ⇒ Object
Read the class annotation.
-
#readClassData(klass, object = nil) ⇒ Object
Read class data and recursively read parent classes.
-
#readClassDesc ⇒ Object
Read the Java class description and create a Ruby class to proxy it in this name-space.
- #readDouble ⇒ Object
-
#readFields(klass) ⇒ Object
Read all the fields from the stream and add them to the class.
- #readFloat ⇒ Object
- #readInt ⇒ Object
- #readLong ⇒ Object
-
#readObject ⇒ Object
Read an object from the stream.
-
#readObjectFields(klass, object) ⇒ Object
Reads the object fields from the stream.
-
#readObjects ⇒ Object
Read all objects in the stream.
- #readShort ⇒ Object
- #readString ⇒ Object
-
#readType(type, arrayType = nil, field = nil) ⇒ Object
Read a primitive data type.
- #readUID ⇒ Object
- #readUShort ⇒ Object
-
#rubyClassFor(name, super_name) ⇒ Object
Gets or creates a corresponding Ruby class for the Java class.
Constructor Details
#initialize(str) ⇒ ObjectInputStream
Initialize from a stream.
477 478 479 480 481 482 483 484 485 486 |
# File 'lib/javaobs.rb', line 477 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
#defaultReadObject(object) ⇒ Object
Cover method for java method.
411 412 413 |
# File 'lib/javaobs.rb', line 411 def defaultReadObject(object) readObjectFields(object.class.javaClass, object) end |
#readArray(klass) ⇒ Object
Read an array of objects.
365 366 367 368 369 370 371 372 373 |
# File 'lib/javaobs.rb', line 365 def readArray(klass) size = readInt a = klass.rubyClass.new type = klass.arrayType 1.upto(size) do a << readType(type) end a end |
#readBlockData ⇒ Object
Read a Java block of data with a size and then the following data.
262 263 264 265 266 267 |
# File 'lib/javaobs.rb', line 262 def readBlockData size = readBlockStart data = @str.read(size) readBlockEnd data end |
#readBlockEnd ⇒ Object
256 257 258 259 |
# File 'lib/javaobs.rb', line 256 def readBlockEnd byte = readByte raise SerializationError, "Unexpected byte #{byte}" unless byte == TC_ENDBLOCKDATA end |
#readBlockStart ⇒ Object
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 |
# File 'lib/javaobs.rb', line 240 def readBlockStart byte = readByte size = nil case byte when TC_BLOCKDATA size = readByte when TC_BLOCKDATALONG size = readInt else raise SerializationError, "Expecting TC_BLOCKDATA, got #{'0x%X' % byte}" unless byte == TC_BLOCKDATA end size end |
#readBool ⇒ Object
236 |
# File 'lib/javaobs.rb', line 236 def readBool; @str.read(1)[0] != 0; end |
#readByte ⇒ Object
229 |
# File 'lib/javaobs.rb', line 229 def readByte; @str.read(1)[0]; end |
#readClassAnnotation ⇒ Object
Read the class annotation. We do not currently handle annotations.
287 288 289 290 |
# File 'lib/javaobs.rb', line 287 def readClassAnnotation ebd = readByte raise SerializationError, "We do not handle annotations!" unless ebd == TC_ENDBLOCKDATA end |
#readClassData(klass, object = nil) ⇒ Object
Read class data and recursively read parent classes.
424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 |
# File 'lib/javaobs.rb', line 424 def readClassData(klass, object = nil) if object == nil object = klass.rubyClass.new() @objects << object end readClassData(klass.superClass, object) if (klass.superClass) if klass.flags == SC_SERIALIZABLE readObjectFields(klass, object) else object._readJavaData(self) end object end |
#readClassDesc ⇒ Object
Read the Java class description and create a Ruby class to proxy it in this name-space. Added special handling for the Date class.
321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 |
# File 'lib/javaobs.rb', line 321 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 =~ /^[A-Z.]+/i # Create the class within the correct module. rclass = rubyClassFor(name, klass.superClass.to_s) 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 |
#readDouble ⇒ Object
233 |
# File 'lib/javaobs.rb', line 233 def readDouble; @str.read(8).unpack("G")[0]; end |
#readFields(klass) ⇒ Object
Read all the fields from the stream and add them to the class.
271 272 273 274 275 276 277 278 279 280 281 282 283 284 |
# File 'lib/javaobs.rb', line 271 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 |
#readFloat ⇒ Object
234 |
# File 'lib/javaobs.rb', line 234 def readFloat; @str.read(4).unpack("g")[0]; end |
#readInt ⇒ Object
232 |
# File 'lib/javaobs.rb', line 232 def readInt; @str.read(4).unpack("i")[0]; end |
#readLong ⇒ Object
238 |
# File 'lib/javaobs.rb', line 238 def readLong; @str.read(8).unpack("Q").first; end |
#readObject ⇒ Object
Read an object from the stream.
442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 |
# File 'lib/javaobs.rb', line 442 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 SerializationError, "Unexpected byte #{byte} at #{@str.pos}" end object end |
#readObjectFields(klass, object) ⇒ Object
Reads the object fields from the stream.
416 417 418 419 420 421 |
# File 'lib/javaobs.rb', line 416 def readObjectFields(klass, object) klass.fields.each do |f| v = readType(f.type, f.subtype, f) object.send((f.name + '=').intern, v) end end |
#readObjects ⇒ Object
Read all objects in the stream. Calls readObject until the stream eof is reached.
490 491 492 493 494 495 496 |
# File 'lib/javaobs.rb', line 490 def readObjects objs = [] until (@str.eof) objs << readObject end objs end |
#readShort ⇒ Object
231 |
# File 'lib/javaobs.rb', line 231 def readShort; @str.read(2).unpack("s")[0]; end |
#readString ⇒ Object
235 |
# File 'lib/javaobs.rb', line 235 def readString; @str.read(readShort); end |
#readType(type, arrayType = nil, field = nil) ⇒ Object
Read a primitive data type.
376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 |
# File 'lib/javaobs.rb', line 376 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 SerializationError, "Unknown type #{type}" end end |
#readUID ⇒ Object
237 |
# File 'lib/javaobs.rb', line 237 def readUID; @str.read(8); end |
#readUShort ⇒ Object
230 |
# File 'lib/javaobs.rb', line 230 def readUShort; @str.read(2).unpack("n")[0]; end |
#rubyClassFor(name, super_name) ⇒ Object
Gets or creates a corresponding Ruby class for the Java class. This will drop leading com or java and transform the rest of the dotted names to modules.
295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 |
# File 'lib/javaobs.rb', line 295 def rubyClassFor(name, super_name) context = name.split('.') f, = context context.shift if f == 'java' or f == 'com' context.map! { |n| n.capitalize! if n !~ /^[A-Z]/o; n } kname = context.pop mod = Java context.each do |m| unless mod.constants.include?(m) mod = mod.module_eval "#{m} = Module.new" else mod = mod.const_get(m) end end unless mod.constants.include?(kname) rclass = mod.module_eval "#{kname} = Class.new(#{super_name})" else rclass = mod.const_get(kname) end rclass end |