#ifndef OSTRING_H_INCLUDED
#define OSTRING_H_INCLUDED

//#include <crypto/crypto.h>
#include <iostream>
#include <cstdlib>


class Range_error {};


typedef unsigned char octet;

class ostring {
	octet *_data;
	int _capacity;
	int _size;

	void init() { _data = 0; _capacity = 0; _size = 0; }

 public:
	ostring()       // initialize to empty string
	{
		init();
	}

	~ostring();     // destructor

	ostring& operator=(const ostring&);  //assignment operator

	ostring(const ostring& s) // copy constructor
	{
		init();
		*this = s;
	}

	ostring& operator=(const char *); // assignment by cstr

	ostring(const char *s) // copy cstr constructor
	{
		init();
		*this = s;
	}

	ostring& operator=(octet);  // assignment by octet

	ostring(octet o) // copy octet constructor
	{
		init();
		*this = o;
	}

	ostring(int n, octet o); // n copies of o

	void reserve(int amt);  // set capacity to amt, allocating space,
				// but leaving size unaffected

	void resize(int sz);    // set size to sz, allocating space

	ostring substr(int pos, int len) const;  // substring pos..pos+len-1

	// access functions

	octet& operator[](int i)
	{
		return _data[i];
	}

	octet operator[](int i) const
	{
		return _data[i];
	}

	octet* data()              // returns a non-const pointer to data
	{
		return _data;
	}

	const octet* data() const  // returns a const pointer to data
	{
		return _data;
	}

	int size() const           // returns current size
	{
		return _size;
	}

	int capacity() const       // returns current capacity
	{
		return _capacity;
	}
};

// concatenation operators

ostring operator+(const ostring& a, const ostring& b);
ostring& operator+=(ostring& a, const ostring& b);

// equality testing

int operator!=(const ostring& left, const ostring& right);
int operator==(const ostring& left, const ostring& right);

// in-place reversal

void reverse(ostring & x);


#endif /* OSTRING_H_INCLUDED */

