#!/usr/bin/python

# cython: profile=True

'''Provides a buffer class'''

import array
import exceptions

ifdef(cython,c)def unpack_slice(position, ifdef(cython,cdef int )length):
	'''Unravel a slice'''
	start = position.start
	stop = position.stop
	step = position.step
	if start == None:
		start = 0
	if stop == None:
		stop = -1
	if step == None:
		step = 1
	if stop >= length:
		stop = length
	if start < 0:
		start = length + start
	if stop < 0:
		stop = length + stop
	return start, stop, step
		
ifdef(cython,cdef )class DRS_buffer:
	# pylint: disable=R0903
	# R0903: We don't want a lot of public methods

	ifdef(cython,cdef object array_)

	'''A buffer class, intended to work with Python 2.x and Python 3.x'''
	def __init__(self, initial_content = ''):
		self.array_ = array.array('B')
		self.array_.extend(initial_content)

	def __getitem__(self, position):
		if isinstance(position, int):
			return self.array_[position]
		elif isinstance(position, slice):
			start, stop, step = unpack_slice(position, `len'(self.array_))
			if step == 1:
				return self.array_[start:stop]
			else:
				return self.array_[start:stop:step]
		else:
			raise exceptions.ValueError, "position is not an integer or slice"

	def __delitem__(self, position):
		if isinstance(position, int):
			del self.array_[position]
		elif isinstance(position, slice):
			start, stop, step = unpack_slice(position, `len'(self.array_))
			if step == 1:
				if start == 0:
					self.array_ = self.array_[stop:]
				else:
					del self.array_[start:stop]
			else:
				del self.array_[start:stop:step]
		else:
			raise exceptions.ValueError, "position is not an integer or slice"
		
	ifdef(cython,c)def extend(self, values):
		'''Extend buffer by values'''
		ifdef(cython,cdef unsigned char byte)
		if isinstance(values, str):
			for character in values:
				byte = ord(character)
				self.array_.append(byte)
		elif isinstance(values, list):
			self.array_.extend(values)
		else:
			raise exceptions.ValueError, "values is not a string or list"

	def __len__(self):
		return `len'(self.array_)

	ifdef(cython,c)def append(self, value):
		'''Append a value to the array'''
		self.array_.append(value)