Functioning sj4lib

This commit is contained in:
Nishi 2026-06-21 23:53:20 +09:00
commit 3ccb4e5b29
6 changed files with 210 additions and 39 deletions

25
LICENSE Normal file
View file

@ -0,0 +1,25 @@
Copyright (c) 1991-1994 Sony Corporation
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL SONY CORPORATION BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Sony Corporation
shall not be used in advertising or otherwise to promote the sale, use
or other dealings in this Software without prior written authorization
from Sony Corporation.

View file

@ -7,12 +7,13 @@
#define SJ4BUFSZ (16 * 1024) #define SJ4BUFSZ (16 * 1024)
typedef union sj4kouhobuffer { typedef union sj4kouhobuffer {
unsigned char sjis[SJ4BUFSZ]; char sjis[SJ4BUFSZ];
unsigned char eucjp[SJ4BUFSZ]; char eucjp[SJ4BUFSZ];
char utf8[SJ4BUFSZ]; char utf8[SJ4BUFSZ];
wchar_t utf16[SJ4BUFSZ / sizeof(wchar_t)]; wchar_t utf16[SJ4BUFSZ / sizeof(wchar_t)];
unsigned char raw[SJ4BUFSZ]; unsigned char raw[SJ4BUFSZ];
wchar_t wraw[SJ4BUFSZ / sizeof(wchar_t)];
} Sj4KouhoBuffer; } Sj4KouhoBuffer;
typedef struct sj4kouho { typedef struct sj4kouho {

View file

@ -261,7 +261,7 @@ opendict(SJ4_CONTEXT char* name, char* passwd) {
u_char* dp; u_char* dp;
VFile vf; VFile vf;
#ifdef EMBED #if defined(EMBED) || defined(EMBED_PLUS)
memset(&vf, 0, sizeof(vf)); memset(&vf, 0, sizeof(vf));
if(strcmp(name, "sj4main.dic") == 0) { if(strcmp(name, "sj4main.dic") == 0) {

View file

@ -1,11 +1,22 @@
#include <sj4lib.h> #include <sj4lib.h>
#include <sj_kanakan.h> #include <sj_kanakan.h>
#include <sj_string.h>
#include <stdlib.h> #include <stdlib.h>
#include <sj_euc2ucs.h> #include <sj_euc2ucs.h>
#include <sj_ucs2euc.h> #include <sj_ucs2euc.h>
struct sj4lib {
Sj4Context* ctx;
int charset;
u_char inbuf[SJ4BUFSZ];
u_char outbuf[SJ4BUFSZ];
u_char wrkbuf[SJ4BUFSZ];
};
static u_int ucs_to_euc(u_int in) { static u_int ucs_to_euc(u_int in) {
if(0 <= in && in <= 0xffff) { if(0 <= in && in <= 0xffff) {
const T_U2E_BITMAP_INDEX* b = &utf16_to_euc_jp_table[(in >> 8) & 0xff]; const T_U2E_BITMAP_INDEX* b = &utf16_to_euc_jp_table[(in >> 8) & 0xff];
@ -56,7 +67,30 @@ static u_int euc_to_ucs(u_int in) {
return 0; return 0;
} }
static int eucjp_write(u_char* out, u_int n) {
if(n <= 0xff) {
*out++ = n;
return 1;
} else if(n <= 0xffff) {
*out++ = (n >> 8) & 0xff;
*out++ = (n >> 0) & 0xff;
return 2;
} else {
*out++ = (n >> 16) & 0xff;
*out++ = (n >> 8) & 0xff;
*out++ = (n >> 0) & 0xff;
return 3;
}
}
static int from_sjis(u_char* out, const u_char* in, int len) { static int from_sjis(u_char* out, const u_char* in, int len) {
unsigned char d[] = {0, 0};
int uf = 0;
return sj4_str_sjistoeuc(out, SJ4BUFSZ, (u_char*)in, len, d, &uf);
} }
static int utf8_later(unsigned char c) { static int utf8_later(unsigned char c) {
@ -108,25 +142,95 @@ static int from_utf8(u_char* out, const u_char* in, int len) {
n = ucs_to_euc(n); n = ucs_to_euc(n);
if(n <= 0xff) { out += eucjp_write(out, n);
*out++ = n;
} else if(n <= 0xffff) {
*out++ = (n >> 8) & 0xff;
*out++ = (n >> 0) & 0xff;
} else {
*out++ = (n >> 16) & 0xff;
*out++ = (n >> 8) & 0xff;
*out++ = (n >> 0) & 0xff;
}
} }
return out - o_out; return out - o_out;
} }
int is_high_surr(wchar_t ch) {
return 0xD800 <= ch && ch < 0xDC00;
}
int is_low_urr(wchar_t ch) {
return 0xDC00 <= ch && ch < 0xE000;
}
static int from_utf16(u_char* out, const u_char* in, int len) { static int from_utf16(u_char* out, const u_char* in, int len) {
const wchar_t* w_in = (const wchar_t*)in;
const wchar_t* o_in = w_in;
u_char* o_out = out;
while((w_in - o_in) < len) {
u_int n = 0;
if(is_high_surr(w_in[0])) {
if(is_low_urr(w_in[1])) {
n = 0x10000 + CAST_I32(w_in[0] - 0xd800) * 0x400 + CAST_I32(w_in[1] - 0xdc00);
w_in += 2;
} else if(w_in[1] == 0) {
n = w_in[0];
w_in += 2;
} else {
return 0;
}
} else if(is_low_urr(w_in[0])) {
if(w_in[1] == 0) {
n = w_in[0];
w_in += 2;
} else {
return 0;
}
} else {
n = w_in[0];
w_in += 1;
}
n = ucs_to_euc(n);
out += eucjp_write(out, n);
}
return out - o_out;
}
static u_int eucjp_read(const u_char* in) {
u_char c = *in;
u_int n = 0;
if(c <= 0x7f) {
n = c;
} else if(c != 0x8f) {
n = CAST_I32(in[0]) << 8;
n |= CAST_I32(in[1]);
} else {
n = CAST_I32(in[0]) << 16;
n |= CAST_I32(in[1]) << 8;
n |= CAST_I32(in[2]);
}
return n;
}
static int eucjp_codesize(u_int n) {
if(n <= 0xff) {
return 1;
} else if(n <= 0xffff) {
return 2;
} else {
return 3;
}
} }
static int to_sjis(u_char* out, const u_char* in, int len) { static int to_sjis(u_char* out, const u_char* in, int len) {
unsigned char d[] = {0, 0};
int uf = 0;
return sj4_str_euctosjis(out, SJ4BUFSZ, (u_char*)in, len, d, &uf);
} }
static int to_utf8(u_char* out, const u_char* in, int len) { static int to_utf8(u_char* out, const u_char* in, int len) {
@ -134,24 +238,31 @@ static int to_utf8(u_char* out, const u_char* in, int len) {
u_char* o_out = out; u_char* o_out = out;
while((in - o_in) < len) { while((in - o_in) < len) {
u_char c = *in; int i, j = 0;
u_int n = 0; u_int n = eucjp_read(in);
if(c <= 0x7f) { in += eucjp_codesize(n);
n = c;
in += 1; n = euc_to_ucs(n);
} else if(c != 0x8f) {
n = CAST_I32(in[0]) << 8;
n |= CAST_I32(in[1]);
in += 2; if(n >= 0x10000) {
*out++ = ((n >> (6 * 3)) & 7) | 0xf0;
j = 3;
} else if(n >= 0x800) {
*out++ = ((n >> (6 * 2)) & 15) | 0xe0;
j = 2;
} else if(n >= 0x80) {
*out++ = ((n >> (6 * 1)) & 31) | 0xc0;
j = 1;
} else { } else {
n = CAST_I32(in[0]) << 16; *out++ = n;
n |= CAST_I32(in[1]) << 8; }
n |= CAST_I32(in[2]);
in += 3; for(i = 0; i < j; i++) {
*out++ = ((n >> (6 * (j - i - 1))) & 63) | 0x80;
} }
} }
@ -159,17 +270,29 @@ static int to_utf8(u_char* out, const u_char* in, int len) {
} }
static int to_utf16(u_char* out, const u_char* in, int len) { static int to_utf16(u_char* out, const u_char* in, int len) {
wchar_t* w_out = (wchar_t*)out;
const u_char* o_in = in;
wchar_t* o_out = w_out;
while((in - o_in) < len) {
int i, j = 0;
u_int n = eucjp_read(in);
in += eucjp_codesize(n);
n = euc_to_ucs(n);
if(n < 0x10000) {
*w_out++ = n;
} else {
*w_out++ = (n - 0x10000) / 0x400 + 0xd800;
*w_out++ = (n - 0x10000) % 0x400 + 0xdc00;
}
}
return w_out - o_out;
} }
struct sj4lib {
Sj4Context* ctx;
int charset;
u_char inbuf[SJ4BUFSZ];
u_char outbuf[SJ4BUFSZ];
};
Sj4Lib* sj4_open(int charset, const char* dic) { Sj4Lib* sj4_open(int charset, const char* dic) {
Sj4Lib* ctx; Sj4Lib* ctx;
@ -198,17 +321,36 @@ Sj4Lib* sj4_open(int charset, const char* dic) {
} }
int sj4_getkan(Sj4Lib* ctx, const void* input, int len, Sj4Kouho* kouho) { int sj4_getkan(Sj4Lib* ctx, const void* input, int len, Sj4Kouho* kouho) {
int len2;
memset(kouho, 0, sizeof(*kouho)); memset(kouho, 0, sizeof(*kouho));
ICONV(ctx->inbuf, input, len, from); ICONV(ctx->inbuf, input, len, from);
len = cl2knj(ctx->ctx, ctx->inbuf, len, ctx->outbuf); len = cl2knj(ctx->ctx, ctx->inbuf, len, ctx->outbuf);
ICONV(kouho->buffer.raw, ctx->outbuf, len, to); len2 = strlen(ctx->outbuf + sizeof(STDYOUT));
ICONV(kouho->buffer.raw, ctx->outbuf + sizeof(STDYOUT), len2, to);
return len; memcpy(ctx->wrkbuf, ctx->inbuf, len);
ICONV(ctx->outbuf, ctx->wrkbuf, len, to);
if(ctx->charset == SJ4UTF16) {
int i;
for(i = 0; i < sizeof(wchar_t); i++) ctx->outbuf[len * sizeof(wchar_t) + i] = 0;
} else {
ctx->outbuf[len] = 0;
}
if(ctx->charset == SJ4UTF16) {
kouho->buffer.utf16[len2] = 0;
} else {
kouho->buffer.raw[len2] = 0;
}
return ctx->charset == SJ4UTF16 ? wcslen((wchar_t*)ctx->outbuf) : strlen(ctx->outbuf);
} }
void sj4_close(Sj4Lib* ctx) { void sj4_close(Sj4Lib* ctx) {
free_context(ctx->ctx);
free(ctx); free(ctx);
} }

View file

@ -177,7 +177,7 @@ int string_cmp(u_char* p1, int l1, u_char* p2, int l2) {
} }
void utf8_print(char* out, int c) { void utf8_print(char* out, int c) {
int i = 0, j, k; int i = 0, j = 0, k;
if(c >= 0x10000) { if(c >= 0x10000) {
out[i++] = ((c >> (6 * 3)) & 7) | 0xf0; out[i++] = ((c >> (6 * 3)) & 7) | 0xf0;

View file

@ -2,6 +2,7 @@
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <locale.h>
int main(int argc, char** argv) { int main(int argc, char** argv) {
char c[8 * 1024]; char c[8 * 1024];
@ -15,7 +16,9 @@ int main(int argc, char** argv) {
c[0] = 0; c[0] = 0;
while(fread(&b, 1, 1, stdin) == 1) { setlocale(LC_ALL, "");
while(fread(&b, 1, sizeof(b), stdin)) {
int n, i; int n, i;
Sj4Kouho kouho; Sj4Kouho kouho;
@ -31,7 +34,7 @@ int main(int argc, char** argv) {
i = 0; i = 0;
while((strlen(c) - i) > 0 && (n = sj4_getkan(ctx, c + i, strlen(c + i), &kouho))) { while((strlen(c) - i) > 0 && (n = sj4_getkan(ctx, c + i, strlen(c + i), &kouho))) {
printf("> %s\n", kouho.buffer); printf("> %s\n", kouho.buffer.sjis);
i += n; i += n;
} }