use String not Text
On second thought, git passes filepaths, which may not be valid utf8, so can't use Text here. String will be a little bit slower, but not enough to worry about.
This commit is contained in:
parent
c9866c7612
commit
d963d40815
2 changed files with 34 additions and 38 deletions
|
@ -6,14 +6,13 @@
|
||||||
- Licensed under the GNU GPL version 3 or higher.
|
- Licensed under the GNU GPL version 3 or higher.
|
||||||
-}
|
-}
|
||||||
|
|
||||||
{-# LANGUAGE OverloadedStrings, LambdaCase #-}
|
{-# LANGUAGE LambdaCase #-}
|
||||||
|
|
||||||
module Git.Protocol.LongRunningProcess where
|
module Git.Protocol.LongRunningProcess where
|
||||||
|
|
||||||
import Git.Protocol.PktLine
|
import Git.Protocol.PktLine
|
||||||
|
|
||||||
import qualified Data.Text as T
|
import Data.List
|
||||||
import Data.ByteString.Builder
|
|
||||||
import Data.Monoid
|
import Data.Monoid
|
||||||
import Control.Applicative
|
import Control.Applicative
|
||||||
import System.IO
|
import System.IO
|
||||||
|
@ -21,31 +20,30 @@ import System.IO
|
||||||
data ClientServer = Client | Server
|
data ClientServer = Client | Server
|
||||||
deriving (Show)
|
deriving (Show)
|
||||||
|
|
||||||
clientServerSuffix :: ClientServer -> T.Text
|
clientServerSuffix :: ClientServer -> String
|
||||||
clientServerSuffix Client = "-client"
|
clientServerSuffix Client = "-client"
|
||||||
clientServerSuffix Server = "-server"
|
clientServerSuffix Server = "-server"
|
||||||
|
|
||||||
data Role = Role ClientServer T.Text
|
data Role = Role ClientServer String
|
||||||
deriving (Show)
|
deriving (Show)
|
||||||
|
|
||||||
parseRole :: T.Text -> Maybe Role
|
parseRole :: String -> Maybe Role
|
||||||
parseRole t = go Client <|> go Server
|
parseRole s = go Client <|> go Server
|
||||||
where
|
where
|
||||||
go cs =
|
go cs =
|
||||||
let suffix = clientServerSuffix cs
|
let suffix = clientServerSuffix cs
|
||||||
in if suffix `T.isSuffixOf` t
|
in if suffix `isSuffixOf` s
|
||||||
then Just $ Role cs $
|
then Just $ Role cs $
|
||||||
T.take (T.length t - T.length suffix) t
|
take (length s - length suffix) s
|
||||||
else Nothing
|
else Nothing
|
||||||
|
|
||||||
pktRole :: PktLine -> Maybe Role
|
pktRole :: PktLine -> Maybe Role
|
||||||
pktRole = either (const Nothing) parseRole
|
pktRole = parseRole . pktLineString
|
||||||
. pktLineText
|
|
||||||
|
|
||||||
rolePkt :: Role -> Maybe PktLine
|
rolePkt :: Role -> Maybe PktLine
|
||||||
rolePkt (Role cs t) = textPktLine $ t <> clientServerSuffix cs
|
rolePkt (Role cs t) = stringPktLine $ t <> clientServerSuffix cs
|
||||||
|
|
||||||
newtype Capability = Capability { fromCapability :: T.Text }
|
newtype Capability = Capability { fromCapability :: String }
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq)
|
||||||
|
|
||||||
pktCapability :: PktLine -> Maybe Capability
|
pktCapability :: PktLine -> Maybe Capability
|
||||||
|
@ -54,7 +52,7 @@ pktCapability = parseKV "capability" Capability
|
||||||
capabilityPkt :: Capability -> Maybe PktLine
|
capabilityPkt :: Capability -> Maybe PktLine
|
||||||
capabilityPkt = formatKV "capability" fromCapability
|
capabilityPkt = formatKV "capability" fromCapability
|
||||||
|
|
||||||
newtype Version = Version { fromVersion :: T.Text }
|
newtype Version = Version { fromVersion :: String }
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq)
|
||||||
|
|
||||||
pktVersion :: PktLine -> Maybe Version
|
pktVersion :: PktLine -> Maybe Version
|
||||||
|
@ -126,15 +124,15 @@ handshake selectrole selectcapability input output =
|
||||||
sendpkts capabilityPkt mycaps $
|
sendpkts capabilityPkt mycaps $
|
||||||
cnt mycaps
|
cnt mycaps
|
||||||
|
|
||||||
formatKV :: T.Text -> (v -> T.Text ) -> v -> Maybe PktLine
|
formatKV :: String -> (v -> String) -> v -> Maybe PktLine
|
||||||
formatKV k f v = textPktLine $ k <> "=" <> f v
|
formatKV k f v = stringPktLine $ k <> "=" <> f v
|
||||||
|
|
||||||
parseKV :: T.Text -> (T.Text -> v) -> PktLine -> Maybe v
|
parseKV :: String -> (String -> v) -> PktLine -> Maybe v
|
||||||
parseKV k mkv = either (const Nothing) go . pktLineText
|
parseKV k mkv = go . pktLineString
|
||||||
where
|
where
|
||||||
kprefix = k <> "="
|
kprefix = k <> "="
|
||||||
go t
|
go t
|
||||||
| kprefix `T.isPrefixOf` t = Just $ mkv $
|
| kprefix `isPrefixOf` t = Just $ mkv $
|
||||||
T.drop (T.length kprefix) t
|
drop (length kprefix) t
|
||||||
| otherwise = Nothing
|
| otherwise = Nothing
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,8 @@
|
||||||
module Git.Protocol.PktLine (
|
module Git.Protocol.PktLine (
|
||||||
PktLine,
|
PktLine,
|
||||||
flushPkt,
|
flushPkt,
|
||||||
textPktLine,
|
stringPktLine,
|
||||||
pktLineText,
|
pktLineString,
|
||||||
streamPktLine,
|
streamPktLine,
|
||||||
encodePktLine,
|
encodePktLine,
|
||||||
parsePktLine,
|
parsePktLine,
|
||||||
|
@ -28,13 +28,13 @@ import Data.Attoparsec.ByteString as A
|
||||||
import Data.Attoparsec.ByteString.Char8 as A
|
import Data.Attoparsec.ByteString.Char8 as A
|
||||||
import Data.Attoparsec.ByteString.Lazy as AL
|
import Data.Attoparsec.ByteString.Lazy as AL
|
||||||
import Data.ByteString.Builder
|
import Data.ByteString.Builder
|
||||||
import qualified Data.Text as T
|
|
||||||
import qualified Data.Text.Encoding as E
|
|
||||||
import qualified Data.Text.Encoding.Error as E
|
|
||||||
import Data.Monoid
|
import Data.Monoid
|
||||||
import Data.Word
|
import Data.Word
|
||||||
import System.IO
|
import System.IO
|
||||||
|
|
||||||
|
import Utility.PartialPrelude
|
||||||
|
import Utility.FileSystemEncoding
|
||||||
|
|
||||||
-- | A pkt-line encodes a variable length binary string with a maximum size.
|
-- | A pkt-line encodes a variable length binary string with a maximum size.
|
||||||
--
|
--
|
||||||
-- This module only exports smart constructors for legal pkt-lines.
|
-- This module only exports smart constructors for legal pkt-lines.
|
||||||
|
@ -55,26 +55,24 @@ maxPktLineLength = 65520
|
||||||
flushPkt :: PktLine
|
flushPkt :: PktLine
|
||||||
flushPkt = PktLine S.empty
|
flushPkt = PktLine S.empty
|
||||||
|
|
||||||
-- | Encodes a Text as a PktLine. Fails if the Text it too large.
|
-- | Encodes a String as a PktLine. Fails if the String is too large.
|
||||||
--
|
--
|
||||||
-- A trailing newline is included after it, as the protocol recommends
|
-- A trailing newline is included after it, as the protocol recommends
|
||||||
-- doing for non-binary data.
|
-- doing for non-binary data.
|
||||||
textPktLine :: T.Text -> Maybe PktLine
|
stringPktLine :: String -> Maybe PktLine
|
||||||
textPktLine t =
|
stringPktLine s =
|
||||||
let b = E.encodeUtf8 t <> "\n"
|
let b = encodeBSS s <> "\n"
|
||||||
in if S.length b > fromIntegral maxPktLineContent
|
in if S.length b > fromIntegral maxPktLineContent
|
||||||
then Nothing
|
then Nothing
|
||||||
else Just (PktLine b)
|
else Just (PktLine b)
|
||||||
|
|
||||||
-- | Extracts Text from a PktLine. Any trailing newline is removed.
|
-- | Extracts a String from a PktLine. Any trailing newline is removed.
|
||||||
pktLineText :: PktLine -> Either E.UnicodeException T.Text
|
pktLineString :: PktLine -> String
|
||||||
pktLineText (PktLine b) = case E.decodeUtf8' b of
|
pktLineString (PktLine b) =
|
||||||
Left e -> Left e
|
let s = decodeBSS b
|
||||||
Right t ->
|
in if end s == "\n"
|
||||||
let (t', end) = T.splitAt (T.length t - 1) t
|
then beginning s
|
||||||
in if end == "\n"
|
else s
|
||||||
then Right t'
|
|
||||||
else Right t
|
|
||||||
|
|
||||||
-- | Creates a stream of PktLines encoding a lazy ByteString of any size.
|
-- | Creates a stream of PktLines encoding a lazy ByteString of any size.
|
||||||
-- Note that the stream is not terminated with a flushPkt.
|
-- Note that the stream is not terminated with a flushPkt.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue