| 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 | } |