@@ -33,20 +33,37 @@ internal constructor(
3333 fun createVcr () = VcrSelfie (sub, call, disk)
3434 }
3535
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+ }
3956 }
4057 private val state: State
4158
4259 init {
4360 val canWrite = Selfie .system.mode.canWrite(isTodo = false , call, Selfie .system)
44- state = State (readMode = ! canWrite)
45- if (state.readMode) {
61+ if (canWrite) {
4662 val snapshot =
4763 disk.readDisk(sub, call)
4864 ? : throw Selfie .system.fs.assertFailed(Selfie .system.mode.msgVcrSnapshotNotFound())
4965 var idx = 1
66+ val frames = mutableListOf<Pair <String , SnapshotValue >>()
5067 for ((key, value) in snapshot.facets) {
5168 check(key.startsWith(OPEN ))
5269 val nextClose = key.indexOf(CLOSE )
@@ -55,27 +72,24 @@ internal constructor(
5572 check(num == idx) { " expected $idx in $key " }
5673 ++ idx
5774 val keyAfterNum = key.substring(nextClose + 1 )
58- state. frames.add(keyAfterNum to value)
75+ frames.add(keyAfterNum to value)
5976 }
77+ state = State .Read (frames)
78+ } else {
79+ state = State .Write ()
6080 }
6181 }
6282 override fun close () {
63- if (state.readMode ) {
83+ if (state is State . Read ) {
6484 if (state.frames.size != state.currentFrame) {
6585 throw Selfie .system.fs.assertFailed(
6686 Selfie .system.mode.msgVcrUnread(state.frames.size, state.currentFrame))
6787 }
6888 } 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)
7690 }
7791 }
78- private fun nextFrameValue (key : String ): SnapshotValue {
92+ private fun nextFrameValue (state : State . Read , key : String ): SnapshotValue {
7993 val mode = Selfie .system.mode
8094 val fs = Selfie .system.fs
8195 if (state.frames.size <= state.currentFrame) {
@@ -91,11 +105,11 @@ internal constructor(
91105 return expected.second
92106 }
93107 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())
96110 } else {
97111 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)))
99113 return value
100114 }
101115 }
@@ -108,11 +122,11 @@ internal constructor(
108122 roundtripValue : Roundtrip <V , ByteArray >,
109123 value : Cacheable <V >
110124 ): 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())
113127 } else {
114128 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)))
116130 return value
117131 }
118132 }
0 commit comments