Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

why does VariableFieldPackager not get value form Map like FixedFieldPackager do in the pack method? #320

Open
Zhangkc opened this issue Jan 20, 2025 · 6 comments

Comments

@Zhangkc
Copy link

Zhangkc commented Jan 20, 2025

VariableFieldPackager returns delimiter if value is null.
FixedFieldPackager would get value from map if value is null.

public byte[] pack(Map<String, String> fields) throws ISOException {
		if (value == null || value.equals("")) {
			return new byte[] { delimiter.byteValue() };
		}



public byte[] pack(Map<String, String> fields) throws ISOException {
		if (value== null) {
			value = fields.get(getName());
		}
		else {
			fields.put(getName(), value);
		}

this causes packing empty value when VariableFieldPackager in a nested FSDMsgX.

@mchhil-incomm
Copy link

Could you provide a simple reproducer code ?
Its been ages since I looked at this module.

@mchhil-incomm
Copy link

I don't know if this related to your issue or not but I it was missing a setValue("") which cause the hexdump method to err out with a null pointer exception.

The idea is that when it eventually gets to a VariableFieldPackager the field can be set with string or null. If its an empty string or null the delimiter must be added to indicate the field is present with no data.

VariableFieldPackager ad the setValue

	public byte[] pack(Map<String, String> fields) throws ISOException {

		if (value == null || value.equals("")) {
			// if field is not set, make sure to send the delimiter to indicate
			// its presence.
                         setValue(""); // set this as the hexdump method chokes because field is not set
			return new byte[] { delimiter.byteValue() };
		}
		if (value.length() <= maxSize) {
			byte[] b = new byte[interpreter.getPackedLength(value.length() + 1)];
			interpreter.interpret(value, b, 0);
			b[b.length - 1] = delimiter.byteValue();

			return b;
		}
		throw new ISOException(String.format("Size [%d] is greater than maxSize[%d] ", value.length(), maxSize));
	}

Test

    public static void main(String[] args) throws ISOException {
        VariableFieldPackager f1  = new VariableFieldPackager("F1", 20, Byte.valueOf((byte) 0x1c),
                                                              AsciiInterpreter.INSTANCE);

        FSDMsgX               msg = new FSDMsgX("Test1");
        msg.add("F1", f1);

        byte[] arr = msg.pack();

        System.out.println(msg.getParserTree(""));
        System.out.println(msg.hexDump(""));

    }

Output

[Test1]
Field [F1] : VAR[0..20] delimiter[0x1C] or EOM  : 

0000  1C                                                .

If this is not your issue please provide a reproducer and I will try an look into it.

@Zhangkc
Copy link
Author

Zhangkc commented Jan 21, 2025

thanks for reply, here is reproducer demo.

            FSDMsgX demo = new FSDMsgX("demo");
            AFSDFieldPackager f1 = new FixedFieldPackager(
                    "F1", 1, AsciiInterpreter.INSTANCE);

            //branch
            FSDMsgX container = new FSDMsgX("n1");
            AFSDFieldPackager var = new VariableFieldPackager("var", 9, new Byte((byte) 0x1c),
                    AsciiInterpreter.INSTANCE);
            AFSDFieldPackager nf1 = new FixedFieldPackager(
                    "NF1", 1, AsciiInterpreter.INSTANCE);
            container.add(var);
            container.add(nf1);

            Map<String, AFSDFieldPackager> cases = new HashMap<String, AFSDFieldPackager>();
            cases.put("1", container);

            BranchFieldPackager branch1 = new BranchFieldPackager(
                    "branch", "F1", cases, null);

            demo.add(f1);
            demo.add(branch1);

            demo.set("F1", "1");
            demo.set("var", "111222333");
            demo.set("NF1", "N");

            byte[] os = demo.pack();
            System.out.println(demo.dump("dump"));
            System.out.println(demo.getParserTree("tree>"));
            System.out.println(ISOUtil.hexdump(os));

output

0000 31 1C 4E 1.N

field var packed empty value

@Zhangkc
Copy link
Author

Zhangkc commented Jan 21, 2025

I know I can set field value in branch FSDMsgX, but when nest more than 1 branch, it's hard to set value in branch FSDMsgX

@mchhil-incomm
Copy link

Thank you for the reproducer.

Can you test it with this pack method

    @Override
    public byte[] pack(Map<String, String> fields) throws ISOException {

        if (value == null || value.equals("")) {
            // if field is not set, make sure to send the delimiter to indicate
            // its presence.
            value = fields.get(getName());
            if (value == null || value.equals("")) {
                setValue(""); // set this as the hexdump method throws NPE
                return new byte[] { delimiter.byteValue() };
            }



        }

        if (value.length() <= maxSize) {
            byte[] b = new byte[interpreter.getPackedLength(value.length() + 1)];
            interpreter.interpret(value, b, 0);
            b[b.length - 1] = delimiter.byteValue();

            return b;
        }
        throw new ISOException(String.format("Size [%d] is greater than maxSize[%d] ", value.length(), maxSize));
    }

Test code

    public static void test2() throws ISOException {
        FSDMsgX demo = getMessage();
        demo.set("F1", "1");
        demo.set("var", "111222333");
        demo.set("NF1", "N");
        byte[] os = demo.pack();

        System.out.println(demo.dump("dump-pack"));
        System.out.println(demo.getParserTree("tree>"));
        System.out.println(ISOUtil.hexdump(os));

        demo = getMessage();
        demo.unpack(os);
        System.out.println(demo.dump("dump-unpack"));
        System.out.println(demo.getParserTree("tree>"));
        System.out.println(ISOUtil.hexdump(os));


    }

    protected static FSDMsgX getMessage() {
        FSDMsgX           demo = new FSDMsgX("demo");
        AFSDFieldPackager f1   = new FixedFieldPackager("F1", 1, AsciiInterpreter.INSTANCE);

        // branch
        FSDMsgX           container = new FSDMsgX("n1");
        AFSDFieldPackager var1      = new VariableFieldPackager("var", 9, Byte.valueOf((byte) 0x1c),
                                                                AsciiInterpreter.INSTANCE);
        AFSDFieldPackager nf1       = new FixedFieldPackager("NF1", 1, AsciiInterpreter.INSTANCE);
        container.add(var1);
        container.add(nf1);

        Map<String, AFSDFieldPackager> cases = new HashMap<>();
        cases.put("1", container);

        BranchFieldPackager branch1 = new BranchFieldPackager("branch", "F1", cases, null);

        demo.add(f1);
        demo.add(branch1);


        return demo;
    }

Output

dump-pack<fsdmsgX name="demo">
dump-pack	<field id="F1" value="1"/>
dump-pack	<fsdmsgX name="n1">
dump-pack		<field id="var" value="111222333"/>
dump-pack		<field id="NF1" value="N"/>
dump-pack	</fsdmsgX>
dump-pack</fsdmsgX>

tree>[demo]
tree>Field [F1] : Fixed [1] : 1
tree>Field [branch] : [Branch]
	switch (F1)
		1:
			[n1]
			Field [var] : VAR[0..9] delimiter[0x1C] or EOM  : 111222333
			Field [NF1] : Fixed [1] : N
		default:
			[Not Set]
0000  31 31 31 31 32 32 32 33  33 33 1C 4E              1111222333.N

dump-unpack<fsdmsgX name="demo">
dump-unpack	<field id="F1" value="1"/>
dump-unpack	<fsdmsgX name="n1">
dump-unpack		<field id="var" value="111222333"/>
dump-unpack		<field id="NF1" value="N"/>
dump-unpack	</fsdmsgX>
dump-unpack</fsdmsgX>

tree>[demo]
tree>Field [F1] : Fixed [1] : 1
tree>Field [branch] : [Branch]
	switch (F1)
		1:
			[n1]
			Field [var] : VAR[0..9] delimiter[0x1C] or EOM  : 111222333
			Field [NF1] : Fixed [1] : N
		default:
			[Not Set]
0000  31 31 31 31 32 32 32 33  33 33 1C 4E              1111222333.N

Currently the fsdmsgx.hexdump does not work, it needs to be fixed, but its usage is for debugging , I will try and get to it later. ISOUtil.hexdump works fine and can be used.

@Zhangkc
Copy link
Author

Zhangkc commented Jan 22, 2025

thanks a lot! I have tested and it seems ok!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants