|
34 | 34 | import com.igormaznitsa.jbbp.model.JBBPAbstractField;
|
35 | 35 | import com.igormaznitsa.jbbp.model.JBBPFieldArrayByte;
|
36 | 36 | import com.igormaznitsa.jbbp.model.JBBPFieldArrayLong;
|
| 37 | +import com.igormaznitsa.jbbp.model.JBBPFieldArrayString; |
37 | 38 | import com.igormaznitsa.jbbp.model.JBBPFieldInt;
|
38 | 39 | import com.igormaznitsa.jbbp.model.JBBPFieldLong;
|
39 | 40 | import com.igormaznitsa.jbbp.model.JBBPFieldString;
|
|
44 | 45 | import java.io.EOFException;
|
45 | 46 | import java.io.IOException;
|
46 | 47 | import java.io.InputStream;
|
| 48 | +import java.nio.charset.StandardCharsets; |
47 | 49 | import java.util.ArrayList;
|
48 | 50 | import java.util.Iterator;
|
49 | 51 | import java.util.List;
|
@@ -252,6 +254,80 @@ public void testStringMsb0() throws Exception {
|
252 | 254 | assertEquals(12345, bitflds.findFieldForNameAndType("i", JBBPFieldInt.class).getAsInt());
|
253 | 255 | }
|
254 | 256 |
|
| 257 | + /** |
| 258 | + * Case 18-feb-2020, #27 Strings in other codecs |
| 259 | + * Example how to implement custom ASCII string format |
| 260 | + * |
| 261 | + * @throws Exception for any error |
| 262 | + */ |
| 263 | + @Test |
| 264 | + public void testAscIIPascalString() throws Exception { |
| 265 | + final class AscIIPascalString implements JBBPCustomFieldTypeProcessor { |
| 266 | + private final String[] TYPES = new String[] {"asciistr"}; |
| 267 | + |
| 268 | + @Override |
| 269 | + public String[] getCustomFieldTypes() { |
| 270 | + return TYPES; |
| 271 | + } |
| 272 | + |
| 273 | + @Override |
| 274 | + public boolean isAllowed( |
| 275 | + final JBBPFieldTypeParameterContainer fieldType, |
| 276 | + final String fieldName, |
| 277 | + final int extraData, |
| 278 | + final boolean isArray |
| 279 | + ) { |
| 280 | + return extraData == 0; |
| 281 | + } |
| 282 | + |
| 283 | + @Override |
| 284 | + public JBBPAbstractField readCustomFieldType( |
| 285 | + final JBBPBitInputStream in, |
| 286 | + final JBBPBitOrder bitOrder, |
| 287 | + final int parserFlags, |
| 288 | + final JBBPFieldTypeParameterContainer customTypeFieldInfo, |
| 289 | + final JBBPNamedFieldInfo fieldName, |
| 290 | + final int extraData, |
| 291 | + final boolean readWholeStream, |
| 292 | + final int arrayLength |
| 293 | + ) throws IOException { |
| 294 | + if (arrayLength < 0) { |
| 295 | + return new JBBPFieldString(fieldName, readPascalAscIIString(in)); |
| 296 | + } else { |
| 297 | + final String[] loadedStrings; |
| 298 | + if (readWholeStream) { |
| 299 | + final List<String> strings = new ArrayList<>(); |
| 300 | + while (in.hasAvailableData()) { |
| 301 | + strings.add(readPascalAscIIString(in)); |
| 302 | + } |
| 303 | + loadedStrings = strings.toArray(new String[0]); |
| 304 | + } else { |
| 305 | + loadedStrings = new String[arrayLength]; |
| 306 | + for (int i = 0; i < arrayLength; i++) { |
| 307 | + loadedStrings[i] = readPascalAscIIString(in); |
| 308 | + } |
| 309 | + } |
| 310 | + return new JBBPFieldArrayString(fieldName, loadedStrings); |
| 311 | + } |
| 312 | + } |
| 313 | + |
| 314 | + private String readPascalAscIIString(final JBBPBitInputStream in) throws IOException { |
| 315 | + final byte[] charArray = in.readByteArray(in.readByte()); |
| 316 | + return new String(charArray, StandardCharsets.US_ASCII); |
| 317 | + } |
| 318 | + } |
| 319 | + |
| 320 | + final JBBPParser parserSingle = JBBPParser.prepare("asciistr str1; asciistr str2;", new AscIIPascalString()); |
| 321 | + final JBBPFieldStruct parsedSingle = parserSingle.parse(new byte[] {5, 65, 66, 67, 68, 69, 0}); |
| 322 | + assertEquals("ABCDE", parsedSingle.findFieldForNameAndType("str1", JBBPFieldString.class).getAsString()); |
| 323 | + assertEquals("", parsedSingle.findFieldForNameAndType("str2", JBBPFieldString.class).getAsString()); |
| 324 | + |
| 325 | + final JBBPParser parserArray = JBBPParser.prepare("asciistr [2] str1; asciistr [_] str2;", new AscIIPascalString()); |
| 326 | + final JBBPFieldStruct parsedArrays = parserArray.parse(new byte[] {2, 65, 66, 1, 67, 3, 68, 69, 70, 2, 71, 72, 1, 73}); |
| 327 | + assertArrayEquals(new String[] {"AB", "C"}, parsedArrays.findFieldForNameAndType("str1", JBBPFieldArrayString.class).getArray()); |
| 328 | + assertArrayEquals(new String[] {"DEF", "GH", "I"}, parsedArrays.findFieldForNameAndType("str2", JBBPFieldArrayString.class).getArray()); |
| 329 | + } |
| 330 | + |
255 | 331 | /**
|
256 | 332 | * Case 10-aug-2017
|
257 | 333 | * NullPointer exception when referencing a JBBPCustomFieldTypeProcessor parsed field.
|
|
0 commit comments