aboutsummaryrefslogtreecommitdiff
path: root/okio/src/jvmTest/kotlin/okio/BufferCursorKotlinTest.kt
blob: 0b50b0054da9844f0915de7fbc34eea26cb53e06 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*
 * Copyright (C) 2018 Square, 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 okio

import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertNotSame
import kotlin.test.assertSame
import kotlin.test.assertTrue
import okio.Buffer.UnsafeCursor
import okio.TestUtil.deepCopy
import org.junit.Assume.assumeTrue
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
import org.junit.runners.Parameterized.Parameter
import org.junit.runners.Parameterized.Parameters

@RunWith(Parameterized::class)
class BufferCursorKotlinTest {
  companion object {
    @Parameters(name = "{0}")
    @JvmStatic
    fun parameters(): List<Array<out Any?>> {
      return BufferFactory.values().map { arrayOf(it) }
    }
  }

  @Parameter lateinit var bufferFactory: BufferFactory

  @Test fun acquireReadOnlyDoesNotCopySharedDataArray() {
    val buffer = deepCopy(bufferFactory.newBuffer())
    assumeTrue(buffer.size > 0L)

    val shared = buffer.clone()
    assertTrue(buffer.head!!.shared)

    buffer.readUnsafe().use { cursor ->
      cursor.seek(0)
      assertSame(cursor.data, shared.head!!.data)
    }
  }

  @Test fun acquireReadWriteDoesNotCopyUnsharedDataArray() {
    val buffer = deepCopy(bufferFactory.newBuffer())
    assumeTrue(buffer.size > 0L)
    assertFalse(buffer.head!!.shared)

    val originalData = buffer.head!!.data

    buffer.readAndWriteUnsafe().use { cursor ->
      cursor.seek(0)
      assertSame(cursor.data, originalData)
    }
  }

  @Test fun acquireReadWriteCopiesSharedDataArray() {
    val buffer = deepCopy(bufferFactory.newBuffer())
    assumeTrue(buffer.size > 0L)

    val shared = buffer.clone()
    assertTrue(buffer.head!!.shared)

    buffer.readAndWriteUnsafe().use { cursor ->
      cursor.seek(0)
      assertNotSame(cursor.data, shared.head!!.data)
    }
  }

  @Test fun writeSharedSegments() {
    val buffer = bufferFactory.newBuffer()

    // Make a deep copy. This buffer's segments are not shared.
    val deepCopy = deepCopy(buffer)
    assertTrue(deepCopy.head == null || !deepCopy.head!!.shared)

    // Make a shallow copy. Both buffers' segments are shared as a side effect.
    val shallowCopy = buffer.clone()
    assertTrue(shallowCopy.head == null || shallowCopy.head!!.shared)
    assertTrue(buffer.head == null || buffer.head!!.shared)

    val expected = Buffer()
    expected.writeUtf8("x".repeat(buffer.size.toInt()))

    buffer.readAndWriteUnsafe().use { cursor ->
      while (cursor.next() != -1) {
        cursor.data!!.fill('x'.code.toByte(), cursor.start, cursor.end)
      }
    }

    // The buffer was fully changed.
    assertEquals(expected, buffer)

    // The buffer we're shared with is unchanged.
    assertEquals(deepCopy, shallowCopy)
  }

  /** As an optimization it's okay to use the same cursor on multiple buffers.  */
  @Test fun cursorReuse() {
    val cursor = UnsafeCursor()

    val buffer1 = bufferFactory.newBuffer()
    buffer1.readUnsafe(cursor)
    assertSame(buffer1, cursor.buffer)
    assertFalse(cursor.readWrite)
    cursor.close()
    assertSame(null, cursor.buffer)

    val buffer2 = bufferFactory.newBuffer()
    buffer2.readAndWriteUnsafe(cursor)
    assertSame(buffer2, cursor.buffer)
    assertTrue(cursor.readWrite)
    cursor.close()
    assertSame(null, cursor.buffer)
  }
}