Skip to content

Commit

Permalink
Add a Text instance for ToSV and FromSV (see #15).
Browse files Browse the repository at this point in the history
Not yet tested.
  • Loading branch information
phlummox committed Feb 5, 2021
1 parent b41079c commit e3361d7
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 4 deletions.
13 changes: 13 additions & 0 deletions cbits/p5embed.c
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,19 @@ perl5_init ( int argc, char **argv )
return my_perl;
}

// switch on Utf8 flag
void
perl5_SvUTF8_on(SV *sv)
{
SvUTF8_on(sv);
}

// convert SV to a Utf8 string
char*
perl5_sv_2pvutf8(SV* sv, STRLEN* lp) {
return sv_2pvutf8(sv, lp);
}

SV *
perl5_get_sv(const char *name)
{
Expand Down
3 changes: 2 additions & 1 deletion cbits/p5embed.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ SV * perl5_newSVnv ( double iv );
bool perl5_SvTRUE ( SV * sv );
SV * perl5_get_sv ( const char *name );
SV * perl5_get_cv ( const char *name );

void perl5_SvUTF8_on(SV *sv);
char* perl5_sv_2pvutf8(SV* sv, STRLEN* lp);

#include <HsFFI.h>
extern SV ** hsPerl5Apply ( HsStablePtr *sub, SV **args, int cxt );
Expand Down
25 changes: 22 additions & 3 deletions src/Language/Perl5.hs
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,13 @@ module Language.Perl5
import Control.Concurrent
import Control.Exception (bracket, throwIO, Exception(..))
import Control.Monad
import Data.Dynamic (toDyn)
import Data.Int
import Data.List ( intercalate)

import qualified Data.ByteString as BS
import Data.Dynamic (toDyn)
import Data.Int
import Data.List ( intercalate)
import Data.Text (Text)
import qualified Data.Text.Encoding as T

import Foreign hiding (void)
import Foreign.C.Types
Expand Down Expand Up @@ -127,6 +131,21 @@ instance FromSV String where
cstr <- perl5_SvPV sv
peekCString cstr

instance ToSV Text where
toSV txt = BS.useAsCStringLen (T.encodeUtf8 txt) $ \(cstr, len) -> do
sv <- perl5_newSVpvn cstr (toEnum len)
perl5_SvUTF8_on sv
return sv

instance FromSV Text where
fromSV sv =
alloca $ \(lenPtr :: Ptr CSize) -> do
cStr <- perl5_sv_2pvutf8 sv lenPtr
len <- peek lenPtr
-- to do: unsafePackCStringLen is presumably faster
T.decodeUtf8 <$> BS.packCStringLen (cStr, fromIntegral len)


-- | For convenience, a 'ToSV' instance is provided for 'Int's.
-- However, it's lossy: actually, a Perl 'SV' will only fit
-- an 'Int32'.
Expand Down
21 changes: 21 additions & 0 deletions src/Language/Perl5/Internal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,27 @@ foreign import ccall "perl5_SvTRUE"
foreign import ccall "perl5_get_sv"
perl5_get_sv :: CString -> IO SV

-- |
-- Turn on the UTF-8 status of an 'SV' (the data is not changed, just the
-- flag). Do not use frivolously.
--
-- source: <https://perldoc.perl.org/perlapi#SvUTF8_on>.
foreign import ccall "perl5_SvUTF8_on"
perl5_SvUTF8_on :: SV -> IO ()

-- |
-- @
-- perl5_sv_2pvutf8 sv lp
-- @
--
-- Return a pointer to the UTF-8-encoded representation of the SV, and set
-- @*lp@ to its length. May cause the SV to be upgraded to UTF-8 as a
-- side-effect.
--
-- source: <https://perldoc.perl.org/perlapi#sv_2pvutf8>
foreign import ccall "perl5_sv_2pvutf8"
perl5_sv_2pvutf8 :: SV -> Ptr CSize -> IO (Ptr CChar)

-- |
-- @perl5_get_cv name flags@: Uses strlen to get the length of name, then calls
-- get_cvn_flags.
Expand Down

0 comments on commit e3361d7

Please sign in to comment.