Little challenge: Best way to read stream and count line returns

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Little challenge: Best way to read stream and count line returns

CyrilFerlicot
Hello everyone,

I often needs to read some streams these days and to get some infos
related to the lines returns for example.
Because of the CRLF it is a little complicated sometimes.

I have an example of code here:

| lfShouldBeCounted char count remaining |
lfShouldBeCounted := false.
remaining := 0.
count := 0.
stream position: startPos.
[ stream position = endPos ]
  whileFalse: [
    "13 is a CR, 10 a LF"
    (char := stream next asInteger) = 13
      ifTrue: [ count := count + 1. remaining := 0. lfShouldBeCounted := false ]
      ifFalse: [
        char = 10
          ifTrue: [
            lfShouldBeCounted
              ifTrue: [ count := count + 1. remaining := 0 ]
              ifFalse: [ lfShouldBeCounted := true ] ]
          ifFalse: [ remaining := remaining + 1 ] ] ]

With this example I know how many lines where passed between the
startPos and the endPos in a stream. I also know how many char there
is between the last line return and the endPos.

 I wanted to know if you had a better way to do that? The way need to
be as performant than this snippet. I know some people here can
produce a snippet more readable and easier to maintain :)

--
Cyril Ferlicot
https://ferlicot.fr

http://www.synectique.eu
2 rue Jacques Prévert 01,
59650 Villeneuve d'ascq France

Reply | Threaded
Open this post in threaded view
|

Re: Little challenge: Best way to read stream and count line returns

Julián Maestri-2
count := 0.
stream do: [ :character | (character = Character cr and: [stream peek = Character lf]) ifTrue: [  count := count + 1 ]].
count.

Snippet with example: 

| count crlftext stream |
stream := (String
streamContents: [ :s | 
s
nextPutAll: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.';
crlf;
nextPutAll: 'Phasellus sollicitudin lorem ac nunc varius aliquam.';
crlf;
nextPutAll: 'Quisque posuere augue in quam suscipit eleifend.';
crlf;
nextPutAll: 'Donec non tempor ex.';
crlf;
nextPutAll: 'Phasellus placerat leo augue, eu placerat augue luctus quis. ';
crlf;
lf;
cr;
cr ]) readStream.
count := 0.
stream
do: [ :char | 
(char = Character cr and: [ stream peek = Character lf ])
ifTrue: [ count := count + 1 ] ].
count

On 13 July 2017 at 09:31, Cyril Ferlicot <[hidden email]> wrote:
Hello everyone,

I often needs to read some streams these days and to get some infos
related to the lines returns for example.
Because of the CRLF it is a little complicated sometimes.

I have an example of code here:

| lfShouldBeCounted char count remaining |
lfShouldBeCounted := false.
remaining := 0.
count := 0.
stream position: startPos.
[ stream position = endPos ]
  whileFalse: [
    "13 is a CR, 10 a LF"
    (char := stream next asInteger) = 13
      ifTrue: [ count := count + 1. remaining := 0. lfShouldBeCounted := false ]
      ifFalse: [
        char = 10
          ifTrue: [
            lfShouldBeCounted
              ifTrue: [ count := count + 1. remaining := 0 ]
              ifFalse: [ lfShouldBeCounted := true ] ]
          ifFalse: [ remaining := remaining + 1 ] ] ]

With this example I know how many lines where passed between the
startPos and the endPos in a stream. I also know how many char there
is between the last line return and the endPos.

 I wanted to know if you had a better way to do that? The way need to
be as performant than this snippet. I know some people here can
produce a snippet more readable and easier to maintain :)

--
Cyril Ferlicot
https://ferlicot.fr

http://www.synectique.eu
2 rue Jacques Prévert 01,
59650 Villeneuve d'ascq France