pub fn decode_html_rw<R: BufRead, W: Write>(
    reader: R,
    writer: &mut W,
    sloppy: bool,
) -> Result<(), DecodeErr> {
    let mut state: DecodeState = Normal;
    let mut good_pos = 0;
    let mut buf = String::with_capacity(8);

    for (pos, c) in io_support::chars(reader).enumerate() {
        let c = match c {
            Err(e) => {
                let kind = match e {
                    CharsError::NotUtf8 => EncodingError,
                    CharsError::Other(io) => IoError(io),
                };
                return Err(DecodeErr {
                    position: pos,
                    kind,
                });
            }
            Ok(c) => c,
        };
        match state {
            Normal if c == '&' => {
                buf.push(c);
                state = Entity
            }
            Normal => try_dec_io!(write_char(writer, c), good_pos),
            Entity if c == '#' => state = Numeric,
            Entity if c == ';' => {
                if sloppy {
                    buf.clear();
                } else {
                    return Err(DecodeErr {
                        position: good_pos,
                        kind: UnknownEntity,
                    });
                }
            }
            Entity => {
                state = Named;
                buf.push(c);
            }
            Named if c == ';' => {
                buf.push(c);
                state = Normal;

                match decode_named_entity(&buf) {
                    Err(reason) => {
                        if sloppy {
                            try_dec_io!(writer.write_all(buf.as_bytes()), good_pos);
                            buf.clear();
                        } else {
                            return Err(DecodeErr {
                                position: good_pos,
                                kind: reason,
                            });
                        }
                    }
                    Ok(res) => {
                        try_dec_io!(writer.write_all(res.as_bytes()), good_pos);
                        buf.clear();
                    }
                }
            }
            Named => buf.push(c),
            Numeric if is_digit(c) => {
                state = Dec;
                buf.push(c);
            }
            Numeric if c == 'x' => state = Hex,
            Dec if c == ';' => {
                state = Normal;
                let ch = try_parse!(
                    decode_numeric(&buf.get(1..).unwrap_or_default(), 10),
                    good_pos
                );
                try_dec_io!(write_char(writer, ch), good_pos);
                buf.clear();
            }
            Hex if c == ';' => {
                state = Normal;
                let ch = try_parse!(
                    decode_numeric(&buf.get(1..).unwrap_or_default(), 16),
                    good_pos
                );
                try_dec_io!(write_char(writer, ch), good_pos);
                buf.clear();
            }
            Hex if is_hex_digit(c) => buf.push(c),
            Dec if is_digit(c) => buf.push(c),
            Numeric | Hex | Dec => {
                if sloppy {
                    buf.clear();
                    state = Normal;
                } else {
                    return Err(DecodeErr {
                        position: good_pos,
                        kind: MalformedNumEscape,
                    });
                }
            }
        }

        if state == Normal {
            good_pos = pos + 1;
        }
    }

    if state != Normal && !sloppy {
        Err(DecodeErr {
            position: good_pos,
            kind: PrematureEnd,
        })
    } else {
        Ok(())
    }
}
/// Decodes an entity-encoded string from a reader to a writer.
///
/// Similar to `decode_html`, except reading from a reader rather than a string, and
/// writing to a writer rather than returning a `String`.
///
/// # Arguments
/// - `reader` - UTF-8 encoded data is read from here.
/// - `writer` - UTF8- decoded data is written to here.
///
/// # Errors
/// Errors can be caused by IO errors, `reader` producing invalid UTF-8, or by syntax errors.
Decodes an entity-encoded string from a reader to a writer.
Similar to `decode_html`, except reading from a reader rather than a string, and
writing to a writer rather than returning a `String`.
Decodes an entity - encoded string from a reader to a writer . Similar to ` decode_html ` except reading from a reader rather than a string and writing to a writer rather than returning a ` String ` .
pub fn decode_html_rw<R: BufRead, W: Write>(
    reader: R,
    writer: &mut W,
    sloppy: bool,
) -> Result<(), DecodeErr> {
    let mut state: DecodeState = Normal;
    let mut good_pos = 0;
    let mut buf = String::with_capacity(8);
    for (pos, c) in io_support::chars(reader).enumerate() {
        let c = match c {
            Err(e) => {
                let kind = match e {
                    CharsError::NotUtf8 => EncodingError,
                    CharsError::Other(io) => IoError(io),
                };
                return Err(DecodeErr {
                    position: pos,
                    kind,
                });
            }
            Ok(c) => c,
        };
        match state {
            Normal if c == '&' => {
                buf.push(c);
                state = Entity
            }
            Normal => try_dec_io!(write_char(writer, c), good_pos),
            Entity if c == '#' => state = Numeric,
            Entity if c == ';' => {
                if sloppy {
                    buf.clear();
                } else {
                    return Err(DecodeErr {
                        position: good_pos,
                        kind: UnknownEntity,
                    });
                }
            }
            Entity => {
                state = Named;
                buf.push(c);
            }
            Named if c == ';' => {
                buf.push(c);
                state = Normal;
                match decode_named_entity(&buf) {
                    Err(reason) => {
                        if sloppy {
                            try_dec_io!(writer.write_all(buf.as_bytes()), good_pos);
                            buf.clear();
                        } else {
                            return Err(DecodeErr {
                                position: good_pos,
                                kind: reason,
                            });
                        }
                    }
                    Ok(res) => {
                        try_dec_io!(writer.write_all(res.as_bytes()), good_pos);
                        buf.clear();
                    }
                }
            }
            Named => buf.push(c),
            Numeric if is_digit(c) => {
                state = Dec;
                buf.push(c);
            }
            Numeric if c == 'x' => state = Hex,
            Dec if c == ';' => {
                state = Normal;
                let ch = try_parse!(
                    decode_numeric(&buf.get(1..).unwrap_or_default(), 10),
                    good_pos
                );
                try_dec_io!(write_char(writer, ch), good_pos);
                buf.clear();
            }
            Hex if c == ';' => {
                state = Normal;
                let ch = try_parse!(
                    decode_numeric(&buf.get(1..).unwrap_or_default(), 16),
                    good_pos
                );
                try_dec_io!(write_char(writer, ch), good_pos);
                buf.clear();
            }
            Hex if is_hex_digit(c) => buf.push(c),
            Dec if is_digit(c) => buf.push(c),
            Numeric | Hex | Dec => {
                if sloppy {
                    buf.clear();
                    state = Normal;
                } else {
                    return Err(DecodeErr {
                        position: good_pos,
                        kind: MalformedNumEscape,
                    });
                }
            }
        }
        if state == Normal {
            good_pos = pos + 1;
        }
    }
    if state != Normal && !sloppy {
        Err(DecodeErr {
            position: good_pos,
            kind: PrematureEnd,
        })
    } else {
        Ok(())
    }
}
pub fn decode_html_rw < R : BufRead , W : Write > ( reader : R , writer : & mut W , sloppy : bool , ) -> Result < ( ) , DecodeErr > { let mut state : DecodeState = Normal ; let mut good_pos = 0 ; let mut buf = String :: with_capacity ( 8 ) ; for ( pos , c ) in io_support :: chars ( reader ) . enumerate ( ) { let c = match c { Err ( e ) => { let kind = match e { CharsError :: NotUtf8 => EncodingError , CharsError :: Other ( io ) => IoError ( io ) , } ; return Err ( DecodeErr { position : pos , kind , } ) ; } Ok ( c ) => c , } ; match state { Normal if c == '&' => { buf . push ( c ) ; state = Entity } Normal => try_dec_io ! ( write_char ( writer c ) good_pos ) , Entity if c == '#' => state = Numeric , Entity if c == ';' => { if sloppy { buf . clear ( ) ; } else { return Err ( DecodeErr { position : good_pos , kind : UnknownEntity , } ) ; } } Entity => { state = Named ; buf . push ( c ) ; } Named if c == ';' => { buf . push ( c ) ; state = Normal ; match decode_named_entity ( & buf ) { Err ( reason ) => { if sloppy { try_dec_io ! ( writer write_all ( buf as_bytes ( ) ) good_pos ) ; buf . clear ( ) ; } else { return Err ( DecodeErr { position : good_pos , kind : reason , } ) ; } } Ok ( res ) => { try_dec_io ! ( writer write_all ( res as_bytes ( ) ) good_pos ) ; buf . clear ( ) ; } } } Named => buf . push ( c ) , Numeric if is_digit ( c ) => { state = Dec ; buf . push ( c ) ; } Numeric if c == 'x' => state = Hex , Dec if c == ';' => { state = Normal ; let ch = try_parse ! ( decode_numeric ( buf get ( 1 ) unwrap_or_default ( ) 10 ) good_pos ) ; try_dec_io ! ( write_char ( writer ch ) good_pos ) ; buf . clear ( ) ; } Hex if c == ';' => { state = Normal ; let ch = try_parse ! ( decode_numeric ( buf get ( 1 ) unwrap_or_default ( ) 16 ) good_pos ) ; try_dec_io ! ( write_char ( writer ch ) good_pos ) ; buf . clear ( ) ; } Hex if is_hex_digit ( c ) => buf . push ( c ) , Dec if is_digit ( c ) => buf . push ( c ) , Numeric | Hex | Dec => { if sloppy { buf . clear ( ) ; state = Normal ; } else { return Err ( DecodeErr { position : good_pos , kind : MalformedNumEscape , } ) ; } } } if state == Normal { good_pos = pos + 1 ; } } if state != Normal && ! sloppy { Err ( DecodeErr { position : good_pos , kind : PrematureEnd , } ) } else { Ok ( ( ) ) } }
Decodes an entity-encoded string from a reader to a writer.
Decodes an entity - encoded string from a reader to a writer .
reader
R
writer
&mut W
sloppy
bool
reader
R
UTF-8 encoded data is read from here.
UTF - 8 encoded data is read from here .
writer
&mut W
UTF8- decoded data is written to here.
UTF8 - decoded data is written to here .
sloppy
bool
errors
Errors can be caused by IO errors, `reader` producing invalid UTF-8, or by syntax errors.
Errors can be caused by IO errors ` reader ` producing invalid UTF - 8 or by syntax errors .