#ifndef TOOLBOX_SHARED_H
#define TOOLBOX_SHARED_H

#include "tools.h"
#include "type.h"

struct cSharedData {
	private:
		uint  BufferLen;
		uint  NumRefs;

	public:
		static cSharedData *construct (size_t len);
		
		operator char * () { return this ? (char*)(this+1) : 0; }

		uint operator++ () { return ++NumRefs; }
		uint operator-- () { return --NumRefs; }

		uint size () const { return BufferLen; }
		uint refs () const { return NumRefs; }
};

class cShared: public cType {
	private:
		cSharedData *Buffer;

	protected:
		void  release   ();
		void  exclusive ();
		void  allocate (size_t len, bool keep = false);
		
		char *buffer   () const { return Buffer ? (char*)*Buffer : NULL; }
		
	public:
		cShared ();
		cShared (const cShared &src);
		virtual ~cShared ();

		virtual void  clear    ();
		virtual void  Set      (const cShared &src);
		
		virtual char *buffer   (uint size);
		virtual void  release  (uint newsize);

		cShared &operator= (const cShared &src) { Set(src); return *this; }

		operator const void * () const { return Buffer ? (void*)(char*)*Buffer 
				: NULL; }
		operator const char * () const { return Buffer ? (char*)*Buffer : NULL; }

		uint size   () const { return Buffer ? Buffer->size() : 0; }
		uint length () const { return Buffer ? Buffer->size() : 0; }

		// friend cSource &operator>> (cSource &dest, cShared &str);
};

inline char *cShared::buffer(uint size) {
	if ((!Buffer) || (Buffer->refs() > 1) || (size > Buffer->size()))
		allocate(size, true);
	return buffer();
}

#endif // TOOLBOX_SHARED_H
