SequenceableCollection.st
changeset 1003 c82f2dcf5611
parent 929 674de4c05dcb
child 1015 a564efc63383
equal deleted inserted replaced
1002:c44e50c09986 1003:c82f2dcf5611
   501 
   501 
   502     |idx1        "{ Class:SmallInteger }"
   502     |idx1        "{ Class:SmallInteger }"
   503      idx2        "{ Class:SmallInteger }"
   503      idx2        "{ Class:SmallInteger }"
   504      totalLength "{ Class:SmallInteger }"
   504      totalLength "{ Class:SmallInteger }"
   505      pos         "{ Class:SmallInteger }"
   505      pos         "{ Class:SmallInteger }"
   506      newString lineString spaces idx nTabs sepCnt|
   506      newString lineString spaces idx nTabs sepCnt
       
   507      any16Bit|
   507 
   508 
   508     "
   509     "
   509      first accumulate the size of the string, to avoid
   510      first accumulate the size of the string, to avoid
   510      countless reallocations. If tabs are compressed,
   511      countless reallocations. If tabs are compressed,
   511      the size computed is not exact, but gives an upper bound ...
   512      the size computed is not exact, but gives an upper bound ...
   512     "
   513      On the fly, look if a 16bit string is needed.
       
   514     "
       
   515     any16Bit := false.
   513     totalLength := 0.
   516     totalLength := 0.
   514     sepCnt := sepCharacter notNil ifTrue:[1] ifFalse:[0].
   517     sepCnt := sepCharacter notNil ifTrue:[1] ifFalse:[0].
   515 
   518 
   516     idx1 := firstLine.
   519     idx1 := firstLine.
   517     idx2 := lastLine.
   520     idx2 := lastLine.
   518     idx1 to:idx2 do:[:lineIndex |
   521     idx1 to:idx2 do:[:lineIndex |
   519 	lineString := self at:lineIndex.
   522         lineString := self at:lineIndex.
   520 	lineString isNil ifTrue:[
   523         (lineString species == TwoByteString) ifTrue:[
   521 	    totalLength := totalLength + sepCnt
   524             any16Bit := true
   522 	] ifFalse: [
   525         ].
   523 	    totalLength := totalLength + lineString size + sepCnt
   526 
   524 	].
   527         lineString isNil ifTrue:[
       
   528             totalLength := totalLength + sepCnt
       
   529         ] ifFalse: [
       
   530             totalLength := totalLength + lineString size + sepCnt
       
   531         ].
   525     ].
   532     ].
   526     endCharacter isNil ifTrue:[
   533     endCharacter isNil ifTrue:[
   527 	totalLength := totalLength - 1
   534         totalLength := totalLength - 1
   528     ].
   535     ].
   529     spaces := '        '.
   536     spaces := '        '.
   530     newString := String new:totalLength.
   537     any16Bit ifTrue:[
       
   538         newString := TwoByteString new:totalLength.
       
   539     ] ifFalse:[
       
   540         newString := String new:totalLength.
       
   541     ].
   531 
   542 
   532     "
   543     "
   533      now, replace ...
   544      now, replace ...
   534     "
   545     "
   535     pos := 1.
   546     pos := 1.
   536     idx1 to:idx2 do:[:lineIndex |
   547     idx1 to:idx2 do:[:lineIndex |
   537 	|thisLen|
   548         |thisLen|
   538 
   549 
   539 	lineString := self at:lineIndex.
   550         lineString := self at:lineIndex.
   540 	thisLen := lineString size.
   551         thisLen := lineString size.
   541 	thisLen ~~ 0 ifTrue:[
   552         thisLen ~~ 0 ifTrue:[
   542 	    compressTabs ifTrue:[
   553             compressTabs ifTrue:[
   543 		"
   554                 "
   544 		 mhmh: could use withTabs from String-class here,
   555                  mhmh: could use withTabs from String-class here,
   545 		 but we should avoid creating too many temporary strings
   556                  but we should avoid creating too many temporary strings
   546 		 (especially, since this method is typically used when converting
   557                  (especially, since this method is typically used when converting
   547 		 big texts such as when saving in the filebrowser ...).
   558                  big texts such as when saving in the filebrowser ...).
   548 		 Therefore, we convert tabs inline here doing a direct replace
   559                  Therefore, we convert tabs inline here doing a direct replace
   549 		 in newString."
   560                  in newString."
   550 
   561 
   551 		idx := lineString findFirst:[:c | (c ~~ Character space)].
   562                 idx := lineString findFirst:[:c | (c ~~ Character space)].
   552 		nTabs := (idx-1) // 8.
   563                 nTabs := (idx-1) // 8.
   553 		nTabs ~~ 0 ifTrue:[
   564                 nTabs ~~ 0 ifTrue:[
   554 		    "any tabs"
   565                     "any tabs"
   555 		    newString atAll:(pos to:pos+nTabs-1) put:(Character tab).
   566                     newString atAll:(pos to:pos+nTabs-1) put:(Character tab).
   556 		    pos := pos + nTabs.
   567                     pos := pos + nTabs.
   557 		    newString replaceFrom:pos with:lineString startingAt:(nTabs * 8 + 1).
   568                     newString replaceFrom:pos with:lineString startingAt:(nTabs * 8 + 1).
   558 		    pos := pos + thisLen - (nTabs * 8).
   569                     pos := pos + thisLen - (nTabs * 8).
   559 		] ifFalse:[
   570                 ] ifFalse:[
   560 		    newString replaceFrom:pos with:lineString.
   571                     newString replaceFrom:pos with:lineString.
   561 		    pos := pos + thisLen
   572                     pos := pos + thisLen
   562 		].
   573                 ].
   563 	    ] ifFalse:[
   574             ] ifFalse:[
   564 		newString replaceFrom:pos with:lineString.
   575                 newString replaceFrom:pos with:lineString.
   565 		pos := pos + thisLen
   576                 pos := pos + thisLen
   566 	    ]
   577             ]
   567 	].
   578         ].
   568 	(sepCharacter notNil 
   579         (sepCharacter notNil 
   569 	and:[lineIndex ~~ lastLine]) ifTrue:[
   580         and:[lineIndex ~~ lastLine]) ifTrue:[
   570 	    newString at:pos put:sepCharacter.
   581             newString at:pos put:sepCharacter.
   571 	    pos := pos + 1
   582             pos := pos + 1
   572 	] ifFalse:[
   583         ] ifFalse:[
   573 	    endCharacter notNil ifTrue:[
   584             endCharacter notNil ifTrue:[
   574 		newString at:pos put:endCharacter.
   585                 newString at:pos put:endCharacter.
   575 		pos := pos + 1
   586                 pos := pos + 1
   576 	    ]
   587             ]
   577 	]
   588         ]
   578     ].
   589     ].
   579 
   590 
   580     "
   591     "
   581      in case of tab compression, the result has to be
   592      in case of tab compression, the result has to be
   582      cut to size ... sorry
   593      cut to size ... sorry
   583     "
   594     "
   584     pos ~~ totalLength ifTrue:[
   595     pos ~~ totalLength ifTrue:[
   585 	^ newString copyTo:(pos - 1)
   596         ^ newString copyTo:(pos - 1)
   586     ].
   597     ].
   587     ^ newString
   598     ^ newString
   588 
   599 
   589     "
   600     "
   590      creating entries for searchpath:
   601      creating entries for searchpath:
   591 
   602 
   592      #('foo' 'bar' 'baz' '/foo/bar') 
   603      #('foo' 'bar' 'baz' '/foo/bar') 
   593 	asStringWith:$: from:1 to:4 compressTabs:false final:nil 
   604         asStringWith:$: from:1 to:4 compressTabs:false final:nil 
   594 
   605 
   595      with trailing colon:
   606      with trailing colon:
   596 
   607 
   597      #('foo' 'bar' 'baz' '/foo/bar') 
   608      #('foo' 'bar' 'baz' '/foo/bar') 
   598 	asStringWith:$: from:1 to:4 compressTabs:false final:$: 
   609         asStringWith:$: from:1 to:4 compressTabs:false final:$: 
   599 
   610 
   600      concatenating all elements:
   611      concatenating all elements:
   601 
   612 
   602      #('foo' 'bar' 'baz') 
   613      #('foo' 'bar' 'baz') 
   603 	asStringWith:nil from:1 to:3 compressTabs:false final:nil 
   614         asStringWith:nil from:1 to:3 compressTabs:false final:nil 
   604 
   615 
   605      creating a string from a collection of lines:
   616      creating a string from a collection of lines:
   606 
   617 
   607      #('foo' 'bar' 'baz') 
   618      #('foo' 'bar' 'baz') 
   608 	asStringWith:(Character cr) from:1 to:3 compressTabs:false final:(Character cr) 
   619         asStringWith:(Character cr) from:1 to:3 compressTabs:false final:(Character cr) 
   609     "
   620     "
       
   621 
       
   622     "Modified: 23.2.1996 / 15:28:55 / cg"
   610 !
   623 !
   611 
   624 
   612 asStringWithCRs
   625 asStringWithCRs
   613     "return a string generated by concatenating my elements 
   626     "return a string generated by concatenating my elements 
   614      (which must be strings or nil) and embedding cr characters in between.
   627      (which must be strings or nil) and embedding cr characters in between.
  2443 ! !
  2456 ! !
  2444 
  2457 
  2445 !SequenceableCollection class methodsFor:'documentation'!
  2458 !SequenceableCollection class methodsFor:'documentation'!
  2446 
  2459 
  2447 version
  2460 version
  2448     ^ '$Header: /cvs/stx/stx/libbasic/SequenceableCollection.st,v 1.48 1996-02-02 16:22:25 cg Exp $'
  2461     ^ '$Header: /cvs/stx/stx/libbasic/SequenceableCollection.st,v 1.49 1996-02-23 16:25:23 cg Exp $'
  2449 ! !
  2462 ! !