@@ -43,10 +43,14 @@ data Header = Header {
4343 , hdrPosition :: ! CInt
4444 , hdrLength :: ! CInt
4545 , hdrResultNum :: ! CInt
46+ , hdrResultLimit :: ! CInt
4647} deriving (Show )
4748
49+ defHeader :: Header
50+ defHeader = Header 0 0 0 0 0 0 0
51+
4852instance Storable Header where
49- sizeOf _ = 7 * sizeOf (undefined :: CInt )
53+ sizeOf _ = 8 * sizeOf (undefined :: CInt )
5054 alignment _ = sizeOf (undefined :: CInt )
5155 peek ptr = do
5256 state <- peekByteOff ptr 0
@@ -55,8 +59,8 @@ instance Storable Header where
5559 position <- peekByteOff ptr (3 * sizeOf state)
5660 slength <- peekByteOff ptr (4 * sizeOf state)
5761 sresultnum <- peekByteOff ptr (5 * sizeOf state)
58- return $ Header state sdata1 sdata2 position slength sresultnum
59- -- return $ Header state sdata1 sdata2 position slength sresultnum
62+ sresultlimit <- peekByteOff ptr ( 6 * sizeOf state)
63+ return $ Header state sdata1 sdata2 position slength sresultnum sresultlimit
6064
6165 poke ptr (Header {.. }) = do
6266 pokeByteOff ptr 0 hdrCurrentState
@@ -65,6 +69,7 @@ instance Storable Header where
6569 pokeByteOff ptr (3 * sizeOf hdrCurrentState) hdrPosition
6670 pokeByteOff ptr (4 * sizeOf hdrCurrentState) hdrLength
6771 pokeByteOff ptr (5 * sizeOf hdrCurrentState) hdrResultNum
72+ pokeByteOff ptr (6 * sizeOf hdrCurrentState) hdrResultLimit
6873
6974peekResultField :: Int -> Int -> ResultPtr -> Int
7075peekResultField n fieldno fptr = inlinePerformIO $ -- !! Using inlinePerformIO should be safe - we are just reading bytes from memory
@@ -91,7 +96,7 @@ callLex bs hdr = unsafeDupablePerformIO $ -- Using Dupable PerformIO should be s
9196 poke hdrptr (hdr{hdrResultNum= 0 , hdrLength= fromIntegral $ BS. length bs})
9297
9398 bsptr <- unsafeUseAsCString bs return
94- resptr <- mallocForeignPtrBytes (resultLimit * sizeOf (undefined :: CInt ) * 4 )
99+ resptr <- mallocForeignPtrBytes (fromIntegral (hdrResultLimit hdr) * sizeOf (undefined :: CInt ) * 4 )
95100 res <- withForeignPtr resptr $ \ resptr' ->
96101 lexJson bsptr hdrptr resptr'
97102
@@ -212,18 +217,22 @@ parseResults (TempData {tmpNumbers=tmpNumbers, tmpBuffer=bs}) (err, hdr, rescoun
212217 PartialResult (StringContent (encodeUtf8 $ T. singleton $ toEnum resAddData)) next
213218 -- -- Partial string, not the end
214219 | resType == resStringPartial ->
215- if resLength == 0
220+ if resLength == - 1
216221 then PartialResult (StringContent (BSW. singleton $ fromIntegral resAddData)) next -- \n\r..
217222 else PartialResult (StringContent textSection) next -- normal string section
218223 | otherwise -> error " Unsupported"
219224
225+ -- | Estimate number of elements in a chunk
226+ estResultLimit :: BS. ByteString -> CInt
227+ estResultLimit dta = fromIntegral $ 1 + BS. length dta `div` 5
228+
220229getNextResult :: TempData -> TokenResult
221230getNextResult tmp@ (TempData {.. })
222231 | tmpError = TokFailed
223232 | hdrPosition tmpHeader < hdrLength tmpHeader = parseResults tmp (callLex tmpBuffer tmpHeader)
224233 | otherwise = TokMoreData newdata
225234 where
226- newdata dta = parseResults newtmp (callLex dta newhdr)
235+ newdata dta = parseResults newtmp (callLex dta newhdr{hdrResultLimit = estResultLimit dta} )
227236 where
228237 newtmp = tmp{tmpBuffer= dta}
229238 newhdr = tmpHeader{hdrPosition= 0 , hdrLength= fromIntegral $ BS. length dta}
@@ -232,4 +241,4 @@ getNextResult tmp@(TempData {..})
232241tokenParser :: BS. ByteString -> TokenResult
233242tokenParser dta = getNextResult (TempData dta newhdr False [] )
234243 where
235- newhdr = Header 0 0 0 0 ( fromIntegral $ BS. length dta) 0
244+ newhdr = defHeader{hdrLength = fromIntegral ( BS. length dta), hdrResultLimit = (estResultLimit dta)}
0 commit comments