+val eight = Word.fromInt 8
+val sixteen = Word.fromInt 16
+val twentyfour = Word.fromInt 24
+
+val mask1 = Word32.fromInt 255
+
+fun readChar bio =
+ let
+ val r = F_OpenSSL_SML_read.f' (bio, C.Ptr.inject' readBuf, one)
+ in
+ if r = 0 then
+ NONE
+ else if r < 0 then
+ (ssl_err "BIO_read";
+ raise OpenSSL "BIO_read failed")
+ else
+ SOME (chr (Compat.Char.toInt (C.Get.uchar'
+ (C.Ptr.sub' C.S.uchar (readBuf, 0)))))
+ end
+
+val charToWord = Word32.fromLargeWord o Compat.Char.toLargeWord
+
+fun readInt bio =
+ let
+ val r = F_OpenSSL_SML_read.f' (bio, C.Ptr.inject' readBuf, four)
+ in
+ if r = 0 then
+ NONE
+ else if r < 0 then
+ (ssl_err "BIO_read";
+ raise OpenSSL "BIO_read failed")
+ else
+ SOME (Word32.toInt
+ (Word32.+
+ (charToWord (C.Get.uchar' (C.Ptr.sub' C.S.uchar (readBuf, 0))),
+ Word32.+
+ (Word32.<< (charToWord (C.Get.uchar' (C.Ptr.sub' C.S.uchar (readBuf, 1))),
+ eight),
+ Word32.+
+ (Word32.<< (charToWord (C.Get.uchar' (C.Ptr.sub' C.S.uchar (readBuf, 2))),
+ sixteen),
+ Word32.<< (charToWord (C.Get.uchar' (C.Ptr.sub' C.S.uchar (readBuf, 3))),
+ twentyfour))))))
+ end
+
+fun readLen (bio, len) =
+ if len = 0 then
+ SOME ""
+ else
+ let
+ val buf =
+ if len > Config.bufSize then
+ C.alloc' C.S.uchar (Word.fromInt len)
+ else
+ readBuf
+
+ fun cleanup () =
+ if len > Config.bufSize then
+ C.free' buf
+ else
+ ()
+
+ fun loop (buf', needed) =
+ let
+ val r = F_OpenSSL_SML_read.f' (bio, C.Ptr.inject' buf, Int32.fromInt len)
+ in
+ if r = 0 then
+ (cleanup (); NONE)
+ else if r < 0 then
+ (cleanup ();
+ ssl_err "BIO_read";
+ raise OpenSSL "BIO_read failed")
+ else if r = needed then
+ SOME (CharVector.tabulate (Int32.toInt needed,
+ fn i => chr (Compat.Char.toInt (C.Get.uchar'
+ (C.Ptr.sub' C.S.uchar (buf, i))))))
+ else
+ loop (C.Ptr.|+! C.S.uchar (buf', Int32.toInt r), needed - r)
+ end
+ in
+ loop (buf, Int32.fromInt len)
+ before cleanup ()
+ end
+
+fun readChunk bio =