package com.digitalpetri.enip.cip.epath;

import java.nio.charset.Charset;

import io.netty.buffer.ByteBuf;

public abstract class DataSegment<T> extends EPathSegment {

    public static final int SEGMENT_TYPE = 0x80;

    protected abstract ByteBuf encode(ByteBuf buffer);

    public static ByteBuf encode(DataSegment<?> segment, boolean padded, ByteBuf buffer) {
        return segment.encode(buffer);
    }

    public static final class AnsiDataSegment extends DataSegment<String> {

        public static final int SUBTYPE = 0x11;

        private static final Charset ASCII = Charset.forName("US-ASCII");

        private final String data;

        public AnsiDataSegment(String data) {
            this.data = data;
        }

        @Override
        protected ByteBuf encode(ByteBuf buffer) {
            String data = this.data.length() <= 255 ?
                this.data : this.data.substring(0, 255);

            buffer.writeByte(SEGMENT_TYPE | SUBTYPE);
            buffer.writeByte(data.length());
            buffer.writeBytes(data.getBytes(ASCII));
            if (data.length() % 2 != 0) buffer.writeByte(0);

            return buffer;
        }

    }

    public static final class SimpleDataSegment extends DataSegment<short[]> {

        private final short[] data;

        public SimpleDataSegment(short[] data) {
            this.data = data;
        }

        @Override
        protected ByteBuf encode(ByteBuf buffer) {
            buffer.writeByte(SEGMENT_TYPE);
            buffer.writeByte(data.length);

            for (short d : data) {
                buffer.writeShort(d);
            }

            return buffer;
        }

    }

}

@@ -67,16 +67,58 @@
 Charset;
+%0Aimport java.nio.charset.StandardCharsets;
 %0A%0Aimport
@@ -594,101 +594,173 @@
 ate 
-static final Charset ASCII = Charset.forName(%22US-ASCII%22);%0A%0A        private final String data;
+final String data;%0A        private final Charset charset;%0A%0A        public AnsiDataSegment(String data) %7B%0A            this(data, StandardCharsets.US_ASCII);%0A        %7D
 %0A%0A  
@@ -791,32 +791,49 @@
 ment(String data
+, Charset charset
 ) %7B%0A            
@@ -842,32 +842,68 @@
 is.data = data;%0A
+            this.charset = charset;%0A
         %7D%0A%0A     
@@ -982,99 +982,105 @@
     
-String data = this.data.length() %3C= 255 ?%0A                this.data : this.data.substring(0
+byte%5B%5D dataBytes = data.getBytes(charset);%0A            int dataLength = Math.min(dataBytes.length
 , 25
@@ -1171,25 +1171,22 @@
 yte(data
-.l
+L
 ength
-()
 );%0A     
@@ -1218,24 +1218,28 @@
 data
-.get
 Bytes
-(ASCII)
+, 0, dataLength
 );%0A 
@@ -1261,17 +1261,14 @@
 data
-.l
+L
 ength
-()
  %25 2

Allow Charset to be specified when constructing AnsiDataSegment (#55)