suzaku-io / boopickle

Binary serialization library for efficient network communication

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Byte ordering issue with the Longs

rabzu opened this issue · comments

commented

Im serialising and then deserialising an object and get wrong Long values

final case class PAXMPSystemInfo(
  playerSystemUUID: UUID,
  systemStartTime: DateTime,
  systemTimeZone: DateTimeZone,
  totalCapacity: Long,
  totalFreeSpace: Long,
  cpuUsage: String,
  memoryTotal: Long,
  memoryUsed: Long,
  hdmiOutput: String)

More specificaly I get wrong systemStartTime: DateTime, totalCapacity: Long, totalFreeSpace: Long,

Before Serialisation

PAXMPSystemInfo(
9e7df0ed-2a5c-4a19-bec7-ecf00e4c495c,
2017-10-07T12:01:04.000+04:00,
America/New_York,
7377477632,
7128944640,
21%,
1048576,
855968,
1920x1080p-60

After desirialization

PAXMPSystemInfo(
194a5c2a-edf0-7d9e-5c49-4c0ef0ecc7be,
205829-11-23T05:36:40.960+04:00,
America/New_York,
27227992434409472,
4762706431180800,
21%,
1048576,
855968,
1920x1080p-60)

Otto Chrons @ochrons Oct 07 15:35
your bytebuffers probably have different ordering for some reason and it only affects on Longs that are larger than Int.MaxValue, since the code then calls putLong and getLong which depend on byte order

After following the documentation https://boopickle.suzaku.io/Misc.html I managed to to fix it.
the ordering was effected by incorrect use of bb.array().

  def toBytes(event: PublishedDomainEvent): Array[Byte] = {
    val bb = Pickle.intoBytes[PublishedDomainEvent](event)
    val bytes = bb.array()
    BufferPool.release(bb)
    bytes
  }

As a result I refactored the code into:

def toBytes(event: PublishedDomainEvent): Array[Byte] = {
     val data = Pickle.intoBytes[PublishedDomainEvent](event)
     if (data == null) return null
 
     data.rewind()
 
     if (data.hasArray()) {
       val arr = data.array();
       if (data.arrayOffset() == 0 && arr.length == data.remaining()) {
         return arr;
       }
     }
 
     val ret = Array.ofDim[Byte](data.remaining())
     data.get(ret, 0, ret.length)
     data.rewind()
     ret
}

Thanks for writing this down!