From ec1e5a94dbaee45a14c33f84e8a8446d378d9ea2 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Tue, 29 Mar 2011 21:25:20 +0200 Subject: [PATCH] ber: Start with BER encoding/decoding for streams Start with a very simple tag class --- BERTLVStream.st | 140 ++++++++++++++++++++++++++++++++++++++++++++ BERTLVStreamTest.st | 43 ++++++++++++++ package.xml | 4 ++ 3 files changed, 187 insertions(+) create mode 100644 BERTLVStream.st create mode 100644 BERTLVStreamTest.st diff --git a/BERTLVStream.st b/BERTLVStream.st new file mode 100644 index 0000000..ff15bc4 --- /dev/null +++ b/BERTLVStream.st @@ -0,0 +1,140 @@ +" + (C) 2011 by Holger Hans Peter Freyther + All Rights Reserved + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +" + +Object subclass: BERTag [ + | classType tagValue constructed | + + + + BERTag class >> classUniversal [ + + ^ 0 + ] + + BERTag class >> classApplication [ + + ^ 1 + ] + + BERTag class >> classContext [ + + ^ 2 + ] + + BERTag class >> classPrivate [ + + ^ 3 + ] + + BERTag class >> new [ + + ^ super new initialize + ] + + BERTag class >> parseFrom: aStream [ + + ^ self new + parseFrom: aStream; + yourself + ] + + BERTag class >> fromTuple: aTuple [ + + ^ self new + fromTuple: aTuple; + yourself + ] + + initialize [ + + classType := BERTag classUniversal. + tagValue := 0. + constructed := false. + ] + + parseExtendedTag: aStream [ + + + ^ self error: 'Extended tags are not implemented yet'. + ] + + parseFrom: aStream [ + | tmp | + + + tmp := aStream next. + classType := (tmp bitAnd: 16rC0) bitShift: -6. + constructed := (tmp bitAnd: 16r20) > 0. + tagValue := tmp bitAnd: 16r1F. + + "This is an extended tag" + (tagValue = 16r1F) ifTrue: [ + self parseExtendedTag: aStream. + ]. + ] + + fromTuple: aTuple [ + + + classType := aTuple first bitAnd: 16r3. + constructed := aTuple second not. + tagValue := aTuple third. + ] + + writeExtendedTag: aStream [ + + self error: 'Cannot encode extended tag.' + ] + + writeOn: aStream [ + + tagValue >= 16r1F + ifTrue: [self writeExtendedTag: aStream.] + ifFalse: [| tag | + tag := classType bitShift: 6. + self isConstructed ifTrue: [tag := tag bitOr: 16r20]. + tag := tag bitOr: self tagValue. + aStream nextPut: tag. + ]. + ] + + classType [ + + ^ classType + ] + + isConstructed [ + + ^ constructed + ] + + isPrimitive [ + + ^ self isConstructed not + ] + + tagValue [ + + ^ tagValue + ] + + asTuple [ + + ^ Array with: self classType with: self isPrimitive with: self tagValue. + ] +] diff --git a/BERTLVStreamTest.st b/BERTLVStreamTest.st new file mode 100644 index 0000000..52b57dc --- /dev/null +++ b/BERTLVStreamTest.st @@ -0,0 +1,43 @@ +" + (C) 2011 by Holger Hans Peter Freyther + All Rights Reserved + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +" + +TestCase subclass: BERTagTest [ + testSimpleTag [ + + self assert: (BERTag parseFrom: #(16rA1) asByteArray readStream) asTuple = #(2 false 1). + ] + + testFromTuple [ + | tuple | + + + tuple := #(2 false 1). + self assert: (BERTag fromTuple: tuple) asTuple = tuple. + ] + + testWriteTuple [ + | tuple stream | + + + tuple := #(2 false 1). + stream := WriteStream on: (ByteArray new: 1). + (BERTag fromTuple: tuple) writeOn: stream. + + self assert: stream contents = #(16rA1) asByteArray + ] +] diff --git a/package.xml b/package.xml index 460e7ea..f22cbf3 100644 --- a/package.xml +++ b/package.xml @@ -3,10 +3,14 @@ Osmo BER.st + BERTLVStream.st Osmo.BERTest + Osmo.BERTagTest + Osmo.BERTLVStreamTest Tests.st + BERTLVStreamTest.st BER.st