Attempts to write some data to the port. Returns how much it actually wrote. If writeAll is not TRUE then it will write what it can until it times out
| 797 | // Attempts to write some data to the port. Returns how much it actually wrote. |
| 798 | // If writeAll is not TRUE then it will write what it can until it times out |
| 799 | unsigned int SerialIO::write(const void* data, unsigned int dataLength) { |
| 800 | if ((data == nullptr) || (dataLength == 0)) return 0; |
| 801 | if (!isPortOpen()) return 0; |
| 802 | |
| 803 | #ifdef FTDI_D2XX_AVAILABLE |
| 804 | if (m_ftdi.isOpen()) { |
| 805 | m_ftdi.FT_SetTimeouts(m_readTimeout + (m_readTimeoutMultiplier * dataLength), m_writeTimeout + (m_writeTimeoutMultiplier * dataLength)); |
| 806 | |
| 807 | DWORD written = 0; |
| 808 | if (m_ftdi.FT_Write((LPVOID)data, dataLength, &written) != FTDI::FT_STATUS::FT_OK) written = 0; |
| 809 | return written; |
| 810 | } |
| 811 | #endif |
| 812 | |
| 813 | #ifdef _WIN32 |
| 814 | DWORD written = 0; |
| 815 | if (!WriteFile(m_portHandle, data, dataLength, &written, NULL)) written = 0; |
| 816 | return written; |
| 817 | #else |
| 818 | unsigned int totalTime = m_writeTimeout + (m_writeTimeoutMultiplier * dataLength); |
| 819 | |
| 820 | struct timeval timeout; |
| 821 | timeout.tv_sec = totalTime / 1000; |
| 822 | timeout.tv_usec = (totalTime - (timeout.tv_sec * 1000)) * 1000; |
| 823 | |
| 824 | size_t written = 0; |
| 825 | unsigned char* buffer = (unsigned char*)data; |
| 826 | |
| 827 | fd_set fds; |
| 828 | |
| 829 | FD_ZERO(&fds); |
| 830 | FD_SET(m_portHandle, &fds); |
| 831 | |
| 832 | // Write with a timeout |
| 833 | while (written < dataLength) { |
| 834 | if ((timeout.tv_sec < 1) && (timeout.tv_usec < 1)) break; |
| 835 | |
| 836 | int result = select(m_portHandle + 1, NULL, &fds, NULL, &timeout); |
| 837 | if (result < 0) { |
| 838 | if (errno == EINTR || errno == EAGAIN) continue; else return 0; |
| 839 | } |
| 840 | else if (result == 0) break; |
| 841 | |
| 842 | result = ::write(m_portHandle, buffer, dataLength - written); |
| 843 | |
| 844 | if (result < 0) { |
| 845 | if (errno == EINTR || errno == EAGAIN) continue; else return 0; |
| 846 | } |
| 847 | |
| 848 | written += result; |
| 849 | buffer += result; |
| 850 | } |
| 851 | |
| 852 | return written; |
| 853 | #endif |
| 854 | |
| 855 | return 0; |
| 856 | } |
no test coverage detected