001: /*
002: * (c) Copyright 2006, 2007, 2008 Hewlett-Packard Development Company, LP
003: * All rights reserved.
004: * [See end of file]
005: */
006:
007: package com.hp.hpl.jena.shared.uuid;
008:
009: // NB shifting is "mod 64" -- <<64 is a no-op (not a clear).
010: // http://mindprod.com/jgloss/masking.html
011:
012: /** Utilities for manipulating a bit pattern which held in a 64 bit long
013: * (java.util.BitSet does not allow getting the pattern as a long)
014: *
015: * @author Andy Seaborne
016: * @version $Id: Bits.java,v 1.4 2008/01/02 12:06:07 andy_seaborne Exp $
017: */
018: public final class Bits {
019: // When this is false, no calls to check() should be generated and the
020: // JIT can inline these class statics.
021: // Methods like XXX$ do no checking.
022: public static final boolean CHECK = false;
023: private static int LongLen = 64; // Long.SIZE - java 5 and later
024:
025: /** Extract the value packed into bits start (inclusive) and finish (exclusive),
026: * the value is returned the low part of the returned long.
027: * The low bit is bit zero.
028: */
029:
030: public static final long unpack(long bits, int start, int finish) {
031: if (CHECK)
032: check(start, finish);
033: if (finish == 0)
034: return 0;
035: // Remove top bits by moving up. Clear bottom bits by them moving down.
036: return (bits << (LongLen - finish)) >>> ((LongLen - finish) + start);
037: }
038:
039: /** Place the value into the bit pattern between start and finish;
040: * leaves other bits along.
041: */
042: public static final long pack(long bits, long value, int start,
043: int finish) {
044: if (CHECK)
045: check(start, finish);
046: bits = clear$(bits, start, finish);
047: bits = bits | (value << start);
048: return bits;
049: }
050:
051: /** Get bits from a hex string.
052: *
053: * @param str
054: * @param startChar Index of first character (counted from the left, string style).
055: * @param finishChar Index after the last character (counted from the left, string style).
056: * @return long
057: */
058:
059: public static final long unpack(String str, int startChar,
060: int finishChar) {
061: String s = str.substring(startChar, finishChar);
062: return Long.parseLong(s, 16);
063: }
064:
065: /** Set the bits specificied.
066: *
067: * @param bits Pattern
068: * @param bitIndex
069: * @return Modified pattern
070: */
071: public static final long set(long bits, int bitIndex) {
072: if (CHECK)
073: check(bitIndex);
074: return set$(bits, bitIndex);
075: }
076:
077: /** Set the bits from string (inc) to finish (exc) to one
078: *
079: * @param bits Pattern
080: * @param start start (inclusive)
081: * @param finish finish (exclusive)
082: * @return Modified pattern
083: */
084: public static final long set(long bits, int start, int finish) {
085: if (CHECK)
086: check(start, finish);
087: return set$(bits, start, finish);
088: }
089:
090: public static final boolean test(long bits, boolean isSet,
091: int bitIndex) {
092: if (CHECK)
093: check(bitIndex);
094: return test$(bits, isSet, bitIndex);
095: }
096:
097: public static final boolean test(long bits, long value, int start,
098: int finish) {
099: if (CHECK)
100: check(start, finish);
101: return test$(bits, value, start, finish);
102: }
103:
104: /** Get the bits from start (inclusive) to finish (exclusive),
105: * leaving them aligned in the long. See alio unpack, returns
106: * the value found at that place.
107: */
108:
109: public static final long access(long bits, int start, int finish) {
110: if (CHECK)
111: check(start, finish);
112: return access$(bits, start, finish);
113: }
114:
115: public static final long clear(long bits, int start, int finish) {
116: if (CHECK)
117: check(start, finish);
118: return clear$(bits, start, finish);
119: }
120:
121: /**
122: * Create a mask that has ones between bit positions start (inc) and finish (exc)
123: */
124: public static final long mask(int start, int finish) {
125: if (CHECK)
126: check(start, finish);
127: return mask$(start, finish);
128: }
129:
130: /**
131: * Create a mask that has zeros between bit positions start (inc) and finish (exc)
132: * and ones elsewhere
133: */
134: public static final long maskZero(int start, int finish) {
135: if (CHECK)
136: check(start, finish);
137: return maskZero$(start, finish);
138: }
139:
140: private static final long clear$(long bits, int start, int finish) {
141: long mask = maskZero$(start, finish);
142: bits = bits & mask;
143: return bits;
144: }
145:
146: private static final long set$(long bits, int bitIndex) {
147: long mask = mask$(bitIndex);
148: return bits | mask;
149: }
150:
151: private static final long set$(long bits, int start, int finish) {
152: long mask = mask$(start, finish);
153: return bits | mask;
154: }
155:
156: private static boolean test$(long bits, boolean isSet, int bitIndex) {
157: return isSet == access$(bits, bitIndex);
158: }
159:
160: private static boolean test$(long bits, long value, int start,
161: int finish) {
162: long v = access$(bits, start, finish);
163: return v == value;
164: }
165:
166: private static final boolean access$(long bits, int bitIndex) {
167: long mask = mask$(bitIndex);
168: return (bits & mask) != 0L;
169: }
170:
171: private static final long access$(long bits, int start, int finish) {
172: // Two ways:
173: // long mask = mask$(start, finish) ;
174: // return bits & mask ;
175:
176: return ((bits << (LongLen - finish)) >>> (LongLen - finish + start)) << start;
177: }
178:
179: private static final long mask$(int bitIndex) {
180: return 1L << bitIndex;
181: }
182:
183: private static final long mask$(int start, int finish) {
184: // long mask = 0 ;
185: // if ( finish == Long.SIZE )
186: // // <<Long.SIZE is a no-op
187: // mask = -1 ;
188: // else
189: // mask = (1L<<finish)-1 ;
190: if (finish == 0)
191: // So start is zero and so the mask is zero.
192: return 0;
193:
194: long mask = -1;
195: // mask = mask << (LongLen-finish) >>> (LongLen-finish) ; // Clear the top bits
196: // return mask >>> start << start ; // Clear the bottom bits
197: return mask << (LongLen - finish) >>> (LongLen - finish + start) << start;
198: }
199:
200: private static final long maskZero$(int start, int finish) {
201:
202: return ~mask$(start, finish);
203: }
204:
205: private static final void check(long bitIndex) {
206: if (bitIndex < 0 || bitIndex >= LongLen)
207: throw new IllegalArgumentException("Illegal bit index: "
208: + bitIndex);
209: }
210:
211: private static final void check(long start, long finish) {
212: if (start < 0 || start >= LongLen)
213: throw new IllegalArgumentException("Illegal start: "
214: + start);
215: if (finish < 0 || finish > LongLen)
216: throw new IllegalArgumentException("Illegal finish: "
217: + finish);
218: if (start > finish)
219: throw new IllegalArgumentException("Illegal range: ("
220: + start + ", " + finish + ")");
221: }
222:
223: }
224:
225: /*
226: * (c) Copyright 2006, 2007, 2008 Hewlett-Packard Development Company, LP
227: * All rights reserved.
228: *
229: * Redistribution and use in source and binary forms, with or without
230: * modification, are permitted provided that the following conditions
231: * are met:
232: * 1. Redistributions of source code must retain the above copyright
233: * notice, this list of conditions and the following disclaimer.
234: * 2. Redistributions in binary form must reproduce the above copyright
235: * notice, this list of conditions and the following disclaimer in the
236: * documentation and/or other materials provided with the distribution.
237: * 3. The name of the author may not be used to endorse or promote products
238: * derived from this software without specific prior written permission.
239: *
240: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
241: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
242: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
243: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
244: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
245: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
246: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
247: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
248: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
249: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
250: */
|