'From Squeak3.1alpha of 28 February 2001 [latest update: #3991] on 8 May 2001 at 10:11:45 pm'! "Change Set: VRMLReaderSpeedup-ar Date: 8 May 2001 Author: Andreas Raab Tweaks for the VRML reader to more efficiently read float values (making up 99% of all data)"! !VRMLStream methodsFor: 'backup-restore' stamp: 'ar 5/8/2001 21:58'! discardTo: offset theStream position: backups removeLast + offset! ! !VRMLStream methodsFor: 'reading data' stamp: 'ar 5/8/2001 22:03'! readFloat | intVal fracVal expVal char s floatValue fracExp negative aStream | self backup. aStream _ ReadStream on: (theStream next: 100) asString. s := ReadWriteStream on: (String new: 10). fracVal := 0.0. "Read sign" negative _ aStream peek = $-. negative ifTrue:[aStream skip: 1]. "Read integer part" (aStream peek = $.) ifTrue:[intVal := 0] ifFalse:[intVal := self readInt32From: aStream]. intVal ifNil:[self restore. ^nil]. "Read fraction part" aStream peek = $. ifTrue:[ aStream skip: 1. fracExp := 1. [(char := aStream next) isDigit] whileTrue:[s nextPut: char. fracExp := fracExp * 10]. aStream skip: -1. s reset. fracVal := Integer readFrom: s. fracVal := fracVal asFloat / fracExp asFloat. ]. "Check for exponent" aStream peek asLowercase = $e ifTrue:[ aStream skip: 1. expVal := self readInt32From: aStream. ] ifFalse:[expVal := 1]. floatValue := intVal asFloat + fracVal. expVal = 1 ifFalse:[ floatValue := floatValue raisedTo: expVal]. self discardTo: aStream position. negative ifTrue:[^0.0 - floatValue] ifFalse:[^floatValue]! ! !VRMLStream methodsFor: 'reading data' stamp: 'ar 5/8/2001 22:05'! readInt32 | aStream value | self backup. aStream := ReadStream on: (theStream next: 33 "+/- plus 32 digits (if base 2)") asString. value _ self readInt32From: aStream. value ifNil:[self restore. ^nil]. self discardTo: aStream position. ^value! ! !VRMLStream methodsFor: 'private-reading' stamp: 'ar 5/8/2001 22:05'! readInt32From: aStream | negative intVal char | negative := false. "Read sign" char := aStream next. char isDigit ifFalse:[ char = $- ifTrue:[ negative := true ] ifFalse:[ char = $+ ifFalse:[^nil]]. char := aStream next]. (char = $0 and:[aStream peek asLowercase = $x]) ifTrue:[ "hexadecimal notation" aStream skip: 1. intVal := self readInteger: 16 from: aStream. ] ifFalse:[ "decimal notation" aStream skip: -1. intVal := self readInteger: 10 from: aStream. ]. ^negative ifTrue:[0 - intVal] ifFalse:[intVal]! ! !VRMLStream methodsFor: 'private-reading' stamp: 'ar 5/8/2001 21:49'! readInteger: base "Heavily optimized version of Integer>>readFrom:base: for the VRML stream" | digit value neg startPos aStream char pos | pos _ self position. aStream _ ReadStream on: (theStream next: 64 "more than enough") asString. char _ aStream next. char = $- ifTrue:[ neg _ true. char _ aStream next] ifFalse:[ neg _ false. char = $+ ifTrue:[char _ aStream next]]. value _ 0. startPos _ aStream position-1. [char == nil] whileFalse:[ digit _ self digitValueOf: char. (digit < 0 or: [digit >= base]) ifTrue:[ aStream skip: -1. aStream position = startPos ifTrue: [self error: 'At least one digit expected here']. self position: pos + aStream position. neg ifTrue: [^ 0 - value]. ^ value ] ifFalse: [value _ value * base + digit]. char _ aStream next]. self position: pos + aStream position. neg ifTrue: [^ 0 - value]. ^ value! ! !VRMLStream methodsFor: 'private-reading' stamp: 'ar 5/8/2001 21:59'! readInteger: base from: aStream "Heavily optimized version of Integer>>readFrom:base: for the VRML stream" | digit value neg startPos char | char _ aStream next. char = $- ifTrue:[ neg _ true. char _ aStream next] ifFalse:[ neg _ false. char = $+ ifTrue:[char _ aStream next]]. value _ 0. startPos _ aStream position-1. [char == nil] whileFalse:[ digit _ self digitValueOf: char. (digit < 0 or: [digit >= base]) ifTrue:[ aStream skip: -1. aStream position = startPos ifTrue: [self error: 'At least one digit expected here']. neg ifTrue: [^ 0 - value]. ^ value ] ifFalse: [value _ value * base + digit]. char _ aStream next]. neg ifTrue: [^ 0 - value]. ^ value! !