Mercurial > hg > blitz_condensed
comparison src/org/dancres/blitz/mangler/MangledField.java @ 0:3dc0c5604566
Initial checkin of blitz 2.0 fcs - no installer yet.
author | Dan Creswell <dan.creswell@gmail.com> |
---|---|
date | Sat, 21 Mar 2009 11:00:06 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:3dc0c5604566 |
---|---|
1 package org.dancres.blitz.mangler; | |
2 | |
3 import java.io.ByteArrayOutputStream; | |
4 import java.io.ByteArrayInputStream; | |
5 import java.io.IOException; | |
6 import java.io.Serializable; | |
7 | |
8 import org.dancres.io.AnnotatingObjectOutputStream; | |
9 import org.dancres.io.AnnotatingObjectInputStream; | |
10 | |
11 /** | |
12 Each field within an Entry is held in a MangledField. We require the | |
13 field's name for indexing purposes. We also use our own hashing | |
14 algorithm which is known not to "funnel" in the vast majority of cases. | |
15 */ | |
16 public class MangledField implements Serializable { | |
17 static final long serialVersionUID = -6256197142057463399L; | |
18 | |
19 private String theName; | |
20 private byte[] theObjectBytes; | |
21 private byte[] theAnnotationBytes; | |
22 private int theHashCode; | |
23 | |
24 MangledField(String aName) { | |
25 theName = aName; | |
26 theObjectBytes = new byte[0]; | |
27 theAnnotationBytes = new byte[0]; | |
28 theHashCode = 0; | |
29 } | |
30 | |
31 MangledField(String aName, Object anObject) | |
32 throws IOException { | |
33 theName = aName; | |
34 mangle(anObject); | |
35 } | |
36 | |
37 MangledField(String aName, byte[] anObject, byte[] aAnnotation, int aHash) { | |
38 theName = aName; | |
39 theObjectBytes = anObject; | |
40 theAnnotationBytes = aAnnotation; | |
41 theHashCode = aHash; | |
42 } | |
43 | |
44 public int sizeOf() { | |
45 if (isNull()) | |
46 return 0; | |
47 else | |
48 return theName.length() + theObjectBytes.length + | |
49 theAnnotationBytes.length + 4 + 4; | |
50 } | |
51 | |
52 public Object unMangle(ClassLoader aDefault, boolean checkIntegrity) | |
53 throws IOException, ClassNotFoundException { | |
54 | |
55 ByteArrayInputStream myObjStream = | |
56 new ByteArrayInputStream(theObjectBytes); | |
57 ByteArrayInputStream myAnnoStream = | |
58 new ByteArrayInputStream(theAnnotationBytes); | |
59 | |
60 AnnotatingObjectInputStream myStream = | |
61 new AnnotatingObjectInputStream(aDefault, myObjStream, | |
62 myAnnoStream, checkIntegrity); | |
63 | |
64 Object myResult = myStream.readObject(); | |
65 | |
66 myStream.close(); | |
67 | |
68 return myResult; | |
69 } | |
70 | |
71 public boolean isNull() { | |
72 // System.err.println("isNull: " + theName); | |
73 // System.err.println("OLength: " + theObjectBytes.length); | |
74 // System.err.println("ALength: " + theAnnotationBytes.length); | |
75 return (theObjectBytes.length == 0); | |
76 } | |
77 | |
78 private void mangle(Object anObject) throws IOException { | |
79 ByteArrayOutputStream myObjectBytes = new ByteArrayOutputStream(); | |
80 ByteArrayOutputStream myAnnotBytes = new ByteArrayOutputStream(); | |
81 | |
82 AnnotatingObjectOutputStream myStream = | |
83 new AnnotatingObjectOutputStream(myObjectBytes, myAnnotBytes); | |
84 | |
85 myStream.writeObject(anObject); | |
86 myStream.close(); | |
87 | |
88 theObjectBytes = myObjectBytes.toByteArray(); | |
89 theAnnotationBytes = myAnnotBytes.toByteArray(); | |
90 | |
91 theHashCode = buildHash(theObjectBytes); | |
92 } | |
93 | |
94 /** | |
95 This algorithm is based on the "One at a time" hash published in | |
96 Dr Dobbs Journal '97 and authored by Bob Jenkins. A copy of the | |
97 article can be found at | |
98 <a href="http://burtleburtle.net/bob/hash/doobs.html"> | |
99 Burtleburtle.net</a> | |
100 */ | |
101 private int buildHash(byte[] aBytes) { | |
102 int myHash = 0; | |
103 | |
104 for (int i = 0; i < aBytes.length; i++) { | |
105 myHash += aBytes[i]; | |
106 myHash += (myHash << 10); | |
107 myHash ^= (myHash >> 6); | |
108 } | |
109 | |
110 myHash += (myHash << 3); | |
111 myHash ^= (myHash >> 11); | |
112 myHash += (myHash << 15); | |
113 | |
114 return myHash; | |
115 } | |
116 | |
117 public boolean matches(MangledField aField) { | |
118 if (aField.theHashCode == theHashCode) { | |
119 if (aField.theObjectBytes.length == theObjectBytes.length) { | |
120 for (int i = 0; i < theObjectBytes.length; i++) { | |
121 if (aField.theObjectBytes[i] != theObjectBytes[i]) | |
122 return false; | |
123 } | |
124 | |
125 return true; | |
126 } | |
127 } | |
128 | |
129 return false; | |
130 } | |
131 | |
132 public String getName() { | |
133 return theName; | |
134 } | |
135 | |
136 byte[] getContent() { | |
137 return theObjectBytes; | |
138 } | |
139 | |
140 byte[] getAnnotations() { | |
141 return theAnnotationBytes; | |
142 } | |
143 | |
144 public int hashCode() { | |
145 return theHashCode; | |
146 } | |
147 } |