// Path: cip-core/src/main/java/com/digitalpetri/enip/cip/epath/EPath.java
// public abstract class EPath {
// 
//     private final EPathSegment[] segments;
// 
//     protected EPath(EPathSegment[] segments) {
//         this.segments = segments;
//     }
// 
//     public EPathSegment[] getSegments() {
//         return segments;
//     }
// 
//     public abstract boolean isPadded();
// 
//     public static ByteBuf encode(EPath path, ByteBuf buffer) {
//         // length placeholder...
//         int lengthStartIndex = buffer.writerIndex();
//         buffer.writeByte(0);
// 
//         // encode the path segments...
//         int dataStartIndex = buffer.writerIndex();
// 
//         for (EPathSegment segment : path.getSegments()) {
//             if (segment instanceof LogicalSegment) {
//                 LogicalSegment.encode((LogicalSegment) segment, path.isPadded(), buffer);
//             } else if (segment instanceof PortSegment) {
//                 PortSegment.encode((PortSegment) segment, path.isPadded(), buffer);
//             } else if (segment instanceof DataSegment) {
//                 DataSegment.encode((DataSegment) segment, path.isPadded(), buffer);
//             } else {
//                 throw new RuntimeException("no encoder for " + segment.getClass().getSimpleName());
//             }
//         }
// 
//         // go back and update the length
//         int bytesWritten = buffer.writerIndex() - dataStartIndex;
//         int wordsWritten = bytesWritten / 2;
//         buffer.markWriterIndex();
//         buffer.writerIndex(lengthStartIndex);
//         buffer.writeByte(wordsWritten);
//         buffer.resetWriterIndex();
// 
//         return buffer;
//     }
// 
//     public static final class PaddedEPath extends EPath {
// 
//         public PaddedEPath(List<EPathSegment> segments) {
//             this(segments.toArray(new EPathSegment[segments.size()]));
//         }
// 
//         public PaddedEPath(EPathSegment... segments) {
//             super(segments);
//         }
// 
//         @Override
//         public boolean isPadded() {
//             return true;
//         }
// 
//         public PaddedEPath append(PaddedEPath other) {
//             int aLen = getSegments().length;
//             int bLen = other.getSegments().length;
// 
//             EPathSegment[] newSegments = new EPathSegment[aLen + bLen];
// 
//             System.arraycopy(getSegments(), 0, newSegments, 0, aLen);
//             System.arraycopy(other.getSegments(), 0, newSegments, aLen, bLen);
// 
//             return new PaddedEPath(newSegments);
//         }
// 
//     }
// 
// }


import java.util.function.Consumer;
import com.digitalpetri.enip.cip.epath.EPath;
import io.netty.buffer.ByteBuf;
package com.digitalpetri.enip.cip.structs;



public class MessageRouterRequest {

    private final int serviceCode;
    private final EPath.PaddedEPath requestPath;
    private final Consumer<ByteBuf> dataEncoder;

    public MessageRouterRequest(int serviceCode, EPath.PaddedEPath requestPath, ByteBuf requestData) {
// Path: cip-core/src/main/java/com/digitalpetri/enip/cip/epath/EPath.java
// public abstract class EPath {
// 
//     private final EPathSegment[] segments;
// 
//     protected EPath(EPathSegment[] segments) {
//         this.segments = segments;
//     }
// 
//     public EPathSegment[] getSegments() {
//         return segments;
//     }
// 
//     public abstract boolean isPadded();
// 
//     public static ByteBuf encode(EPath path, ByteBuf buffer) {
//         // length placeholder...
//         int lengthStartIndex = buffer.writerIndex();
//         buffer.writeByte(0);
// 
//         // encode the path segments...
//         int dataStartIndex = buffer.writerIndex();
// 
//         for (EPathSegment segment : path.getSegments()) {
//             if (segment instanceof LogicalSegment) {
//                 LogicalSegment.encode((LogicalSegment) segment, path.isPadded(), buffer);
//             } else if (segment instanceof PortSegment) {
//                 PortSegment.encode((PortSegment) segment, path.isPadded(), buffer);
//             } else if (segment instanceof DataSegment) {
//                 DataSegment.encode((DataSegment) segment, path.isPadded(), buffer);
//             } else {
//                 throw new RuntimeException("no encoder for " + segment.getClass().getSimpleName());
//             }
//         }
// 
//         // go back and update the length
//         int bytesWritten = buffer.writerIndex() - dataStartIndex;
//         int wordsWritten = bytesWritten / 2;
//         buffer.markWriterIndex();
//         buffer.writerIndex(lengthStartIndex);
//         buffer.writeByte(wordsWritten);
//         buffer.resetWriterIndex();
// 
//         return buffer;
//     }
// 
//     public static final class PaddedEPath extends EPath {
// 
//         public PaddedEPath(List<EPathSegment> segments) {
//             this(segments.toArray(new EPathSegment[segments.size()]));
//         }
// 
//         public PaddedEPath(EPathSegment... segments) {
//             super(segments);
//         }
// 
//         @Override
//         public boolean isPadded() {
//             return true;
//         }
// 
//         public PaddedEPath append(PaddedEPath other) {
//             int aLen = getSegments().length;
//             int bLen = other.getSegments().length;
// 
//             EPathSegment[] newSegments = new EPathSegment[aLen + bLen];
// 
//             System.arraycopy(getSegments(), 0, newSegments, 0, aLen);
//             System.arraycopy(other.getSegments(), 0, newSegments, aLen, bLen);
// 
//             return new PaddedEPath(newSegments);
//         }
// 
//     }
// 
// }


// Path: cip-core/src/main/java/com/digitalpetri/enip/cip/structs/MessageRouterRequest.java
import java.util.function.Consumer;
import com.digitalpetri.enip.cip.epath.EPath;
import io.netty.buffer.ByteBuf;

package com.digitalpetri.enip.cip.structs;



public class MessageRouterRequest {

    private final int serviceCode;
    private final EPath.PaddedEPath requestPath;
    private final Consumer<ByteBuf> dataEncoder;

    public MessageRouterRequest(int serviceCode, EPath.PaddedEPath requestPath, ByteBuf requestData) {
        this.serviceCode = serviceCode;