View Javadoc
1   /**
2    * Copyright 2014 Internet2
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *   http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  /*
17   * Copyright (C) 2006 Joe Walnes.
18   * Copyright (C) 2006, 2007 XStream Committers.
19   * All rights reserved.
20   *
21   * The software in this package is published under the terms of the BSD
22   * style license a copy of which has been included with this distribution in
23   * the LICENSE.txt file.
24   * 
25   * Created on 04. June 2006 by Joe Walnes
26   */
27  package edu.internet2.middleware.grouperClientExt.com.thoughtworks.xstream.io.binary;
28  
29  import java.io.DataInput;
30  import java.io.DataOutput;
31  import java.io.IOException;
32  
33  import edu.internet2.middleware.grouperClientExt.com.thoughtworks.xstream.io.StreamException;
34  
35  /**
36   * Represents the Tokens stored in the binary stream used by
37   * {@link BinaryStreamReader} and {@link BinaryStreamWriter}.
38   * <p/>
39   * <p>A token consists of a type and (depending on this type)
40   * it may additionally have an ID (positive long number)
41   * and/or a value (String).</p>
42   * <p/>
43   * <p>The first byte of the token represents how many subsequent
44   * bytes are used by the ID.
45   *
46   * @author Joe Walnes
47   * @see BinaryStreamReader
48   * @see BinaryStreamWriter
49   * @since 1.2
50   */
51  public abstract class Token {
52  
53      private static final byte TYPE_MASK = 0x7;
54      public static final byte TYPE_VERSION = 0x1;
55      public static final byte TYPE_MAP_ID_TO_VALUE = 0x2;
56      public static final byte TYPE_START_NODE = 0x3;
57      public static final byte TYPE_END_NODE = 0x4;
58      public static final byte TYPE_ATTRIBUTE = 0x5;
59      public static final byte TYPE_VALUE = 0x6;
60  
61      private static final byte ID_MASK = 0x38;
62      private static final byte ID_ONE_BYTE = 0x08;
63      private static final byte ID_TWO_BYTES = 0x10;
64      private static final byte ID_FOUR_BYTES = 0x18;
65      private static final byte ID_EIGHT_BYTES = 0x20;
66  
67      private final byte type;
68  
69      protected long id = -1;
70      protected String value;
71  
72      public Token(byte type) {
73          this.type = type;
74      }
75  
76      public byte getType() {
77          return type;
78      }
79  
80      public long getId() {
81          return id;
82      }
83  
84      public String getValue() {
85          return value;
86      }
87  
88      public String toString() {
89          return getClass().getName() + " [id=" + id + ", value='" + value + "']";
90      }
91  
92      public boolean equals(Object o) {
93          if (this == o) return true;
94          if (o == null || getClass() != o.getClass()) return false;
95  
96          final Token="../../../../../../../../../edu/internet2/middleware/grouperClientExt/com/thoughtworks/xstream/io/binary/Token.html#Token">Token token = (Token) o;
97  
98          if (id != token.id) return false;
99          if (type != token.type) return false;
100         return !(value != null ? !value.equals(token.value) : token.value != null);
101 
102     }
103 
104     public int hashCode() {
105         int result;
106         result = type;
107         result = 29 * result + (int) (id ^ (id >>> 32));
108         result = 29 * result + (value != null ? value.hashCode() : 0);
109         return result;
110     }
111 
112     public abstract void writeTo(DataOutput out, byte idType) throws IOException;
113 
114     public abstract void readFrom(DataInput in, byte idType) throws IOException;
115 
116     protected void writeId(DataOutput out, long id, byte idType) throws IOException {
117         if (id < 0) {
118             throw new IOException("id must not be negative " + id);
119         }
120         switch (idType) {
121             case ID_ONE_BYTE:
122                 out.writeByte((byte) id + Byte.MIN_VALUE);
123                 break;
124             case ID_TWO_BYTES:
125                 out.writeShort((short) id + Short.MIN_VALUE);
126                 break;
127             case ID_FOUR_BYTES:
128                 out.writeInt((int) id + Integer.MIN_VALUE);
129                 break;
130             case ID_EIGHT_BYTES:
131                 out.writeLong(id + Long.MIN_VALUE);
132                 break;
133             default:
134                 throw new Error("Unknown idType " + idType);
135         }
136     }
137 
138     protected void writeString(DataOutput out, String string) throws IOException {
139         out.writeUTF(string);
140     }
141 
142     protected long readId(DataInput in, byte idType) throws IOException {
143         switch (idType) {
144             case ID_ONE_BYTE:
145                 return in.readByte() - Byte.MIN_VALUE;
146             case ID_TWO_BYTES:
147                 return in.readShort() - Short.MIN_VALUE;
148             case ID_FOUR_BYTES:
149                 return in.readInt() - Integer.MIN_VALUE;
150             case ID_EIGHT_BYTES:
151                 return in.readLong() - Long.MIN_VALUE;
152             default:
153                 throw new Error("Unknown idType " + idType);
154         }
155     }
156 
157     protected String readString(DataInput in) throws IOException {
158         return in.readUTF();
159     }
160 
161     public static class Formatter {
162 
163         public void write(DataOutput out, Token token) throws IOException {
164             long id = token.getId();
165             byte idType;
166             if (id <= Byte.MAX_VALUE - Byte.MIN_VALUE) {
167                 idType = ID_ONE_BYTE;
168             } else if (id <= Short.MAX_VALUE - Short.MIN_VALUE) {
169                 idType = ID_TWO_BYTES;
170             } else if (id <= (long) Integer.MAX_VALUE - (long) Integer.MIN_VALUE) { // cast to long to prevent overflo
171                 idType = ID_FOUR_BYTES;
172             } else {
173                 idType = ID_EIGHT_BYTES;
174             }
175             out.write(token.getType() + idType);
176             token.writeTo(out, idType);
177         }
178 
179         public Token read(DataInput in) throws IOException {
180             byte nextByte = in.readByte();
181             byte type = (byte) (nextByte & TYPE_MASK);
182             byte idType = (byte) (nextByte & ID_MASK);
183             Token token = contructToken(type);
184             token.readFrom(in, idType);
185             return token;
186         }
187 
188         private Token contructToken(byte type) {
189             switch (type) {
190                 case Token.TYPE_START_NODE:
191                     return new StartNode();
192                 case Token.TYPE_MAP_ID_TO_VALUE:
193                     return new MapIdToValue();
194                 case Token.TYPE_ATTRIBUTE:
195                     return new Attribute();
196                 case Token.TYPE_END_NODE:
197                     return new EndNode();
198                 case Token.TYPE_VALUE:
199                     return new Value();
200                 default:
201                     throw new StreamException("Unknown token type");
202             }
203         }
204     }
205 
206     public static class MapIdToValue extends Token {
207 
208         public MapIdToValue(long id, String value) {
209             super(TYPE_MAP_ID_TO_VALUE);
210             this.id = id;
211             this.value = value;
212         }
213 
214         public MapIdToValue() {
215             super(TYPE_MAP_ID_TO_VALUE);
216         }
217 
218         public void writeTo(DataOutput out, byte idType) throws IOException {
219             writeId(out, id, idType);
220             writeString(out, value);
221         }
222 
223         public void readFrom(DataInput in, byte idType) throws IOException {
224             id = readId(in, idType);
225             value = readString(in);
226         }
227 
228     }
229 
230     public static class StartNode extends Token {
231 
232         public StartNode(long id) {
233             super(TYPE_START_NODE);
234             this.id = id;
235         }
236 
237         public StartNode() {
238             super(TYPE_START_NODE);
239         }
240 
241         public void writeTo(DataOutput out, byte idType) throws IOException {
242             writeId(out, id, idType);
243         }
244 
245         public void readFrom(DataInput in, byte idType) throws IOException {
246             id = readId(in, idType);
247         }
248 
249     }
250 
251     public static class EndNode extends Token {
252 
253         public EndNode() {
254             super(TYPE_END_NODE);
255         }
256 
257         public void writeTo(DataOutput out, byte idType) {
258         }
259 
260         public void readFrom(DataInput in, byte idType) {
261         }
262 
263     }
264 
265     public static class Attribute extends Token {
266 
267         public Attribute(long id, String value) {
268             super(TYPE_ATTRIBUTE);
269             this.id = id;
270             this.value = value;
271         }
272 
273         public Attribute() {
274             super(TYPE_ATTRIBUTE);
275         }
276 
277         public void writeTo(DataOutput out, byte idType) throws IOException {
278             writeId(out, id, idType);
279             writeString(out, value);
280         }
281 
282         public void readFrom(DataInput in, byte idType) throws IOException {
283             this.id = readId(in, idType);
284             this.value = readString(in);
285         }
286 
287     }
288 
289     public static class Value extends Token {
290 
291         public Value(String value) {
292             super(TYPE_VALUE);
293             this.value = value;
294         }
295 
296         public Value() {
297             super(TYPE_VALUE);
298         }
299 
300         public void writeTo(DataOutput out, byte idType) throws IOException {
301             writeString(out, value);
302         }
303 
304         public void readFrom(DataInput in, byte idType) throws IOException {
305             value = readString(in);
306         }
307 
308     }
309 
310 }