1 /***
2 * Java DAB EPG API - Serialize/Deserialize To/From POJOs to XML/Binary as per
3 * ETSI specifications TS 102 818 (XML Specification for DAB EPG) and TS 102
4 * 371 (Transportation and Binary Encoding Specification for EPG).
5 *
6 * Copyright (C) 2007 GCap Media PLC
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22 package com.gcapmedia.dab.epg.binary;
23
24 import java.util.Iterator;
25 import java.util.Map;
26 import java.util.TreeMap;
27
28 /***
29 *
30 */
31 public class TokenTable implements Encodable, Iterable<Token> {
32
33 /***
34 * token table tag
35 */
36 public static final byte TAG = 0x04;
37
38 /***
39 * Token map
40 */
41 private Map<TokenTag, Token> tokens;
42
43 /***
44 * Create a new token table type
45 */
46 public TokenTable() {
47 tokens = new TreeMap<TokenTag, Token>();
48 }
49
50 /***
51 * Returns a token from its tag, null if it does not exist in the table
52 * @param tag Tag to search for
53 * @return
54 */
55 public Token getToken(TokenTag tag) {
56 return tokens.get(tag);
57 }
58
59 /***
60 * Generate a new token from a string value
61 * @param value
62 * @return
63 */
64 public synchronized Token newToken(StringType value) {
65 Token token = null;
66 for(TokenTag tag : TokenTag.values()) {
67 if(!tokens.containsKey(tag)) {
68 token = new Token(tag, value);
69 tokens.put(tag, token);
70 break;
71 }
72 }
73 return token;
74 }
75
76 /***
77 * @return Returns true if the table is full
78 */
79 public boolean isFull() {
80 for(TokenTag tag : TokenTag.values()) {
81 if(!tokens.containsKey(tag)) {
82 return false;
83 }
84 }
85 return true;
86 }
87
88 /***
89 * @see com.gcapmedia.dab.epg.binary.Encodable#getBytes()
90 */
91 public byte[] getBytes() {
92
93 BitBuilder bits = new BitBuilder(16);
94
95
96 bits.put(0, 8, TAG);
97
98 BitBuilder tokenBuilder = new BitBuilder(1);
99 int position = 0;
100 for(Token token : this) {
101 int length = token.getLength() * 8;
102 tokenBuilder.setSize(position + length);
103 tokenBuilder.put(position, length, token.getBytes());
104 position += length;
105 }
106
107
108 bits.put(8, 8, tokenBuilder.size() / 8);
109
110
111 bits.setSize(bits.size() + tokenBuilder.size());
112 bits.put(16, tokenBuilder.size(), tokenBuilder.toByteArray());
113
114 return bits.toByteArray();
115 }
116
117 /***
118 * Parse a token table from its byte array representation
119 */
120 public static TokenTable fromBytes(byte[] bytes) {
121
122 TokenTable table = new TokenTable();
123
124 BitParser parser = new BitParser(bytes);
125
126 int position = 16;
127
128 while(position < bytes.length * 8) {
129 Token token = Token.fromBytes(parser.getByteArray(position, parser.size() - position));
130 table.tokens.put(token.getTag(), token);
131 position += token.getLength() * 8;
132 }
133
134 return table;
135 }
136
137 /***
138 * Expand a array of data using the values contained with the table
139 * @param bytes
140 * @return
141 */
142 public byte[] expand(byte[] bytes) {
143 BitBuilder builder = new BitBuilder(bytes.length * 8);
144 int position = 0;
145 for(byte bite : bytes) {
146 if(TokenTag.isToken(bite)) {
147 TokenTag tag = TokenTag.fromBytes(new byte[]{bite});
148 Token token = this.getToken(tag);
149 int length = token.getValue().getLength() * 8;
150 builder.setSize(builder.size() + (length - 8));
151 builder.put(position, length, token.getValue().getBytes());
152 position += length;
153 } else {
154 builder.put(position, 8, new byte[]{bite});
155 position += 8;
156 }
157 }
158 return builder.toByteArray();
159 }
160
161 /***
162 * @see com.gcapmedia.dab.epg.binary.Encodable#getLength()
163 */
164 public int getLength() {
165 return getBytes().length;
166 }
167
168 /***
169 * @see java.lang.Iterable#iterator()
170 */
171 public Iterator<Token> iterator() {
172 return tokens.values().iterator();
173 }
174
175 /***
176 * @see java.lang.Object#equals(java.lang.Object)
177 */
178 @Override
179 public boolean equals(Object obj) {
180 if(!(obj instanceof TokenTable)) {
181 return false;
182 }
183 TokenTable that = (TokenTable)obj;
184 return this.tokens.equals(that.tokens);
185 }
186
187 /***
188 * @see java.lang.Object#toString()
189 */
190 @Override
191 public String toString() {
192 return tokens.values().toString();
193 }
194
195 }