@@ 89,25 89,39 @@ functor BackingFileFn (ARG : BACKING_FIL
fun size (F { extent, ... } : file) =
Position.toInt (Position.quot (! extent,
Position.fromInt ARG.Pack.bytesPerElem))
-
- fun read { file = F { setPosIn, readVec, inPos, ... },
+
+ fun read { file = F { setPosIn, readVec, inPos, extent, ... },
start : int,
count : int
}
: ARG.V.vector IoResult.result =
- let val bytesPerElem = ARG.Pack.bytesPerElem
+ let fun readVecWithRetry' n
+ : Word8Vector.vector list =
+ let val v = readVec n
+ val obtained = Word8Vector.length v
+ in
+ if obtained = 0 orelse obtained >= n
+ then [v]
+ else [v] @ readVecWithRetry' (n - obtained)
+ end
+ fun readVecWithRetry n =
+ case readVecWithRetry' n of
+ [v] => v
+ | vv => Word8Vector.concat vv
+ val bytesPerElem = ARG.Pack.bytesPerElem
val startPosition = Position.fromInt start *
Position.fromInt bytesPerElem
val () = if startPosition <> !inPos
then setPosIn startPosition
else ()
val countBytes = count * bytesPerElem
- val raw = readVec countBytes
+ val raw = readVecWithRetry countBytes
val bytesRead = Word8Vector.length raw
val () = inPos := startPosition + Position.fromInt bytesRead
in
if bytesRead < countBytes
- then IoResult.ERROR ("EOF during read")
+ then (SignalBitsLog.warn (fn () => ["BackingFileFn.read: EOF during read with start = %1, count = %2 [bytesPerElem = %3] after %4 of %5 bytes read [extent = %6]", SignalBitsLog.I start, SignalBitsLog.I count, SignalBitsLog.I ARG.Pack.bytesPerElem, SignalBitsLog.I bytesRead, SignalBitsLog.I countBytes, SignalBitsLog.I (Position.toInt (! extent))]);
+ IoResult.ERROR ("EOF during read"))
else IoResult.OK
(ARG.V.tabulate
(count, fn i => ARG.Pack.subVec (raw, i)))
@@ 137,7 151,8 @@ functor BackingFileFn (ARG : BACKING_FIL
else ()
in
if written < countBytes
- then IoResult.ERROR ("Truncated write")
+ then (SignalBitsLog.warn (fn () => ["BackingFileFn.write: Write truncated with start = %1, count = %2 [bytesPerElem = %3] after %4 of %5 bytes written", SignalBitsLog.I start, SignalBitsLog.I count, SignalBitsLog.I ARG.Pack.bytesPerElem, SignalBitsLog.I written, SignalBitsLog.I countBytes]);
+ IoResult.ERROR ("Truncated write"))
else IoResult.OK ()
end
handle ex =>
@@ 187,7 202,7 @@ functor TempBackingFileFn (FILE : BACKIN
forFile : string option,
extension : string option
}
-
+
fun new (arg : new_args) =
let val filename = FileMisc.tempFile arg
val () = SignalBitsLog.info (fn () => ["TempBackingFileFn.new: using temp file \"%1\"", filename])
@@ 40,7 40,7 @@ signature TEMP_BACKING_FILE = sig
}
val new : new_args -> file IoResult.result
-
+
end
(** BACKED_VECTOR stores a vector to some representation (nominally a