CT_INT_TYPE CConn_Streambuf::overflow(CT_INT_TYPE c) { if (!m_Conn) return CT_EOF; size_t n_written; size_t n_towrite = (size_t)(pptr() - pbase()); if (n_towrite) { // send buffer do { m_Status = CONN_Write(m_Conn, pbase(), n_towrite, &n_written, eIO_WritePlain); _ASSERT(n_written <= n_towrite); if (!n_written) { _ASSERT(m_Status != eIO_Success); break; } // update buffer content (get rid of the data just sent) memmove(pbase(), pbase() + n_written, n_towrite - n_written); x_PPos += (CT_OFF_TYPE) n_written; pbump(-int(n_written)); // store char if (!CT_EQ_INT_TYPE(c, CT_EOF)) return sputc(CT_TO_CHAR_TYPE(c)); n_towrite -= n_written; } while (n_towrite && m_Status == eIO_Success); if (n_towrite) { _ASSERT(m_Status != eIO_Success); ERR_POST_X(4, x_Message("overflow(): CONN_Write() failed")); return CT_EOF; } } else if (!CT_EQ_INT_TYPE(c, CT_EOF)) { // send char CT_CHAR_TYPE b = CT_TO_CHAR_TYPE(c); m_Status = CONN_Write(m_Conn, &b, 1, &n_written, eIO_WritePlain); _ASSERT(n_written <= 1); if (!n_written) { _ASSERT(m_Status != eIO_Success); ERR_POST_X(5, x_Message("overflow(): CONN_Write(1) failed")); return CT_EOF; } x_PPos += (CT_OFF_TYPE) 1; return c; } _ASSERT(CT_EQ_INT_TYPE(c, CT_EOF)); if ((m_Status = CONN_Flush(m_Conn)) != eIO_Success) { ERR_POST_X(9, x_Message("overflow(): CONN_Flush() failed")); return CT_EOF; } return CT_NOT_EOF(CT_EOF); }
EIO_Status CConn_FtpStream::Drain(const STimeout* timeout) { const STimeout* r_timeout = kInfiniteTimeout/*0*/; const STimeout* w_timeout = kInfiniteTimeout/*0*/; CONN conn = GetCONN(); char block[1024]; if (conn) { size_t n; r_timeout = CONN_GetTimeout(conn, eIO_Read); w_timeout = CONN_GetTimeout(conn, eIO_Write); _VERIFY(SetTimeout(eIO_Read, timeout) == eIO_Success); _VERIFY(SetTimeout(eIO_Write, timeout) == eIO_Success); // Cause any upload-in-progress to abort CONN_Read (conn, block, sizeof(block), &n, eIO_ReadPlain); // Cause any command-in-progress to abort CONN_Write(conn, "NOOP\n", 5, &n, eIO_WritePersist); } clear(); while (read(block, sizeof(block))) ; if (!conn) return eIO_Closed; EIO_Status status; do { size_t n; status = CONN_Read(conn, block, sizeof(block), &n, eIO_ReadPersist); } while (status == eIO_Success); _VERIFY(CONN_SetTimeout(conn, eIO_Read, r_timeout) == eIO_Success); _VERIFY(CONN_SetTimeout(conn, eIO_Write, w_timeout) == eIO_Success); clear(); return status == eIO_Closed ? eIO_Success : status; }
NLM_EXTERN CONN QUERY_OpenServiceQueryEx ( const char* service, const char* parameters, Nlm_Uint4 timeoutsec, const char* arguments ) { CONN conn; CONNECTOR connector; SConnNetInfo* net_info; size_t n_written; EIO_Status status; /* fill in connection info fields and create the connection */ net_info = ConnNetInfo_Create (service); ASSERT ( net_info ); /* let the user agent be set with a program name */ x_SetupUserHeader (net_info, NULL, eMIME_T_Unknown, eMIME_Unknown, eENCOD_None); if (timeoutsec == (Nlm_Uint4)(-1L)) { net_info->timeout = kInfiniteTimeout; } else if ( timeoutsec ) { net_info->tmo.sec = timeoutsec; net_info->tmo.usec = timeoutsec; net_info->timeout = &net_info->tmo; } ConnNetInfo_PostOverrideArg (net_info, arguments, 0); connector = SERVICE_CreateConnectorEx (service, fSERV_Any, net_info, 0); ConnNetInfo_Destroy (net_info); if (connector == NULL) { ErrPostEx (SEV_ERROR, 0, 0, "QUERY_OpenServiceQuery failed in SERVICE_CreateConnectorEx"); conn = NULL; } else if ((status = CONN_Create (connector, &conn)) != eIO_Success) { ErrPostEx (SEV_ERROR, 0, 0, "QUERY_OpenServiceQuery failed in CONN_Create:" " %s", IO_StatusStr (status)); ASSERT (conn == NULL); } else if (StringDoesHaveText (parameters)) { status = CONN_Write (conn, parameters, StringLen (parameters), &n_written, eIO_WritePersist); if (status != eIO_Success) { ErrPostEx (SEV_ERROR, 0, 0, "QUERY_OpenServiceQuery failed to write service parameters in CONN_Write: %s", IO_StatusStr (status)); CONN_Close (conn); conn = NULL; } } return conn; }
static Nlm_Int2 LIBCALL AsnIoConnWrite ( Pointer ptr, CharPtr buf, Nlm_Uint2 count ) { size_t bytes; AsnIoConnPtr aicp; aicp = (AsnIoConnPtr) ptr; if (aicp == NULL || aicp->conn == NULL) return 0; CONN_Write (aicp->conn, buf, (size_t) count, &bytes, eIO_WritePersist); return (Nlm_Int2) bytes; }
static void s_SingleBouncePrint (CONN conn, FILE* data_file) { static const char write_str[] = "This is a s_*BouncePrint test string.\n"; size_t n_written, n_read; char message[128]; char buf[8192]; EIO_Status status; TEST_LOG(eIO_Success, "[s_SingleBouncePrint] Starting..."); /* WRITE */ status = CONN_Write(conn, write_str, strlen(write_str), &n_written, eIO_WritePersist); if (status != eIO_Success || n_written != strlen(write_str)) { TEST_LOG(status, "[s_SingleBouncePrint] CONN_Write(persistent) failed"); } assert(n_written == strlen(write_str)); assert(status == eIO_Success); /* READ the "bounced" data from the connection */ status = CONN_Read(conn, buf, sizeof(buf) - 1, &n_read, eIO_ReadPersist); sprintf(message, "[s_SingleBouncePrint] CONN_Read(persistent)" " %lu byte%s read", (unsigned long) n_read, &"s"[n_read == 1]); TEST_LOG(status, message); /* Printout to data file, if any */ if (data_file && n_read) { fprintf(data_file, "\ns_SingleBouncePrint(BEGIN PRINT)\n"); assert(fwrite(buf, n_read, 1, data_file) == 1); fprintf(data_file, "\ns_SingleBouncePrint(END PRINT)\n"); fflush(data_file); } /* Check-up */ assert(n_read >= n_written); buf[n_read] = '\0'; assert(strstr(buf, write_str)); TEST_LOG(eIO_Success, "[s_SingleBouncePrint] ...finished"); }
NLM_EXTERN void QUERY_CopyFileToQuery ( CONN conn, FILE *fp ) { char* buffer; size_t ct; size_t n_written; EIO_Status status; if (conn == NULL || fp == NULL) return; buffer = (char*) MemNew(URL_QUERY_BUFLEN + 1); if (buffer != NULL) { while ((ct = FileRead (buffer, 1, URL_QUERY_BUFLEN, fp)) > 0) { status = CONN_Write (conn, (const void *) buffer, ct, &n_written, eIO_WritePersist); if (status != eIO_Success) break; } MemFree (buffer); } }
static Int2 LIBCALLBACK s_AsnWrite(Pointer conn, CharPtr buf, Uint2 len) { size_t n_written; CONN_Write((CONN) conn, buf, len, &n_written, eIO_WritePersist); return (Int2) n_written; }
int main(int argc, const char* argv[]) { CONN conn; CONNECTOR connector; EIO_Status status; const char* inp_file; /* cmd.-line args */ if (argc != 2) { Usage(argv[0], "Must specify the input file name"); } inp_file = argv[1]; /* log and data log streams */ CORE_SetLOGFormatFlags(fLOG_None | fLOG_Level | fLOG_OmitNoteLevel | fLOG_DateTime); CORE_SetLOGFILE(stderr, 0/*false*/); /* run the test */ fprintf(stderr, "Starting the FILE CONNECTOR test...\n" "Copy data from file \"%s\" to file \"%s\".\n\n", inp_file, OUT_FILE); /* create connector, and bind it to the connection */ connector = FILE_CreateConnector(inp_file, OUT_FILE); if ( !connector ) { Usage(argv[0], "Failed to create FILE connector"); } verify(CONN_Create(connector, &conn) == eIO_Success); /* pump the data from one file to another */ for (;;) { char buf[100]; size_t n_read, n_written; /* read */ status = CONN_Read(conn, buf, sizeof(buf), &n_read, eIO_ReadPlain); if (status != eIO_Success) { fprintf(stderr, "CONN_Read() failed (status: %s)\n", IO_StatusStr(status)); break; } fprintf(stderr, "READ: %ld bytes\n", (long) n_read); /* write */ status = CONN_Write(conn, buf, n_read, &n_written, eIO_WritePersist); if (status != eIO_Success) { fprintf(stderr, "CONN_Write() failed (status: %s)\n", IO_StatusStr(status)); assert(0); break; } assert(n_written == n_read); } assert(status == eIO_Closed); /* cleanup, exit */ verify(CONN_Close(conn) == eIO_Success); CORE_LOG(eLOG_Note, "TEST completed successfully"); CORE_SetLOG(0); return 0; }
static void s_SingleBounceCheck (CONN conn, const STimeout* timeout, FILE* data_file) { static const char sym[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; EIO_Status status; char message[128]; #define TEST_N_LINES 200 #define TEST_BUF_SIZE (TEST_N_LINES * (TEST_N_LINES + 3) / 2) char buf[TEST_BUF_SIZE]; TEST_LOG(eIO_Success, "[s_SingleBounceCheck] Starting..."); /* WRITE to the connection: "0\n12\n345\n6789\n01234\n........" */ {{ size_t k = 0, j = 0; size_t i; for (i = 0; k != sizeof(buf); i++) { /* prepare output data */ size_t n_write, n_written; for (n_write = 0; n_write < i; n_write++, k++) { assert(k < sizeof(buf)); buf[n_write] = sym[j++ % sizeof(sym)]; } assert(k < sizeof(buf)); if ( n_write ) { buf[n_write++] = '\n'; k++; } buf[n_write] = '\0'; do { /* persistently */ /* WAIT... sometimes */ if (n_write % 5 == 3) { status = CONN_Wait(conn, eIO_Write, timeout); if (status != eIO_Success) { TEST_LOG(status, "[s_SingleBounceCheck] CONN_Wait(write)" " failed, retrying..."); assert(status == eIO_Timeout); } } /* WRITE */ status = CONN_Write(conn, buf, n_write, &n_written, eIO_WritePersist); if (status != eIO_Success) { TEST_LOG(status, "[s_SingleBounceCheck] CONN_Write(persistent)" " failed, retrying..."); assert(n_written < n_write); assert(status == eIO_Timeout); } else { assert(n_written == n_write); } } while (status != eIO_Success); } }} /* READ the "bounced" data from the connection, the first TEST_BUF_SIZE * bytes must be: "0\n12\n345\n6789\n01234\n........" */ {{ char* x_buf; size_t n_read, n_to_read; memset(buf, '\0', TEST_BUF_SIZE); /* PEEK until the 1st 1/3 of the "bounced" data is available */ x_buf = buf; n_to_read = TEST_BUF_SIZE/3; do { TEST_LOG(eIO_Success, "[s_SingleBounceCheck] 1/3 PEEK..."); status = CONN_Read(conn, x_buf, n_to_read, &n_read, eIO_ReadPeek); if (status != eIO_Success) { TEST_LOG(status, "[s_SingleBounceCheck] 1/3 CONN_Read(peek)" " failed, retrying..."); assert(n_read < n_to_read); assert(status == eIO_Timeout); } if (n_read < n_to_read) { sprintf(message, "[s_SingleBounceCheck] 1/3 CONN_Read(peek)" " %lu byte%s peeked out of %lu byte%s, continuing...", (unsigned long) n_read, &"s"[n_read == 1], (unsigned long) n_to_read, &"s"[n_to_read == 1]); TEST_LOG(status, message); } } while (n_read != n_to_read); /* READ 1st 1/3 of "bounced" data, compare it with the PEEKed data */ TEST_LOG(eIO_Success, "[s_SingleBounceCheck] 1/3 READ..."); status = CONN_Read(conn, x_buf + n_to_read, n_to_read, &n_read, eIO_ReadPlain); if (status != eIO_Success) { TEST_LOG(status, "[s_SingleBounceCheck] 1/3 CONN_Read(plain) failed"); } assert(status == eIO_Success); assert(n_read == n_to_read); assert(memcmp(x_buf, x_buf + n_to_read, n_to_read) == 0); memset(x_buf + n_to_read, '\0', n_to_read); /* WAIT on read */ status = CONN_Wait(conn, eIO_Read, timeout); if (status != eIO_Success) { TEST_LOG(status, "[s_SingleBounceCheck] CONN_Wait(read) failed"); assert(status == eIO_Timeout); } /* READ the 2nd 1/3 of "bounced" data */ x_buf = buf + TEST_BUF_SIZE/3; n_to_read = TEST_BUF_SIZE/3; while ( n_to_read ) { TEST_LOG(eIO_Success, "[s_SingleBounceCheck] 2/3 READ..."); status = CONN_Read(conn, x_buf, n_to_read, &n_read, eIO_ReadPlain); if (status != eIO_Success) { sprintf(message, "[s_SingleBounceCheck] 2/3 CONN_Read(plain)" " %lu byte%s read out of %lu byte%s, retrying...", (unsigned long) n_read, &"s"[n_read == 1], (unsigned long) n_to_read, &"s"[n_to_read == 1]); TEST_LOG(status, message); assert(n_read < n_to_read); assert(status == eIO_Timeout); } else { assert(n_read <= n_to_read); } n_to_read -= n_read; x_buf += n_read; } assert(status == eIO_Success); /* Persistently READ the 3rd 1/3 of "bounced" data */ n_to_read = TEST_BUF_SIZE - (x_buf - buf); TEST_LOG(eIO_Success, "[s_SingleBounceCheck] 3/3 READ..."); status = CONN_Read(conn, x_buf, n_to_read, &n_read, eIO_ReadPersist); if (status != eIO_Success) { sprintf(message, "[s_SingleBounceCheck] 3/3 CONN_Read(persistent)" " %lu byte%s read", (unsigned long) n_read, &"s"[n_read == 1]); TEST_LOG(status, message); assert(n_read < n_to_read); assert(0); } else { assert(n_read == n_to_read); } }} /* Check for the received "bounced" data is identical to the sent data */ {{ const char* x_buf = buf; size_t k = 0, j = 0; size_t i; for (i = 1; k != sizeof(buf); i++) { size_t n; for (n = 0; n < i; n++, k++) { if (k == sizeof(buf)) break; assert(*x_buf++ == sym[j++ % sizeof(sym)]); } assert(*x_buf++ == '\n'); k++; } }} /* Now when the "bounced" data is read and tested, READ an arbitrary extra * data sent in by the peer and print it out to LOG file */ if ( data_file ) { fprintf(data_file, "\ns_SingleBounceCheck(BEGIN EXTRA DATA)\n"); fflush(data_file); for (;;) { size_t n; TEST_LOG(eIO_Success, "[s_SingleBounceCheck] EXTRA READ..."); status = CONN_Read(conn, buf, sizeof(buf), &n, eIO_ReadPersist); TEST_LOG(status, "[s_SingleBounceCheck] EXTRA CONN_Read(persistent)"); if ( n ) { assert(fwrite(buf, n, 1, data_file) == 1); fflush(data_file); } if (status == eIO_Closed || status == eIO_Timeout) break; /* okay */ assert(status == eIO_Success); } fprintf(data_file, "\ns_SingleBounceCheck(END EXTRA DATA)\n\n"); fflush(data_file); } TEST_LOG(eIO_Success, "[s_SingleBounceCheck] ...finished"); }
int main(int argc, const char* argv[]) { const char* service = argc > 1 && *argv[1] ? argv[1] : "bounce"; static char obuf[8192 + 2]; SConnNetInfo* net_info; CONNECTOR connector; EIO_Status status; char ibuf[1024]; CONN conn; size_t n; setlocale(LC_ALL, ""); g_NCBI_ConnectRandomSeed = (int) time(0) ^ NCBI_CONNECT_SRAND_ADDEND; srand(g_NCBI_ConnectRandomSeed); CORE_SetLOGFormatFlags(fLOG_None | fLOG_Level | fLOG_OmitNoteLevel | fLOG_DateTime); CORE_SetLOGFILE(stderr, 0/*false*/); net_info = ConnNetInfo_Create(service); ConnNetInfo_AppendArg(net_info, "testarg", "val"); ConnNetInfo_AppendArg(net_info, "service", "none"); ConnNetInfo_AppendArg(net_info, "platform", "none"); ConnNetInfo_AppendArg(net_info, "address", "2010"); ConnNetInfo_Log(net_info, eLOG_Note, CORE_GetLOG()); connector = SERVICE_CreateConnectorEx(service, fSERV_Any, net_info, 0); if (!connector) CORE_LOG(eLOG_Fatal, "Failed to create service connector"); if (CONN_Create(connector, &conn) != eIO_Success) CORE_LOG(eLOG_Fatal, "Failed to create connection"); if (argc > 2) { strncpy0(obuf, argv[2], sizeof(obuf) - 2); obuf[n = strlen(obuf)] = '\n'; obuf[++n] = '\0'; if (CONN_Write(conn, obuf, strlen(obuf), &n, eIO_WritePersist) != eIO_Success) { CONN_Close(conn); CORE_LOG(eLOG_Fatal, "Cannot write to connection"); } assert(n == strlen(obuf)); } else { for (n = 0; n < 10; n++) { size_t m; for (m = 0; m < sizeof(obuf) - 2; m++) obuf[m] = "0123456789\n"[rand() % 11]; obuf[m++] = '\n'; obuf[m] = '\0'; if (CONN_Write(conn, obuf, strlen(obuf), &m, eIO_WritePersist) != eIO_Success) { if (!n) { CONN_Close(conn); CORE_LOG(eLOG_Fatal, "Cannot write to connection"); } else break; } assert(m == strlen(obuf)); } } for (;;) { if (CONN_Wait(conn, eIO_Read, net_info->timeout) != eIO_Success) { CONN_Close(conn); CORE_LOG(eLOG_Fatal, "Failed to wait for reading"); } status = CONN_Read(conn, ibuf, sizeof(ibuf), &n, eIO_ReadPersist); if (n) { char* descr = CONN_Description(conn); CORE_DATAF(eLOG_Note, ibuf, n, ("%lu bytes read from service (%s%s%s):", (unsigned long) n, CONN_GetType(conn), descr ? ", " : "", descr ? descr : "")); if (descr) free(descr); } if (status != eIO_Success) { if (status != eIO_Closed) CORE_LOGF(n ? eLOG_Error : eLOG_Fatal, ("Read error: %s", IO_StatusStr(status))); break; } } ConnNetInfo_Destroy(net_info); CONN_Close(conn); #if 0 CORE_LOG(eLOG_Note, "Trying ID1 service"); net_info = ConnNetInfo_Create(service); connector = SERVICE_CreateConnectorEx("ID1", fSERV_Any, net_info); ConnNetInfo_Destroy(net_info); if (!connector) CORE_LOG(eLOG_Fatal, "Service ID1 not available"); if (CONN_Create(connector, &conn) != eIO_Success) CORE_LOG(eLOG_Fatal, "Failed to create connection"); if (CONN_Write(conn, "\xA4\x80\x02\x01\x02\x00", 7, &n, eIO_WritePersist) != eIO_Success) { CONN_Close(conn); CORE_LOG(eLOG_Fatal, "Cannot write to service ID1"); } assert(n == 7); if (CONN_Read(conn, ibuf, sizeof(ibuf), &n, eIO_ReadPlain) != eIO_Success){ CONN_Close(conn); CORE_LOG(eLOG_Fatal, "Cannot read from service ID1"); } CORE_LOGF(eLOG_Note, ("%d bytes read from service ID1", n)); CONN_Close(conn); #endif CORE_LOG(eLOG_Note, "TEST completed successfully"); CORE_SetLOG(0); return 0/*okay*/; }
int main(int argc, const char* argv[]) { const char* inp_file = (argc > 5) ? argv[5] : ""; const char* user_header = (argc > 6) ? argv[6] : ""; SConnNetInfo* net_info; CONNECTOR connector; CONN conn; EIO_Status status; char buffer[100]; size_t n_read, n_written; /* Prepare to connect: parse and check cmd.-line args, etc. */ s_Args.host = (argc > 1) ? argv[1] : ""; s_Args.port = (argc > 2) ? argv[2] : ""; s_Args.path = (argc > 3) ? argv[3] : ""; s_Args.args = (argc > 4) ? argv[4] : ""; fprintf(stderr, "Running '%s':\n" " URL host: '%s'\n" " URL port: '%s'\n" " URL path: '%s'\n" " URL args: '%s'\n" " Input data file: '%s'\n" " User header: '%s'\n" "Reply(if any) from the hit URL goes to the standard output.\n\n", argv[0], s_Args.host, s_Args.port, s_Args.path, s_Args.args, inp_file, user_header); /* Log stream */ CORE_SetLOGFormatFlags(fLOG_None | fLOG_Level | fLOG_OmitNoteLevel | fLOG_DateTime); CORE_SetLOGFILE(stderr, 0/*false*/); /* Tune to the test URL using hard-coded pseudo-registry */ CORE_SetREG( REG_Create(0, s_REG_Get, 0, 0, 0) ); SOCK_SetupSSL(NcbiSetupTls); /* Usage */ if (argc < 4) { fprintf(stderr, "Usage: %s host port path [args] [inp_file] [user_header]\n" "Example: %s www.ncbi.nlm.nih.gov 80 " "/Service/bounce.cgi 'arg1+arg2+arg3'\n", argv[0], argv[0]); CORE_LOG(eLOG_Fatal, "Too few arguments"); return 1; } /* Connect */ if (atoi(s_Args.port) == CONN_PORT_HTTPS) { verify((net_info = ConnNetInfo_Create(0)) != 0); net_info->scheme = eURL_Https; } else net_info = 0; connector = HTTP_CreateConnector(net_info, user_header, 0); assert(connector); verify(CONN_Create(connector, &conn) == eIO_Success); ConnNetInfo_Destroy(net_info); /* If input file specified, then send its content (as HTTP request body) */ if (*inp_file) { FILE* inp_fp; if (strcmp(inp_file, "-") != 0) { static const char kDevNull[] = #ifdef NCBI_OS_MSWIN "NUL" #else "/dev/null" #endif /*NCBI_OS_MSWIN*/ ; if (strcmp(inp_file, "+") == 0) inp_file = kDevNull; if (!(inp_fp = fopen(inp_file, "rb"))) { CORE_LOGF(eLOG_Fatal, ("Cannot open file '%s' for reading", inp_file)); } } else inp_fp = stdin; for (;;) { n_read = fread(buffer, 1, sizeof(buffer), inp_fp); if (n_read <= 0) { assert(feof(inp_fp)); break; /* EOF */ } status = CONN_Write(conn, buffer, n_read, &n_written, eIO_WritePersist); if (status != eIO_Success) { CORE_LOGF(eLOG_Fatal, ("Unable to write to URL: %s",IO_StatusStr(status))); } assert(n_written == n_read); } fclose(inp_fp); } /* Read reply from connection, write it to standard output */ for (;;) { status = CONN_Read(conn,buffer,sizeof(buffer),&n_read,eIO_ReadPlain); if (status != eIO_Success) break; if (connector) puts("----- [BEGIN] HTTP Content -----"); fwrite(buffer, 1, n_read, stdout); fflush(stdout); connector = 0; } if (!connector) { puts("\n----- [END] HTTP Content -----"); fclose(stdout); } if (status != eIO_Closed) { CORE_LOGF(eLOG_Fatal, ("Unable to read from URL: %s", IO_StatusStr(status))); } /* Success: close the connection, cleanup, and exit */ CONN_Close(conn); CORE_SetREG(0); CORE_LOG(eLOG_Note, "TEST completed successfully"); CORE_SetLOG(0); return 0; }
streamsize CConn_Streambuf::xsputn(const CT_CHAR_TYPE* buf, streamsize m) { if (!m_Conn || m < 0) return 0; _ASSERT((Uint8) m < numeric_limits<size_t>::max()); m_Status = eIO_Success; size_t n = (size_t) m; size_t n_written = 0; size_t x_written; do { if (pbase()) { if (n && pbase() + n < epptr()) { // Would entirely fit into the buffer not causing an overflow x_written = (size_t)(epptr() - pptr()); if (x_written > n) x_written = n; if (x_written) { memcpy(pptr(), buf, x_written); pbump(int(x_written)); n_written += x_written; n -= x_written; if (!n) return (streamsize) n_written; buf += x_written; } } size_t x_towrite = (size_t)(pptr() - pbase()); if (x_towrite) { m_Status = CONN_Write(m_Conn, pbase(), x_towrite, &x_written, eIO_WritePlain); _ASSERT(x_written <= x_towrite); if (!x_written) { _ASSERT(m_Status != eIO_Success); ERR_POST_X(6, x_Message("xsputn(): " " CONN_Write() failed")); break; } memmove(pbase(), pbase() + x_written, x_towrite - x_written); x_PPos += (CT_OFF_TYPE) x_written; pbump(-int(x_written)); continue; } } _ASSERT(m_Status == eIO_Success); m_Status = CONN_Write(m_Conn, buf, n, &x_written, eIO_WritePlain); _ASSERT(x_written <= n); if (!x_written && n) { _ASSERT(m_Status != eIO_Success); ERR_POST_X(7, x_Message("xsputn(): " " CONN_Write(direct) failed")); break; } x_PPos += (CT_OFF_TYPE) x_written; n_written += x_written; n -= x_written; if (!n) return (streamsize) n_written; buf += x_written; } while (m_Status == eIO_Success); _ASSERT(n && m_Status != eIO_Success); if (pbase()) { x_written = (size_t)(epptr() - pptr()); if (x_written) { if (x_written > n) x_written = n; memcpy(pptr(), buf, x_written); n_written += x_written; pbump(int(x_written)); } } return (streamsize) n_written; }