bini (empty) → 0.1.0
raw patch · 6 files changed
+214/−0 lines, 6 filesdep +basesetup-changed
Dependencies added: base
Files
- CHANGES +4/−0
- LICENSE +27/−0
- README +2/−0
- Setup.hs +2/−0
- bini.cabal +25/−0
- src/Data/Bini.hs +154/−0
+ CHANGES view
@@ -0,0 +1,4 @@++* 0.1++ - Allows you to parse Bini-files
+ LICENSE view
@@ -0,0 +1,27 @@+Copyright (c) 2016 Tobias Weise++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions+are met:+1. Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.+2. Redistributions in binary form must reproduce the above copyright+ notice, this list of conditions and the following disclaimer in the+ documentation and/or other materials provided with the distribution.+3. Neither the name of the author nor the names of other contributors+ may be used to endorse or promote products derived from this software+ without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF+SUCH DAMAGE.
+ README view
@@ -0,0 +1,2 @@++Data.Bini is a manipulation library for b(inary)ini files used in windows programms like the game Freelancer.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ bini.cabal view
@@ -0,0 +1,25 @@+Name: bini+Version: 0.1.0+Stability: stable++Description: A collection of various methods for reading and writing bini files. +Synopsis: A manipulation library for b(inary)ini files used in windows programms like the game Freelancer.+License: BSD3+License-file: LICENSE+Copyright: (c) Tobias Weise 2016+Extra-source-files: README, CHANGES+Author: Tobias Weise+Maintainer: tobias_weise@gmx.de+Category: Data, Configuration+Build-type: Simple+Cabal-Version: >= 1.10+Tested-with: GHC ==7.0.4, GHC ==7.2.1, GHC ==7.4.*, GHC ==7.6.1+Bug-reports: ++Library+ ghc-options: -Wall+ build-depends: base <4.8+ exposed-modules: Data.Bini+ default-language: Haskell2010+ hs-source-dirs: src/+
+ src/Data/Bini.hs view
@@ -0,0 +1,154 @@+++-- | Compressed binary configuration files in the (B)INI format.+--+--+-- Parsing example:+--+-- @+-- r <- readBiniFromFile "loadouts.ini"+-- case r of+-- Nothing -> putStrLn "No file, no output!"+-- Just bini -> do+-- writeFile "loadouts.ini.txt" (show bini)+-- @+--+-- Outputfile:+--+-- @+-- [Loadout]+-- nickname = msn_playerloadout+-- archetype = ge_fighter+-- equip = ge_gf1_engine_01+-- equip = shield01_mark01_lf, HpShield01+-- equip = ge_fighter_power01+-- ...+-- @+++module Data.Bini+ (-- * Reading+ readBiniFromFile,+ -- * Types+ Bini(..),+ Section(..),+ Entry(..),+ BiniVal(..)) where++import qualified Data.ByteString.Lazy as BL+import Data.Binary.Get+import Data.Word+import Data.Binary+import Data.Int+import Data.List(intercalate)++--helper++bstr2str :: BL.ByteString -> String+bstr2str = tail.init.show++-- |Get a String from the stringtable+getOffset :: BL.ByteString -> Int -> BL.ByteString+getOffset bstr offset = BL.takeWhile (\c-> not $ c==0) s where+ (_,s) = BL.splitAt (fromIntegral offset) bstr++--datatypes++-- |The abstract representation of the Bini+data Bini = Bini{ version :: Int, sections :: [Section] }++-- |The abstract representation of a section+data Section = Section{ name :: String, entries :: [Entry] }++-- |The abstract representation of an entry+data Entry = Entry String [BiniVal]++-- |The abstract representation of a bini-value+data BiniVal = BiniInt Int | BiniFloat Float | BiniString String++++instance Show Bini where+ show (Bini v secs) = intercalate "\n" (map show secs)++instance Show Section where+ show (Section name entries) = "["++name++"]\n"++(intercalate "\n" (map show entries))++"\n"++instance Show Entry where+ show (Entry name vals) = name++" = "++(intercalate ", " (map show vals))++instance Show BiniVal where+ show (BiniInt i) = show i+ show (BiniFloat f) = show f+ show (BiniString s) = s+++-- |Parse a Binifile+readBiniFromFile :: String -> IO (Maybe Bini)+readBiniFromFile path = do+ content <- BL.readFile path+ let (isBini, version, strtableoff) = runGet parseHeader content+ let (header_body, table) = BL.splitAt (fromIntegral strtableoff) content+ let body = BL.drop 12 header_body+ let secs = runGet (parseSections table) body+ return $ Just $ Bini version secs+++--Parsing the Bini-file:++-- |Parse an entry+parseEntry :: BL.ByteString -> Get Entry+parseEntry ls = do+ stroffset <- getWord16le+ n_vals <- getWord8+ let entryname = bstr2str $ ls `getOffset` (fromIntegral stroffset)+ vals <- sequence [parseVal ls | x<-[1..(fromIntegral n_vals)]]+ return (Entry entryname vals)++-- |Parse an entry-value+parseVal :: BL.ByteString -> Get BiniVal+parseVal ls = do+ typ <- getWord8+ dat <- getWord32le+ let val = case (fromIntegral typ) of+ 1 -> BiniInt $ fromIntegral dat+ 2 -> BiniFloat $ fromIntegral dat+ 3 -> BiniString $ bstr2str $ ls `getOffset` (fromIntegral dat)+ return val++parseSection :: BL.ByteString -> Get Section+parseSection table = do+ stroffset <- getWord16le+ num_e <- getWord16le+ let secname = bstr2str $ table `getOffset` (fromIntegral stroffset)+ let num_entries = fromIntegral num_e+ entries <- sequence [parseEntry table | x<-[1..num_entries]]+ return Section{ name = secname, entries = entries }++parseSections :: BL.ByteString -> Get [Section]+parseSections table = do+ b <- isEmpty+ if b then do+ return []+ else do+ sec <- parseSection table+ b2 <- isEmpty+ if b2 then do+ return [sec]+ else do+ secs <- parseSections table+ return $ [sec]++secs++parseHeader :: Get (Word32, Int, Int)+parseHeader = do+ isBini <- getWord32le+ version <- getWord32le+ str_table_offset <- getWord32le+ return (isBini, fromIntegral version, fromIntegral str_table_offset)+++++++