X-Git-Url: http://git.cielonegro.org/gitweb.cgi?a=blobdiff_plain;f=Network%2FHTTP%2FLucu%2FUtils.hs;h=ec4b6727f60567613549604a1c0e209d6d2a7727;hb=db4b61223e0d8b34079d3b190fb3e3644b0b4866;hp=abd4556b64930789940b2f89da1e75e5fe6c7ca5;hpb=65a16e9330e797303a5cf8143dcbe135812d526f;p=Lucu.git diff --git a/Network/HTTP/Lucu/Utils.hs b/Network/HTTP/Lucu/Utils.hs index abd4556..ec4b672 100644 --- a/Network/HTTP/Lucu/Utils.hs +++ b/Network/HTTP/Lucu/Utils.hs @@ -10,11 +10,15 @@ module Network.HTTP.Lucu.Utils , joinWith , quoteStr , parseWWWFormURLEncoded + , show3 ) where +import Blaze.ByteString.Builder.ByteString as B +import Blaze.Text.Int as BT import Control.Monad import Data.Ascii (Ascii, AsciiBuilder) import qualified Data.Ascii as A +import Data.ByteString (ByteString) import qualified Data.ByteString.Char8 as BS import Data.List hiding (last) import Data.Monoid.Unicode @@ -65,13 +69,33 @@ quoteStr str = A.toAsciiBuilder "\"" ⊕ -- |> parseWWWFormURLEncoded "aaa=bbb&ccc=ddd" -- > ==> [("aaa", "bbb"), ("ccc", "ddd")] -parseWWWFormURLEncoded ∷ String → [(String, String)] +parseWWWFormURLEncoded ∷ Ascii → [(ByteString, ByteString)] parseWWWFormURLEncoded src - | src == "" = [] - | otherwise = do pairStr <- splitBy (\ c → c == ';' || c == '&') src - let (key, value) = break (== '=') pairStr - return ( unEscapeString key - , unEscapeString $ case value of - ('=':val) → val - val → val + -- THINKME: We could gain some performance by using attoparsec + -- here. + | src ≡ "" = [] + | otherwise = do pairStr ← splitBy (\ c → c ≡ ';' ∨ c ≡ '&') (A.toString src) + let (key, value) = break (≡ '=') pairStr + return ( unescape key + , unescape $ case value of + ('=':val) → val + val → val ) + where + unescape ∷ String → ByteString + unescape = BS.pack ∘ unEscapeString ∘ map plusToSpace + + plusToSpace ∷ Char → Char + plusToSpace '+' = ' ' + plusToSpace c = c + +-- |> show3 5 +-- > ==> "005" +show3 ∷ Integral n ⇒ n → AsciiBuilder +{-# INLINEABLE show3 #-} +show3 = A.unsafeFromBuilder ∘ go + where + go i | i ≥ 0 ∧ i < 10 = B.fromByteString "00" ⊕ BT.digit i + | i ≥ 0 ∧ i < 100 = B.fromByteString "0" ⊕ BT.integral i + | i ≥ 0 ∧ i < 1000 = BT.integral i + | otherwise = error ("show3: the integer i must satisfy 0 <= i < 1000: " ⧺ show i)