svndump 0.4.0 → 0.4.1
raw patch · 3 files changed
+38/−56 lines, 3 files
Files
- src/Subversion/Dump/Raw.hs +35/−53
- svndump.cabal +2/−2
- test/test-raw.hs +1/−1
src/Subversion/Dump/Raw.hs view
@@ -3,7 +3,6 @@ module Subversion.Dump.Raw ( FieldMap , Entry(..)- , readInt , readSvnDumpRaw ) where@@ -29,79 +28,62 @@ , entryProps :: FieldMap , entryBody :: BL.ByteString } deriving Show-+ readSvnDumpRaw :: BL.ByteString -> [Entry] readSvnDumpRaw dump = case parse parseHeader dump of Fail {} -> error "Stream is not a Subversion dump file" Done contents _ -> parseDumpFile contents +parseHeader :: Parser ByteString+parseHeader = string "SVN-fs-dump-format-version: 2\n\n"+ *> string "UUID: " *> takeWhile1 uuidMember+ <* newline <* newline+ -- Accept any hexadecimal character or '-'+ where uuidMember w = w == 45+ || (w >= 48 && w <= 57)+ || (w >= 97 && w <= 102)+ parseDumpFile :: BL.ByteString -> [Entry] parseDumpFile contents = case parse parseEntry contents of+ --Fail _ _ y -> error y Fail {} -> [] Done contents' (entry, bodyLen) -> entry { entryBody = BL.take (fromIntegral bodyLen) contents' } : parseDumpFile (BL.drop (fromIntegral bodyLen) contents')---- These are the Parsec parsers for the various parts of the input file. -space :: Parser Word8-space = word8 32--newline :: Parser Word8-newline = word8 10--parseTag :: Parser (ByteString, ByteString)-parseTag =- (,) <$> takeWhile1 fieldChar <* string ": " -- :- <*> takeWhile1 (/= 10) <* newline- where fieldChar w = (w >= 65 && w <= 90) -- A-Z- || (w >= 97 && w <= 121) -- a-z- || (w >= 48 && w <= 57) -- 0-9- || w == 45 -- -- || w == 95 -- _--parseIndicator :: Parser (Word8, Int)-parseIndicator = (,) <$> satisfy (oneOf 75 86) <* space -- K or V- <*> AC.decimal <* newline- where oneOf x y w = w == x || w == y--parseSpecValue :: Parser ByteString-parseSpecValue = do- (_, len) <- parseIndicator- AL.take len <* newline--parseProperty :: Parser (ByteString, ByteString)-parseProperty = (,) <$> parseSpecValue -- K- <*> parseSpecValue -- V+-- Don't read the entry body here in the parser, rather let the caller extract+-- it from the ByteString (which might be lazy, saving us from needlessly+-- strictifying it here). parseEntry :: Parser (Entry, Int) parseEntry = do- fields <- AL.takeWhile (== 10) *> many1 parseTag <* newline- props <- case L.lookup "Prop-content-length" fields of- Nothing -> return []- Just _ -> manyTill parseProperty (try (string "PROPS-END\n"))-- -- Don't read the body here in AttoParsec, let the caller extract it from- -- the ByteString (which might be lazy, saving us from strictifying it in- -- AttoParsec).- let bodyLen = fromMaybe 0 (readInt <$> L.lookup "Text-content-length" fields)-+ fields <- skipWhile (== 10) *> many1 parseTag <* newline+ props <- case L.lookup "Prop-content-length" fields of+ Nothing -> return []+ Just _ -> manyTill parseProperty (try (string "PROPS-END\n")) return ( Entry { entryTags = fields , entryProps = props , entryBody = BL.empty }- , bodyLen )+ , fromMaybe 0 (readInt <$> L.lookup "Text-content-length" fields) ) -parseHeader :: Parser ByteString-parseHeader = do- _ <- string "SVN-fs-dump-format-version: 2\n\n"- <?> "Dump file starts without a recognizable tag"- string "UUID: " *> takeWhile1 uuidMember- <* newline <* newline- where- -- Accept any hexadecimal character, or '-'- uuidMember w = w == 45 || (w >= 48 && w <= 57) || (w >= 97 && w <= 102)+parseTag :: Parser (ByteString, ByteString)+parseTag = (,) <$> takeWhile1 fieldChar <* string ": "+ <*> takeWhile1 (/= 10) <* newline+ where fieldChar w = (w >= 97 && w <= 121) -- a-z+ || (w >= 65 && w <= 90) -- A-Z+ || w == 45 -- -+ || (w >= 48 && w <= 57) -- 0-9++parseProperty :: Parser (ByteString, ByteString)+parseProperty = (,) <$> (string "K " *> getField <* newline)+ <*> (string "V " *> getField <* newline)+ -- Read a decimal integer followed by \n and 'take' that many bytes+ where getField = AC.decimal <* newline >>= AL.take++newline :: Parser Word8+newline = word8 10 -- | Efficiently convert a ByteString of integers into an Int. --
svndump.cabal view
@@ -1,6 +1,6 @@ name: svndump category: Subversion-version: 0.4.0+version: 0.4.1 license: BSD3 cabal-version: >= 1.8 license-file: LICENSE@@ -42,7 +42,7 @@ Subversion.Dump Subversion.Dump.Raw - ghc-options: -Wall -fwarn-tabs -O2+ ghc-options: -Wall -fwarn-tabs hs-source-dirs: src -- Verify the results of the examples
test/test-raw.hs view
@@ -19,7 +19,7 @@ else exitFailure (fileName:_) -> do- contents <- B.readFile fileName+ contents <- B.readFile fileName print $ length $ readSvnDumpRaw contents -- test-raw.hs ends here