Skip to content

Commit

Permalink
More touch ups
Browse files Browse the repository at this point in the history
  • Loading branch information
oldmanmike committed Nov 11, 2015
1 parent 291ca0d commit 694a753
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 2 deletions.
3 changes: 1 addition & 2 deletions README.md
Expand Up @@ -24,8 +24,7 @@ For the most basic usage, you'll need to read a NBT file in as a `ByteString`, d
import qualified Codec.Compression.GZip as GZip
import qualified Data.ByteString.Lazy as BL
import Data.NBT
import Data.Serialize.Get
import Data.Serialize.Put
import Data.Serialize

main :: IO ()
main = do
Expand Down
16 changes: 16 additions & 0 deletions src/Data/NBT.hs
Expand Up @@ -52,15 +52,18 @@ data TagType
| IntArrayType
deriving (Show, Eq, Enum)


instance Serialize TagType where
get = fmap (toEnum . fromIntegral) getWord8
put = putWord8 . fromIntegral . fromEnum


-- | Primitive representation of NBT data. This type contains only the data
-- part, since named nodes can only exist inside compound nodes.
data NBT = NBT T.Text NbtContents
deriving (Show, Eq)


data NbtContents
= ByteTag Int8
| ShortTag Int16
Expand All @@ -75,6 +78,7 @@ data NbtContents
| IntArrayTag (UArray Int32 Int32)
deriving (Show, Eq)


getByType :: TagType -> Get NbtContents
getByType EndType = fail "Can not get end-marker elements"
getByType ByteType = ByteTag <$> get
Expand All @@ -89,11 +93,13 @@ getByType ListType = ListTag <$> getList
getByType CompoundType = CompoundTag <$> getCompoundElements
getByType IntArrayType = IntArrayTag <$> getArrayElements get


getList :: Get (Array Int32 NbtContents)
getList = do
subType <- get
getArrayElements (getByType subType)


putList :: Array Int32 NbtContents -> Put
putList ts = do
let ty = case elems ts of
Expand All @@ -102,6 +108,7 @@ putList ts = do
put ty
putArray putContents ts


getCompoundElements :: Get [NBT]
getCompoundElements = do
ty <- get
Expand All @@ -111,34 +118,40 @@ getCompoundElements = do
xs <- getCompoundElements
return (x:xs)


putCompoundElements :: [NBT] -> Put
putCompoundElements xs = traverse_ put xs >> put EndType


getArrayElements :: IArray a e => Get e -> Get (a Int32 e)
getArrayElements getter = do
len <- get
elts <- replicateM (fromIntegral len) getter
return (listArray (0, len - 1) elts)


getString :: Get T.Text
getString = do
len <- get :: Get Int16
bs <- getByteString (fromIntegral len)
return (decodeUtf8 bs)


putString :: T.Text -> Put
putString str = do
let bs = encodeUtf8 str
len = B.length bs
put (fromIntegral len :: Int16)
putByteString bs


putArray :: (Ix i, IArray a e) => (e -> Put) -> a i e -> Put
putArray putter a = do
let len = rangeSize (bounds a)
put (fromIntegral len :: Int32)
traverse_ putter (elems a)


putContents :: NbtContents -> Put
putContents tag = case tag of
ByteTag b -> put b
Expand All @@ -153,6 +166,7 @@ putContents tag = case tag of
CompoundTag ts -> putCompoundElements ts
IntArrayTag is -> putArray put is


instance Serialize NBT where
get = do
ty <- get
Expand All @@ -162,9 +176,11 @@ instance Serialize NBT where
putString name
putContents tag


getNBT :: TagType -> Get NBT
getNBT ty = NBT <$> getString <*> getByType ty


typeOf :: NbtContents -> TagType
typeOf ByteTag {} = ByteType
typeOf ShortTag {} = ShortType
Expand Down

0 comments on commit 694a753

Please sign in to comment.