# $SnapHashLicense:
#
# SnapLogic - Open source data services
#
# Copyright (C) 2008, SnapLogic, Inc. All rights reserved.
#
# See http://www.snaplogic.org for more information about
# the SnapLogic project.
#
# This program is free software, distributed under the terms of
# the GNU General Public License Version 2. See the LEGAL file
# at the top of the source tree.
#
# "SnapLogic" is a trademark of SnapLogic, Inc.
#
#
# $
#$Id: tsv_rp.py 3401 2008-06-20 01:27:02Z grisha $
from decimal import Decimal
import codecs
from snaplogic.rp import _RPReader,_RPWriter
from snaplogic.common.snap_exceptions import *
"""
RP for Tab-Separated Values (TSV) as described in
http://www.iana.org/assignments/media-types/text/tab-separated-values.
Note that fields with tab characters or newlines in them are explicitly
disallowed.
"""
CONTENT_TYPE = 'text/tab-separated-values'
class Writer(_RPWriter):
"""
Writes out Python objects as Tab Separated Values
"""
def __init__(self, stream, version=None, human_request=False, options=False):
"""
Initializes this writer. See L{_RPWriter}.
@param options: May include 'encoding' key. If included, will attempt to
read using the supplied encoding. Otherwise, UTF-8 will be used.
@type options: dict
"""
super(Writer, self).__init__(stream)
self._encoding = None
if options:
if options.has_key('encoding'):
self._encoding = options['encoding']
if not self._encoding:
self._encoding = 'utf-8'
writer_cls = codecs.getwriter(self._encoding)
self._writer = writer_cls(self.stream)
def initialize(self, header = ""):
"""Prepare the underlying stream for sending the data."""
pass
def write(self, raw_record):
"""
Write a Snap Record to the underlying stream.
"""
str = unicode()
first = True
for field in raw_record:
if not first:
str += u"\t"
if field is None:
str += u''
elif type(field) == unicode:
str += field
else:
str += unicode(field)
first = False
str += "\n"
self._writer.write(str)
return str
def end(self, footer=""):
pass
class Reader(_RPReader):
"""
Reads a tab separated stream.
"""
def __init__(self, stream, version=None, options=None):
"""
Initializes this reader. See L{_RPReader}.
@param options: May include 'encoding' key. If included, will attempt to
read using the supplied encoding. Otherwise, UTF-8 will be used.
@type options: dict
"""
super(Reader, self).__init__(stream)
self._encoding = None
if options:
if options.has_key('encoding'):
self._encoding = options['encoding']
if not self._encoding:
self._encoding = 'utf-8'
# TODO What should we do in case of a LookupError
reader_cls = codecs.getreader(self._encoding)
self._reader = reader_cls(self.stream)
@classmethod
def supports_non_blocking_read(cls):
"""
Returns False (there is no End-of-Stream marker supported by TSV standard)
"""
return False
def next(self):
line = self._reader.readline()
line = line[:-1]
if not line:
raise StopIteration
rec = line.split("\t")
return rec
|