[공통] util → framework 유틸 (ACM-CM-002)
This commit is contained in:
parent
c64af2335a
commit
d194866b26
1 changed files with 60 additions and 96 deletions
|
|
@ -1,109 +1,73 @@
|
|||
/*
|
||||
* util_msg.c - 고정길이 전문 pack/unpack 유틸리티 (plain C)
|
||||
*/
|
||||
#include "acq_util.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
void msg_field_copy(char *out, const char *field, int len)
|
||||
{
|
||||
int end;
|
||||
#define MSG_HEADER_SIZE 4
|
||||
#define MSG_MAX_SIZE 4096
|
||||
|
||||
if (!out || !field || len < 0)
|
||||
return;
|
||||
typedef struct {
|
||||
char type[MSG_HEADER_SIZE + 1];
|
||||
int length;
|
||||
char* payload;
|
||||
} message_t;
|
||||
|
||||
/* 우측 공백 제거하여 널 종료 문자열 생성 */
|
||||
end = len;
|
||||
while (end > 0 && (field[end - 1] == ' ' || field[end - 1] == '\0'))
|
||||
end--;
|
||||
|
||||
memcpy(out, field, end);
|
||||
out[end] = '\0';
|
||||
}
|
||||
|
||||
void msg_field_set(char *field, const char *src, int len)
|
||||
{
|
||||
int slen, i;
|
||||
|
||||
if (!field || len < 0)
|
||||
return;
|
||||
|
||||
slen = src ? (int)strlen(src) : 0;
|
||||
if (slen > len)
|
||||
slen = len;
|
||||
|
||||
memcpy(field, src, slen);
|
||||
for (i = slen; i < len; i++) /* 우측 공백 패딩 */
|
||||
field[i] = ' ';
|
||||
}
|
||||
|
||||
void msg_field_set_num(char *field, const char *src, int len)
|
||||
{
|
||||
int slen, pad, i;
|
||||
|
||||
if (!field || len < 0)
|
||||
return;
|
||||
|
||||
slen = src ? (int)strlen(src) : 0;
|
||||
if (slen > len)
|
||||
slen = len;
|
||||
|
||||
pad = len - slen;
|
||||
for (i = 0; i < pad; i++) /* 좌측 zero 패딩 */
|
||||
field[i] = '0';
|
||||
if (src)
|
||||
memcpy(field + pad, src, slen);
|
||||
}
|
||||
|
||||
int msg_unpack(acq_msg_t *msg, const char *raw, int rawlen)
|
||||
{
|
||||
if (!msg || !raw)
|
||||
return -1;
|
||||
if (rawlen < MSG_ACQ_LEN)
|
||||
return -1;
|
||||
|
||||
/* 위치기반 레이아웃이 곧 구조체 메모리 배열과 동일 */
|
||||
memcpy(msg, raw, MSG_ACQ_LEN);
|
||||
int msg_create(const char* type, const void* data, int len, message_t* out) {
|
||||
if (!type || !out) return -1;
|
||||
strncpy(out->type, type, MSG_HEADER_SIZE);
|
||||
out->type[MSG_HEADER_SIZE] = '\0';
|
||||
out->length = len;
|
||||
out->payload = malloc(len);
|
||||
if (!out->payload && len > 0) return -1;
|
||||
if (data && len > 0) memcpy(out->payload, data, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int msg_pack(const acq_msg_t *msg, char *raw, int rawlen)
|
||||
{
|
||||
if (!msg || !raw)
|
||||
return -1;
|
||||
if (rawlen < MSG_ACQ_LEN)
|
||||
return -1;
|
||||
|
||||
memcpy(raw, msg, MSG_ACQ_LEN);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int field_blank(const char *field, int len)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < len; i++) {
|
||||
if (field[i] != ' ' && field[i] != '\0')
|
||||
return 0;
|
||||
int msg_encode(const message_t* msg, char* buf, size_t len) {
|
||||
if (!msg || !buf) return -1;
|
||||
int pos = 0;
|
||||
pos += snprintf(buf + pos, len - pos, "%s|%d|", msg->type, msg->length);
|
||||
if (msg->payload && msg->length > 0) {
|
||||
memcpy(buf + pos, msg->payload, msg->length);
|
||||
pos += msg->length;
|
||||
}
|
||||
return 1;
|
||||
return pos;
|
||||
}
|
||||
|
||||
int msg_validate(const acq_msg_t *msg)
|
||||
{
|
||||
if (!msg)
|
||||
return -1;
|
||||
|
||||
if (field_blank(msg->msg_type, FLD_MSG_TYPE_LEN))
|
||||
return -1;
|
||||
if (field_blank(msg->merch_id, FLD_MERCH_ID_LEN))
|
||||
return -1;
|
||||
if (field_blank(msg->card_no, FLD_CARD_NO_LEN))
|
||||
return -1;
|
||||
if (field_blank(msg->amount, FLD_AMOUNT_LEN))
|
||||
return -1;
|
||||
if (field_blank(msg->txn_date, FLD_TXN_DATE_LEN))
|
||||
return -1;
|
||||
|
||||
int msg_decode(const char* buf, size_t len, message_t* out) {
|
||||
if (!buf || !out) return -1;
|
||||
const char* pipe1 = strchr(buf, '|');
|
||||
if (!pipe1) return -1;
|
||||
size_t type_len = pipe1 - buf;
|
||||
if (type_len > MSG_HEADER_SIZE) type_len = MSG_HEADER_SIZE;
|
||||
strncpy(out->type, buf, type_len);
|
||||
out->type[type_len] = '\0';
|
||||
const char* pipe2 = strchr(pipe1 + 1, '|');
|
||||
if (!pipe2) return -1;
|
||||
sscanf(pipe1 + 1, "%d", &out->length);
|
||||
const char* payload_start = pipe2 + 1;
|
||||
size_t payload_len = len - (payload_start - buf);
|
||||
if (payload_len > 0 && payload_len <= MSG_MAX_SIZE) {
|
||||
out->payload = malloc(payload_len);
|
||||
if (!out->payload) return -1;
|
||||
memcpy(out->payload, payload_start, payload_len);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void msg_free(message_t* msg) {
|
||||
if (msg) {
|
||||
free(msg->payload);
|
||||
msg->payload = NULL;
|
||||
msg->length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int msg_checksum(const message_t* msg) {
|
||||
if (!msg) return 0;
|
||||
int sum = 0;
|
||||
for (int i = 0; i < msg->length; i++) {
|
||||
sum += (unsigned char)msg->payload[i];
|
||||
}
|
||||
return sum & 0xFFFF;
|
||||
}
|
||||
|
|
|
|||
Reference in a new issue