001 /*
002 * Copyright (C) 2007 The Guava Authors
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017 package com.google.common.io;
018
019 import com.google.common.annotations.Beta;
020 import com.google.common.base.Preconditions;
021 import com.google.common.primitives.Longs;
022
023 import java.io.DataOutput;
024 import java.io.DataOutputStream;
025 import java.io.FilterOutputStream;
026 import java.io.IOException;
027 import java.io.OutputStream;
028
029 /**
030 * An implementation of {@link DataOutput} that uses little-endian byte ordering
031 * for writing {@code char}, {@code short}, {@code int}, {@code float}, {@code
032 * double}, and {@code long} values.
033 * <p>
034 * <b>Note:</b> This class intentionally violates the specification of its
035 * supertype {@code DataOutput}, which explicitly requires big-endian byte
036 * order.
037 *
038 * @author Chris Nokleberg
039 * @author Keith Bottner
040 * @since 8.0
041 */
042 @Beta
043 public class LittleEndianDataOutputStream extends FilterOutputStream
044 implements DataOutput {
045
046 /**
047 * Creates a {@code LittleEndianDataOutputStream} that wraps the given stream.
048 *
049 * @param out the stream to delegate to
050 */
051 public LittleEndianDataOutputStream(OutputStream out) {
052 super(new DataOutputStream(Preconditions.checkNotNull(out)));
053 }
054
055
056 @Override
057 public void write(byte[] b, int off, int len) throws IOException {
058 // Override slow FilterOutputStream impl
059 out.write(b, off, len);
060 }
061
062 public void writeBoolean(boolean v) throws IOException {
063 ((DataOutputStream) out).writeBoolean(v);
064 }
065
066 public void writeByte(int v) throws IOException {
067 ((DataOutputStream) out).writeByte(v);
068 }
069
070 /**
071 * @deprecated The semantics of {@code writeBytes(String s)} are considered
072 * dangerous. Please use {@link #writeUTF(String s)},
073 * {@link #writeChars(String s)} or another write method instead.
074 */
075 @Deprecated
076 public void writeBytes(String s) throws IOException {
077 ((DataOutputStream) out).writeBytes(s);
078 }
079
080 /**
081 * Writes a char as specified by {@link DataOutputStream#writeChar(int)},
082 * except using little-endian byte order.
083 *
084 * @throws IOException if an I/O error occurs
085 */
086 public void writeChar(int v) throws IOException {
087 writeShort(v);
088 }
089
090 /**
091 * Writes a {@code String} as specified by
092 * {@link DataOutputStream#writeChars(String)}, except each character is
093 * written using little-endian byte order.
094 *
095 * @throws IOException if an I/O error occurs
096 */
097 public void writeChars(String s) throws IOException {
098 for (int i = 0; i < s.length(); i++) {
099 writeChar(s.charAt(i));
100 }
101 }
102
103 /**
104 * Writes a {@code double} as specified by
105 * {@link DataOutputStream#writeDouble(double)}, except using little-endian
106 * byte order.
107 *
108 * @throws IOException if an I/O error occurs
109 */
110 public void writeDouble(double v) throws IOException {
111 writeLong(Double.doubleToLongBits(v));
112 }
113
114 /**
115 * Writes a {@code float} as specified by
116 * {@link DataOutputStream#writeFloat(float)}, except using little-endian byte
117 * order.
118 *
119 * @throws IOException if an I/O error occurs
120 */
121 public void writeFloat(float v) throws IOException {
122 writeInt(Float.floatToIntBits(v));
123 }
124
125 /**
126 * Writes an {@code int} as specified by
127 * {@link DataOutputStream#writeInt(int)}, except using little-endian byte
128 * order.
129 *
130 * @throws IOException if an I/O error occurs
131 */
132 public void writeInt(int v) throws IOException {
133 out.write(0xFF & v);
134 out.write(0xFF & (v >> 8));
135 out.write(0xFF & (v >> 16));
136 out.write(0xFF & (v >> 24));
137 }
138
139 /**
140 * Writes a {@code long} as specified by
141 * {@link DataOutputStream#writeLong(long)}, except using little-endian byte
142 * order.
143 *
144 * @throws IOException if an I/O error occurs
145 */
146 public void writeLong(long v) throws IOException {
147 byte[] bytes = Longs.toByteArray(Long.reverseBytes(v));
148 write(bytes, 0, bytes.length);
149 }
150
151 /**
152 * Writes a {@code short} as specified by
153 * {@link DataOutputStream#writeShort(int)}, except using little-endian byte
154 * order.
155 *
156 * @throws IOException if an I/O error occurs
157 */
158 public void writeShort(int v) throws IOException {
159 out.write(0xFF & v);
160 out.write(0xFF & (v >> 8));
161 }
162
163 public void writeUTF(String str) throws IOException {
164 ((DataOutputStream) out).writeUTF(str);
165 }
166 }