feat: acquire-core full legacy C corpus (~2066 files, build-verified) + generator + inventory
This commit is contained in:
commit
b96cf702ee
2897 changed files with 264970 additions and 0 deletions
68
app/shared/common/util_amount.c
Normal file
68
app/shared/common/util_amount.c
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* util_amount.c - 금액/통화 유틸리티 (plain C, 공유)
|
||||
*/
|
||||
#include "acq_util.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define AMOUNT_MAX 100000000L
|
||||
|
||||
long amount_parse(const char *field, int len)
|
||||
{
|
||||
long v = 0;
|
||||
int i;
|
||||
if (!field || len <= 0)
|
||||
return -1;
|
||||
for (i = 0; i < len; i++) {
|
||||
char c = field[i];
|
||||
if (c == ' ')
|
||||
continue;
|
||||
if (!isdigit((unsigned char)c))
|
||||
return -1;
|
||||
v = v * 10 + (c - '0');
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
int amount_format(long amount, char *out, int len)
|
||||
{
|
||||
char tmp[32];
|
||||
int n;
|
||||
if (!out || len <= 0 || amount < 0)
|
||||
return -1;
|
||||
n = snprintf(tmp, sizeof(tmp), "%0*ld", len, amount);
|
||||
if (n < 0 || n > len)
|
||||
return -1;
|
||||
memcpy(out, tmp, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void amount_format_won(long amount, char *out, int outlen)
|
||||
{
|
||||
char raw[32];
|
||||
int n, i, j, digits, first;
|
||||
if (!out || outlen <= 0)
|
||||
return;
|
||||
n = snprintf(raw, sizeof(raw), "%ld", amount);
|
||||
if (n < 0) { out[0] = '\0'; return; }
|
||||
first = (raw[0] == '-') ? 1 : 0;
|
||||
digits = n - first;
|
||||
j = 0;
|
||||
if (first && j < outlen - 1)
|
||||
out[j++] = '-';
|
||||
for (i = first; i < n && j < outlen - 1; i++) {
|
||||
int pos = i - first;
|
||||
if (pos > 0 && (digits - pos) % 3 == 0)
|
||||
if (j < outlen - 1)
|
||||
out[j++] = ',';
|
||||
out[j++] = raw[i];
|
||||
}
|
||||
out[j] = '\0';
|
||||
}
|
||||
|
||||
int amount_is_valid(long amount)
|
||||
{
|
||||
return (amount >= 1 && amount <= AMOUNT_MAX) ? 1 : 0;
|
||||
}
|
||||
113
app/shared/common/util_date.c
Normal file
113
app/shared/common/util_date.c
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* util_date.c - 일자/영업일 유틸리티 (plain C, 공유)
|
||||
*/
|
||||
#include "acq_util.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
static int is_all_digit(const char *s, int len)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < len; i++)
|
||||
if (!isdigit((unsigned char)s[i]))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int to_int(const char *s, int len)
|
||||
{
|
||||
int i, v = 0;
|
||||
for (i = 0; i < len; i++)
|
||||
v = v * 10 + (s[i] - '0');
|
||||
return v;
|
||||
}
|
||||
|
||||
static int days_in_month(int y, int m)
|
||||
{
|
||||
static const int d[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||
if (m < 1 || m > 12)
|
||||
return 0;
|
||||
if (m == 2) {
|
||||
int leap = (y % 4 == 0 && y % 100 != 0) || (y % 400 == 0);
|
||||
return leap ? 29 : 28;
|
||||
}
|
||||
return d[m - 1];
|
||||
}
|
||||
|
||||
int date_is_valid(const char *yyyymmdd)
|
||||
{
|
||||
int y, m, d;
|
||||
if (!yyyymmdd || strlen(yyyymmdd) < 8)
|
||||
return 0;
|
||||
if (!is_all_digit(yyyymmdd, 8))
|
||||
return 0;
|
||||
y = to_int(yyyymmdd, 4);
|
||||
m = to_int(yyyymmdd + 4, 2);
|
||||
d = to_int(yyyymmdd + 6, 2);
|
||||
if (y < 1900 || y > 2999) return 0;
|
||||
if (m < 1 || m > 12) return 0;
|
||||
if (d < 1 || d > days_in_month(y, m)) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int date_weekday(const char *yyyymmdd)
|
||||
{
|
||||
static const int t[] = { 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 };
|
||||
int y, m, d;
|
||||
if (!date_is_valid(yyyymmdd))
|
||||
return -1;
|
||||
y = to_int(yyyymmdd, 4);
|
||||
m = to_int(yyyymmdd + 4, 2);
|
||||
d = to_int(yyyymmdd + 6, 2);
|
||||
if (m < 3)
|
||||
y -= 1;
|
||||
return (y + y / 4 - y / 100 + y / 400 + t[m - 1] + d) % 7;
|
||||
}
|
||||
|
||||
int date_is_weekend(const char *yyyymmdd)
|
||||
{
|
||||
int w = date_weekday(yyyymmdd);
|
||||
return (w == 0 || w == 6) ? 1 : 0;
|
||||
}
|
||||
|
||||
static void add_one_day(const char *in, char *out)
|
||||
{
|
||||
int y = to_int(in, 4);
|
||||
int m = to_int(in + 4, 2);
|
||||
int d = to_int(in + 6, 2);
|
||||
d++;
|
||||
if (d > days_in_month(y, m)) {
|
||||
d = 1; m++;
|
||||
if (m > 12) { m = 1; y++; }
|
||||
}
|
||||
snprintf(out, 9, "%04d%02d%02d", y, m, d);
|
||||
}
|
||||
|
||||
int date_next_business(const char *yyyymmdd, char *out)
|
||||
{
|
||||
char cur[9];
|
||||
int guard = 0;
|
||||
if (!date_is_valid(yyyymmdd) || !out)
|
||||
return -1;
|
||||
memcpy(cur, yyyymmdd, 8);
|
||||
cur[8] = '\0';
|
||||
do {
|
||||
add_one_day(cur, cur);
|
||||
if (++guard > 14)
|
||||
return -1;
|
||||
} while (date_is_weekend(cur));
|
||||
memcpy(out, cur, 8);
|
||||
out[8] = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
void date_today(char *out)
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
struct tm tmv;
|
||||
localtime_r(&now, &tmv);
|
||||
strftime(out, 9, "%Y%m%d", &tmv);
|
||||
}
|
||||
88
app/shared/common/util_msg.c
Normal file
88
app/shared/common/util_msg.c
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* util_msg.c - 고정길이 전문 pack/unpack 유틸리티 (plain C, 공유)
|
||||
*/
|
||||
#include "acq_util.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
void msg_field_copy(char *out, const char *field, int len)
|
||||
{
|
||||
int end;
|
||||
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';
|
||||
}
|
||||
|
||||
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++)
|
||||
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);
|
||||
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;
|
||||
return 1;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
27
app/shared/include/acq_util.h
Normal file
27
app/shared/include/acq_util.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* acq_util.h - 공통 유틸리티 (일자/금액/전문) 선언 (공유)
|
||||
*/
|
||||
#ifndef ACQ_UTIL_H
|
||||
#define ACQ_UTIL_H
|
||||
|
||||
#include "msg_layout.h"
|
||||
|
||||
int date_is_valid(const char *yyyymmdd);
|
||||
int date_weekday(const char *yyyymmdd);
|
||||
int date_is_weekend(const char *yyyymmdd);
|
||||
int date_next_business(const char *yyyymmdd, char *out);
|
||||
void date_today(char *out);
|
||||
|
||||
long amount_parse(const char *field, int len);
|
||||
int amount_format(long amount, char *out, int len);
|
||||
void amount_format_won(long amount, char *out, int outlen);
|
||||
int amount_is_valid(long amount);
|
||||
|
||||
void msg_field_copy(char *out, const char *field, int len);
|
||||
void msg_field_set(char *field, const char *src, int len);
|
||||
void msg_field_set_num(char *field, const char *src, int len);
|
||||
int msg_unpack(acq_msg_t *msg, const char *raw, int rawlen);
|
||||
int msg_pack(const acq_msg_t *msg, char *raw, int rawlen);
|
||||
int msg_validate(const acq_msg_t *msg);
|
||||
|
||||
#endif /* ACQ_UTIL_H */
|
||||
43
app/shared/include/msg_layout.h
Normal file
43
app/shared/include/msg_layout.h
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* msg_layout.h - 카드 매입 전문(電文) 고정길이 레이아웃 (공유)
|
||||
*/
|
||||
#ifndef MSG_LAYOUT_H
|
||||
#define MSG_LAYOUT_H
|
||||
|
||||
#define MSG_TYPE_RECV "0200"
|
||||
#define MSG_TYPE_RESP "0210"
|
||||
#define MSG_TYPE_RECON "0500"
|
||||
|
||||
#define RESP_OK "0000"
|
||||
#define RESP_INVALID "9001"
|
||||
#define RESP_NOMERCH "9002"
|
||||
#define RESP_SYSERR "9999"
|
||||
|
||||
typedef struct {
|
||||
char msg_type[4];
|
||||
char trans_code[6];
|
||||
char merch_id[15];
|
||||
char card_no[16];
|
||||
char approval_no[9];
|
||||
char amount[12];
|
||||
char txn_date[8];
|
||||
char txn_time[6];
|
||||
char inst_month[2];
|
||||
char resp_code[4];
|
||||
char filler[18];
|
||||
} acq_msg_t;
|
||||
|
||||
#define MSG_ACQ_LEN ((int)sizeof(acq_msg_t))
|
||||
|
||||
#define FLD_MSG_TYPE_LEN 4
|
||||
#define FLD_TRANS_CODE_LEN 6
|
||||
#define FLD_MERCH_ID_LEN 15
|
||||
#define FLD_CARD_NO_LEN 16
|
||||
#define FLD_APPROVAL_LEN 9
|
||||
#define FLD_AMOUNT_LEN 12
|
||||
#define FLD_TXN_DATE_LEN 8
|
||||
#define FLD_TXN_TIME_LEN 6
|
||||
#define FLD_INST_LEN 2
|
||||
#define FLD_RESP_LEN 4
|
||||
|
||||
#endif /* MSG_LAYOUT_H */
|
||||
Reference in a new issue