mirror of
https://github.com/mii443/mozc.git
synced 2025-08-31 04:19:20 +00:00
Unify the implementation of ResizeSegment and ResizeSegments.
#codehealth PiperOrigin-RevId: 706354368
This commit is contained in:
@ -30,8 +30,10 @@
|
|||||||
#include "converter/converter.h"
|
#include "converter/converter.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <limits>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -441,90 +443,23 @@ bool Converter::ResizeSegment(Segments *segments,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
segment_index = GetSegmentIndex(segments, segment_index);
|
if (segment_index >= segments->conversion_segments_size()) {
|
||||||
if (segment_index == kErrorIndex) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// the last segments cannot become longer
|
absl::string_view key = segments->conversion_segment(segment_index).key();
|
||||||
if (offset_length > 0 && segment_index == segments->segments_size() - 1) {
|
if (key.empty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Segment &cur_segment = segments->segment(segment_index);
|
const int key_len = Util::CharsLen(key);
|
||||||
const size_t cur_length = Util::CharsLen(cur_segment.key());
|
const int new_size = key_len + offset_length;
|
||||||
|
if (new_size <= 0 || new_size > std::numeric_limits<uint8_t>::max()) {
|
||||||
// length cannot become 0
|
|
||||||
if (cur_length + offset_length == 0) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
const std::array<uint8_t, 1> new_size_array = {
|
||||||
const std::string cur_segment_key = cur_segment.key();
|
static_cast<uint8_t>(new_size)};
|
||||||
|
return ResizeSegments(segments, request, segment_index, new_size_array);
|
||||||
if (offset_length > 0) {
|
|
||||||
int length = offset_length;
|
|
||||||
std::string last_key;
|
|
||||||
size_t last_clen = 0;
|
|
||||||
{
|
|
||||||
std::string new_key = cur_segment_key;
|
|
||||||
while (segment_index + 1 < segments->segments_size()) {
|
|
||||||
last_key = segments->segment(segment_index + 1).key();
|
|
||||||
segments->erase_segment(segment_index + 1);
|
|
||||||
last_clen = Util::CharsLen(last_key);
|
|
||||||
length -= static_cast<int>(last_clen);
|
|
||||||
if (length <= 0) {
|
|
||||||
std::string tmp;
|
|
||||||
Util::Utf8SubString(last_key, 0, length + last_clen, &tmp);
|
|
||||||
new_key += tmp;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
new_key += last_key;
|
|
||||||
}
|
|
||||||
|
|
||||||
Segment *segment = segments->mutable_segment(segment_index);
|
|
||||||
segment->Clear();
|
|
||||||
segment->set_segment_type(Segment::FIXED_BOUNDARY);
|
|
||||||
segment->set_key(std::move(new_key));
|
|
||||||
} // scope out |segment|, |new_key|
|
|
||||||
|
|
||||||
if (length < 0) { // remaining part
|
|
||||||
Segment *segment = segments->insert_segment(segment_index + 1);
|
|
||||||
segment->set_segment_type(Segment::FREE);
|
|
||||||
segment->set_key(
|
|
||||||
Util::Utf8SubString(last_key, static_cast<size_t>(length + last_clen),
|
|
||||||
static_cast<size_t>(-length)));
|
|
||||||
}
|
|
||||||
} else if (offset_length < 0) {
|
|
||||||
if (cur_length + offset_length > 0) {
|
|
||||||
Segment *segment1 = segments->mutable_segment(segment_index);
|
|
||||||
segment1->Clear();
|
|
||||||
segment1->set_segment_type(Segment::FIXED_BOUNDARY);
|
|
||||||
segment1->set_key(
|
|
||||||
Util::Utf8SubString(cur_segment_key, 0, cur_length + offset_length));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (segment_index + 1 < segments->segments_size()) {
|
|
||||||
Segment *segment2 = segments->mutable_segment(segment_index + 1);
|
|
||||||
segment2->set_segment_type(Segment::FREE);
|
|
||||||
std::string tmp;
|
|
||||||
Util::Utf8SubString(cur_segment_key,
|
|
||||||
std::max<size_t>(0, cur_length + offset_length),
|
|
||||||
cur_length, &tmp);
|
|
||||||
tmp += segment2->key();
|
|
||||||
segment2->set_key(std::move(tmp));
|
|
||||||
} else {
|
|
||||||
Segment *segment2 = segments->add_segment();
|
|
||||||
segment2->set_segment_type(Segment::FREE);
|
|
||||||
segment2->set_key(Util::Utf8SubString(
|
|
||||||
cur_segment_key, std::max<size_t>(0, cur_length + offset_length),
|
|
||||||
cur_length));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
segments->set_resized(true);
|
|
||||||
|
|
||||||
ApplyConversion(segments, request);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Converter::ResizeSegments(Segments *segments,
|
bool Converter::ResizeSegments(Segments *segments,
|
||||||
@ -547,21 +482,23 @@ bool Converter::ResizeSegments(Segments *segments,
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string key;
|
std::string key;
|
||||||
|
size_t key_len = 0;
|
||||||
size_t segments_size = 0;
|
size_t segments_size = 0;
|
||||||
for (const Segment &segment : segments->all().drop(start_segment_index)) {
|
for (const Segment &segment : segments->all().drop(start_segment_index)) {
|
||||||
absl::StrAppend(&key, segment.key());
|
absl::StrAppend(&key, segment.key());
|
||||||
|
key_len += Util::CharsLen(segment.key());
|
||||||
++segments_size;
|
++segments_size;
|
||||||
if (Util::CharsLen(key) >= total_size) {
|
if (key_len >= total_size) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key.empty()) {
|
// If key is empty or less than the total size of new segments, return false.
|
||||||
|
if (key_len == 0 || key_len < total_size) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t consumed = 0;
|
size_t consumed = 0;
|
||||||
const size_t key_len = Util::CharsLen(key);
|
|
||||||
std::vector<std::string> new_keys;
|
std::vector<std::string> new_keys;
|
||||||
new_keys.reserve(new_size_array.size());
|
new_keys.reserve(new_size_array.size());
|
||||||
|
|
||||||
@ -580,12 +517,20 @@ bool Converter::ResizeSegments(Segments *segments,
|
|||||||
seg->set_key(std::move(new_keys[i]));
|
seg->set_key(std::move(new_keys[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there is a remaining key, create a segment as a FREE type.
|
// If there is a remaining key, replace the next segment with the new key
|
||||||
|
// prepending the remaining key to the next segment as a FREE type.
|
||||||
if (consumed < key_len) {
|
if (consumed < key_len) {
|
||||||
Segment *seg =
|
std::string next_segment_key(
|
||||||
segments->insert_segment(start_segment_index + new_keys.size());
|
Util::Utf8SubString(key, consumed, key_len - consumed));
|
||||||
|
const size_t next_segment_index = start_segment_index + new_keys.size();
|
||||||
|
if (next_segment_index < segments->segments_size()) {
|
||||||
|
absl::StrAppend(&next_segment_key,
|
||||||
|
segments->segment(next_segment_index).key());
|
||||||
|
segments->erase_segment(next_segment_index);
|
||||||
|
}
|
||||||
|
Segment *seg = segments->insert_segment(next_segment_index);
|
||||||
seg->set_segment_type(Segment::FREE);
|
seg->set_segment_type(Segment::FREE);
|
||||||
seg->set_key(Util::Utf8SubString(key, consumed, key_len - consumed));
|
seg->set_key(next_segment_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
segments->set_resized(true);
|
segments->set_resized(true);
|
||||||
|
Reference in New Issue
Block a user