123 static constexpr size_t kMaxNumericInputLength = 3116;
126 if (msg.GetLength() > kMaxNumericInputLength)
133 if (msg.Back() == kMacroTrailer) {
135 if (left
== kMacro05Header) {
139 }
else if (left
== kMacro06Header) {
146 std::vector<std::unique_ptr<CBC_Encoder>> encoders;
147 encoders.push_back(
std::make_unique<CBC_ASCIIEncoder>());
149 encoders.push_back(
std::make_unique<CBC_TextEncoder>());
150 encoders.push_back(
std::make_unique<CBC_X12Encoder>());
151 encoders.push_back(
std::make_unique<CBC_EdifactEncoder>());
152 encoders.push_back(
std::make_unique<CBC_Base256Encoder>());
155 if (!encoders[EncoderIndex(encodingMode)]->Encode(&context))
163 size_t len = context.m_codewords.GetLength();
167 size_t capacity = context.m_symbolInfo->data_capacity();
168 if (len < capacity) {
173 if (codewords.GetLength() < capacity)
176 while (codewords.GetLength() < capacity)
177 codewords += Randomize253State(kPad, codewords.GetLength() + 1);
179 DCHECK(!codewords.IsEmpty());
188 if (startpos >= msg.GetLength())
191 std::array<
float, kEncoderCount> charCounts;
193 charCounts = {0, 1, 1, 1, 1, 1.25f};
195 charCounts = {1, 2, 2, 2, 2, 2.25f};
196 charCounts[EncoderIndex(currentMode)] = 0;
199 size_t charsProcessed = 0;
201 if ((startpos + charsProcessed) == msg.GetLength()) {
202 std::array<int32_t, kEncoderCount> intCharCounts;
203 std::array<uint8_t, kEncoderCount> mins;
204 int32_t min = FindMinimums(charCounts, &intCharCounts, &mins);
205 if (intCharCounts[EncoderIndex(Encoding::ASCII)] == min)
207 const int32_t minCount = GetMinimumCount(mins);
209 if (mins[EncoderIndex(Encoding::BASE256)] > 0)
211 if (mins[EncoderIndex(Encoding::EDIFACT)] > 0)
213 if (mins[EncoderIndex(Encoding::TEXT)] > 0)
215 if (mins[EncoderIndex(Encoding::X12)] > 0)
221 wchar_t c = msg[startpos + charsProcessed];
224 auto& count = charCounts[EncoderIndex(Encoding::ASCII)];
228 count = ceilf(count) + 2;
230 count = ceilf(count) + 1;
234 auto& count = charCounts[EncoderIndex(Encoding::C40)];
236 count += 2.0f / 3.0f;
238 count += 8.0f / 3.0f;
240 count += 4.0f / 3.0f;
244 auto& count = charCounts[EncoderIndex(Encoding::TEXT)];
246 count += 2.0f / 3.0f;
248 count += 8.0f / 3.0f;
250 count += 4.0f / 3.0f;
254 auto& count = charCounts[EncoderIndex(Encoding::X12)];
256 count += 2.0f / 3.0f;
258 count += 13.0f / 3.0f;
260 count += 10.0f / 3.0f;
264 auto& count = charCounts[EncoderIndex(Encoding::EDIFACT)];
265 if (IsNativeEDIFACT(c))
266 count += 3.0f / 4.0f;
268 count += 17.0f / 4.0f;
270 count += 13.0f / 4.0f;
273 charCounts[EncoderIndex(Encoding::BASE256)]++;
274 if (charsProcessed < 4)
277 std::array<int32_t, kEncoderCount> intCharCounts;
278 std::array<uint8_t, kEncoderCount> mins;
279 FindMinimums(charCounts, &intCharCounts, &mins);
280 int32_t minCount = GetMinimumCount(mins);
281 int32_t ascii_count = intCharCounts[EncoderIndex(Encoding::ASCII)];
282 int32_t c40_count = intCharCounts[EncoderIndex(Encoding::C40)];
283 int32_t text_count = intCharCounts[EncoderIndex(Encoding::TEXT)];
284 int32_t x12_count = intCharCounts[EncoderIndex(Encoding::X12)];
285 int32_t editfact_count = intCharCounts[EncoderIndex(Encoding::EDIFACT)];
286 int32_t base256_count = intCharCounts[EncoderIndex(Encoding::BASE256)];
287 int32_t bet_min =
std::min({base256_count, editfact_count, text_count});
288 if (ascii_count < bet_min && ascii_count < c40_count &&
289 ascii_count < x12_count) {
292 if (base256_count < ascii_count ||
293 (mins[EncoderIndex(Encoding::C40)] +
294 mins[EncoderIndex(Encoding::TEXT)] +
295 mins[EncoderIndex(Encoding::X12)] +
296 mins[EncoderIndex(Encoding::EDIFACT)]) == 0) {
300 if (mins[EncoderIndex(Encoding::EDIFACT)] > 0)
302 if (mins[EncoderIndex(Encoding::TEXT)] > 0)
304 if (mins[EncoderIndex(Encoding::X12)] > 0)
307 if (c40_count + 1 < ascii_count && c40_count + 1 < bet_min) {
308 if (c40_count < x12_count)
310 if (c40_count == x12_count) {
311 size_t p = startpos + charsProcessed + 1;
312 while (p < msg.GetLength()) {
314 if (IsX12TermSep(tc))
316 if (!IsNativeX12(tc))
void writeCodeword(wchar_t codeword)
CBC_HighLevelEncoder::Encoding m_newEncoding
void setSkipAtEnd(int32_t count)
bool HasCharactersOutsideISO88591Encoding() const
CBC_EncoderContext(const WideString &msg)