38
38
#endif
39
39
#define _check (value,info ) { if (!(value)) { throw std::runtime_error (info); } }
40
40
static const char * kBsDiffVersionType =" BSDIFF40" ;
41
+ static const char * kEsBsDiffVersionType = " ENDSLEY/BSDIFF43" ;
41
42
42
43
namespace hdiff_private {
43
44
static inline void pushUInt64 (std::vector<unsigned char >& buf,hpatch_uint64_t v){
@@ -103,23 +104,115 @@ namespace hdiff_private{
103
104
}
104
105
};
105
106
107
+
108
+ struct TInterlaceStream :public hpatch_TStreamInput {
109
+ explicit TInterlaceStream (const TCovers& _covers,TCtrlStream& _ctrlStream,
110
+ TNewDataSubDiffStream& _subStream,TNewDataDiffStream& _diffStream)
111
+ :curPos(0 ),curi(0 ),covers(_covers),
112
+ curCtrlPos(0 ),curSubPos(0 ),curDiffPos(0 ),curCtrlLen(0 ),curSubLen(0 ),curDiffLen(0 ),
113
+ ctrlStream(_ctrlStream),subStream(_subStream),diffStream(_diffStream){
114
+ streamImport=this ;
115
+ read=_read;
116
+ streamSize=ctrlStream.streamSize +subStream.streamSize +diffStream.streamSize ;
117
+ }
118
+ private:
119
+ hpatch_StreamPos_t curPos;
120
+ size_t curi;
121
+ const TCovers& covers;
122
+ hpatch_StreamPos_t curCtrlPos;
123
+ hpatch_StreamPos_t curSubPos;
124
+ hpatch_StreamPos_t curDiffPos;
125
+ size_t curCtrlLen;
126
+ size_t curSubLen;
127
+ size_t curDiffLen;
128
+ TCtrlStream& ctrlStream;
129
+ TNewDataSubDiffStream& subStream;
130
+ TNewDataDiffStream& diffStream;
131
+ void _update (){
132
+ if (curi+1 <covers.coverCount ()){
133
+ TCover c,cnext;
134
+ covers.covers (curi++,&c);
135
+ covers.covers (curi,&cnext);
136
+ curCtrlLen=3 *8 ;
137
+ curDiffLen=cnext.newPos -(c.newPos +c.length );
138
+ curSubLen=c.length ;
139
+ }
140
+ }
141
+ hpatch_BOOL readTo (hpatch_StreamPos_t readFromPos,unsigned char * out_data,unsigned char * out_data_end){
142
+ if (readFromPos!=curPos)
143
+ return hpatch_FALSE;
144
+ size_t readLen=out_data_end-out_data;
145
+ curPos+=readLen;
146
+ while (readLen>0 ){
147
+ if (curCtrlLen+curSubLen+curDiffLen==0 ){
148
+ _update ();
149
+ _check (curCtrlLen+curSubLen+curDiffLen>0 ," TInterlaceStream _update" );
150
+ }
151
+
152
+ hpatch_StreamPos_t* dataPos;
153
+ size_t * dataLen;
154
+ hpatch_TStreamInput* dataStream;
155
+ if (curCtrlLen>0 ){
156
+ dataPos=&curCtrlPos;
157
+ dataLen=&curCtrlLen;
158
+ dataStream=&ctrlStream;
159
+ }else if (curSubLen>0 ){
160
+ dataPos=&curSubPos;
161
+ dataLen=&curSubLen;
162
+ dataStream=&subStream;
163
+ }else {
164
+ assert (curDiffLen>0 );
165
+ dataPos=&curDiffPos;
166
+ dataLen=&curDiffLen;
167
+ dataStream=&diffStream;
168
+ }
169
+
170
+ size_t cLen=(*dataLen);
171
+ if (cLen>readLen) cLen=readLen;
172
+ _check (dataStream->read (dataStream,*dataPos,out_data,out_data+cLen)," TInterlaceStream dataStream->read" )
173
+ out_data+=cLen;
174
+ readLen-=cLen;
175
+ (*dataPos)+=cLen;
176
+ (*dataLen)-=cLen;
177
+ }
178
+ return hpatch_TRUE;
179
+ }
180
+ static hpatch_BOOL _read (const hpatch_TStreamInput* stream,hpatch_StreamPos_t readFromPos,
181
+ unsigned char * out_data,unsigned char * out_data_end){
182
+ TInterlaceStream* self=(TInterlaceStream*)stream->streamImport ;
183
+ return self->readTo (readFromPos,out_data,out_data_end);
184
+ }
185
+ };
186
+
106
187
static void serialize_bsdiff (const hpatch_TStreamInput* newData,const hpatch_TStreamInput* oldData,
107
188
const TCovers& covers,const hpatch_TStreamOutput* out_diff,
108
- const hdiff_TCompress* compressPlugin,bool isZeroSubDiff=false ){
189
+ const hdiff_TCompress* compressPlugin,bool isEndsleyBsdiff, bool isZeroSubDiff=false ){
109
190
std::vector<unsigned char > buf;
110
191
TDiffStream outDiff (out_diff);
111
192
size_t ctrlDataSize_pos;
112
- size_t subDataSize_pos;
113
193
{// head
114
194
buf.clear ();
115
- pushCStr (buf,kBsDiffVersionType );
195
+ pushCStr (buf,isEndsleyBsdiff? kEsBsDiffVersionType : kBsDiffVersionType );
116
196
ctrlDataSize_pos=buf.size ();
117
- pushUInt64 (buf,0 ); // ctrlDataSize
118
- subDataSize_pos=buf.size ();
119
- pushUInt64 (buf,0 ); // subDataSize
197
+ if (!isEndsleyBsdiff){
198
+ pushUInt64 (buf,0 ); // ctrlDataSize
199
+ pushUInt64 (buf,0 ); // subDataSize
200
+ }
120
201
pushUInt64 (buf,newData->streamSize );
121
202
outDiff.pushBack (buf.data (),buf.size ());
122
203
}
204
+
205
+ if (isEndsleyBsdiff){
206
+ // endsley/bsdiff
207
+ TCtrlStream ctrlStream (covers);
208
+ TNewDataSubDiffStream subStream (newData,oldData,covers,true ,isZeroSubDiff);
209
+ TNewDataDiffStream diffStream (covers,newData);
210
+
211
+ TInterlaceStream interlaceStream (covers,ctrlStream,subStream,diffStream);
212
+ outDiff.pushStream (&interlaceStream,compressPlugin,true );
213
+ return ;
214
+ }
215
+ // else bsdiff4
123
216
124
217
{// ctrl data
125
218
TCtrlStream ctrlStream (covers);
@@ -135,6 +228,7 @@ static void serialize_bsdiff(const hpatch_TStreamInput* newData,const hpatch_TSt
135
228
TNewDataSubDiffStream subStream (newData,oldData,covers,true ,isZeroSubDiff);
136
229
hpatch_StreamPos_t subDataSize=outDiff.pushStream (&subStream,compressPlugin,true );
137
230
231
+ size_t subDataSize_pos=ctrlDataSize_pos+8 ;
138
232
buf.clear ();
139
233
pushUInt64 (buf,subDataSize);// update subDataSize
140
234
_check (out_diff->write (out_diff,subDataSize_pos,buf.data (),
@@ -173,7 +267,7 @@ static void _to_bsdiff_covers(std::vector<_TCover>& covers,_TSize newSize){
173
267
void _create_bsdiff (const unsigned char * newData,const unsigned char * cur_newData_end,const unsigned char * newData_end,
174
268
const unsigned char * oldData,const unsigned char * cur_oldData_end,const unsigned char * oldData_end,
175
269
const hpatch_TStreamOutput* out_diff,const hdiff_TCompress* compressPlugin,
176
- int kMinSingleMatchScore ,bool isUseBigCacheMatch,
270
+ bool isEndsleyBsdiff, int kMinSingleMatchScore ,bool isUseBigCacheMatch,
177
271
ICoverLinesListener* coverLinesListener,size_t threadNum){
178
272
std::vector<hpatch_TCover_sz> covers;
179
273
get_match_covers_by_sstring (newData,cur_newData_end,oldData,cur_oldData_end,covers,
@@ -188,7 +282,7 @@ void _create_bsdiff(const unsigned char* newData,const unsigned char* cur_newDat
188
282
mem_as_hStreamInput (&newStream,newData,newData_end);
189
283
mem_as_hStreamInput (&oldStream,oldData,oldData_end);
190
284
191
- serialize_bsdiff (&newStream,&oldStream,_covers,out_diff,compressPlugin);
285
+ serialize_bsdiff (&newStream,&oldStream,_covers,out_diff,compressPlugin,isEndsleyBsdiff );
192
286
}
193
287
194
288
}// end namespace hdiff_private
@@ -198,15 +292,15 @@ using namespace hdiff_private;
198
292
void create_bsdiff (const unsigned char * newData,const unsigned char * newData_end,
199
293
const unsigned char * oldData,const unsigned char * oldData_end,
200
294
const hpatch_TStreamOutput* out_diff,const hdiff_TCompress* compressPlugin,
201
- int kMinSingleMatchScore ,bool isUseBigCacheMatch,
295
+ bool isEndsleyBsdiff, int kMinSingleMatchScore ,bool isUseBigCacheMatch,
202
296
ICoverLinesListener* coverLinesListener,size_t threadNum){
203
297
_create_bsdiff (newData,newData_end,newData_end,oldData,oldData_end,oldData_end,
204
- out_diff,compressPlugin,kMinSingleMatchScore ,isUseBigCacheMatch,
298
+ out_diff,compressPlugin,isEndsleyBsdiff, kMinSingleMatchScore ,isUseBigCacheMatch,
205
299
coverLinesListener,threadNum);
206
300
}
207
301
void create_bsdiff (const hpatch_TStreamInput* newData,const hpatch_TStreamInput* oldData,
208
302
const hpatch_TStreamOutput* out_diff,const hdiff_TCompress* compressPlugin,
209
- int kMinSingleMatchScore ,bool isUseBigCacheMatch,
303
+ bool isEndsleyBsdiff, int kMinSingleMatchScore ,bool isUseBigCacheMatch,
210
304
ICoverLinesListener* coverLinesListener,size_t threadNum){
211
305
TAutoMem oldAndNewData;
212
306
loadOldAndNewStream (oldAndNewData,oldData,newData);
@@ -215,50 +309,50 @@ void create_bsdiff(const hpatch_TStreamInput* newData,const hpatch_TStreamInput*
215
309
unsigned char * pNewData=pOldData+old_size;
216
310
unsigned char * pNewDataEnd=pNewData+(size_t )newData->streamSize ;
217
311
_create_bsdiff (pNewData,pNewDataEnd,pNewDataEnd,pOldData,pOldData+old_size,pOldData+old_size,
218
- out_diff,compressPlugin,kMinSingleMatchScore ,isUseBigCacheMatch,
312
+ out_diff,compressPlugin,isEndsleyBsdiff, kMinSingleMatchScore ,isUseBigCacheMatch,
219
313
coverLinesListener,threadNum);
220
314
}
221
315
222
316
void create_bsdiff_stream (const hpatch_TStreamInput* newData,const hpatch_TStreamInput* oldData,
223
317
const hpatch_TStreamOutput* out_diff,const hdiff_TCompress* compressPlugin,
224
- size_t kMatchBlockSize ,const hdiff_TMTSets_s* mtsets){
318
+ bool isEndsleyBsdiff, size_t kMatchBlockSize ,const hdiff_TMTSets_s* mtsets){
225
319
TCoversBuf covers (newData->streamSize ,oldData->streamSize );
226
320
get_match_covers_by_block (newData,oldData,&covers,kMatchBlockSize ,mtsets);
227
321
if (covers._isCover32 )
228
322
_to_bsdiff_covers (covers.m_covers_limit ,(hpatch_uint32_t )newData->streamSize );
229
323
else
230
324
_to_bsdiff_covers (covers.m_covers_larger ,newData->streamSize );
231
325
covers.update ();
232
- serialize_bsdiff (newData,oldData,covers,out_diff,compressPlugin,true );
326
+ serialize_bsdiff (newData,oldData,covers,out_diff,compressPlugin,isEndsleyBsdiff, true );
233
327
}
234
328
235
329
236
330
void create_bsdiff_block (unsigned char * newData,unsigned char * newData_end,
237
331
unsigned char * oldData,unsigned char * oldData_end,
238
332
const hpatch_TStreamOutput* out_diff,const hdiff_TCompress* compressPlugin,
239
- int kMinSingleMatchScore ,bool isUseBigCacheMatch,
333
+ bool isEndsleyBsdiff, int kMinSingleMatchScore ,bool isUseBigCacheMatch,
240
334
size_t matchBlockSize,size_t threadNum){
241
335
if (matchBlockSize==0 ){
242
336
_create_bsdiff (newData,newData_end,newData_end,oldData,oldData_end,oldData_end,
243
- out_diff,compressPlugin,kMinSingleMatchScore ,isUseBigCacheMatch,0 ,threadNum);
337
+ out_diff,compressPlugin,isEndsleyBsdiff, kMinSingleMatchScore ,isUseBigCacheMatch,0 ,threadNum);
244
338
return ;
245
339
}
246
340
TCoversOptimMB<TMatchBlock> coversOp (newData,newData_end,oldData,oldData_end,matchBlockSize,threadNum);
247
341
_create_bsdiff (newData,coversOp.matchBlock ->newData_end_cur ,newData_end,
248
342
oldData,coversOp.matchBlock ->oldData_end_cur ,oldData_end,
249
- out_diff,compressPlugin,kMinSingleMatchScore ,isUseBigCacheMatch,&coversOp,threadNum);
343
+ out_diff,compressPlugin,isEndsleyBsdiff, kMinSingleMatchScore ,isUseBigCacheMatch,&coversOp,threadNum);
250
344
}
251
345
void create_bsdiff_block (const hpatch_TStreamInput* newData,const hpatch_TStreamInput* oldData,
252
346
const hpatch_TStreamOutput* out_diff,const hdiff_TCompress* compressPlugin,
253
- int kMinSingleMatchScore ,bool isUseBigCacheMatch,
347
+ bool isEndsleyBsdiff, int kMinSingleMatchScore ,bool isUseBigCacheMatch,
254
348
size_t matchBlockSize,size_t threadNum){
255
349
TAutoMem oldAndNewData;
256
350
loadOldAndNewStream (oldAndNewData,oldData,newData);
257
351
size_t old_size=oldData?(size_t )oldData->streamSize :0 ;
258
352
unsigned char * pOldData=oldAndNewData.data ();
259
353
unsigned char * pNewData=pOldData+old_size;
260
354
create_bsdiff_block (pNewData,pNewData+(size_t )newData->streamSize ,pOldData,pOldData+old_size,
261
- out_diff,compressPlugin,kMinSingleMatchScore ,isUseBigCacheMatch,
355
+ out_diff,compressPlugin,isEndsleyBsdiff, kMinSingleMatchScore ,isUseBigCacheMatch,
262
356
matchBlockSize,threadNum);
263
357
}
264
358
0 commit comments