void X509Certificate_OpenSSL::write (utility::outputStream& os, const Format format) const { BIO* membio = 0; int dataSize = 0; unsigned char* out = 0; if (format == FORMAT_DER) { if ((dataSize = i2d_X509(m_data->cert, &out)) < 0) goto err; os.write(reinterpret_cast <utility::stream::value_type*>(out), dataSize); os.flush(); OPENSSL_free(out); } else if (format == FORMAT_PEM) { membio = BIO_new(BIO_s_mem()); BIO_set_close(membio, BIO_CLOSE); if (!PEM_write_bio_X509(membio, m_data->cert)) goto pem_err; dataSize = BIO_get_mem_data(membio, &out); os.write(reinterpret_cast <utility::stream::value_type*>(out), dataSize); os.flush(); BIO_vfree(membio); } else { throw vmime::exceptions::unsupported_certificate_type("Unknown cert type"); } return; // #### Early Return #### pem_err: { if (membio) BIO_vfree(membio); } err: { char errstr[256]; long ec = ERR_get_error(); ERR_error_string(ec, errstr); throw vmime::exceptions::certificate_exception( "OpenSSLX509Certificate_OpenSSL::write exception - " + string(errstr)); } }
void charsetConverter_Win::convert(utility::inputStream& in, utility::outputStream& out) { char s8_Buffer[32000]; string s_In, s_Out; while (!in.eof()) { size_t len = in.read(s8_Buffer, sizeof(s8_Buffer)); s_In.append(s8_Buffer, len); } convert(s_In, s_Out); out.write(s_Out.data(), s_Out.length()); }
void maildirMessage::extractImpl(utility::outputStream& os, utility::progressListener* progress, const size_t start, const size_t length, const size_t partialStart, const size_t partialLength, const bool /* peek */) const { shared_ptr <const maildirFolder> folder = m_folder.lock(); shared_ptr <utility::fileSystemFactory> fsf = platform::getHandler()->getFileSystemFactory(); const utility::file::path path = folder->getMessageFSPath(m_num); shared_ptr <utility::file> file = fsf->create(path); shared_ptr <utility::fileReader> reader = file->getFileReader(); shared_ptr <utility::inputStream> is = reader->getInputStream(); is->skip(start + partialStart); byte_t buffer[8192]; size_t remaining = (partialLength == static_cast <size_t>(-1) ? length : std::min(partialLength, length)); const size_t total = remaining; size_t current = 0; if (progress) progress->start(total); while (!is->eof() && remaining > 0) { const size_t read = is->read(buffer, std::min(remaining, sizeof(buffer))); remaining -= read; current += read; os.write(buffer, read); if (progress) progress->progress(current, total); } if (progress) progress->stop(total); // TODO: mark as read unless 'peek' is set }
void X509Certificate::write (utility::outputStream& os, const Format format) const { size_t dataSize = 0; gnutls_x509_crt_fmt fmt = GNUTLS_X509_FMT_DER; switch (format) { case FORMAT_DER: fmt = GNUTLS_X509_FMT_DER; break; case FORMAT_PEM: fmt = GNUTLS_X509_FMT_PEM; break; } gnutls_x509_crt_export(m_data->cert, fmt, NULL, &dataSize); std::vector <byte_t> data(dataSize); gnutls_x509_crt_export(m_data->cert, fmt, &data[0], &dataSize); os.write(reinterpret_cast <utility::stream::value_type*>(&data[0]), dataSize); }
size_t POP3Response::readResponseImpl (string& firstLine, utility::outputStream& os, utility::progressListener* progress, const size_t predictedSize) { size_t current = 0, total = predictedSize; string temp; bool codeDone = false; if (progress) progress->start(total); if (m_timeoutHandler) m_timeoutHandler->resetTimeOut(); utility::inputStreamSocketAdapter sis(*m_socket); utility::stopSequenceFilteredInputStream <5> sfis1(sis, "\r\n.\r\n"); utility::stopSequenceFilteredInputStream <3> sfis2(sfis1, "\n.\n"); utility::dotFilteredInputStream dfis(sfis2); // "\n.." --> "\n." utility::inputStream& is = dfis; while (!is.eof()) { // Check whether the time-out delay is elapsed if (m_timeoutHandler && m_timeoutHandler->isTimeOut()) { if (!m_timeoutHandler->handleTimeOut()) throw exceptions::operation_timed_out(); } // Receive data from the socket byte_t buffer[65536]; const size_t read = is.read(buffer, sizeof(buffer)); if (read == 0) // buffer is empty { if (m_socket->getStatus() & socket::STATUS_WANT_WRITE) { m_socket->waitForWrite(); } else if (m_socket->getStatus() & socket::STATUS_WANT_READ) { m_socket->waitForRead(); } else { // Input stream needs more bytes to continue, but there // is enough data into socket buffer. Do not waitForRead(), // just retry read()ing on the stream. } continue; } // We have received data: reset the time-out counter if (m_timeoutHandler) m_timeoutHandler->resetTimeOut(); // Notify progress current += read; if (progress) { total = std::max(total, current); progress->progress(current, total); } // If we don't have extracted the response code yet if (!codeDone) { vmime::utility::stringUtils::appendBytesToString(temp, buffer, read); string responseData; if (stripFirstLine(temp, responseData, &firstLine) == true) { PDBG0( "firstLine: %s", firstLine.c_str() ); if (getResponseCode(firstLine) != CODE_OK) throw exceptions::command_error("?", firstLine); codeDone = true; os.write(responseData.data(), responseData.length()); temp.clear(); continue; } } else { // Inject the data into the output stream os.write(buffer, read); } } if (progress) progress->stop(total); return current; }
void charsetConverter::convert(utility::inputStream& in, utility::outputStream& out) { if (m_desc == NULL) throw exceptions::charset_conv_error("Cannot initialize converter."); const iconv_t cd = *static_cast <iconv_t*>(m_desc); char inBuffer[32768]; char outBuffer[32768]; size_t inPos = 0; bool prevIsInvalid = false; while (true) { // Fullfill the buffer size_t inLength = static_cast <size_t>(in.read(inBuffer + inPos, sizeof(inBuffer) - inPos) + inPos); size_t outLength = sizeof(outBuffer); const char* inPtr = inBuffer; char* outPtr = outBuffer; // Convert input bytes if (iconv(cd, ICONV_HACK(&inPtr), &inLength, &outPtr, &outLength) == static_cast <size_t>(-1)) { // Illegal input sequence or input sequence has no equivalent // sequence in the destination charset. if (prevIsInvalid) { // Write successfully converted bytes out.write(outBuffer, sizeof(outBuffer) - outLength); // Output a special character to indicate we don't known how to // convert the sequence at this position out.write("?", 1); // Skip a byte and leave unconverted bytes in the input buffer std::copy(const_cast <char*>(inPtr + 1), inBuffer + sizeof(inBuffer), inBuffer); inPos = inLength - 1; } else { // Write successfully converted bytes out.write(outBuffer, sizeof(outBuffer) - outLength); // Leave unconverted bytes in the input buffer std::copy(const_cast <char*>(inPtr), inBuffer + sizeof(inBuffer), inBuffer); inPos = inLength; if (errno != E2BIG) prevIsInvalid = true; } } else { // Write successfully converted bytes out.write(outBuffer, sizeof(outBuffer) - outLength); inPos = 0; prevIsInvalid = false; } // Check for end of data if (in.eof() && inPos == 0) break; } }
void charsetConverter_icu::convert (utility::inputStream& in, utility::outputStream& out, status* st) { UErrorCode err = U_ZERO_ERROR; ucnv_reset(m_from); ucnv_reset(m_to); if (st) new (st) status(); // From buffers byte_t cpInBuffer[16]; // stream data put here const size_t outSize = ucnv_getMinCharSize(m_from) * sizeof(cpInBuffer) * sizeof(UChar); std::vector <UChar> uOutBuffer(outSize); // Unicode chars end up here // To buffers // converted (char) data end up here const size_t cpOutBufferSz = ucnv_getMaxCharSize(m_to) * outSize; std::vector <char> cpOutBuffer(cpOutBufferSz); // Tell ICU what to do when encountering an illegal byte sequence if (m_options.silentlyReplaceInvalidSequences) { // Set replacement chars for when converting from Unicode to codepage icu::UnicodeString substString(m_options.invalidSequence.c_str()); ucnv_setSubstString(m_to, substString.getTerminatedBuffer(), -1, &err); if (U_FAILURE(err)) throw exceptions::charset_conv_error("[ICU] Error when setting substitution string."); } else { // Tell ICU top stop (and return an error) on illegal byte sequences ucnv_setToUCallBack (m_from, UCNV_TO_U_CALLBACK_STOP, UCNV_SUB_STOP_ON_ILLEGAL, NULL, NULL, &err); if (U_FAILURE(err)) throw exceptions::charset_conv_error("[ICU] Error when setting ToU callback."); ucnv_setFromUCallBack (m_to, UCNV_FROM_U_CALLBACK_STOP, UCNV_SUB_STOP_ON_ILLEGAL, NULL, NULL, &err); if (U_FAILURE(err)) throw exceptions::charset_conv_error("[ICU] Error when setting FromU callback."); } // Input data available while (!in.eof()) { // Read input data into buffer size_t inLength = in.read(cpInBuffer, sizeof(cpInBuffer)); // Beginning of read data const char* source = reinterpret_cast <const char*>(&cpInBuffer[0]); const char* sourceLimit = source + inLength; // end + 1 UBool flush = in.eof(); // is this last run? UErrorCode toErr; // Loop until all source has been processed do { // Set up target pointers UChar* target = &uOutBuffer[0]; UChar* targetLimit = &target[0] + outSize; toErr = U_ZERO_ERROR; ucnv_toUnicode(m_from, &target, targetLimit, &source, sourceLimit, NULL, flush, &toErr); if (st) st->inputBytesRead += (source - reinterpret_cast <const char*>(&cpInBuffer[0])); if (toErr != U_BUFFER_OVERFLOW_ERROR && U_FAILURE(toErr)) { if (toErr == U_INVALID_CHAR_FOUND || toErr == U_TRUNCATED_CHAR_FOUND || toErr == U_ILLEGAL_CHAR_FOUND) { // Error will be thrown later (*) } else { throw exceptions::charset_conv_error("[ICU] Error converting to Unicode from " + m_source.getName()); } } // The Unicode source is the buffer just written and the limit // is where the previous conversion stopped (target is moved in the conversion) const UChar* uSource = &uOutBuffer[0]; UChar* uSourceLimit = &target[0]; UErrorCode fromErr; // Loop until converted chars are fully written do { char* cpTarget = &cpOutBuffer[0]; const char* cpTargetLimit = &cpOutBuffer[0] + cpOutBufferSz; fromErr = U_ZERO_ERROR; // Write converted bytes (Unicode) to destination codepage ucnv_fromUnicode(m_to, &cpTarget, cpTargetLimit, &uSource, uSourceLimit, NULL, flush, &fromErr); if (st) { // Decrement input bytes count by the number of input bytes in error char errBytes[16]; int8_t errBytesLen = sizeof(errBytes); UErrorCode errBytesErr = U_ZERO_ERROR; ucnv_getInvalidChars(m_from, errBytes, &errBytesLen, &errBytesErr); st->inputBytesRead -= errBytesLen; st->outputBytesWritten += cpTarget - &cpOutBuffer[0]; } // (*) If an error occurred while converting from input charset, throw it now if (toErr == U_INVALID_CHAR_FOUND || toErr == U_TRUNCATED_CHAR_FOUND || toErr == U_ILLEGAL_CHAR_FOUND) { throw exceptions::illegal_byte_sequence_for_charset(); } if (fromErr != U_BUFFER_OVERFLOW_ERROR && U_FAILURE(fromErr)) { if (fromErr == U_INVALID_CHAR_FOUND || fromErr == U_TRUNCATED_CHAR_FOUND || fromErr == U_ILLEGAL_CHAR_FOUND) { throw exceptions::illegal_byte_sequence_for_charset(); } else { throw exceptions::charset_conv_error("[ICU] Error converting from Unicode to " + m_dest.getName()); } } // Write to destination stream out.write(&cpOutBuffer[0], (cpTarget - &cpOutBuffer[0])); } while (fromErr == U_BUFFER_OVERFLOW_ERROR); } while (toErr == U_BUFFER_OVERFLOW_ERROR); } }