Permalink
Browse files

extracting offset delta and base obj data properly, just need to patc…

…h it
  • Loading branch information...
1 parent a97300e commit ab92a2b5bec992f364934c7a243e5114a6778f3b @schacon committed Dec 3, 2009
Showing with 75 additions and 17 deletions.
  1. +63 −15 src/packfile.erl
  2. +2 −2 t/002-cat-file-packed.t
  3. +10 −0 t/004-cat-file-packed-delta.t
View
78 src/packfile.erl
@@ -8,34 +8,82 @@
get_packfile_data(PackFilePath, Offset) ->
case file:open(PackFilePath, [read, binary]) of
{ok, IoDevice} ->
- file:position(IoDevice, Offset),
- {ok, Byte} = file:read(IoDevice, 1),
- <<ContinueBit:1, Type:3, InitSize:4>> = Byte,
- %io:fwrite("Object Data: ~p ~p ~p~n", [ContinueBit, Type, InitSize]),
- {Size, Data} = read_object_data(IoDevice, ContinueBit, InitSize, 0),
- %io:fwrite("Final Object Data: ~p ~p ~p~n", [Size, Type, Data]),
- {type_int_to_term(Type), Size, Data};
+ read_packfile_object_offset(IoDevice, Offset);
{error, Reason} ->
error
end.
-read_object_data(IoDevice, 1, Size, Offset) ->
+read_packfile_object_offset(IoDevice, Offset) ->
+ file:position(IoDevice, Offset),
+ {ok, Byte} = file:read(IoDevice, 1),
+ <<ContinueBit:1, Type:3, InitSize:4>> = Byte,
+ TypeTerm = type_int_to_term(Type),
+ %io:fwrite("Object Data: ~p ~p ~p~n", [ContinueBit, Type, InitSize]),
+ {FinalType, Size, Data} = read_object_data(IoDevice, ContinueBit, InitSize, 4, Offset, Offset + 1, TypeTerm),
+ io:fwrite("Final Object Data: ~p ~p ~p~n", [Size, FinalType, Data]),
+ {FinalType, Size, Data}.
+
+read_object_data(IoDevice, 1, Size, Offset, OrigOffset, FileOffset, TypeTerm) ->
{ok, Byte} = file:read(IoDevice, 1),
<<ContinueBit:1, NextSize:7>> = Byte,
% bit shift the size
- NextOffset = Offset + 4,
- SizeOr = NextSize bsl NextOffset,
+ SizeOr = NextSize bsl Offset,
NewSize = Size bor SizeOr,
+ NextOffset = Offset + 7,
%io:fwrite("Object Data: ~p ~p (~p)~n", [ContinueBit, NextSize, NewSize]),
- read_object_data(IoDevice, ContinueBit, NewSize, NextOffset);
-read_object_data(IoDevice, 0, Size, Offset) ->
+ read_object_data(IoDevice, ContinueBit, NewSize, NextOffset, OrigOffset, FileOffset + 1, TypeTerm);
+read_object_data(IoDevice, 0, Size, Offset, OrigOffset, FileOffset, ofs_delta) ->
+ read_ofs_deltified_object_data(IoDevice, Size, Offset, FileOffset, OrigOffset);
+read_object_data(IoDevice, 0, Size, Offset, OrigOffset, FileOffset, ref_delta) ->
+ read_ref_deltified_object_data(IoDevice, Size, Offset, FileOffset, OrigOffset);
+read_object_data(IoDevice, 0, Size, Offset, OrigOffset, FileOffset, NormalType) ->
Z = zlib:open(),
ok = zlib:inflateInit(Z),
Data = inflate_object_data(Z, IoDevice, []),
%io:fwrite("Bits:~p~n", [Data]),
ok = zlib:inflateEnd(Z),
zlib:close(Z),
- {Size, Data}.
+ {NormalType, Size, Data}.
+
+read_ofs_deltified_object_data(IoDevice, Size, Offset, FileOffset, OrigOffset) ->
+ {ok, BaseOffset, BytesRead} = get_base_offset(IoDevice),
+ NewOffset = OrigOffset - BaseOffset,
+ io:fwrite("BaseOffset: ~p:~p:~p~n", [NewOffset, OrigOffset, BaseOffset]),
+ {TypeTerm, BaseSize, BaseData} = read_packfile_object_offset(IoDevice, NewOffset),
+ file:position(IoDevice, FileOffset + BytesRead),
+ {TypeTerm, DeltaSize, DeltaData} = read_object_data(IoDevice, 0, Size, Offset, OrigOffset, FileOffset + BytesRead, TypeTerm),
+ io:fwrite("DeltaData: ~p:~p:~p~n", [TypeTerm, DeltaSize, DeltaData]),
+ PatchedData = patch_delta(DeltaData, BaseData),
+ {TypeTerm, BaseSize, PatchedData}.
+
+patch_delta(DeltaData, BaseData) ->
+ BaseData.
+
+get_base_offset(IoDevice) ->
+ {ok, Byte} = file:read(IoDevice, 1),
+ <<ContinueBit:1, NextData:7>> = Byte,
+ get_base_offset(IoDevice, ContinueBit, NextData, 1).
+
+get_base_offset(IoDevice, 1, Offset, BytesRead) ->
+ {ok, Byte} = file:read(IoDevice, 1),
+ <<ContinueBit:1, NextData:7>> = Byte,
+ io:fwrite("Data:~p:~p~n", [ContinueBit, NextData]),
+ Offset2 = Offset + 1,
+ Offset3 = Offset2 bsl 7,
+ NewOffset = Offset3 bor NextData,
+ get_base_offset(IoDevice, ContinueBit, NewOffset, BytesRead + 1);
+get_base_offset(_IoDevice, 0, Offset, BytesRead) ->
+ {ok, Offset, BytesRead}.
+
+
+read_ref_deltified_object_data(IoDevice, Size, Offset, FileOffset, OrigOffset) ->
+ {ok, Sha} = file:read(IoDevice, 20),
+ HexSha = hex:bin_to_hexstr(Sha),
+ % find the offset of HexSha, run read_object_data again
+ % {Size, Data} = get_packfile_data(Path, Offset),
+ % DeltaData = read_object_data(%here),
+ % patch_delta(Data, DeltaData)
+ {100, <<"Ref Data">>}.
inflate_object_data(Z, IoDevice, SoFar) ->
case file:read(IoDevice, 4096) of
@@ -63,6 +111,6 @@ type_int_to_term(ObjInt) ->
2 -> tree;
3 -> blob;
4 -> tag;
- 6 -> delta_ofs;
- 7 -> delta_base
+ 6 -> ofs_delta;
+ 7 -> ref_delta
end.
View
4 t/002-cat-file-packed.t
@@ -4,8 +4,8 @@
main(_) ->
Git = git:open("test_git"),
- %{Type, Size, Data} = git:read_object(Git, "aa7dfe7c2a634cb9e7a9d5838eb58fe150ebd7fb"), %% tree
- {Type, Size, Data} = git:read_object(Git, "be62addb149d286893e2ec254e0dc783a871e8af"), %% tree
+ {Type, Size, Data} = git:read_object(Git, "aa7dfe7c2a634cb9e7a9d5838eb58fe150ebd7fb"), %% tree
+ %{Type, Size, Data} = git:read_object(Git, "be62addb149d286893e2ec254e0dc783a871e8af"), %% tree
io:fwrite("Data: ~p ~p~n", [Type, Size]),
io:fwrite("Data: ~p~n", [Data]),
io:fwrite("Data: ~s~n", [binary_to_list(Data)]).
View
10 t/004-cat-file-packed-delta.t
@@ -0,0 +1,10 @@
+#!/usr/bin/env escript
+%% -*- erlang -*-
+%%! -pa ./ebin -sasl -boot start_sasl -noshell
+
+main(_) ->
+ Git = git:open("test_git"),
+ {Type, Size, Data} = git:read_object(Git, "9cad8d7e8ee5b3b6fcb401ac9dcc557dd808762d"), %% tree
+ io:fwrite("Data: ~p ~p~n", [Type, Size]),
+ io:fwrite("Data: ~p~n", [Data]),
+ io:fwrite("Data: ~s~n", [binary_to_list(Data)]).

0 comments on commit ab92a2b

Please sign in to comment.