#如果Python的生成器用HaXe来表达.gunicorn的ChunkedReader类,作用是从当TransferEncoding: Chunked的时候用该类来分析读取Body。通过生成器从Bu
#如果Python的生成器用HaXe来表达.
gunicorn的ChunkedReader类,作用是从当TransferEncoding: Chunked的时候用该类来分析读取Body。
通过生成器从Buffer中读取字符,生成器用在这个地方既方便又清晰明了。看了这段代码,让我也对Python生成器的应用场景又多了些认识。
我现在尝试用HaXe语言来翻译这个软件,通过迭代器进行模拟,因为会增加一个类,而且状态被转移到了类的字段上,再加上我的设计有些问题,所以这样的设计没有Python看起来优美,简洁。因为我希望别人看这段代码的时候无障碍,提高易读性,所以特来求助。
##期望
- 你可以为我提供设计思路,点出迭代器在这个场景引用的缺点。或者我代码的缺陷。
- 如果你想为我提供代码解惑,可以fork我这个库然后pull & request给我。
##URLS
- https://github.com/shitou/gunicorn/blob/master/gunicorn/http/body.py
- https://github.com/shitou/hxgunicorn/blob/master/src/http/body/ChunkedReader.hx
- https://github.com/shitou/hxgunicorn/blob/master/src/http/body/ChunkedReaderIterator.hx
以上是相关代码地址:
<!-- lang: python -->pass<!-- lang: python -->class ChunkedReader(object):def __init__(self, req, unreader): self.req = req self.parser = self.parse_chunked(unreader) self.buf = StringIO()def read(self, size): if self.parser: while self.buf.tell() < size: try: self.buf.write(self.parser.next()) except StopIteration: self.parser = None breakdef parse_chunked(self, unreader): (size, rest) = self.parse_chunk_size(unreader) while size > 0: while size > len(rest): size -= len(rest) yield rest rest = unreader.read() if not rest: raise NoMoreData() yield rest[:size] # Remove /r/n after chunk rest = rest[size:] while len(rest) < 2: rest += unreader.read() if rest[:2] != '/r/n': raise ChunkMissingTerminator(rest[:2]) (size, rest) = self.parse_chunk_size(unreader, data=rest[2:])<!-- lang: as3 -->class ChunkedReader {var parser : ChunkedReaderIterator ( );public function new ( ){ parser = ChunkedReaderIterator ( );}function read ( ? size : Int ) : String{ if ( parser ) { while ( this.buffer.position < size ) { this.buffer.write ( chunkReaderIterator.next ( ) ); } }}<!-- lang: as3 -->class ChunkedReaderIterator{public function next ( ) : String{ var chunks : Array<Dynamic>; if ( null == size ) { chunks = parseChunkSize ( ); size = chunks[0]; rest = chunks[1]; } else parseChunkSize ( rest ); var ret = rest.substring ( 0, size ); rest = rest.substr ( size ); if ( rest.length < 2 ) rest += unreader.read ( ); if ( "/r/n" != rest.substr ( 0, 2 ) ) throw new ChunkMissingTerminator ( rest.substr ( 0, 2 ) ); return ret;}function parseChunkSize ( ?data : String = null ) : Array<Dynamic>{}