//
// File: hzXbuf.h
//
// Legal Notice: This file is part of the HadronZoo C++ Class Library.
//
// Copyright 2025 HadronZoo Project (http://www.hadronzoo.com)
//
// The HadronZoo C++ Class Library is free software: You can redistribute it, and/or modify it under the terms of the GNU Lesser General Public License, as published by the Free
// Software Foundation, either version 3 of the License, or any later version.
//
// The HadronZoo C++ Class Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
// A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License along with the HadronZoo C++ Class Library. If not, see http://www.gnu.org/licenses.
//
#ifndef hzXbuf_h
#define hzXbuf_h
#include <iostream>
#include <fstream>
#include <stdarg.h>
#include "hzBasedefs.h"
#include "hzString.h"
#include "hzTmplArray.h"
class hzEmaddr ;
class hzIpaddr ;
/*
** Section 2: The hzXbuf class
*/
class hzXbuf
{
// Category: Data
//
// hzXbuf can be considered a variant of hzChain. Both are chains of blocks that act as unlimited buffers, but where hzChain is aimed at string value assembly, hzXbuf is aimed
// at storing internal RAM Primacy data. hzXbuf is used in the data cache of the HDB data object repository, hdbObjRepos, and by the hdbIdset class.
//
// To these ends, hzXbuf uses a different allocation regime, does not support a Printf function, and cannot be reverse iterated.
struct _xbuf
{
// hzXbuf control area
uint32_t m_nSize ; // Total size in bytes
uint16_t m_copy ; // Copy count
uint16_t m_blox ; // Block count
void* m_Begin ; // Address of first block in chain
void* m_End ; // Address of last block in chain
_xbuf (void) ;
~_xbuf (void) ;
} ;
_xbuf* mx ; // Smart pointer to contents
int32_t _compare (const hzXbuf& op) const ;
public:
struct Iter
{
// Standard bytewise chain iterator
void* m_block ; // Current block address
uint32_t m_nLine ; // For tracking line numbers
uint32_t m_nCol ; // Column number
uint16_t m_nOset ; // Current offset within block
char m_cDefault ; // Default char
char m_Reserved ; // Not used at present
Iter (void)
{
// Construct and init the chain iterator
m_block = 0 ;
m_nLine = 1 ;
m_nCol = 0 ;
m_nOset = 0 ;
m_cDefault = 0 ;
}
// Read unicode char
hzEcode ReadUnicodeChar (uint32_t& uniVal) ;
// Skip whitespace
Iter& Skipwhite (void) ;
// Misc functions
uint32_t Line (void) { return m_nLine ; }
uint32_t Col (void) { return m_nCol ; }
void Line (uint32_t n) { m_nLine = n ; }
uchar current (void) const ;
bool eof (void) const ;
// Operators to set iterator position
Iter& operator= (const hzXbuf& I)
{
// Set this chain iterator to the start of the supplied chain
if (I.mx)
m_block = I.mx->m_Begin ;
else
m_block = 0 ;
m_nLine = 1 ;
m_nCol = 0 ;
m_nOset = 0 ;
return *this ;
}
Iter& operator= (const Iter& I)
{
// Set this chain iterator to another
m_block = I.m_block ;
m_nLine = I.m_nLine ;
m_nOset = I.m_nOset ;
m_cDefault = I.m_cDefault ;
return *this ;
}
// Write out block of chars to buffer. Return bytes written out but don't increment iterator (do that in app with the return value)
uint32_t Write (void* pBuf, uint32_t maxBytes) ;
bool operator== (const Iter& I) const { return m_block == I.m_block && m_nOset == I.m_nOset ? true : false ; }
bool operator!= (const Iter& I) const { return m_block == I.m_block && m_nOset == I.m_nOset ? false : true ; }
// Advance (increment without column/line accounting)
uint32_t Advance (uint32_t nInc) ;
// Increment and decrement
Iter& operator++ (void) ;
Iter& operator++ (int) ;
Iter& operator+= (uint32_t nInc) ;
// Case sensitive compare functions
bool Equal (const uchar c) const ;
bool Equal (const uchar* s) const ;
bool Equal (const hzString& S) const { return Equal(*S) ; }
// Case in-sensitive compare functions
bool Equiv (const uchar c) const ;
bool Equiv (const uchar* s) const ;
bool Equiv (const hzString& S) const { return Equiv(*S) ; }
// Compare operators
bool operator== (const uchar c) const { return Equal(c) ; }
bool operator== (const uchar* s) const { return Equal(s) ; }
bool operator== (hzString& S) const { return Equal(S) ; }
bool operator== (Iter& I) const { return m_block == I.m_block && m_nOset == I.m_nOset ? true : false ; }
bool operator!= (const uchar c) const { return !Equal(c) ; }
bool operator!= (const uchar* s) const { return !Equal(s) ; }
bool operator!= (hzString& S) const { return !Equal(S) ; }
bool operator!= (Iter& I) const { return m_block == I.m_block && m_nOset == I.m_nOset ? false : true ; }
// Set current char
uchar operator= (const uchar c) ;
// Get current or offset char
uchar operator[] (uint32_t nOset) const ;
uchar operator* (void) const ;
// Diagnostics
uint32_t _oset (void) { return m_nOset ; }
} ;
void Clear (void) ;
// Constructors/Destructors
hzXbuf (void) ;
hzXbuf (const hzXbuf& op) ;
~hzXbuf (void) ;
// Get hzXbuf attributes
uint32_t Size (void) const { return mx ? mx->m_nSize : 0 ; }
// Set chain contents
hzXbuf& operator= (const hzXbuf& op) ;
hzXbuf& operator= (const hzString& S) ;
hzXbuf& operator= (const char* pStr) ;
// Test operator
bool operator! (void) { return Size() > 0 ? false : true ; }
// Append void* data to the chain. Note as there is no null termination the number of bytes to append must be specified.
uint32_t Append (const void* vpBuf, uint32_t nBytes) ;
// Append a sub-chain
//uint32_t AppendSub (hzXbuf& Z, uint32_t nStart, uint32_t nBytes) ;
// Append single character
hzEcode AddByte (const char c) ;
// Append whole entities by operators
hzXbuf& operator+= (const uchar* s) ;
hzXbuf& operator+= (const hzString& s) ;
hzXbuf& operator+= (const hzXbuf& op) ;
hzXbuf& operator+= (const hzChain& Z) ;
// Compare operators
bool operator== (const hzXbuf& op) const { return _compare(op) == 0 ? true : false ; }
bool operator!= (const hzXbuf& op) const { return _compare(op) != 0 ? true : false ; }
bool operator< (const hzXbuf& op) const { return _compare(op) < 0 ? true : false ; }
bool operator<= (const hzXbuf& op) const { return _compare(op) <= 0 ? true : false ; }
bool operator> (const hzXbuf& op) const { return _compare(op) > 0 ? true : false ; }
bool operator>= (const hzXbuf& op) const { return _compare(op) >= 0 ? true : false ; }
} ;
#define xbufIter hzXbuf::Iter
#endif // hzXbuf_h