11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/* 21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2007 The Guava Authors 31d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 41d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License"); 51d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * you may not use this file except in compliance with the License. 61d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * You may obtain a copy of the License at 71d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 81d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0 91d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unless required by applicable law or agreed to in writing, software 111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS, 121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * See the License for the specific language governing permissions and 141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * limitations under the License. 151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpackage com.google.common.io; 181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.Beta; 201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Preconditions; 211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.primitives.Longs; 221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.DataOutput; 241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.DataOutputStream; 251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.FilterOutputStream; 261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.IOException; 271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.OutputStream; 281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/** 301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * An implementation of {@link DataOutput} that uses little-endian byte ordering 311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * for writing {@code char}, {@code short}, {@code int}, {@code float}, {@code 321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * double}, and {@code long} values. 331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p> 341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <b>Note:</b> This class intentionally violates the specification of its 351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * supertype {@code DataOutput}, which explicitly requires big-endian byte 361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * order. 371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Chris Nokleberg 391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Keith Bottner 401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 8.0 411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@Beta 430888a09821a98ac0680fad765217302858e70fa4Paul Duffinpublic class LittleEndianDataOutputStream extends FilterOutputStream 440888a09821a98ac0680fad765217302858e70fa4Paul Duffin implements DataOutput { 451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates a {@code LittleEndianDataOutputStream} that wraps the given stream. 481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param out the stream to delegate to 501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public LittleEndianDataOutputStream(OutputStream out) { 521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super(new DataOutputStream(Preconditions.checkNotNull(out))); 531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 550888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public void write(byte[] b, int off, int len) throws IOException { 561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Override slow FilterOutputStream impl 571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert out.write(b, off, len); 581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 600888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public void writeBoolean(boolean v) throws IOException { 611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ((DataOutputStream) out).writeBoolean(v); 621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 640888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public void writeByte(int v) throws IOException { 651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ((DataOutputStream) out).writeByte(v); 661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @deprecated The semantics of {@code writeBytes(String s)} are considered 701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * dangerous. Please use {@link #writeUTF(String s)}, 711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link #writeChars(String s)} or another write method instead. 721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Deprecated 740888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public void writeBytes(String s) throws IOException { 751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ((DataOutputStream) out).writeBytes(s); 761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Writes a char as specified by {@link DataOutputStream#writeChar(int)}, 801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * except using little-endian byte order. 811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IOException if an I/O error occurs 831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 840888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public void writeChar(int v) throws IOException { 851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert writeShort(v); 861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Writes a {@code String} as specified by 901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link DataOutputStream#writeChars(String)}, except each character is 911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * written using little-endian byte order. 921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IOException if an I/O error occurs 941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 950888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public void writeChars(String s) throws IOException { 961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < s.length(); i++) { 971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert writeChar(s.charAt(i)); 981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Writes a {@code double} as specified by 1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link DataOutputStream#writeDouble(double)}, except using little-endian 1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * byte order. 1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IOException if an I/O error occurs 1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1080888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public void writeDouble(double v) throws IOException { 1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert writeLong(Double.doubleToLongBits(v)); 1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Writes a {@code float} as specified by 1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link DataOutputStream#writeFloat(float)}, except using little-endian byte 1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * order. 1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IOException if an I/O error occurs 1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1190888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public void writeFloat(float v) throws IOException { 1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert writeInt(Float.floatToIntBits(v)); 1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Writes an {@code int} as specified by 1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link DataOutputStream#writeInt(int)}, except using little-endian byte 1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * order. 1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IOException if an I/O error occurs 1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1300888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public void writeInt(int v) throws IOException { 1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert out.write(0xFF & v); 1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert out.write(0xFF & (v >> 8)); 1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert out.write(0xFF & (v >> 16)); 1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert out.write(0xFF & (v >> 24)); 1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Writes a {@code long} as specified by 1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link DataOutputStream#writeLong(long)}, except using little-endian byte 1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * order. 1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IOException if an I/O error occurs 1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1440888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public void writeLong(long v) throws IOException { 1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert byte[] bytes = Longs.toByteArray(Long.reverseBytes(v)); 1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert write(bytes, 0, bytes.length); 1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Writes a {@code short} as specified by 1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link DataOutputStream#writeShort(int)}, except using little-endian byte 1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * order. 1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IOException if an I/O error occurs 1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1560888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public void writeShort(int v) throws IOException { 1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert out.write(0xFF & v); 1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert out.write(0xFF & (v >> 8)); 1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1610888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public void writeUTF(String str) throws IOException { 1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ((DataOutputStream) out).writeUTF(str); 1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1640888a09821a98ac0680fad765217302858e70fa4Paul Duffin 1650888a09821a98ac0680fad765217302858e70fa4Paul Duffin // Overriding close() because FilterOutputStream's close() method pre-JDK8 has bad behavior: 1660888a09821a98ac0680fad765217302858e70fa4Paul Duffin // it silently ignores any exception thrown by flush(). Instead, just close the delegate stream. 1670888a09821a98ac0680fad765217302858e70fa4Paul Duffin // It should flush itself if necessary. 1680888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public void close() throws IOException { 1690888a09821a98ac0680fad765217302858e70fa4Paul Duffin out.close(); 1700888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert} 172