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 * @author ben.poor
26 *
27 */
28 public class CData implements Encodable {
29
30 /***
31 * CDATA tag
32 */
33 public static final byte TAG = 0x01;
34
35 /***
36 * CDATA content value, encoded using ISO/IEC 10646 with
37 * UTF-8 encoding.
38 */
39 private StringType value;
40
41 /***
42 * Create new CDATA content
43 * @param value CDATA content value
44 */
45 public CData(StringType value) {
46 if(value == null) {
47 throw new IllegalArgumentException("Must specify a value for this CDATA content");
48 }
49 this.value = value;
50 }
51
52 /***
53 * Create new CDATA content
54 * @param value CDATA content value
55 */
56 public CData(String value) {
57 if(value == null) {
58 throw new IllegalArgumentException("Must specify a value for this CDATA content");
59 }
60 this.value = new StringType(value);
61 }
62
63 /***
64 * @see com.gcapmedia.dab.epg.binary.Encodable#getBytes()
65 */
66 public byte[] getBytes() {
67 if(value == null) {
68 throw new IllegalStateException("Bytes requested when value is null");
69 }
70
71 BitBuilder bits = new BitBuilder(8);
72
73
74 bits.put(0, 8, TAG);
75
76
77
78
79 byte[] databytes = value.getBytes();
80 int datalength = databytes.length;
81 if(datalength <= 253) {
82 bits.setSize(bits.size() + 8);
83 bits.put(8, 8, datalength);
84 } else if(datalength >= 1<<8 && datalength <= 1<<16) {
85 bits.setSize(bits.size() + 8 + 16);
86 bits.put(8, 8, 0xFE);
87 bits.put(16, 16, datalength);
88 } else if(datalength > 1<<16 && datalength <= 1<<24) {
89 bits.setSize(bits.size() + 8 + 24);
90 bits.put(8, 8, 0xFF);
91 bits.put(16, 24, datalength);
92 } else {
93 throw new IndexOutOfBoundsException("CDATA content length exceeds the maximum allowed by the extended cdata length (24bits): " + datalength + " > " + (1<<24));
94 }
95
96
97 bits.setSize(bits.size() + databytes.length * 8);
98 bits.put(bits.position(), databytes.length * 8, databytes);
99
100 return bits.toByteArray();
101 }
102
103 /***
104 * @see com.gcapmedia.dab.epg.binary.Encodable#getLength()
105 */
106 public int getLength() {
107 return getBytes().length;
108 }
109
110 /***
111 * @return Returns the CDATA content
112 */
113 public StringType getString() {
114 return value;
115 }
116
117 /***
118 * Parse a CDATA object from its byte array representation
119 */
120 public static CData fromBytes(byte[] bytes) {
121 return fromBytes(bytes, null);
122 }
123
124 /***
125 * Parse a CDATA object from its byte array representation
126 */
127 public static CData fromBytes(byte[] bytes, TokenTable tokens) {
128
129 BitParser parser = new BitParser(bytes);
130
131
132
133
134 int length = parser.getInt(8, 8);
135 int position = 16;
136 if(length == 0xFE) {
137
138 length = parser.getInt(16, 16);
139 position = 32;
140 } else if(length == 0xFE) {
141
142 length = parser.getInt(16, 24);
143 position = 40;
144 }
145
146
147 byte[] data = parser.getByteArray(position, bytes.length * 8 - position);
148 if(tokens != null) data = tokens.expand(data);
149 StringType content = StringType.fromBytes(data);
150
151 CData cdata = new CData(content);
152 return cdata;
153 }
154
155 /***
156 * @see java.lang.Object#toString()
157 */
158 public String toString() {
159 return value.toString();
160 }
161
162 /***
163 * @see java.lang.Object#equals(java.lang.Object)
164 */
165 @Override
166 public boolean equals(Object obj) {
167 if(!(obj instanceof CData)) {
168 return false;
169 }
170 CData that = (CData)obj;
171 return this.value.equals(that.value);
172 }
173
174
175
176 }
177