source: trunk/gsdl3/src/packages/javagdbm/java/au/com/pharos/packing/QuotedVectorPacking.java@ 10737

Last change on this file since 10737 was 10737, checked in by kjdon, 19 years ago

Java Wrapper for GDBM, from Martin Pool. Original website gone, so added it all in here. I have modified the Makefiles to work in greenstone, and on macs, and added windows makefiles

  • Property svn:keywords set to Author Date Id Revision
File size: 5.8 KB
Line 
1/*
2 * module: pip/java/packing -- Strategy objects for converting
3 * Java objects to and from stored data.
4 * class: QuotedVectorPacking -- Vectors of Strings packed in a Perl-
5 * style format
6 *
7 * Copyright (C) 1997 Pharos IP Pty Ltd
8 * $Id: QuotedVectorPacking.java 10737 2005-10-19 03:06:40Z kjdon $
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25package au.com.pharos.packing;
26
27import java.util.Vector;
28
29// FIXME: Escape bad characters! -- mbp
30// TODO: Write a more formal definition of the encoding system
31// TODO: More documentation
32
33// XXX: Perhaps the strategy for encoding characters should be in a
34// separate class used by this class? They would have to
35// interact to make sure that separator chatacters were decoded
36// properly. Probably not worth worrying about, as this class
37// is only a compatibility measure in any case.
38
39/** Stores Vectors of strings, packed into a single string, as used by
40 * some Perl code. The encoding format is similar to that used in
41 * Unix databases like
42 * <A HREF="file:/etc/passwd/"><CODE>/etc/passwd</CODE></A>, except that
43 * it uses escape sequences to represent characters that would
44 * normally not be allowed.
45 *
46 * <P>The strings within the vector are separated by separator characters,
47 * which default to colons.
48 *
49 * <P>The resulting packed string is UTF encoded after escaping
50 * control-characters, so non-ASCII characters should be passed through
51 * unchanged.
52 *
53 * <P>Certain characters are escaped as quoted-printable strings.
54 * These characters include colon, equals, and escape characters. The
55 * encoding accepts and interprets any hex escape when reading data.
56 *
57 * <P>If any elements of the vector are null, they are stored as empty
58 * strings. On unpacking, empty strings are returned as such.
59 *
60 * <P>An example of a vector encoded in this manner is:
61 * <BLOCKQUOTE>
62 * <PRE>oC7okz059wGnQ:vf:Peter Barnes%2c Pharos Business Solutions</PRE>
63 * </BLOCKQUOTE>
64 *
65 * @author Martin Pool
66 * @version $Revision: 10737 $ $Date: 2005-10-19 03:06:40 +0000 (Wed, 19 Oct 2005) $
67 *
68 * @see java.util.Vector
69 **/
70public class QuotedVectorPacking extends Packing
71implements java.io.Serializable
72{
73 private char hexEscape;
74 private char separator;
75
76 /** Constructs a QuotedVectorPacking using the default separator
77 * character ':' and escape character '%'.
78 **/
79 public QuotedVectorPacking() {
80 this('%', ':');
81 }
82
83
84 /** Constructs a QuotedVectorPacking with specified separator and
85 * hex-escape characters.
86 *
87 * @param hexEscape the character used to begin a three-character
88 * hex escape
89 *
90 * @param separator the character used to separate elements in the
91 * vector.
92 **/
93 public QuotedVectorPacking(char hexEscape, char separator) {
94 if (hexEscape == separator)
95 throw new IllegalArgumentException
96 ("hexEscape and separator characters are the same");
97 this.hexEscape = hexEscape;
98 this.separator = separator;
99 }
100
101
102 /** Convert a Vector of Strings to a QuotedVector represented as an
103 * array of bytes.
104 *
105 * @param obj the Vector to encode; or null.
106 *
107 * @returns an array of bytes containing a packed representation of
108 * <EM>obj</EM>; or null if <EM>obj</EM> is null.
109 *
110 * @exception java.lang.ClassCastException if obj is not a Vector
111 * or null; or if any element of <EM>obj</EM> is not a String or
112 * null.
113 **/
114 public byte[] toBytes(Object obj)
115 {
116 if (obj == null)
117 return null;
118 Vector vec = (Vector) obj;
119 StringBuffer sb = new StringBuffer();
120 Object elem;
121 for (int i = 0; i < vec.size(); i++) {
122 if (i > 0)
123 sb.append(separator);
124 elem = vec.elementAt(i);
125 sb.append((elem == null) ? "" : encodeString((String) elem));
126 }
127 return sb.toString().getBytes();
128 }
129
130
131
132 /** Perform hex-escapes on a string.
133 * @returns <EM>from</EM> encoded as a quoted-printable string
134 **/
135 private String encodeString(String from) {
136 StringBuffer buf = new StringBuffer(from.length());
137 char[] chars = from.toCharArray();
138 for (int i = 0; i < chars.length; i++) {
139 char ch = chars[i];
140 if (ch == separator
141 || ch == hexEscape
142 || Character.isISOControl(ch)
143 || (ch != ' ' && ch != '\t' && Character.isWhitespace(ch)))
144 {
145 buf.append(hexEscape);
146 // XXX: This will truncate high Unicode characters, but I
147 // don't know what else we can do with them. -- mbp
148 buf.append(Character.forDigit((ch>>4) & 0xf, 16));
149 buf.append(Character.forDigit(ch & 0xf, 16));
150 } else {
151 buf.append(ch);
152 }
153 }
154 return buf.toString();
155 }
156
157
158
159 /** Interprets <em>raw</em> as a packed quoted Vector, and
160 * returns the unpacked Vector of strings. */
161 public Object fromBytes(byte[] raw)
162 {
163 if (raw == null)
164 return null;
165
166 Vector result = new Vector();
167 StringBuffer sb = new StringBuffer();
168 for (int i = 0; i < raw.length; i++) {
169 char ch = (char) raw[i];
170 if (ch == separator) {
171 result.addElement(sb.toString());
172 sb.setLength(0);
173 } else if (ch == hexEscape && i < (raw.length - 2)) {
174 byte[] hexBytes = new byte[2];
175 hexBytes[0] = raw[++i];
176 hexBytes[1] = raw[++i];
177 String hex = new String(hexBytes);
178 ch = (char)Integer.parseInt(hex, 16);
179 sb.append(ch);
180 } else {
181 sb.append(ch);
182 }
183 }
184 result.addElement(sb.toString());
185 return result;
186 }
187}
Note: See TracBrowser for help on using the repository browser.