#!/usr/bin/env python

import os 
import sys 
import time 
import pprint 
import random 
import tarfile 

try:
	from StringIO import StringIO as memoryio
except ImportError:
	from io import BytesIO as memoryio

class rawio:
	# mostly here to get binary I/O that works in 2.x and 3.x
	def __init__(self, filename=None, mode=7*64 + 7*8 + 7, perms = 6*64 + 6*8 + 6, handle=None):
		assert (filename != None) + (handle != None) == 1
		self.perms = perms
		if filename:
			self.filename = filename
			if mode == 'r':
				self.mode = os.O_RDONLY
			elif mode == 'w':
				self.mode = os.O_WRONLY | os.O_CREAT | os.O_TRUNC
			elif mode == 'rw':
				self.mode = os.O_RDRW | os.O_CREAT
			else:
				raise ValueError('Invalid mode: %s' % mode)
			self.file_descriptor = os.open(filename, self.mode, perms)
		elif handle:
			self.file_descriptor = handle

	open = __init__

	def read(self, length):
		return os.read(self.file_descriptor, length)

	def write(self, data):
		if hasattr(data, 'encode'):
			return os.write(self.file_descriptor, data.encode('latin-1'))
		else:
			return os.write(self.file_descriptor, data)

	def close(self):
		#os.close(self.file_descriptor)
		pass

	def __enter__(self):
		return self

	def __exit__(self, *dummy):
		os.close(self.file_descriptor)

string_file_1 = ("stringio first.txt",  8,     memoryio("one one\n".encode('ascii')),               None) 
string_file_2 = ("stringio second.txt", 4,     memoryio("two\n".encode('ascii')),                   None) 
string_file_3 = ("stringio third.txt",  2**16, memoryio(('\0' * 2**16).encode('ascii')),            None) 
string_file_4 = ("stringio fourth.txt", 4,     memoryio("two\n".encode('ascii')),                 string_file_2) 
string_file_5 = ("stringio fifth.txt",  896,   memoryio(('fifth of firth' * 2**6).encode('ascii')), None) 

tar = tarfile.open(fileobj=rawio(handle = 1), mode="w|") 

mtime = time.time() 
for name, length, file_, duplicates in [ 
	string_file_1,
	string_file_2,
	string_file_3,
	string_file_4,
	string_file_5,
	]: 
	tarinfo = tarfile.TarInfo(name) 
	#pprint.pprint(tarinfo)
	if length == None:
		tarinfo.size = file_.length
	else:
		tarinfo.size = length
	if name == 'stringio fourth.txt':
		tarinfo.type = tarfile.LNKTYPE
		tarinfo.linkname = 'stringio second.txt'
		tarinfo.size = 0
	else:
		tarinfo.type = tarfile.REGTYPE
	tarinfo.mtime = mtime 
	tarinfo.uname = 'dstromberg'
	tarinfo.gname = 'blee'
	tarinfo.mode = int('764', 8)
	# add more attributes as needed 
	#sys.stderr.write('%s\n' % pprint.pformat(dir(tarinfo)))
	tar.addfile(tarinfo, file_) 

tar.close()