ds2.10/bin/
ds2.10/extra/
ds2.10/extra/crat/
ds2.10/extra/creremote/
ds2.10/extra/mingw/
ds2.10/extra/wolfpaw/
ds2.10/fluffos-2.16-ds05/
ds2.10/fluffos-2.16-ds05/Win32/
ds2.10/fluffos-2.16-ds05/compat/
ds2.10/fluffos-2.16-ds05/compat/simuls/
ds2.10/fluffos-2.16-ds05/include/
ds2.10/fluffos-2.16-ds05/testsuite/
ds2.10/fluffos-2.16-ds05/testsuite/clone/
ds2.10/fluffos-2.16-ds05/testsuite/command/
ds2.10/fluffos-2.16-ds05/testsuite/data/
ds2.10/fluffos-2.16-ds05/testsuite/etc/
ds2.10/fluffos-2.16-ds05/testsuite/include/
ds2.10/fluffos-2.16-ds05/testsuite/inherit/
ds2.10/fluffos-2.16-ds05/testsuite/inherit/master/
ds2.10/fluffos-2.16-ds05/testsuite/log/
ds2.10/fluffos-2.16-ds05/testsuite/single/
ds2.10/fluffos-2.16-ds05/testsuite/single/tests/compiler/
ds2.10/fluffos-2.16-ds05/testsuite/single/tests/efuns/
ds2.10/fluffos-2.16-ds05/testsuite/single/tests/operators/
ds2.10/fluffos-2.16-ds05/testsuite/u/
ds2.10/lib/cmds/admins/
ds2.10/lib/cmds/common/
ds2.10/lib/cmds/creators/include/
ds2.10/lib/daemon/services/
ds2.10/lib/daemon/tmp/
ds2.10/lib/doc/
ds2.10/lib/doc/bguide/
ds2.10/lib/doc/efun/all/
ds2.10/lib/doc/efun/arrays/
ds2.10/lib/doc/efun/buffers/
ds2.10/lib/doc/efun/compile/
ds2.10/lib/doc/efun/floats/
ds2.10/lib/doc/efun/functions/
ds2.10/lib/doc/efun/general/
ds2.10/lib/doc/efun/mixed/
ds2.10/lib/doc/efun/numbers/
ds2.10/lib/doc/efun/parsing/
ds2.10/lib/doc/help/classes/
ds2.10/lib/doc/help/races/
ds2.10/lib/doc/lfun/
ds2.10/lib/doc/lfun/all/
ds2.10/lib/doc/lfun/lib/abilities/
ds2.10/lib/doc/lfun/lib/armor/
ds2.10/lib/doc/lfun/lib/bank/
ds2.10/lib/doc/lfun/lib/bot/
ds2.10/lib/doc/lfun/lib/clay/
ds2.10/lib/doc/lfun/lib/clean/
ds2.10/lib/doc/lfun/lib/clerk/
ds2.10/lib/doc/lfun/lib/client/
ds2.10/lib/doc/lfun/lib/combat/
ds2.10/lib/doc/lfun/lib/connect/
ds2.10/lib/doc/lfun/lib/container/
ds2.10/lib/doc/lfun/lib/corpse/
ds2.10/lib/doc/lfun/lib/creator/
ds2.10/lib/doc/lfun/lib/daemon/
ds2.10/lib/doc/lfun/lib/damage/
ds2.10/lib/doc/lfun/lib/deterioration/
ds2.10/lib/doc/lfun/lib/donate/
ds2.10/lib/doc/lfun/lib/door/
ds2.10/lib/doc/lfun/lib/equip/
ds2.10/lib/doc/lfun/lib/file/
ds2.10/lib/doc/lfun/lib/fish/
ds2.10/lib/doc/lfun/lib/fishing/
ds2.10/lib/doc/lfun/lib/flashlight/
ds2.10/lib/doc/lfun/lib/follow/
ds2.10/lib/doc/lfun/lib/ftp_client/
ds2.10/lib/doc/lfun/lib/ftp_data_connection/
ds2.10/lib/doc/lfun/lib/fuel/
ds2.10/lib/doc/lfun/lib/furnace/
ds2.10/lib/doc/lfun/lib/genetics/
ds2.10/lib/doc/lfun/lib/holder/
ds2.10/lib/doc/lfun/lib/id/
ds2.10/lib/doc/lfun/lib/interactive/
ds2.10/lib/doc/lfun/lib/lamp/
ds2.10/lib/doc/lfun/lib/leader/
ds2.10/lib/doc/lfun/lib/light/
ds2.10/lib/doc/lfun/lib/limb/
ds2.10/lib/doc/lfun/lib/living/
ds2.10/lib/doc/lfun/lib/load/
ds2.10/lib/doc/lfun/lib/look/
ds2.10/lib/doc/lfun/lib/manipulate/
ds2.10/lib/doc/lfun/lib/meal/
ds2.10/lib/doc/lfun/lib/messages/
ds2.10/lib/doc/lfun/lib/player/
ds2.10/lib/doc/lfun/lib/poison/
ds2.10/lib/doc/lfun/lib/position/
ds2.10/lib/doc/lfun/lib/post_office/
ds2.10/lib/doc/lfun/lib/potion/
ds2.10/lib/doc/lfun/lib/room/
ds2.10/lib/doc/lfun/lib/server/
ds2.10/lib/doc/lfun/lib/spell/
ds2.10/lib/doc/lfun/lib/torch/
ds2.10/lib/doc/lfun/lib/vendor/
ds2.10/lib/doc/lfun/lib/virt_sky/
ds2.10/lib/doc/lfun/lib/weapon/
ds2.10/lib/doc/lfun/lib/worn_storage/
ds2.10/lib/doc/lpc/constructs/
ds2.10/lib/doc/lpc/etc/
ds2.10/lib/doc/lpc/intermediate/
ds2.10/lib/doc/lpc/types/
ds2.10/lib/doc/misc/
ds2.10/lib/doc/old/
ds2.10/lib/doc/phints/
ds2.10/lib/domains/
ds2.10/lib/domains/Praxis/adm/
ds2.10/lib/domains/Praxis/attic/
ds2.10/lib/domains/Praxis/cemetery/mon/
ds2.10/lib/domains/Praxis/data/
ds2.10/lib/domains/Praxis/death/
ds2.10/lib/domains/Praxis/mountains/
ds2.10/lib/domains/Praxis/obj/armour/
ds2.10/lib/domains/Praxis/obj/magic/
ds2.10/lib/domains/Praxis/obj/weapon/
ds2.10/lib/domains/Praxis/orc_valley/
ds2.10/lib/domains/Ylsrim/
ds2.10/lib/domains/Ylsrim/adm/
ds2.10/lib/domains/Ylsrim/armor/
ds2.10/lib/domains/Ylsrim/broken/
ds2.10/lib/domains/Ylsrim/fish/
ds2.10/lib/domains/Ylsrim/meal/
ds2.10/lib/domains/Ylsrim/npc/
ds2.10/lib/domains/Ylsrim/obj/
ds2.10/lib/domains/Ylsrim/virtual/
ds2.10/lib/domains/Ylsrim/weapon/
ds2.10/lib/domains/alpha/room/
ds2.10/lib/domains/alpha/virtual/
ds2.10/lib/domains/campus/adm/
ds2.10/lib/domains/campus/etc/
ds2.10/lib/domains/campus/meals/
ds2.10/lib/domains/campus/txt/ai/charles/
ds2.10/lib/domains/campus/txt/ai/charles/bak2/
ds2.10/lib/domains/campus/txt/ai/charles/bak2/bak1/
ds2.10/lib/domains/campus/txt/ai/charly/
ds2.10/lib/domains/campus/txt/ai/charly/bak/
ds2.10/lib/domains/campus/txt/jenny/
ds2.10/lib/domains/cave/doors/
ds2.10/lib/domains/cave/etc/
ds2.10/lib/domains/cave/meals/
ds2.10/lib/domains/cave/weap/
ds2.10/lib/domains/default/chamber/
ds2.10/lib/domains/default/creator/
ds2.10/lib/domains/default/doors/
ds2.10/lib/domains/default/etc/
ds2.10/lib/domains/default/vehicle/
ds2.10/lib/domains/default/virtual/
ds2.10/lib/domains/town/save/
ds2.10/lib/domains/town/txt/shame/
ds2.10/lib/domains/town/virtual/
ds2.10/lib/domains/town/virtual/bottom/
ds2.10/lib/domains/town/virtual/space/
ds2.10/lib/estates/
ds2.10/lib/ftp/
ds2.10/lib/lib/comp/
ds2.10/lib/lib/daemons/
ds2.10/lib/lib/daemons/include/
ds2.10/lib/lib/lvs/
ds2.10/lib/lib/user/
ds2.10/lib/lib/virtual/
ds2.10/lib/log/
ds2.10/lib/log/adm/
ds2.10/lib/log/archive/
ds2.10/lib/log/chan/
ds2.10/lib/log/errors/
ds2.10/lib/log/law/adm/
ds2.10/lib/log/law/email/
ds2.10/lib/log/law/names/
ds2.10/lib/log/law/sites-misc/
ds2.10/lib/log/law/sites-register/
ds2.10/lib/log/law/sites-tempban/
ds2.10/lib/log/law/sites-watch/
ds2.10/lib/log/open/
ds2.10/lib/log/reports/
ds2.10/lib/log/router/
ds2.10/lib/log/secure/
ds2.10/lib/log/watch/
ds2.10/lib/obj/book_source/
ds2.10/lib/obj/include/
ds2.10/lib/powers/prayers/
ds2.10/lib/powers/spells/
ds2.10/lib/realms/template/
ds2.10/lib/realms/template/adm/
ds2.10/lib/realms/template/area/
ds2.10/lib/realms/template/area/armor/
ds2.10/lib/realms/template/area/npc/
ds2.10/lib/realms/template/area/obj/
ds2.10/lib/realms/template/area/room/
ds2.10/lib/realms/template/area/weap/
ds2.10/lib/realms/template/bak/
ds2.10/lib/realms/template/cmds/
ds2.10/lib/save/kills/o/
ds2.10/lib/secure/cfg/classes/
ds2.10/lib/secure/cmds/builders/
ds2.10/lib/secure/cmds/creators/include/
ds2.10/lib/secure/cmds/players/include/
ds2.10/lib/secure/daemon/imc2server/
ds2.10/lib/secure/daemon/include/
ds2.10/lib/secure/lib/
ds2.10/lib/secure/lib/include/
ds2.10/lib/secure/lib/net/include/
ds2.10/lib/secure/lib/std/
ds2.10/lib/secure/log/adm/
ds2.10/lib/secure/log/bak/
ds2.10/lib/secure/log/intermud/
ds2.10/lib/secure/log/network/
ds2.10/lib/secure/modules/
ds2.10/lib/secure/npc/
ds2.10/lib/secure/obj/include/
ds2.10/lib/secure/room/
ds2.10/lib/secure/save/
ds2.10/lib/secure/save/backup/
ds2.10/lib/secure/save/boards/
ds2.10/lib/secure/save/players/g/
ds2.10/lib/secure/tmp/
ds2.10/lib/secure/upgrades/files/
ds2.10/lib/secure/verbs/creators/
ds2.10/lib/std/board/
ds2.10/lib/std/lib/
ds2.10/lib/verbs/admins/include/
ds2.10/lib/verbs/builders/
ds2.10/lib/verbs/common/
ds2.10/lib/verbs/common/include/
ds2.10/lib/verbs/creators/
ds2.10/lib/verbs/creators/include/
ds2.10/lib/verbs/rooms/
ds2.10/lib/verbs/rooms/include/
ds2.10/lib/www/client/
ds2.10/lib/www/errors/
ds2.10/lib/www/images/
ds2.10/win32/
#include "fliconv.h"
#include <errno.h>
#include "std.h"
#include "lpc_incl.h"
#include "comm.h"

#ifdef USE_ICONV

struct translation *head;

static struct translation *find_translator(const char *encoding){
    struct translation *cur = head;
    while(cur){
        if(!strcmp(cur->name, encoding))
            break;
        cur = cur->next;
    }
    return cur;
}


struct translation *get_translator(const char *encoding){
    struct translation *ret = find_translator(encoding);
    if(ret)
        return ret;
    ret = (struct translation *)MALLOC(sizeof(struct translation));
    char *name = (char *)MALLOC(strlen(encoding)+18+1);
    strcpy(name, encoding);
#ifdef linux
    strcat(name, "//TRANSLIT//IGNORE");
#endif
    ret->name = name;
    ret->incoming = iconv_open("UTF-8", encoding);
    ret->outgoing = iconv_open(name, "UTF-8");

    ret->next = 0;
    if(ret->incoming == (iconv_t)-1 || ret->outgoing == (iconv_t)-1){
        FREE(name);
        FREE(ret);
        return 0;
    }
    name[strlen(encoding)] = 0;
    if(!head)
        head = ret;
    else {
        struct translation *cur = head;
        while(cur->next)
            cur = cur->next;
        cur->next = ret;
    }
    return ret;
}

char *translate(iconv_t tr, const char *mes, int inlen, int *outlen){
    size_t len = inlen;
    size_t len2;
    unsigned char *tmp = (unsigned char *)mes;
    static char *res = 0;
    static size_t reslen = 0;
    char *tmp2;

    if(!res){
        res = (char *)MALLOC(1);
        reslen = 1;
    }

    tmp2 = res;
    len2 = reslen;

    while(len){
        iconv(tr, (char **)&tmp, &len, &tmp2, &len2);
#ifdef PACKAGE_DWLIB
        if(len > 1 && tmp[0] == 0xff && tmp[1] == 0xf9){
            len -=2;
            tmp +=2;
#else
            if(0){
#endif
            } else {

                if(E2BIG == errno){
                    errno = 0;
                    tmp = (unsigned char *)mes;
                    len = strlen(mes)+1;
                    FREE(res);
                    reslen *= 2;
                    res = (char *)MALLOC(reslen);
                    tmp2 = res;
                    len2 = reslen;
                    continue;
                }
                tmp2[0] = 0;
                *outlen = reslen - len2;
                return res;
            }

        }
        *outlen = reslen - len2;
        return res;
    }

#else
    char *translate(iconv_t tr, const char *mes, int inlen, int *outlen){
        *outlen = inlen;
        return (char *)mes;
    }
#endif



    char *translate_easy(iconv_t tr, char *mes){
        int dummy;
        char *res = translate(tr, mes, strlen(mes)+1, &dummy);
        return res;
    }



#ifdef F_SET_ENCODING
    void f_set_encoding(){
        if(current_object->interactive){
            struct translation *newt = get_translator((char *)sp->u.string);
            if(newt){
                current_object->interactive->trans = newt;
                return;
            }
        }
        pop_stack();
        push_number(0);
    }
#endif

#ifdef F_TO_UTF8
    void f_to_utf8(){
        struct translation *newt = get_translator((char *)sp->u.string);
        pop_stack();
        if(!newt)
            error("unknown encoding");
        char *text = (char *)sp->u.string;
        char *translated = translate_easy(newt->incoming, text);
        pop_stack();
        copy_and_push_string(translated);
    }
#endif

#ifdef F_UTF8_TO
    void f_utf8_to(){
        struct translation *newt = get_translator((char *)sp->u.string);
        pop_stack();
        if(!newt)
            error("unknown encoding");
        char *text = (char *)sp->u.string;
        char *translated = translate_easy(newt->outgoing, text);
        pop_stack();
        copy_and_push_string(translated);
    }
#endif

#ifdef F_STR_TO_ARR
    void f_str_to_arr(){
        static struct translation *newt = 0;
        if(!newt){
            newt = get_translator("UTF-32");
            translate_easy(newt->outgoing, " ");
        }
        int len;
        int *trans = (int *)translate(newt->outgoing, sp->u.string, SVALUE_STRLEN(sp)+1, &len);
        len/=4;
        array_t *arr = allocate_array(len);
        while(len--)
            arr->item[len].u.number = trans[len];
        free_svalue(sp, "str_to_arr");
        put_array(arr);
    }

#endif

#ifdef F_ARR_TO_STR
    void f_arr_to_str(){
        static struct translation *newt = 0;
        if(!newt){
            newt = get_translator("UTF-32");
        }
        int len = sp->u.arr->size;
        int *in = (int *)MALLOC(sizeof(int)*(len+1));
        char *trans;
        in[len] = 0;
        while(len--)
            in[len] = sp->u.arr->item[len].u.number;

        trans = translate(newt->incoming, (char *)in, (sp->u.arr->size+1)*4, &len);
        FREE(in);
        pop_stack();
        copy_and_push_string(trans);
    }

#endif

#ifdef F_STRWIDTH
    void f_strwidth(){
        int len = SVALUE_STRLEN(sp);
        int width = 0;
        int i;
        for(i=0; i<len; i++)
            width += !(((sp->u.string[i]) & 0xc0) == 0x80);
        pop_stack();
        push_number(width);
    }

#endif