#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "CP932.h2"

//--------------------stdlib.h------------------

int cp932towcs(const char *p1, int n, wchar_t *unicode){
	int left = 0;
	int right = sizeof(cp932_unicode) / sizeof(cp932_unicode[0]);
	int cp932 = 0;
	int ret = 0;
	unsigned char *p = (unsigned char *)p1;
	unsigned char c = *p;
	//fprintf(stderr, "c:%02X\n", *p);
	if(c < 0x7f){
		*unicode = c;
		return 1;
	}else if (c >= 0xa1 && c <= 0xdf){
		cp932 = c;
		ret = 1;
	}else{
		if(n < 2){
			return 0;
		}
		cp932 = p[1] | (p[0] << 8);
		//fprintf(stderr, "p:%p\n", cp932);
		ret = 2;
	}
	*unicode = 0;
	while(1){
		if(right <= left){
			break;
		}
		int mid = (right + left) / 2;
		//printf("r:%04X(%04X) l:%04X(%04X) m:%04X(%04X)\n", right, cp932_unicode[right].cp932, left, cp932_unicode[left].cp932, mid, cp932_unicode[mid].cp932);
		if(cp932_unicode[mid].cp932 < cp932){
			left = mid + 1;
		}else if(cp932_unicode[mid].cp932 > cp932){
			right = mid;
		}else{
			*unicode = cp932_unicode[mid].unicode;
			break;
		}
	}
	if(*unicode == 0){
		return 0;
	}
	return ret;
}

size_t mbstowcs(wchar_t *dest, const char *src, size_t n){
	if(dest != NULL){
		size_t p = 0;
		for(;;){
			int r = cp932towcs(src, 10, dest + p);
			if(r == 0){
				return (size_t)-1;
			}
			if(dest[p] == 0){
				return p;
			}
			if(p >= n - 1){
				return n;
			}
			p++;

			src += r;
		}
	}else{
		size_t p = 0;
		for(;;){
			wchar_t u;
			int r = cp932towcs(src, 10, &u);
			if(r == 0){
				return (size_t)-1;
			}
			if(u == 0){
				return p;
			}
			p++;

			src += r;
		}
	}
}

//----------------------string.h--------------------------


int wcslen(const wchar_t *p){
	int len = 0;
	while(p[len++]);
	return len - 1;
}

wchar_t *wcsncpy(wchar_t *dest, const wchar_t *src, int n){
	for(int i = 0; i < n; i++){
		if(!(dest[i] = src[i])){
			break;
		}
	}
	return dest;
}

int wcsicmp(const wchar_t *s1, const wchar_t *s2){
	int i;
	for(i = 0; towlower(s1[i]) == towlower(s2[i]); i++){
		if(s1[i] == L'\0' || s2[i] == L'\0'){
			return (int)s1[i] - (int)s2[i];
		}
	}
	return (int)towlower(s1[i]) - (int)towlower(s2[i]);
}
