--- a/MD5Stream.st Wed Feb 19 14:01:49 2003 +0100
+++ b/MD5Stream.st Wed Feb 19 18:10:44 2003 +0100
@@ -171,56 +171,6 @@
Transcript show:(n*50/1024 / t); showCR:' Kb/s'
[exEnd]
"
-!
-
-testVectors
-"
- Test Vectors:
- 'abc'
-
- #[90 1 50 98 3C D2 4F B0 D6 96 3F 7D 28 E1 7F 72]
-
- 'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq'
- #[82 15 EF 7 96 A2 B CA AA E1 16 D3 87 6C 66 4A]
-
- A million repetitions of 'a'
- #[77 7 D6 AE 4E 2 7C 70 EE A2 A9 35 C2 29 6F 21]
-"
- |hashStream result stream|
-
- stream := WriteStream on:''.
- hashStream := MD5Stream new.
- hashStream nextPut:'abc'.
- result := hashStream hashValue.
- result printOn:stream base:16.
- stream contents = '#[90 1 50 98 3C D2 4F B0 D6 96 3F 7D 28 E1 7F 72]' ifFalse:[
- self error.
- ].
- stream reset.
- hashStream := MD5Stream new.
- hashStream nextPut:'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq'.
- result := hashStream hashValue.
- result printOn:stream base:16.
- stream contents = '#[82 15 EF 7 96 A2 B CA AA E1 16 D3 87 6C 66 4A]' ifFalse:[
- self error.
- ].
- stream reset.
- hashStream := MD5Stream new.
- 1000000 timesRepeat:[ hashStream nextPut:$a ].
- result := hashStream hashValue.
- result printOn:stream base:16.
- stream contents = '#[77 7 D6 AE 4E 2 7C 70 EE A2 A9 35 C2 29 6F 21]' ifFalse:[
- self error.
- ].
- stream reset.
- result := MD5Stream hashValueOf:'abc'.
- result printOn:stream base:16.
- stream contents = '#[90 1 50 98 3C D2 4F B0 D6 96 3F 7D 28 E1 7F 72]' ifFalse:[
- self error.
- ].
-"
-self testVectors
-"
! !
!MD5Stream class methodsFor:'initialization'!
@@ -260,6 +210,26 @@
"Created: / 18.3.1999 / 08:02:16 / stefan"
! !
+!MD5Stream class methodsFor:'testing'!
+
+testVector
+
+ ^ #(
+ ('abc'
+ #[16r90 16r01 16r50 16r98 16r3C 16rD2 16r4F 16rB0 16rD6 16r96 16r3F 16r7D 16r28 16rE1 16r7F 16r72])
+
+ ('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq'
+ #[16r82 16r15 16rEF 16r07 16r96 16rA2 16r0B 16rCA 16rAA 16rE1 16r16 16rD3 16r87 16r6C 16r66 16r4A])
+ ) copyWith:
+ (Array with:(String new:1000000 withAll:$a)
+ with:#[16r77 16r07 16rD6 16rAE 16r4E 16r02 16r7C 16r70 16rEE 16rA2 16rA9 16r35 16rC2 16r29 16r6F 16r21])
+
+
+ "
+ self test
+ "
+! !
+
!MD5Stream methodsFor:'initialization'!
initialize
@@ -331,8 +301,7 @@
nextPut:anObject
"update our hash value for anObject.
anObject may be a String, a Character, a Smallinteger or an Array of primitive
- types like ByteArray.
- "
+ types like ByteArray"
|ret|
@@ -341,71 +310,135 @@
__qClass(__INST(hashContext)) == @global(ByteArray) &&
__byteArraySize(__INST(hashContext)) == sizeof(MD5_CTX)
) {
- MD5_CTX *ctx =
- (MD5_CTX *)__ByteArrayInstPtr(__INST(hashContext))->ba_element;
+ MD5_CTX *ctx =
+ (MD5_CTX *)__ByteArrayInstPtr(__INST(hashContext))->ba_element;
- if (__isNonNilObject(anObject)) {
- OBJ cls =__qClass(anObject);
- INT mask = (INT)(__ClassInstPtr(cls)->c_flags) & __MASKSMALLINT(ARRAYMASK);
+ if (__isNonNilObject(anObject)) {
+ OBJ cls =__qClass(anObject);
+ INT mask = (INT)(__ClassInstPtr(cls)->c_flags) & __MASKSMALLINT(ARRAYMASK);
- if (cls == @global(String) || cls == @global(Symbol)) {
- /* String: omit leading '\0' */
+ if (cls == @global(String) || cls == @global(Symbol)) {
+ /* String: omit leading '\0' */
- MD5Update(ctx, __StringInstPtr(anObject)->s_element, __stringSize(anObject));
- } else if (mask != __MASKSMALLINT(POINTERARRAY) &&
- mask != __MASKSMALLINT(WKPOINTERARRAY) &&
- mask != __MASKSMALLINT(0)
- ) {
- /* Byte|Integer|.... Array */
+ MD5Update(ctx, __StringInstPtr(anObject)->s_element, __stringSize(anObject));
+ } else if (mask != __MASKSMALLINT(POINTERARRAY) &&
+ mask != __MASKSMALLINT(WKPOINTERARRAY) &&
+ mask != __MASKSMALLINT(0)
+ ) {
+ /* Byte|Integer|.... Array */
- register int n;
- char *pFirst;
+ register int n;
+ char *pFirst;
- n /* nInstVars */ = __intVal(__ClassInstPtr(cls)->c_ninstvars);
- n /* nInstBytes */ = OHDR_SIZE + __OBJS2BYTES__(n /* nInstVars */);
- pFirst = (char *)(__InstPtr(anObject)) + n /* nInstBytes */;
- n /* nbytes */ = __qSize(anObject) - n /* nInstBytes */;
- MD5Update(ctx, pFirst, n);
- } else if (cls == @global(Character)) {
- /* Character */
+ n /* nInstVars */ = __intVal(__ClassInstPtr(cls)->c_ninstvars);
+ n /* nInstBytes */ = OHDR_SIZE + __OBJS2BYTES__(n /* nInstVars */);
+ pFirst = (char *)(__InstPtr(anObject)) + n /* nInstBytes */;
+ n /* nbytes */ = __qSize(anObject) - n /* nInstBytes */;
+ MD5Update(ctx, pFirst, n);
+ } else if (cls == @global(Character)) {
+ /* Character */
- INT val = __intVal(_characterVal(anObject));
- if (val > 255) {
- /* Two byte character */
- short s = val;
- MD5Update(ctx, &s, 2);
- } else {
- char c = val;
- MD5Update(ctx, &c, 1);
- }
- } else {
- ret = false;
- }
- } else {
- if (anObject == nil) {
- ret = false;
- } else {
- /* SmallInteger */
+ INT val = __intVal(_characterVal(anObject));
+ if (val > 255) {
+ /* Two byte character */
+ short s = val;
+ MD5Update(ctx, &s, 2);
+ } else {
+ char c = val;
+ MD5Update(ctx, &c, 1);
+ }
+ } else {
+ ret = false;
+ }
+ } else {
+ if (anObject == nil) {
+ ret = false;
+ } else {
+ /* SmallInteger */
- INT i = __intVal(anObject);
- MD5Update(ctx, &i, sizeof(INT));
- }
- }
+ INT i = __intVal(anObject);
+ MD5Update(ctx, &i, sizeof(INT));
+ }
+ }
}
%}.
ret notNil ifTrue:[
- ^ self primitiveFailed
+ ^ self primitiveFailed
].
"Created: 22.10.1996 / 21:53:24 / stefan"
+!
+
+nextPutBytes:count from:anObject startingAt:start
+ "update the hash value with count bytes from an object starting at index start.
+ The object must have non-pointer indexed instvars
+ (i.e. be a ByteArray, String, Float- or DoubleArray),
+ or an externalBytes object (with known size)"
+
+%{
+ int len, offs;
+ int objSize, nInstVars, nInstBytes;
+ char *extPtr;
+ OBJ oClass;
+
+ if (__isNonNilObject(__INST(hashContext))
+ &&__qClass(__INST(hashContext)) == @global(ByteArray)
+ &&__byteArraySize(__INST(hashContext)) == sizeof(MD5_CTX)
+ && __bothSmallInteger(count, start)
+ ) {
+ MD5_CTX *ctx =
+ (MD5_CTX *)__ByteArrayInstPtr(__INST(hashContext))->ba_element;
+
+ len = __intVal(count);
+ offs = __intVal(start) - 1;
+
+ oClass = __Class(anObject);
+ if (oClass == ExternalBytes) {
+ OBJ sz;
+
+ nInstBytes = 0;
+ extPtr = (char *)__externalBytesAddress(anObject);
+ sz = __externalBytesSize(anObject);
+ if (__isSmallInteger(sz)) {
+ objSize = __intVal(sz);
+ } else {
+ objSize = 0; /* unknown */
+ }
+ } else {
+ switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
+ case BYTEARRAY:
+ case WORDARRAY:
+ case LONGARRAY:
+ case SWORDARRAY:
+ case SLONGARRAY:
+ case FLOATARRAY:
+ case DOUBLEARRAY:
+ break;
+ default:
+ goto bad;
+ }
+ nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
+ nInstBytes = OHDR_SIZE + __OBJS2BYTES__(nInstVars);
+ objSize = __Size(anObject) - nInstBytes;
+ extPtr = (char *)__byteArrayVal(anObject);
+ }
+ if ((offs >= 0) && (len >= 0) && (objSize >= (len + offs))) {
+ MD5Update(ctx, extPtr+offs, len);
+ RETURN (count);
+ }
+ }
+bad: ;
+%}.
+
+ ^ self primitiveFailed
! !
!MD5Stream class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/MD5Stream.st,v 1.2 2003-02-19 13:01:49 penk Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/MD5Stream.st,v 1.3 2003-02-19 17:09:46 stefan Exp $'
! !
MD5Stream initialize!