From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- comm/mailnews/base/src/nsMsgLineBuffer.h | 123 +++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 comm/mailnews/base/src/nsMsgLineBuffer.h (limited to 'comm/mailnews/base/src/nsMsgLineBuffer.h') diff --git a/comm/mailnews/base/src/nsMsgLineBuffer.h b/comm/mailnews/base/src/nsMsgLineBuffer.h new file mode 100644 index 0000000000..2ac579be3b --- /dev/null +++ b/comm/mailnews/base/src/nsMsgLineBuffer.h @@ -0,0 +1,123 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ +#ifndef _nsMsgLineBuffer_H +#define _nsMsgLineBuffer_H + +#include "msgCore.h" // precompiled header... + +// I can't believe I have to have this stupid class, but I can't find +// anything suitable (nsStrImpl might be, when it's done). nsIByteBuffer +// would do, if I had a stream for input, which I don't. + +class nsByteArray { + public: + nsByteArray(); + virtual ~nsByteArray(); + uint32_t GetSize() { return m_bufferSize; } + uint32_t GetBufferPos() { return m_bufferPos; } + nsresult GrowBuffer(uint64_t desired_size, uint32_t quantum = 1024); + nsresult AppendString(const char* string); + nsresult AppendBuffer(const char* buffer, uint32_t length); + void ResetWritePos() { m_bufferPos = 0; } + char* GetBuffer() { return m_buffer; } + + protected: + char* m_buffer; + uint32_t m_bufferSize; + uint32_t + m_bufferPos; // write Pos in m_buffer - where the next byte should go. +}; + +/** + * nsMsgLineBuffer breaks up incoming data into lines. + * It accepts CRLF, CR or LF line endings. + * + * Data is fed in via BufferInput(). The virtual HandleLine() will be + * invoked for each line. The data passed to HandleLine() is verbatim, + * and will include whatever line endings were in the source data. + * + * Flush() should be called when the data is exhausted, to handle any + * leftover bytes in the buffer (e.g. if the data doesn't end with an EOL). + */ +class nsMsgLineBuffer : private nsByteArray { + public: + nsMsgLineBuffer(); + virtual ~nsMsgLineBuffer(); + nsresult BufferInput(const char* net_buffer, int32_t net_buffer_size); + + /** + * HandleLine should be implemented by derived classes, to handle a line. + * The line will have whatever end-of-line characters were present in the + * source data (potentially none, if the data ends mid-line). + */ + virtual nsresult HandleLine(const char* line, uint32_t line_length) = 0; + + /** + * Flush processes any unprocessed data currently in the buffer. Should + * be called when the source data is exhausted. + */ + nsresult Flush(); +}; + +// I'm adding this utility class here for lack of a better place. This utility +// class is similar to nsMsgLineBuffer except it works from an input stream. It +// is geared towards efficiently parsing new lines out of a stream by storing +// read but unprocessed bytes in a buffer. I envision the primary use of this to +// be our mail protocols such as imap, news and pop which need to process line +// by line data being returned in the form of a proxied stream from the server. + +class nsIInputStream; + +class nsMsgLineStreamBuffer { + public: + NS_INLINE_DECL_REFCOUNTING(nsMsgLineStreamBuffer) + + // aBufferSize -- size of the buffer you want us to use for buffering stream + // data + // aEndOfLinetoken -- The delimiter string to be used for determining the end + // of line. This allows us to parse platform specific end of + // line endings by making it a parameter. + // aAllocateNewLines -- true if you want calls to ReadNextLine to allocate new + // memory for the line. + // if false, the char * returned is just a ptr into the buffer. + // Subsequent calls to ReadNextLine will alter the data so your + // ptr only has a life time of a per call. + // aEatCRLFs -- true if you don't want to see the CRLFs on the lines + // returned by ReadNextLine. + // false if you do want to see them. + // aLineToken -- Specify the line token to look for, by default is LF ('\n') + // which cover as well CRLF. If lines are terminated with a CR + // only, you need to set aLineToken to CR ('\r') + nsMsgLineStreamBuffer( + uint32_t aBufferSize, bool aAllocateNewLines, bool aEatCRLFs = true, + char aLineToken = '\n'); // specify the size of the buffer you want the + // class to use.... + + // Caller must free the line returned using PR_Free + // aEndOfLinetoken -- delimiter used to denote the end of a line. + // aNumBytesInLine -- The number of bytes in the line returned + // aPauseForMoreData -- There is not enough data in the stream to make a line + // at this time... + char* ReadNextLine(nsIInputStream* aInputStream, uint32_t& aNumBytesInLine, + bool& aPauseForMoreData, nsresult* rv = nullptr, + bool addLineTerminator = false); + nsresult GrowBuffer(uint32_t desiredSize); + void ClearBuffer(); + bool NextLineAvailable(); + + private: + virtual ~nsMsgLineStreamBuffer(); + + protected: + bool m_eatCRLFs; + bool m_allocateNewLines; + char* m_dataBuffer; + uint32_t m_dataBufferSize; + uint32_t m_startPos; + uint32_t m_numBytesInBuffer; + char m_lineToken; +}; + +#endif -- cgit v1.2.3