All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bson.io.OutputBuffer Maven / Gradle / Ivy

Go to download

The MongoDB Java Driver uber-artifact, containing mongodb-driver, mongodb-driver-core, and bson

There is a newer version: 3.12.14
Show newest version
/*
 * Copyright 2008-present MongoDB, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.bson.io;

import org.bson.BsonSerializationException;
import org.bson.ByteBuf;
import org.bson.types.ObjectId;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;

import static java.lang.String.format;

/**
 * An abstract base class for classes implementing {@code BsonOutput}.
 */
public abstract class OutputBuffer extends OutputStream implements BsonOutput {

    @Override
    public void write(final byte[] b) {
        write(b, 0, b.length);
    }

    @Override
    public void close() {
    }

    @Override
    public void write(final byte[] bytes, final int offset, final int length) {
        writeBytes(bytes, offset, length);
    }

    @Override
    public void writeBytes(final byte[] bytes) {
        writeBytes(bytes, 0, bytes.length);
    }

    @Override
    public void writeInt32(final int value) {
        write(value >> 0);
        write(value >> 8);
        write(value >> 16);
        write(value >> 24);
    }

    @Override
    public void writeInt32(final int position, final int value) {
        write(position, value >> 0);
        write(position + 1, value >> 8);
        write(position + 2, value >> 16);
        write(position + 3, value >> 24);
    }

    @Override
    public void writeInt64(final long value) {
        write((byte) (0xFFL & (value >> 0)));
        write((byte) (0xFFL & (value >> 8)));
        write((byte) (0xFFL & (value >> 16)));
        write((byte) (0xFFL & (value >> 24)));
        write((byte) (0xFFL & (value >> 32)));
        write((byte) (0xFFL & (value >> 40)));
        write((byte) (0xFFL & (value >> 48)));
        write((byte) (0xFFL & (value >> 56)));
    }

    @Override
    public void writeDouble(final double x) {
        writeLong(Double.doubleToRawLongBits(x));
    }

    @Override
    public void writeString(final String str) {
        writeInt(0); // making space for size
        int strLen = writeCharacters(str, false);
        writeInt32(getPosition() - strLen - 4, strLen);
    }

    @Override
    public void writeCString(final String value) {
        writeCharacters(value, true);
    }

    @Override
    public void writeObjectId(final ObjectId value) {
        write(value.toByteArray());
    }

    /**
     * Gets the output size in bytes.
     * @return the size
     */
    public int size() {
        return getSize();
    }

    /**
     * Pipe the contents of this output buffer into the given output stream
     *
     * @param out the stream to pipe to
     * @return number of bytes written to the stream
     * @throws java.io.IOException if the stream throws an exception
     */
    public abstract int pipe(OutputStream out) throws IOException;

    /**
     * Get a list of byte buffers that are prepared to be read from; in other words, whose position is 0 and whose limit is the number of
     * bytes that should read. 

Note that the byte buffers may be read-only.

* * @return the non-null list of byte buffers, in LITTLE_ENDIAN order */ public abstract List getByteBuffers(); @Override public abstract void truncateToPosition(int newPosition); /** * Gets a copy of the buffered bytes. * * @return the byte array * @see org.bson.io.OutputBuffer#pipe(java.io.OutputStream) */ public byte[] toByteArray() { try { ByteArrayOutputStream bout = new ByteArrayOutputStream(size()); pipe(bout); return bout.toByteArray(); } catch (IOException ioe) { throw new RuntimeException("should be impossible", ioe); } } @Override public void write(final int value) { writeByte(value); } /** * Writes the given integer value to the buffer. * * @param value the value to write * @see #writeInt32 */ public void writeInt(final int value) { writeInt32(value); } @Override public String toString() { return getClass().getName() + " size: " + size() + " pos: " + getPosition(); } /** * Write the specified byte at the specified position. * * @param position the position, which must be greater than equal to 0 and at least 4 less than the stream size * @param value the value to write. The 24 high-order bits of the value are ignored. */ protected abstract void write(int position, int value); /** * Writes the given long value to the buffer. * * @param value the value to write * @see #writeInt64 */ public void writeLong(final long value) { writeInt64(value); } private int writeCharacters(final String str, final boolean checkForNullCharacters) { int len = str.length(); int total = 0; for (int i = 0; i < len;) { int c = Character.codePointAt(str, i); if (checkForNullCharacters && c == 0x0) { throw new BsonSerializationException(format("BSON cstring '%s' is not valid because it contains a null character " + "at index %d", str, i)); } if (c < 0x80) { write((byte) c); total += 1; } else if (c < 0x800) { write((byte) (0xc0 + (c >> 6))); write((byte) (0x80 + (c & 0x3f))); total += 2; } else if (c < 0x10000) { write((byte) (0xe0 + (c >> 12))); write((byte) (0x80 + ((c >> 6) & 0x3f))); write((byte) (0x80 + (c & 0x3f))); total += 3; } else { write((byte) (0xf0 + (c >> 18))); write((byte) (0x80 + ((c >> 12) & 0x3f))); write((byte) (0x80 + ((c >> 6) & 0x3f))); write((byte) (0x80 + (c & 0x3f))); total += 4; } i += Character.charCount(c); } write((byte) 0); total++; return total; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy