B4J Question [JAVA] Use of B4XSerializator

rdkartono

Member
Licensed User
Longtime User
I make this question for knowledge, so I need to know how to do it.

In JAVA code, i can use B4XSerializator to convert from Map to Bytes. Here are the code :
Map to Bytes:
/**
     * Write Map Object to TCPSocket
     * @param value : Map value
     * @return true if can be sent
     */
    public boolean WriteMap(Map value) {
        if (IsConnected()) {
            if (_output instanceof ObjectOutputStream) {
                try {
                    byte[] outputbyte = _converter.WriteObject(value);
                    _output.write(outputbyte);
                    _output.flush();
                    printbytes("MapBytes",outputbyte);
                    return true;
                } catch (IOException e) {
                    raise_log_error("IOException on WriteObject", e);
                    Disconnect();
                }
               
               
            }
        }
        return false;
    }

PrintBytes:
private void printbytes(String prefix, byte[] value) {
        StringBuilder str = new StringBuilder();
        str.append(prefix).append(" : ");
        if (value!=null) {
            if (value.length>0) {
                for (int ii=0;ii<value.length;ii++) {
                    str.append(Bit.ToHexString(Bit.And(value[ii], 0xFF))).append(" ");
                }
            }
        }
        BA.Log(str.toString());
    }

Output from PrintBytes called from WriteMap function is :
printbytes from WriteMap function:
MapBytes : 78 9c 13 61 64 60 60 60 64 7 12 ce fe be be 8e 7e 2e 8c 9c 40 b6 bb 6b 48 70 88 63 48 68 30 0 35 74 4 eb


However I can't cast back from Bytes to Map.

Here is my code for receiving bytes then convert to Map
Bytes Receiving:
while(true) {
                    // selama _input masih ObjectInputStream, coba looping lagi
                    // Kalau Disconnect dipanggil, _input akan jadi null
                    // maka while ini jadi break
                   
                    if (_input instanceof ObjectInputStream) {
                        int readcount = 0;
                        while(true) {
                            // coba ambil data di sini , loop terus sampe break
                            // kondisi terus, kalau readcount = buf.length, artinya bisa ambil data banyak
                            // mungkin masih ada data lagi setelahnya
                            //
                            // kondisi break, kalau readcount < buf.length, artinya buffernya aja gak sampe penuh
                            // berarti datanya cuma dikit
                           
                            byte[] buf = new byte[1024];
                           
                            try {
                                readcount = _input.read(buf);    // ngeblok di sini
                            } catch (IOException e) {
                                raise_log_error("IOException from input.read", e);
                                break;
                            }
                           
                            if (readcount>0) {            // perlu disimpen apa nggak
                                if (readcount>bytebuf.remaining()) {
                                    // gak cukup, gedein byte buffer
                                    ByteBuffer newbytebuf = ByteBuffer.allocate(bytebuf.capacity()+readcount);
                                    newbytebuf.put(bytebuf);
                                    bytebuf = newbytebuf;  // alokasikan ke sini
                               
                                }
                               
                                // sampe sini , size cukup
                                bytebuf.put(buf,0,readcount);
                               
                                // kalau readcount = 1024, artinya datanya cukup banyak, mungkin perlu baca lagi
                                // kalau readcount < 1024, artinya datanya sedikit, cukup sekali baca aja
                                if (readcount!=buf.length) break;
                            };
                           
                        }
                       
                        if (bytebuf.position()>0) {
                            bytebuf.flip();
                            byte[] totalbytes = new byte[bytebuf.remaining()];
                            bytebuf.get(totalbytes);
                            printbytes("TotalBytes",totalbytes);
                            try {
                                Object rxobject = _converter.ReadObject(totalbytes);
                                BA.Log("_converter.ReadObject success");
                               
                                Map rxmap = (Map) rxobject;
                                BA.Log("Casting to Map success");
                               
                                raise_newmapdata(rxmap);
                                BA.Log("raise_newmapdata complete");
                            } catch (IOException e) {
                                raise_log_error("IOException on converter.ReadObject",e);
                            } catch(ClassCastException e) {
                                raise_log_error("ClassCastException on converter.ReadObject",e);
                            }
                           
                            // bersihin
                            bytebuf.clear();
                        }

On code "Map rxmap = (Map) rxobject", it will raise ClassCastException, and code stop there.

Printbytes from totalbytes array is the same as above printbytes
Printbytes from TotalBytes array:
TotalBytes : 78 9c 13 61 64 60 60 60 64 7 12 ce fe be be 8e 7e 2e 8c 9c 40 b6 bb 6b 48 70 88 63 48 68 30 0 35 74 4 eb

Can somebody give advice how to cast back from bytes --> Object --> Map ?
 

DonManfred

Expert
Licensed User
Longtime User
Do you want to use java or B4X code?

B4X:
Dim ser As B4XSerializator
    File.WriteBytes(File.DirInternal, "map.dat", ser.ConvertObjectToBytes(yourmap))

and

B4X:
Dim ser As B4XSerializator
dim bytes() as Byte= File.ReadBytes(File.DirInternal, "map.dat")
dim m as Map = ser.ConvertBytesToObject(bytes)
 
Upvote 0
Top