The Artima Developer Community
Sponsored Link

Agile Buzz Forum
Another extension to PeekableStream

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
James Robertson

Posts: 29924
Nickname: jarober61
Registered: Jun, 2003

David Buck, Smalltalker at large
Another extension to PeekableStream Posted: Jun 9, 2004 8:26 AM
Reply to this message Reply

This post originated from an RSS feed registered with Agile Buzz by James Robertson.
Original Post: Another extension to PeekableStream
Feed Title: Richard Demers Blog
Feed URL: http://www.cincomsmalltalk.com/rssBlog/rademers-rss.xml
Feed Description: Richard Demers on Smalltalk
Latest Agile Buzz Posts
Latest Agile Buzz Posts by James Robertson
Latest Posts From Richard Demers Blog

Advertisement

Another extension to PeekableStream

In A Peek at some more Extensions Travis Griggs points out that "There are two basic things we do with streams, skip their contents, and extract them." And then he provides the Smalltalk code for two nifty methods he had written as extensions to class PeekableStream.

Well, there's one more basic thing we do with streams, we peek to see what's coming next. And that's what I needed to do when I had to detect any HTML entities (sequences of the form &xxx; that represent < > & ") in a string and replace them with their single character encodings. One possibility was to tokenize the string, translate the tokens as needed, and then reassemble the string -- but that seemed like too much work. The other possibility was to read, parse and translate the string in a single pass on a ReadStream.

A ReadStream on any collection moves a cursor forward and back one object at a time, and on a String that means one character at a time. It also means that you can peek ahead at only one character at a time, which is not very convenient when looking for multi-character entities.

I'd be surprised to learn I was the first to have this problem, but I couldn't find any existing method that would let me "peek ahead for a specific sequence of objects." So I wrote the following as an extension to PeekableStream:

peekForAll: aCollection 
	"Answer false and do not move the position if the next sequence of objects
	does not equal the corresponding objects in aCollection, or if the receiver is at the end. 
	Otherwise, answer true and increment position for the number of objects in aCollection."

	| peek |
	aCollection isEmpty ifTrue: [^false].
	1 to: aCollection size
		do: 
			[:index | 
			self atEnd 
				ifTrue: 
					[self skip: (index - 1) negated.
					^false].
			peek := self next.
			(aCollection at: index) = peek 
				ifFalse: 
					[self skip: index negated.
					^false]].
	^true

Here's its TestCase:

testPeekForAll_

	| rs |
	rs := 'ab' readStream.
	self shouldnt: [rs peekForAll: ''].
	self should: [rs peekForAll: 'a'].

	rs := 'ab' readStream.
	self should: [rs peekForAll: 'ab'].

	rs := 'abcdefg' readStream.
	self should: [rs peekForAll: 'a'].
	self should: [rs peekForAll: 'bc'].
	self shouldnt: [rs peekForAll: 'dxg'].
	self should: [rs peekForAll: 'def'].
	self shouldnt: [rs peekForAll: 'ghk'].
	self should: [rs peekForAll: 'g'].
	self shouldnt: [rs peekForAll: 'hk'].

	"Now do same tests with a different kind of object."
	rs := #(1 2 3 4 5 6 7) readStream.
	self shouldnt: [rs peekForAll: #()].
	self should: [rs peekForAll: #(1)].
	self should: [rs peekForAll: #(2 3)].
	self shouldnt: [rs peekForAll: #(4 9 6)].
	self should: [rs peekForAll: #(4 5 6)].
	self shouldnt: [rs peekForAll: #(7 8 9)].
	self should: [rs peekForAll: #(7)].
	self shouldnt: [rs peekForAll: #(8 9)].

Read: Another extension to PeekableStream

Topic: Double clicking patented by Microsoft? Previous Topic   Next Topic Topic: Smalltalk in Sydney, Australia

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use