[공통] util → framework 유틸 (ACM-CM-002)
This commit is contained in:
parent
2757f6a51b
commit
f2cc439327
1 changed files with 145 additions and 0 deletions
|
|
@ -0,0 +1,145 @@
|
||||||
|
package com.klaro.acquirecore.framework.util;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Base64;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Static utility class for message/frame processing migrated from legacy C code.
|
||||||
|
* Provides encoding, decoding, and checksum operations for message frames.
|
||||||
|
*/
|
||||||
|
public final class MessageUtil {
|
||||||
|
|
||||||
|
private static final int HEADER_SIZE = 4;
|
||||||
|
private static final int MAX_MESSAGE_SIZE = 4096;
|
||||||
|
private static final String DELIMITER = "|";
|
||||||
|
|
||||||
|
private MessageUtil() {
|
||||||
|
// Utility class - prevent instantiation
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String encode(String type, byte[] payload) {
|
||||||
|
if (type == null || type.isBlank()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
int length = (payload != null) ? payload.length : 0;
|
||||||
|
String header = String.format("%s%s%d%s", padRight(type, HEADER_SIZE), DELIMITER, length, DELIMITER);
|
||||||
|
if (payload == null || payload.length == 0) {
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
return header + new String(payload, StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String encode(String type, String payload) {
|
||||||
|
if (payload == null) {
|
||||||
|
return encode(type, (byte[]) null);
|
||||||
|
}
|
||||||
|
return encode(type, payload.getBytes(StandardCharsets.UTF_8));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MessageFrame decode(String message) {
|
||||||
|
if (message == null || message.isBlank()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
int firstDelim = message.indexOf(DELIMITER);
|
||||||
|
if (firstDelim < 0 || firstDelim > HEADER_SIZE) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String type = message.substring(0, firstDelim).trim();
|
||||||
|
int secondDelim = message.indexOf(DELIMITER, firstDelim + 1);
|
||||||
|
if (secondDelim < 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String lengthStr = message.substring(firstDelim + 1, secondDelim).trim();
|
||||||
|
int length;
|
||||||
|
try {
|
||||||
|
length = Integer.parseInt(lengthStr);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String payloadStr = message.substring(secondDelim + 1);
|
||||||
|
byte[] payload = payloadStr.getBytes(StandardCharsets.UTF_8);
|
||||||
|
return new MessageFrame(type, length, payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int checksum(byte[] payload) {
|
||||||
|
if (payload == null || payload.length == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int sum = 0;
|
||||||
|
for (byte b : payload) {
|
||||||
|
sum += (b & 0xFF);
|
||||||
|
}
|
||||||
|
return sum & 0xFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int checksum(String payload) {
|
||||||
|
if (payload == null || payload.isEmpty()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return checksum(payload.getBytes(StandardCharsets.UTF_8));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String encodeBase64(byte[] data) {
|
||||||
|
if (data == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return Base64.getEncoder().encodeToString(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] decodeBase64(String encoded) {
|
||||||
|
if (encoded == null || encoded.isBlank()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return Base64.getDecoder().decode(encoded);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isValidSize(String message) {
|
||||||
|
return message != null && message.length() <= MAX_MESSAGE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String padRight(String str, int length) {
|
||||||
|
if (str == null) {
|
||||||
|
str = "";
|
||||||
|
}
|
||||||
|
if (str.length() >= length) {
|
||||||
|
return str.substring(0, length);
|
||||||
|
}
|
||||||
|
StringBuilder sb = new StringBuilder(str);
|
||||||
|
while (sb.length() < length) {
|
||||||
|
sb.append(' ');
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class MessageFrame {
|
||||||
|
private final String type;
|
||||||
|
private final int length;
|
||||||
|
private final byte[] payload;
|
||||||
|
|
||||||
|
public MessageFrame(String type, int length, byte[] payload) {
|
||||||
|
this.type = type;
|
||||||
|
this.length = length;
|
||||||
|
this.payload = payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType() { return type; }
|
||||||
|
public int getLength() { return length; }
|
||||||
|
public byte[] getPayload() { return payload; }
|
||||||
|
|
||||||
|
public String getPayloadAsString() {
|
||||||
|
if (payload == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return new String(payload, StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return String.format("MessageFrame{type='%s', length=%d, payload=%s}", type, length, getPayloadAsString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in a new issue