001/*
002 * ModeShape (http://www.modeshape.org)
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 */
016package org.modeshape.schematic.internal.io;
017
018import static org.junit.Assert.fail;
019import java.io.ByteArrayOutputStream;
020import java.io.DataOutputStream;
021import org.junit.After;
022import org.junit.Before;
023import org.junit.Test;
024
025public class BsonDataOutputTest {
026
027    private BsonDataOutput output;
028    private ByteArrayOutputStream bigEndianBytes;
029    private DataOutputStream bigEndian;
030    private ByteArrayOutputStream littleEndianBytes;
031
032    @Before
033    public void beforeMethod() {
034        this.output = new BsonDataOutput();
035        this.bigEndianBytes = new ByteArrayOutputStream();
036        this.bigEndian = new DataOutputStream(this.bigEndianBytes);
037        this.littleEndianBytes = new ByteArrayOutputStream();
038    }
039
040    @After
041    public void afterMethod() {
042    }
043
044    @Test
045    public void shouldWriteAndReadInteger() throws Exception {
046        output.writeInt(102);
047        bigEndian.writeInt(toLittleEndian(102));
048        output.writeTo(littleEndianBytes);
049        assertSame(littleEndianBytes.toByteArray(), bigEndianBytes.toByteArray(), "littleEndian", "bigEndian");
050    }
051
052    @Test
053    public void shouldWriteAndReadLong() throws Exception {
054        output.writeLong(102L);
055        bigEndian.writeLong(toLittleEndian(102L));
056        output.writeTo(littleEndianBytes);
057        assertSame(littleEndianBytes.toByteArray(), bigEndianBytes.toByteArray(), "littleEndian", "bigEndian");
058    }
059
060    @Test
061    public void shouldWriteAndReadShort() throws Exception {
062        output.writeShort(102);
063        bigEndian.writeShort(toLittleEndian((short)102));
064        output.writeTo(littleEndianBytes);
065        assertSame(littleEndianBytes.toByteArray(), bigEndianBytes.toByteArray(), "littleEndian", "bigEndian");
066    }
067
068    @Test
069    public void shouldWriteAndReadChar() throws Exception {
070        output.writeChar('c');
071        bigEndian.writeChar(toLittleEndian('c'));
072        output.writeTo(littleEndianBytes);
073        assertSame(littleEndianBytes.toByteArray(), bigEndianBytes.toByteArray(), "littleEndian", "bigEndian");
074    }
075
076    protected char toLittleEndian( char value ) {
077        byte b1 = (byte)value;
078        byte b2 = (byte)(value >> 8);
079        int result = b1 << 8 | (b2 & 0xFF);
080        return (char)result;
081    }
082
083    protected short toLittleEndian( short value ) {
084        byte b1 = (byte)value;
085        byte b2 = (byte)(value >> 8);
086        int result = b1 << 8 | (b2 & 0xFF);
087        return (short)result;
088    }
089
090    protected int toLittleEndian( int value ) {
091        byte b1 = (byte)value;
092        byte b2 = (byte)(value >> 8);
093        byte b3 = (byte)(value >> 16);
094        byte b4 = (byte)(value >> 24);
095        int result = b1 << 24 | (b2 & 0xFF) << 16 | (b3 & 0xFF) << 8 | (b4 & 0xFF);
096        return result;
097    }
098
099    protected long toLittleEndian( long value ) {
100        byte b1 = (byte)value;
101        byte b2 = (byte)(value >> 8);
102        byte b3 = (byte)(value >> 16);
103        byte b4 = (byte)(value >> 24);
104        byte b5 = (byte)(value >> 32);
105        byte b6 = (byte)(value >> 40);
106        byte b7 = (byte)(value >> 48);
107        byte b8 = (byte)(value >> 56);
108        long result = (b1 & 0xFFL) << 56 | (b2 & 0xFFL) << 48 | (b3 & 0xFFL) << 40 | (b4 & 0xFFL) << 32 | (b5 & 0xFFL) << 24
109                      | (b6 & 0xFFL) << 16 | (b7 & 0xFFL) << 8 | (b8 & 0xFFL);
110        return result;
111    }
112
113    @SuppressWarnings( "cast" )
114    protected void assertSame( byte[] b1,
115                               byte[] b2,
116                               String name1,
117                               String name2 ) {
118        if (b1.equals(b2)) return;
119        int s1 = b1.length;
120        int s2 = b2.length;
121        StringBuilder sb1 = new StringBuilder();
122        for (byte b : b1) {
123            sb1.append((int)b).append(' ');
124        }
125        StringBuilder sb2 = new StringBuilder();
126        for (byte b : b2) {
127            sb2.append((int)b).append(' ');
128        }
129        if (!sb1.toString().equals(sb2.toString())) {
130            System.out.println(name1 + " size: " + s1 + " content: " + sb1);
131            System.out.println(name2 + " size: " + s2 + " content: " + sb2);
132            fail();
133        }
134    }
135
136}