#pragma once #ifndef _SerialPortServer_DLL #define SERIALPORTSERVER_API _declspec(dllimport) #else #define SERIALPORTSERVER_API _declspec(dllexport) #endif struct StreamData { long nRefs; // reference count int nDataLength; // length of data (including terminator) int nAllocLength; // length of allocation // char data[nAllocLength] char * data () // char* to managed data { return (char*) (this+1); } }; class SERIALPORTSERVER_API Stream { public: Stream (); // copy constructor Stream (const Stream & stream); // from characters Stream (const char * lpsz, int length); // from characters Stream (const char * lpsz); // from unsigned characters Stream (const unsigned char * lpsz) { Init(); *this = (const char *) lpsz; } // alloc Stream (int length); // Attributes & Operations // get data length int GetLength () const { return GetData ()->nDataLength; } // TRUE if zero length BOOL IsEmpty () const { return (GetData ()->nDataLength == 0); } // clear contents to empty void Empty (); // return single character at zero-based index char GetAt (int nIndex) const { return m_pchData[nIndex]; } // return single character at zero-based index char operator [] (int nIndex) const { return GetAt (nIndex); } // set a single character at zero-based index void SetAt (int nIndex, char ch); // return pointer to const string operator const char * () const { return m_pchData; } const char * constBuffer (void) const { return m_pchData; } // overloaded assignment // ref-counted copy from another Stream Stream & operator = (const Stream & stringSrc); // copy string content from ANSI string (converts to char) Stream & operator = (const char * lpsz); // copy string content from unsigned chars Stream & operator = (const unsigned char * lpsz) { *this = (const char *) lpsz; return *this; } // get pointer to modifiable buffer at least as long as nMinBufLength char * GetBuffer (int nMinBufLength); // get pointer to modifiable buffer exactly as long as nNewLength char * GetBufferSetLength (int nNewLength); // Use LockBuffer/UnlockBuffer to turn refcounting off // turn refcounting back on char * LockBuffer (); // turn refcounting off void UnlockBuffer (); // Implementation public: ~Stream (); int GetAllocLength () const { return GetData ()->nAllocLength; } protected: char * m_pchData; // pointer to ref counted string data protected: // implementation helpers StreamData * Stream::GetData() const { return ((StreamData *) m_pchData)-1; } void Init (); void AllocCopy (Stream & dest, int nCopyLen, int nCopyIndex, int nExtraLen) const; void AllocBuffer (int nLen); void AssignCopy (int nSrcLen, const char * lpszSrcData); void ConcatCopy (int nSrc1Len, const char * lpszSrc1Data, int nSrc2Len, const char * lpszSrc2Data); void ConcatInPlace (int nSrcLen, const char * lpszSrcData); void CopyBeforeWrite (); void AllocBeforeWrite (int nLen); void Release (); static void Release (StreamData * pData); static void FreeData (StreamData * pData); };