Skip to content

Commit 7dc38ed

Browse files
committed
Add instances for ShortByteString
1 parent a6922ec commit 7dc38ed

File tree

2 files changed

+34
-0
lines changed

2 files changed

+34
-0
lines changed

src/Python/Inline/Literal.hs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ module Python.Inline.Literal
1414
, fromPy'
1515
) where
1616

17+
import Control.Exception (evaluate)
1718
import Control.Monad
1819
import Control.Monad.Catch
1920
import Control.Monad.Trans.Cont
@@ -23,6 +24,7 @@ import Data.Int
2324
import Data.Word
2425
import Data.ByteString qualified as BS
2526
import Data.ByteString.Unsafe qualified as BS
27+
import Data.ByteString.Short qualified as SBS
2628
import Data.ByteString.Lazy qualified as BL
2729
import Data.Set qualified as Set
2830
import Data.Map.Strict qualified as Map
@@ -577,6 +579,36 @@ instance ToPy BL.ByteString where
577579
instance FromPy BL.ByteString where
578580
basicFromPy = fmap BL.fromStrict . basicFromPy
579581

582+
583+
-- | @since NEXT_VERSION@. Accepts @bytes@ and @bytearray@
584+
instance FromPy SBS.ShortByteString where
585+
basicFromPy py = pyIO $ do
586+
[CU.exp| int { PyBytes_Check($(PyObject* py)) } |] >>= \case
587+
TRUE -> do
588+
sz <- [CU.exp| int64_t { PyBytes_GET_SIZE( $(PyObject* py)) } |]
589+
buf <- [CU.exp| char* { PyBytes_AS_STRING($(PyObject* py)) } |]
590+
fini buf (fromIntegral sz)
591+
_ -> [CU.exp| int { PyByteArray_Check($(PyObject* py)) } |] >>= \case
592+
TRUE -> do
593+
sz <- [CU.exp| int64_t { PyByteArray_GET_SIZE( $(PyObject* py)) } |]
594+
buf <- [CU.exp| char* { PyByteArray_AS_STRING($(PyObject* py)) } |]
595+
fini buf (fromIntegral sz)
596+
_ -> throwM BadPyType
597+
where
598+
fini buf sz = do
599+
bs <- BS.unsafePackCStringLen (buf, sz)
600+
evaluate $ SBS.toShort bs
601+
602+
-- | @since NEXT_VERSION@. Converted to @bytes@
603+
instance ToPy SBS.ShortByteString where
604+
basicToPy bs = pyIO $ SBS.useAsCStringLen bs $ \(ptr,len) -> do
605+
let c_len = fromIntegral len :: CLLong
606+
py <- [CU.exp| PyObject* { PyBytes_FromStringAndSize($(char* ptr), $(long long c_len)) }|]
607+
case py of
608+
NULL -> unsafeRunPy mustThrowPyError
609+
_ -> return py
610+
611+
580612
-- | @since NEXT_VERSION@.
581613
instance ToPy T.Text where
582614
-- NOTE: Is there ore efficient way to access

test/TST/Roundtrip.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import Python.Inline.QQ
2222

2323
import Data.ByteString qualified as BS
2424
import Data.ByteString.Lazy qualified as BL
25+
import Data.ByteString.Short qualified as SBS
2526
import Data.Vector qualified as V
2627
#if MIN_VERSION_vector(0,13,2)
2728
import Data.Vector.Strict qualified as VV
@@ -82,6 +83,7 @@ tests = testGroup "Roundtrip"
8283
#endif
8384
, testRoundtrip @BS.ByteString
8485
, testRoundtrip @BL.ByteString
86+
, testRoundtrip @SBS.ShortByteString
8587
, testRoundtrip @T.Text
8688
, testRoundtrip @TL.Text
8789
]

0 commit comments

Comments
 (0)