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 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
|
Configuration
-------------
Natural ratio between input and output: n:m
Unseekable <=== (n == 0 || m == 0)
Configurational state
---------------------
Chosen ratio, without user intervention
Flag, possible to overide ratio above or not ?
Chosen ratio, after possible intervention by user
State
-----
Stream location of transformation. UpLoc
Stream location of start and end of the read buffer. UpLocBS, UpLocBE
Stream location of downstream channel. DwLoc
"End" = Location of the character behind the last character in the buffer.
!Integrity condition: (1) DwLoc "equivalent to" UpLocBE
(2) UpLocBS = UpLocBE = UpLoc for an empty buffer.
(3) UpLoc* % n == 0, i.e. a multiple of n.
Derived state
-------------
(up * m) / n = down (Position relative to starting point)
Zero = Position downstream "equivalent to" Zero position upward.
(1) DwLoc "equivalent to" UpLocBE
===> (UpLocBE * m) / n + Zero = DwLoc
===> Zero = (UpLocBE * m) / n - DwLoc
Actions
-------
Tell /done/
....
Report stream location of transformation.
Seek, general /done/
.............
[Tell]
Unseekable
===> Error
STOP_____________________________
Identity
===> discard read/write buffers,
pass request
set flag "changed"
STOP_____________________________
Seek, relative to start of stream (as seen by the transformation) /done/
.................................................................
Delta = NewPos - UpLoc
Seek (Delta, relative to current position)
STOP_____________________________
Seek, relative to current position (as seen by the transformation) /done/
..................................................................
(Delta % n) != 0
===> Error
NewUpLoc := UpLoc + Delta
NewUpLoc < 0
===> Error
NewUpLoc < UpLocBS
|| NewUpLoc >= UpLocBE
===> Discard read buffer
DeltaDown := ((NewUpLoc - UpLocBE) * m) / n
DeltaDown != 0
===> Seek down, relative to current: DeltaDown.
DwLoc := DwLoc + DeltaDown
UpLoc,UpLocBS,UpLocBE := NewUpLoc
STOP_____________________________
UpLoc := NewUpLoc
STOP_____________________________
Seek, relative to end of stream
...............................
??? not yet
STOP_____________________________
Write /done/
.....
// Partial writes (incomplete tuple?, seek effect)
// no seek!, no change of location
// next read discards incomplete information.
// next seek discards incomplete information! too.
UpLoc != UpLocBE
===> Get Zero
Discard read buffer.
DeltaDown := ((UpLocBE - UpLoc) * m) / n
Seek down, relative: DeltaDown.
DwLoc := DwLoc + DeltaDown
-- Now UpLoc "equivalent to" DwLoc
-- IOW Positions up and down are now in sync.
-- Phase == 0 now!
UpLoc,UpLocBS,UpLocBE := UpLoc += toWrite
DwLoc += (toWrite * m)/n
Write complete transformation results.
STOP_____________________________
// Handle only complete writes, in writer proc, do the above.
// Automatic handling of incomplete tuples as described //above
UpLoc == UpLocBE
-- No read buffer existing, positions are in sync.
Write complete transformation results.
STOP_____________________________
Read
....
Discard incomplete tuples in write buffer!
Repeat
Data in read buffer
===> Copy x from read buffer
UpLoc += x
Remove x from buffer
LOOP
Satisified
===> STOP
(Integrity: UpLoc == UpLocBE)
got := Read from down
transform
// got % m == 0 not assertable, can be fract
// maintain phase! value as last ditch correction value
DwLoc += got
UpLocBS := UpLocBE
UpLocBE += (got-phase) / m * n
endrepeat
STOP_____________________________
Stack /done/
.....
UpLoc,UpLocBS,UpLocBE := 0
DwLoc := Tell down.
Phase == 0.
Empty read/write buffers.
STOP_____________________________
Force identity
..............
Set flag "identity"
Unset flag "changed"
STOP_____________________________
Unforce identity
................
Changed
===> See "Stack"
STOP_____________________________
...
handling force unseekable ? for seekable transforms.
|