Package totalcross.io

Class CompressedByteArrayStream

  • All Implemented Interfaces:
    java.io.Closeable, java.lang.AutoCloseable

    public class CompressedByteArrayStream
    extends Stream
    Creates a compressed byte array stream, saving memory when reading and writting huge amount of data. Arrays of 16000 bytes will be created and each byte array will be compressed once filled and will be automatically decompressed on read. This saves space but adds a slowdown to the process. It is useful when transferring FTP files to/from the server.

    This class cannot be used for output AND input, but only for output OR input, in an absolutely sequential mode (the skipBytes method is NOT implemented): you must write everything, then read everything. To change the mode, use the setMode(READ_MODE or WRITE_MODE) method. No check is made to see if you're in the right mode, but your program will probably crash if you do it in the wrong one.

    Sample that transfers bytes to the server:

     CompressedByteArrayStream cbas = new CompressedByteArrayStream(9); // default mode is WRITE_MODE
     for (int i = 0; i < 50000; i++)
        cbas.writeLine("1234567890"); // already appends \r\n
     cbas.flush();
     cbas.setMode(CompressedByteArrayStream.READ_MODE); // prepare for read
     ftp.sendFile(cbas, "bigfile.txt", true);
     // if you want to send another one, just call
     
     cbas.setMode(CompressedByteArrayStream.WRITE_MODE);
     
     
    Sample that transfers bytes from the server:
     CompressedByteArrayStream cbas = new CompressedByteArrayStream(9);
     ftp.receiveFile("bigfile.txt", cbas);
     cbas.flush();
     String line;
     while ((line = cbas.readLine()) != null)
        // do something with the line!
     
    Here is another fully functional sample:
     int i;
     String g = "1234567890";
     CompressedByteArrayStream cbas = new CompressedByteArrayStream(9); // default mode is WRITE_MODE
     for (i = 0; i < 50000; i++)
        cbas.writeLine(g); // already appends \r\n
     cbas.flush();
     Vm.debug("size: " + cbas.getCompressedSize() + " -> " + cbas.getSize());
     String s;
     for (i = 0; (s = cbas.readLine()) != null; i++)
        if (!g.equals(s))
           Vm.debug("error in " + i);
     if (i != 50000)
        Vm.debug("i differs!");
     cbas.close();
     
    Note that, although the samples above use writeLine and readLine, you can store any kind of data. By attaching a DataStream it's possible to read any data type from the stream.
     CompressedByteArrayStream cbas = new CompressedByteArrayStream(5);
     DataStream ds = new DataStream(cbas);
     byte[] big = new byte[200000];
     // fill big with something
     ds.writeBytes(big);
     for (int i = 0; i < 100000; i++)
     {
        ds.writeInt(0x123456);
        ds.writeString("Natasha");
        ds.writeDouble(123.456d);
     }
     // well, now we do something with these!
     int realSize = cbas.getSize(); // just for fun
     int compressed = cbas.getCompressedSize(); // just for fun
     ds.readBytes(big);
     for (int i = 0; i < 100000; i++)
     {
        int i = ds.readInt();
        String love = ds.readString(); // Natasha
        double d = ds.readDouble();
     }
     
    Call the close method only when you're completely done in using it: all the internal buffers will be released, and reading from it will crash your program.

    Note that the readLine method will not work if there are any character with accentuation.

    • Nested Class Summary

      Nested Classes 
      Modifier and Type Class Description
      static class  CompressedByteArrayStream.DirectCharConverter
      Implements a CharacterConverter that converts from char[] to byte[] which just casts the char to byte; thus, ignoring any non-ASCII character.
    • Field Summary

      Fields 
      Modifier and Type Field Description
      static byte[] crlf
      Defines the line terminator, which is by default \r\n.
      static int DESTRUCTIVE_READ_MODE
      Used in the setMode method.
      static int READ_MODE
      Used in the setMode method.
      static int WRITE_MODE
      Used in the setMode method.
    • Constructor Summary

      Constructors 
      Constructor Description
      CompressedByteArrayStream()
      Creates a new CompressedByteArrayStream using the maximum compression level (9)
      CompressedByteArrayStream​(int compressionLevel)
      Creates a new CompressedByteArrayStream, using the given compression level (0 = no compression, 9 = max compression).
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      void close()
      Deletes all internal buffers.
      void flush()
      After everything was written, call this method to flush the internal buffers and prepare the CompressedByteArrayStream for read.
      int getCompressedSize()
      Returns the compressed size of the data written.
      int getSize()
      Returns the real (uncompressed) size of data written.
      int readBytes​(byte[] buffer, int start, int count)
      Transfers count bytes from the internal buffer to the given one.
      void readFully​(Stream inputStream, int retryCount, int bufSize)
      Reads all data from the input stream into our buffer.
      java.lang.String readLine()
      Reads a String until the next control character (newline, enter, tab, etc) is read.
      java.lang.String readUntilNextChar​(char c)
      Reads the buffer until the given character is found.
      void setMode​(int newMode)
      Changes the mode to the given one, calling flush if in write mode.
      int writeBytes​(byte[] buffer, int start, int count)
      This method writes to the byte array, expanding it if necessary.
      void writeLine​(java.lang.String s)
      Writes a line of text.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • READ_MODE

        public static final int READ_MODE
        Used in the setMode method. Turns the mode into READ.
        See Also:
        Constant Field Values
      • WRITE_MODE

        public static final int WRITE_MODE
        Used in the setMode method. Turns the mode into WRITE.
        See Also:
        Constant Field Values
      • DESTRUCTIVE_READ_MODE

        public static final int DESTRUCTIVE_READ_MODE
        Used in the setMode method. Turns the mode into READ, and after reading each buffer, discards it, releasing memory. CompressedByteArrayStream will not be able to read the buffer again. This is useful when you download data and then want to read from it, releasing memory on-demand.
        See Also:
        Constant Field Values
      • crlf

        public static byte[] crlf
        Defines the line terminator, which is by default \r\n. To change it to a single \n use CompressedByteArrayStream.crlf = new byte[]{'\n'};
    • Constructor Detail

      • CompressedByteArrayStream

        public CompressedByteArrayStream​(int compressionLevel)
                                  throws java.lang.IllegalArgumentException
        Creates a new CompressedByteArrayStream, using the given compression level (0 = no compression, 9 = max compression).
        Throws:
        java.lang.IllegalArgumentException
      • CompressedByteArrayStream

        public CompressedByteArrayStream()
        Creates a new CompressedByteArrayStream using the maximum compression level (9)
    • Method Detail

      • flush

        public void flush()
                   throws IOException
        After everything was written, call this method to flush the internal buffers and prepare the CompressedByteArrayStream for read. It is already called by setMode when it changes the modes.
        Throws:
        IOException
        See Also:
        setMode(int)
      • close

        public void close()
        Deletes all internal buffers. Do not try to use the object afterwards.
        Specified by:
        close in interface java.lang.AutoCloseable
        Specified by:
        close in interface java.io.Closeable
      • getSize

        public int getSize()
        Returns the real (uncompressed) size of data written.
      • getCompressedSize

        public int getCompressedSize()
        Returns the compressed size of the data written.
      • readBytes

        public int readBytes​(byte[] buffer,
                             int start,
                             int count)
                      throws IOException
        Transfers count bytes from the internal buffer to the given one.
        Specified by:
        readBytes in class Stream
        Parameters:
        buffer - the byte array to read data into
        start - the start position in the array
        count - the number of bytes to read
        Returns:
        the number of bytes read. If an error occurred, -1 is returned and
        Throws:
        IOException
      • writeBytes

        public int writeBytes​(byte[] buffer,
                              int start,
                              int count)
                       throws IOException,
                              java.lang.IllegalArgumentException
        This method writes to the byte array, expanding it if necessary.
        Specified by:
        writeBytes in class Stream
        Parameters:
        buffer - the byte array to write data from
        start - the start position in the byte array
        count - the number of bytes to write
        Returns:
        the number of bytes written. If an error occurred, -1 is returned and
        Throws:
        IOException
        java.lang.IllegalArgumentException
        Since:
        SuperWaba 2.0 beta 2
      • readLine

        public java.lang.String readLine()
                                  throws IOException
        Reads a String until the next control character (newline, enter, tab, etc) is read.
        Returns:
        A line of text read from internal buffer or null if no more lines are available.
        Throws:
        IOException
      • readFully

        public void readFully​(Stream inputStream,
                              int retryCount,
                              int bufSize)
                       throws IOException
        Reads all data from the input stream into our buffer. Note that setMode(WRITE) is called prior to writting. When returned, data is ready to be read.
        Parameters:
        inputStream - The input stream from where data will be read
        retryCount - The number of times to retry if no data is read. In remote connections, use at least 5; for files, it can be 0.
        bufSize - The size of the buffer used to read data.
        Throws:
        IOException
        Since:
        SuperWaba 5.7
      • writeLine

        public void writeLine​(java.lang.String s)
                       throws IOException
        Writes a line of text. The \r\n line terminator is appended to the line. You can avoid this by setting CompressedByteArrayStream.crlf = new byte[0];
        Parameters:
        s - the String to be written; cannot be null!
        Throws:
        IOException
      • readUntilNextChar

        public java.lang.String readUntilNextChar​(char c)
                                           throws IOException
        Reads the buffer until the given character is found.
        Returns:
        A line of text read from internal buffer or null if no more lines are available.
        Throws:
        IOException