/********************************************************************************* * TotalCross Software Development Kit * * Copyright (C) 2000-2012 SuperWaba Ltda. * * All Rights Reserved * * * * This library and virtual machine is distributed in the hope that it will * * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * * * This file is covered by the GNU LESSER GENERAL PUBLIC LICENSE VERSION 3.0 * * A copy of this license is located in file license.txt at the root of this * * SDK or can be downloaded here: * * http://www.gnu.org/licenses/lgpl-3.0.txt * * * *********************************************************************************/ package totalcross.io; /** * DataStreamLE can be attached to any Stream such as a * PortConnector, PDBFile, or ByteArrayStream, which lets you read and write * standard Java data types like int, double, and String in a simple * manner. Here's an example: * * <pre> * PortConnector port = new PortConnector(9600, 0); * DataStream ds = new DataStream(port); * ds.writeString("Hello"); * int status = ds.readUnsignedByte(); * if (status == 1) * { * ds.writeString("Pi"); * ds.writeDouble(3.14); * } * port.close(); * </pre> * * <br> * <b>Important!</b>: All methods * read and write numeric data in the little endian format (Intel format). * For more information, see <a target=_blank * href='http://www.webopedia.com/TERM/l/little_endian.html'>this</a>. * @see DataStream */ public class DataStreamLE extends DataStream { /** * Constructs a new DataStreamLE which sits upon the given stream using litle * endian notation for multibyte values. * * @param stream the base stream */ public DataStreamLE(Stream stream) { super(stream); } public int readInt() throws EOFException, totalcross.io.IOException { byte[] b = buffer; readBytesInternal(b, 0, 4, true); return (((b[3] & 0xFF) << 24) | ((b[2] & 0xFF) << 16) | ((b[1] & 0xFF) << 8) | (b[0] & 0xFF)); } public short readShort() throws EOFException, totalcross.io.IOException { byte[] b = buffer; readBytesInternal(b, 0, 2, true); return (short) (((b[1] & 0xFF) << 8) | (b[0] & 0xFF)); } public long readLong() throws EOFException, totalcross.io.IOException { long l1 = (long) readInt() & 0xFFFFFFFFL; long l2 = (long) readInt() & 0xFFFFFFFFL; return (l2 << 32) | l1; } public int readUnsignedShort() throws EOFException, totalcross.io.IOException { byte[] b = buffer; readBytesInternal(b, 0, 2, true); return (((b[1] & 0xFF) << 8) | (b[0] & 0xFF)); } public int writeInt(int i) throws totalcross.io.IOException { byte[] b = buffer; b[0] = (byte)i; i >>= 8; // guich@300_40 b[1] = (byte)i; i >>= 8; b[2] = (byte)i; i >>= 8; b[3] = (byte)i; return writeBytesInternal(b, 0, 4); } public int writeShort(int i) throws totalcross.io.IOException { byte[] b = buffer; b[0] = (byte)i; i >>= 8; // guich@300_40 b[1] = (byte)i; return writeBytesInternal(b, 0, 2); } public int writeLong(long l) throws totalcross.io.IOException { return writeInt((int)l) + writeInt((int)(l >> 32)); } public char readChar() throws EOFException, totalcross.io.IOException // guich@421_31 { byte[] b = buffer; readBytesInternal(b, 0, 2, true); return (char) (((b[1] & 0xFF) << 8) | (b[0] & 0xFF)); } public int writeChar(char c) throws totalcross.io.IOException // guich@421_31 { byte[] b = buffer; b[0] = (byte)c; c >>= 8; b[1] = (byte)c; return writeBytesInternal(b, 0, 2); } /** * Reads a char array with the given length. * * @param chars An already created chars array. * @param len The array length. * @throws EOFException * @throws totalcross.io.IOException * @since TotalCross 1.01 */ public void readChars(char[] chars, int len) throws EOFException, totalcross.io.IOException { byte[] bytes = buffer; int buflen = bytes.length / 2, start = 0; while (len > 0) { int avail = (len > buflen ? buflen : len) * 2; readBytesInternal(bytes, 0, avail, true); for (int i =0; i < avail; i += 2) chars[start++] = (char) (((bytes[i+1] & 0xFF) << 8) | (bytes[i] & 0xFF)); len -= avail / 2; } } protected char[] readChars(int len) throws EOFException, totalcross.io.IOException { char[] chars = new char[len]; byte[] bytes = buffer; int buflen = bytes.length / 2, start = 0; while (len > 0) { int avail = (len > buflen ? buflen : len) * 2; readBytesInternal(bytes, 0, avail, true); for (int i =0; i < avail; i += 2) chars[start++] = (char) (((bytes[i+1] & 0xFF) << 8) | (bytes[i] & 0xFF)); len -= avail / 2; } return chars; } public int writeChars(char[] chars, int start, int len, int lenSize) throws totalcross.io.IOException { int n=0,c; if (len < 0) len = chars == null ? 0 : chars.length; len -= start; if (len < 0) len = 0; // eisvogel@421_70 if (lenSize == 2) { if (len > 65535) throw new IOException("String size "+len+" is too big to use with writeChars!"); n = writeShort(len); } else if (lenSize == 4) n = writeInt(len); else if (lenSize == 1) { if (len > 255) throw new IOException("String size "+len+" is too big to use with writeChars!"); n = writeByte(len); } byte[] bytes = buffer; int buflen = bytes.length / 2; while (len > 0) { int avail = (len > buflen ? buflen : len) * 2; for (int i =0; i < avail; i += 2) { c = chars[start++]; bytes[i] = (byte)c; bytes[i+1] = (byte)(c>>8); } n += writeBytesInternal(bytes, 0, avail); len -= avail / 2; } return n; } public int writeChars(String s, int len) throws totalcross.io.IOException { int c; int start = 0; int n = writeShort(len); byte[] bytes = buffer; int buflen = bytes.length / 2; while (len > 0) { int avail = (len > buflen ? buflen : len) * 2; for (int i =0; i < avail; i += 2) { c = s.charAt(start++); bytes[i] = (byte)c; bytes[i+1] = (byte)(c>>8); } n += writeBytesInternal(bytes, 0, avail); len -= avail / 2; } return n; } }