Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libvdelta/vdexpand.c
1808 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1995-2011 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Phong Vo <[email protected]> *
18
* *
19
***********************************************************************/
20
#include "vdelhdr.h"
21
22
23
/* Expand a squeezed string
24
**
25
** Written by Kiem-Phong Vo, [email protected], 2/15/95
26
*/
27
typedef struct _table_s
28
{ uchar* delta; /* delta string */
29
uchar* tar; /* target data */
30
int n_tar;
31
K_UDECL(quick,recent,rhere); /* address caches */
32
} Table_t;
33
34
#if __STD_C
35
static int vdunfold(reg Table_t* tab)
36
#else
37
static int vdunfold(tab)
38
reg Table_t* tab;
39
#endif
40
{
41
reg int size, copy;
42
reg int inst, k_type, n;
43
reg uchar *tar, *to, *fr;
44
reg int t, c_addr, n_tar;
45
46
n_tar = tab->n_tar;
47
tar = tab->tar;
48
49
for(t = 0, c_addr = 0; t < n_tar; )
50
{ inst = STRGETC(tab);
51
k_type = K_GET(inst);
52
53
if(!VD_ISCOPY(k_type))
54
{ if(K_ISMERGE(k_type)) /* merge/add instruction */
55
size = A_TGET(inst);
56
else if(A_ISHERE(inst)) /* locally coded ADD size */
57
size = A_LGET(inst);
58
else /* non-local ADD size */
59
{ STRGETU(tab,size);
60
size = A_GET(size);
61
}
62
if((t+size) > n_tar) /* out of sync */
63
return -1;
64
c_addr += size;
65
66
/* copy data from the delta stream to target */
67
STRREAD(tab,tar+t,size);
68
t += size;
69
70
if(K_ISMERGE(k_type))
71
{ size = C_TGET(inst);
72
k_type -= K_MERGE;
73
goto do_copy;
74
}
75
}
76
else
77
{ if(C_ISHERE(inst)) /* locally coded COPY size */
78
size = C_LGET(inst);
79
else
80
{ STRGETU(tab,size);
81
size = C_GET(size);
82
}
83
do_copy:
84
if((t+size) > n_tar) /* out of sync */
85
return -1;
86
87
if(k_type >= K_QUICK && k_type < (K_QUICK+K_QTYPE) )
88
{ copy = STRGETC(tab);
89
copy = tab->quick[copy + ((k_type-K_QUICK)<<VD_BITS)];
90
}
91
else
92
{ STRGETU(tab,copy);
93
if(k_type >= K_RECENT && k_type < (K_RECENT+K_RTYPE) )
94
copy += tab->recent[k_type - K_RECENT];
95
else if(k_type == K_HERE)
96
copy = c_addr - copy;
97
/* else k_type == K_SELF */
98
}
99
K_UPDATE(tab->quick,tab->recent,tab->rhere,copy);
100
c_addr += size;
101
102
if(copy >= t || (copy+size) > n_tar) /* out-of-sync */
103
return -1;
104
105
for(;;) /* allow for copying overlapped data */
106
{ if((n = t-copy) > size)
107
n = size;
108
to = tar+t; fr = tar+copy;
109
MEMCPY(to,fr,n);
110
t += n;
111
if((size -= n) == 0)
112
break;
113
}
114
}
115
}
116
117
return 0;
118
}
119
120
#if __STD_C
121
int vdexpand(Void_t* target, int size, Void_t* delta)
122
#else
123
int vdexpand(target, size, delta)
124
Void_t* target; /* target data */
125
int size;
126
Void_t* delta; /* delta data */
127
#endif
128
{
129
reg int t;
130
Table_t tab;
131
132
/* get true target size */
133
tab.tar = (uchar*)target;
134
tab.delta = (uchar*)delta;
135
STRGETU(&tab,t);
136
if(t > size)
137
return -1;
138
tab.n_tar = t;
139
140
K_INIT(tab.quick,tab.recent,tab.rhere);
141
if(vdunfold(&tab) < 0)
142
return -1;
143
144
return t;
145
}
146
147