| 481 | } |
| 482 | |
| 483 | EncodeResult Encode(const std::wstring& content, ErrorCorrectionLevel ecLevel, CharacterSet charset, int versionNumber, |
| 484 | bool useGs1Format, int maskPattern) |
| 485 | { |
| 486 | bool charsetWasUnknown = charset == CharacterSet::Unknown; |
| 487 | if (charsetWasUnknown) { |
| 488 | charset = DEFAULT_BYTE_MODE_ENCODING; |
| 489 | } |
| 490 | |
| 491 | // Pick an encoding mode appropriate for the content. Note that this will not attempt to use |
| 492 | // multiple modes / segments even if that were more efficient. Twould be nice. |
| 493 | CodecMode mode = ChooseMode(content, charset); |
| 494 | |
| 495 | // This will store the header information, like mode and |
| 496 | // length, as well as "header" segments like an ECI segment. |
| 497 | BitArray headerBits; |
| 498 | |
| 499 | // Append ECI segment if applicable |
| 500 | if (mode == CodecMode::BYTE && !charsetWasUnknown) { |
| 501 | AppendECI(charset, headerBits); |
| 502 | } |
| 503 | |
| 504 | // Append the FNC1 mode header for GS1 formatted data if applicable |
| 505 | if (useGs1Format) { |
| 506 | // GS1 formatted codes are prefixed with a FNC1 in first position mode header |
| 507 | AppendModeInfo(CodecMode::FNC1_FIRST_POSITION, headerBits); |
| 508 | } |
| 509 | |
| 510 | // (With ECI in place,) Write the mode marker |
| 511 | AppendModeInfo(mode, headerBits); |
| 512 | |
| 513 | // Collect data within the main segment, separately, to count its size if needed. Don't add it to |
| 514 | // main payload yet. |
| 515 | BitArray dataBits; |
| 516 | AppendBytes(content, mode, charset, dataBits); |
| 517 | |
| 518 | const Version* version; |
| 519 | if (versionNumber > 0) { |
| 520 | version = Version::FromNumber(versionNumber); |
| 521 | if (version != nullptr) { |
| 522 | int bitsNeeded = CalculateBitsNeeded(mode, headerBits, dataBits, *version); |
| 523 | if (!WillFit(bitsNeeded, *version, ecLevel)) { |
| 524 | throw std::invalid_argument("Data too big for requested version"); |
| 525 | } |
| 526 | } |
| 527 | else { |
| 528 | version = &RecommendVersion(ecLevel, mode, headerBits, dataBits); |
| 529 | } |
| 530 | } |
| 531 | else { |
| 532 | version = &RecommendVersion(ecLevel, mode, headerBits, dataBits); |
| 533 | } |
| 534 | |
| 535 | BitArray headerAndDataBits; |
| 536 | headerAndDataBits.appendBitArray(headerBits); |
| 537 | // Find "length" of main segment and write it |
| 538 | int numLetters = mode == CodecMode::BYTE ? dataBits.sizeInBytes() : Size(content); |
| 539 | AppendLengthInfo(numLetters, *version, mode, headerAndDataBits); |
| 540 | // Put data together into the overall payload |
no test coverage detected