MCPcopy Create free account
hub / github.com/couchbase/fleece / createStringDelta

Method createStringDelta

Fleece/Core/JSONDelta.cc:430–488  ·  view source on GitHub ↗

static*/

Source from the content-addressed store, hash-verified

428
429
430 /*static*/ string JSONDelta::createStringDelta(slice oldStr, slice nuuStr) {
431 if (nuuStr.size < gMinStringDiffLength
432 || (gCompatibleDeltas && oldStr.size > gMinStringDiffLength))
433 return "";
434 diff_match_patch<string> dmp;
435 dmp.Diff_Timeout = gTextDiffTimeout;
436 auto patches = dmp.patch_make(string(oldStr), string(nuuStr));
437
438 if (gCompatibleDeltas)
439 return dmp.patch_toText(patches);
440
441 // Iterate over the diffs, writing the encoded form to the output stream:
442 stringstream diff;
443 long lastOldPos = 0, correction = 0;
444 for (auto patch = patches.begin(); patch != patches.end(); ++patch) {
445 long oldPos = patch->start1 + correction; // position in oldStr
446 long nuuPos = patch->start2; // position in nuuStr
447 auto &diffs = patch->diffs;
448 for (auto cur_diff = diffs.begin(); cur_diff != diffs.end(); ++cur_diff) {
449 auto length = cur_diff->text.length();
450 if (cur_diff->operation == diff_match_patch<string>::EQUAL) {
451 oldPos += narrow_cast<long>(length);
452 nuuPos += narrow_cast<long>(length);
453 } else {
454 // Don't break up a UTF-8 multibyte character:
455 if (cur_diff->operation == diff_match_patch<string>::DELETE)
456 snapToUTF8Character(oldPos, length, oldStr);
457 else
458 snapToUTF8Character(nuuPos, length, nuuStr);
459
460 assert(oldPos >= lastOldPos);
461 if (oldPos > lastOldPos) {
462 // Write the number of matching bytes since the last insert/delete:
463 diff << (oldPos-lastOldPos) << '=';
464 }
465 if (cur_diff->operation == diff_match_patch<string>::DELETE) {
466 // Write the number of deleted bytes:
467 diff << length << '-';
468 oldPos += narrow_cast<long>(length);
469 } else /* INSERT */ {
470 // Write an insertion, both the count and the bytes:
471 diff << length << '+';
472 diff.write((const char*)&nuuStr[nuuPos], length);
473 diff << '|';
474 nuuPos += narrow_cast<long>(length);
475 }
476 lastOldPos = oldPos;
477 }
478 if ((size_t)diff.tellp() + 6 >= nuuStr.size)
479 return ""; // Patch is too long; give up on using a diff
480 }
481 correction += patch->length1 - patch->length2;
482 }
483 if (oldStr.size > size_t(lastOldPos)) {
484 // Write a final matching-bytes count:
485 diff << (oldStr.size-lastOldPos) << '=';
486 }
487 return diff.str();

Callers

nothing calls this directly

Calls 7

snapToUTF8CharacterFunction · 0.85
patch_makeMethod · 0.80
patch_toTextMethod · 0.80
lengthMethod · 0.80
beginMethod · 0.45
endMethod · 0.45
writeMethod · 0.45

Tested by

no test coverage detected