@@ -33,20 +33,37 @@ internal constructor(
33
33
fun createVcr () = VcrSelfie (sub, call, disk)
34
34
}
35
35
36
- private class State (val readMode : Boolean ) {
37
- var currentFrame = 0
38
- val frames = mutableListOf<Pair <String , SnapshotValue >>()
36
+ internal sealed class State {
37
+ class Read (val frames : List <Pair <String , SnapshotValue >>) : State() {
38
+ var currentFrame = 0
39
+ }
40
+
41
+ class Write : State () {
42
+ private val frames = mutableListOf<Pair <String , SnapshotValue >>()
43
+ fun add (key : String , value : SnapshotValue ) {
44
+ frames.add(key to value)
45
+ }
46
+ fun toSnapshot (): Snapshot {
47
+ var snapshot = Snapshot .of(" " )
48
+ var idx = 1
49
+ for ((key, value) in frames) {
50
+ snapshot = snapshot.plusFacet(" $OPEN$idx$CLOSE$key " , value)
51
+ ++ idx
52
+ }
53
+ return snapshot
54
+ }
55
+ }
39
56
}
40
57
private val state: State
41
58
42
59
init {
43
60
val canWrite = Selfie .system.mode.canWrite(isTodo = false , call, Selfie .system)
44
- state = State (readMode = ! canWrite)
45
- if (state.readMode) {
61
+ if (canWrite) {
46
62
val snapshot =
47
63
disk.readDisk(sub, call)
48
64
? : throw Selfie .system.fs.assertFailed(Selfie .system.mode.msgVcrSnapshotNotFound())
49
65
var idx = 1
66
+ val frames = mutableListOf<Pair <String , SnapshotValue >>()
50
67
for ((key, value) in snapshot.facets) {
51
68
check(key.startsWith(OPEN ))
52
69
val nextClose = key.indexOf(CLOSE )
@@ -55,27 +72,24 @@ internal constructor(
55
72
check(num == idx) { " expected $idx in $key " }
56
73
++ idx
57
74
val keyAfterNum = key.substring(nextClose + 1 )
58
- state. frames.add(keyAfterNum to value)
75
+ frames.add(keyAfterNum to value)
59
76
}
77
+ state = State .Read (frames)
78
+ } else {
79
+ state = State .Write ()
60
80
}
61
81
}
62
82
override fun close () {
63
- if (state.readMode ) {
83
+ if (state is State . Read ) {
64
84
if (state.frames.size != state.currentFrame) {
65
85
throw Selfie .system.fs.assertFailed(
66
86
Selfie .system.mode.msgVcrUnread(state.frames.size, state.currentFrame))
67
87
}
68
88
} else {
69
- var snapshot = Snapshot .of(" " )
70
- var idx = 1
71
- for ((key, value) in state.frames) {
72
- snapshot = snapshot.plusFacet(" $OPEN$idx$CLOSE$key " , value)
73
- ++ idx
74
- }
75
- disk.writeDisk(snapshot, sub, call)
89
+ disk.writeDisk((state as State .Write ).toSnapshot(), sub, call)
76
90
}
77
91
}
78
- private fun nextFrameValue (key : String ): SnapshotValue {
92
+ private fun nextFrameValue (state : State . Read , key : String ): SnapshotValue {
79
93
val mode = Selfie .system.mode
80
94
val fs = Selfie .system.fs
81
95
if (state.frames.size <= state.currentFrame) {
@@ -91,11 +105,11 @@ internal constructor(
91
105
return expected.second
92
106
}
93
107
fun <V > nextFrame (key : String , roundtripValue : Roundtrip <V , String >, value : Cacheable <V >): V {
94
- if (state.readMode ) {
95
- return roundtripValue.parse(nextFrameValue(key).valueString())
108
+ if (state is State . Read ) {
109
+ return roundtripValue.parse(nextFrameValue(state, key).valueString())
96
110
} else {
97
111
val value = value.get()
98
- state.frames .add(key to SnapshotValue .of(roundtripValue.serialize(value)))
112
+ ( state as State . Write ) .add(key, SnapshotValue .of(roundtripValue.serialize(value)))
99
113
return value
100
114
}
101
115
}
@@ -108,11 +122,11 @@ internal constructor(
108
122
roundtripValue : Roundtrip <V , ByteArray >,
109
123
value : Cacheable <V >
110
124
): V {
111
- if (state.readMode ) {
112
- return roundtripValue.parse(nextFrameValue(key).valueBinary())
125
+ if (state is State . Read ) {
126
+ return roundtripValue.parse(nextFrameValue(state, key).valueBinary())
113
127
} else {
114
128
val value = value.get()
115
- state.frames .add(key to SnapshotValue .of(roundtripValue.serialize(value)))
129
+ ( state as State . Write ) .add(key, SnapshotValue .of(roundtripValue.serialize(value)))
116
130
return value
117
131
}
118
132
}
0 commit comments