📄 ckcfns.c
字号:
static int save = 0; /* For CRLF */ static char ** ap = NULL; /* Array pointer */ static char * p = NULL; /* Character pointer */ static int i = 0, n = 0; /* Array index and limit */ extern int a_dim[]; /* Array dimension */ int x = 1; if (!ap) { /* First time thru */ ap = sndarray; /* Set up array pointers */ if (!ap || (i = sndxlo) > a_dim[sndxin]) { sndarray = NULL; ap = NULL; return(-1); } p = ap[i]; /* Point to first element in range */ n = sndxhi; /* Index of last element in range */ if (sndxhi > a_dim[sndxin]) /* Adjust if necessary */ n = a_dim[sndxin]; } if (save) { /* If anything saved */ c = save; /* unsave it */ save = 0; /* and return it */ return(c & 0xff); } if (i > n) { /* No more elements */ sndarray = NULL; ap = NULL; return(-1); } if (!p) /* Source pointer is NULL */ c = NUL; /* this means an empty line */ else /* Source pointer not NULL */ c = *p++; /* Next char */ if (!c) { /* Char is empty? */ if (!binary) { /* Text: end of line. */ if (feol) { /* Supply NL */ c = feol; } else { /* or CRLF */ save = LF; c = CR; } p = ap[++i]; return(c & 0xff); } while (i++ < n) { /* Binary - get next element */ p = ap[i]; if (!p) /* Empty line? */ continue; /* Ignore it and get another */ c = *p++; /* Get next char */ if (!c) /* Emtpy char? */ continue; /* Ignore it and get another */ return(c & 0xff); /* Not empty - return it */ } sndarray = NULL; ap = NULL; return(-1); /* Done */ } return(c & 0xff); /* Char is not empty */#else sndarray = NULL; return(-1);#endif /* NOSPL */}#endif /* NOXFER */#ifndef NOCSETSstatic CHAR xlabuf[32] = { 0, 0, 0, 0, 0, 0, 0, 0 };static int xlacount = 0;static int xlaptr = 0;static USHORT lastucs2 = 0;/* X G N B Y T E -- Get next translated byte from the input file. Returns the next byte that is to be put into the packet, already translated. This isolates getpkt() from having to know anything about translation, single- vs multibyte character sets, one-to-many vs many-to-one, etc, but it has rather high overhead, so don't call it unless you know translation is needed to or from Unicode, Japanese, or other multibyte character set. Call with: fcs: File character set (source, file we are reading from) tcs: Target character set (use an FC_xxx code, not a TC_xxx code) Returns: >= 0: A translated byte suitable for writing. < 0: Fatal error (such as EOF on input source).*/intxgnbyte(tcs,fcs) int tcs, fcs; { _PROTOTYP( int (*xx), (USHORT) ) = NULL;#ifdef UNICODE extern int ucsorder; /* SET FILE UCS BYTE-ORDER */#endif /* UNICODE */ int haveuc = 0; /* Flag for have Unicode character */#ifdef KANJI int havesj = 0; /* Have Shift-JIS character */ int haveeu = 0; /* Have EUC-JP character */#endif /* KANJI */ int rc = -1, x = 0, flag = 0; int utferror = 0; int eolflag = 0; unsigned int xc, thischar; static int swapping = 0; CHAR rt; USHORT ch;#ifdef UNICODE union ck_short uc;#endif /* UNICODE */#ifdef KANJI union ck_short sj, eu; /* Shift-JIS character */#endif /* KANJI */#ifdef KANJI sj.x_short = 0;#endif /* KANJI */ if (xlacount-- > 0) { /* We already have some */ x = xlabuf[xlaptr++]; debug(F001,"xgnbyte SEND from buf","",x); return(x); } if (xlatype != XLA_NONE) { /* Not not translating... */ haveuc = 0;#ifdef UNICODE if (fcs == FC_UCS2) { /* UCS-2: Read two bytes */ if (ffc == 0) { /* Beginning of file? */ swapping = 0; /* Reset byte-swapping flag */ } uc.x_short = 0; bomskip: x = zminchar(); /* Get first byte */ flag = 1; /* Remember we called zminchar() */ if (x > -1) { /* Didn't fail */ ffc++; /* Count a file byte */ uc.x_char[swapping] = x & 0xff;#ifndef NOXFER if (docrc && what == W_SEND) dofilcrc(x);#endif /* NOXFER */ if ((x = zminchar()) > -1) { /* If didn't fail */ ffc++; /* count another file byte */ uc.x_char[1-swapping] = x & 0xff; haveuc = 1; /* And remember we have Unicode */#ifndef NOXFER if (docrc && what == W_SEND) dofilcrc(x);#endif /* NOXFER */ if (ffc == 2) { /* Second char of file */ debug(F001,"xgnbyte 1st UCS2","",uc.x_short); if (uc.x_short == (USHORT)0xfeff) { swapping = 0; debug(F101, "xgnbyte UCS2 goodbom swap","",swapping); goto bomskip; } else if (uc.x_short == (USHORT)0xfffe) { swapping = 1; debug(F101, "xgnbyte UCS2 badbom swap","",swapping); goto bomskip; } else if ((byteorder && !ucsorder) || (!byteorder && ucsorder)) { CHAR c; c = uc.x_char[0]; uc.x_char[0] = uc.x_char[1]; uc.x_char[1] = c; swapping = 1; debug(F101, "xgnbyte UCS2 no BOM X swap","",swapping); } else { swapping = 0; debug(F101, "xgnbyte UCS2 no BOM Y swap","",swapping); } } } else return(x); } else return(x); debug(F001,"xgnbyte UCS2","",uc.x_short); } else if (fcs == FC_UTF8) { /* File is UTF-8 */ CHAR ch = 0; /* Data types needed for API... */ USHORT * us = NULL; uc.x_short = 0; flag = 1; /* We (will) have called zminchar() */ while ((x = zminchar()) > -1) { /* Read source bytes */ ffc++; /* Got a byte - count it */#ifndef NOXFER if (docrc && what == W_SEND) dofilcrc(x);#endif /* NOXFER */ ch = x; rc = utf8_to_ucs2(ch,&us); /* Convert to UCS-2 */ if (rc == 0) { /* Done */ uc.x_short = *us; haveuc = 1; break; } else if (rc < 0) { /* Error */ utferror = 1; debug(F101,"xgnbyte UTF-8 input error","",rc); haveuc = 1; uc.x_short = *us; break; } } if (x < 0) return(x); debug(F001,"xgnbyte UTF8->UTF2","",uc.x_short); }#endif /* UNICODE */#ifdef KANJI#ifdef UNICODE else#endif /* UNICODE */ if (fcsinfo[fcs].alphabet == AL_JAPAN) { /* Japanese source file */ int c7, x, y, done = 0; if (fcs == FC_JIS7) { /* If file charset is JIS-7 */ if (ffc == 0L) /* If first byte of file */ j7init(); /* Initialize JIS-7 parser */ x = getj7(); /* Get a JIS-7 byte */ } else /* Otherwise */ x = zminchar(); /* Just get byte */ if (x < 0) { /* Propogate EOF or error */ debug(F100,"XGNBYTE EOF","",0); return(x); } debug(F001,"XGNBYTE x","",x); ffc++; /* Count */#ifndef NOXFER if (docrc && what == W_SEND) dofilcrc(x); /* Do CRC */#endif /* NOXFER */ switch (fcs) { /* What next depends on charset */ case FC_SHJIS: /* Shift-JIS */ if ((x <= 0x80) || /* Any 7-bit char... */ (x >= 0xa0 && x <= 0xdf)) { /* or halfwidth Katakana */ sj.x_short = (USHORT) x; /* we read one byte. */ } else { /* Anything else */ if ((y = zminchar()) < 0) /* get another */ return(y);#ifndef NOXFER if (docrc && what == W_SEND) dofilcrc(y);#endif /* NOXFER */ ffc++; sj.x_char[byteorder] = (CHAR) x; sj.x_char[1-byteorder] = (CHAR) y; } break; case FC_JIS7: /* JIS-7 */ case FC_JDEC: /* DEC Kanji */ case FC_JEUC: /* EUC-JP */ if ((x & 0x80) == 0) { /* Convert to Shift-JIS */ sj.x_short = (USHORT) x; /* C0 or G0: one byte */ eu.x_short = (USHORT) x; haveeu = 1; } else { c7 = x & 0x7f; if (c7 > 0x20 && c7 < 0x7f) { /* Kanji: two bytes */ if ((y = (fcs == FC_JEUC) ? zminchar() : getj7()) < 0) return(y); ffc++;#ifndef NOXFER if (docrc && what == W_SEND) dofilcrc(y);#endif /* NOXFER */ eu.x_char[byteorder] = (CHAR) x; eu.x_char[1-byteorder] = (CHAR) y; sj.x_short = eu_to_sj(eu.x_short); haveeu = 1; } else if (x == 0x8e) { /* SS2 Katakana prefix: 2 bytes */ if ((y = (fcs == FC_JIS7) ? getj7() : zminchar()) < 0) return(y); ffc++;#ifndef NOXFER if (docrc && what == W_SEND) dofilcrc(y);#endif /* NOXFER */ sj.x_short = y | 0x80; debug(F001,"XGNBYTE KANA SJ","",sj.x_short); } else { /* Something that translates to U+FFFD */ sj.x_short = UNKSJIS; } } break; } havesj = 1; /* Have Shift-JIS */#ifdef UNICODE uc.x_short = sj_to_un(sj.x_short); /* Translate to UCS-2 */ haveuc = 1; /* Have Unicode */#endif /* UNICODE */ flag = 1; /* Have a char */ }#endif /* KANJI */ } if (!flag) { /* If no character was read yet... */ if ((x = zminchar()) > -1) /* read one now */ ffc++; debug(F101,"xgnbyte zminchar 1","",x); if (x < 0) return(x); haveuc = 0; }#ifdef UNICODE if (haveuc) { thischar = uc.x_short; lastucs2 = uc.x_short; } else#endif /* UNICODE */ thischar = x; debug(F001,"xgnbyte thischar",haveuc ? "[UNICODE]" : "[other]",thischar);#ifdef CK_CTRLZ /* SET EOF CTRLZ */ if (eofmethod == XYEOF_Z && !binary && thischar == 26) { debug(F100,"xgnbyte EOF on Ctrl-Z 1","",0); return(-1); }#endif /* CK_CTRLZ */#ifdef UNICODE if (!haveuc) /* If not Unicode... */#endif /* UNICODE */ x &= fmask; /* Apply SET FILE BYTESIZE mask */ switch (xlatype) { /* Translation type... */#ifdef UNICODE case XLA_UNICODE: { /* Unicode is involved */ xc = 0;/* Here we must choose the appropriate translation function. If we are being called by getpkt() (i.e. when transferring a file), we are translating from Unicode to the Transfer Character Set and therefore must use the function pointed to by xut. Otherwise, e.g. during TRANSLATE, CONNECT, TRANSMIT, etc, we are translating from Unicode to the File Character Set and so must call the function pointed to by xuf. There might be a cleaner way to set this up but I don't think so. For example, setxlatype() might have been called too soon and so might not have known whether it was a file transfer or a local operation.*/ xx = (what == W_SEND) ? xut : xuf; eolflag = 0; if (haveuc) { /* File is Unicode */ /* See Unicode TR13, "Converting to Other Character Sets" */ if (uc.x_short == 0x2028 || /* Line Separator? */ uc.x_short == 0x2029 || /* Paragraph Separator */ (feol && (uc.x_short == (USHORT)feol)) ) { debug(F001,"xgnbyte uc eol","",uc.x_short); rc = 0; eolflag = 1; /* Don't translate and handle later */ } if (xx && !eolflag) { /* UCS-to-TCS function (UCS->byte) */ rc = (*xx)(uc.x_short); /* These can fail... */ debug(F101,"xgnbyte xx rc","",rc); if (rc < 0) /* If it can't be translated */ uc.x_short = UNK; /* Put unknown-character symbol */ else uc.x_short = (unsigned)((unsigned)rc & 0xffff); debug(F101,"xgnbyte xx uc","",uc.x_short); }#ifdef KANJI if (tcs == FC_JEUC) { /* Translating to EUC-JP */ USHORT sj; union ck_short eu; debug(F001,"xgnbyte UCS->EUC UCS","",uc.x_short); if (!havesj) /* If we don't already have it */ sj = un_to_sj(uc.x_short); /* convert to Shift-JIS */ eu.x_short = sj_to_eu(sj); debug(F001,"xgnbyte UCS->EUC EUC","",eu.x_short); xlaptr = 0; xlacount = 0; if (eolflag) { if (what == W_SEND) { xlabuf[xlacount++] = LF; return(CR); } else { return(feol); } } if (eu.x_char[byteorder]) { /* Two bytes */ rc = eu.x_char[byteorder]; xlabuf[xlacount++] = eu.x_char[1-byteorder]; debug(F001,"xgnbyte UCS->EUC xlabuf[0]","",xlabuf[0]); } else { /* One byte */ rc = eu.x_char[1-byteorder]; } debug(F101,"xgnbyte UCS->EUC xlacount","",xlacount); debug(F001,"xgnbyte UCS->EUC rc","",rc); return(rc); } else#endif /* KANJI */ if (tcs != FC_UCS2 && tcs != FC_UTF8) { if (uc.x_short & 0xff00) { /* Decoding error */ debug(F001,"xgnbyte decoding error","",uc.x_short); return(-2); } else return((unsigned int)(uc.x_short & 0xff)); } xc = uc.x_short; } else { /* File is not Unicode */ USHORT ch; /* Translate from single FCS byte to UCS-2 *//* This is a bit nonobvious... The blah_u() (Blah-to-Unicode) routines are called only with pieces of character sets, in the ISO 2022 sense. So, for example, if ch is a Latin-1 character, we call the translation routine only if it is in the right half; if it's in the left half, it isn't translated, and in fact will give the wrong result if sent to the translation function. That's because those functions were designed for use with the ISO 2022 G0..G3 sets, not for file transfer. On the other hand, if it's a 7-bit character set, we *do* call the translation function. (To put it another way, the left half of any 8-bit character set is ASCII and therefore doesn't need to be translated but 7-bit sets such as ISO 646 German do need translation).*/ ch = (unsigned)(thischar & 0xff); if (((fcsinfo[fcs].size > 128) && (ch & 0x80)) || fcsinfo[fcs].size <= 128) { if (xfu) { /* FCS-to-UCS function */ ch = (*xfu)(ch); } } xc = ch; } /* At this point we have a UCS-2 character in native format */ /* (Big Endian or Little Endian) in xc, which is an unsigned int. */ debug(F001,"xgnbyte xc","",xc); if (tcs == FC_UTF8) { /* Now convert to UTF-8 */ USHORT c
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -