# sectionedfile.py
#
# Copyright 2002 Wichert Akkerman <wichert@deephackmode.org>
#
# This file is free software; you can redistribute it and/or modify it
# under the terms of version 2 of the GNU General Public License as
# published by the Free Software Foundation.
#
# This program 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
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

"""Multipart file reader

A SectionedFile is a file that contains multiple sections, which are
seperator by a specific seperator. It works much like python's multifile,
except this eats consecutive seperators as well.
"""

__docformat__   = "epytext en"


class SectionedFile:
	"""Sectioned file reader.

	"""
	def __init__(self, fp):
		"""Simple constructor to initialize our data.

		@param fp: file to be read
		@type fp:  class instance supporting a readline() method
		"""
		self.fp=fp
		self.blocked=0
		self.eof=0
		self.divider=""
		self.mustunget=0
		self.unget=""


	def readline(self):
		"""Read the next line from our input.
		
		If a divider is hit an empty line is returned and further
		reading is blocked until unblock() is called. Dividers found
		at the beginning are skipped.

		@return: line of text
		@rtype:  string
		"""

		if self.blocked:
			return ""

		eating=0
		while 1:
			line=""
			if self.mustunget:
				line=self.unget
				self.mustunget=0
			else:
				line=self.fp.readline()
				if not line:
					self.eof=1
					self.blocked=1
					return ""

			if line.strip()==self.divider:
				eating=1
				continue;
			else:
				if eating:
					self.mustunget=1
					self.unget=line
					self.blocked=1
					return ""
				else:
					return line
		self.newblock=0
		return line


	def readlines(self):
		"""Return multiple lines.
		
		Read as much lines from our input as possible until we hit a
		divider.

		@return: lines read
		@rtype:  list of strings
		"""

		lines=[]
		while 1:
			line=self.readline()
			if not line:
				break
			lines.append(line)
		return lines


	def read(self):
		"""Read all lines up to a divider and return them.

		@return: data read
		@rtype:  string
		"""

		return "".join(self.readlines())


	def unblock(self):
		"""Unblock ourselves so we can proceed to the next section.

		@return: wether unblocking succeeded
		@rtype:  boolean
		"""

		if self.eof:
			return 0
		self.blocked=0
		self.newblock=1
		return 1

