fast CString -> IO PackedString fuction

Hal Daume t-hald@microsoft.com
Thu, 21 Aug 2003 09:27:39 -0700


Hrm.  On the C side the arrays disappear shortly after my call, so just
casting wouldn't really work.  I settled for the following monstrosity
where (cast :: a -> b) is your standard unsafePerformIO/IORef based
casting function:

peekPackedCString :: CString -> IO PackedString
peekPackedCString cs =3D do
  i <- findLength cs 0
  (arr :: IOUArray Int Char) <- newArray_ (0,i)
  writeToArr arr i 0 cs
  (arr' :: UArray Int Char) <- unsafeFreeze arr
  return (cast arr')
  where
    findLength ptr n =3D do
      c <- peek ptr
      if c =3D=3D 0
        then return n
        else findLength (plusPtr ptr 1) $! n+1
    writeToArr arr len pos ptr
        | pos >=3D len =3D return ()
        | otherwise  =3D do
      c <- peek ptr
      writeArray arr pos (castCCharToChar c)
      writeToArr arr len (len+1) (plusPtr ptr 1)

it's pretty fast and works only because the type of PackedString is
  newtype PackedString =3D PS (UArray Int Char)

so the casting gives us what we want.

This does seem like something that belongs in the PackedString library
or the Foreign.C.String library, though.

 - Hal

--
 Hal Daume III                                   | hdaume@isi.edu
 "Arrest this man, he talks in maths."           | www.isi.edu/~hdaume


> -----Original Message-----
> From: glasgow-haskell-users-admin@haskell.org=20
> [mailto:glasgow-haskell-users-admin@haskell.org] On Behalf Of=20
> John Meacham
> Sent: Thursday, August 21, 2003 3:10 AM
> To: glasgow-haskell-users@haskell.org
> Subject: Re: fast CString -> IO PackedString fuction
>=20
>=20
> On Wed, Aug 20, 2003 at 06:48:58PM -0700, Hal Daume wrote:
> > is there a way to go from a CString to a PackedString w/o=20
> going through
> > a normal String in the middle?
> > or should i write my own?
>=20
> If you can get a wchar_t * out of the app then that can be simply cast
> to a packedstring, this is quite speedy.
> if you use mbsrtowcs(3) and friends to do the conversion from char *
> then you get properly localized text via locale settings for free :)
> I have used this sort of thing for interfacing haskell to libraries
> where honoring locale was important in the past.=20
>         John=20
>=20
> --=20
> --------------------------------------------------------------
> -------------
> John Meacham - California Institute of Technology, Alum. -=20
> john@foo.net
> --------------------------------------------------------------
> -------------
> _______________________________________________
> Glasgow-haskell-users mailing list
> Glasgow-haskell-users@haskell.org
> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>=20