// // File: hdbObject.cpp // // 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. //
// // Implimentation of the HadronZoo Proprietary Database Suite //
#include <iostream> #include <fstream> #include <cstdio>
#include <unistd.h> #include <stdlib.h> #include <fcntl.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h>
#include "hzBasedefs.h" #include "hzString.h" #include "hzChars.h" #include "hzChain.h" #include "hzDate.h" #include "hzTextproc.h" #include "hzCodec.h" #include "hzDocument.h" #include "hzDirectory.h" #include "hzDatabase.h" #include "hzDelta.h" #include "hzProcess.h"
using namespace std ;
/* ** Definitions */
struct _val_idx { // Applicable only to atomic members with multiple values
uint16_t m_First ; // In the root entry for the member, this is the address of first value in buffer. In subsequent entries it is the position. uint16_t m_Last ; // In the root entry for the member, this is the address of last value in buffer. In subsequent entries it is the address of the next entry. uint32_t m_Data ; // Data area } ;
class _obj_data { // Support class to hold data object on behalf of hdbObject. // // hdbObject is constructed as a wrapper, with the actual object member values held by a tree of one or more _obj_data instances. If the hdbObject native class has no subclass // members, the _obj_data will be singular, otherwise a branch is formed for each subclass member. In each branch there will be an _obj_data instance for each subclass object. // hdbObject has a single _obj_data pointer to the root. // // _obj_data has a fixed size core buffer to store member values. Within this members are assigned slots, sized and aligned in accordance with datum size as per the data type. // Values are written to and read from the slots by means of a pointer, cast to the applicable type. In the case of subclass members, which always anticipate multiple subclass // objects, the slot is cast to an array of _obj_data pointers.
_obj_data (void) { m_pArrValues = 0 ; m_pClass = 0 ; m_ObjId = 0 ; m_copy = 0 ; }
public: //hzMapM <uint16_t,_atomval>* m_pArrValues ; // This is created if ANY class members expect arrays hzXbuf* m_pArrValues ; // This is psudo array, created if ANY class members expect arrays
const hdbClass* m_pClass ; // Applicable data class _mut uint32_t m_ObjId ; // Current object id _mut int16_t m_copy ; // Copy count int16_t m_Resv ; // Reserved uchar m_Core[8] ; // Start of core, actual size will fit the data class
static _obj_data* GetInstance (const hdbClass* pClass) ;
~_obj_data (void) { Clear() ; }
_obj_data& operator= (const _obj_data* pOD) { Clear() ; if (m_pArrValues) delete m_pArrValues ; return *this ; }
uchar* Litmus (void) ; hzEcode Clear (void) ; hzEcode Integrity (hzChain& err) ;
// Member value SET functions hzEcode SetBool (const hdbMember* pMbr, bool bValue) ; hzEcode SetBinAddr (const hdbMember* pMbr, uint32_t datumId) ; hzEcode SetBinary (const hdbMember* pMbr, const hzChain& Z) ; hzEcode SetValue (const hdbMember* pMbr, const hzAtom& atom) ; hzEcode SetObject (const hdbMember* pMbr, const _obj_data* pOD) ; hzEcode _setMbrValue (const hdbMember* pMbr, const hzMD5& md5) ; hzEcode _setMbrValue (const hdbMember* pMbr, const hzString& str) ; hzEcode _setMbrValue (const hdbMember* pMbr, const hzDomain& dom) ; hzEcode _setMbrValue (const hdbMember* pMbr, const hzEmaddr& ema) ; hzEcode _setMbrValue (const hdbMember* pMbr, const hzUrl& url) ; hzEcode _setMbrValue (const hdbMember* pMbr, const hzXDate& xdate) ; hzEcode _setMbrValue (const hdbMember* pMbr, const hzSDate& sdate) ; hzEcode _setMbrValue (const hdbMember* pMbr, const hzTime& time) ; hzEcode _setMbrValue (const hdbMember* pMbr, uint64_t val) ; hzEcode _setMbrValue (const hdbMember* pMbr, int64_t val) ; hzEcode _setMbrValue (const hdbMember* pMbr, uint32_t val) ; hzEcode _setMbrValue (const hdbMember* pMbr, int32_t val) ;
// Member value GET functions hzEcode GetBool (bool& result, const hdbMember* pMbr) const ; hzEcode GetBinAddr (uint32_t& datumId, const hdbMember* pMbr) const ; hzEcode GetValue (hzAtom& atom, const hdbMember* pMbr, uint32_t nOset) const ; hzEcode GetMbrValue (hzMD5& md5, const hdbMember* pMbr) const ; hzEcode GetMbrValue (hzString& str, const hdbMember* pMbr) const ; hzEcode GetMbrValue (hzDomain& dom, const hdbMember* pMbr) const ; hzEcode GetMbrValue (hzEmaddr& ema, const hdbMember* pMbr) const ; hzEcode GetMbrValue (hzUrl& url, const hdbMember* pMbr) const ; hzEcode GetMbrValue (hzIpaddr& ipa, const hdbMember* pMbr) const ; hzEcode GetMbrValue (hzXDate& xd, const hdbMember* pMbr) const ; hzEcode GetMbrValue (hzSDate& sd, const hdbMember* pMbr) const ; hzEcode GetMbrValue (hzTime& time, const hdbMember* pMbr) const ; hzEcode GetMbrValue (uint32_t& val, const hdbMember* pMbr) const ; } ;
/* ** _obj_data Functions */
_obj_data* _obj_data::GetInstance (const hdbClass* pClass) { // Constructor is private so this function is the only means of instantiation. This ensures the _obj_data is set to a data class and has a core buffer sized in accordance with // the data class.
_obj_data* pOD ; // The new object uchar* pSpace ; // Space for the new object (16 bytes plus actual length of the core
if (!pClass) hzexit(E_ARGUMENT, "No class supplied") ;
pSpace = new uchar[pClass->CoreLen() + pClass->MbrCount() + 24] ; memset(pSpace, 0, pClass->CoreLen() + pClass->MbrCount() + 24) ; pOD = (_obj_data*) pSpace ; pOD->m_pClass = pClass ; if (pClass->HasArrays()) { //pOD->m_pArrValues = new hzMapM<uint16_t,_atomval> ; pOD->m_pArrValues = new hzXbuf ; //threadLog("Created value array %p\n", pOD->m_pArrValues) ; } pOD->m_copy = 1 ; return pOD ; }
uchar* _obj_data::Litmus (void) { // Return array of litmus bytes
if (m_pClass) return m_Core + m_pClass->CoreLen() ;
return 0 ; }
hzEcode _obj_data::Clear (void) { // Decrement the copy count and when this falls to 0, clear the content. // // Note that actual content deletion requires the data class, as this determines whether the _obj_data buffer can contain pointers to further space. Subclass members will need // to call this function recursively. // // As a further note, where subclass objects apply, the _obj_data of subclass object are deleted by this function, directly after clearing. However this _obj_data instance is // only cleared. It is not deleted at this stage. // // Arguments: None // // Returns: E_NOINIT Object not initialized // E_CORRUPT If there is a mismatch between value amd indicator // E_OK Operation successful. All atoms at null values
_hzfunc("_obj_data::Clear") ;
const hdbMember* pMbr ; // This class member hzChain* pCh ; // Cast to chain hzString* pStr ; // Cast to string hzDomain* pDom ; // Cast to domain hzEmaddr* pEma ; // Cast to emaddr hzUrl* pUrl ; // Cast to URL uchar* pLitmus ; // Litmus bits uchar* pMCS ; // Pointer to member core space uint32_t mbrNo ; // Member number uint32_t nA ; // Counter
if (!this) hzexit(E_CORRUPT, "No instance") ; if (!m_pClass) hzexit(E_CORRUPT, "No Class") ; if (m_copy < 1) return hzerr(E_CORRUPT, "Class %s Object Already cleared", m_pClass->txtName()) ;
// Perform an actual delete, but leave the _obj_data to be deleted by hdbObject::Clear() pLitmus = Litmus() ;
// Clear member data spaces for (mbrNo = 0 ; mbrNo < m_pClass->MbrCount() ; mbrNo++) { pMbr = m_pClass->GetMember(mbrNo) ;
if (!pLitmus[pMbr->Posn()]) continue ;
if (pMbr->Basetype() == BASETYPE_BOOL || pMbr->Basetype() == BASETYPE_TBOOL) continue ;
pMCS = m_Core + pMbr->OsetStd() ;
if (pMbr->Basetype() == BASETYPE_CLASS) { hzArray <_obj_data*>* pArr ; // Cast to array of subclass objects _obj_data* pSub ; // Subclass object
pArr = (hzArray<_obj_data*>*) pMCS ;
if (pArr) { threadLog("Clearing object array %p with %u objects\n", pArr, pArr->Count()) ; for (nA = 0 ; nA < pArr->Count() ; nA++) { threadLog("Clearing sub %u\n", nA) ; pSub = pArr->operator[](nA) ; if (pSub) { threadLog("Clearing sub %p\n", pSub) ; pSub->Clear() ; } } pArr->Clear() ; threadLog("Cleared object array %p with %u objects\n", pArr, pArr->Count()) ; }
continue ; }
switch (pMbr->Basetype()) { case BASETYPE_BINARY: case BASETYPE_TXTDOC: pMCS = m_Core + pMbr->OsetAux() ; pCh = (hzChain*) pMCS ; pCh->Clear() ; break ;
case BASETYPE_STRING: pStr = (hzString*) pMCS ; pStr->Clear() ; break ; case BASETYPE_DOMAIN: pDom = (hzDomain*) pMCS ; pDom->Clear() ; break ; case BASETYPE_EMADDR: pEma = (hzEmaddr*) pMCS ; pEma->Clear() ; break ; case BASETYPE_URL: pUrl = (hzUrl*) pMCS ; pUrl->Clear() ; break ; } }
// Empty values array if it exists if (m_pArrValues) { m_pArrValues->Clear() ; //delete m_pArrValues ; //m_pArrValues = 0 ; }
// Finally clear the core memset(m_Core, 0, m_pClass->CoreLen() + m_pClass->MbrCount()) ; return E_OK ; }
hzEcode _obj_data::Integrity (hzChain& err) { // Check integrity // // Arguments: None // // Returns: E_NOINIT Object not initialized // E_CORRUPT If there is a mismatch between value amd indicator // E_NODATA If a member has a min pop of 1 and no value // E_OK Operation successful. All atoms at null values
_hzfunc("_obj_data::Integrity") ;
const hdbMember* pMbr ; // This class member uchar* pMCS ; // Member core space uchar* pLitmus ; // Litmus bits _atomval av ; // Member value uint32_t n ; // Counter hzEcode rc ; // Return code
if (!m_pClass) return E_NOINIT ;
pLitmus = m_Core + m_pClass->CoreLen() ;
err.Printf("Class %s, core size %u [", m_pClass->txtName(), m_pClass->CoreLen()) ; for (n = 0 ; n < m_pClass->CoreLen() ; n++) { err.Printf(" %02x", m_Core[n]) ; } err << " ]\n" ;
// Check member data space and litmus values for (n = 0 ; n < m_pClass->MbrCount() ; n++) { pMbr = m_pClass->GetMember(n) ;
err.Printf("\tMember %u of %u %s (datum size %u oset %u aux %d): ", n+1, m_pClass->MbrCount(), pMbr->txtName(), pMbr->SizeDatum(), pMbr->OsetStd(), pMbr->OsetAux()) ;
if (pMbr->Basetype() == BASETYPE_BOOL || pMbr->Basetype() == BASETYPE_TBOOL) { // Contained in litmus bits so the test does not apply err << "Boolean\n" ; continue ; }
pMCS = m_Core + pMbr->OsetStd() ;
if (pMbr->Basetype() == BASETYPE_CLASS) { hzArray <_obj_data*>* pArr ; // Cast to array of subclass objects _obj_data* pSub ; // Subclass object uint64_t* pTest ; // Test if array exists
pTest = (uint64_t*) pMCS ; if (*pTest == 0) continue ;
pArr = (hzArray<_obj_data*>*) pMCS ; for (n = 0 ; n < pArr->Count() ; n++) { pSub = pArr->operator[](n) ; rc = pSub->Integrity(err) ; } continue ; }
if (pMbr->Basetype() == BASETYPE_BINARY || pMbr->Basetype() == BASETYPE_TXTDOC) { pMCS = m_Core + pMbr->OsetStd() ; av.m_uInt64 = 0 ; memcpy(&av, pMCS, 4) ;
if (av.m_uInt64) err.Printf("Member has datum id\n") ; else { if (pMbr->Compulsory()) { rc = E_NODATA ; err.Printf("Member requires datum id\n") ; } else err.Printf("Member NULL but OK\n") ; } continue ; }
// All other members have core space only pMCS = m_Core + pMbr->OsetStd() ; av.m_uInt64 = 0 ; if (pMbr->SizeDatum() > 8) memcpy(&av, pMCS, 8) ; else memcpy(&av, pMCS, pMbr->SizeDatum()) ;
if (pLitmus[n] & LITMUS_ERR) { rc = E_CORRUPT ; err.Printf("Bad value\n") ; continue ; }
if (av.m_uInt64 == 0) { if (pMbr->Basetype() >= BASETYPE_INT64 && pMbr->Basetype() <= BASETYPE_UBYTE) { // Litmus disambiguates zero so if the litmus is clear, 0 is still legal err << "Numeric\n" ; continue ; }
if (!pLitmus[n]) err << "Both NULL\n" ; else { rc = E_CORRUPT ; err.Printf("No value but litmus set to %u\n", pLitmus[n]) ; } if (pMbr->Compulsory()) { rc = E_NODATA ; err.Printf("Member requires a value\n") ; } continue ; }
if (!(pLitmus[n] & LITMUS_SET)) { rc = E_CORRUPT ; err.Printf("Value found (%u) but not indicated\n", av.m_uInt64) ; continue ; }
err.Printf("Litmus %u value %u\n", pLitmus[n], av.m_uInt64) ; }
if (rc != E_OK) { threadLog("ERROR:-\n") ; threadOut(err) ; }
return rc ; }
hzEcode _obj_data::SetBool (const hdbMember* pMbr, bool bValue) { // Set boolean member within data object. The object must be initialized to a data class, and the supplied member must exist within that class and be of datatype BOOL or TBOOL // // Arguments: 1) pMbr The member // 2) bValue The boolean value the member will be set to // // Returns: E_NOINIT If the object has not been initialized to a class // E_ARGUMENT If no member is supplied // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not atomic (is another class) or if the supplied atom has the wrong type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("_obj_data::SetBool") ;
uchar* pLitmus ; // Litmus bits
if (!this) hzexit(E_CORRUPT, "No instance") ; if (!pMbr) hzexit(E_ARGUMENT, "No member") ;
if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
pLitmus = Litmus() ; //m_Core + m_pClass->CoreLen() ;
if (pMbr->Basetype() == BASETYPE_BOOL) { pLitmus[pMbr->Posn()] = LITMUS_SET ; return E_OK ; }
if (pMbr->Basetype() == BASETYPE_TBOOL) { pLitmus[pMbr->Posn()] = 0 ; pLitmus[pMbr->Posn()] |= LITMUS_SET ; if (bValue) pLitmus[pMbr->Posn()] |= LITMUS_AUX ; return E_OK ; }
return hzerr(E_TYPE, "Member %s is not BOOL or TBOOL", pMbr->txtName()) ; }
hzEcode _obj_data::SetBinAddr (const hdbMember* pMbr, uint32_t datumId) { // Set binary datum address // // Arguments: 1) pMbr The member // 2) datumId The datum id, as per the asigned binary datum repository // // Returns: E_NOINIT If the object has not been initialized to a class // E_ARGUMENT If no member is supplied // E_CORRUPT If no instance or the supplied member number does not identify an object class member. // E_TYPE If the object class member is not atomic (is another class) or if the supplied atom has the wrong type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("_obj_data::SetBinAddr") ;
uint32_t* pInt ; // Internal cast uchar* pLitmus ; // Litmus bits
if (!this) hzexit(E_CORRUPT, "No instance") ; if (!pMbr) hzexit(E_ARGUMENT, "No member") ;
if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_BINARY && pMbr->Basetype() != BASETYPE_TXTDOC) return hzerr(E_TYPE, "%s->%s is not of binary data type", m_pClass->txtName(), pMbr->txtName()) ;
if (datumId) { pLitmus = Litmus() ; pInt = (uint32_t*) (m_Core + pMbr->OsetStd()) ; *pInt = datumId ; pLitmus[pMbr->Posn()] |= LITMUS_SET ; } return E_OK ; }
hzEcode _obj_data::SetBinary (const hdbMember* pMbr, const hzChain& Z) { // Set binary member value within data object. // // The object must be initialized to a data class, and the supplied member must exist within that class and be of a BINARY datatype. This function will copy the supplied chain // to the core entry of the applicable member, and sets the member litmus byte to LITMUS_SET to state that the member has a new value. The chain is NOT committed to the target // binary repository at this juncture. This will only happen when the onject as a whole is committed to the applicable data object repository, in either an INSERT or an UPDATE // operation. // // Note that BINARY members have an aux core entry in addition to the standard core entry. The aux is used to store the datum id of the chain. This is only set on a FETCH. In // a new object, the aux is 0. In an existing object, the aux will contain the datim id that was previously assigned. On UPDATE, if the chain has changed, the datum id in the // aux is used to DELETE the previous datum. // // Arguments: 1) pMbr The member // 2) Z The chain value the member will be set to // // Returns: E_NOINIT If the object has not been initialized to a class // E_ARGUMENT If no member is supplied // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not atomic (is another class) or if the supplied atom has the wrong type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("_obj_data::SetBinary") ;
hzChain* pCh ; // Internal cast uchar* pLitmus ; // Litmus bits uchar* pUch ; // Member space
if (!this) hzexit(E_CORRUPT, "No instance") ; if (!pMbr) hzexit(E_ARGUMENT, "No member") ;
if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_BINARY && pMbr->Basetype() != BASETYPE_TXTDOC) return hzerr(E_TYPE, "%s->%s is not of binary data type", m_pClass->txtName(), pMbr->txtName()) ;
threadLog("Setting member %s to chain of %u bytes\n", pMbr->txtName(), Z.Size()) ;
pLitmus = m_Core + m_pClass->CoreLen() ; pUch = m_Core + pMbr->OsetAux() ; pCh = (hzChain*) pUch ; *pCh = Z ; if (Z.Size()) pLitmus[pMbr->Posn()] |= LITMUS_AUX ; else pLitmus[pMbr->Posn()] |= ~LITMUS_AUX ; return E_OK ; }
hzEcode _obj_data::SetValue (const hdbMember* pMbr, const hzAtom& atom) { // Set member value within data object. The object must be initialized to a data class, and the supplied member must exist within that class. Note that in the case of BINARY // and TXTDOC members, the expected data type is UINT32, being the binary datum id. // // Arguments: 1) pMbr The member // 2) atom The atomic value the member will be set to // // Returns: E_NOINIT If the object has not been initialized to a class // E_ARGUMENT If no member is supplied // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not atomic (is another class) or if the supplied atom has the wrong type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("_obj_data::SetValue") ;
_atomval av ; // atom data uint64_t* pUI64 ; // Cast to uint64 ; uint32_t* pUI32 ; // Cast to uint64 ; uchar* pLitmus ; // Litmus bits uchar* pMCS ; // Pointer to member core space
// Object has class? if (!this) hzexit(E_CORRUPT, "No instance") ; if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ;
if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
// Check status if (atom.Status() == ATOM_ERROR) return hzerr(E_BADVALUE, "Member %s not set", pMbr->txtName()) ;
pLitmus = m_Core + m_pClass->CoreLen() ;
if (atom.IsNull()) { threadLog("NULL value - Member %s not set\n", pMbr->txtName()) ; pLitmus[pMbr->Posn()] = LITMUS_NULL ; return E_OK ; }
if (atom.Type() != pMbr->Basetype()) return hzerr(E_TYPE, "Type mismatch (Mbr %s %s, atom %s)\n", pMbr->txtName(), Basetype2Txt(pMbr->Basetype()), Basetype2Txt(atom.Type())) ;
pLitmus[pMbr->Posn()] = LITMUS_SET ; if (pMbr->Basetype() == BASETYPE_BOOL) return E_OK ;
if (pMbr->Basetype() == BASETYPE_TBOOL) { if (atom.Bool() == true) pLitmus[pMbr->Posn()] |= LITMUS_AUX ; return E_OK ; }
pMCS = m_Core + pMbr->OsetStd() ;
// Set the value in the object if (pMbr->Basetype() == BASETYPE_STRING) _setMbrValue(pMbr, atom.Str()) ; else if (pMbr->Basetype() == BASETYPE_DOMAIN) _setMbrValue(pMbr, atom.Domain()) ; else if (pMbr->Basetype() == BASETYPE_EMADDR) _setMbrValue(pMbr, atom.Emaddr()) ; else if (pMbr->Basetype() == BASETYPE_URL) _setMbrValue(pMbr, atom.Url()) ; else if (pMbr->Basetype() == BASETYPE_XDATE) _setMbrValue(pMbr, atom.XDate()) ;
else if (pMbr->Basetype() == BASETYPE_BINARY || pMbr->Basetype() == BASETYPE_TXTDOC) { // Only set address uint32_t* pInt ;
pUI32 = (uint32_t*) pMCS ; *pUI32 = atom.Unt32() ; } else { av = atom.Datum() ;
switch (pMbr->Basetype()) { //case BASETYPE_XDATE: memcpy(pMCS, &av, 8) ; break ; //case BASETYPE_SDATE: memcpy(pMCS, &av.m_uInt32, 4) ; break ; //case BASETYPE_TIME: memcpy(pMCS, &av.m_uInt32, 4) ; break ;
//case BASETYPE_XDATE: pUI64 = (uint64_t*) pMCS ; *pUI64 = av.m_uInt64 ; break ; case BASETYPE_SDATE: pUI32 = (uint32_t*) pMCS ; *pUI32 = av.m_uInt32 ; break ; case BASETYPE_TIME: pUI32 = (uint32_t*) pMCS ; *pUI32 = av.m_uInt32 ; break ; default: memcpy(pMCS, &av, pMbr->SizeDatum()) ; break ; } }
return E_OK ; }
hzEcode _obj_data::SetObject (const hdbMember* pMbr, const _obj_data* pOD) { // Either add a new subclass data object or return a modified subclass data object, to the supplied host class member. In the case of a new subclass data object, the object id // will be zero. In the case of a modified subclass data object, this must necessarily have been fetched, so will have the object id it was given when originally added. // // This object must be initialized to the host data class and the supplied data object must be initialized to subclass introduced by the applicable host class member. // // Arguments: 1) pMbr The subclass member of this, the host class object // 2) pOD Pointer to the subclass _obj_data instance to be placed in the host class member space // // Returns: E_NOINIT If the object has not been initialized to a class // E_ARGUMENT If no member is supplied // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not atomic (is another class) or if the supplied atom has the wrong type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("hdbObject::SetObject") ;
hzArray <const _obj_data*>* pArr ; // Cast of core entry to object array
uchar* pMCS ; // Member core space uchar* pLitmus ; // Litmus bits hzEcode rc ; // Return code
// Object has class? if (!this) hzexit(E_CORRUPT, "No instance") ; if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ; if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_CLASS) return hzerr(E_TYPE, "Member %s is atomic", pMbr->txtName()) ;
// Set litmus and core space pointers pMCS = m_Core + pMbr->OsetStd() ; pLitmus = m_Core + m_pClass->CoreLen() ;
// Cast the array pArr = (hzArray<const _obj_data*>*) pMCS ; if (pMbr->OsetStd() % 8) hzexit(E_CORRUPT, "8 byte alignement - %u %p\n", pMbr->OsetStd(), pMCS) ; // Copy object data into the member data list pOD->m_copy++ ; rc = pArr->Add(pOD) ; if (rc != E_OK) return hzerr(rc, "Could not add to array") ;
pLitmus[pMbr->Posn()] = LITMUS_SET ; return rc ; }
hzEcode _obj_data::_setMbrValue (const hdbMember* pMbr, const hzMD5& md5) { // Set the supplied member with the value of the supplied digest // // Arguments: 1) str The string to be set // 2) pMbr Pointer to the data class member // // Returns: E_NOINIT If the object has not been initialized to a class // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not a string or a string-like data type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("_obj_data::_setMbrValue(md5)") ;
hzMD5* pMd5 ; // MD5 pointer uchar* pLitmus ; // Litmus bits
if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ; if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_DIGEST) return hzerr(E_TYPE, "Member %s is not an MD5 digest", pMbr->txtName()) ;
// Cast the member space to an MD5, then set it. pMd5 = (hzMD5*) (m_Core + pMbr->OsetStd()) ; *pMd5 = md5 ;
pLitmus = m_Core + m_pClass->CoreLen() ; pLitmus[pMbr->Posn()] = LITMUS_SET ;
return E_OK ; }
hzEcode _obj_data::_setMbrValue (const hdbMember* pMbr, const hzString& str) { // Set value of the supplied member in the object, with the supplied string // // Arguments: 1) pMbr Pointer to the member to be set // 2) str The string value // // Returns: E_NOINIT If the object has not been initialized to a class // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not a string or a string-like data type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("_obj_data::_setMbrValue(str)") ;
uchar* pLitmus ; // Litmus bits hzString* pStr ; // Pointer to string
if (!m_pClass) return hzerr(E_NOINIT, "Object has no class") ; if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ;
if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_STRING) return hzerr(E_TYPE, "Member %s is not a string", pMbr->txtName()) ;
pLitmus = m_Core + m_pClass->CoreLen() ;
// Copy string to member entry if (pMbr->Singular()) { pStr = (hzString*) (m_Core + pMbr->OsetStd()) ; *pStr = str ; }
pLitmus[pMbr->Posn()] = str ? LITMUS_SET : 0 ; if (!str) return E_OK ;
// Ensure string is in the string repository _hzGlobal_setStrings.Insert(str) ;
return E_OK ; }
hzEcode _obj_data::_setMbrValue (const hdbMember* pMbr, const hzDomain& dom) { // Set value of the supplied member in the object, with the supplied domain // // Arguments: 1) pMbr Pointer to the member to be set // 2) dom The domain name value // // Returns: E_NOINIT If the object has not been initialized to a class // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not a string or a string-like data type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("_obj_data::_setMbrValue(domain)") ;
uchar* pLitmus ; // Litmus bits hzDomain* pDom ; // Member entry cast to domain
if (!m_pClass) return hzerr(E_NOINIT, "Object has no class") ; if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ;
if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_DOMAIN) return E_TYPE ;
pLitmus = m_Core + m_pClass->CoreLen() ;
// Ensure domain is in the domain repository _hzGlobal_setDomains.Insert(dom) ;
// Copy domain to member entry if (pMbr->Singular()) { pDom = (hzDomain*) (m_Core + pMbr->OsetStd()) ; *pDom = dom ; pLitmus[pMbr->Posn()] = dom ? LITMUS_SET : 0 ; }
return E_OK ; }
hzEcode _obj_data::_setMbrValue (const hdbMember* pMbr, const hzEmaddr& ema) { // Set the supplied string with the value of the supplied member // // Arguments: 1) pMbr Pointer to the member to be set // 2) dom The email address value // // Returns: E_NOINIT If the object has not been initialized to a class // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not a string or a string-like data type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("_obj_data::_setMbrValue(emaddr)") ;
//_atomval av ; // Atomval hzEmaddr newEma ; // Make sure the emaddr is in _hzGlobal_setEmaddrs is used hzEmaddr* pEma ; // Member entry cast to emaddr uchar* pLitmus ; // Litmus bits
if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ; if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_EMADDR) return E_TYPE ;
pLitmus = m_Core + m_pClass->CoreLen() ;
// Ensure domain is in the domain repository _hzGlobal_setEmaddrs.Insert(ema) ; newEma = _hzGlobal_setEmaddrs[ema] ;
// Copy emaddr to member entry if (pMbr->Singular()) { pEma = (hzEmaddr*) (m_Core + pMbr->OsetStd()) ; *pEma = ema ; pLitmus[pMbr->Posn()] = ema ? LITMUS_SET : 0 ; }
return E_OK ; }
hzEcode _obj_data::_setMbrValue (const hdbMember* pMbr, const hzUrl& url) { // Set the supplied string with the value of the supplied member // // Arguments: 1) pMbr Pointer to the member to be set // 2) dom The email address value // // Returns: E_NOINIT If the object has not been initialized to a class // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not a string or a string-like data type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("_obj_data::_setMbrValue(url)") ;
//hzUrl newUrl ; // Make sure the emaddr is in _hzGlobal_setEmaddrs is used hzUrl* pUrl ; // Member entry cast to emaddr uchar* pLitmus ; // Litmus bits
if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ; if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_URL) return E_TYPE ;
pLitmus = m_Core + m_pClass->CoreLen() ;
// Ensure URL is in the string repository?
// Copy URL to member entry if (pMbr->Singular()) { pUrl = (hzUrl*) (m_Core + pMbr->OsetStd()) ; *pUrl = url ; pLitmus[pMbr->Posn()] = url ? LITMUS_SET : 0 ; }
return E_OK ; }
hzEcode _obj_data::_setMbrValue (const hdbMember* pMbr, const hzXDate& xdate) { // Set the supplied string with the value of the supplied member // // Arguments: 1) pMbr Pointer to the member to be set // 2) dom The email address value // // Returns: E_NOINIT If the object has not been initialized to a class // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not a string or a string-like data type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("_obj_data::_setMbrValue(xdate)") ;
hzXDate* pXd ; // Internal cast uchar* pLitmus ; // Litmus bits
if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ; if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_XDATE) return E_TYPE ;
pLitmus = m_Core + m_pClass->CoreLen() ;
pXd = (hzXDate*) (m_Core + pMbr->OsetStd()) ; *pXd = xdate ; pLitmus[pMbr->Posn()] = xdate.IsNull() ? 0 : LITMUS_SET ; return E_OK ; }
hzEcode _obj_data::_setMbrValue (const hdbMember* pMbr, const hzSDate& sdate) { // Set the supplied string with the value of the supplied member // // Arguments: 1) pMbr Pointer to the member to be set // 2) dom The email address value // // Returns: E_NOINIT If the object has not been initialized to a class // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not a string or a string-like data type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("_obj_data::_setMbrValue(sdate)") ;
hzSDate* pSd ; // Internal cast uchar* pLitmus ; // Litmus bits
if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ; if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_SDATE) return E_TYPE ;
pLitmus = m_Core + m_pClass->CoreLen() ;
pSd = (hzSDate*) (m_Core + pMbr->OsetStd()) ; *pSd = sdate ; pLitmus[pMbr->Posn()] = sdate.IsNull() ? 0 : LITMUS_SET ; return E_OK ; }
hzEcode _obj_data::_setMbrValue (const hdbMember* pMbr, const hzTime& time) { // Set the supplied string with the value of the supplied member // // Arguments: 1) pMbr Pointer to the member to be set // 2) dom The email address value // // Returns: E_NOINIT If the object has not been initialized to a class // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not a string or a string-like data type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("_obj_data::_setMbrValue(time)") ;
hzTime* pTime ; // Internal cast uchar* pLitmus ; // Litmus bits
if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ; if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_TIME) return E_TYPE ;
pLitmus = m_Core + m_pClass->CoreLen() ;
pTime = (hzTime*) (m_Core + pMbr->OsetStd()) ; *pTime = time ; pLitmus[pMbr->Posn()] = time.IsNull() ? 0 : LITMUS_SET ; return E_OK ; }
hzEcode _obj_data::_setMbrValue (const hdbMember* pMbr, uint64_t val) { _hzfunc("_obj_data::_setMbrValue(uint64)") ;
uint64_t* pUint ; // Internal cast uchar* pLitmus ; // Litmus bits
if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ; if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_UINT64) return E_TYPE ;
pLitmus = m_Core + m_pClass->CoreLen() ;
pUint = (uint64_t*) (m_Core + pMbr->OsetStd()) ; *pUint = val ; pLitmus[pMbr->Posn()] = LITMUS_SET ; return E_OK ; }
hzEcode _obj_data::_setMbrValue (const hdbMember* pMbr, int64_t val) { _hzfunc("_obj_data::_setMbrValue(int64)") ;
int64_t* pInt ; // Internal cast uchar* pLitmus ; // Litmus bits
if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ; if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_INT64) return E_TYPE ;
pLitmus = m_Core + m_pClass->CoreLen() ;
pInt = (int64_t*) (m_Core + pMbr->OsetStd()) ; *pInt = val ; pLitmus[pMbr->Posn()] = LITMUS_SET ; return E_OK ; }
hzEcode _obj_data::_setMbrValue (const hdbMember* pMbr, uint32_t val) { _hzfunc("_obj_data::_setMbrValue(uint32)") ;
uint32_t* pUint ; // Internal cast uchar* pLitmus ; // Litmus bits
if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ; if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_UINT32) return E_TYPE ;
pLitmus = m_Core + m_pClass->CoreLen() ;
pUint = (uint32_t*) (m_Core + pMbr->OsetStd()) ; *pUint = val ; pLitmus[pMbr->Posn()] = LITMUS_SET ; return E_OK ; }
hzEcode _obj_data::_setMbrValue (const hdbMember* pMbr, int32_t val) { _hzfunc("_obj_data::_setMbrValue(int32)") ;
int32_t* pInt ; // Internal cast uchar* pLitmus ; // Litmus bits
if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ; if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_INT32) return E_TYPE ;
pLitmus = m_Core + m_pClass->CoreLen() ;
pInt = (int32_t*) (m_Core + pMbr->OsetStd()) ; *pInt = val ; pLitmus[pMbr->Posn()] = LITMUS_SET ; return E_OK ; }
/* ** _obj_data Get Functions */
hzEcode _obj_data::GetBool (bool& result, const hdbMember* pMbr) const { // Get boolean member within data object. The object must be initialized to a data class, and the supplied member must exist within that class and be of datatype BOOL or TBOOL // // Arguments: 1) result The bool result // 2) pMbr Member pointer // // Returns: E_NOINIT If the object has not been initialized to a class // E_ARGUMENT If no member is supplied // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not atomic (is another class) or if the supplied atom has the wrong type. // E_NODATA If the member is of type TBOOL and has not been set // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("_obj_data::GetBool") ;
const uchar* pLitmus ; // Litmus bits
if (!this) hzexit(E_CORRUPT, "No instance") ;
if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ; if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
pLitmus = m_Core + m_pClass->CoreLen() ;
if (pMbr->Basetype() == BASETYPE_BOOL) { result = pLitmus[pMbr->Posn()] & LITMUS_SET ? true : false ; return E_OK ; }
if (pMbr->Basetype() == BASETYPE_TBOOL) { if (pLitmus[pMbr->Posn()] & LITMUS_SET) result = pLitmus[pMbr->Posn()] & LITMUS_AUX ? true : false ; else return E_NODATA ; }
result = false ; return hzerr(E_TYPE, "Member %s is not BOOL or TBOOL", pMbr->txtName()) ; }
hzEcode _obj_data::GetBinAddr (uint32_t& datumId, const hdbMember* pMbr) const { // Get binary datum address // // Arguments: 1) datumId The datum id, as per the asigned binary datum repository // 2) pMbr The member // // Returns: E_NOINIT If the object has not been initialized to a class // E_ARGUMENT If no member is supplied // E_CORRUPT If no instance or the supplied member number does not identify an object class member. // E_TYPE If the object class member is not atomic (is another class) or if the supplied atom has the wrong type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("_obj_data::SetBinAddr") ;
uint32_t* pInt ; // Internal cast const uchar* pLitmus ; // Litmus bits
if (!this) hzexit(E_CORRUPT, "No instance") ; if (!pMbr) hzexit(E_ARGUMENT, "No member") ;
if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_BINARY && pMbr->Basetype() != BASETYPE_TXTDOC) return hzerr(E_TYPE, "%s->%s is not of binary data type", m_pClass->txtName(), pMbr->txtName()) ;
datumId = 0 ; pLitmus = m_Core + m_pClass->CoreLen() ; if (pLitmus[pMbr->Posn()] & LITMUS_SET) { pInt = (uint32_t*) (m_Core + pMbr->OsetStd()) ; datumId = *pInt ; }
return E_OK ; }
hzEcode _obj_data::GetValue (hzAtom& atom, const hdbMember* pMbr, uint32_t nOset) const { // Set the supplied atom with the value of the supplied member. Note that in the case of BINARY/TXTDOC members, the atom will be set with the binary datum id, not the binary // datum itself. // // Arguments: 1) atom The atom to be set // 2) pMbr Pointer to the data class member // 3) nOset Default 0, applicable only if the member is an array // // Returns: E_NOINIT If the object has not been initialized to a class // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not atomic (is another class) or if the supplied atom has the wrong type. // E_RANGE If the requested element (nOset) exceeds the number of member values // E_OK If the object class member has been set to the supplied atom value. _hzfunc("_obj_data::GetValue(atom)") ;
_atomval av ; // Value from atom const uchar* pLitmus ; // Litmus bits const uchar* pMCS ; // Pointer to member core space
atom.Clear() ;
// Object has class? if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ; if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
// For BOOL and TBOOL members, values are read from the litmus bits if (pMbr->Basetype() == BASETYPE_CLASS) return E_TYPE ;
pLitmus = m_Core + m_pClass->CoreLen() ;
if (nOset > 0) { if (pMbr->Singular()) return E_RANGE ; }
if (pMbr->Basetype() == BASETYPE_BOOL) { if (pLitmus[pMbr->Posn()] & LITMUS_SET) atom = true ; else atom = false ; return E_OK ; }
if (pMbr->Basetype() == BASETYPE_TBOOL) { if (pLitmus[pMbr->Posn()] & LITMUS_SET) { if (pLitmus[pMbr->Posn()] & LITMUS_AUX) atom = true ; else atom = false ; } // atom = (bool) m_pLitmus[pMbr->Posn()] & 0x02 ? true : false ; return E_OK ; }
if (!(pLitmus[pMbr->Posn()] & LITMUS_SET)) return E_NOTFOUND ;
// Get cast value pMCS = m_Core + pMbr->OsetStd() ;
if (pMbr->Basetype() == BASETYPE_STRING) { hzString* pStr ;
pStr = (hzString*) pMCS ; atom = *pStr ; } else if (pMbr->Basetype() == BASETYPE_DOMAIN) { hzDomain* pDom ;
pDom = (hzDomain*) pMCS ; atom = *pDom ; } else if (pMbr->Basetype() == BASETYPE_EMADDR) { hzEmaddr* pEma ;
pEma = (hzEmaddr*) pMCS ; atom = *pEma ; } else if (pMbr->Basetype() == BASETYPE_URL) { hzUrl* pUrl ;
pUrl = (hzUrl*) pMCS ; atom = *pUrl ; } else if (pMbr->Basetype() == BASETYPE_BINARY || pMbr->Basetype() == BASETYPE_TXTDOC) { uint32_t* pUint ;
pUint = (uint32_t*) pMCS ; atom = *pUint ; } else if (pMbr->Basetype() == BASETYPE_DIGEST) { hzMD5* pDigest ;
pDigest = (hzMD5*) pMCS ; atom = *pDigest ; } else { switch (pMbr->Basetype()) { case BASETYPE_XDATE: { hzXDate* pXd ; pXd = (hzXDate*) pMCS ; atom = *pXd ; } break ;
case BASETYPE_SDATE: atom = (hzSDate*) pMCS ; break ; case BASETYPE_TIME: atom = (hzTime*) pMCS ; break ; default: av.m_uInt64 = 0 ; memcpy(&av, pMCS, pMbr->SizeDatum()) ; atom.SetValue(pMbr->Basetype(), av) ; } }
return E_OK ; }
#if 0 hzEcode _obj_data::GetObject (_obj_data& obj, const hdbMember* pMbr, uint32_t nOset) const { // Fetches a subclass object from the applicable member of this (host class) object. The supplied hdbObject must have been previously initialized to the subclass. The supplied // hdbObject is first cleared, then populated by the object in question (assuming it exists). The operation is a simple copy of the _obj_data held in the array for the member, // to the supplied object. This will increment the copy count. // // Arguments: 1) obj The subclass object container // 2) pMbr The applicable host class member // 3) nOset Position in array of subclass objects held by the host class member //
_hzfunc("_obj_data::GetObject") ;
hzArray <_obj_data*>* pArr ; // Cast of core entry to object array
_obj_data* pSub ; // Subclass object pointer const uchar* pMCS ; // Member core space const uchar* pLitmus ; // Litmus bits hzEcode rc ; // Return code
// Object has class? if (!this) hzexit(E_CORRUPT, "No instance") ; if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ;
if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_CLASS) return hzerr(E_TYPE, "Member %s is atomic", pMbr->txtName()) ;
// Set litmus and core space pointers pMCS = m_Core + pMbr->OsetStd() ; pLitmus = m_Core + m_pClass->CoreLen() ;
if (pLitmus[pMbr->Posn()] & LITMUS_SET) { // Cast the array pArr = (hzArray<_obj_data*>*) pMCS ;
if (nOset >= pArr->Count()) return E_NOTFOUND ;
pSub = pArr->operator[](nOset) ; obj.Clear() ; // ??? memcpy(obj.m_pCore, pSub->m_pCore, m_pClass->CoreLen()) ; //obj.m_pRoot->m_copy++ ; obj.m_copy++ ; //*obj.m_pRoot = pSub ; }
return E_OK ; } #endif
hzEcode _obj_data::GetMbrValue (hzMD5& md5, const hdbMember* pMbr) const { // Set the supplied string with the value of the supplied member // // Arguments: 1) str The string to be set // 2) pMbr Pointer to the data class member // // Returns: E_NOINIT If the object has not been initialized to a class // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not a string or a string-like data type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("_obj_data::GetMbrValue(md5)") ;
//_atomval av ; // Member value hzMD5* pMd5 ; // MD5 pointer
// Clear value and check object set-up md5.Clear() ;
if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ; if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_DIGEST) return hzerr(E_TYPE, "Member %s is not an MD5 digest", pMbr->txtName()) ;
// Fetch the value from the member space. pMd5 = (hzMD5*) (m_Core + pMbr->OsetStd()) ; md5 = *pMd5 ;
return E_OK ; }
hzEcode _obj_data::GetMbrValue (hzString& str, const hdbMember* pMbr) const { // Set the supplied string with the value of the supplied member // // Arguments: 1) str The string to be set // 2) pMbr Pointer to the data class member // // Returns: E_NOINIT If the object has not been initialized to a class // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not a string or a string-like data type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("_obj_data::GetMbrValue(str)") ;
hzString* pStr ; // Member entry cast to string
if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ; if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_STRING) return hzerr(E_TYPE, "Member %s is not a string", pMbr->txtName()) ;
// Fetch the value from the member space. pStr = (hzString*) (m_Core + pMbr->OsetStd()) ; str = *pStr ; return E_OK ; }
hzEcode _obj_data::GetMbrValue (hzDomain& dom, const hdbMember* pMbr) const { // Set the supplied string with the value of the supplied member // // Arguments: 1) dom The domain name to be set // 2) pMbr Pointer to the data class member // // Returns: E_NOINIT If the object has not been initialized to a class // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not a string or a string-like data type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("_obj_data::GetMbrValue(dom)") ;
_atomval av ; // Member value
hzDomain* pDom ; // Member entry cast to domain
dom.Clear() ;
if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ; if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_DOMAIN) return E_TYPE ;
// Fetch the value from the member space. pDom = (hzDomain*) (m_Core + pMbr->OsetStd()) ; dom = *pDom ; return E_OK ; }
hzEcode _obj_data::GetMbrValue (hzEmaddr& ema, const hdbMember* pMbr) const { // Set the supplied string with the value of the supplied member // // Arguments: 1) ema The email address to be set // 2) pMbr Pointer to the data class member // // Returns: E_NOINIT If the object has not been initialized to a class // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not a string or a string-like data type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("_obj_data::GetMbrValue(ema)") ;
//_atomval av ; // Member value hzEmaddr* pEma ; // Member entry cast to emaddr
// Clear email address ema.Clear() ;
if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ; if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_EMADDR) return E_TYPE ;
// Fetch the value from the member space. pEma = (hzEmaddr*) (m_Core + pMbr->OsetStd()) ; ema = *pEma ; return E_OK ; }
hzEcode _obj_data::GetMbrValue (hzUrl& url, const hdbMember* pMbr) const { // Set the supplied URL with the value of the supplied member // // Arguments: 1) url The email address to be set // 2) pMbr Pointer to the data class member // // Returns: E_NOINIT If the object has not been initialized to a class // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not a string or a string-like data type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("_obj_data::GetMbrValue(ema)") ;
hzUrl* pUrl ; // Member entry cast to hzUrl
// Clear email address url.Clear() ;
if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ; if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_URL) return E_TYPE ;
// Fetch the value from the member space. pUrl = (hzUrl*) (m_Core + pMbr->OsetStd()) ; url = *pUrl ; return E_OK ; }
hzEcode _obj_data::GetMbrValue (hzIpaddr& ipa, const hdbMember* pMbr) const { // Set the supplied string with the value of the supplied member // // Arguments: 1) ipa The IP address to be set // 2) pMbr Pointer to the data class member // // Returns: E_NOINIT If the object has not been initialized to a class // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not a string or a string-like data type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("_obj_data::GetMbrValue(ipa)") ;
const uchar* pLitmus ; // Litmus bits const uchar* pMCS ; // Pointer to member core space
if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ; if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_EMADDR) return E_TYPE ;
// Fetch the value from the member space. pLitmus = m_Core + m_pClass->CoreLen() ; pMCS = m_Core + pMbr->OsetStd() ;
ipa.Clear() ; if (pLitmus[pMbr->Posn()] & LITMUS_SET) { memcpy(&ipa, pMCS, 4) ; } return E_OK ; }
hzEcode _obj_data::GetMbrValue (hzXDate& xdate, const hdbMember* pMbr) const { // Set the supplied string with the value of the supplied member // // Arguments: 1) pMbr Pointer to the member to be set // 2) dom The email address value // // Returns: E_NOINIT If the object has not been initialized to a class // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not a string or a string-like data type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("_obj_data::GetMbrValue(xdate)") ;
const uchar* pLitmus ; // Litmus bits hzXDate* pXd ; // Internal cast
if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ; if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_XDATE) return E_TYPE ;
pLitmus = m_Core + m_pClass->CoreLen() ;
xdate.Clear() ; if (pLitmus[pMbr->Posn()] & LITMUS_SET) { pXd = (hzXDate*) (m_Core + pMbr->OsetStd()) ; xdate = *pXd ; }
return E_OK ; }
hzEcode _obj_data::GetMbrValue (hzSDate& sdate, const hdbMember* pMbr) const { // Set the supplied string with the value of the supplied member // // Arguments: 1) pMbr Pointer to the member to be set // 2) dom The email address value // // Returns: E_NOINIT If the object has not been initialized to a class // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not a string or a string-like data type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("_obj_data::GetMbrValue(sdate)") ;
hzSDate* pSd ; // Internal cast const uchar* pLitmus ; // Litmus bits
if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ; if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_SDATE) return E_TYPE ;
sdate.Clear() ; pLitmus = m_Core + m_pClass->CoreLen() ;
if (pLitmus[pMbr->Posn()] & LITMUS_SET) { pSd = (hzSDate*) (m_Core + pMbr->OsetStd()) ; sdate = *pSd ; }
return E_OK ; }
hzEcode _obj_data::GetMbrValue (hzTime& time, const hdbMember* pMbr) const { // Set the supplied string with the value of the supplied member // // Arguments: 1) pMbr Pointer to the member to be set // 2) dom The email address value // // Returns: E_NOINIT If the object has not been initialized to a class // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not a string or a string-like data type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("_obj_data::GetMbrValue(time)") ;
hzTime* pTime ; // Internal cast const uchar* pLitmus ; // Litmus bits
if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ; if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_SDATE) return E_TYPE ;
time.Clear() ; pLitmus = m_Core + m_pClass->CoreLen() ;
if (pLitmus[pMbr->Posn()] & LITMUS_SET) { pTime = (hzTime*) (m_Core + pMbr->OsetStd()) ; time = *pTime ; }
return E_OK ; }
hzEcode _obj_data::GetMbrValue (uint32_t& val, const hdbMember* pMbr) const { // Set the supplied string with the value of the supplied member // // Arguments: 1) pMbr Pointer to the member to be set // 2) dom The email address value // // Returns: E_NOINIT If the object has not been initialized to a class // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not a string or a string-like data type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("_obj_data::GetMbrValue(uint32)") ;
uint32_t* pUI ; // Internal cast const uchar* pLitmus ; // Litmus bits
if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ; if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_UINT32) return E_TYPE ;
val = 0 ; pLitmus = m_Core + m_pClass->CoreLen() ;
if (pLitmus[pMbr->Posn()] & LITMUS_SET) { pUI = (uint32_t*) (m_Core + pMbr->OsetStd()) ; val = *pUI ; }
return E_OK ; }
/* ** hdbObject Functions */
hdbObject::hdbObject (void) { m_pClass = 0 ; m_ReposId = m_ClassId = 0 ; m_pRoot = 0 ; }
hdbObject::~hdbObject (void) { Clear() ; delete m_pRoot ; }
hzEcode hdbObject::SetName (const hzString& objKey) { // Set single object container name if required. // // Argument: objClass The data class
if (m_Key) return E_DUPLICATE ; m_Key = objKey ; return E_OK ; }
void hdbObject::SetObjId (uint32_t nObjId) const { // Set the object id. This is upon FETCH of a data object from a repository. // // Argument: nObjId The Object ID // Returns: None
if (!m_pClass) hzexit(E_NOINIT, "Object not initialized - Cannot set ID") ;
if (!m_pRoot) m_pRoot = _obj_data::GetInstance(m_pClass) ;
m_pRoot->m_ObjId = nObjId ; }
uint32_t hdbObject::GetObjId (void) const { // Get the object id. // // Argument: nObjId The Object ID // Returns: The object id
if (!m_pRoot) return 0 ; return m_pRoot->m_ObjId ; }
hzEcode hdbObject::SetRepos (const hdbObjRepos* pRepos) { // Set single object container name if required. // // Argument: pRepos The associated repository
if (m_pRepos) { if (m_pRepos == pRepos) return E_OK ; return E_TYPE ; }
m_pRepos = pRepos ; return E_OK ; }
hzEcode hdbObject::Integrity (void) { // Check integrity // // Arguments: None // // Returns: E_NOINIT Object not initialized // E_CORRUPT If there is a mismatch between value amd indicator // E_NODATA If a member has a min pop of 1 and no value // E_OK Operation successful. All atoms at null values
_hzfunc("hdbObject::Integrity") ;
hzChain err ; // Error report (discarded if no error)
if (!m_pClass) return hzerr(E_NOINIT, "No class") ; if (!m_pRoot) return hzerr(E_NOINIT, "No root") ;
return m_pRoot->Integrity(err) ; }
hzEcode hdbObject::Clear (void) { // Clear all hdbObject values // // Arguments: None // // Returns: E_NOINIT Object not initialized // E_CORRUPT If there is a mismatch between value amd indicator // E_OK Operation successful. All atoms at null values
_hzfunc("hdbObject::Clear") ;
if (!m_pClass) return E_NOINIT ; if (!m_pRoot) return E_OK ;
if (m_pRoot->m_copy > 1) { m_pRoot->m_copy-- ; m_pRoot = 0 ; return E_OK ; }
m_pRoot->Clear() ; delete m_pRoot ; m_pRoot = 0 ; return E_OK ; }
hzEcode hdbObject::Init (const hdbClass* pClass) { // Initialize a single object container // // Single object containers are assigned a data class (the operational native), and a name. The name was added so that hdbObject instances in Dissemino user sessions could be // referenced by form handler commands. // // Argument: objClass The data class // // Returns: E_CORRUPT If called without a hdbObject instance // E_ARGUMENT If the class is not supplied // E_NOINIT If the supplied class is not initialized // E_DUPLICATE If this hdbObject is already initialized // E_OK If the hdbObject is initialized to the class
_hzfunc("hdbObject::Init") ;
const hdbMember* pMbr ; // This class member uint32_t nMbr ; // Member iterator hzEcode rc = E_OK ; // Return code
// Check class and class init state if (!this) hzexit(E_CORRUPT, "No instance") ; if (!pClass) return hzerr(E_ARGUMENT, "No data class supplied") ; if (!pClass->IsInit()) return hzerr(E_NOINIT, "Data class is not initialized") ; if (m_pClass) return hzerr(E_DUPLICATE, "Object already initialized") ;
// Clear any pre-existing initialization and data Clear() ;
// Set the class m_pClass = pClass ;
// Allocate data space for members m_pRoot = _obj_data::GetInstance(m_pClass) ;
// Go thru members for (nMbr = 0 ; rc == E_OK && nMbr < pClass->MbrCount() ; nMbr++) { pMbr = pClass->GetMember(nMbr) ; if (!pMbr) return hzerr(E_CORRUPT, "No member in position %d", nMbr) ;
if (!pMbr->txtName()) return hzerr(E_CORRUPT, "Member in position %d has no name", nMbr) ; }
return E_OK ; }
hzEcode hdbObject::Init (const hdbObjRepos* pRepos) { // Initialize a single object container to a repository and thus a data class // // Argument: pRepos The initialized data object repository // // Returns: E_CORRUPT If called without a hdbObject instance // E_ARGUMENT If the class is not supplied // E_NOINIT If the supplied class is not initialized // E_DUPLICATE If this hdbObject is already initialized // E_OK If the hdbObject is initialized to the class
_hzfunc("hdbObject::Init") ;
const hdbMember* pMbr ; // This class member uint32_t nMbr ; // Member iterator hzEcode rc = E_OK ; // Return code
// Check class and class init state if (!this) hzexit(E_CORRUPT, "No instance") ; if (!pRepos) return hzerr(E_ARGUMENT, "No data object repository supplied") ; if (!pRepos->IsInit()) return hzerr(E_NOINIT, "Data object repository is not initialized") ; if (m_pClass) return hzerr(E_DUPLICATE, "Object already initialized") ;
// Clear any pre-existing initialization and data Clear() ;
// Set the class m_pRepos = pRepos ; m_pClass = pRepos->Class() ;
// Allocate data space for members m_pRoot = _obj_data::GetInstance(m_pClass) ;
// Go thru members for (nMbr = 0 ; rc == E_OK && nMbr < m_pClass->MbrCount() ; nMbr++) { pMbr = m_pClass->GetMember(nMbr) ; if (!pMbr) return hzerr(E_CORRUPT, "No member in position %d", nMbr) ;
if (!pMbr->txtName()) return hzerr(E_CORRUPT, "Member in position %d has no name", nMbr) ; }
return E_OK ; }
/* ** Set Member Functions */
hzEcode hdbObject::SetBool (const hdbMember* pMbr, bool bValue) { // Set boolean member within data object. The object must be initialized to a data class, and the supplied member must exist within that class and be of datatype BOOL or TBOOL // // Arguments: 1) pMbr The member // 2) bValue The boolean value the member will be set to // // Returns: E_NOINIT If the object has not been initialized to a class // E_ARGUMENT If no member is supplied // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not atomic (is another class) or if the supplied atom has the wrong type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("hdbObject::SetBool") ;
if (!this) hzexit(E_CORRUPT, "No instance") ; if (!m_pClass) return hzerr(E_NOINIT, "Single object container not init to a data class") ; if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ;
if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (!m_pRoot) m_pRoot = _obj_data::GetInstance(m_pClass) ;
return m_pRoot->SetBool(pMbr, bValue) ; } ;
hzEcode hdbObject::SetBinary (const hdbMember* pMbr, const hzChain& Z) { // Set binary member value within data object. // // The object must be initialized to a data class, and the supplied member must exist within that class and be of a BINARY datatype. This function will copy the supplied chain // to the core entry of the applicable member, and sets the member litmus byte to LITMUS_SET to state that the member has a new value. The chain is NOT committed to the target // binary repository at this juncture. This will only happen when the onject as a whole is committed to the applicable data object repository, in either an INSERT or an UPDATE // operation. // // Note that BINARY members have an aux core entry in addition to the standard core entry. The aux is used to store the datum id of the chain. This is only set on a FETCH. In // a new object, the aux is 0. In an existing object, the aux will contain the datim id that was previously assigned. On UPDATE, if the chain has changed, the datum id in the // aux is used to DELETE the previous datum. // // Arguments: 1) pMbr The member // 2) Z The chain value the member will be set to // // Returns: E_NOINIT If the object has not been initialized to a class // E_ARGUMENT If no member is supplied // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not atomic (is another class) or if the supplied atom has the wrong type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("hdbObject::SetBinary") ;
if (!this) hzexit(E_CORRUPT, "No instance") ; if (!m_pClass) return hzerr(E_NOINIT, "Single object container not init to a data class") ; if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ;
if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_BINARY && pMbr->Basetype() != BASETYPE_TXTDOC) return hzerr(E_TYPE, "Member %s is not BINARY or TXTDOC", pMbr->txtName()) ;
if (!m_pRoot) m_pRoot = _obj_data::GetInstance(m_pClass) ;
return m_pRoot->SetBinary(pMbr, Z) ; }
hzEcode hdbObject::SetValue (const hdbMember* pMbr, const hzAtom& atom) { // Set member value within data object. The object must be initialized to a data class, and the supplied member must exist within that class // // Arguments: 1) pMbr The member // 2) atom The atomic value the member will be set to // // Returns: E_NOINIT If the object has not been initialized to a class // E_ARGUMENT If no member is supplied // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not atomic (is another class) or if the supplied atom has the wrong type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("hdbObject::SetValue") ;
//_atomval av ; // atom data //uchar* pLitmus ; // Litmus bits //uchar* pMCS ; // Pointer to member core space
// Object has class? if (!this) hzexit(E_CORRUPT, "No instance") ; if (!m_pClass) return hzerr(E_NOINIT, "Single object container not init to a data class") ; if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ;
if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
// Check status if (atom.Status() == ATOM_ERROR) return hzerr(E_BADVALUE, "Member %s not set", pMbr->txtName()) ;
if (!m_pRoot) m_pRoot = _obj_data::GetInstance(m_pClass) ;
return m_pRoot->SetValue(pMbr, atom) ; }
hzEcode hdbObject::SetObject (const hdbMember* pMbr, const hdbObject& sub) { // Either add a new subclass data object or return a modified subclass data object, to the supplied host class member. In the case of a new subclass data object, the object id // will be zero. In the case of a modified subclass data object, this must necessarily have been fetched, so will have the object id it was given when originally added. // // This object must be initialized to the host data class and the supplied data object must be initialized to subclass introduced by the applicable host class member. // // Arguments: 1) pMbr The subclass member of this, the host class object // 2) sub The subclass object to be placed in the pMbr array of objects // // Returns: E_NOINIT If the object has not been initialized to a class // E_ARGUMENT If no member is supplied // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not atomic (is another class) or if the supplied atom has the wrong type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("hdbObject::SetObject") ;
// Object has class? if (!this) hzexit(E_CORRUPT, "No instance") ; if (!m_pClass) return hzerr(E_NOINIT, "Single object container not init to a data class") ; if (!sub.m_pClass) return hzerr(E_NOINIT, "Operand object container not init to a data class") ; if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ;
if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_CLASS) return hzerr(E_TYPE, "Member %s is atomic", pMbr->txtName()) ; if (pMbr->Datatype() != sub.m_pClass) return hzerr(E_TYPE, "Member %s is not of type class %s", pMbr->txtName(), sub.m_pClass->txtName()) ;
if (!m_pRoot) m_pRoot = _obj_data::GetInstance(m_pClass) ;
return m_pRoot->SetObject(pMbr, sub.m_pRoot) ; }
hzEcode hdbObject::SetMbrValue (const hdbMember* pMbr, const hzMD5& md5) { // Set value of the supplied member in the object, with the supplied string // // Arguments: 1) pMbr Pointer to the member to be set // 2) str The string value // // Returns: E_NOINIT If the object has not been initialized to a class // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not a string or a string-like data type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("hdbObject::SetMbrValue(str)") ;
if (!m_pClass) return hzerr(E_NOINIT, "Object has no class") ; if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ;
if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_DIGEST) return hzerr(E_TYPE, "Member %s is not MD5 Digest", pMbr->txtName()) ;
if (!m_pRoot) m_pRoot = _obj_data::GetInstance(m_pClass) ;
return m_pRoot->_setMbrValue(pMbr, md5) ; }
hzEcode hdbObject::SetMbrValue (const hdbMember* pMbr, const hzString& str) { // Set value of the supplied member in the object, with the supplied string // // Arguments: 1) pMbr Pointer to the member to be set // 2) str The string value // // Returns: E_NOINIT If the object has not been initialized to a class // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not a string or a string-like data type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("hdbObject::SetMbrValue(str)") ;
if (!m_pClass) return hzerr(E_NOINIT, "Object has no class") ; if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ;
if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_STRING) return hzerr(E_TYPE, "Member %s is not a string", pMbr->txtName()) ;
if (!m_pRoot) m_pRoot = _obj_data::GetInstance(m_pClass) ;
return m_pRoot->_setMbrValue(pMbr, str) ; }
hzEcode hdbObject::SetMbrValue (const hdbMember* pMbr, const hzDomain& dom) { // Set value of the supplied member in the object, with the supplied domain // // Arguments: 1) pMbr Pointer to the member to be set // 2) dom The domain name value // // Returns: E_NOINIT If the object has not been initialized to a class // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not a string or a string-like data type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("hdbObject::SetMbrValue(domain)") ;
if (!m_pClass) return hzerr(E_NOINIT, "Object has no class") ; if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ;
if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_DOMAIN) return E_TYPE ;
if (!m_pRoot) m_pRoot = _obj_data::GetInstance(m_pClass) ;
return m_pRoot->_setMbrValue(pMbr, dom) ; }
hzEcode hdbObject::SetMbrValue (const hdbMember* pMbr, const hzEmaddr& ema) { // Set the supplied string with the value of the supplied member // // Arguments: 1) pMbr Pointer to the member to be set // 2) dom The email address value // // Returns: E_NOINIT If the object has not been initialized to a class // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not a string or a string-like data type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("hdbObject::SetMbrValue(emaddr)") ;
if (!m_pClass) return hzerr(E_NOINIT, "Object has no class") ; if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ;
if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_EMADDR) return E_TYPE ;
if (!m_pRoot) m_pRoot = _obj_data::GetInstance(m_pClass) ;
return m_pRoot->_setMbrValue(pMbr, ema) ; }
hzEcode hdbObject::SetMbrValue (const hdbMember* pMbr, const hzUrl& url) { // Set the supplied string with the value of the supplied member // // Arguments: 1) pMbr Pointer to the member to be set // 2) dom The email address value // // Returns: E_NOINIT If the object has not been initialized to a class // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not a string or a string-like data type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("hdbObject::SetMbrValue(url)") ;
if (!m_pClass) return hzerr(E_NOINIT, "Object has no class") ; if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ;
if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_URL) return E_TYPE ;
if (!m_pRoot) m_pRoot = _obj_data::GetInstance(m_pClass) ;
return m_pRoot->_setMbrValue(pMbr, url) ; }
hzEcode hdbObject::SetMbrValue (const hdbMember* pMbr, const hzXDate& xd) { // Set the supplied string with the value of the supplied member // // Arguments: 1) pMbr Pointer to the member to be set // 2) dom The email address value // // Returns: E_NOINIT If the object has not been initialized to a class // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not a string or a string-like data type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("hdbObject::SetMbrValue(xdate)") ;
//hzXDate* pXd ; // Internal cast //uchar* pLitmus ; // Litmus bits
if (!m_pClass) return hzerr(E_NOINIT, "Object has no class") ; if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ;
if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_XDATE) return E_TYPE ;
if (!m_pRoot) m_pRoot = _obj_data::GetInstance(m_pClass) ;
return m_pRoot->_setMbrValue(pMbr, xd) ; }
hzEcode hdbObject::SetMbrValue (const hdbMember* pMbr, const hzSDate& sd) { // Set the supplied string with the value of the supplied member // // Arguments: 1) pMbr Pointer to the member to be set // 2) dom The email address value // // Returns: E_NOINIT If the object has not been initialized to a class // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not a string or a string-like data type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("hdbObject::SetMbrValue(sdate)") ;
//hzSDate* pSd ; // Internal cast //uchar* pLitmus ; // Litmus bits
if (!m_pClass) return hzerr(E_NOINIT, "Object has no class") ; if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ;
if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_SDATE) return E_TYPE ;
if (!m_pRoot) m_pRoot = _obj_data::GetInstance(m_pClass) ;
return m_pRoot->_setMbrValue(pMbr, sd) ; }
hzEcode hdbObject::SetMbrValue (const hdbMember* pMbr, const hzTime& time) { // Set the supplied string with the value of the supplied member // // Arguments: 1) pMbr Pointer to the member to be set // 2) dom The email address value // // Returns: E_NOINIT If the object has not been initialized to a class // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not a string or a string-like data type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("hdbObject::SetMbrValue(time)") ;
//hzTime* pTime ; // Internal cast //uchar* pLitmus ; // Litmus bits
if (!m_pClass) return hzerr(E_NOINIT, "Object has no class") ; if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ;
if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_TIME) return E_TYPE ;
if (!m_pRoot) m_pRoot = _obj_data::GetInstance(m_pClass) ;
return m_pRoot->_setMbrValue(pMbr, time) ; }
hzEcode hdbObject::SetMbrValue (const hdbMember* pMbr, uint64_t val) { _hzfunc("hdbObject::SetMbrValue(uint64)") ;
//uint64_t* pUint ; // Internal cast //uchar* pLitmus ; // Litmus bits
if (!m_pClass) return hzerr(E_NOINIT, "Object has no class") ; if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ;
if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_UINT64) return E_TYPE ;
if (!m_pRoot) m_pRoot = _obj_data::GetInstance(m_pClass) ;
return m_pRoot->_setMbrValue(pMbr, val) ; }
hzEcode hdbObject::SetMbrValue (const hdbMember* pMbr, int64_t val) { _hzfunc("hdbObject::SetMbrValue(int64)") ;
//int64_t* pInt ; // Internal cast //uchar* pLitmus ; // Litmus bits
if (!m_pClass) return hzerr(E_NOINIT, "Object has no class") ; if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ;
if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_INT64) return E_TYPE ;
if (!m_pRoot) m_pRoot = _obj_data::GetInstance(m_pClass) ;
return m_pRoot->_setMbrValue(pMbr, val) ; }
hzEcode hdbObject::SetMbrValue (const hdbMember* pMbr, uint32_t val) { _hzfunc("hdbObject::SetMbrValue(uint32)") ;
//uint32_t* pUint ; // Internal cast //uchar* pLitmus ; // Litmus bits
if (!m_pClass) return hzerr(E_NOINIT, "Object has no class") ; if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ;
if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_UINT32) return E_TYPE ;
if (!m_pRoot) m_pRoot = _obj_data::GetInstance(m_pClass) ;
return m_pRoot->_setMbrValue(pMbr, val) ; }
hzEcode hdbObject::SetMbrValue (const hdbMember* pMbr, int32_t val) { _hzfunc("hdbObject::SetMbrValue(int32)") ;
//int32_t* pInt ; // Internal cast //uchar* pLitmus ; // Litmus bits
if (!m_pClass) return hzerr(E_NOINIT, "Object has no class") ; if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ;
if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_INT32) return E_TYPE ;
if (!m_pRoot) m_pRoot = _obj_data::GetInstance(m_pClass) ;
return m_pRoot->_setMbrValue(pMbr, val) ; }
/* ** Get Member Functions */
hzEcode hdbObject::GetBool (bool& result, const hdbMember* pMbr) const { // Get boolean member within data object. The object must be initialized to a data class, and the supplied member must exist within that class and be of datatype BOOL or TBOOL // // Arguments: 1) result The bool result // 2) pMbr Member pointer // // Returns: E_NOINIT If the object has not been initialized to a class // E_ARGUMENT If no member is supplied // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not atomic (is another class) or if the supplied atom has the wrong type. // E_NODATA If the member is of type TBOOL and has not been set // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("hdbObject::GetBool") ;
result = false ;
if (!this) hzexit(E_CORRUPT, "No instance") ; if (!m_pClass) return hzerr(E_NOINIT, "Single object container not init to a data class") ; if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ;
if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ; if (!m_pRoot) return E_OK ;
return m_pRoot->GetBool(result, pMbr) ; }
hzEcode hdbObject::GetBinary (hzChain& Z, const hdbMember* pMbr) { // Place the actual binary datum member value into the supplied chain. This requires the object container to name a source repository. // // Arguments: 1) Z The hzChain to be set // 2) pMbr Pointer to the data class member // // Returns: E_NOINIT If the object has not been initialized to a class // E_CORRUPT If the supplied member number does not identify an object class member. // E_NODATA If the binary datum repository could not be identified // E_TYPE If the object class member is not atomic (is another class) or if the supplied atom has the wrong type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("hdbObject::GetBinary") ;
hzChain* pCh ; // Internal cast (binary datum) uint32_t* pId ; // Internal cast (binary datum id) hzEcode rc = E_OK ; // Return code // Object has class? if (!m_pClass) return hzerr(E_NOINIT, "Object has no class") ; if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ;
if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
// Check member data type if (pMbr->Basetype() != BASETYPE_BINARY && pMbr->Basetype() != BASETYPE_TXTDOC) return E_TYPE ;
Z.Clear() ;
// Check for the default binary datum repository of the associated data object repository if (!m_pRepos) return hzerr(E_NOINIT, "No repository") ; if (!m_pRepos->BinRepos()) return hzerr(E_NOINIT, "Associated repository has no binary datum repository") ; if (!m_pRoot) return E_OK ;
// The member space may already hold the binary in hzChain form. If so simply copy it pCh = (hzChain*) (m_pRoot->m_Core + pMbr->OsetAux()) ; if (pCh->Size()) { Z = *pCh ; return E_OK ; }
// Binary datum not in-situ, fetch from the binary datum repository pId = (uint32_t*) (m_pRoot->m_Core + pMbr->OsetStd()) ; if (*pId) { // Fetch chain from the binary datum repository rc = m_pRepos->BinRepos()->Fetch(Z, *pId) ; } return rc ; }
hzEcode hdbObject::GetValue (hzAtom& atom, const hdbMember* pMbr, uint32_t nOset) const { // Set the supplied atom with the value of the supplied member. Note that for BINARY/TXTDOC members, the atom is set with the binary datum id, not the binary datum value. // // Arguments: 1) atom The atom to be set // 2) pMbr Pointer to the data class member // 3) nOset Default 0, applicable only if the member is an array // // Returns: E_NOINIT If the object has not been initialized to a class // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not atomic (is another class) or if the supplied atom has the wrong type. // E_RANGE If the requested element (nOset) exceeds the number of member values // E_OK If the object class member has been set to the supplied atom value. _hzfunc("hdbObject::GetValue(atom)") ;
_atomval av ; // Value from atom //uchar* pLitmus ; // Litmus bits //uchar* pMCS ; // Pointer to member core space
atom.Clear() ;
// Object has class? if (!m_pClass) return hzerr(E_NOINIT, "Object has no class") ; if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ;
if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
// For BOOL and TBOOL members, values are read from the litmus bits if (pMbr->Basetype() == BASETYPE_CLASS) return E_TYPE ; if (!m_pRoot) return E_OK ;
return m_pRoot->GetValue(atom, pMbr, nOset) ; }
hzEcode hdbObject::GetObject (hdbObject& sub, const hdbMember* pMbr, uint32_t nOset) const { // Fetches a subclass object from the applicable member of this (host class) object. // // The supplied hdbObject (previously initialized to the subclass), is first cleared leaving its m_pRoot pointer as NULL. m_pRoot is then set to the fetched _obj_data, raising // the copy count. // // Arguments: 1) sub The target subclass object container // 2) pMbr The applicable host class member // 3) nOset Position in array of subclass objects held by the host class member //
_hzfunc("hdbObject::GetObject") ;
hzArray <_obj_data*>* pArr ; // Cast of core entry to object array
_obj_data* pSub ; // Subclass object pointer uchar* pMCS ; // Member core space uchar* pLitmus ; // Litmus bits hzEcode rc ; // Return code
// Object has class? if (!this) hzexit(E_CORRUPT, "No instance") ; if (!m_pClass) return hzerr(E_NOINIT, "Single object container not init to a data class") ; if (!sub.m_pClass) return hzerr(E_NOINIT, "Subclass object container not init to a data class") ; if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ;
if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_CLASS) return hzerr(E_TYPE, "Member %s is atomic", pMbr->txtName()) ; if (pMbr->Datatype() != sub.m_pClass) return hzerr(E_TYPE, "Member %s is not of type class %s", pMbr->txtName(), sub.m_pClass->txtName()) ;
sub.Clear() ;
// Set litmus and core space pointers pMCS = m_pRoot->m_Core + pMbr->OsetStd() ; pLitmus = m_pRoot->m_Core + m_pClass->CoreLen() ;
if (pLitmus[pMbr->Posn()] & LITMUS_SET) { // Cast the array pArr = (hzArray<_obj_data*>*) pMCS ;
if (nOset >= pArr->Count()) return E_NOTFOUND ;
pSub = pArr->operator[](nOset) ; sub.m_pRoot = pSub ; sub.m_pRoot->m_copy++ ; }
return E_OK ; }
hzEcode hdbObject::GetMbrValue (hzMD5& md5, const hdbMember* pMbr) const { // Set the supplied string with the value of the supplied member // // Arguments: 1) str The string to be set // 2) pMbr Pointer to the data class member // // Returns: E_NOINIT If the object has not been initialized to a class // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not a string or a string-like data type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("hdbObject::GetMbrValue(md5)") ;
//_atomval av ; // Member value hzMD5* pMd5 ; // MD5 pointer
// Clear value and check object set-up md5.Clear() ;
if (!m_pClass) return hzerr(E_NOINIT, "Object has no class") ; if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ;
if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_DIGEST) return hzerr(E_TYPE, "Member %s is not an MD5 digest", pMbr->txtName()) ; if (!m_pRoot) return E_OK ;
// Fetch the value from the member space. pMd5 = (hzMD5*) (m_pRoot->m_Core + pMbr->OsetStd()) ; md5 = *pMd5 ;
return E_OK ; }
hzEcode hdbObject::GetMbrValue (hzString& str, const hdbMember* pMbr) const { // Set the supplied string with the value of the supplied member // // Arguments: 1) str The string to be set // 2) pMbr Pointer to the data class member // // Returns: E_NOINIT If the object has not been initialized to a class // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not a string or a string-like data type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("hdbObject::GetMbrValue(str)") ;
hzString* pStr ; // Member entry cast to string //hzString S ; // Temp string
if (!m_pClass) return hzerr(E_NOINIT, "Object has no class") ; if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ;
if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_STRING) return hzerr(E_TYPE, "Member %s is not a string", pMbr->txtName()) ; if (!m_pRoot) return E_OK ;
// Fetch the value from the member space. //str.Clear() ;
pStr = (hzString*) (m_pRoot->m_Core + pMbr->OsetStd()) ; str = *pStr ; return E_OK ; }
hzEcode hdbObject::GetMbrValue (hzDomain& dom, const hdbMember* pMbr) const { // Set the supplied string with the value of the supplied member // // Arguments: 1) dom The domain name to be set // 2) pMbr Pointer to the data class member // // Returns: E_NOINIT If the object has not been initialized to a class // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not a string or a string-like data type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("hdbObject::GetMbrValue(dom)") ;
_atomval av ; // Member value
hzDomain* pDom ; // Member entry cast to domain
dom.Clear() ;
if (!m_pClass) return hzerr(E_NOINIT, "Object has no class") ; if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ;
if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_DOMAIN) return E_TYPE ; if (!m_pRoot) return E_OK ;
// Fetch the value from the member space. pDom = (hzDomain*) (m_pRoot->m_Core + pMbr->OsetStd()) ; dom = *pDom ; return E_OK ; }
hzEcode hdbObject::GetMbrValue (hzEmaddr& ema, const hdbMember* pMbr) const { // Set the supplied string with the value of the supplied member // // Arguments: 1) ema The email address to be set // 2) pMbr Pointer to the data class member // // Returns: E_NOINIT If the object has not been initialized to a class // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not a string or a string-like data type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("hdbObject::GetMbrValue(ema)") ;
//_atomval av ; // Member value hzEmaddr* pEma ; // Member entry cast to emaddr
// Clear email address ema.Clear() ;
if (!m_pClass) return hzerr(E_NOINIT, "Object has no class") ; if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ;
if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_EMADDR) return E_TYPE ; if (!m_pRoot) return E_OK ;
// Fetch the value from the member space. pEma = (hzEmaddr*) (m_pRoot->m_Core + pMbr->OsetStd()) ; ema = *pEma ; return E_OK ; }
hzEcode hdbObject::GetMbrValue (hzUrl& url, const hdbMember* pMbr) const { // Set the supplied URL with the value of the supplied member // // Arguments: 1) url The email address to be set // 2) pMbr Pointer to the data class member // // Returns: E_NOINIT If the object has not been initialized to a class // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not a string or a string-like data type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("hdbObject::GetMbrValue(ema)") ;
hzUrl* pUrl ; // Member entry cast to hzUrl
// Clear email address url.Clear() ;
if (!m_pClass) return hzerr(E_NOINIT, "Object has no class") ; if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ;
if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_URL) return E_TYPE ; if (!m_pRoot) return E_OK ;
// Fetch the value from the member space. pUrl = (hzUrl*) (m_pRoot->m_Core + pMbr->OsetStd()) ; url = *pUrl ; return E_OK ; }
hzEcode hdbObject::GetMbrValue (hzIpaddr& ipa, const hdbMember* pMbr) const { // Set the supplied string with the value of the supplied member // // Arguments: 1) ipa The IP address to be set // 2) pMbr Pointer to the data class member // // Returns: E_NOINIT If the object has not been initialized to a class // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not a string or a string-like data type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("hdbObject::GetMbrValue(ipa)") ;
uchar* pLitmus ; // Litmus bits uchar* pMCS ; // Pointer to member core space
if (!m_pClass) return hzerr(E_NOINIT, "Object has no class") ; if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ;
if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_EMADDR) return E_TYPE ; if (!m_pRoot) return E_OK ;
// Fetch the value from the member space. pLitmus = m_pRoot->m_Core + m_pClass->CoreLen() ; pMCS = m_pRoot->m_Core + pMbr->OsetStd() ;
ipa.Clear() ; if (pLitmus[pMbr->Posn()] & LITMUS_SET) { memcpy(&ipa, pMCS, 4) ; } return E_OK ; }
hzEcode hdbObject::GetMbrValue (hzXDate& xdate, const hdbMember* pMbr) const { // Set the supplied string with the value of the supplied member // // Arguments: 1) pMbr Pointer to the member to be set // 2) dom The email address value // // Returns: E_NOINIT If the object has not been initialized to a class // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not a string or a string-like data type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("hdbObject::GetMbrValue(xdate)") ;
uchar* pLitmus ; // Litmus bits hzXDate* pXd ; // Internal cast
if (!m_pClass) return hzerr(E_NOINIT, "Object has no class") ; if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ;
if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_XDATE) return E_TYPE ; if (!m_pRoot) return E_OK ;
pLitmus = m_pRoot->m_Core + m_pClass->CoreLen() ;
xdate.Clear() ; if (pLitmus[pMbr->Posn()] & LITMUS_SET) { pXd = (hzXDate*) (m_pRoot->m_Core + pMbr->OsetStd()) ; xdate = *pXd ; }
return E_OK ; }
hzEcode hdbObject::GetMbrValue (hzSDate& sdate, const hdbMember* pMbr) const { // Set the supplied string with the value of the supplied member // // Arguments: 1) pMbr Pointer to the member to be set // 2) dom The email address value // // Returns: E_NOINIT If the object has not been initialized to a class // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not a string or a string-like data type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("hdbObject::GetMbrValue(sdate)") ;
uchar* pLitmus ; // Litmus bits hzSDate* pSd ; // Internal cast
if (!m_pClass) return hzerr(E_NOINIT, "Object has no class") ; if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ;
if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_SDATE) return E_TYPE ; if (!m_pRoot) return E_OK ;
sdate.Clear() ; pLitmus = m_pRoot->m_Core + m_pClass->CoreLen() ;
if (pLitmus[pMbr->Posn()] & LITMUS_SET) { pSd = (hzSDate*) (m_pRoot->m_Core + pMbr->OsetStd()) ; sdate = *pSd ; }
return E_OK ; }
hzEcode hdbObject::GetMbrValue (hzTime& time, const hdbMember* pMbr) const { // Set the supplied string with the value of the supplied member // // Arguments: 1) pMbr Pointer to the member to be set // 2) dom The email address value // // Returns: E_NOINIT If the object has not been initialized to a class // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not a string or a string-like data type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("hdbObject::GetMbrValue(time)") ;
hzTime* pTime ; // Internal cast uchar* pLitmus ; // Litmus bits
if (!m_pClass) return hzerr(E_NOINIT, "Object has no class") ; if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ;
if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_SDATE) return E_TYPE ; if (!m_pRoot) return E_OK ;
time.Clear() ; pLitmus = m_pRoot->m_Core + m_pClass->CoreLen() ;
if (pLitmus[pMbr->Posn()] & LITMUS_SET) { pTime = (hzTime*) (m_pRoot->m_Core + pMbr->OsetStd()) ; time = *pTime ; }
return E_OK ; }
hzEcode hdbObject::GetMbrValue (uint32_t& val, const hdbMember* pMbr) const { // Set the supplied string with the value of the supplied member // // Arguments: 1) pMbr Pointer to the member to be set // 2) dom The email address value // // Returns: E_NOINIT If the object has not been initialized to a class // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not a string or a string-like data type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("hdbObject::GetMbrValue(uint32)") ;
uint32_t* pUI ; // Internal cast uchar* pLitmus ; // Litmus bits
if (!m_pClass) return hzerr(E_NOINIT, "Object has no class") ; if (!pMbr) return hzerr(E_ARGUMENT, "No member supplied") ;
if (pMbr->Class() != m_pClass) return hzerr(E_CORRUPT, "Member %s does not belong to class %s", pMbr->txtName(), m_pClass->txtName()) ;
if (pMbr->Basetype() != BASETYPE_UINT32) return E_TYPE ; if (!m_pRoot) return E_OK ;
val = 0 ; pLitmus = m_pRoot->m_Core + m_pClass->CoreLen() ;
if (pLitmus[pMbr->Posn()] & LITMUS_SET) { pUI = (uint32_t*) (m_pRoot->m_Core + pMbr->OsetStd()) ; val = *pUI ; }
return E_OK ; }
/* ** hdbObject Import/Export JSON Functions */
hzEcode _commit_binaries_r (hdbBinRepos* pRepos, _obj_data* pOD) { // hdbObject::CommitBinaries recursive support function
_hzfunc(__func__) ;
const hdbMember* pMbr ; // Member hzChain* pCh ; // Cast for datum uint32_t* pInt ; // Cast for datumId uchar* pLitmus ; // Litmus bits uchar* pMCS ; // Pointer to member core space uint32_t mbrNo ; // Member number (position within class) uint32_t datumId ; // Datum id allocate by binary datum repository hzEcode rc = E_OK ; // Return code
pLitmus = pOD->m_Core + pOD->m_pClass->CoreLen() ;
for (mbrNo = 0 ; rc == E_OK && mbrNo < pOD->m_pClass->MbrCount() ; mbrNo++) { pMbr = pOD->m_pClass->GetMember(mbrNo) ;
if (pMbr->Basetype() == BASETYPE_CLASS) { // Recurse to handle sub-class hzArray <_obj_data*>* pArr ; // Cast to array of subclass objects _obj_data* pSub ; // Subclass object uint32_t n ; // Object counter
pMCS = pOD->m_Core + pMbr->OsetStd() ; pArr = (hzArray<_obj_data*>*) pMCS ;
for (n = 0 ; n < pArr->Count() ; n++) { pSub = pArr->operator[](n) ; rc = _commit_binaries_r(pRepos, pSub) ; } continue ; }
if (pMbr->Basetype() == BASETYPE_BINARY || pMbr->Basetype() == BASETYPE_TXTDOC) { if (pLitmus[pMbr->Posn()] & LITMUS_AUX) { // Commit pCh = (hzChain*) (pOD->m_Core + pMbr->OsetAux()) ; pInt = (uint32_t*) (pOD->m_Core + pMbr->OsetStd()) ;
threadLog("member %s posn %u oset %d aux %d\n", pMbr->txtName(), pMbr->Posn(), pMbr->OsetStd(), pMbr->OsetAux()) ;
threadLog("Repos name %s\n", pRepos->txtName()) ; rc = pRepos->Insert(datumId, *pCh) ; threadLog("case 1\n") ; threadLog("datum id %u size %u rc=%s\n", datumId, pCh->Size(), Err2Txt(rc)) ; threadLog("case 2\n") ; if (rc == E_OK) { *pInt = datumId ; pLitmus[pMbr->Posn()] |= LITMUS_SET ; } threadLog("case 3\n") ; } } }
return E_OK ; }
hzEcode hdbObject::CommitBinaries (hdbBinRepos* pRepos) const { // Commit all binary member values in this, and any subclass objects, to the supplied binary datum repository. It is expected that the binary datum repository will that of the // data object repository, this object is to be placed in (either in an INSERT or UPDATE operation). // // With binary members the litmus bit is only set by SetBinary(), which places a binary datum (presumed to be a new binary datum), in the member's core space. It is not set by // retrieving the binary from a binary datum repository. In other words, the litmus bit is set if there is a new value, and not otherwise. // // This function checks the litmus bit before committing the datum to the target binary datum repository. Once the commit is done, the address (binary datum id), is placed in // the in member's aux core space, from where it is used in the export of deltas and EDOs. // // Arguments: 1) pMbr The member // 2) pRepos The target binary datum repository // // Returns: E_NOINIT If the object has not been initialized to a class // E_ARGUMENT If no member is supplied // E_CORRUPT If the supplied member number does not identify an object class member. // E_TYPE If the object class member is not atomic (is another class) or if the supplied atom has the wrong type. // E_OK If the object class member has been set to the supplied atom value.
_hzfunc("hdbObject::CommitBinaries") ;
hzEcode rc = E_OK ; // Return code
if (!this) hzexit(E_CORRUPT, "No instance") ; if (!pRepos) return hzerr(E_NOINIT, "No target binary datum repository") ; if (!m_pClass) return hzerr(E_ARGUMENT, "No data class") ;
if (!m_pRoot) return E_OK ;
rc = _commit_binaries_r(pRepos, m_pRoot) ; threadLog("returned from commit_br\n") ;
return rc ; }
hzEcode _import_json_r (hzChain& err, chIter& zi, _obj_data* pOD) { // Support function to hdbObject::ImportJSON():- Populate the supplied object data container (_obj_data), by reading from the supplied chain (iterator). // // Subclass objects are handled by recursion. // // Argument: J The hzChain to be populated by the JSON value
_hzfunc(__func__) ;
const hdbMember* pMbr ; // Member hzAtom atom ; // Atom value hzChain W ; // For building values hzXDate xdate ; // Long form date _atomval av ; // Temp value //uchar* pLitmus ; // Litmus bits hzString mbrName ; // Member name hzString str_val ; // Temp string hzString num_val ; // Temp string hzSDate sdate ; // Short form date hzTime stime ; // hzTime hzIpaddr ipa ; // IP address uint32_t objId ; // Object id (start at 1) bool bMultObj ; // Expecting multiple objects bool bMultVal ; // Expecting multiple objects hzEcode rc = E_OK ; // Return code
if (!pOD) { err.Printf("No _obj_data supplied\n") ; return E_ARGUMENT ; }
// Lose leading whitespace and check for [] block for (; !zi.eof() && *zi <= CHAR_SPACE ; zi++) ;
bMultObj = false ; if (*zi == CHAR_SQOPEN) { bMultObj = true ; zi++ ; }
// Go thru {} object body objId = 1 ; for (; !zi.eof() && rc == E_OK ;) { for (; !zi.eof() && *zi <= CHAR_SPACE ; zi++) ;
// Expect to be at object open if (*zi != CHAR_CUROPEN) { rc = E_FORMAT ; err.Printf("line %d col %d. No opening curly brace for object %d (at %c)\n", zi.Line(), zi.Col(), objId, *zi) ; break ; } for (zi++ ; !zi.eof() && *zi <= CHAR_SPACE ; zi++) ;
// Do the members for (; rc == E_OK ;) { // Expect member name followed by a colon, whitespace and a value for (; !zi.eof() && *zi <= CHAR_SPACE ; zi++) ; if (*zi != CHAR_DQUOTE) { if (*zi == CHAR_CURCLOSE) break ; rc = E_FORMAT ; err.Printf("line %d col %d. Expected a quoted member name (at %c)\n", zi.Line(), zi.Col(), *zi) ; break ; }
// Get quoted value (handle escapes) for (zi++ ;; zi++) { if (*zi == CHAR_BKSLASH) { zi++ ; switch (*zi) { case CHAR_DQUOTE: W.AddByte(CHAR_DQUOTE) ; break ; case CHAR_LC_N: W.AddByte(CHAR_NL) ; break ; default: W.AddByte(*zi) ; } } if (*zi == CHAR_DQUOTE) { zi++ ; break ; } W.AddByte(*zi) ; }
if (!W.Size()) { rc = E_FORMAT ; err.Printf("No data class memeber name found on line %d col %d\n", zi.Line(), zi.Col()) ; break ; } if (*zi != CHAR_COLON) { rc = E_FORMAT ; err.Printf("Expected colon after name on line %d col %d\n", zi.Line(), zi.Col()) ; break ; } mbrName = W ; W.Clear() ; for (zi++ ; !zi.eof() && *zi <= CHAR_SPACE ; zi++) ; // LOOKUP MEMBER pMbr = pOD->m_pClass->GetMember(mbrName) ; if (!pMbr) { rc = E_FORMAT ; err.Printf("Line %d col %d. Member %s not found in class %s\n", zi.Line(), zi.Col(), *mbrName, pOD->m_pClass->txtName()) ; break ; }
if (pMbr->Basetype() == BASETYPE_CLASS) { // Recurse to handle sub-class hzArray <_obj_data*>* pArr ; // Cast to array of subclass objects const hdbClass* pSubclass ; // Subclass (if any) _obj_data* pSub ; // Subclass object uchar* pMCS ; // Pointer to member core space
pSubclass = dynamic_cast<const hdbClass*>(pMbr->Datatype()) ;
pMCS = pOD->m_Core + pMbr->OsetStd() ; pArr = (hzArray<_obj_data*>*) pMCS ; pSub = _obj_data::GetInstance(pSubclass) ; pArr->Add(pSub) ;
rc = _import_json_r(err, zi, pSub) ; continue ; }
bMultVal = false ; if (*zi == CHAR_SQOPEN) { bMultVal = true ; zi++ ; } for (; !zi.eof() && *zi <= CHAR_SPACE ; zi++) ;
// Expect member value. Can be single value or array but not an object as these are dealt with by sub-class recursion for (;;) { // Get value if (*zi == CHAR_DQUOTE) { // Get quoted value (handle escapes) for (zi++ ;; zi++) { if (*zi == CHAR_BKSLASH) { zi++ ; switch (*zi) { case CHAR_DQUOTE: W.AddByte(CHAR_DQUOTE) ; break ; case CHAR_LC_N: W.AddByte(CHAR_NL) ; break ; default: W.AddByte(*zi) ; } } if (*zi == CHAR_DQUOTE) { zi++ ; break ; } W.AddByte(*zi) ; } } else { for (; *zi >= CHAR_SPACE && *zi != CHAR_SCOLON ; zi++) W.AddByte(*zi) ; } str_val = W ; W.Clear() ;
if (str_val == "null") str_val.Clear() ;
for (; !zi.eof() && *zi <= CHAR_SPACE ; zi++) ;
// Set atom atom.SetValue(pMbr->Basetype(), str_val) ; if (atom.Status() == ATOM_SET) pOD->SetValue(pMbr, atom) ;
// Continue if multiple else break if (bMultVal) { // Expect either a comma or a closing square brace if (*zi == CHAR_COMMA) { zi++ ; continue ; } for (; !zi.eof() && *zi <= CHAR_SPACE ; zi++) ; if (*zi == CHAR_SQCLOSE) zi++ ; }
for (; !zi.eof() && *zi <= CHAR_SPACE ; zi++) ;
if (*zi != CHAR_SCOLON) { rc = E_FORMAT ; err.Printf("Line %d Col %d Expected semi-colon to end value (at %c)\n", zi.Line(), zi.Col(), *zi) ; break ; } zi++ ; break ; } }
if (rc != E_OK) break ;
for (; !zi.eof() && *zi <= CHAR_SPACE ; zi++) ; if (*zi != CHAR_CURCLOSE) { rc = E_FORMAT ; err.Printf("Line %d Col %d Expected closing curly brace to end object (at %c)\n", zi.Line(), zi.Col(), *zi) ; break ; } for (zi++ ; !zi.eof() && *zi <= CHAR_SPACE ; zi++) ;
// Continue if multiple object else break if (bMultObj) { // Expect either a comma or a closing square brace if (*zi == CHAR_COMMA) { zi++ ; objId++ ; continue ; } for (; !zi.eof() && *zi <= CHAR_SPACE ; zi++) ; if (*zi != CHAR_SQCLOSE) { rc = E_FORMAT ; err.Printf("Line %d Col %d Expected closing square brace to end object array (at %c)\n", zi.Line(), zi.Col(), *zi) ; break ; } zi++ ; } break ; }
return rc ; }
hzEcode hdbObject::ImportJSON (const hzChain& J) { // Import the hdbObject value as a JSON. Note that the JSON must be compatible with the native data class. // // Arguments: 1) J The JSON as hzChain // // Returns: E_NOINIT If this hdbObject is not initialized // E_NODATA If the supplied JSON is empty // E_FORMAT If the JSON does not comply with the data class // E_OK Operation successful
_hzfunc("hdbObject::ImportJSON") ;
hzChain err ; // Gather all errors chIter zi ; // Chain iterator hzEcode rc ; // Return code
if (!m_pClass) return E_NOINIT ; if (!J.Size()) return E_NODATA ;
Clear() ;
zi = J ; if (*zi != CHAR_CUROPEN) return E_FORMAT ;
if (!m_pRoot) m_pRoot = _obj_data::GetInstance(m_pClass) ;
rc = _import_json_r(err, zi, m_pRoot) ; if (rc != E_OK) { threadLog("START IMPORT ERROR\n") ; threadLog(err) ; threadLog("END IMPORT ERROR\n") ; }
return rc ; }
/* ** EDO Import/Export Functions */
hzEcode hdbObject::ImportEDO (const hzChain& Z) { // Populate the hdbObject with the supplied hzChain content, which must be an EDO. This function is strictly for the purposes of LOADING from a hdbObjRepos cache. Please note // the following:- // // a) In the case of STRING and string-like datum, the string space address is copied from the EDO but then the member core space is cast to the applicable class in order // to keep proper track of the string space copy count. // // b) For BINARY and TXTDOC members, the binary datum address appears in the EDO and is copied to the aux, rather than the core space. The core space only comes into play // when the binary is fetched, at which point the core space is cast to a hzChain (in order to keep track of the copy count). // // c) For single selection ENUM members, the core space is 1 byte. For multiple selection ENUM members, the core space is however many bytes are needed to hold the bitmap // covering the entire ENUM population. In the latter case, the EDO entry for the member will have a length indicator (1 byte), followed by an idset encoding. // // d) For subclass members, the EDO will either contain the address of the subclass objects or a list of EDOs representing the actual subclass objects - depending on the // repository configuration. By default repositories do not store data objects, be those of the host native data class, or of any subclass. // // Argument: Z The input serialize object // // Returns: E_FORMAT If the supplied chain does not comply with the expected format // E_OK If the operation is successful
_hzfunc("hdbObject::ImportEDO") ;
const hdbMember* pMbr ; // This class member hzMD5 digest ; // MD5 chIter zi ; // Input iterator chIter zend ; // Input iterator (expected end) _atomval av ; // For 64 and 32 bit values const hdbEnum* pEnum ; // ENUM data type (if applicable) uchar* pLitmus ; // Litmus bits uchar* pMCS ; // Pointer to member core space hzString* pStr ; // Cast to string hzDomain* pDom ; // Cast to domain hzEmaddr* pEma ; // Cast to emaddr hzUrl* pUrl ; // Cast to URL hzString S ; // Temp string uint32_t mbrNo ; // Member number (position within class) uint32_t nLenEDO ; // EDO tail length uint32_t nObjId ; // Object id uint32_t nC ; // Counter uint32_t bitMask ; // Litmus bit mask hzEcode rc ; // Return code
// Object has class? if (!m_pClass) hzexit(E_NOINIT, "Object has no class") ;
if (!m_pRoot) m_pRoot = _obj_data::GetInstance(m_pClass) ;
pLitmus = m_pRoot->m_Core + m_pClass->CoreLen() ;
// Obtain the EDO length and object id zi = Z ; rc = ReadSerialUINT32(nLenEDO, zi) ; if (rc != E_OK) return hzerr(rc, "Could not process EDO length") ;
memset(m_pRoot->m_Core, 0, m_pClass->CoreLen()) ; memset(pLitmus, 0, m_pClass->MbrCount()) ;
zend = zi ; zend += nLenEDO ; rc = ReadSerialUINT32(nObjId, zi) ; if (rc != E_OK) return hzerr(rc, "Could not process EDO Object Id") ; //threadLog("Reading EDO %u of %u bytes\n", nObjId, nLenEDO) ;
// Grab the litmus bits bitMask = 128 ; for (mbrNo = nC = 0 ; mbrNo < m_pClass->MbrCount() ; mbrNo++) { if (*zi & bitMask) { nC++ ; pLitmus[mbrNo] = LITMUS_SET ; }
bitMask /= 2 ; if (bitMask == 0) { bitMask = 128 ; zi++ ; } }
if (bitMask < 128) zi++ ;
// Count up how many entries the fixed part will have for (mbrNo = 0 ; rc == E_OK && mbrNo < m_pClass->MbrCount() ; mbrNo++) { pMbr = m_pClass->GetMember(mbrNo) ;
if (pLitmus[mbrNo] == 0) continue ;
if (pMbr->Basetype() == BASETYPE_BOOL || pMbr->Basetype() == BASETYPE_TBOOL) continue ;
// Set pointer to member core space pMCS = m_pRoot->m_Core + pMbr->OsetStd() ;
if (pMbr->Basetype() == BASETYPE_ENUM) { if (pMbr->Singular()) { // Single selection, only 1 byte pMCS[0] = *zi++ ; continue ; }
// Multiple selections allowed, so treat the EDO entry as an idset-encoded bitmap pEnum = dynamic_cast<const hdbEnum*>(pMbr->Datatype()) ; if (pEnum->Count() < 31) { // In this case the length is 4 bytes } continue ; }
if (pMbr->Basetype() == BASETYPE_BINARY || pMbr->Basetype() == BASETYPE_TXTDOC) { // The EDO will only contain the address (uint32_t), which must go in the member AUX area for (nC = 0 ; !zi.eof() && nC < 4 ; nC++, zi++) { pMCS[nC] = *zi ; } continue ; }
pMCS = m_pRoot->m_Core + pMbr->OsetStd() ; for (nC = 0 ; !zi.eof() && nC < pMbr->SizeDatum() ; nC++, zi++) { pMCS[nC] = *zi ; }
if (nC < pMbr->SizeDatum()) threadLog("Incomplete read of member %s\n", pMbr->txtName()) ;
if (pMbr->Basetype() == BASETYPE_STRING || pMbr->Basetype() == BASETYPE_APPDEF) { pStr = (hzString*) pMCS ; if (pStr) pStr->_inc_copy() ; }
if (pMbr->Basetype() == BASETYPE_DOMAIN) { pDom = (hzDomain*) pMCS ; if (*pDom) pDom->_inc_copy() ; }
if (pMbr->Basetype() == BASETYPE_EMADDR) { pEma = (hzEmaddr*) pMCS ; if (*pEma) pEma->_inc_copy() ; }
if (pMbr->Basetype() == BASETYPE_URL) { pUrl = (hzUrl*) pMCS ; if (*pUrl) pUrl->_inc_copy() ; } }
if (zi != zend) { rc = hzerr(E_CORRUPT, "Object Id %u: Not at EDO end\n", nObjId) ; for (zi = Z, nC = 0 ; !zi.eof() && nC <= nLenEDO ; nC++, zi++) { threadLog("%u: char is %02x\n", nC, (uchar) *zi) ; } }
return rc ; }
uint32_t _calc_edo_len (const hdbClass* pClass, const uchar* pCore, uint32_t objId) { // Support function to ExportEDO(). Calculates the length of the would-be EDO ahead of its export. // // Given the applicable class (arg 1), and the supplied buffer (pCore, assumed to be a hdbObject core), calculate the length of the would-be EDO. Note the following factors:- // // The process loops through all the direct members in the object. For single value members, the space needed in the EDO is either 0 (member is NULL), or the datum size (which // depends on the data type). For multiple value members (arrays), of an atomic data type, the space needed is the datum size multiplied by the number of values, plus the size // of the serial integer needed to indicate the number of values. If there are no CLASS members or the CLASS members are empty, the total size returned will be the total space // consumed by members which are present, plus the size of the litmus block as per the class, plus the size of the serial integer needed to indicate the object id. // // For CLASS members which are invariably multiple value, this function is recursively called on each subclass object in the array. CLASS members appear in the EDO as a serial // integer stating the aggregate total size of the subclass objects, followed by a concatenation of the subclass objects, each of which has a litmus block, a serial integer tp // indicate the object id, and a serial integer to indicate object size!
_hzfunc("calc_edo_len") ;
const hdbMember* pMbr ; // This class member const uchar* pMCS ; // Member core space const uchar* pLitmus ; // Litmus byte uint32_t mbrNo ; // EDO tail length //uint32_t subSize ; // Size of subclass EDO uint32_t edoSize ; // Size of EDO uint32_t n ; // Loop counter (for arrays)
// Object has class? if (!pClass) { hzerr(E_ARGUMENT, "No class supplied") ; return 0 ; } if (!pCore) { hzerr(E_ARGUMENT, "No object supplied") ; return 0 ; }
edoSize = SizeSerialUINT32(objId) ; edoSize += pClass->LitmusSize() ; pLitmus = pCore + pClass->CoreLen() ;
for (mbrNo = 0 ; mbrNo < pClass->MbrCount() ; pLitmus++, mbrNo++) { pMbr = pClass->GetMember(mbrNo) ;
if (!(*pLitmus & LITMUS_SET)) continue ;
if (pMbr->Basetype() == BASETYPE_CLASS) { hzArray <_obj_data*>* pArr ; // Cast to array of subclass objects const hdbClass* pSubclass ; // Subclass (if any) _obj_data* pSub ; // Subclass object
pSubclass = dynamic_cast<const hdbClass*>(pMbr->Datatype()) ;
pMCS = pCore + pMbr->OsetStd() ; pArr = (hzArray<_obj_data*>*) pMCS ; edoSize = SizeSerialUINT32(pArr->Count()) ;
for (n = 0 ; n < pArr->Count() ; n++) { pSub = pArr->operator[](n) ; edoSize += _calc_edo_len(pSubclass, pSub->m_Core, n+1) ; } continue ; }
if (pMbr->Basetype() == BASETYPE_BINARY || pMbr->Basetype() == BASETYPE_TXTDOC) edoSize += 4 ; else edoSize += pMbr->SizeDatum() ; }
return edoSize ; }
hzEcode _export_edo_r (hzChain& E, const hdbClass* pClass, const uchar* pCore, uint32_t objId) { // Support function to the ExportTailEDO() member function. // // This exports an EDO from the contents held in this hdbObject's core. The export process begins with the litmus bits and follows with the member data. Subclass members which // are manifest as arrays of subclass hdbObject cores, are handled by recursive calls to this function.
_hzfunc("hdbObject::_export_edo_r") ;
const hdbMember* pMbr ; // This class member const uchar* pMCS ; // Member core space const uchar* pLitmus ; // Litmus byte hzAtom atom ; // Staging value _atomval av ; // 64-bit value from member space hzString* pStr ; // Temp string pointer (memeber data cast) hzDomain* pDom ; // Temp domain pointer (member data cast) hzEmaddr* pEma ; // Temp email pointer (member data cast) hzUrl* pUrl ; // Temp URL pointer (member data cast) uint32_t* pInt ; // Cast to UINT32 hzString str ; // Temp string instance uint32_t mbrNo ; // EDO tail length uint32_t nSerlen ; // Length of serialized integer uint32_t nSize ; // Size of EDO based on litmus bits uint32_t n ; // Loop counter (for arrays) uchar bitMask ; // Bitwise litmus value uchar byte ; // Litmus byte to write to EDO tail
// Object has class? if (!pClass) return hzerr(E_NOINIT, "No class supplied") ; if (!pCore) return hzerr(E_NOINIT, "No core supplied") ;
pLitmus = pCore + pClass->CoreLen() ;
// Check the litmus bits to determine which members have values. This will also determine the size of the EDO. nSize = _calc_edo_len(pClass, pCore, objId) ; if (!nSize) return hzerr(E_NODATA, "Zero EDO size") ; WriteSerialUINT32(E, nSerlen, nSize) ;
// Write the object id WriteSerialUINT32(E, nSerlen, objId) ;
// Build the EDO tail in chain E. Start with checking the object's litmus bits. This will pLitmus = pCore + pClass->CoreLen() ; bitMask = 128 ; byte = 0 ;
for (mbrNo = 0 ; mbrNo < pClass->MbrCount() ; pLitmus++, mbrNo++) { if (*pLitmus & LITMUS_SET) { // The member has a value (or is a BOOL) byte |= bitMask ; }
bitMask /= 2 ; if (bitMask == 0) { E.AddByte(byte) ; byte = 0 ; bitMask = 128 ; } }
// Deal with additional litmus bits pLitmus = pCore + pClass->CoreLen() ;
for (mbrNo = 0 ; mbrNo < pClass->MbrCount() ; pLitmus++, mbrNo++) { pMbr = pClass->GetMember(mbrNo) ;
if (pMbr->Basetype() == BASETYPE_TBOOL) { if (*pLitmus & LITMUS_AUX) byte |= bitMask ; } else { continue ; }
bitMask /= 2 ; if (bitMask == 0) { E.AddByte(byte) ; byte = 0 ; bitMask = 128 ; } }
if (bitMask < 128) E.AddByte(byte) ;
// Write out values pLitmus = pCore + pClass->CoreLen() ;
for (mbrNo = 0 ; mbrNo < pClass->MbrCount() ; pLitmus++, mbrNo++) { pMbr = pClass->GetMember(mbrNo) ; //threadLog("DOING member %s\n", pMbr->txtName()) ;
if (pMbr->Basetype() == BASETYPE_BOOL || pMbr->Basetype() == BASETYPE_TBOOL) continue ;
if (!(*pLitmus & LITMUS_SET)) continue ;
if (pMbr->Basetype() == BASETYPE_BINARY || pMbr->Basetype() == BASETYPE_TXTDOC) { pMCS = pCore + pMbr->OsetStd() ; pInt = (uint32_t*) pMCS ; E.Append(pMCS, 4) ; continue ; }
// Set member core space pointer pMCS = pCore + pMbr->OsetStd() ;
if (pMbr->Basetype() == BASETYPE_CLASS) { hzArray <_obj_data*>* pArr ; // Cast to array of subclass objects const hdbClass* pSubclass ; // Subclass (if any) _obj_data* pSub ; // Subclass object
pSubclass = dynamic_cast<const hdbClass*>(pMbr->Datatype()) ; if (!pSubclass) { hzerr(E_TYPE, "Member %s has no subclass", pMbr->txtName()) ; continue ; }
pArr = (hzArray<_obj_data*>*) pMCS ;
for (n = 0 ; n < pArr->Count() ; n++) { threadLog("DOING subclass object\n") ; pSub = pArr->operator[](n) ; _export_edo_r(E, pSubclass, pSub->m_Core, n+1) ; } continue ; }
// Data will be committed to the EDO. Where applicable, string repositories will be updated.
switch (pMbr->Basetype()) { case BASETYPE_DOMAIN: pDom = (hzDomain*) pMCS ; if (_hzGlobal_setDomains.Exists(*pDom)) _hzGlobal_setDomains[*pDom]._inc_copy() ; else _hzGlobal_setDomains.Insert(*pDom) ; *pDom = _hzGlobal_setDomains[*pDom] ; break ;
case BASETYPE_EMADDR: pEma = (hzEmaddr*) pMCS ; if (_hzGlobal_setEmaddrs.Exists(*pEma)) _hzGlobal_setEmaddrs[*pEma]._inc_copy() ; else _hzGlobal_setEmaddrs.Insert(*pEma) ; *pEma = _hzGlobal_setEmaddrs[*pEma] ; break ;
case BASETYPE_URL: pUrl = (hzUrl*) pMCS ; str = *pUrl ; if (_hzGlobal_setStrings.Exists(str)) _hzGlobal_setStrings[str]._inc_copy() ; else _hzGlobal_setStrings.Insert(str) ; break ;
case BASETYPE_STRING: pStr = (hzString*) pMCS ; str = *pStr ; //threadLog("doing value %s\n", *str) ; if (_hzGlobal_setStrings.Exists(str)) _hzGlobal_setStrings[str]._inc_copy() ; else _hzGlobal_setStrings.Insert(str) ; *pStr = _hzGlobal_setStrings[str] ; //threadLog("done value %s\n", *str) ; break ; }
E.Append(pMCS, pMbr->SizeDatum()) ; //threadLog("done mbr\n") ; } //threadLog("done object\n") ;
return E_OK ; }
hzEcode hdbObject::ExportEDO (hzChain& E) const { // Export an EDO tail, which is part of the EDO commit sequence. This begins with the litmus bits and follows with the member data. There is no length indicator at this point. // Note that this function does not clear the supplied chain. It simply appends the chain with the EDO of this object. // // Argument: E The chain to which the object EDO is appended // // Returns: E_NOINIT If this object is not initialized to a data class // E_OK Operation successful
_hzfunc("hdbObject::ExportEDO") ;
hzEcode rc ; // Return code
E.Clear() ; return _export_edo_r(E, m_pClass, m_pRoot->m_Core, m_pRoot->m_ObjId) ; }
/* ** Delta Import/Export Functions */
hzEcode _import_delta_r (chIter& zi, _obj_data* pOD, uint32_t nLevel) { // Populate object by reading in a whole object delta. This function assumes file deltas, which do not specify the repository or class as these are in the delta file header. // // This expects the supplied chain iterator (arg 1) to be iterating a chain whose content is a delta, and to be at a @obj or @sub sequence (or at a preceeding set of TABs).
_hzfunc(__func__) ;
const hdbMember* pMbr ; // Member hzAtom atom ; // Value carrier hzChain V ; // For member value hzString val ; // Member value as string uint32_t reposId ; // Repos id uint32_t datumId ; // Binary datum id uint32_t objId ; // Object id uint32_t mbrNo ; // Member number hzEcode rc = E_OK ; // Return code
if (!pOD->m_pClass) hzexit(E_ARGUMENT, "No class supplied") ;
//zi.Skipwhite() ;
if (!nLevel) { if (zi != "@obj") return hzerr(E_FORMAT, "Whole object deltas are expected to begin with '@obj'") ; zi += 4 ; } else { if (*zi != CHAR_LC_S) return hzerr(E_FORMAT, "Class %s: Whole subclass object deltas are expected to begin with 's'", pOD->m_pClass->txtName()) ; zi++ ; }
// Get object id for (objId = 0 ; IsDigit(*zi) ; zi++) { objId *= 10 ; objId += (*zi - '0') ; } pOD->m_ObjId = objId ; threadLog("Class %s obj %u\n", pOD->m_pClass->txtName(), objId) ;
// Expect start of object if (zi != "={\n") return hzerr(E_FORMAT, "Class %s: Object %u: Expected a '={' follow by newline, to declare object. Got %c", pOD->m_pClass->txtName(), objId, *zi) ; zi += 3 ;
// Look for member entries ('m' followed by member number and = sign) for (; rc == E_OK && !zi.eof() ;) { //zi.Skipwhite() ; for (; *zi == CHAR_NL || *zi == CHAR_TAB ; zi++) ; if (*zi == '}') { zi++ ; break ; }
// Expect start of member if (*zi != CHAR_LC_M) { rc = hzerr(E_FORMAT, "Class %s: Expected a member value starting with 'm'. Got [%c]", pOD->m_pClass->txtName(), *zi) ; for (; !zi.eof() ; zi++) threadLog("char is [%c]\n", *zi) ; break ; }
// Get member number for (zi++, mbrNo = 0 ; IsDigit(*zi) ; zi++) { mbrNo *= 10 ; mbrNo += *zi - '0' ; }
pMbr = pOD->m_pClass->GetMember(mbrNo) ; if (!pMbr) { rc = hzerr(E_FORMAT, "Class %s: Member %d does not exist\n", pOD->m_pClass->txtName(), mbrNo) ; break ; } threadLog("Doing Class %s Member %s\n", pOD->m_pClass->txtName(), pMbr->txtName()) ;
// Deal with subclass member if (pMbr->Basetype() == BASETYPE_CLASS) { hzArray <_obj_data*>* pArr ; // Cast to array of subclass objects const hdbClass* pSubclass ; // Subclass (if any) _obj_data* pSub ; // Subclass object uchar* pMCS ; // Pointer to member core space
pSubclass = dynamic_cast<const hdbClass*>(pMbr->Datatype()) ;
pSub = _obj_data::GetInstance(pSubclass) ; _import_delta_r(zi, pSub, nLevel + 1) ;
pMCS = pOD->m_Core + pMbr->OsetStd() ; pArr = (hzArray<_obj_data*>*) pMCS ; //rc = pArr->Add(pSub) ; //if (rc != E_OK) // { rc = hzerr(rc, "Could not add subclass object to array") ; break ; } //threadLog("Subclass object array now has %u items\n", pArr->Count()) ; continue ; }
// Expect equal sign if (*zi != CHAR_EQUAL) { rc = hzerr(E_FORMAT, "Class %s: Member %u %s: Expected an '=' sign. Got [%c]", pOD->m_pClass->txtName(), mbrNo, pMbr->txtName(), *zi) ; break ; } zi++ ;
// Deal with BOOL and TBOOL members if (pMbr->Basetype() == BASETYPE_BOOL || pMbr->Basetype() == BASETYPE_TBOOL) { if (zi == "true") pOD->SetBool(pMbr, true) ; else pOD->SetBool(pMbr, false) ; threadLog("Set bool member\n") ; for (; !zi.eof() && *zi != CHAR_NL ; zi++) ; zi++ ; threadLog("Continuing ....\n") ; continue ; }
// Get value or binary datum address if (pMbr->Basetype() == BASETYPE_BINARY || pMbr->Basetype() == BASETYPE_TXTDOC) { // Get binary address datumId = 0 ; for (; !zi.eof() ;) { if (*zi == CHAR_NL) { zi++ ; break ; }
if (!IsDigit(*zi)) { rc = hzerr(E_FORMAT, "Class %s: Member %u %s: Binary address so digits only", pOD->m_pClass->txtName(), mbrNo, pMbr->txtName()) ; break ; } datumId *= 10 ; datumId += (*zi - '0') ; zi++ ; }
if (rc != E_OK) break ;
//threadLog("datum Id %u char %c\n", datumId, *zi) ; rc = pOD->SetBinAddr(pMbr, datumId) ; continue ; }
// For STRING and TEXT members, deal with possible multi-line values // if (pMbr->Basetype() == BASETYPE_STRING || pMbr->Basetype() == BASETYPE_TEXT) // { // }
// For all other cases gather the value into a chain, convert to a string and use this to set an atom, use the atom to set the value. for (; !zi.eof() ;) { if (*zi == CHAR_NL) { for (zi++ ; *zi == CHAR_TAB ; zi++) ; if (*zi == '}') break ; if (*zi == 'm') break ;
// Otherwise we have a multiple line value V.AddByte(CHAR_NL) ; continue ; }
V.AddByte(*zi) ; zi++ ;
if (V.Size() > 1000) { rc = hzerr(E_FORMAT, "Class %s. Member %u %s: Excess size", pOD->m_pClass->txtName(), mbrNo, pMbr->txtName()) ; break ; } } val = V ; V.Clear() ;
atom.SetValue(pMbr->Basetype(), val) ; rc = pOD->SetValue(pMbr, atom) ;
if (rc != E_OK) { hzerr(rc, "Class %s: Could not set member %s with [%s]\n", pOD->m_pClass->txtName(), pMbr->txtName(), *val) ; break ; } }
return rc ; }
hzEcode hdbObject::ImportDelta (const hzChain& Z) { // Populate object by reading in a whole object delta // // Argument: Z Chain to which delta is written // // Returns: E_FORMAT If the delta is malformed // E_OK Operation successful
_hzfunc("hdbObject::ImportDelta") ;
chIter zi ; // Chain iterator
zi = Z ; if (zi != "@obj") return hzerr(E_FORMAT, "Whole object deltas are expected to begin with '@obj'") ;
// Clear object Clear() ; if (!m_pRoot) m_pRoot = _obj_data::GetInstance(m_pClass) ;
threadLog("Importing delta of %d bytes\n", Z.Size()) ; return _import_delta_r(zi, m_pRoot, 0) ; }
hzEcode _export_delta_r (hzChain& D, const hdbClass* pClass, const uchar* pCore, uint32_t objId, uint32_t nLevel) { // Support function to the ExportDelta() member function. // // This exports an EDO from the contents held in this hdbObject's core. The export process begins with the litmus bits and follows with the member data. Subclass members which // are manifest as arrays of subclass hdbObject cores, are handled by recursive calls to this function.
_hzfunc("_export_delta_r") ;
const hdbMember* pMbr ; // This class member const uchar* pMCS ; // Member core space const uchar* pLitmus ; // Litmus byte hzMD5* pMd5 ; // Cast to hzMD5 hzString* pStr ; // Cast to string hzDomain* pDom ; // Cast to domain hzEmaddr* pEma ; // Cast to emaddr hzUrl* pUrl ; // Cast to URL uint32_t* pUint ; // Cast to uint32 hzAtom atom ; // Staging value _atomval av ; // Atomval uint32_t mbrNo ; // Member number uint32_t nI ; // Loop counter (for indentation) uint32_t nA ; // Loop counter (for object arrays) hzEcode rc ; // Return code
if (nLevel) { //for (nI = nLevel ; nI ; nI--) // D.AddByte(CHAR_TAB) ; //D.Printf("@sub %u:%u\n", pClass->ClassId(), objId) ; D.Printf("s%u", objId) ; } else //D.Printf("@obj %u:%u\n", pClass->ClassId(), objId) ; D.Printf("@obj%u", objId) ;
//for (nI = nLevel ; nI ; nI--) // D.AddByte(CHAR_TAB) ; D << "={\n" ;
//threadLog("case 1\n") ; pLitmus = pCore + pClass->CoreLen() ;
for (mbrNo = 0 ; mbrNo < pClass->MbrCount() ; pLitmus++, mbrNo++) { //threadLog("case 2\n") ; pMbr = pClass->GetMember(mbrNo) ;
if (pMbr->Basetype() == BASETYPE_BOOL) { //threadLog("case 3\n") ; for (nI = nLevel ; nI ; nI--) D.AddByte(CHAR_TAB) ; if (*pLitmus & LITMUS_SET) D.Printf("\tm%d=true\n", mbrNo) ; else D.Printf("\tm%d=false\n", mbrNo) ; continue ; }
if (!(*pLitmus & LITMUS_SET)) continue ;
// Output values if (pMbr->Basetype() == BASETYPE_TBOOL) { //threadLog("case 4\n") ; for (nI = nLevel ; nI ; nI--) D.AddByte(CHAR_TAB) ;
if (*pLitmus & LITMUS_AUX) D.Printf("\tm%d=true\n", mbrNo) ; else D.Printf("\tm%d=false\n", mbrNo) ; continue ; }
if (pMbr->Basetype() == BASETYPE_BINARY || pMbr->Basetype() == BASETYPE_TXTDOC) { //threadLog("case 7\n") ; pUint = (uint32_t*) (pCore + pMbr->OsetStd()) ; D.Printf("\tm%d=%u\n", mbrNo, *pUint) ; continue ; }
// Get pointer to member core space pMCS = pCore + pMbr->OsetStd() ;
if (pMbr->Basetype() == BASETYPE_CLASS) { hzArray <_obj_data*>* pArr ; // Cast to array of subclass objects const hdbClass* pSubclass ; // Subclass (if any) _obj_data* pSub ; // Subclass object
//threadLog("case 5\n") ; pSubclass = dynamic_cast<const hdbClass*>(pMbr->Datatype()) ;
pArr = (hzArray<_obj_data*>*) pMCS ;
for (nA = 0 ; nA < pArr->Count() ; nA++) { for (nI = nLevel ; nI ; nI--) D.AddByte(CHAR_TAB) ; D.Printf("\tm%u", mbrNo) ;
pSub = pArr->operator[](nA) ; _export_delta_r(D, pSubclass, pSub->m_Core, nA+1, nLevel+1) ; pSub->Clear() ; } continue ; }
// Indent for (nI = nLevel ; nI ; nI--) D.AddByte(CHAR_TAB) ; //threadLog("case 6\n") ;
if (pMbr->Basetype() == BASETYPE_STRING) { pStr = (hzString*) pMCS ; D.Printf("\tm%d=%s\n", mbrNo, (const char*) *pStr) ; continue ; } if (pMbr->Basetype() == BASETYPE_DOMAIN) { pDom = (hzDomain*) pMCS ; D.Printf("\tm%d=%s\n", mbrNo, (const char*) *pDom) ; continue ; } if (pMbr->Basetype() == BASETYPE_EMADDR) { pEma = (hzEmaddr*) pMCS ; D.Printf("\tm%d=%s\n", mbrNo, (const char*) *pEma) ; continue ; } if (pMbr->Basetype() == BASETYPE_URL) { pUrl = (hzUrl*) pMCS ; D.Printf("\tm%d=%s\n", mbrNo, (const char*) *pUrl) ; continue ; }
if (pMbr->Basetype() == BASETYPE_DIGEST) { //threadLog("case A\n") ; pMd5 = (hzMD5*) pMCS ; D.Printf("\tm%d=%s\n", mbrNo, pMd5->Txt()) ; continue ; }
//threadLog("case 8\n") ; // Deal with other types switch (pMbr->Basetype()) { case BASETYPE_XDATE: { hzXDate* pXd ; pXd = (hzXDate*) pMCS ; atom = *pXd ; } break ;
case BASETYPE_SDATE: atom = (hzSDate*) pMCS ; break ; //memcpy(pMCS, &av.m_uInt32, 4) ; break ; case BASETYPE_TIME: atom = (hzTime*) pMCS ; break ; //memcpy(pMCS, &av.m_uInt32, 4) ; break ; default: //threadLog("case 9\n") ; av.m_uInt64 = 0 ; memcpy(&av, pMCS, pMbr->SizeDatum()) ; atom.SetValue(pMbr->Basetype(), av) ; } //threadLog("case 10\n") ; D.Printf("\tm%d=%s\n", mbrNo, atom.Show()) ; } //threadLog("case 11\n") ;
for (nI = nLevel ; nI ; nI--) D.AddByte(CHAR_TAB) ; D << "}\n" ; return E_OK ; }
hzEcode hdbObject::ExportDelta (hzChain& Z) const { // Write out whole form delta // // Argument: Z Chain to which delta is written
_hzfunc("hdbObject::ExportDelta") ;
Z.Clear() ; return _export_delta_r(Z, m_pClass, m_pRoot->m_Core, m_pRoot->m_ObjId, 0) ; }
/* ** JSON Export */
static void _write_mbr_JSON (hzChain& J, const hdbMember* pMbr, _atomval av, uint32_t nLevel) { // JSON Export support function: Write out a single value and nothing but a single value, but only if the value is in the supplied _atomval. Values of BOOL and TBOOL members // are in the litmus bits and not handled here.
hzIpaddr ipa ; // IP address hzTime stime ; // hzTime hzSDate sdate ; // Short form date hzSDate xdate ; // Long form date hzString strVal ; // Test string
switch (pMbr->Basetype()) { // 64-bit entities case BASETYPE_DOUBLE: J.Printf("%f", av.m_Double) ; break ; case BASETYPE_INT64: J.Printf("%dl", av.m_sInt64) ; break ; case BASETYPE_UINT64: J.Printf("%ul", av.m_uInt64) ; break ;
case BASETYPE_XDATE: xdate = av.m_uInt64 ; J.Printf("\"%s\"", xdate.Txt()) ; break ;
// 32-bit entities case BASETYPE_INT32: J.Printf("%d", av.m_sInt32) ; break ; case BASETYPE_INT16: J.Printf("%d", av.m_sInt16) ; break ; case BASETYPE_BYTE: J.Printf("%d", av.m_sByte) ; break ; case BASETYPE_UINT32: J.Printf("%u", av.m_uInt32) ; break ; case BASETYPE_UINT16: J.Printf("%u", av.m_uInt16) ; break ; case BASETYPE_UBYTE: J.Printf("%u", av.m_uByte) ; break ;
case BASETYPE_IPADDR: ipa = av.m_uInt32 ; J.Printf("\"%s\"", *ipa) ; break ; case BASETYPE_TIME: stime = av.m_uInt32 ; J << stime.Txt() ; break ; case BASETYPE_SDATE: sdate = av.m_uInt32 ; J << sdate.Txt() ; break ;
// Strings case BASETYPE_EMADDR: case BASETYPE_URL: case BASETYPE_STRING: case BASETYPE_APPDEF: case BASETYPE_TEXT: J.AddByte(CHAR_DQUOTE) ; strVal.Clear() ; strVal._int_set(av.m_uInt32) ; J << strVal ; strVal._int_clr() ; J.AddByte(CHAR_DQUOTE) ; break ;
#if 0 case BASETYPE_BINARY: // File assummed to be un-indexable (eg image). Stored on disk, infrequent change. case BASETYPE_TXTDOC: // Document from which text can be extracted/indexed. Stored on disk, infrequent change. J.Printf("%u", val) ; break ;
case BASETYPE_ENUM: // Kludge for now #endif } }
hzEcode hdbObject::_export_json_r (hzChain& json, const hdbClass* pClass, uint32_t nLevel) const { // Recursive JSON export by class. // // This function writes out the opening '{', member values in the first level of the applicable data object, then the closing '}'. Member values are written in order of member // position within the applicable data class. Recursion is used to export subclass objects. All atomic values are written out in full text form except BINARY and TXTDOC, which // are written as Base64. // // Arguments: 1) J The hzChain to be populated by the JSON value // 2) nLevel The object level
_hzfunc("hdbObject::_export_json_r") ;
//hzArray<_atomval>* pArr8 ; // Pointer to an array of 64-bit values //hzArray<uint32_t>* pArr4 ; // Pointer to an array of 32-bit values
hzAtom atom ; // Extracted value _atomval av ; // 64-bit value from member space //const hdbClass* pSub ; // Sub-class const hdbMember* pMbr ; // Member pointer uchar* pLitmus ; // Litmus byte uchar* pMCS ; // Member core space
uint32_t mbrNo ; // Member number //uint32_t objId ; // Object number uint32_t nIndent ; // Indent iterator //int32_t nV ; // Value iterator //int32_t val ; // Value from m_Values (value or offset into m_Large or m_Strings) uint32_t n ; // Array counter
// Object has class? if (!m_pClass) return hzerr(E_NOINIT, "Object has no class") ;
// Write the opening '{' json << "{\n" ;
// Write out values pLitmus = m_pRoot->m_Core + m_pClass->CoreLen() ;
for (mbrNo = 0 ; mbrNo < m_pClass->MbrCount() ; pLitmus++, mbrNo++) { pMbr = m_pClass->GetMember(mbrNo) ;
for (nIndent = 0 ; nIndent <= nLevel ; nIndent++) json.AddByte(CHAR_TAB) ; json.Printf("\"%s\": ", pMbr->txtName()) ;
// Deal with BOOL and TBOOL members if (pMbr->Basetype() == BASETYPE_BOOL) { if (m_pRoot->m_Core[pMbr->OsetStd()] & LITMUS_SET) json << "true;\n" ; else json << "false;\n" ; continue ; } if (pMbr->Basetype() == BASETYPE_TBOOL) { if (m_pRoot->m_Core[pMbr->OsetStd()] & LITMUS_SET) { if (m_pRoot->m_Core[pMbr->OsetStd()] & LITMUS_AUX) json << "true;\n" ; else json << "false;\n" ; } else json << "null;\n" ; continue ; }
// Deal with empty member if (!(*pLitmus & LITMUS_SET)) { json << "null;\n" ; continue ; }
// Recurse if sub-class if (pMbr->Basetype() == BASETYPE_CLASS) { hzArray <_obj_data*>* pArr ; // Cast to array of subclass objects const hdbClass* pSubclass ; // Subclass (if any) //_obj_data* pSub ; // Subclass object
pSubclass = dynamic_cast<const hdbClass*>(pMbr->Datatype()) ;
pArr = (hzArray<_obj_data*>*) pMCS ;
for (n = 0 ; n < pArr->Count() ; n++) { //pSub = pArr->operator[](n) ; _export_json_r(json, pSubclass, nLevel + 1) ; } continue ; }
// Write out member values as an array if multiple values are allowed (even if only 1 is present) if (pMbr->Multiple()) { // Array of values json << "[\n" ;
// array present /* if (pMbr->SizeVal() == 8) { // 64-bit values pArr8 = (hzArray<_atomval>*) av.m_pVoid ;
av = pArr8->operator[](0) ; _write_mbr_JSON(json, pMbr, av, nLevel) ;
for (n = 1 ; n < pArr8->Count() ; n++) { json.AddByte(CHAR_COMMA) ; av = pArr8->operator[](n) ; _write_mbr_JSON(json, pMbr, av, nLevel) ; } } else { // Values of 32-bit size or less pArr4 = (hzArray<uint32_t>*) av.m_pVoid ;
av.m_uInt32 = pArr4->operator[](0) ; _write_mbr_JSON(json, pMbr, av, nLevel) ;
for (n = 1 ; n < pArr4->Count() ; n++) { json.AddByte(CHAR_COMMA) ; av.m_uInt32 = pArr4->operator[](n) ; _write_mbr_JSON(json, pMbr, av, nLevel) ; } } */ json << "]\n" ; continue ; }
if (*pLitmus & LITMUS_SET) { _write_mbr_JSON(json, pMbr, av, nLevel) ; json.AddByte(NEWLINE) ; continue ; } }
return E_OK ; }
hzEcode hdbObject::ExportJSON (hzChain& J) const { // Export the hdbObject value as a JSON // // Argument: J The hzChain to be populated by the JSON value
_hzfunc("hdbObject::ExportJSON") ;
if (!m_pClass) return E_NOINIT ;
J.Clear() ; return _export_json_r(J, m_pClass, 0) ; }