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 /***
25 * Defines an entry in the token table as per clause 4.9.1 of the binary
26 * encoding specification.
27 *
28 * Frequently recurring strings in the EPG character data ("tokens") can
29 * be encoded using a token table. A token holds a tag used to represent
30 * an equivalent string. Whenever a decoder finds the tag in a stream it
31 * shall replace the tag with its equivalent string.
32 *
33 * A token can only occur within the two top-level elements (epg and
34 * serviceInformation) and all children of the parent element.
35 */
36 public class Token implements Encodable {
37
38 /***
39 *
40 */
41 private TokenTag tag;
42
43 /***
44 * Contains either a string (4.5.1) or an enumerated data value
45 * (4.6) or a common data type (4.7)
46 */
47 private Encodable value;
48
49 /***
50 * Create a new attribute
51 * @param tag Attribute tag
52 * @param data Attribute value
53 */
54 public Token(TokenTag tag, StringType value) {
55 if(tag == null) {
56 throw new IllegalArgumentException("Must specify a tag for this attribute");
57 }
58 this.tag = tag;
59 if(value == null) {
60 throw new IllegalArgumentException("Must specify a value for this attribute: " + this.getTag());
61 }
62 this.value = value;
63 }
64
65 /***
66 * @return Returns the attribute tag
67 */
68 public TokenTag getTag() {
69 return tag;
70 }
71
72 /***
73 * @return Returns the attribute value
74 */
75 public Encodable getValue() {
76 return value;
77 }
78
79 /***
80 * @see com.gcapmedia.dab.epg.binary.Encodable#getBytes()
81 */
82 public byte[] getBytes() {
83 if(value == null) {
84 throw new IllegalStateException("Bytes requested when value is null");
85 }
86
87 BitBuilder bits = new BitBuilder(16);
88 int position = 0;
89
90
91 bits.put(position, 8, tag.getBytes());
92 position += 8;
93
94
95 byte[] databytes = value.getBytes();
96 int datalength = databytes.length;
97 if(datalength >= 1<<8) {
98 throw new IndexOutOfBoundsException("Token data length exceeds the maximum allowed (8bits): " + datalength + " > " + (1<<8));
99 }
100 bits.setSize(16 + datalength * 8);
101 bits.put(position, 8, datalength);
102 position += 8;
103
104
105 bits.put(position, databytes.length * 8, databytes);
106 position += databytes.length * 8;
107
108 return bits.toByteArray();
109 }
110
111 /***
112 * @see com.gcapmedia.dab.epg.binary.Encodable#getLength()
113 */
114 public int getLength() {
115 return getBytes().length;
116 }
117
118 /***
119 * Parse an object from its byte array representation
120 * @param parent Tag parent
121 * @param bytes Byte array representation
122 */
123 public static Token fromBytes(byte[] bytes) {
124 BitParser parser = new BitParser(bytes);
125
126
127 TokenTag tag = TokenTag.fromBytes(bytes);
128
129
130 int length = parser.getInt(8, 8);
131
132
133 byte[] data = parser.getByteArray(16, length * 8);
134 StringType value = StringType.fromBytes(data);
135
136 Token token = new Token(tag, value);
137
138 return token;
139 }
140
141 /***
142 * @see java.lang.Object#equals(java.lang.Object)
143 */
144 @Override
145 public boolean equals(Object obj) {
146 if(!(obj instanceof Token)) {
147 return false;
148 }
149 Token that = (Token)obj;
150 return this.tag == that.tag && this.value.equals(that.value);
151 }
152
153 /***
154 * @see java.lang.Object#toString()
155 */
156 public String toString() {
157 return tag + "=" + value;
158 }
159 }