Skip to content

Commit

Permalink
pack: parse OBJ_OFS_DELTA base
Browse files Browse the repository at this point in the history
This was introduced in git in the following commit:
http://www.gelato.unsw.edu.au/archives/git/0609/27763.html

The encoding does not seem to be otherwise documented in the git source
or the git book.
  • Loading branch information
kfish committed May 2, 2011
1 parent 0e640fd commit eede640
Showing 1 changed file with 19 additions and 11 deletions.
30 changes: 19 additions & 11 deletions Git/Pack.hs
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,13 @@ data PackObjectType = OBJ_COMMIT
| OBJ_TREE
| OBJ_BLOB
| OBJ_TAG
| OBJ_OFS_DELTA
| OBJ_REF_DELTA
| OBJ_OFS_DELTA Int
| OBJ_REF_DELTA [Word8]
deriving (Show, Eq)

data PackObject = PackObject
{ poType :: PackObjectType
, poSize :: Int
, poBase :: Maybe [Word8]
, poData :: ByteString
} deriving (Show)

Expand Down Expand Up @@ -85,17 +84,17 @@ packObjectRead = do
sz' <- if doNext x
then readSize 4 sz
else return sz
base <- readBase t
t' <- readBase t
d <- I.joinIM $ enumInflate Zlib defaultDecompressParams I.stream2stream
return $ PackObject <$> t <*> pure sz' <*> pure base <*> pure d
return $ PackObject <$> t' <*> pure sz' <*> pure d
where
parseOBJ :: Word8 -> Maybe PackObjectType
parseOBJ 1 = Just OBJ_COMMIT
parseOBJ 2 = Just OBJ_TREE
parseOBJ 3 = Just OBJ_BLOB
parseOBJ 4 = Just OBJ_TAG
parseOBJ 6 = Just OBJ_OFS_DELTA
parseOBJ 7 = Just OBJ_REF_DELTA
parseOBJ 6 = Just (OBJ_OFS_DELTA 0)
parseOBJ 7 = Just (OBJ_REF_DELTA [])
parseOBJ _ = Nothing

doNext :: Word8 -> Bool
Expand All @@ -109,10 +108,19 @@ packObjectRead = do
then readSize (shft+7) sz
else return sz

readBase :: Maybe PackObjectType -> I.Iteratee ByteString IO (Maybe [Word8])
readBase (Just OBJ_OFS_DELTA) = Just <$> (sequence $ replicate 20 I.head)
readBase (Just OBJ_REF_DELTA) = Just <$> (sequence $ replicate 20 I.head)
readBase _ = return Nothing
readBase :: Maybe PackObjectType -> I.Iteratee ByteString IO (Maybe PackObjectType)
readBase (Just (OBJ_OFS_DELTA 0)) = Just . OBJ_OFS_DELTA <$> readOFSBase 0 0
readBase (Just (OBJ_REF_DELTA [])) = Just . OBJ_REF_DELTA <$> (sequence $ replicate 20 I.head)
readBase (Just t) = return (Just t)
readBase Nothing = return Nothing

readOFSBase :: Int -> Int -> I.Iteratee ByteString IO Int
readOFSBase shft acc = do
x <- I.head
let bs = acc + (((castEnum (x .&. 0x7f)) :: Int) `shiftL` shft)
if doNext x
then readOFSBase (shft+7) (bs+1)
else return bs

castEnum = toEnum . fromEnum

Expand Down

0 comments on commit eede640

Please sign in to comment.