/*
*******************************************************************************
*
*   Copyright (C) 2000, International Business Machines
*   Corporation and others.  All Rights Reserved.
*
*******************************************************************************
*   file name:  genmbcs.c
*   encoding:   US-ASCII
*   tab size:   8 (not used)
*   indentation:4
*
*   created on: 2000jul06
*   created by: Markus W. Scherer
*/

#include <stdio.h>
#include "unicode/utypes.h"
#include "cstring.h"
#include "cmemory.h"
#include "unewdata.h"
#include "ucnvmbcs.h"
#include "makeconv.h"
#include "genmbcs.h"

enum {
    MBCS_STATE_FLAG_DIRECT=1,
    MBCS_STATE_FLAG_SURROGATES,

    MBCS_STATE_FLAG_READY=16
};

enum {
    MBCS_MAX_STATE_COUNT=128,
    MBCS_MAX_FALLBACK_COUNT=1000
};

typedef struct MBCSData {
    NewConverter newConverter;

    /* toUnicode */
    int32_t stateTable[MBCS_MAX_STATE_COUNT][256];
    uint32_t stateFlags[MBCS_MAX_STATE_COUNT],
             stateOffsetSum[MBCS_MAX_STATE_COUNT];
    _MBCSToUFallback toUFallbacks[MBCS_MAX_FALLBACK_COUNT];
    uint16_t *unicodeCodeUnits;
    _MBCSHeader header;
    uint32_t countToUCodeUnits;

    /* fromUnicode */
    uint16_t table[0x20440];
    uint8_t *fromUBytes;
    uint32_t stage2Top, stage3Top, maxCharLength;
} MBCSData;

/* prototypes */
static void
MBCSClose(NewConverter *cnvData);

static UBool
MBCSProcessStates(NewConverter *cnvData);

static UBool
MBCSAddToUnicode(NewConverter *cnvData,
                 const uint8_t *bytes, int32_t length,
                 UChar32 c, uint32_t b,
                 int8_t isFallback);

static UBool
MBCSAddFromUnicode(NewConverter *cnvData,
                   const uint8_t *bytes, int32_t length,
                   UChar32 c, uint32_t b,
                   int8_t isFallback);

static void
MBCSPostprocess(NewConverter *cnvData, const UConverterStaticData *staticData);

static uint32_t
MBCSWrite(NewConverter *cnvData, const UConverterStaticData *staticData, UNewDataMemory *pData);

/* implementation ----------------------------------------------------------- */

static void
MBCSInit(MBCSData *mbcsData, uint8_t maxCharLength) {
    uprv_memset(mbcsData, 0, sizeof(MBCSData));

    mbcsData->newConverter.close=MBCSClose;
    mbcsData->newConverter.startMappings=MBCSProcessStates;
    mbcsData->newConverter.addToUnicode=MBCSAddToUnicode;
    mbcsData->newConverter.addFromUnicode=MBCSAddFromUnicode;
    mbcsData->newConverter.finishMappings=MBCSPostprocess;
    mbcsData->newConverter.write=MBCSWrite;

    mbcsData->header.version[0]=1;
    mbcsData->stateFlags[0]=MBCS_STATE_FLAG_DIRECT;
    mbcsData->maxCharLength=maxCharLength;
    mbcsData->header.flags=maxCharLength-1; /* outputType */
}

NewConverter *
MBCSOpen(uint8_t maxCharLength) {
    MBCSData *mbcsData=(MBCSData *)uprv_malloc(sizeof(MBCSData));
    if(mbcsData!=NULL) {
        MBCSInit(mbcsData, maxCharLength);
    }
    return &mbcsData->newConverter;
}

static void
MBCSClose(NewConverter *cnvData) {
    MBCSData *mbcsData=(MBCSData *)cnvData;
    if(mbcsData!=NULL) {
        if(mbcsData->unicodeCodeUnits!=NULL) {
            uprv_free(mbcsData->unicodeCodeUnits);
        }
        if(mbcsData->fromUBytes!=NULL) {
            uprv_free(mbcsData->fromUBytes);
        }
        uprv_free(mbcsData);
    }
}

static const char *
skipWhitespace(const char *s) {
    while(*s==' ' || *s=='\t') {
        ++s;
    }
    return s;
}

/*
 * state table row grammar (ebnf-style):
 * (whitespace is allowed between all tokens)
 *
 * row=[firstentry ','] entry (',' entry)*
 * firstentry="initial" | "surrogates"
 *            (initial state (default for state 0), output is all surrogate pairs)
 * entry=range [':' nextstate] ['.' action]
 * range=number ['-' number]
 * nextstate=number
 *           (0..7f)
 * action='u' | 's' | 'p' | 'i'
 *        (unassigned, state change only, surrogate pair, illegal)
 * number=(1- or 2-digit hexadecimal number)
 */
static const char *
parseState(const char *s, int32_t state[256], uint32_t *pFlags) {
    const char *t;
    uint32_t start, end, i;
    int32_t value;

    /* initialize the state */
    for(i=0; i<256; ++i) {
        state[i]=0x80000000|(MBCS_STATE_ILLEGAL<<27);
    }

    /* skip leading white space */
    s=skipWhitespace(s);

    /* is there a "direct" or "surrogates" directive? */
    if(uprv_strncmp("direct", s, 6)==0) {
        *pFlags=MBCS_STATE_FLAG_DIRECT;
        s=skipWhitespace(s+6);
        if(*s++!=',') {
            return s-1;
        }
    } else if(*pFlags==0 && uprv_strncmp("surrogates", s, 10)==0) {
        *pFlags=MBCS_STATE_FLAG_SURROGATES;
        s=skipWhitespace(s+10);
        if(*s++!=',') {
            return s-1;
        }
    }

    for(;;) {
        /* read an entry, the start of the range first */
        s=skipWhitespace(s);
        start=uprv_strtoul(s, (char **)&t, 16);
        if(s==t || 0xff<start) {
            return s;
        }
        s=skipWhitespace(t);

        /* read the end of the range if there is one */
        if(*s=='-') {
            s=skipWhitespace(s+1);
            end=uprv_strtoul(s, (char **)&t, 16);
            if(s==t || end<start || 0xff<end) {
                return s;
            }
            s=skipWhitespace(t);
        } else {
            end=start;
        }

        /* determine the state values for this range */
        if(*s!=':' && *s!='.') {
            /* the default is: final state with valid entries */
            value=0x80000000|(MBCS_STATE_VALID_16<<27UL);
        } else {
            value=0;
            if(*s==':') {
                /* get the next state, default to 0 */
                s=skipWhitespace(s+1);
                i=uprv_strtoul(s, (char **)&t, 16);
                if(s!=t) {
                    if(0x7f<i) {
                        return s;
                    }
                    s=skipWhitespace(t);
                    value|=i;
                }
            }

            /* get the state action, default to valid */
            if(*s=='.') {
                /* this is a final state */
                value|=0x80000000;

                s=skipWhitespace(s+1);
                if(*s=='u') {
                    value|=MBCS_STATE_UNASSIGNED<<27UL;
                    s=skipWhitespace(s+1);
                } else if(*s=='p') {
                    if(*pFlags!=MBCS_STATE_FLAG_DIRECT) {
                        value|=MBCS_STATE_VALID_16_PAIR<<27UL;
                    } else {
                        value|=MBCS_STATE_VALID_16<<27UL;
                    }
                    s=skipWhitespace(s+1);
                } else if(*s=='s') {
                    value|=MBCS_STATE_CHANGE_ONLY<<27UL;
                    s=skipWhitespace(s+1);
                } else if(*s=='i') {
                    value|=MBCS_STATE_ILLEGAL<<27UL;
                    s=skipWhitespace(s+1);
                } else {
                    value|=MBCS_STATE_VALID_16<<27UL;
                }
            } else {
                /* this is an intermediate state, nothing to do */
            }
        }

        /* adjust "final valid" states according to the state flags */
        if(((uint32_t)value>>27U)==(16|MBCS_STATE_VALID_16)) {
            switch(*pFlags) {
            case 0:
                /* no adjustment */
                break;
            case MBCS_STATE_FLAG_DIRECT:
                /* set the valid-direct code point to "unassigned"==0xfffe */
                value=value&0x87ffffff|(MBCS_STATE_VALID_DIRECT_16<<27UL)|(0xfffe<<7L);
                break;
            case MBCS_STATE_FLAG_SURROGATES:
                value=value&0x87ffffff|(MBCS_STATE_VALID_16_PAIR<<27UL);
                break;
            default:
                break;
            }
        }

        /* set this value for the range */
        for(i=start; i<=end; ++i) {
            state[i]=value;
        }

        if(*s==',') {
            ++s;
        } else {
            return *s==0 ? NULL : s;
        }
    }
}

UBool
MBCSAddState(NewConverter *cnvData, const char *s) {
    MBCSData *mbcsData=(MBCSData *)cnvData;
    const char *error;

    if(mbcsData->header.countStates==MBCS_MAX_STATE_COUNT) {
        fprintf(stderr, "error: too many states (maximum %u)\n", MBCS_MAX_STATE_COUNT);
        return FALSE;
    }

    error=parseState(s, mbcsData->stateTable[mbcsData->header.countStates],
                       &mbcsData->stateFlags[mbcsData->header.countStates]);
    if(error!=NULL) {
        fprintf(stderr, "parse error in state definition at '%s'\n", error);
        return FALSE;
    }

    ++mbcsData->header.countStates;
    return TRUE;
}

static UBool
MBCSProcessStates(NewConverter *cnvData) {
    MBCSData *mbcsData=(MBCSData *)cnvData;
    uint32_t sum, i;
    int32_t entry;
    int state, cell, count;
    UBool allStatesReady;

    /*
     * first make sure that all "next state" values are within limits
     * and that all next states after final ones have the "direct"
     * flag of initial states
     */
    for(state=mbcsData->header.countStates-1; state>=0; --state) {
        for(cell=0; cell<256; ++cell) {
            entry=mbcsData->stateTable[state][cell];
            if((uint32_t)(entry&0x7f)>=mbcsData->header.countStates) {
                fprintf(stderr, "error: state table entry [%x][%x] has a next state of %x that is too high\n",
                    state, cell, entry&0x7f);
                return FALSE;
            }
            if(entry<0 && mbcsData->stateFlags[entry&0x7f]!=MBCS_STATE_FLAG_DIRECT) {
                fprintf(stderr, "error: state table entry [%x][%x] is final but has a non-initial next state of %x\n",
                    state, cell, entry&0x7f);
                return FALSE;
            }
        }
    }

    /*
     * Sum up the offsets for all states.
     * In each final state (where there are only final entries),
     * the offsets add up directly.
     * In all other state table rows, for each transition entry to another state,
     * the offsets sum of that state needs to be added.
     * This is achieved in at most countStates iterations.
     */
    allStatesReady=FALSE;
    for(count=mbcsData->header.countStates; !allStatesReady && count>=0; --count) {
        allStatesReady=TRUE;
        for(state=mbcsData->header.countStates-1; state>=0; --state) {
            if(!(mbcsData->stateFlags[state]&MBCS_STATE_FLAG_READY)) {
                allStatesReady=FALSE;
                sum=0;

                /* at first, add up only the final delta offsets to keep them <512 */
                for(cell=0; cell<256; ++cell) {
                    entry=mbcsData->stateTable[state][cell];
                    if(entry<0) {
                        switch((uint32_t)entry>>27U) {
                        case 16|MBCS_STATE_VALID_16:
                            mbcsData->stateTable[state][cell]=entry&0xf800007f|(sum<<7L);
                            sum+=1;
                            break;
                        case 16|MBCS_STATE_VALID_16_PAIR:
                            mbcsData->stateTable[state][cell]=entry&0xf800007f|(sum<<7L);
                            sum+=2;
                            break;
                        default:
                            /* no addition */
                            break;
                        }
                    }
                }

                /* now, add up the delta offsets for the transitional entries */
                for(cell=0; cell<256; ++cell) {
                    entry=mbcsData->stateTable[state][cell];
                    if(entry>=0) {
                        if(mbcsData->stateFlags[entry&0x7f]&MBCS_STATE_FLAG_READY) {
                            mbcsData->stateTable[state][cell]=entry&0xf800007f|(sum<<7L);
                            sum+=mbcsData->stateOffsetSum[entry&0x7f];
                        } else {
                            /* that next state does not have a sum yet, we cannot finish the one for this state */
                            sum=0xffffffff;
                            break;
                        }
                    }
                }

                if(sum!=0xffffffff) {
                    mbcsData->stateOffsetSum[state]=sum;
                    mbcsData->stateFlags[state]|=MBCS_STATE_FLAG_READY;
                }
            }
        }
    }

    if(!allStatesReady) {
        fprintf(stderr, "error: the state table contains loops\n");
        return FALSE;
    }

    /*
     * For all "direct" (i.e., initial) states>0,
     * the offsets need to be increased by the sum of
     * the previous initial states.
     */
    sum=mbcsData->stateOffsetSum[0];
    for(state=1; state<(int)mbcsData->header.countStates; ++state) {
        if((mbcsData->stateFlags[state]&0xf)==MBCS_STATE_FLAG_DIRECT) {
            uint32_t sum2=sum<<7;
            sum+=mbcsData->stateOffsetSum[state];
            for(cell=0; cell<256; ++cell) {
                entry=mbcsData->stateTable[state][cell];
                if(entry>=0) {
                    mbcsData->stateTable[state][cell]=entry+sum2;
                }
            }
        }
    }
    if(VERBOSE) {
        printf("the total number of offsets is 0x%lx=%lu\n", sum, sum);
    }

    /* round up to the next even number to have the following data 32-bit-aligned */
    sum=(sum+1)&~1;
    mbcsData->countToUCodeUnits=sum;

    /* allocate the code unit array and prefill it with "unassigned" values */
    if(sum>0) {
        mbcsData->unicodeCodeUnits=(uint16_t *)uprv_malloc(sum*sizeof(uint16_t));
        if(mbcsData->unicodeCodeUnits==NULL) {
            fprintf(stderr, "error: out of memory allocating %ld 16-bit code units\n", sum);
            return FALSE;
        }
        for(i=0; i<sum; ++i) {
            mbcsData->unicodeCodeUnits[i]=0xfffe;
        }
    }

    /* allocate the codepage mappings and preset the first 16 characters to 0 */
    mbcsData->fromUBytes=(uint8_t *)uprv_malloc(0x100000*mbcsData->maxCharLength); /* 1M mappings is the maximum possible */
    if(mbcsData->fromUBytes==NULL) {
        fprintf(stderr, "error: out of memory allocating %ldMB for target mappings\n", mbcsData->maxCharLength);
        return FALSE;
    }
    uprv_memset(mbcsData->fromUBytes, 0, 16*mbcsData->maxCharLength);
    mbcsData->stage2Top=0x80;
    mbcsData->stage3Top=16*mbcsData->maxCharLength;

    return TRUE;
}

/* return TRUE for success */
static UBool
setFallback(MBCSData *mbcsData, uint32_t offset, UChar32 c) {
    _MBCSToUFallback *toUFallbacks=mbcsData->toUFallbacks;
    uint32_t i, limit;

    /* first, see if there is already a fallback for this offset */
    limit=mbcsData->header.countToUFallbacks;

    /* do a linear search for the fallback mapping (the table is not yet sorted) */
    for(i=0; i<limit; ++i) {
        if(offset==toUFallbacks[i].offset) {
            toUFallbacks[i].codePoint=c;
            return TRUE;
        }
    }

    /* if there is no fallback for this offset, then add one */
    if(limit>=MBCS_MAX_FALLBACK_COUNT) {
        fprintf(stderr, "error: too many toUnicode fallbacks, currently at: U+%lx\n", c);
        return FALSE;
    }
    toUFallbacks[limit].offset=offset;
    toUFallbacks[limit].codePoint=c;
    mbcsData->header.countToUFallbacks=limit+1;
    return TRUE;
}

/* remove fallback if there is one with this offset; return the code point if there was such a fallback, otherwise -1 */
static int32_t
removeFallback(MBCSData *mbcsData, uint32_t offset) {
    _MBCSToUFallback *toUFallbacks=mbcsData->toUFallbacks;
    uint32_t i, limit;

    /* see if there is a fallback for this offset */
    limit=mbcsData->header.countToUFallbacks;

    /* do a linear search for the fallback mapping (the table is not yet sorted) */
    for(i=0; i<limit; ++i) {
        if(offset==toUFallbacks[i].offset) {
            int32_t old=(int32_t)toUFallbacks[i].codePoint;

            /* copy the last fallback entry here to keep the list contiguous */
            toUFallbacks[i].offset=toUFallbacks[limit-1].offset;
            toUFallbacks[i].codePoint=toUFallbacks[limit-1].codePoint;
            mbcsData->header.countToUFallbacks=limit-1;
            return old;
        }
    }
    return -1;
}

/*
 * isFallback is almost a boolean:
 * 1 (TRUE)  this is a fallback mapping
 * 0 (FALSE) this is a precise mapping
 * -1        the precision of this mapping is not specified
 */
static UBool
MBCSAddToUnicode(NewConverter *cnvData,
                 const uint8_t *bytes, int32_t length,
                 UChar32 c, uint32_t b,
                 int8_t isFallback) {
    MBCSData *mbcsData=(MBCSData *)cnvData;
    uint32_t offset=0;
    int32_t i=0, entry, old;
    uint8_t state=0;

    if(mbcsData->header.countStates==0) {
        fprintf(stderr, "error: there is no state information!\n");
        return FALSE;
    }

    /*
     * Walk down the state table like in conversion,
     * much like getNextUChar().
     * We assume that c<=0x10ffff.
     */
    for(i=0;;) {
        entry=mbcsData->stateTable[state][bytes[i++]];
        if(entry>=0) {
            if(i==length) {
                fprintf(stderr, "error: byte sequence too short, ends in non-final state %hu: 0x%02lx (U+%lx)\n", state, b, c);
                return FALSE;
            }
            state=(uint8_t)(entry&0x7f);
            offset+=entry>>7;
        } else {
            if(i<length) {
                fprintf(stderr, "error: byte sequence too long by %d bytes, final state %hu: 0x%02lx (U+%lx)\n", (length-i), state, b, c);
                return FALSE;
            }
            switch((uint32_t)entry>>27U) {
            case 16|MBCS_STATE_ILLEGAL:
                fprintf(stderr, "error: byte sequence ends in illegal state at U+%04lx<->0x%02lx\n", c, b);
                return FALSE;
            case 16|MBCS_STATE_CHANGE_ONLY:
                fprintf(stderr, "error: byte sequence ends in state-change-only at U+%04lx<->0x%02lx\n", c, b);
                return FALSE;
            case 16|MBCS_STATE_UNASSIGNED:
                fprintf(stderr, "error: byte sequence ends in unassigned state at U+%04lx<->0x%02lx\n", c, b);
                return FALSE;
            case 16|MBCS_STATE_FALLBACK_DIRECT_16:
            case 16|MBCS_STATE_VALID_DIRECT_16:
            case 16|MBCS_STATE_FALLBACK_DIRECT_20:
            case 16|MBCS_STATE_VALID_DIRECT_20:
                if((entry&0x7ffff80)!=0x7fff00) {
                    /* the "direct" action's value is not "unassigned" any more */
                    if((entry&(1L<<27))==0) {
                        old=entry>>7;
                    } else {
                        old=0x10000+(entry>>7);
                    }
                    if(isFallback>=0) {
                        fprintf(stderr, "error: duplicate codepage byte sequence at U+%04lx<->0x%02lx see U+%04lx\n", c, b, old);
                        return FALSE;
                    } else if(VERBOSE) {
                        fprintf(stderr, "duplicate codepage byte sequence at U+%04lx<->0x%02lx see U+%04lx\n", c, b, old);
                    }
                    /*
                     * Continue after the above warning
                     * if the precision of the mapping is unspecified.
                     */
                }
                /* reassign the correct action code */
                entry=
                    entry&0x8000007f|
                    (MBCS_STATE_FALLBACK_DIRECT_16+(isFallback>0 ? 0 : 2)+(c>=0x10000 ? 1 : 0))
                        <<27;
                /* put the code point into bits 22..7 for BMP, c-0x10000 into 26..7 for others */
                if(c<=0xffff) {
                    entry|=c<<7;
                } else {
                    entry|=(c-0x10000)<<7;
                }
                mbcsData->stateTable[state][bytes[i-1]]=entry;
                break;
            case 16|MBCS_STATE_VALID_16:
                /* bits 26..16 are not used, 0 */
                /* bits 15..7 contain the final offset delta to one 16-bit code unit */
                offset+=(uint16_t)entry>>7;
                /* check that this byte sequence is still unassigned */
                if((old=mbcsData->unicodeCodeUnits[offset])!=0xfffe || (old=removeFallback(mbcsData, offset))!=-1) {
                    if(isFallback>=0) {
                        fprintf(stderr, "error: duplicate codepage byte sequence at U+%04lx<->0x%02lx see U+%04lx\n", c, b, old);
                        return FALSE;
                    } else if(VERBOSE) {
                        fprintf(stderr, "duplicate codepage byte sequence at U+%04lx<->0x%02lx see U+%04lx\n", c, b, old);
                    }
                }
                if(isFallback>0) {
                    /* assign only if there is no precise mapping */
                    if(mbcsData->unicodeCodeUnits[offset]==0xfffe) {
                        return setFallback(mbcsData, offset, c);
                    }
                } else {
                    if(c>=0x10000) {
                        fprintf(stderr, "error: code point does not fit into valid-16-bit state at U+%04lx<->0x%02lx\n", c, b);
                        return FALSE;
                    }
                    mbcsData->unicodeCodeUnits[offset]=(uint16_t)c;
                }
                break;
            case 16|MBCS_STATE_VALID_16_PAIR:
                /* bits 26..16 are not used, 0 */
                /* bits 15..7 contain the final offset delta to two 16-bit code units */
                if(UTF_IS_FIRST_SURROGATE(c)) {
                    fprintf(stderr, "error: cannot assign single first surrogate to surrogate-pair state at U+%04lx<->0x%02lx\n", c, b);
                    return FALSE;
                }
                offset+=(uint16_t)entry>>7;
                /* check that this byte sequence is still unassigned */
                if((old=mbcsData->unicodeCodeUnits[offset])!=0xfffe || (old=removeFallback(mbcsData, offset))!=-1) {
                    if(isFallback>=0) {
                        fprintf(stderr, "error: duplicate codepage byte sequence at U+%04lx<->0x%02lx see U+%04lx\n", c, b, old);
                        return FALSE;
                    } else if(VERBOSE) {
                        fprintf(stderr, "duplicate codepage byte sequence at U+%04lx<->0x%02lx see U+%04lx\n", c, b, old);
                    }
                }
                if(isFallback>0) {
                    /* assign only if there is no precise mapping */
                    if(mbcsData->unicodeCodeUnits[offset]==0xfffe) {
                        return setFallback(mbcsData, offset, c);
                    }
                } else {
                    if(c<=0xffff) {
                        /* set BMP code point */
                        mbcsData->unicodeCodeUnits[offset]=(uint16_t)c;
                    } else {
                        /* set a surrogate pair */
                        mbcsData->unicodeCodeUnits[offset++]=(uint16_t)(0xd7c0+(c>>10));
                        mbcsData->unicodeCodeUnits[offset]=(uint16_t)(0xdc00+(c&0x3ff));
                    }
                }
                break;
            default:
                /* reserved, must never occur */
                fprintf(stderr, "internal error: byte sequence reached reserved action code, entry0x%02lx: 0x%02lx (U+%lx)\n", entry, b, c);
                return FALSE;
            }

            return TRUE;
        }
    }
}

static UBool
MBCSAddFromUnicode(NewConverter *cnvData,
                   const uint8_t *bytes, int32_t length,
                   UChar32 c, uint32_t b,
                   int8_t isFallback) {
    MBCSData *mbcsData=(MBCSData *)cnvData;
    uint8_t *p;
    uint32_t index, old;

    /*
     * Walk down the triple-stage compact array and
     * allocate parts as necessary.
     * Note that stage 2 and 3 blocks 0 are reserved for all-unassigned mappings.
     * We assume that length<=maxCharLength and that c<=0x10ffff.
     */

    /* inspect stage 1 */
    index=c>>10;
    if(mbcsData->table[index]==0) {
        /* allocate another block in stage 2 */
        if(mbcsData->stage2Top==2*0xffc0) {
            fprintf(stderr, "error: too many code points at U+%04lx<->0x%02lx\n", c, b);
            return FALSE;
        }
        /*
         * each block has 64*2 entries:
         * 6 code point bits 9..4 with 1 flags value and 1 stage 3 index
         * stage 1 values are half of the indexes to the stage 2 blocks
         * so that they fit into 16 bits;
         * therefore, stage 1 values increase only by 64 per stage 2 block
         */
        mbcsData->table[index]=(uint16_t)(mbcsData->stage2Top/2);
        mbcsData->stage2Top+=0x80;
    }

    /* inspect stage 2 */
    index=0x440+2*((uint32_t)mbcsData->table[index]+((c>>4)&0x3f));
    if(mbcsData->table[index+1]==0) {
        /* allocate another block in stage 3 */
        if(mbcsData->stage3Top+16*mbcsData->maxCharLength>=0x100000) {
            fprintf(stderr, "error: too many code points at U+%04lx<->0x%02lx\n", c, b);
            return FALSE;
        }
        /* each block has 16*maxCharLength bytes */
        mbcsData->table[index+1]=(uint16_t)((mbcsData->stage3Top/16)/mbcsData->maxCharLength);
        uprv_memset(mbcsData->fromUBytes+mbcsData->stage3Top, 0, 16*mbcsData->maxCharLength);
        mbcsData->stage3Top+=16*mbcsData->maxCharLength;
    }

    /* write the codepage bytes into stage 3 and get the previous bytes */
    old=0;
    p=mbcsData->fromUBytes+(16*(uint32_t)mbcsData->table[index+1]+(c&0xf))*mbcsData->maxCharLength;
    switch(mbcsData->maxCharLength) {
    case 4:
        old=*p;
        *p++=(uint8_t)(b>>24);
    case 3:
        old=(old<<8)|*p;
        *p++=(uint8_t)(b>>16);
    case 2:
        old=(old<<8)|*p;
        *p++=(uint8_t)(b>>8);
    case 1:
        old=(old<<8)|*p;
        *p=(uint8_t)b;
    default:
        break;
    }

    /* check that this Unicode code point was still unassigned */
    if((mbcsData->table[index]&(1<<(c&0xf)))!=0 || old!=0) {
        if(isFallback>=0) {
            fprintf(stderr, "error: duplicate Unicode code point at U+%04lx<->0x%02lx see 0x%02lx\n", c, b, old);
            return FALSE;
        } else if(VERBOSE) {
            fprintf(stderr, "duplicate Unicode code point at U+%04lx<->0x%02lx see 0x%02lx\n", c, b, old);
        }
        /* continue after the above warning if the precision of the mapping is unspecified */
    }
    if(isFallback<=0) {
        /* set the "assigned" flag */
        mbcsData->table[index]|=(1<<(c&0xf));
    }

    return TRUE;
}

static int
compareFallbacks(const void *fb1, const void *fb2) {
    return ((const _MBCSToUFallback *)fb1)->offset-((const _MBCSToUFallback *)fb2)->offset;
}

static UBool
MBCSTransformEUC(MBCSData *mbcsData) {
    uint8_t *p, *q;
    uint32_t i, oldLength=mbcsData->maxCharLength, old3Top=mbcsData->stage3Top, new3Top;
    uint8_t b;

    if(oldLength<3) {
        return FALSE;
    }

    /* test if all first bytes are in {0, 0x8e, 0x8f} */
    p=mbcsData->fromUBytes;
    for(i=0; i<old3Top; i+=oldLength) {
        b=p[i];
        if(b!=0 && b!=0x8e && b!=0x8f) {
            /* some first byte does not fit the EUC pattern, nothing to be done */
            return FALSE;
        }
    }

    /* modify outputType and adjust stage3Top */
    mbcsData->header.flags=MBCS_OUTPUT_3_EUC+oldLength-3;
    mbcsData->stage3Top=new3Top=(old3Top*(oldLength-1))/oldLength;

    /*
     * EUC-encode all byte sequences;
     * see "CJKV Information Processing" (1st ed. 1999) from Ken Lunde, O'Reilly,
     * p. 161 in chapter 4 "Encoding Methods"
     */
    q=p;
    for(i=0; i<old3Top; i+=oldLength) {
        b=*p++;
        if(b==0) {
            /* short sequences are stored directly */
            /* code set 0 or 1 */
            *q++=*p++;
            *q++=*p++;
        } else if(b==0x8e) {
            /* code set 2 */
            *q++=(uint8_t)(*p++&0x7f);
            *q++=*p++;
        } else /* b==0x8f */ {
            /* code set 3 */
            *q++=*p++;
            *q++=(uint8_t)(*p++&0x7f);
        }
        if(oldLength==4) {
            *q++=*p++;
        }
    }

    return TRUE;
}

static void
MBCSPostprocess(NewConverter *cnvData, const UConverterStaticData *staticData) {
    MBCSData *mbcsData=(MBCSData *)cnvData;
    int32_t entry;
    int state, cell;

    /* this needs to be printed before the EUC transformation because later maxCharLength might not be correct */
    if(VERBOSE) {
        printf("number of codepage characters in 16-blocks: 0x%lx=%lu\n",
               mbcsData->stage3Top/mbcsData->maxCharLength,
               mbcsData->stage3Top/mbcsData->maxCharLength);
    }

    /* test each state table entry */
    for(state=0; state<(int)mbcsData->header.countStates; ++state) {
        for(cell=0; cell<256; ++cell) {
            entry=mbcsData->stateTable[state][cell];
            /*
             * if the entry is a final one with a "...-direct" action code
             * and the code point is "unassigned" (0xfffe), then change it to
             * the "unassigned" action code with bits 26..7 set to zero.
             */
            if( ((uint32_t)(((entry&0xf8000000)>>27U)-(16|MBCS_STATE_FALLBACK_DIRECT_16))<=3) &&
                (entry&0x7ffff80)==0x7fff00
            ) {
                mbcsData->stateTable[state][cell]=(entry&0x8000007f)|(MBCS_STATE_UNASSIGNED<<27UL);
            }
        }
    }

    /* sort toUFallbacks */
    if(mbcsData->header.countToUFallbacks>0) {
        qsort(mbcsData->toUFallbacks, mbcsData->header.countToUFallbacks, sizeof(_MBCSToUFallback), compareFallbacks);
    }

    MBCSTransformEUC(mbcsData);
}

static uint32_t
MBCSWrite(NewConverter *cnvData, const UConverterStaticData *staticData, UNewDataMemory *pData) {
    MBCSData *mbcsData=(MBCSData *)cnvData;
    /* fill the header */
    mbcsData->header.offsetToUCodeUnits=
        sizeof(_MBCSHeader)+
        mbcsData->header.countStates*1024+
        mbcsData->header.countToUFallbacks*sizeof(_MBCSToUFallback);
    mbcsData->header.offsetFromUTable=
        mbcsData->header.offsetToUCodeUnits+
        mbcsData->countToUCodeUnits*2;
    mbcsData->header.offsetFromUBytes=
        mbcsData->header.offsetFromUTable+
        (0x440+mbcsData->stage2Top)*2;

    /* write the MBCS data */
    udata_writeBlock(pData, &mbcsData->header, sizeof(_MBCSHeader));
    udata_writeBlock(pData, mbcsData->stateTable, mbcsData->header.countStates*1024);
    udata_writeBlock(pData, mbcsData->toUFallbacks, mbcsData->header.countToUFallbacks*sizeof(_MBCSToUFallback));
    udata_writeBlock(pData, mbcsData->unicodeCodeUnits, mbcsData->countToUCodeUnits*2);
    udata_writeBlock(pData, mbcsData->table, (0x440+mbcsData->stage2Top)*2);
    udata_writeBlock(pData, mbcsData->fromUBytes, mbcsData->stage3Top);

    /* return the number of bytes that should have been written */
    return mbcsData->header.offsetFromUBytes+mbcsData->stage3Top;
}

#if 0
    /* test code, uses only this file and genmbcs.h */

extern int
main(int argc, const char *argv[]) {
    MBCSData *mbcsData;
    static uint8_t bytes[4];
    int32_t entry;
    int i, j;

    /*
     * sample arguments for shift-jis (max 2):
     * 0-7f,81-9f:1,a1-df,e0-ef:1  40-7e,80-fc
     *
     * sample arguments for euc-jp (max 3):
     * 0-7f,8e:2,8f:3,a1-fe:1  a1-fe  a1-df  a1-fe:1
     */
    if(argc>=2) {
        mbcsData=MBCSOpen(3);

        for(i=1; i<argc; ++i) {
            if(!MBCSAddState(mbcsData, argv[i])) {
                return 2;
            }
        }
        MBCSProcessStates(mbcsData);

        bytes[0]=0x5c;
        MBCSAddToUnicode(mbcsData, bytes, 1, 0xa5, TRUE);
        MBCSAddFromUnicode(mbcsData, bytes, 1, 0xa5, TRUE);
        bytes[0]=0xe2;
        bytes[1]=0xa3;
        MBCSAddToUnicode(mbcsData, bytes, 2, 0x4e00, FALSE);
        MBCSAddFromUnicode(mbcsData, bytes, 2, 0x4e00, FALSE);
        bytes[0]=0x8e;
        bytes[1]=0xdf;
        MBCSAddToUnicode(mbcsData, bytes, 2, 0x3415, FALSE);
        MBCSAddFromUnicode(mbcsData, bytes, 2, 0x3415, FALSE);
        bytes[0]=0x8f;
        bytes[1]=0xbb;
        bytes[2]=0xcc;
        MBCSAddToUnicode(mbcsData, bytes, 3, 0x9876, FALSE);
        MBCSAddFromUnicode(mbcsData, bytes, 3, 0x9876, FALSE);

        MBCSPostprocess(mbcsData, NULL);

        for(i=0; i<(int)mbcsData->header.countStates; ++i) {
            printf("state=%x: flags=%x\n", i, mbcsData->stateFlags[i]);
            for(j=0; j<256; ++j) {
                entry=mbcsData->stateTable[i][j];
                printf("%2lx  %8lx = %u.%x.%5x.%2x\n", j, entry,
                       (uint32_t)entry>>31, entry>>27&0xf, entry>>7&0xfffff, entry&0x7f);
            }
        }

        MBCSClose(mbcsData);
    } else {
        fprintf(stderr, "error: missing state table arguments\n");
        return 1;
    }
    return 0;
}
#endif
