|
int file2wcs (int fd, const char *charset, wchar_t *outbuf, size_t avail) { char inbuf[BUFSIZ]; size_t insize = 0; char *wrptr = (char *) outbuf; int result = 0; iconv_t cd; cd = iconv_open ("WCHAR_T", charset); if (cd == (iconv_t) -1) { /* Yanlış giden birşeyler olabilir. */ if (errno == EINVAL) error (0, 0, "'%s' için wchar_t cinsinden bir karşılık yok", charset); else perror ("iconv_open"); /* Çıktı dizgesini sonlandıralım. */ *outbuf = L'\0'; return -1; } while (avail > 0) { size_t nread; size_t nconv; char *inptr = inbuf; /* Girdinin kalanını okuyalım. */ nread = read (fd, inbuf + insize, sizeof (inbuf) - insize); if (nread == 0) { /* Buraya gelimişsek okuma tamamlanmıştır. Ama hala inbuf içinde kullanılmamış karakterler kalmış olabilir. Onları geri koyalım. */ if (lseek (fd, -insize, SEEK_CUR) == -1) result = -1; /* Gerekliyse, ilk duruma girecek bayt dizilimini yazalım. */ iconv (cd, NULL, NULL, &wrptr, &avail); break; } insize += nread; /* Dönüşümü yapalım. */ nconv = iconv (cd, &inptr, &insize, &wrptr, &avail); if (nconv == (size_t) -1) { /* Herşey yolunda gitmez. Tamponun sonunda bitmemiş bir bayt dizilimi olabilir. Kimi zaman da gerçekten önemli bir sorun olabilir. if (errno == EINVAL) /* Bu zararsız. Kullanılmayan baytları tamponun başına taşıyalım ki, sonraki adımda onlar kullanılabilsin. */ memmove (inbuf, inptr, insize); else { /* Bu gerçekten bir sorun. Ya çıktı tamponu yetersiz ya da girdi geçersizdir. Her durumda, dosya göstericisini işlenen son baytın konumuna ayarlayacağız. */ lseek (fd, -insize, SEEK_CUR); result = -1; break; } } } /* Çıktı dizgesini sonlandıralım. */ if (avail >= sizeof (wchar_t)) *((wchar_t *) wrptr) = L'\0'; if (iconv_close (cd) != 0) perror ("iconv_close"); return (wchar_t *) wrptr - outbuf; }
|