private ByteBuf encode0(RequestContext ctx, WebSocketFrame msg) {
        final WebSocketFrameType type = msg.type();
        final int length = msg.length();
        if (type.isControlFrame() && length > 125) {
            throw new TooLongFrameException("the payload length " + length +
                                            " of a control frame exceeded the limit 125. frame type: " + type);
        }

        logger.trace("Encoding a WebSocket Frame. type: {}, length: {}", type.opcode(), length);

        // https://datatracker.ietf.org/doc/html/rfc6455#section-5.2
        int b0 = 0;
        if (msg.isFinalFragment()) {
            b0 |= 1 << 7;
        }
        // b0 |= msg.rsv() << 4; // TODO(minwoox): Support rsv when we introduce the extension.
        b0 |= type.opcode();

        boolean release = true;
        ByteBuf buf = null;
        try {
            final int maskLength = maskPayload ? 4 : 0;
            if (length <= 125) {
                final int size = 2 + maskLength + length;
                buf = ctx.alloc().buffer(size);
                buf.writeByte(b0);
                // maskPayload + payload length (<= 125)
                final byte b = (byte) (maskPayload ? 0x80 | (byte) length : (byte) length);
                buf.writeByte(b);
            } else if (length <= 65535) {
                int size = 4 + maskLength;
                if (maskPayload || length <= GATHERING_WRITE_THRESHOLD) {
                    size += length;
                }
                buf = ctx.alloc().buffer(size);
                buf.writeByte(b0);
                // maskPayload + payload length (== 126). When payload length is 126, following two bytes
                // are the payload length.
                buf.writeByte(maskPayload ? 0xFE : 126); // 11111110 : 01111110
                buf.writeByte(length >>> 8 & 0xFF);
                buf.writeByte(length & 0xFF);
            } else {
                int size = 10 + maskLength;
                if (maskPayload) {
                    size += length;
                }
                buf = ctx.alloc().buffer(size);
                buf.writeByte(b0);
                // maskPayload + payload length (== 127). When payload length is 127, following 8 bytes
                // are the payload length.
                buf.writeByte(maskPayload ? 0xFF : 127);
                buf.writeLong(length);
            }

            // Write payload
            if (maskPayload) {
                final int mask = ThreadLocalRandom.current().nextInt(Integer.MAX_VALUE);
                buf.writeInt(mask);

                long longMask = mask & 0xFFFFFFFFL;
                longMask |= longMask << 32;

                final ByteBuf data = msg.byteBuf();
                int i = data.readerIndex();
                final int end = data.writerIndex();
                for (final int lim = end - 7; i < lim; i += 8) {
                    buf.writeLong(data.getLong(i) ^ longMask);
                }

                if (i < end - 3) {
                    buf.writeInt(data.getInt(i) ^ (int) longMask);
                    i += 4;
                }
                int maskOffset = 0;
                for (; i < end; i++) {
                    final byte byteData = data.getByte(i);
                    buf.writeByte(byteData ^ byteAtIndex(mask, maskOffset++ & 3));
                }
            } else {
                if (buf.writableBytes() >= msg.length()) {
                    // merge buffers as this is cheaper than a gathering write if the payload is small enough
                    buf.writeBytes(msg.byteBuf());
                } else {
                    buf = Unpooled.wrappedBuffer(buf, msg.byteBuf(ByteBufAccessMode.FOR_IO));
                }
            }
            release = false;
            return buf;
        } finally {
            if (release && buf != null) {
                buf.release();
            }
        }
    }
The size threshold for gathering writes. Non-Masked messages bigger than this size will be sent
fragmented as a header and a content ByteBuf whereas messages smaller than the size will be merged
into a single buffer and sent at once.<br>
Masked messages will always be sent at once.
core/src/main/java/com/linecorp/armeria/internal/common/websocket/WebSocketFrameEncoder.java