/** * @brief * Advance the input cursor by one character. * @remark * If the file is was not opened, end of the input was reached or an error was encountered, * before a call to this method, the call immediatly returns, not observably modifying the * state of this object or the file. */ virtual void advance() { // (1) If an error or the end of the input was encountered ... if (_current == Traits::error() || _current == Traits::endOfInput()) { // ... do nothing. return; } // (2) If the backing VFS file is not opened ... if (!_file) { // ... raise an error. _current = Traits::error(); return; } // (3) Otherwise: Read a single Byte. uint8_t byte; size_t size = vfs_read(&byte, 1, 1, _file); if (1 != size) { if (vfs_error(_file)) { _current = Traits::error(); return; } else if (vfs_eof(_file)) { _current = Traits::endOfInput(); return; } else { ostringstream message; message << __FILE__ << ":" << __LINE__ << ": " << "inconsistent state of file object of file `" << this->getFileName() << "`"; throw runtime_error(message.str()); } } // (4) Verify that it is a Byte the represents the starting Byte of a UTF-8 character sequence of length 1. if (byte > 0x7F) { _current = Traits::error(); return; } // (5) Verify that it is not the zero terminator. if ('\0' == byte) { _current = Traits::error(); return; } // (6) Propage the Byte to an extended character and store it. _current = (typename Traits::ExtendedType)byte; }
// --------------------------------------------------------------------------- // supplementary functions // int vfs_getc( int fd ) { unsigned char c = 0xFF; sint32_t res; if(!vfs_eof( fd )) { if (1 != vfs_read( fd, &c, 1 )) { NODE_DBG("getc errno %i\n", vfs_ferrno( fd )); return VFS_EOF; } else { return (int)c; } } return VFS_EOF; }
static void send_file(struct ftpd_datastate *fsd, struct tcp_pcb *pcb) { if (!fsd->connected) return; if (fsd->vfs_file) { char buffer[2048]; int len; len = sfifo_space(&fsd->fifo); if (len == 0) { send_data(pcb, fsd); return; } if (len > 2048) len = 2048; len = vfs_read(buffer, 1, len, fsd->vfs_file); if (len == 0) { if (vfs_eof(fsd->vfs_file) == 0) return; vfs_close(fsd->vfs_file); fsd->vfs_file = NULL; return; } sfifo_write(&fsd->fifo, buffer, len); send_data(pcb, fsd); } else { struct ftpd_msgstate *fsm; struct tcp_pcb *msgpcb; if (sfifo_used(&fsd->fifo) > 0) { send_data(pcb, fsd); return; } fsm = fsd->msgfs; msgpcb = fsd->msgpcb; vfs_close(fsd->vfs_file); fsd->vfs_file = NULL; ftpd_dataclose(pcb, fsd); fsm->datapcb = NULL; fsm->datafs = NULL; fsm->state = FTPD_IDLE; send_msg(msgpcb, fsm, msg226); return; } }