<commit_before>package spray.can.websocket.frame

import akka.util.ByteString
import java.nio.ByteOrder
import java.nio.charset.Charset
import java.io.{ Closeable, InputStream }
import spray.can.websocket.UTF8Validator

/**
 *
 * http://tools.ietf.org/html/rfc6455
 */
object Frame {
  implicit val byteOrder = ByteOrder.BIG_ENDIAN
  val UTF8 = Charset.forName("UTF-8")

  /**
   * Octet i of the transformed data ("transformed-octet-i") is the XOR of
   * octet i of the original data ("original-octet-i") with octet at index
   * i modulo 4 of the masking key ("masking-key-octet-j"):
   *
   * j                   = i MOD 4
   * transformed-octet-i = original-octet-i XOR masking-key-octet-j
   */
  def maskData(data: Array[Byte], maskingKey: Array[Byte]): Array[Byte] = {
    var i = 0
    while (i < data.length) {
      data(i) = (data(i) ^ (maskingKey(i % 4))).toByte
      i += 1
    }
    data
  }

  def maskData(data: ByteString, maskingKey: Array[Byte]): ByteString = {
    val masked = Array.ofDim[Byte](data.length)
    var i = 0
    while (i < data.length) {
      masked(i) = (data(i) ^ (maskingKey(i % 4))).toByte
      i += 1
    }
    ByteString(masked)
  }

  def toFinRsvOp(fin: Boolean, opcode: Opcode, rsv1: Boolean = false, rsv2: Boolean = false, rsv3: Boolean = false): Byte = (
    (if (fin) 0x80 else 0x00)
    | (if (rsv1) 0x40 else 0x00)
    | (if (rsv2) 0x20 else 0x00)
    | (if (rsv3) 0x10 else 0x00)
    | (opcode.code & 0x0f)).toByte

  def finFrom(finRsvOp: Byte): Boolean = (finRsvOp & 0x80) != 0
  def rsv1From(finRsvOp: Byte): Boolean = (finRsvOp & 0x40) != 0
  def rsv2From(finRsvOp: Byte): Boolean = (finRsvOp & 0x20) != 0
  def rsv3From(finRsvOp: Byte): Boolean = (finRsvOp & 0x10) != 0
  def opcodeFrom(finRsvOp: Byte): Opcode = Opcode((finRsvOp & 0x0f).toByte)

  def rsvFrom(finRsvOp: Byte): Byte = ((finRsvOp >> 4) & 7).toByte

  /**
   * Note fin should be true for control frames.
   */
  private[frame] def apply(finRsvOp: Byte, payload: ByteString) = opcodeFrom(finRsvOp) match {
    case Opcode.Continuation => ContinuationFrame(finRsvOp, payload)
    case Opcode.Binary       => BinaryFrame(finRsvOp, payload)
    case Opcode.Text         => TextFrame(finRsvOp, payload)
    case Opcode.Close        => CloseFrame(finRsvOp, payload)
    case Opcode.Ping         => PingFrame(finRsvOp, payload)
    case Opcode.Pong         => PongFrame(finRsvOp, payload)
  }

  def unapply(x: Frame): Option[(Boolean, Opcode, ByteString)] =
    Some(x.fin, x.opcode, x.payload)
}

abstract class Frame(_finRsvOp: Byte, _payload: ByteString) {
  import Frame._

  def finRsvOp: Byte = _finRsvOp
  def payload: ByteString = _payload

  def fin: Boolean = finFrom(finRsvOp)
  def rsv1: Boolean = rsv1From(finRsvOp)
  def rsv2: Boolean = rsv2From(finRsvOp)
  def rsv3: Boolean = rsv3From(finRsvOp)
  def opcode: Opcode = opcodeFrom(finRsvOp)

  def rsv: Byte = rsvFrom(finRsvOp)

  def isControl = opcode.isControl
  def isData = !isControl

  def copy(fin: Boolean = this.fin,
           rsv1: Boolean = this.rsv1,
           rsv2: Boolean = this.rsv2,
           rsv3: Boolean = this.rsv3,<commit_msg>make Frame serializable for cluster<commit_after>package spray.can.websocket.frame

import akka.util.ByteString
import java.nio.ByteOrder
import java.nio.charset.Charset
import java.io.{ Closeable, InputStream }
import spray.can.websocket.UTF8Validator

/**
 *
 * http://tools.ietf.org/html/rfc6455
 */
object Frame {
  implicit val byteOrder = ByteOrder.BIG_ENDIAN
  val UTF8 = Charset.forName("UTF-8")

  /**
   * Octet i of the transformed data ("transformed-octet-i") is the XOR of
   * octet i of the original data ("original-octet-i") with octet at index
   * i modulo 4 of the masking key ("masking-key-octet-j"):
   *
   * j                   = i MOD 4
   * transformed-octet-i = original-octet-i XOR masking-key-octet-j
   */
  def maskData(data: Array[Byte], maskingKey: Array[Byte]): Array[Byte] = {
    var i = 0
    while (i < data.length) {
      data(i) = (data(i) ^ (maskingKey(i % 4))).toByte
      i += 1
    }
    data
  }

  def maskData(data: ByteString, maskingKey: Array[Byte]): ByteString = {
    val masked = Array.ofDim[Byte](data.length)
    var i = 0
    while (i < data.length) {
      masked(i) = (data(i) ^ (maskingKey(i % 4))).toByte
      i += 1
    }
    ByteString(masked)
  }

  def toFinRsvOp(fin: Boolean, opcode: Opcode, rsv1: Boolean = false, rsv2: Boolean = false, rsv3: Boolean = false): Byte = (
    (if (fin) 0x80 else 0x00)
    | (if (rsv1) 0x40 else 0x00)
    | (if (rsv2) 0x20 else 0x00)
    | (if (rsv3) 0x10 else 0x00)
    | (opcode.code & 0x0f)).toByte

  def finFrom(finRsvOp: Byte): Boolean = (finRsvOp & 0x80) != 0
  def rsv1From(finRsvOp: Byte): Boolean = (finRsvOp & 0x40) != 0
  def rsv2From(finRsvOp: Byte): Boolean = (finRsvOp & 0x20) != 0
  def rsv3From(finRsvOp: Byte): Boolean = (finRsvOp & 0x10) != 0
  def opcodeFrom(finRsvOp: Byte): Opcode = Opcode((finRsvOp & 0x0f).toByte)

  def rsvFrom(finRsvOp: Byte): Byte = ((finRsvOp >> 4) & 7).toByte

  /**
   * Note fin should be true for control frames.
   */
  private[frame] def apply(finRsvOp: Byte, payload: ByteString) = opcodeFrom(finRsvOp) match {
    case Opcode.Continuation => ContinuationFrame(finRsvOp, payload)
    case Opcode.Binary       => BinaryFrame(finRsvOp, payload)
    case Opcode.Text         => TextFrame(finRsvOp, payload)
    case Opcode.Close        => CloseFrame(finRsvOp, payload)
    case Opcode.Ping         => PingFrame(finRsvOp, payload)
    case Opcode.Pong         => PongFrame(finRsvOp, payload)
  }

  def unapply(x: Frame): Option[(Boolean, Opcode, ByteString)] =
    Some(x.fin, x.opcode, x.payload)
}

abstract class Frame(_finRsvOp: Byte, _payload: ByteString) extends Serializable {
  import Frame._

  def finRsvOp: Byte = _finRsvOp
  def payload: ByteString = _payload

  def fin: Boolean = finFrom(finRsvOp)
  def rsv1: Boolean = rsv1From(finRsvOp)
  def rsv2: Boolean = rsv2From(finRsvOp)
  def rsv3: Boolean = rsv3From(finRsvOp)
  def opcode: Opcode = opcodeFrom(finRsvOp)

  def rsv: Byte = rsvFrom(finRsvOp)

  def isControl = opcode.isControl
  def isData = !isControl

  def copy(fin: Boolean = this.fin,
           rsv1: Boolean = this.rsv1,
           rsv2: Boolean = this.rsv2,
           rsv3: Boolean = this.rsv3,
{'fraction_non_alphanumeric': 0.12767305559955647, 'fraction_numerical': 0.025978140345319183, 'mean_word_length': 3.1566820276497696, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2763151', 'n_tokens_mistral': 2491, 'n_tokens_neox': 2356, 'n_words': 583}