{----------------------------------------------------------------- (c) 2008-2009 Markus Dittrich This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License Version 3 as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License Version 3 for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --------------------------------------------------------------------} -- | this module parses the contents of a package and -- puts everything into a list of PackageContent data -- structures module Parsers.Content ( defaultContent , get_content , FileType(..) , PackageContentItem(..) , retrieve_package_content ) where -- basic imports import qualified Data.ByteString as B(ByteString, null, split, concat) import Prelude import System.FilePath.Posix(()) import Text.Regex.PCRE((=~)) -- local imports import Helpers.ByteString(newlineW, remove_last_newline, spaceChar, spaceCharW) import Helpers.FileIO(read_file) -- | data type for describing the type of "file" -- in the PackageContent data FileType = None | Dir | Sym | Obj deriving(Eq) -- | data structure for holding a single entry in the -- CONTENTS file of a package data PackageContentItem = PackageContentItem { fileType :: FileType, name :: B.ByteString, md5 :: B.ByteString, size :: B.ByteString } deriving(Eq) -- | default Dependency data structure defaultContent :: PackageContentItem defaultContent = PackageContentItem { fileType = None, name = spaceChar, md5 = spaceChar, size = spaceChar } -- | read the CONTENT of a file and return it as a raw -- ByteString get_content :: FilePath -> IO B.ByteString get_content path = read_file (path "CONTENTS") -- | retrieve content of package located at location path retrieve_package_content :: FilePath -> IO [PackageContentItem] retrieve_package_content path = get_content path >>= return . content_parser -- | split the content into list of lines and then hands them -- over for parsing of each line -- NOTE: the passed string may be empty so we need to check content_parser :: B.ByteString -> [PackageContentItem] content_parser content | B.null content = [] | otherwise = map (parse_line) splitLines where lineList = B.split newlineW $ remove_last_newline content splitLines = map (B.split spaceCharW) lineList -- | parse each line and create a corresponding -- PackageContentItem entry parse_line :: [B.ByteString] -> PackageContentItem parse_line [] = defaultContent parse_line (x:xs) | x =~ "dir" = defaultContent { fileType = Dir, name = head xs } | x =~ "sym" = defaultContent { fileType = Sym, name = assemble_link xs, size = (!!) xs 3 } | x =~ "obj" = defaultContent { fileType = Obj, name = (!!) xs 0, md5 = (!!) xs 1, size = (!!) xs 2 } | otherwise = defaultContent where assemble_link :: [B.ByteString] -> B.ByteString assemble_link (a:b:c:_) = B.concat [a, spaceChar, b, spaceChar, c] assemble_link _ = spaceChar