[공통] util → framework 유틸 (ACM-CM-002)
This commit is contained in:
parent
9b53fa043f
commit
582bef95fb
1 changed files with 78 additions and 98 deletions
|
|
@ -1,109 +1,89 @@
|
|||
/*
|
||||
* 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;
|
||||
typedef struct {
|
||||
char* data;
|
||||
int length;
|
||||
} Message;
|
||||
|
||||
if (!out || !field || len < 0)
|
||||
return;
|
||||
|
||||
/* 우측 공백 제거하여 널 종료 문자열 생성 */
|
||||
end = len;
|
||||
while (end > 0 && (field[end - 1] == ' ' || field[end - 1] == '\0'))
|
||||
end--;
|
||||
|
||||
memcpy(out, field, end);
|
||||
out[end] = '\0';
|
||||
Message* msg_create(const char* data, int length) {
|
||||
Message* m = (Message*)malloc(sizeof(Message));
|
||||
m->data = (char*)malloc(length + 1);
|
||||
memcpy(m->data, data, length);
|
||||
m->data[length] = '\0';
|
||||
m->length = length;
|
||||
return m;
|
||||
}
|
||||
|
||||
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_free(Message* m) {
|
||||
free(m->data);
|
||||
free(m);
|
||||
}
|
||||
|
||||
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);
|
||||
char* msg_to_hex(Message* m) {
|
||||
char* hex = (char*)malloc(m->length * 2 + 1);
|
||||
for (int i = 0; i < m->length; i++) {
|
||||
sprintf(hex + i * 2, "%02x", (unsigned char)m->data[i]);
|
||||
}
|
||||
hex[m->length * 2] = '\0';
|
||||
return hex;
|
||||
}
|
||||
|
||||
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);
|
||||
return 0;
|
||||
Message* msg_from_hex(const char* hex) {
|
||||
int len = strlen(hex);
|
||||
int data_len = len / 2;
|
||||
char* data = (char*)malloc(data_len);
|
||||
for (int i = 0; i < data_len; i++) {
|
||||
sscanf(hex + i * 2, "%2hhx", &data[i]);
|
||||
}
|
||||
return msg_create(data, data_len);
|
||||
}
|
||||
|
||||
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;
|
||||
char* msg_to_base64(Message* m) {
|
||||
static const char* b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
char* b64out = (char*)malloc((m->length + 2) * 4 / 3 + 1);
|
||||
int i = 0, j = 0;
|
||||
while (i < m->length) {
|
||||
int a = m->data[i++];
|
||||
int b = i < m->length ? m->data[i++] : 0;
|
||||
int c = i < m->length ? m->data[i++] : 0;
|
||||
b64out[j++] = b64[(a >> 2) & 0x3F];
|
||||
b64out[j++] = b64[((a << 4) | (b >> 4)) & 0x3F];
|
||||
b64out[j++] = b64[((b << 2) | (c >> 6)) & 0x3F];
|
||||
b64out[j++] = b64[c & 0x3F];
|
||||
}
|
||||
int padding = (3 - (m->length % 3)) % 3;
|
||||
for (int p = 0; p < padding; p++) b64out[j - 1 - p] = '=';
|
||||
b64out[j] = '\0';
|
||||
return b64out;
|
||||
}
|
||||
|
||||
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;
|
||||
Message* msg_from_base64(const char* b64) {
|
||||
static unsigned char decode[256];
|
||||
static int init = 0;
|
||||
if (!init) {
|
||||
memset(decode, 0xFF, 256);
|
||||
const char* b64chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
for (int i = 0; b64chars[i]; i++) decode[(int)b64chars[i]] = i;
|
||||
init = 1;
|
||||
}
|
||||
return 1;
|
||||
int len = strlen(b64);
|
||||
int out_len = len * 3 / 4;
|
||||
char* data = (char*)malloc(out_len);
|
||||
int i = 0, j = 0;
|
||||
while (i < len) {
|
||||
int a = decode[(unsigned char)b64[i++]];
|
||||
int b = i < len ? decode[(unsigned char)b64[i++]] : 0;
|
||||
int c = i < len ? decode[(unsigned char)b64[i++]] : 0;
|
||||
int d = i < len ? decode[(unsigned char)b64[i++]] : 0;
|
||||
if (a < 0 || b < 0) continue;
|
||||
data[j++] = (a << 2) | (b >> 4);
|
||||
if (c < 0xFF) data[j++] = (b << 4) | (c >> 2);
|
||||
if (d < 0xFF) data[j++] = (c << 6) | d;
|
||||
}
|
||||
return msg_create(data, j);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
return 0;
|
||||
}
|
||||
int msg_get_length(Message* m) { return m->length; }
|
||||
char* msg_get_data(Message* m) { return m->data; }
|
||||
|
|
|
|||
Reference in a new issue