1 /* -*- Mode: C;-*-
2  *
3  * This file is part of XDelta - A binary delta generator.
4  *
5  * Copyright (C) 1997, 1998, 1999  Josh MacDonald
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  *
21  * Author: Josh MacDonald <jmacd@CS.Berkeley.EDU>
22  *
23  * $Id: xdapply.c 1.1 Thu, 01 Apr 1999 23:29:11 -0800 jmacd $
24  */
25 
26 #include <string.h>
27 #include <stdlib.h>
28 
29 #include "xdelta.h"
30 #include "xdeltapriv.h"
31 
32 /* This code used to be more general, but implemented a very
33  * inefficient algorithm.  It is sufficient (and efficient) for the
34  * special case below, though, so I'm leaving it. */
35 static gboolean
xdp_copy_delta_region(XdeltaControl * cont,XdeltaOutStream * output_stream)36 xdp_copy_delta_region    (XdeltaControl     *cont,
37 			  XdeltaOutStream   *output_stream)
38 {
39   gint i, l = cont->inst_len;
40   guint save_written = 0;
41 
42   for (i = 0; i < l; i += 1)
43     {
44       const XdeltaInstruction *inst = cont->inst + i;
45       XdeltaSourceInfo* info;
46 
47       if (inst->index >= cont->source_info_len)
48 	{
49 	  xd_generate_int_event (EC_XdOutOfRangeSourceIndex, inst->index);
50 	  return FALSE;
51 	}
52 
53       info = cont->source_info[inst->index];
54 
55       if (! handle_copy (info->in, output_stream, inst->offset, inst->length))
56 	return FALSE;
57 
58       save_written += inst->length;
59     }
60 
61   return TRUE;
62 }
63 
64 gboolean
xdp_apply_delta(XdeltaControl * cont,XdeltaOutStream * res)65 xdp_apply_delta (XdeltaControl     *cont,
66 		 XdeltaOutStream   *res)
67 {
68   if (! xdp_copy_delta_region (cont, res))
69     return FALSE;
70 
71   if (! handle_close (res, 0))
72     return FALSE;
73 
74   if (! check_stream_integrity (res, cont->to_md5, cont->to_len))
75     {
76       int i;
77 
78       /* to better report errors, check if the inputs were invalid now
79        */
80       for (i = 0; i < cont->source_info_len; i += 1)
81 	{
82 	  check_stream_integrity (cont->source_info[i]->in,
83 				  cont->source_info[i]->md5,
84 				  cont->source_info[i]->len);
85 	}
86 
87       return FALSE;
88     }
89 
90   return TRUE;
91 }
92