peekCAStringLen (cp, len)  = do
  cs <- peekArray len cp
  return (cCharsToChars cs)
#else
peekCAStringLen (cp, len) 
  | len <= 0  = return "" -- being (too?) nice.
  | otherwise = loop [] (len-1)
  where
    loop acc i = do
         xval <- peekElemOff cp i
	 let val = castCCharToChar xval
	   -- blow away the coercion ASAP.
	 if (val `seq` (i == 0))
	  then return (val:acc)
	  else loop (val:acc) (i-1)
#endif

-- | Marshal a Haskell string into a NUL terminated C string.
--
-- * the Haskell string may /not/ contain any NUL characters
--
-- * new storage is allocated for the C string and must be
--   explicitly freed using 'Foreign.Marshal.Alloc.free' or
--   'Foreign.Marshal.Alloc.finalizerFree'.
--
peekCAStringLen (cp, len)  = do
  cs <- peekArray len cp
  return (cCharsToChars cs)
#else
peekCAStringLen (cp, len) 
  | len <= 0  = return "" -- being (too?) nice.
  | otherwise = loop [] (len-1)
  where
    loop acc i = do
         xval <- peekElemOff cp i
	 let val = castCCharToChar xval
	   -- blow away the coercion ASAP.
	 if (val `seq` (i == 0))
	  then return (val:acc)
	  else loop (val:acc) (i-1)
#endif

-- | Marshal a Haskell string into a NUL terminated C string.
--
-- * the Haskell string may /not/ contain any NUL characters
--
-- * new storage is allocated for the C string and must be
--   explicitly freed using 'Foreign.Marshal.Alloc.free' or
--   'Foreign.Marshal.Alloc.finalizerFree'.
--
peekCAStringLen (cp, len)  = do
  cs <- peekArray len cp
  return (cCharsToChars cs)
#else
peekCAStringLen (cp, len) 
  | len <= 0  = return "" -- being (too?) nice.
  | otherwise = loop [] (len-1)
  where
    loop acc i = do
         xval <- peekElemOff cp i
	 let val = castCCharToChar xval
	   -- blow away the coercion ASAP.
	 if (val `seq` (i == 0))
	  then return (val:acc)
	  else loop (val:acc) (i-1)
#endif

-- | Marshal a Haskell string into a NUL terminated C string.
--
-- * the Haskell string may /not/ contain any NUL characters
--
-- * new storage is allocated for the C string and must be
--   explicitly freed using 'Foreign.Marshal.Alloc.free' or
--   'Foreign.Marshal.Alloc.finalizerFree'.
--