mirror of
https://github.com/Alukym/VMProtect-Source.git
synced 2025-06-11 06:57:58 -05:00
Initial commit
This commit is contained in:
202
third-party/scintilla/Partitioning.h
vendored
Normal file
202
third-party/scintilla/Partitioning.h
vendored
Normal file
@ -0,0 +1,202 @@
|
||||
// Scintilla source code edit control
|
||||
/** @file Partitioning.h
|
||||
** Data structure used to partition an interval. Used for holding line start/end positions.
|
||||
**/
|
||||
// Copyright 1998-2007 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#ifndef PARTITIONING_H
|
||||
#define PARTITIONING_H
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
namespace Scintilla {
|
||||
#endif
|
||||
|
||||
/// A split vector of integers with a method for adding a value to all elements
|
||||
/// in a range.
|
||||
/// Used by the Partitioning class.
|
||||
|
||||
class SplitVectorWithRangeAdd : public SplitVector<int> {
|
||||
public:
|
||||
explicit SplitVectorWithRangeAdd(int growSize_) {
|
||||
SetGrowSize(growSize_);
|
||||
ReAllocate(growSize_);
|
||||
}
|
||||
~SplitVectorWithRangeAdd() {
|
||||
}
|
||||
void RangeAddDelta(int start, int end, int delta) {
|
||||
// end is 1 past end, so end-start is number of elements to change
|
||||
int i = 0;
|
||||
int rangeLength = end - start;
|
||||
int range1Length = rangeLength;
|
||||
int part1Left = part1Length - start;
|
||||
if (range1Length > part1Left)
|
||||
range1Length = part1Left;
|
||||
while (i < range1Length) {
|
||||
body[start++] += delta;
|
||||
i++;
|
||||
}
|
||||
start += gapLength;
|
||||
while (i < rangeLength) {
|
||||
body[start++] += delta;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/// Divide an interval into multiple partitions.
|
||||
/// Useful for breaking a document down into sections such as lines.
|
||||
/// A 0 length interval has a single 0 length partition, numbered 0
|
||||
/// If interval not 0 length then each partition non-zero length
|
||||
/// When needed, positions after the interval are considered part of the last partition
|
||||
/// but the end of the last partition can be found with PositionFromPartition(last+1).
|
||||
|
||||
class Partitioning {
|
||||
private:
|
||||
// To avoid calculating all the partition positions whenever any text is inserted
|
||||
// there may be a step somewhere in the list.
|
||||
int stepPartition;
|
||||
int stepLength;
|
||||
SplitVectorWithRangeAdd *body;
|
||||
|
||||
// Move step forward
|
||||
void ApplyStep(int partitionUpTo) {
|
||||
if (stepLength != 0) {
|
||||
body->RangeAddDelta(stepPartition+1, partitionUpTo + 1, stepLength);
|
||||
}
|
||||
stepPartition = partitionUpTo;
|
||||
if (stepPartition >= body->Length()-1) {
|
||||
stepPartition = body->Length()-1;
|
||||
stepLength = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Move step backward
|
||||
void BackStep(int partitionDownTo) {
|
||||
if (stepLength != 0) {
|
||||
body->RangeAddDelta(partitionDownTo+1, stepPartition+1, -stepLength);
|
||||
}
|
||||
stepPartition = partitionDownTo;
|
||||
}
|
||||
|
||||
void Allocate(int growSize) {
|
||||
body = new SplitVectorWithRangeAdd(growSize);
|
||||
stepPartition = 0;
|
||||
stepLength = 0;
|
||||
body->Insert(0, 0); // This value stays 0 for ever
|
||||
body->Insert(1, 0); // This is the end of the first partition and will be the start of the second
|
||||
}
|
||||
|
||||
// no copy ctr or assignment op
|
||||
Partitioning(const Partitioning &);
|
||||
Partitioning &operator =(const Partitioning &);
|
||||
|
||||
public:
|
||||
explicit Partitioning(int growSize) {
|
||||
Allocate(growSize);
|
||||
}
|
||||
|
||||
~Partitioning() {
|
||||
delete body;
|
||||
body = 0;
|
||||
}
|
||||
|
||||
int Partitions() const {
|
||||
return body->Length()-1;
|
||||
}
|
||||
|
||||
void InsertPartition(int partition, int pos) {
|
||||
if (stepPartition < partition) {
|
||||
ApplyStep(partition);
|
||||
}
|
||||
body->Insert(partition, pos);
|
||||
stepPartition++;
|
||||
}
|
||||
|
||||
void SetPartitionStartPosition(int partition, int pos) {
|
||||
ApplyStep(partition+1);
|
||||
if ((partition < 0) || (partition > body->Length())) {
|
||||
return;
|
||||
}
|
||||
body->SetValueAt(partition, pos);
|
||||
}
|
||||
|
||||
void InsertText(int partitionInsert, int delta) {
|
||||
// Point all the partitions after the insertion point further along in the buffer
|
||||
if (stepLength != 0) {
|
||||
if (partitionInsert >= stepPartition) {
|
||||
// Fill in up to the new insertion point
|
||||
ApplyStep(partitionInsert);
|
||||
stepLength += delta;
|
||||
} else if (partitionInsert >= (stepPartition - body->Length() / 10)) {
|
||||
// Close to step but before so move step back
|
||||
BackStep(partitionInsert);
|
||||
stepLength += delta;
|
||||
} else {
|
||||
ApplyStep(body->Length()-1);
|
||||
stepPartition = partitionInsert;
|
||||
stepLength = delta;
|
||||
}
|
||||
} else {
|
||||
stepPartition = partitionInsert;
|
||||
stepLength = delta;
|
||||
}
|
||||
}
|
||||
|
||||
void RemovePartition(int partition) {
|
||||
if (partition > stepPartition) {
|
||||
ApplyStep(partition);
|
||||
stepPartition--;
|
||||
} else {
|
||||
stepPartition--;
|
||||
}
|
||||
body->Delete(partition);
|
||||
}
|
||||
|
||||
int PositionFromPartition(int partition) const {
|
||||
PLATFORM_ASSERT(partition >= 0);
|
||||
PLATFORM_ASSERT(partition < body->Length());
|
||||
if ((partition < 0) || (partition >= body->Length())) {
|
||||
return 0;
|
||||
}
|
||||
int pos = body->ValueAt(partition);
|
||||
if (partition > stepPartition)
|
||||
pos += stepLength;
|
||||
return pos;
|
||||
}
|
||||
|
||||
/// Return value in range [0 .. Partitions() - 1] even for arguments outside interval
|
||||
int PartitionFromPosition(int pos) const {
|
||||
if (body->Length() <= 1)
|
||||
return 0;
|
||||
if (pos >= (PositionFromPartition(body->Length()-1)))
|
||||
return body->Length() - 1 - 1;
|
||||
int lower = 0;
|
||||
int upper = body->Length()-1;
|
||||
do {
|
||||
int middle = (upper + lower + 1) / 2; // Round high
|
||||
int posMiddle = body->ValueAt(middle);
|
||||
if (middle > stepPartition)
|
||||
posMiddle += stepLength;
|
||||
if (pos < posMiddle) {
|
||||
upper = middle - 1;
|
||||
} else {
|
||||
lower = middle;
|
||||
}
|
||||
} while (lower < upper);
|
||||
return lower;
|
||||
}
|
||||
|
||||
void DeleteAll() {
|
||||
int growSize = body->GetGrowSize();
|
||||
delete body;
|
||||
Allocate(growSize);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user