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

org.glassfish.tyrus.core.Frame Maven / Gradle / Ivy

There is a newer version: 3.1.1
Show newest version
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2013-2014 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * http://glassfish.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

package org.glassfish.tyrus.core;

import java.security.SecureRandom;

/**
 * WebSocket frame representation.
 * 

*

TODO:
 * - masking (isMask is currently ignored)
 * - validation
 * - payloadLength is limited to int
* * @author Pavel Bucek (pavel.bucek at oracle.com) */ public class Frame { private final boolean fin; private final boolean rsv1; private final boolean rsv2; private final boolean rsv3; private final boolean mask; private final byte opcode; private final long payloadLength; private final int maskingKey; private final byte[] payloadData; private final boolean controlFrame; /** * Copy constructor. *

* Note: this is shallow copy. Payload is *not* copied to new array. * * @param frame copied frame. */ protected Frame(Frame frame) { this.fin = frame.fin; this.rsv1 = frame.rsv1; this.rsv2 = frame.rsv2; this.rsv3 = frame.rsv3; this.mask = frame.mask; this.opcode = frame.opcode; this.payloadLength = frame.payloadLength; this.maskingKey = frame.maskingKey; this.payloadData = frame.payloadData; this.controlFrame = (opcode & 0x08) == 0x08; } private Frame(boolean fin, boolean rsv1, boolean rsv2, boolean rsv3, boolean mask, byte opcode, long payloadLength, int maskingKey, byte[] payloadData) { this.fin = fin; this.rsv1 = rsv1; this.rsv2 = rsv2; this.rsv3 = rsv3; this.mask = mask; this.opcode = opcode; this.payloadLength = payloadLength; this.maskingKey = maskingKey; this.payloadData = payloadData; this.controlFrame = (opcode & 0x08) == 0x08; } /** * Get FIN value. * * @return {@code true} when FIN flag is set, {@code false} otherwise. */ public boolean isFin() { return fin; } /** * GET RSV1 value. * * @return {@code true} when RSV1 flag is set, {@code false} otherwise. */ public boolean isRsv1() { return rsv1; } /** * GET RSV2 value. * * @return {@code true} when RSV2 flag is set, {@code false} otherwise. */ public boolean isRsv2() { return rsv2; } /** * GET RSV3 value. * * @return {@code true} when RSV3 flag is set, {@code false} otherwise. */ public boolean isRsv3() { return rsv3; } /** * Currently not used. * * @return not used. */ public boolean isMask() { return mask; } /** * Get opcode. * * @return opcode (4 bit value). */ public byte getOpcode() { return opcode; } /** * Get payload length. * * @return payload length. */ public long getPayloadLength() { return payloadLength; } /** * Get masking key. * * @return masking key (32 bit value). */ public int getMaskingKey() { return maskingKey; } /** * Get payload data. *

* Changes done to returned array won't be propagated to current {@link Frame} instance. If you need to modify payload, * you have to create new instance, see {@link org.glassfish.tyrus.core.Frame.Builder#Frame(Frame)}. Length of returned * array will be always same as {@link #getPayloadLength()}. * * @return payload data. */ public byte[] getPayloadData() { byte[] tmp = new byte[(int) payloadLength]; System.arraycopy(payloadData, 0, tmp, 0, (int) payloadLength); return tmp; } /** * Get information about frame type. * * @return {@code true} when this frame is control (close, ping, pong) frame, {@code false} otherwise. */ public boolean isControlFrame() { return controlFrame; } @Override public String toString() { final StringBuilder sb = new StringBuilder("Frame{"); sb.append("fin=").append(fin); sb.append(", rsv1=").append(rsv1); sb.append(", rsv2=").append(rsv2); sb.append(", rsv3=").append(rsv3); sb.append(", mask=").append(mask); sb.append(", opcode=").append(opcode); sb.append(", payloadLength=").append(payloadLength); sb.append(", maskingKey=").append(maskingKey); sb.append('}'); return sb.toString(); } /** * Create new {@link org.glassfish.tyrus.core.Frame.Builder}. * * @return new builder instance. */ public static Builder builder() { return new Builder(); } /** * Create new {@link org.glassfish.tyrus.core.Frame.Builder} based on provided frame. * * @param frame frame used as a base for building new frame. * @return new builder instance. */ public static Builder builder(Frame frame) { return new Builder(frame); } /** * Frame builder. */ public final static class Builder { private boolean fin; private boolean rsv1; private boolean rsv2; private boolean rsv3; private boolean mask; private byte opcode; private long payloadLength; private int maskingKey = new SecureRandom().nextInt(); private byte[] payloadData; /** * Constructor. */ public Builder() { } /** * Constructor. * * @param frame frame used as a base for building new frame. */ public Builder(Frame frame) { this.fin = frame.fin; this.rsv1 = frame.rsv1; this.rsv2 = frame.rsv2; this.rsv3 = frame.rsv3; this.mask = frame.mask; this.opcode = frame.opcode; this.payloadLength = frame.payloadLength; this.maskingKey = frame.maskingKey; this.payloadData = frame.payloadData; } /** * Build new frame. * * @return built frame. */ public Frame build() { return new Frame(fin, rsv1, rsv2, rsv3, mask, opcode, payloadLength, maskingKey, payloadData); } /** * Set FIN flag. * * @param fin value to be set as FIN. * @return updated {@link org.glassfish.tyrus.core.Frame.Builder} instance. */ public Builder fin(boolean fin) { this.fin = fin; return this; } /** * Set RSV1 flag. * * @param rsv1 value to be set as RSV1. * @return updated {@link org.glassfish.tyrus.core.Frame.Builder} instance. */ public Builder rsv1(boolean rsv1) { this.rsv1 = rsv1; return this; } /** * Set RSV2 flag. * * @param rsv2 value to be set as RSV2. * @return updated {@link org.glassfish.tyrus.core.Frame.Builder} instance. */ public Builder rsv2(boolean rsv2) { this.rsv2 = rsv2; return this; } /** * Set RSV3 flag. * * @param rsv3 value to be set as RSV3. * @return updated {@link org.glassfish.tyrus.core.Frame.Builder} instance. */ public Builder rsv3(boolean rsv3) { this.rsv3 = rsv3; return this; } /** * Currently not used. * * @param mask not used. * @return updated {@link org.glassfish.tyrus.core.Frame.Builder} instance. */ public Builder mask(boolean mask) { this.mask = mask; return this; } /** * Set opcode. * * @param opcode opcode to be set. (4 bits). * @return updated {@link org.glassfish.tyrus.core.Frame.Builder} instance. */ public Builder opcode(byte opcode) { this.opcode = (byte) (opcode & 0x0f); return this; } /** * Set payload length. *

* Payload length is automatically set to payloadData length when {@link #payloadData(byte[])} is called. This * method can limit the data used for this frame by setting smaller value than payloadData.length. * * @param payloadLength payload length. Must not be greater than payloadData.length. * @return updated {@link org.glassfish.tyrus.core.Frame.Builder} instance. * @see #payloadData(byte[]) */ public Builder payloadLength(long payloadLength) { this.payloadLength = payloadLength; return this; } /** * Set masking key. Default value is {@code new SecureRandom().nextInt();}. * * @param maskingKey masking key. * @return updated {@link org.glassfish.tyrus.core.Frame.Builder} instance. */ public Builder maskingKey(int maskingKey) { this.maskingKey = maskingKey; return this; } /** * Set payload data. {@link #payloadLength(long)} is also updated with payloadData.length. * * @param payloadData data to be set. * @return updated {@link org.glassfish.tyrus.core.Frame.Builder} instance. * @see #payloadLength(long) */ public Builder payloadData(byte[] payloadData) { this.payloadData = payloadData; this.payloadLength = payloadData.length; return this; } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy