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; }
CT_INT_TYPE CConn_Streambuf::underflow(void) { _ASSERT(gptr() >= egptr()); if (!m_Conn) return CT_EOF; // flush output buffer, if tied up to it if (m_Tie && x_sync() != 0) return CT_EOF; #ifdef NCBI_COMPILER_MIPSPRO if (m_MIPSPRO_ReadsomeGptrSetLevel && m_MIPSPRO_ReadsomeGptr != gptr()) return CT_EOF; m_MIPSPRO_ReadsomeGptr = (CT_CHAR_TYPE*)(-1L); #endif /*NCBI_COMPILER_MIPSPRO*/ // read from connection size_t n_read; m_Status = CONN_Read(m_Conn, m_ReadBuf, m_BufSize, &n_read, eIO_ReadPlain); _ASSERT(n_read <= m_BufSize); if (!n_read) { _ASSERT(m_Status != eIO_Success); if (m_Status != eIO_Closed) ERR_POST_X(8, x_Message("underflow(): CONN_Read() failed")); return CT_EOF; } // update input buffer with the data just read x_GPos += (CT_OFF_TYPE) n_read; setg(m_ReadBuf, m_ReadBuf, m_ReadBuf + n_read); return CT_TO_INT_TYPE(*m_ReadBuf); }
static Nlm_Int2 LIBCALL AsnIoConnRead ( Pointer ptr, CharPtr buf, Nlm_Uint2 count ) { size_t bytes; AsnIoConnPtr aicp; aicp = (AsnIoConnPtr) ptr; if (aicp == NULL || aicp->conn == NULL) return 0; CONN_Read (aicp->conn, buf, (size_t) count, &bytes, eIO_ReadPlain); 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_CopyResultsToFile ( CONN conn, FILE *fp ) { char* buffer; size_t n_read; EIO_Status status; if (conn == NULL || fp == NULL) return; buffer = (char*) MemNew(URL_QUERY_BUFLEN + 1); if (buffer != NULL) { do { status = CONN_Read (conn, buffer, URL_QUERY_BUFLEN, &n_read, eIO_ReadPlain); if ( n_read ) FileWrite (buffer, 1, n_read, fp); } while (status == eIO_Success); MemFree (buffer); } }
static Int2 LIBCALLBACK s_AsnRead(Pointer conn, CharPtr buf, Uint2 len) { size_t n_read; CONN_Read((CONN) conn, buf, len, &n_read, eIO_ReadPlain); return (Int2) n_read; }
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::showmanyc(void) { static const STimeout kZeroTmo = {0, 0}; _ASSERT(gptr() >= egptr()); if (!m_Conn) return -1L; // flush output buffer, if tied up to it if (m_Tie) x_sync(); const STimeout* tmo; const STimeout* timeout = CONN_GetTimeout(m_Conn, eIO_Read); if (timeout == kDefaultTimeout) { // HACK * HACK * HACK tmo = ((SMetaConnector*) m_Conn)->default_timeout; } else tmo = timeout; size_t x_read; bool backup = false; if (m_BufSize > 1) { if (eback() < gptr()) { x_Buf = gptr()[-1]; backup = true; } if (!tmo) _VERIFY(CONN_SetTimeout(m_Conn, eIO_Read, &kZeroTmo)==eIO_Success); m_Status = CONN_Read(m_Conn, m_ReadBuf + 1, m_BufSize - 1, &x_read, eIO_ReadPlain); if (!tmo) _VERIFY(CONN_SetTimeout(m_Conn, eIO_Read, timeout) ==eIO_Success); _ASSERT(x_read > 0 || m_Status != eIO_Success); } else { m_Status = CONN_Wait(m_Conn, eIO_Read, tmo ? tmo : &kZeroTmo); x_read = 0; } if (!x_read) { switch (m_Status) { case eIO_Success: _ASSERT(m_BufSize <= 1); return 1L; // can read at least 1 byte case eIO_Timeout: if (!tmo || !(tmo->sec | tmo->usec)) break; /*FALLTHRU*/ case eIO_Closed: return -1L; // EOF default: break; } return 0; // no data available immediately } m_ReadBuf[0] = x_Buf; _ASSERT(m_BufSize > 1); setg(m_ReadBuf + !backup, m_ReadBuf + 1, m_ReadBuf + 1 + x_read); x_GPos += x_read; return x_read; }
streamsize CConn_Streambuf::xsgetn(CT_CHAR_TYPE* buf, streamsize m) { if (!m_Conn) return 0; // flush output buffer, if tied up to it if (m_Tie && x_sync() != 0) return 0; if (m < 0) return 0; _ASSERT((Uint8) m < numeric_limits<size_t>::max()); size_t n = (size_t) m; size_t n_read; if (n) { // first, read from the memory buffer n_read = (size_t)(egptr() - gptr()); if (n_read > n) n_read = n; memcpy(buf, gptr(), n_read); gbump(int(n_read)); n -= n_read; if (!n) return (streamsize) n_read; buf += n_read; } else n_read = 0; do { // next, read from the connection size_t x_toread = n && n < m_BufSize ? m_BufSize : n; CT_CHAR_TYPE* x_buf = n < m_BufSize ? m_ReadBuf : buf; size_t x_read; m_Status = CONN_Read(m_Conn, x_buf, x_toread, &x_read, eIO_ReadPlain); _ASSERT(x_read <= x_toread); if (!x_read) { _ASSERT(!x_toread || m_Status != eIO_Success); if (m_Status != eIO_Success && m_Status != eIO_Closed) ERR_POST_X(10, x_Message("xsgetn(): CONN_Read() failed")); break; } x_GPos += (CT_OFF_TYPE) x_read; // satisfy "usual backup condition", see standard: 27.5.2.4.3.13 if (x_buf == m_ReadBuf) { size_t xx_read = x_read; if (x_read > n) x_read = n; memcpy(buf, m_ReadBuf, x_read); setg(m_ReadBuf, m_ReadBuf + x_read, m_ReadBuf + xx_read); } else { _ASSERT(x_read <= n); size_t xx_read = x_read > m_BufSize ? m_BufSize : x_read; memcpy(m_ReadBuf, buf + x_read - xx_read, xx_read); setg(m_ReadBuf, m_ReadBuf + xx_read, m_ReadBuf + xx_read); } n_read += x_read; if (m_Status != eIO_Success) break; buf += x_read; n -= x_read; } while (n); return (streamsize) n_read; }