mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-08-22 12:23:08 +09:00
145 lines
3.8 KiB
C++
145 lines
3.8 KiB
C++
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "nsMsgCompressOStream.h"
|
|
#include "prio.h"
|
|
#include "prmem.h"
|
|
|
|
#define BUFFER_SIZE 16384
|
|
|
|
nsMsgCompressOStream::nsMsgCompressOStream() :
|
|
m_zbuf(nullptr)
|
|
{
|
|
}
|
|
|
|
nsMsgCompressOStream::~nsMsgCompressOStream()
|
|
{
|
|
Close();
|
|
}
|
|
|
|
NS_IMPL_ISUPPORTS(nsMsgCompressOStream, nsIOutputStream)
|
|
|
|
nsresult nsMsgCompressOStream::InitOutputStream(nsIOutputStream *rawStream)
|
|
{
|
|
// protect against repeat calls
|
|
if (m_oStream)
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
// allocate some memory for a buffer
|
|
m_zbuf = mozilla::MakeUnique<char[]>(BUFFER_SIZE);
|
|
if (!m_zbuf)
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
// set up the zlib object
|
|
m_zstream.zalloc = Z_NULL;
|
|
m_zstream.zfree = Z_NULL;
|
|
m_zstream.opaque = Z_NULL;
|
|
|
|
// http://zlib.net/manual.html is rather silent on the topic, but
|
|
// perl's Compress::Raw::Zlib manual says:
|
|
// -WindowBits [...]
|
|
// To compress an RFC 1951 data stream, set WindowBits to -MAX_WBITS.
|
|
if (deflateInit2(&m_zstream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
|
|
-MAX_WBITS, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY) != Z_OK)
|
|
return NS_ERROR_FAILURE;
|
|
|
|
m_oStream = rawStream;
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
/* void close (); */
|
|
NS_IMETHODIMP nsMsgCompressOStream::Close()
|
|
{
|
|
if (m_oStream)
|
|
{
|
|
m_oStream = nullptr;
|
|
deflateEnd(&m_zstream);
|
|
}
|
|
m_zbuf = nullptr;
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgCompressOStream::Write(const char *buf, uint32_t count, uint32_t *result)
|
|
{
|
|
if (!m_oStream)
|
|
return NS_BASE_STREAM_CLOSED;
|
|
|
|
m_zstream.next_in = (Bytef *) buf;
|
|
m_zstream.avail_in = count;
|
|
|
|
// keep looping until the buffer doesn't get filled
|
|
do
|
|
{
|
|
m_zstream.next_out = (Bytef *) m_zbuf.get();
|
|
m_zstream.avail_out = BUFFER_SIZE;
|
|
// Using "Z_SYNC_FLUSH" may cause excess flushes if the calling
|
|
// code does a lot of small writes. An option with the IMAP
|
|
// protocol is to check the buffer for "\n" at the end, but
|
|
// in the interests of keeping this generic, don't optimise
|
|
// yet. An alternative is to require ->Flush always, but that
|
|
// is likely to break callers.
|
|
int zr = deflate(&m_zstream, Z_SYNC_FLUSH);
|
|
if (zr == Z_STREAM_END || zr == Z_BUF_ERROR)
|
|
zr = Z_OK; // not an error for our purposes
|
|
if (zr != Z_OK)
|
|
return NS_ERROR_FAILURE;
|
|
|
|
uint32_t out_size = BUFFER_SIZE - m_zstream.avail_out;
|
|
const char *out_buf = m_zbuf.get();
|
|
|
|
// push everything in the buffer before repeating
|
|
while (out_size)
|
|
{
|
|
uint32_t out_result;
|
|
nsresult rv = m_oStream->Write(out_buf, out_size, &out_result);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
if (!out_result)
|
|
return NS_BASE_STREAM_CLOSED;
|
|
out_size -= out_result;
|
|
out_buf += out_result;
|
|
}
|
|
|
|
// http://www.zlib.net/manual.html says:
|
|
// If deflate returns with avail_out == 0, this function must be
|
|
// called again with the same value of the flush parameter and
|
|
// more output space (updated avail_out), until the flush is
|
|
// complete (deflate returns with non-zero avail_out).
|
|
} while (!m_zstream.avail_out);
|
|
|
|
*result = count;
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgCompressOStream::Flush(void)
|
|
{
|
|
if (!m_oStream)
|
|
return NS_BASE_STREAM_CLOSED;
|
|
|
|
return m_oStream->Flush();
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgCompressOStream::WriteFrom(nsIInputStream *inStr, uint32_t count, uint32_t *_retval)
|
|
{
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgCompressOStream::WriteSegments(nsReadSegmentFun reader, void * closure, uint32_t count, uint32_t *_retval)
|
|
{
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
/* boolean isNonBlocking (); */
|
|
NS_IMETHODIMP nsMsgCompressOStream::IsNonBlocking(bool *aNonBlocking)
|
|
{
|
|
*aNonBlocking = false;
|
|
return NS_OK;
|
|
}
|
|
|