📄 ckcfns.c
字号:
Here we handle characters that were encoded for the last packet but did not fit, and so were saved in the "leftover" array.*/ if (nleft) { for (p1 = leftover; nleft > 0; nleft--) /* Copy leftovers */ *dp++ = *p1++; *leftover = '\0'; /* Delete leftovers */ nleft = 0; } if (first == -1) /* Handle EOF */ return(size = (dp - data));/* Now fill up the rest of the packet. */ rpt = 0; /* Initialize character repeat count */ while (first > -1) { /* Until EOF... */#ifdef CALIBRATE if (calibrate) { /* We generate our own "file" */ if (ffc >= calibrate) { /* EOF */ first = -1; ffc--; } else { /* Generate next character */ if (cal_j > CAL_M * ffc) cal_j = cal_a[ffc & 0xff]; x = (unsigned)cal_a[(cal_j & 0xff)]; if (x == rt) x ^= 2; } ffc++; cal_j += (unsigned int)(ffc + CAL_O); } else#endif /* CALIBRATE */ if ((x = zminchar()) < 0) { /* Check for EOF */ if (x == -3) { /* Timeout. */ t = rt; size = (dp-data); debug(F101,"bgetpkt timeout size","",size); return((size == 0) ? x : size); } first = -1; /* Flag eof for next time. */ if (x == -2) cxseen = 1; /* If error, cancel this file. */ } else { ffc++; /* Count the character */ if (docrc && (what & W_SEND)) { /* Accumulate file crc */ z = crc16 ^ (long)((CHAR)x & 0xff); crc16 = (crc16 >> 8) ^ (crcta[(z & 0xF0) >> 4] ^ crctb[z & 0x0F]); } } rnext = (CHAR) (x & fmask); /* Apply file mask *//* At this point, the character we just read is in rnext, and the character we are about to encode into the packet is in rt.*/ odp = dp; /* Remember where we started. */ xxrc = xxcq = NUL; /* Clear these. *//* Now encode the character according to the options that are in effect: ctlp[]: whether this control character needs prefixing. rptflg: repeat counts enabled. Other options don't apply in this routine.*/ if (rptflg && (rt == rnext) && (first == 0)) { /* Got a run... */ if (++rpt < 94) { /* Below max, just count */ continue; /* go back and get another */ } else if (rpt == 94) { /* Reached max, must dump */ xxrc = (CHAR) tochar(rpt); /* Put the repeat count here */ rptn += rpt; /* Accumulate it for statistics */ rpt = 0; /* And reset it */ } } else if (rpt > 0) { /* End of run */ xxrc = (CHAR)tochar(++rpt); /* The count */ rptn += rpt; /* For stats */ rpt = 0; /* Reset repeat count */ } a7 = rt & 0177; /* Get low 7 bits of character */ if (#ifdef CK_SPEED ctlp[(unsigned)(rt & 0xff)] /* Lop off any "sign" extension */#else (a7 < SP) || (a7 == DEL)#endif /* CK_SPEED */ ) { /* Do control prefixing if necessary */ xxcq = myctlq; /* The prefix */ ccp++; /* Count it */ rt = (CHAR) ctl(rt); /* Uncontrollify the character */ }#ifdef CK_SPEED else if ((a7 < SP) || (a7 == DEL)) /* Count an unprefixed one */ ccu++;#endif /* CK_SPEED */ if (a7 == myctlq) /* Always prefix the control prefix */ xxcq = myctlq; if ((rptflg) && (a7 == rptq)) /* If it's the repeat prefix, */ xxcq = myctlq; /* prefix it if doing repeat counts *//* Now construct the prefixed sequence */ if (xxrc) { /* Repeat count */#ifdef COMMENT if (xxrc == (CHAR) '"' && !xxcq) { /* 2 in a row & not prefixed */ *dp++ = rt; /* So just do this */ } else { /* More than two or prefixed */ *dp++ = (CHAR) rptq; *dp++ = xxrc; /* Emit repeat sequence */ }#else /* CHECK THIS */ if (xxrc == (CHAR) '"' && !xxcq) { /* 2 in a row & not prefixed */ if (dp == data) { *dp++ = rt; /* So just do this */ } else if (*(dp-1) == rt) { *dp++ = (CHAR) rptq; *dp++ = xxrc; /* Emit repeat sequence */ } else { *dp++ = rt; /* So just do this */ } } else { /* More than two or prefixed */ *dp++ = (CHAR) rptq; *dp++ = xxrc; /* Emit repeat sequence */ }#endif /* COMMENT */ } if (xxcq) { *dp++ = myctlq; } /* Control prefix */ *dp++ = rt; /* Finally, the character itself */ rt = rnext; /* Next character is now current. *//* Done encoding the character. Now take care of packet buffer overflow. */ size = dp - data; /* How many bytes we put in buffer. */ if (size >= bufmax) { /* If too big, save some for next. */ *dp = '\0'; /* Mark the end. */ if (size > bufmax) { /* if packet is overfull */ /* Copy the part that doesn't fit into the leftover buffer, */ /* taking care not to split a prefixed sequence. */ int i; nleft = dp - odp; p1 = leftover; p2 = odp; for (i = 0; i < nleft; i++) *p1++ = *p2++; size = odp - data; /* Return truncated packet. */ *odp = '\0'; /* Mark the new end */ } t = rt; /* Save for next time */ return(size); } } /* Otherwise, keep filling. */ size = dp - data; /* End of file */ *dp = '\0'; /* Mark the end of the data. */ return(size); /* Return partially filled last packet. */}#endif /* CKTUNING */VOIDdofilcrc(c) int c; { /* Accumulate file crc */ long z; z = crc16 ^ (long)c; crc16 = (crc16 >> 8) ^ (crcta[(z & 0xF0) >> 4] ^ crctb[z & 0x0F]);}/* For SENDing from an array... */intagnbyte() { /* Get next byte from array */#ifndef NOSPL char 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 */ 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). As of Sat Sep 7 18:37:41 2002: When the output character-set is UCS-2, bytes are ALWAYS returned in big-endian order (previously they could also be returned in LE order under certain conditions, which was just way too confusing).*/int#ifdef CK_ANSICxgnbyte(int tcs, int fcs, int (*fn)(void))#else /* CK_ANSIC */xgnbyte(tcs,fcs,fn) int tcs, fcs, (*fn)();#endif /* CK_ANSIC *//* xgnbyte */ { _PROTOTYP( int (*xx), (USHORT) ) = NULL; 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 */#ifdef DEBUG if (deblog && ffc == 0) { debug(F101,"xgnbyte initial swap","",swapping); }#endif /* DEBUG */ if (xlacount-- > 0) { /* We already have some */ x = xlabuf[xlaptr++]; debug(F001,"xgnbyte 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 = fn ? (*fn)() : zminchar(); /* Get first byte */ debug(F001,"zminchar swapping","",swapping); debug(F001,"zminchar C0","",x); 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 */ x = fn ? (*fn)() : zminchar(); /* Get second byte */ if (x > -1) { /* If didn't fail */ debug(F001,"zminchar C1","",x); 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); debug(F111,"xgnbyte fileorder","A",fileorder); if (fileorder < 0) /* Byte order of this file */ fileorder = ucsorder; /* Default is ucsorder */ if (fileorder > 1) fileorder = 1; debug(F111,"xgnbyte fileorder","B",fileorder); if (uc.x_short == (USHORT)0xfeff) { swapping = 0; debug(F101, "xgnbyte UCS2 goodbom swap","",swapping); fileorder = byteorder; /* Note: NOT 0 */ goto bomskip; } else if (uc.x_short == (USHORT)0xfffe) { swapping = 1; debug(F101, "xgnbyte UCS2 badbom swap","",swapping); fileorder = (1 - byteorder); /* Note: NOT 1 */ goto bomskip; } else if ((byteorder && !fileorder) || /* No BOM */ (!byteorder && fileorder > 0)) { /* fileorder might have been set by scanfile() */ CHAR c; c = uc.x_char[0]; uc.x_char[0] = uc.x_char[1]; uc.x_char[1] = c; swapping = 1; debug(F111,"xgnbyte UCS2 noBOM swap","A",swapping); } else { swapping = 0; debug(F111,"xgnbyte UCS2 noBOM swap","B",swapping); } debug(F111,"xgnbyte fileorder","C",fileorder); } } 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() */ /* Read source bytes */ while ((x = fn ? (*fn)() : zminchar()) > -1) { 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->UCS2","",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; 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 = fn ? (*fn)() : 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 = fn ? (*fn)() : zminchar()) < 0) /* get another */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -