From mboxrd@z Thu Jan 1 00:00:00 1970 From: =?UTF-8?q?Herv=C3=A9=20Cauwelier?= Subject: [PATCH 4/6] Inflate an object from a pack file Date: Wed, 14 Oct 2009 12:37:47 +0200 Message-ID: <1255516669-26745-4-git-send-email-herve@itaapy.com> References: <1255516669-26745-1-git-send-email-herve@itaapy.com> <1255516669-26745-2-git-send-email-herve@itaapy.com> <1255516669-26745-3-git-send-email-herve@itaapy.com> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: QUOTED-PRINTABLE To: git@vger.kernel.org X-From: git-owner@vger.kernel.org Wed Oct 14 12:50:14 2009 Return-path: Envelope-to: gcvg-git-2@lo.gmane.org Received: from vger.kernel.org ([209.132.176.167]) by lo.gmane.org with esmtp (Exim 4.50) id 1My1Qi-0004AO-A0 for gcvg-git-2@lo.gmane.org; Wed, 14 Oct 2009 12:50:04 +0200 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932771AbZJNKps convert rfc822-to-quoted-printable (ORCPT ); Wed, 14 Oct 2009 06:45:48 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S932340AbZJNKps (ORCPT ); Wed, 14 Oct 2009 06:45:48 -0400 Received: from mailhost-p4-m2.nerim.net ([78.40.49.191]:51107 "EHLO smtp-delay2.nerim.net" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1755526AbZJNKpn (ORCPT ); Wed, 14 Oct 2009 06:45:43 -0400 Received: from mallaury.nerim.net (smtp-103-wednesday.noc.nerim.net [62.4.17.103]) by smtp-delay2.nerim.net (Postfix) with ESMTP id EF30AB3CD4C for ; Wed, 14 Oct 2009 12:36:53 +0200 (CEST) Received: from localhost.localdomain (itaapy-35-170.cnt.nerim.net [213.215.35.170]) by mallaury.nerim.net (Postfix) with ESMTP id 2C62BA107F for ; Wed, 14 Oct 2009 12:35:53 +0200 (CEST) X-Mailer: git-send-email 1.6.5 In-Reply-To: <1255516669-26745-3-git-send-email-herve@itaapy.com> Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Archived-At: Support delta objects too. Signed-off-by: Herv=C3=A9 Cauwelier --- src/odb.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++- 1 files changed, 68 insertions(+), 1 deletions(-) diff --git a/src/odb.c b/src/odb.c index 349747b..c71948b 100644 --- a/src/odb.c +++ b/src/odb.c @@ -28,6 +28,7 @@ #include "git/zlib.h" #include "fileops.h" #include "hash.h" +#include "delta-apply.h" #include "odb.h" =20 #define GIT_PACK_NAME_MAX (5 + 40 + 1) @@ -232,7 +233,7 @@ static int is_zlib_compressed_data(unsigned char *d= ata) unsigned int w; =20 w =3D ((unsigned int)(data[0]) << 8) + data[1]; - return data[0] =3D=3D 0x78 && !(w %31); + return data[0] =3D=3D 0x78 && !(w % 31); } =20 static size_t get_binary_object_header(obj_hdr *hdr, gitfo_buf *obj) @@ -1192,6 +1193,72 @@ int git_odb__read_loose(git_obj *out, git_odb *d= b, const git_oid *id) return GIT_SUCCESS; } =20 +static int inflate_pack_obj(git_obj *out, git_pack *p, off_t offset) +{ + obj_hdr hdr; + gitfo_buf buf; + size_t used; + void *data; + git_obj base; + + /* Cast the map to a gitfo_buf */ + buf.data =3D (unsigned char *)p->pack_map.data + offset; + buf.len =3D p->pack_map.len - offset; + + /* + * Read the object header, which is an (uncompressed) + * binary encoding of the object type and size. + */ + if (!(used =3D get_binary_object_header(&hdr, &buf))) + return GIT_ERROR; + + /* + * Read the object data as a zlib compressed data + */ + buf.data +=3D used; + buf.len -=3D used; + assert(is_zlib_compressed_data(buf.data)); + + if (!(data =3D git__malloc(hdr.size + 1))) + return GIT_ERROR; + if (inflate_buffer(buf.data, buf.len, data, hdr.size)) + goto inflate_fail; + + switch (hdr.type) { + case GIT_OBJ_COMMIT: + case GIT_OBJ_TREE: + case GIT_OBJ_BLOB: + case GIT_OBJ_TAG: + out->data =3D data; + out->len =3D hdr.size; + out->type =3D hdr.type; + return GIT_SUCCESS; + case GIT_OBJ_OFS_DELTA: + offset -=3D hdr.base_offset; + if (inflate_pack_obj(&base, p, offset)) + goto inflate_fail; + if (git__delta_apply(out, base.data, base.len, data, hdr.size)) + goto inflate_fail; + out->type =3D base.type; + return GIT_SUCCESS; + case GIT_OBJ_REF_DELTA: + if (p->idx_search(&offset, p, &hdr.base_name)) + goto inflate_fail; + if (inflate_pack_obj(&base, p, offset)) + goto inflate_fail; + if (git__delta_apply(out, base.data, base.len, data, hdr.size)) + goto inflate_fail; + out->type =3D base.type; + return GIT_SUCCESS; + default: + goto inflate_fail; + } + +inflate_fail: + free(data); + return GIT_ERROR; +} + static int read_packed(git_obj *out, git_pack *p, const git_oid *id) { off_t pos; --=20 1.6.5