// Copyright 2013 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // Author: [email protected] (Dick Sites) // // #include "offsetmap.h" #include <string.h> // for strcmp #include <algorithm> // for min usingnamespacestd; namespace chrome_lang_id { namespace CLD2 { // Constructor, destructor OffsetMap::OffsetMap() { … } OffsetMap::~OffsetMap() { … } // Clear the map // After: // next_diff_sub_ is 0 // Windows are the a and a' ranges covered by diffs_[next_diff_sub_-1] // which is a fake range of width 0 mapping 0=>0 void OffsetMap::Clear() { … } static inline char OpPart(const char c) { … } static inline char LenPart(const char c) { … } // Reset to offset 0 void OffsetMap::Reset() { … } // Add to mapping from A to A', specifying how many next bytes are // identical in A and A' void OffsetMap::Copy(int bytes) { … } // Add to mapping from A to A', specifying how many next bytes are // inserted in A' while not advancing in A at all void OffsetMap::Insert(int bytes){ … } // Add to mapping from A to A', specifying how many next bytes are // deleted from A while not advancing in A' at all void OffsetMap::Delete(int bytes){ … } void OffsetMap::Flush() { … } // Add one more entry to copy one byte off the end, then flush void OffsetMap::FlushAll() { … } // Flush all if necessary void OffsetMap::MaybeFlushAll() { … } // Len may be 0, for example as the low piece of length=64 void OffsetMap::Emit(MapOp op, int len) { … } //----------------------------------------------------------------------------// // The guts of the 2013 design // // If there are three ranges a b c in diffs_, we can be in one of five // // states: LEFT of a, in ranges a b c, or RIGHT of c // // In each state, there are windows A[Alo..Ahi), A'[A'lo..A'hi) and diffs_ // // position next_diff_sub_ // // There also are mapping constants max_aoffset_ and max_aprimeoffset_ // // If LEFT, Alo=Ahi=0, A'lo=A'hi=0 and next_diff_sub_=0 // // If RIGHT, Alo=Ahi=max_aoffset_, A'lo=A'hi=max_aprimeoffset_ and // // next_diff_sub_=diffs_.size() // // Otherwise, at least one of A[) and A'[) is non-empty and the first bytes // // correspond to each other. If range i is active, next_diff_sub_ is at // // the first byte of range i+1. Because of the length-prefix operator, // // an individual range item in diffs_ may be multiple bytes // // In all cases aprimeoffset = aoffset + current_diff_ // // i.e. current_diff_ = aprimeoffset - aoffset // // // // In the degenerate case of diffs_.empty(), there are only two states // // LEFT and RIGHT and the mapping is the identity mapping. // // The initial state is LEFT. // // It is an error to move left into LEFT or right into RIGHT, but the code // // below is robust in these cases. // //----------------------------------------------------------------------------// void OffsetMap::SetLeft() { … } void OffsetMap::SetRight() { … } // Back up over previous range, 1..5 bytes // Return subscript at the beginning of that. Pins at 0 int OffsetMap::Backup(int sub) { … } // Parse next range, 1..5 bytes // Return subscript just off the end of that int OffsetMap::ParseNext(int sub, MapOp* op, int* length) { … } // Parse previous range, 1..5 bytes // Return current subscript int OffsetMap::ParsePrevious(int sub, MapOp* op, int* length) { … } // Move active window one range to the right // Return true if move was OK bool OffsetMap::MoveRight() { … } // Move active window one range to the left // Return true if move was OK bool OffsetMap::MoveLeft() { … } // Map an offset in A' to the corresponding offset in A int OffsetMap::MapBack(int aprimeoffset){ … } // Map an offset in A to the corresponding offset in A' int OffsetMap::MapForward(int aoffset){ … } // static bool OffsetMap::CopyInserts(OffsetMap* source, OffsetMap* dest) { … } // static bool OffsetMap::CopyDeletes(OffsetMap* source, OffsetMap* dest) { … } // static void OffsetMap::ComposeOffsetMap( OffsetMap* g, OffsetMap* f, OffsetMap* h) { … } // For testing only -- force a mapping void OffsetMap::StuffIt(const std::string& diffs, int max_aoffset, int max_aprimeoffset) { … } } // namespace CLD2 } // namespace chrome_lang_id