packages feed

iconv 0.4.0.2 → 0.4.1.0

raw patch · 5 files changed

+92/−94 lines, 5 filesdep ~basedep ~bytestring

Dependency ranges changed: base, bytestring

Files

Codec/Text/IConv.hs view
@@ -1,10 +1,10 @@+{-# LANGUAGE CPP #-} ----------------------------------------------------------------------------- -- | -- Copyright   :  (c) 2006-2007 Duncan Coutts -- License     :  BSD-style -- -- Maintainer  :  duncan@haskell.org--- Stability   :  experimental -- Portability :  portable (H98 + FFI) -- -- String encoding conversion@@ -58,9 +58,7 @@ import Foreign.C.Error as C.Error (Errno, errnoToIOError)  import qualified Data.ByteString.Lazy as L (ByteString, toChunks, fromChunks)-#ifndef BYTESTRING_IN_BASE import qualified Data.ByteString.Lazy.Internal as L (defaultChunkSize)-#endif import qualified Data.ByteString as S  import qualified Codec.Text.IConv.Internal as IConv@@ -139,7 +137,7 @@     --   | UnexpectedError C.Error.Errno -reportConversionError :: ConversionError -> Exception.Exception+reportConversionError :: ConversionError -> IOError reportConversionError conversionError = case conversionError of   UnsuportedConversion fromEncoding toEncoding                           -> err $ "cannot convert from string encoding "@@ -149,11 +147,10 @@                                ++ show inputPos   IncompleteChar inputPos -> err $ "incomplete input sequence at byte offset "                                ++ show inputPos-  UnexpectedError errno   -> Exception.IOException $ C.Error.errnoToIOError+  UnexpectedError errno   -> C.Error.errnoToIOError                                "Codec.Text.IConv: unexpected error" errno                                Nothing Nothing-  where err msg = Exception.ErrorCall $ "Codec.Text.IConv: " ++ msg-+  where err msg = userError $ "Codec.Text.IConv: " ++ msg  {-# NOINLINE convert #-} -- | Convert text from one named string encoding to another.@@ -178,7 +175,12 @@    where     span (Span c)            cs = c : cs-    span (ConversionError e) _  = Exception.throw (reportConversionError e)+    span (ConversionError e) _  =+#if MIN_VERSION_base(4,0,0)+      Exception.throw (reportConversionError e)+#else+      Exception.throw (Exception.IOException (reportConversionError e))+#endif   data Fuzzy = Transliterate | Discard@@ -405,7 +407,7 @@          IConv.InvalidChar -> invalidChar ignore inChunks -        IConv.IncompleteChar -> +        IConv.IncompleteChar ->           assert (inSize < consumed && consumed < tmpChunkSize) $           --    inSize < consumed < tmpChunkSize           -- => { subtract inSize from each side }@@ -463,13 +465,7 @@     else    return [               ConversionError err]  outChunkSize :: Int-#ifdef BYTESTRING_IN_BASE-outChunkSize = 32 * k - overhead-   where k = 1024-         overhead = 16-#else outChunkSize = L.defaultChunkSize-#endif  tmpChunkSize :: Int tmpChunkSize = 16
Codec/Text/IConv/Internal.hs view
@@ -4,7 +4,6 @@ -- License     :  BSD-style -- -- Maintainer  :  duncan@haskell.org--- Stability   :  experimental -- Portability :  portable (H98 + FFI) -- -- IConv wrapper layer@@ -46,11 +45,7 @@  import Foreign import Foreign.C-#ifdef BYTESTRING_IN_BASE-import qualified Data.ByteString.Base as S-#else import qualified Data.ByteString.Internal as S-#endif import System.IO.Unsafe (unsafeInterleaveIO) import System.IO (hPutStrLn, stderr) import Control.Exception (assert)@@ -66,7 +61,7 @@   assert (inAvail == 0) $ return ()    -- now set the available input buffer ptr and length-  modify $ \bufs -> bufs { +  modify $ \bufs -> bufs {     inBuffer = inBuffer',     inOffset = inOffset',     inLength = inLength'@@ -86,18 +81,15 @@   replaceInputBuffer :: (S.ByteString -> S.ByteString) -> IConv ()-replaceInputBuffer replace = do-  modify $ \bufs@Buffers {-    inBuffer = inBuffer,-    inOffset = inOffset,-    inLength = inLength-  } -> case replace (S.PS inBuffer inOffset inLength) of-         S.PS inBuffer' inOffset' inLength' ->-           bufs {-             inBuffer = inBuffer',-             inOffset = inOffset',-             inLength = inLength'-           }+replaceInputBuffer replace =+  modify $ \bufs ->+    case replace (S.PS (inBuffer bufs) (inOffset bufs) (inLength bufs)) of+      S.PS inBuffer' inOffset' inLength' ->+        bufs {+          inBuffer = inBuffer',+          inOffset = inOffset',+          inLength = inLength'+        }   newOutputBuffer :: Int -> IConv ()@@ -111,9 +103,9 @@   -- there's only a few free bytes left.    -- now set the available output buffer ptr and length-  outBuffer <- unsafeLiftIO $ S.mallocByteString size+  outBuffer' <- unsafeLiftIO $ S.mallocByteString size   modify $ \bufs -> bufs {-      outBuffer = outBuffer,+      outBuffer = outBuffer',       outOffset = 0,       outLength = 0,       outFree   = size@@ -126,21 +118,17 @@ popOutputBuffer :: IConv S.ByteString popOutputBuffer = do -  Buffers {-    outBuffer = outBuffer,-    outOffset = outOffset,-    outLength = outLength-    } <- get+  bufs <- get    -- there really should be something to pop, otherwise it's silly-  assert (outLength > 0) $ return ()+  assert (outLength bufs > 0) $ return ()    modify $ \buf -> buf {-      outOffset = outOffset + outLength,+      outOffset = outOffset bufs + outLength bufs,       outLength = 0     } -  return (S.PS outBuffer outOffset outLength)+  return (S.PS (outBuffer bufs) (outOffset bufs) (outLength bufs))   -- this is the number of bytes available in the output buffer@@ -255,10 +243,6 @@                               else return (cd, UnexpectedInitError errno)   (_,a) <- unI (m status) (ConversionDescriptor cd) nullBuffers   return a-#if __GLASGOW_HASKELL__<=604-  where ptrToIntPtr :: Ptr a -> Int-        ptrToIntPtr p = p `minusPtr` nullPtr-#endif  unsafeLiftIO :: IO a -> IConv a unsafeLiftIO m = I $ \_ bufs -> do@@ -269,8 +253,8 @@ -- between running this and forcing the result then you'll get an inconsistent -- iconv state. unsafeInterleave :: IConv a -> IConv a-unsafeInterleave m = I $ \iconv st -> do-  res <- unsafeInterleaveIO (unI m iconv st)+unsafeInterleave m = I $ \cd st -> do+  res <- unsafeInterleaveIO (unI m cd st)   return (st, snd res)  get :: IConv Buffers@@ -307,36 +291,28 @@        | UnexpectedError Errno  iconv :: IConv Status-iconv = I $ \(ConversionDescriptor cdfptr) bufs@Buffers {-    inBuffer  = inBuffer,-    inOffset  = inOffset,-    inLength  = inLength,-    inTotal   = inTotal,-    outBuffer = outBuffer,-    outOffset = outOffset,-    outLength = outLength,-    outFree   = outFree-  } ->-  assert (outFree > 0) $+iconv = I $ \(ConversionDescriptor cdfptr) bufs ->+  assert (outFree bufs > 0) $   --TODO: optimise all this allocation-  withForeignPtr cdfptr                              $ \cdPtr -> -  withForeignPtr inBuffer                            $ \inBufPtr ->-  with (inBufPtr `plusPtr` inOffset)                 $ \inBufPtrPtr ->-  with (fromIntegral inLength)                       $ \inLengthPtr ->-  withForeignPtr outBuffer                           $ \outBufPtr ->-  with (outBufPtr `plusPtr` (outOffset + outLength)) $ \outBufPtrPtr ->-  with (fromIntegral outFree)                        $ \outFreePtr -> do-    +  withForeignPtr cdfptr                   $ \cdPtr ->+  withForeignPtr (inBuffer bufs)          $ \inBufPtr ->+  with (inBufPtr `plusPtr` inOffset bufs) $ \inBufPtrPtr ->+  with (fromIntegral (inLength bufs))     $ \inLengthPtr ->+  withForeignPtr (outBuffer bufs)         $ \outBufPtr ->+  let outBufPtr' = outBufPtr `plusPtr` (outOffset bufs + outLength bufs) in+  with outBufPtr'                         $ \outBufPtrPtr ->+  with (fromIntegral (outFree bufs))      $ \outFreePtr -> do+     result <- c_iconv cdPtr inBufPtrPtr inLengthPtr outBufPtrPtr outFreePtr     inLength' <- fromIntegral `fmap` peek inLengthPtr     outFree'  <- fromIntegral `fmap` peek outFreePtr-    let inByteCount   = inLength - inLength'-        outByteCount  = outFree  - outFree'+    let inByteCount   = inLength bufs - inLength'+        outByteCount  = outFree bufs  - outFree'         bufs' = bufs {-            inOffset  = inOffset  + inByteCount,+            inOffset  = inOffset bufs + inByteCount,             inLength  = inLength',-            inTotal   = inTotal   + inByteCount,-            outLength = outLength + outByteCount,+            inTotal   = inTotal bufs   + inByteCount,+            outLength = outLength bufs + outByteCount,             outFree   = outFree'           }     if result /= errVal@@ -368,12 +344,12 @@  newtype ConversionDescriptor = ConversionDescriptor (ForeignPtr ConversionDescriptor) -- iconv_t -foreign import ccall unsafe "iconv.h iconv_open"+foreign import ccall unsafe "hsiconv.h hs_wrap_iconv_open"   c_iconv_open :: CString  -- to code                -> CString  -- from code                -> IO (Ptr ConversionDescriptor) -foreign import ccall unsafe "iconv.h iconv"+foreign import ccall unsafe "hsiconv.h hs_wrap_iconv"   c_iconv :: Ptr ConversionDescriptor           -> Ptr (Ptr CChar)  -- in buf           -> Ptr CSize        -- in buf bytes left@@ -381,5 +357,5 @@           -> Ptr CSize        -- out buf bytes left           -> IO CSize -foreign import ccall unsafe "iconv.h &iconv_close"+foreign import ccall unsafe "hsiconv.h &hs_wrap_iconv_close"   c_iconv_close :: FinalizerPtr ConversionDescriptor
+ cbits/hsiconv.c view
@@ -0,0 +1,20 @@+#include "hsiconv.h"++/* On some platforms (notably darwin) the iconv functions are defined as+ * a macro rather than a real C function. Doh! That means we need these+ * wrappers to get a real C functions we can import via the Haskell FFI.+ */++iconv_t hs_wrap_iconv_open(const char *tocode, const char *fromcode) {+  return iconv_open(tocode, fromcode);+}++size_t hs_wrap_iconv(iconv_t cd,+                     char **inbuf, size_t *inbytesleft,+                     char **outbuf, size_t *outbytesleft) {+  return iconv(cd, inbuf, inbytesleft, outbuf, outbytesleft);+}++int hs_wrap_iconv_close(iconv_t cd) {+  return iconv_close(cd);+}
+ cbits/hsiconv.h view
@@ -0,0 +1,9 @@+#include <iconv.h>++iconv_t hs_wrap_iconv_open(const char *tocode, const char *fromcode);++size_t hs_wrap_iconv(iconv_t cd,+                     char **inbuf, size_t *inbytesleft,+                     char **outbuf, size_t *outbytesleft);++int hs_wrap_iconv_close(iconv_t cd);
iconv.cabal view
@@ -1,37 +1,34 @@ name:            iconv-version:         0.4.0.2+version:         0.4.1.0 copyright:       (c) 2006-2008 Duncan Coutts license:         BSD3 license-file:    LICENSE-author:          Duncan Coutts <duncan@haskell.org>-maintainer:      Duncan Coutts <duncan@haskell.org>+author:          Duncan Coutts <duncan@community.haskell.org>+maintainer:      Duncan Coutts <duncan@community.haskell.org> category:        Text synopsis:        String encoding conversion description:     Provides an interface to the POSIX iconv library functions                  for string encoding conversion.-stability:       experimental build-type:      Simple-cabal-version:   >= 1.2.1-extra-source-files: README examples/hiconv.hs+cabal-version:   >= 1.6+extra-source-files: README examples/hiconv.hs cbits/hsiconv.h -flag bytestring_in_base+source-repository head+  type: darcs+  location: http://code.haskell.org/iconv/  library   exposed-modules: Codec.Text.IConv   other-modules:   Codec.Text.IConv.Internal-  if flag(bytestring_in_base)-    -- bytestring was in base-2.0 and 2.1.1-    build-depends: base >= 2.0 && < 2.2-    cpp-options: -DBYTESTRING_IN_BASE-  else-    build-depends: base < 2.0 || >= 2.2, bytestring >= 0.9-  extensions:      CPP, ForeignFunctionInterface-  includes:        iconv.h+  build-depends:   base >= 3 && < 5,+                   bytestring == 0.9.*+  extensions:      ForeignFunctionInterface+  includes:        hsiconv.h+  include-dirs:    cbits+  c-sources:       cbits/hsiconv.c   if os(darwin) || os(freebsd)     -- on many systems the iconv api is part of the standard C library     -- but on some others we have to link to an external libiconv:     extra-libraries: iconv -  -- We need to compile via C because on some platforms (notably darwin)-  -- iconv is a macro rather than real C function. doh!-  ghc-options:     -fvia-C -Wall+  ghc-options: -Wall