mirror of https://github.com/apache/nifi.git
NIFI-10722 - Add handling of TBCD-STRING in nifi-asn1-services
This closes #6611 Signed-off-by: David Handermann <exceptionfactory@apache.org>
This commit is contained in:
parent
4083e07447
commit
56af75f5bd
|
@ -92,6 +92,7 @@
|
|||
<argument>${basedir}/src/test/resources/simple_types.asn</argument>
|
||||
<argument>${basedir}/src/test/resources/complex_types.asn</argument>
|
||||
<argument>${basedir}/src/test/resources/example.asn</argument>
|
||||
<argument>${basedir}/src/test/resources/tbcd_string.asn</argument>
|
||||
<argument>-o</argument>
|
||||
<argument>${basedir}/target/generated-test-sources</argument>
|
||||
</arguments>
|
||||
|
@ -128,8 +129,10 @@
|
|||
<exclude>src/test/resources/example.asn</exclude>
|
||||
<exclude>src/test/resources/simple_types.asn</exclude>
|
||||
<exclude>src/test/resources/complex_types.asn</exclude>
|
||||
<exclude>src/test/resources/tbcd_string.asn</exclude>
|
||||
<exclude>src/test/resources/examples/basic-types.dat</exclude>
|
||||
<exclude>src/test/resources/examples/composite.dat</exclude>
|
||||
<exclude>src/test/resources/examples/tbcd-string.dat</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
|
|
@ -29,6 +29,7 @@ import org.apache.nifi.jasn1.convert.converters.BerOctetStringConverter;
|
|||
import org.apache.nifi.jasn1.convert.converters.BerRealConverter;
|
||||
import org.apache.nifi.jasn1.convert.converters.BerRecordConverter;
|
||||
import org.apache.nifi.jasn1.convert.converters.BerStringConverter;
|
||||
import org.apache.nifi.jasn1.convert.converters.TbcdStringConverter;
|
||||
import org.apache.nifi.jasn1.convert.converters.BerTimeOfDayConverter;
|
||||
import org.apache.nifi.serialization.record.DataType;
|
||||
import org.apache.nifi.serialization.record.RecordSchema;
|
||||
|
@ -50,6 +51,7 @@ public class JASN1ConverterImpl implements JASN1Converter {
|
|||
new BerDateTimeConverter(),
|
||||
new BerRealConverter(),
|
||||
new BerStringConverter(),
|
||||
new TbcdStringConverter(),
|
||||
new BerOctetStringConverter(),
|
||||
new BerArrayConverter(),
|
||||
new BerRecordConverter(schemaProvider)
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.jasn1.convert.converters;
|
||||
|
||||
import com.beanit.asn1bean.ber.types.BerOctetString;
|
||||
import com.beanit.asn1bean.ber.types.BerType;
|
||||
import org.apache.nifi.jasn1.convert.JASN1Converter;
|
||||
import org.apache.nifi.jasn1.convert.JASN1TypeAndValueConverter;
|
||||
import org.apache.nifi.serialization.record.DataType;
|
||||
import org.apache.nifi.serialization.record.RecordFieldType;
|
||||
|
||||
public class TbcdStringConverter implements JASN1TypeAndValueConverter {
|
||||
|
||||
private static final String TBCD_STRING_TYPE = "TBCDSTRING";
|
||||
private static final char[] TBCD_SYMBOLS = "0123456789*#abc".toCharArray();
|
||||
private static final int FILLER_DECIMAL_CODE = 15;
|
||||
|
||||
@Override
|
||||
public boolean supportsType(Class<?> berType) {
|
||||
boolean supportsType = BerOctetString.class.isAssignableFrom(berType) && isTbcdString(berType);
|
||||
|
||||
return supportsType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType convertType(Class<?> berType, JASN1Converter converter) {
|
||||
DataType dataType = RecordFieldType.STRING.getDataType();
|
||||
|
||||
return dataType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsValue(BerType value, DataType dataType) {
|
||||
boolean supportsValue = value instanceof BerOctetString && isTbcdString(value.getClass());
|
||||
|
||||
return supportsValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convertValue(BerType value, DataType dataType, JASN1Converter converter) {
|
||||
final BerOctetString berValue = ((BerOctetString) value);
|
||||
|
||||
byte[] bytes = berValue.value;
|
||||
|
||||
int size = (bytes == null ? 0 : bytes.length);
|
||||
StringBuilder resultBuilder = new StringBuilder(2 * size);
|
||||
|
||||
for (int octetIndex = 0; octetIndex < size; ++octetIndex) {
|
||||
int octet = bytes[octetIndex];
|
||||
|
||||
int digit2 = (octet >> 4) & 0xF;
|
||||
int digit1 = octet & 0xF;
|
||||
|
||||
if (digit1 == FILLER_DECIMAL_CODE) {
|
||||
invalidFiller(octetIndex, octet);
|
||||
} else if (digit1 > 15) {
|
||||
invalidInteger(digit1);
|
||||
} else {
|
||||
resultBuilder.append(TBCD_SYMBOLS[digit1]);
|
||||
}
|
||||
|
||||
if (digit2 == FILLER_DECIMAL_CODE) {
|
||||
if (octetIndex != size - 1) {
|
||||
invalidFiller(octetIndex, octet);
|
||||
}
|
||||
} else if (digit2 > 15) {
|
||||
invalidInteger(digit2);
|
||||
} else {
|
||||
resultBuilder.append(TBCD_SYMBOLS[digit2]);
|
||||
}
|
||||
}
|
||||
|
||||
return resultBuilder.toString();
|
||||
}
|
||||
|
||||
private boolean isTbcdString(Class<?> berType) {
|
||||
Class<?> currentType = berType;
|
||||
while (currentType != null) {
|
||||
if (currentType.getSimpleName().equals(TBCD_STRING_TYPE)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
currentType = currentType.getSuperclass();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void invalidFiller(int octetIndex, int octet) {
|
||||
throw new NumberFormatException("Illegal filler in octet " + octetIndex + ": " + octet);
|
||||
}
|
||||
|
||||
private void invalidInteger(int digit) {
|
||||
throw new IllegalArgumentException(
|
||||
"Integer should be between 0 - 15 for Telephony Binary Coded Decimal String. Received " + digit);
|
||||
}
|
||||
}
|
|
@ -25,6 +25,8 @@ import com.beanit.asn1bean.ber.types.string.BerUTF8String;
|
|||
import org.apache.nifi.jasn1.example.BasicTypeSet;
|
||||
import org.apache.nifi.jasn1.example.BasicTypes;
|
||||
import org.apache.nifi.jasn1.example.Composite;
|
||||
import org.apache.nifi.jasn1.tbcd.TBCDSTRING;
|
||||
import org.apache.nifi.jasn1.tbcd.TbcdStringWrapper;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -52,6 +54,8 @@ public class ExampleDataGenerator {
|
|||
generateComposite(dir);
|
||||
|
||||
generateMultiRecord(dir);
|
||||
|
||||
generateTbcdString(dir);
|
||||
}
|
||||
|
||||
private static void generateBasicTypes(File dir) throws IOException {
|
||||
|
@ -143,4 +147,17 @@ public class ExampleDataGenerator {
|
|||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
private static void generateTbcdString(File dir) throws IOException {
|
||||
final File file = new File(dir, "tbcd-string.dat");
|
||||
try (final ReverseByteArrayOutputStream rev = new ReverseByteArrayOutputStream(1024);
|
||||
final OutputStream out = new FileOutputStream(file)) {
|
||||
final TbcdStringWrapper tbcdStringWrapper = new TbcdStringWrapper();
|
||||
tbcdStringWrapper.setTbcdString(new TBCDSTRING(new byte[]{1, 2, 3, 4, 5, 6, 7, 8}));
|
||||
tbcdStringWrapper.setOctetString(new BerOctetString(new byte[]{1, 2, 3, 4, 5, 6, 7, 8}));
|
||||
final int encoded = tbcdStringWrapper.encode(rev);
|
||||
out.write(rev.getArray(), 0, encoded);
|
||||
LOG.info("Generated {} bytes to {}", encoded, file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -153,4 +153,23 @@ public class TestJASN1RecordReader implements JASN1ReadRecordTester {
|
|||
assertNull(record3);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTbcdString() throws Exception {
|
||||
try (final InputStream input = TestJASN1RecordReader.class.getResourceAsStream("/examples/tbcd-string.dat")) {
|
||||
|
||||
final JASN1RecordReader reader = new JASN1RecordReader("org.apache.nifi.jasn1.tbcd.TbcdStringWrapper", null,
|
||||
new RecordSchemaProvider(), Thread.currentThread().getContextClassLoader(), null,
|
||||
input, new MockComponentLog("id", new JASN1Reader()));
|
||||
|
||||
final RecordSchema schema = reader.getSchema();
|
||||
assertEquals("TbcdStringWrapper", schema.getSchemaName().orElse(null));
|
||||
|
||||
Record record = reader.nextRecord(true, false);
|
||||
assertNotNull(record);
|
||||
|
||||
record = reader.nextRecord(true, false);
|
||||
assertNull(record);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
0<14><08>
|
|
@ -0,0 +1,22 @@
|
|||
ORG-APACHE-NIFI-JASN1-TBCD
|
||||
|
||||
DEFINITIONS IMPLICIT TAGS ::=
|
||||
|
||||
BEGIN
|
||||
|
||||
TbcdStringWrapper ::= SEQUENCE
|
||||
{
|
||||
tbcdString [0] TBCD-STRING,
|
||||
octetString [1] OCTET STRING (SIZE (4..255))
|
||||
}
|
||||
|
||||
TBCD-STRING ::= OCTET STRING
|
||||
-- This type (Telephony Binary Coded Decimal String) is used to
|
||||
-- represent several digits from 0 through 9, *, #, a, b , c, two
|
||||
-- digits per octet, each digit encoded 0000 to 1001 (0 to 9),
|
||||
-- 1010 (*), 1011 (#), 1100 (a), 1101 (b) or 1110 (c); 1111 used
|
||||
-- as filler when there is an odd number of digits.
|
||||
-- bits 8765 of octet n encoding digit 2n
|
||||
-- bits 4321 of octet n encoding digit 2(n-1) 1
|
||||
|
||||
END
|
Loading…
Reference in New Issue