* Copyright (c) 1991 The Regents of the University of California.
* This code is derived from software contributed to Berkeley by
* Keith Muller of the University of California, San Diego.
* %sccs.include.redist.c%
static char sccsid
[] = "@(#)conv.c 5.1 (Berkeley) %G%";
* Copy input to output. Input is buffered until reaches obs, and then
* output until less than obs remains. Only a single buffer is used.
* Worst case buffer calculations are as follows:
* if (ibs > obs) # read ibs, output just over half
* max = ibs - 1 - ibs / 2 + ibs;
* else if (ibs < obs) # obs - 1 a multiple of ibs
register u_char
*inp
, *t
;
for (inp
= in
.dbp
- (cnt
= in
.dbrcnt
); cnt
--; ++inp
)
/* Make the output buffer look right. */
if (in
.dbcnt
>= out
.dbsz
) {
/* If the output buffer is full, write it. */
* Ddout copies the leftover output to the beginning of
* the buffer and resets the output buffer. Reset the
* input buffer to match it.
/* Just update the count, everything is already in the buffer. */
* Copy variable length newline terminated records with a max size cbsz
* bytes to output. Records less than cbs are padded with spaces.
* max in buffer: MAX(ibs, cbsz)
* max out buffer: obs + cbsz
register u_char
*inp
, *outp
, *t
;
* Record truncation can cross block boundaries. If currently in a
* truncation state, keep tossing characters until reach a newline.
* Start at the beginning of the buffer, as the input buffer is always
for (inp
= in
.db
, cnt
= in
.dbrcnt
;
cnt
&& *inp
++ != '\n'; --cnt
);
/* Adjust the input buffer numbers. */
* Copy records (max cbsz size chunks) into the output buffer. The
* translation is done as we copy into the output buffer.
for (inp
= in
.dbp
- in
.dbcnt
, outp
= out
.dbp
; in
.dbcnt
;) {
maxlen
= MIN(cbsz
, in
.dbcnt
);
cnt
< maxlen
&& (ch
= *inp
++) != '\n'; ++cnt
)
cnt
< maxlen
&& (ch
= *inp
++) != '\n'; ++cnt
)
* Check for short record without a newline. Reassemble the
if (ch
!= '\n' && in
.dbcnt
< cbsz
) {
bcopy(in
.dbp
- in
.dbcnt
, in
.db
, in
.dbcnt
);
/* Adjust the input buffer numbers. */
/* Pad short records with "spaces". */
(void)memset(outp
, ctab
? ctab
[' '] : ' ', cbsz
- cnt
);
/* Toss characters to a newline. */
for (; in
.dbcnt
&& *inp
++ != '\n'; --in
.dbcnt
);
/* Adjust output buffer numbers. */
if ((out
.dbcnt
+= cbsz
) >= out
.dbsz
)
in
.dbp
= in
.db
+ in
.dbcnt
;
* Copy any remaining data into the output buffer and pad to a record.
* Don't worry about truncation or translation, the input buffer is
* always empty when truncating, and no characters have been added for
* translation. The bottom line is that anything left in the input
* buffer is a truncated record. Anything left in the output buffer
* just wasn't big enough.
bcopy(in
.dbp
- in
.dbcnt
, out
.dbp
, in
.dbcnt
);
(void)memset(out
.dbp
+ in
.dbcnt
,
ctab
? ctab
[' '] : ' ', cbsz
- in
.dbcnt
);
* Convert fixed length (cbsz) records to variable length. Deletes any
* trailing blanks and appends a newline.
* max in buffer: MAX(ibs, cbsz) + cbsz
* max out buffer: obs + cbsz
register u_char
*inp
, *t
;
/* Translation and case conversion. */
for (cnt
= in
.dbrcnt
, inp
= in
.dbp
; cnt
--;)
* Copy records (max cbsz size chunks) into the output buffer. The
* translation has to already be done or we might not recognize the
for (inp
= in
.db
; in
.dbcnt
>= cbsz
; inp
+= cbsz
, in
.dbcnt
-= cbsz
) {
for (t
= inp
+ cbsz
- 1; t
>= inp
&& *t
== ' '; --t
);
bcopy(inp
, out
.dbp
, cnt
);
if (out
.dbcnt
>= out
.dbsz
)
bcopy(in
.dbp
- in
.dbcnt
, in
.db
, in
.dbcnt
);
in
.dbp
= in
.db
+ in
.dbcnt
;
warn("%s: short input record", in
.name
);
for (t
= in
.db
+ in
.dbcnt
- 1; t
>= in
.db
&& *t
== ' '; --t
);
bcopy(in
.db
, out
.dbp
, cnt
);