1 // Copyright 2014 PDFium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 // Original code is licensed as follows: 7 /* 8 * Copyright 2006-2007 Jeremias Maerki. 9 * 10 * Licensed under the Apache License, Version 2.0 (the "License"); 11 * you may not use this file except in compliance with the License. 12 * You may obtain a copy of the License at 13 * 14 * http://www.apache.org/licenses/LICENSE-2.0 15 * 16 * Unless required by applicable law or agreed to in writing, software 17 * distributed under the License is distributed on an "AS IS" BASIS, 18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 * See the License for the specific language governing permissions and 20 * limitations under the License. 21 */ 22 23 #include "xfa/src/fxbarcode/barcode.h" 24 #include "xfa/src/fxbarcode/common/BC_CommonBitMatrix.h" 25 #include "xfa/src/fxbarcode/BC_Dimension.h" 26 #include "BC_Encoder.h" 27 #include "BC_SymbolShapeHint.h" 28 #include "BC_SymbolInfo.h" 29 #include "BC_EncoderContext.h" 30 #include "BC_HighLevelEncoder.h" 31 #include "BC_EdifactEncoder.h" 32 CBC_EdifactEncoder::CBC_EdifactEncoder() {} 33 CBC_EdifactEncoder::~CBC_EdifactEncoder() {} 34 int32_t CBC_EdifactEncoder::getEncodingMode() { 35 return EDIFACT_ENCODATION; 36 } 37 void CBC_EdifactEncoder::Encode(CBC_EncoderContext& context, int32_t& e) { 38 CFX_WideString buffer; 39 while (context.hasMoreCharacters()) { 40 FX_WCHAR c = context.getCurrentChar(); 41 encodeChar(c, buffer, e); 42 if (e != BCExceptionNO) { 43 return; 44 } 45 context.m_pos++; 46 int32_t count = buffer.GetLength(); 47 if (count >= 4) { 48 context.writeCodewords(encodeToCodewords(buffer, 0, e)); 49 if (e != BCExceptionNO) { 50 return; 51 } 52 buffer.Delete(0, 4); 53 int32_t newMode = CBC_HighLevelEncoder::lookAheadTest( 54 context.m_msg, context.m_pos, getEncodingMode()); 55 if (newMode != getEncodingMode()) { 56 context.signalEncoderChange(ASCII_ENCODATION); 57 break; 58 } 59 } 60 } 61 buffer += (FX_WCHAR)31; 62 handleEOD(context, buffer, e); 63 } 64 void CBC_EdifactEncoder::handleEOD(CBC_EncoderContext& context, 65 CFX_WideString buffer, 66 int32_t& e) { 67 int32_t count = buffer.GetLength(); 68 if (count == 0) { 69 return; 70 } 71 if (count == 1) { 72 context.updateSymbolInfo(e); 73 if (e != BCExceptionNO) { 74 return; 75 } 76 int32_t available = 77 context.m_symbolInfo->m_dataCapacity - context.getCodewordCount(); 78 int32_t remaining = context.getRemainingCharacters(); 79 if (remaining == 0 && available <= 2) { 80 return; 81 } 82 } 83 if (count > 4) { 84 e = BCExceptionIllegalStateCountMustNotExceed4; 85 return; 86 } 87 int32_t restChars = count - 1; 88 CFX_WideString encoded = encodeToCodewords(buffer, 0, e); 89 if (e != BCExceptionNO) { 90 return; 91 } 92 FX_BOOL endOfSymbolReached = !context.hasMoreCharacters(); 93 FX_BOOL restInAscii = endOfSymbolReached && restChars <= 2; 94 if (restChars <= 2) { 95 context.updateSymbolInfo(context.getCodewordCount() + restChars, e); 96 if (e != BCExceptionNO) { 97 return; 98 } 99 int32_t available = 100 context.m_symbolInfo->m_dataCapacity - context.getCodewordCount(); 101 if (available >= 3) { 102 restInAscii = FALSE; 103 context.updateSymbolInfo(context.getCodewordCount() + encoded.GetLength(), 104 e); 105 if (e != BCExceptionNO) { 106 return; 107 } 108 } 109 } 110 if (restInAscii) { 111 context.resetSymbolInfo(); 112 context.m_pos -= restChars; 113 } else { 114 context.writeCodewords(encoded); 115 } 116 context.signalEncoderChange(ASCII_ENCODATION); 117 } 118 void CBC_EdifactEncoder::encodeChar(FX_WCHAR c, 119 CFX_WideString& sb, 120 int32_t& e) { 121 if (c >= ' ' && c <= '?') { 122 sb += c; 123 } else if (c >= '@' && c <= '^') { 124 sb += (FX_WCHAR)(c - 64); 125 } else { 126 CBC_HighLevelEncoder::illegalCharacter(c, e); 127 } 128 } 129 CFX_WideString CBC_EdifactEncoder::encodeToCodewords(CFX_WideString sb, 130 int32_t startPos, 131 int32_t& e) { 132 int32_t len = sb.GetLength() - startPos; 133 if (len == 0) { 134 e = BCExceptionNoContents; 135 return (FX_WCHAR*)""; 136 } 137 FX_WCHAR c1 = sb.GetAt(startPos); 138 FX_WCHAR c2 = len >= 2 ? sb.GetAt(startPos + 1) : 0; 139 FX_WCHAR c3 = len >= 3 ? sb.GetAt(startPos + 2) : 0; 140 FX_WCHAR c4 = len >= 4 ? sb.GetAt(startPos + 3) : 0; 141 int32_t v = (c1 << 18) + (c2 << 12) + (c3 << 6) + c4; 142 FX_WCHAR cw1 = (FX_WCHAR)((v >> 16) & 255); 143 FX_WCHAR cw2 = (FX_WCHAR)((v >> 8) & 255); 144 FX_WCHAR cw3 = (FX_WCHAR)(v & 255); 145 CFX_WideString res; 146 res += cw1; 147 if (len >= 2) { 148 res += cw2; 149 } 150 if (len >= 3) { 151 res += cw3; 152 } 153 return res; 154 } 155