1 | /* |
2 | * $Id: GUID.java,v 1.7 2005/11/02 02:49:13 hastings Exp $ |
3 | * |
4 | * (c) Copyright, Moebius Solutions, Inc., 2004 |
5 | * |
6 | * All Rights Reserved |
7 | * |
8 | * This material may be reproduced by or for the U. S. Government |
9 | * pursuant to the copyright license under the clause at |
10 | * DFARS 252.227-7014 (OCT 2001). |
11 | */ |
12 | |
13 | package com.moesol.bindings.platform_sdk.component_services; |
14 | |
15 | import java.io.IOException; |
16 | import java.io.PushbackReader; |
17 | import java.io.StringReader; |
18 | import java.nio.ByteBuffer; |
19 | |
20 | import com.moesol.bindings.NativeStructure; |
21 | |
22 | /** |
23 | * Emulate Win32 GUID structure in Java. |
24 | * Not generated by tlb2-stdole because it is marked as [hidden]. |
25 | */ |
26 | public class GUID extends NativeStructure { |
27 | |
28 | /** |
29 | * Create a new instance |
30 | */ |
31 | public GUID() { |
32 | super(new byte[sizeof()]); |
33 | } |
34 | /** |
35 | * Wrap a guid onto a byte buffer. |
36 | * @param bb |
37 | */ |
38 | public GUID(ByteBuffer bb) { |
39 | super(bb); |
40 | bb.limit(sizeof()); |
41 | } |
42 | /** |
43 | * @return static size of native structure. |
44 | */ |
45 | public static int sizeof() { |
46 | return 16; |
47 | } |
48 | |
49 | /** |
50 | * Represent a native array of these structures |
51 | */ |
52 | public static class Array extends com.moesol.bindings.NativeArrayOfStructs { |
53 | public Array(java.nio.ByteBuffer bb) { |
54 | super(bb); |
55 | } |
56 | public GUID get(int index) { |
57 | return new GUID(getElementSlice(index, GUID.sizeof())); |
58 | } |
59 | public void put(int index, GUID value) { |
60 | get(index).putStruct(0, GUID.sizeof(), value); |
61 | } |
62 | public int length() { |
63 | return _getByteBuffer().limit() / GUID.sizeof(); |
64 | } |
65 | public String toString() { |
66 | StringBuffer sb = new StringBuffer("\n"); |
67 | for (int i = 0; i < length(); i++) { |
68 | sb.append(get(i)); |
69 | sb.append('\n'); |
70 | } |
71 | return sb.toString(); |
72 | } |
73 | } |
74 | |
75 | |
76 | public void set_Data1(int v) { |
77 | putInt(0, v); |
78 | } |
79 | public int get_Data1() { |
80 | return getInt(0); |
81 | } |
82 | public void set_Data2(short v) { |
83 | putShort(4, v); |
84 | } |
85 | public short get_Data2() { |
86 | return getShort(4); |
87 | } |
88 | public void set_Data3(short v) { |
89 | putShort(6, v); |
90 | } |
91 | public short get_Data3() { |
92 | return getShort(6); |
93 | } |
94 | public void set_Data4(byte[] v) { |
95 | assert(v.length == 8); |
96 | putArray(8, 8, v); |
97 | } |
98 | public byte[] get_Data4() { |
99 | return getArray(8, 8); |
100 | } |
101 | |
102 | // BEGIN_KEEP |
103 | public static final GUID NULL = new GUID(); |
104 | |
105 | public GUID(int d1, short d2, short d3, byte[] d4) { |
106 | super(new byte[sizeof()]); |
107 | set_Data1(d1); |
108 | set_Data2(d2); |
109 | set_Data3(d3); |
110 | set_Data4(d4); |
111 | } |
112 | public String toString() { |
113 | StringBuffer r = new StringBuffer(); |
114 | r.append('{'); |
115 | appendPaddedHex(r, get_Data1(), 8); |
116 | r.append('-'); |
117 | appendPaddedHex(r, get_Data2(), 4); |
118 | r.append('-'); |
119 | appendPaddedHex(r, get_Data3(), 4); |
120 | r.append('-'); |
121 | |
122 | byte[] data4 = get_Data4(); |
123 | int i; |
124 | for (i = 0; i < 2; i++) { |
125 | appendPaddedHex(r, data4[i], 2); |
126 | } |
127 | r.append('-'); |
128 | for (i = 2; i < 4; i++) { |
129 | appendPaddedHex(r, data4[i], 2); |
130 | } |
131 | for (/* continue(i) */; i < data4.length; i++) { |
132 | appendPaddedHex(r, data4[i], 2); |
133 | } |
134 | r.append('}'); |
135 | return r.toString().toUpperCase(); |
136 | } |
137 | |
138 | public static GUID fromString(String string) { |
139 | StringReader sr = new StringReader(string); |
140 | PushbackReader pbr = new PushbackReader(sr); |
141 | try { |
142 | GUID g = new GUID(); |
143 | |
144 | readOpen(pbr); |
145 | g.set_Data1((int)readHexField(pbr, 8)); |
146 | readDash(pbr); |
147 | g.set_Data2((short)readHexField(pbr, 4)); |
148 | readDash(pbr); |
149 | g.set_Data3((short)readHexField(pbr, 4)); |
150 | readDash(pbr); |
151 | |
152 | byte[] data4 = g.get_Data4(); |
153 | int i; |
154 | for (i = 0; i < 2; i++) { |
155 | data4[i] = (byte)readHexField(pbr, 2); |
156 | } |
157 | readDash(pbr); |
158 | for (i = 2; i < 4; i++) { |
159 | data4[i] = (byte)readHexField(pbr, 2); |
160 | } |
161 | for (/* continue(i) */; i < data4.length; i++) { |
162 | data4[i] = (byte)readHexField(pbr, 2); |
163 | } |
164 | g.set_Data4(data4); |
165 | |
166 | readClose(pbr); |
167 | |
168 | return g; |
169 | } catch (IOException e) { |
170 | throw new IllegalArgumentException("bad input string"); |
171 | } |
172 | } |
173 | |
174 | /** |
175 | * @param pbr |
176 | * @throws IOException |
177 | */ |
178 | private static void readOpen(PushbackReader pbr) throws IOException { |
179 | int c = pbr.read(); |
180 | if (c == '{') { |
181 | c = pbr.read(); |
182 | } |
183 | pbr.unread(c); |
184 | |
185 | } |
186 | private static void readDash(PushbackReader pbr) throws IOException { |
187 | int c = pbr.read(); |
188 | if (c != '-') { |
189 | throw new IllegalArgumentException("mising dash"); |
190 | } |
191 | } |
192 | private static long readHexField(PushbackReader pbr, int length) throws IOException { |
193 | long res = 0; |
194 | for (int i = 0; i < length; i++) { |
195 | res = readNibble(pbr, res); |
196 | } |
197 | return res; |
198 | } |
199 | private static long readNibble(PushbackReader pbr, long res) throws IOException { |
200 | int c = pbr.read(); |
201 | if (c == -1) { |
202 | throw new IllegalArgumentException("missing data"); |
203 | } |
204 | int digit = Character.digit((char)c, 16); |
205 | if (digit < 0 || 16 <= digit) { |
206 | throw new IllegalArgumentException("malformed needed hex digit, got: '" + (char)c + "'"); |
207 | } |
208 | res <<= 4; |
209 | res |= digit; |
210 | return res; |
211 | } |
212 | private static void readClose(PushbackReader pbr) throws IOException { |
213 | int c = pbr.read(); |
214 | if (c == -1) { |
215 | return; |
216 | } |
217 | if (c == '}') { |
218 | c = pbr.read(); |
219 | } |
220 | if (c != -1) { |
221 | throw new IllegalArgumentException("to many characters"); |
222 | } |
223 | } |
224 | |
225 | private void appendPaddedHex(StringBuffer r, int value, int width) { |
226 | String hex = Integer.toHexString(value); |
227 | for (int i = width - hex.length(); i > 0; i--) { |
228 | r.append('0'); |
229 | } |
230 | r.append(hex); |
231 | } |
232 | private void appendPaddedHex(StringBuffer r, short value, int width) { |
233 | appendPaddedHex(r, value & 0xFFFF, width); |
234 | } |
235 | private void appendPaddedHex(StringBuffer r, byte value, int width) { |
236 | appendPaddedHex(r, value & 0xFF, width); |
237 | } |
238 | // END_KEEP |
239 | } |