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 }