some fast patch
This commit is contained in:
parent
9c671b8527
commit
b38b829612
9 changed files with 150 additions and 7 deletions
|
|
@ -108,6 +108,17 @@ typedef struct global {
|
|||
TypeDicSeg Jpeepidx;
|
||||
} Global;
|
||||
|
||||
typedef struct dictskipseg {
|
||||
u_int first;
|
||||
u_short count;
|
||||
TypeDicOfs end;
|
||||
} DictSkipSeg;
|
||||
|
||||
typedef struct dictskipent {
|
||||
TypeDicOfs offset;
|
||||
u_short lower;
|
||||
} DictSkipEnt;
|
||||
|
||||
typedef struct vfile {
|
||||
u_char* buffer;
|
||||
u_int size;
|
||||
|
|
@ -129,6 +140,8 @@ typedef struct dictfile {
|
|||
long segstrt;
|
||||
|
||||
TypeIdxOfs* ofsptr;
|
||||
DictSkipSeg* skipseg;
|
||||
DictSkipEnt* skipent;
|
||||
|
||||
struct dictfile* link;
|
||||
} DictFile;
|
||||
|
|
|
|||
|
|
@ -65,7 +65,8 @@ CLREC* alloc_clrec(SJ4_CONTEXT2);
|
|||
void free_clrec(SJ4_CONTEXT CLREC*);
|
||||
|
||||
/* charsize.c */
|
||||
static __inline int codesize_inline(u_char code) {
|
||||
static __inline int
|
||||
codesize_inline(u_char code) {
|
||||
switch(code & KANJIMODEMASK) {
|
||||
case ZENHIRAASSYUKU:
|
||||
case ZENKATAASSYUKU:
|
||||
|
|
@ -159,7 +160,8 @@ int getkanji(SJ4_CONTEXT u_char*, int, u_char*, u_char*);
|
|||
void getrank(SJ4_CONTEXT2);
|
||||
|
||||
/* hzstrlen.c */
|
||||
static __inline int euc_codesize_inline(u_char c) {
|
||||
static __inline int
|
||||
euc_codesize_inline(u_char c) {
|
||||
if((c & KANJIMODEMASK) == 0x90) {
|
||||
return 1;
|
||||
} else if(isknj1(c)) {
|
||||
|
|
@ -268,6 +270,7 @@ extern u_char kigou[];
|
|||
/* sdepend.c */
|
||||
DictFile* opendict(SJ4_CONTEXT char*, char*);
|
||||
int closedict(SJ4_CONTEXT DictFile*);
|
||||
u_char* skipdict(SJ4_CONTEXT u_char*, TypeDicSeg, u_char);
|
||||
StdyFile* openstdy(SJ4_CONTEXT char*, char*);
|
||||
int closestdy(SJ4_CONTEXT StdyFile*);
|
||||
int putstydic(SJ4_CONTEXT2);
|
||||
|
|
|
|||
|
|
@ -142,6 +142,7 @@ typedef struct dict {
|
|||
IFunc putidx;
|
||||
IFunc putdic;
|
||||
IFunc rszdic;
|
||||
VFuncDict skipdic;
|
||||
} DICT;
|
||||
|
||||
typedef struct dictl {
|
||||
|
|
|
|||
|
|
@ -55,6 +55,12 @@ typedef int (*IFuncDict)(
|
|||
#endif
|
||||
void*);
|
||||
|
||||
typedef void* (*VFuncDict)(
|
||||
#ifndef SJ4_GLOBAL
|
||||
void*,
|
||||
#endif
|
||||
void*, short);
|
||||
|
||||
typedef u_char TypeGroup;
|
||||
typedef u_char TypeGram;
|
||||
typedef u_short TypeIdxOfs;
|
||||
|
|
|
|||
|
|
@ -74,8 +74,9 @@ void initwork(SJ4_CONTEXT2) {
|
|||
}
|
||||
|
||||
#ifndef SJ4_GLOBAL
|
||||
Sj4Context* alloccontext(const char* dic) {
|
||||
Sj4Context* ctx = calloc(1, sizeof(*ctx));
|
||||
Sj4Context*
|
||||
alloccontext(const char* dic) {
|
||||
Sj4Context* ctx = (Sj4Context*)calloc(1, sizeof(*ctx));
|
||||
DictFile* dict;
|
||||
DICTL* node;
|
||||
|
||||
|
|
|
|||
|
|
@ -217,6 +217,114 @@ rszdic(SJ4_CONTEXT DictFile* dp, TypeDicSeg seg) {
|
|||
return fputfile(dp->fp, 0, HEADERLENGTH, dp->buffer);
|
||||
}
|
||||
|
||||
static void
|
||||
freedicskip(DictFile* dp) {
|
||||
free((char*)dp->skipent);
|
||||
free((char*)dp->skipseg);
|
||||
dp->skipent = NULL;
|
||||
dp->skipseg = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
mkdicskip(DictFile* dp) {
|
||||
DictSkipSeg* segs;
|
||||
DictSkipEnt* ents;
|
||||
u_short* stack;
|
||||
u_int total = 0;
|
||||
int seg;
|
||||
|
||||
if(dp->dict.maxunit != 0 || dp->dict.segunit <= 0) return;
|
||||
|
||||
segs = (DictSkipSeg*)calloc(dp->dict.segunit, sizeof(*segs));
|
||||
if(segs == NULL) return;
|
||||
|
||||
for(seg = 0; seg < dp->dict.segunit; seg++) {
|
||||
u_char* base = dp->buffer + dp->segstrt + dp->dict.seglen * seg;
|
||||
u_char* p = base + *base + 1;
|
||||
|
||||
segs[seg].first = total;
|
||||
while(p < base + dp->dict.seglen && *p != DICSEGTERM) {
|
||||
segs[seg].count++;
|
||||
total++;
|
||||
p = getntag(p);
|
||||
}
|
||||
segs[seg].end = (TypeDicOfs)(p - base);
|
||||
}
|
||||
|
||||
ents = (DictSkipEnt*)malloc(total * sizeof(*ents));
|
||||
stack = (u_short*)malloc(dp->dict.seglen * sizeof(*stack));
|
||||
if(ents == NULL || stack == NULL) {
|
||||
free((char*)stack);
|
||||
free((char*)ents);
|
||||
free((char*)segs);
|
||||
}
|
||||
|
||||
for(seg = 0; seg < dp->dict.segunit; seg++) {
|
||||
DictSkipSeg* s = &segs[seg];
|
||||
u_char* base = dp->buffer + dp->segstrt + dp->dict.seglen * seg;
|
||||
u_char* p = base + *base + 1;
|
||||
int top = 0;
|
||||
int i;
|
||||
|
||||
for(i = 0; i < s->count; i++) {
|
||||
ents[s->first + i].offset = (TypeDicOfs)(p - base);
|
||||
p = getntag(p);
|
||||
}
|
||||
|
||||
for(i = s->count - 1; i >= 0; i--) {
|
||||
u_char plen = getplen(base + ents[s->first + i].offset);
|
||||
|
||||
while(top > 0 && getplen(base + ents[s->first + stack[top - 1]].offset) >= plen) top--;
|
||||
|
||||
ents[s->first + i].lower = (top > 0) ? stack[top - 1] : s->count;
|
||||
stack[top++] = (u_short)i;
|
||||
}
|
||||
}
|
||||
|
||||
free((char*)stack);
|
||||
dp->skipseg = segs;
|
||||
dp->skipent = ents;
|
||||
}
|
||||
|
||||
static u_char*
|
||||
skipdic(SJ4_CONTEXT u_char* tagp, TypeDicSeg seg) {
|
||||
DictFile* dp = (DictFile*)curdict;
|
||||
DictSkipSeg* s;
|
||||
TypeDicOfs offset;
|
||||
int lo, hi;
|
||||
u_short i;
|
||||
|
||||
if(dp->skipseg == NULL || seg < 0 || seg >= dp->dict.segunit) return NULL;
|
||||
|
||||
s = &dp->skipseg[seg];
|
||||
offset = (TypeDicOfs)(tagp - dicbuf);
|
||||
lo = 0;
|
||||
hi = s->count - 1;
|
||||
while(lo <= hi) {
|
||||
int mid = (lo + hi) / 2;
|
||||
TypeDicOfs moff = dp->skipent[s->first + mid].offset;
|
||||
|
||||
if(moff < offset)
|
||||
lo = mid + 1;
|
||||
else if(moff > offset)
|
||||
hi = mid - 1;
|
||||
else {
|
||||
i = (u_short)mid;
|
||||
while(i < s->count) {
|
||||
u_short next = dp->skipent[s->first + i].lower;
|
||||
|
||||
if(next >= s->count) return dicbuf + s->end;
|
||||
i = next;
|
||||
if(getplen(dicbuf + dp->skipent[s->first + i].offset) <= dicsaml)
|
||||
return dicbuf + dp->skipent[s->first + i].offset;
|
||||
}
|
||||
return dicbuf + s->end;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DictFile*
|
||||
opendict(SJ4_CONTEXT char* name, char* passwd) {
|
||||
FILE* fp = NULL;
|
||||
|
|
@ -298,6 +406,7 @@ opendict(SJ4_CONTEXT char* name, char* passwd) {
|
|||
dfp->dict.putidx = (IFunc)putidx;
|
||||
dfp->dict.putdic = (IFunc)putdic;
|
||||
dfp->dict.rszdic = (IFunc)rszdic;
|
||||
dfp->dict.skipdic = (VFuncDict)skipdic;
|
||||
dfp->refcnt = 1;
|
||||
dfp->fp = fp;
|
||||
dfp->vf = vf;
|
||||
|
|
@ -314,6 +423,7 @@ opendict(SJ4_CONTEXT char* name, char* passwd) {
|
|||
goto error3;
|
||||
}
|
||||
mkidxtbl(SJ4_CONTEXT_PASS & (dfp->dict));
|
||||
mkdicskip(dfp);
|
||||
|
||||
dfp->link = dictlink;
|
||||
dictlink = dfp;
|
||||
|
|
|
|||
|
|
@ -222,6 +222,15 @@ srchdict(SJ4_CONTEXT u_char* tagp) {
|
|||
return tagp;
|
||||
}
|
||||
}
|
||||
|
||||
else if(cmp == CONT && getnlen(tagp) != 0 && getplen(tagp) > dicsaml && curdict->skipdic != NULL) {
|
||||
u_char* next = (*curdict->skipdic)(SJ4_CONTEXT_PASS tagp, segno);
|
||||
|
||||
if(next != NULL) {
|
||||
tagp = next;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
tagp = getntag(tagp);
|
||||
}
|
||||
dicinl = dicsaml + 1;
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ static struct sj4table {
|
|||
Sj4Ime* sj4_ime(int charset, const char* dict, Sj4ImePacket packet) {
|
||||
Sj4Ime* ime;
|
||||
|
||||
if((ime = calloc(1, sizeof(*ime))) == NULL) return NULL;
|
||||
if((ime = (Sj4Ime*)calloc(1, sizeof(*ime))) == NULL) return NULL;
|
||||
|
||||
if((ime->lib = sj4_open(charset, dict)) == NULL) {
|
||||
free((char*)ime);
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ Sj4Lib* sj4_open(int charset, const char* dic) {
|
|||
if(charset == SJ4UTF8 || charset == SJ4UTF16) return NULL;
|
||||
#endif
|
||||
|
||||
if((ctx = calloc(1, sizeof(*ctx))) == NULL) return NULL;
|
||||
if((ctx = (Sj4Lib*)calloc(1, sizeof(*ctx))) == NULL) return NULL;
|
||||
|
||||
if((ctx->ctx = alloccontext(dic)) == NULL) {
|
||||
free((char*)ctx);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue