001/* A token that contains an unsigned byte number in the range 0 through 255. 002 003 Copyright (c) 1998-2014 The Regents of the University of California. 004 All rights reserved. 005 Permission is hereby granted, without written agreement and without 006 license or royalty fees, to use, copy, modify, and distribute this 007 software and its documentation for any purpose, provided that the above 008 copyright notice and the following two paragraphs appear in all copies 009 of this software. 010 011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 012 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 013 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 014 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 015 SUCH DAMAGE. 016 017 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 020 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 021 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 022 ENHANCEMENTS, OR MODIFICATIONS. 023 024 PT_COPYRIGHT_VERSION_2 025 COPYRIGHTENDKEY 026 027 028 */ 029package ptolemy.data; 030 031import ptolemy.data.type.BaseType; 032import ptolemy.data.type.Type; 033import ptolemy.data.type.TypeLattice; 034import ptolemy.graph.CPO; 035import ptolemy.kernel.util.IllegalActionException; 036import ptolemy.math.Complex; 037 038/////////////////////////////////////////////////////////////////// 039//// UnsignedByteToken 040 041/** 042 A token that contains a byte number in the range 0 through 255. This 043 UnsignedByteToken definition is in contrast to Java's definition of a 044 byte as a number in the range -128 through 127. 045 046 <p>Overflow and underflow are handled by returning the result of all 047 operations modulo 256. Thus, the result is always in the range 0 048 through 255. Likewise, constructors of this class generate tokens 049 whose values are the argument modulo 256. Note, for example, that 050 UnsignedByteToken((byte)(-100)) generates a UnsignedByteToken 051 representing the value 156, which is -100 modulo 256. 052 053 <p>Note, also, that the byteValue() method returns a Java byte in the 054 range -128 through 127. This is in contrast to the intValue(), 055 longValue(), doubleValue(), and complexValue() methods which all 056 return values in the range 0 through 255. The value returned by 057 byteValue() is the value represented by the UnsignedByteToken but with 058 256 subtracted if this value is greater than 127. In other words, the 059 result and the argument are equal modulo 256. 060 061 @author Winthrop Williams, Steve Neuendorffer, Contributor: Christopher Hylands 062 @version $Id$ 063 @since Ptolemy II 2.0 064 @Pt.ProposedRating Yellow (cxh) ONE, ZERO, nil Token 065 @Pt.AcceptedRating Red (winthrop) 066 */ 067public class UnsignedByteToken extends ScalarToken { 068 /** Construct a token with byte 0. 069 */ 070 public UnsignedByteToken() { 071 _value = 0; 072 } 073 074 /** Construct a UnsignedByteToken with the specified byte value. The 075 * UnsignedByteToken constructed represents a value in the range 0 076 * through 255. However, the byte passed in as the argument to 077 * this method represents a value in Java in the range -128 to 078 * 127. Due to the difference between these definitions, this 079 * method effectively adds 256 if the argument is negative, 080 * resulting in a positive value for the UnsignedByteToken. 081 * @param value The specified value. 082 */ 083 public UnsignedByteToken(byte value) { 084 _value = value; 085 } 086 087 /** Construct a UnsignedByteToken with the specified integer value. The 088 * UnsignedByteToken constructed represents a value in the range 0 089 * through 255. However, the integer passed in as the argument 090 * to this method represents a value in Java in the range -2^31 091 * to (2^31)-1. This method's cast to (byte) keeps only the low 092 * order 8 bits of the integer. This effectively adds or 093 * subtracts a multiple of 256 to/from the argument. The 094 * resulting UnsignedByteToken falls in the range 0 through 255. 095 * @param value The specified value. 096 */ 097 public UnsignedByteToken(int value) { 098 _value = (byte) value; 099 } 100 101 /** Construct a UnsignedByteToken from the specified string. The string 102 * is parsed by the parseByte() method of the Java Byte object. 103 * @param init The initialization string, which is an integer from 104 * 0 to 255. -1 and 256 are illegal values. 105 * @exception IllegalActionException If the token could not 106 * be created from the given string. 107 */ 108 public UnsignedByteToken(String init) throws IllegalActionException { 109 if (init == null || init.equals("nil")) { 110 throw new IllegalActionException(notSupportedNullNilStringMessage( 111 "UnsignedByteToken", init)); 112 } 113 try { 114 // Note that Byte.parseByte performs signed conversion, 115 // which is not really what we want. 116 int value = Integer.parseInt(init); 117 118 if (value > 255 || value < 0) { 119 throw new IllegalActionException("Value '" + init 120 + "' is out of the range of Unsigned Byte"); 121 } 122 123 _value = (byte) value; 124 } catch (NumberFormatException e) { 125 throw new IllegalActionException(null, e, 126 "Failed to parse \"" + init + "\" as a number."); 127 } 128 } 129 130 /////////////////////////////////////////////////////////////////// 131 //// public methods //// 132 133 /** Return the value in this token as a byte, modulo 256. The 134 * UnsignedByteToken being converted represents a value in the range 0 135 * through 255. However, the Java byte it is being converted to 136 * represents a value in the range -128 through 127. Thus, this 137 * method has the effect subtracting 256 from the value if the 138 * value is greater than 127. 139 * @return The byte value contained in this token, modulo 256. 140 */ 141 @Override 142 public byte byteValue() { 143 return _value; 144 } 145 146 /** Return the value of this token as a Complex. The real part 147 * of the Complex is the value of this token, the imaginary part 148 * is set to 0. 149 * @return A Complex. 150 */ 151 @Override 152 public Complex complexValue() { 153 return new Complex(unsignedConvert(_value)); 154 } 155 156 /** Convert the specified token into an instance of 157 * UnsignedByteToken. The units of the returned token will be 158 * the same as the units of the given token. If the argument is 159 * already an instance of UnsignedByteToken, it is returned 160 * without any change. If the argument is null or a nil token, 161 * then {@link #NIL} is returned. Otherwise, if the argument is 162 * above UnsignedByteToken in the type hierarchy or is 163 * incomparable with UnsignedByteToken, an exception is thrown 164 * with a message stating that either the conversion is not 165 * supported, or the types are incomparable. If none of the 166 * above conditions is met, then the argument must be below 167 * UnsignedByteToken in the type hierarchy. However, not such 168 * types exist at this time, so an exception is thrown with a 169 * message stating simply that the conversion is not supported. 170 * @param token The token to be converted to a UnsignedByteToken. 171 * @return A UnsignedByteToken. 172 * @exception IllegalActionException If the conversion 173 * cannot be carried out. 174 */ 175 public static UnsignedByteToken convert(Token token) 176 throws IllegalActionException { 177 if (token instanceof UnsignedByteToken) { 178 return (UnsignedByteToken) token; 179 } 180 181 if (token.isNil()) { 182 return UnsignedByteToken.NIL; 183 } 184 int compare = TypeLattice.compare(BaseType.UNSIGNED_BYTE, token); 185 186 if (compare == CPO.LOWER || compare == CPO.INCOMPARABLE) { 187 throw new IllegalActionException( 188 notSupportedIncomparableConversionMessage(token, "byte")); 189 } 190 191 throw new IllegalActionException( 192 notSupportedConversionMessage(token, "byte")); 193 } 194 195 /** Return the value in the token as a double. 196 * @return The value contained in this token as a double. 197 */ 198 @Override 199 public double doubleValue() { 200 return unsignedConvert(_value); 201 } 202 203 /** Return true if the class of the argument is UnsignedByteToken, 204 * and it has the same value as this token. 205 * @param object An instance of Object. 206 * @return True if the argument is an instance of 207 * UnsignedByteToken with the same value. If either this object 208 * or the argument is a nil Token, return false. 209 */ 210 @Override 211 public boolean equals(Object object) { 212 if (object == null) { 213 return false; 214 } 215 // This test rules out subclasses. 216 if (object.getClass() != getClass()) { 217 return false; 218 } 219 220 if (isNil() || ((UnsignedByteToken) object).isNil()) { 221 return false; 222 } 223 224 if (((UnsignedByteToken) object).byteValue() == _value) { 225 return true; 226 } 227 228 return false; 229 } 230 231 /** Return the type of this token. 232 * @return BaseType.UNSIGNED_BYTE 233 */ 234 @Override 235 public Type getType() { 236 return BaseType.UNSIGNED_BYTE; 237 } 238 239 /** Return a hash code value for this token. This method just returns 240 * the value of this token. 241 * @return A hash code value for this token. 242 */ 243 @Override 244 public int hashCode() { 245 return _value; 246 } 247 248 /** Return the value in the token as an integer. 249 * @return The byte value contained in this token as a int. 250 */ 251 @Override 252 public int intValue() { 253 return unsignedConvert(_value); 254 } 255 256 /** Return true if the token is nil, (aka null or missing). 257 * Nil or missing tokens occur when a data source is sparsely populated. 258 * @return True if the token is the {@link #NIL} token. 259 */ 260 @Override 261 public boolean isNil() { 262 // We use a method here so that we can easily change how 263 // we determine if a token is nil without modify lots of classes. 264 // Can't use equals() here, or we'll go into an infinite loop. 265 return this == UnsignedByteToken.NIL; 266 } 267 268 /** Returns a token representing the result of shifting the bits 269 * of this token towards the most significant bit, filling the 270 * least significant bits with zeros. 271 * @param bits The number of bits to shift. 272 * @return The left shift. 273 * If this token is nil, then {@link #NIL} is returned. 274 */ 275 @Override 276 public ScalarToken leftShift(int bits) { 277 if (isNil()) { 278 return UnsignedByteToken.NIL; 279 } 280 return new UnsignedByteToken(_value << bits); 281 } 282 283 /** Returns a token representing the result of shifting the bits 284 * of this token towards the least significant bit, filling the 285 * most significant bits with zeros. This treats the value as an 286 * unsigned number, which may have the effect of destroying the 287 * sign of the value. 288 * @param bits The number of bits to shift. 289 * @return The logical right shift. 290 * If this token is nil, then {@link #NIL} is returned. 291 */ 292 @Override 293 public ScalarToken logicalRightShift(int bits) { 294 if (isNil()) { 295 return UnsignedByteToken.NIL; 296 } 297 return new UnsignedByteToken(_value >>> bits); 298 } 299 300 /** Return the value in the token as a long. 301 * @return The byte value contained in this token as a long. 302 */ 303 @Override 304 public long longValue() { 305 return unsignedConvert(_value); 306 } 307 308 /** Returns an UnsignedByteToken with value 1. 309 * @return an UnsignedByteToken with value 1. 310 */ 311 @Override 312 public Token one() { 313 return ONE; 314 } 315 316 /** Returns a token representing the result of shifting the bits 317 * of this token towards the least significant bit, filling the 318 * most significant bits with the sign of the value. This preserves 319 * the sign of the result. 320 * @param bits The number of bits to shift. 321 * @return The right shift. 322 * If this token is nil, then {@link #NIL} is returned. 323 */ 324 @Override 325 public ScalarToken rightShift(int bits) { 326 if (isNil()) { 327 return UnsignedByteToken.NIL; 328 } 329 // Note that this performs a logicalRightShift, since we are 330 // interpreting the byte to always be unsigned. 331 return new UnsignedByteToken(_value >>> bits); 332 } 333 334 /** Return the value in the token as a short. 335 * @return The value contained in this token as a short. 336 */ 337 @Override 338 public short shortValue() { 339 return unsignedConvert(_value); 340 } 341 342 /** Return the value of this token as a string that can be parsed 343 * by the expression language to recover a token with the same value. 344 * If this token has a unit, the return string also includes a unit 345 * string produced by the unitsString() method in the super class. 346 * @return A String representing the byte value and the units (if 347 * any) of this token. 348 * @see ptolemy.data.ScalarToken#unitsString 349 */ 350 @Override 351 public String toString() { 352 String unitString = ""; 353 354 if (!_isUnitless()) { 355 unitString = " * " + unitsString(); 356 } 357 358 if (isNil()) { 359 // FIXME: what about units? 360 return super.toString(); 361 } 362 363 return Integer.toString(unsignedConvert(_value)) + "ub" + unitString; 364 } 365 366 /** Convert a byte to an integer, treating the byte as an unsigned 367 * value in the range 0 through 255. Note that Java defines the 368 * byte as having a value ranging from -128 through 127, so 256 369 * is added if this value is negative. 370 * @param value The byte to convert to an unsigned byte. 371 * @return An integer in the range 0 through 255. 372 */ 373 public static short unsignedConvert(byte value) { 374 short intValue = value; 375 376 if (intValue < 0) { 377 intValue += 256; 378 } 379 380 return intValue; 381 } 382 383 /** Returns an UnsignedByteToken with value 0. 384 * @return An UnsignedByteToken with value 0. 385 */ 386 @Override 387 public Token zero() { 388 return ZERO; 389 } 390 391 /////////////////////////////////////////////////////////////////// 392 //// public variablesds //// 393 394 /** A token that represents a missing value. 395 * Null or missing tokens are common in analytical systems 396 * like R and SAS where they are used to handle sparsely populated data 397 * sources. In database parlance, missing tokens are sometimes called 398 * null tokens. Since null is a Java keyword, we use the term "nil". 399 * The toString() method on a nil token returns the string "nil". 400 */ 401 public static final UnsignedByteToken NIL = new UnsignedByteToken(); 402 403 /** A UnsignedByteToken with the value 1. */ 404 public static final UnsignedByteToken ONE = new UnsignedByteToken(1); 405 406 /** A UnsignedByteToken with the value 0. */ 407 public static final UnsignedByteToken ZERO = new UnsignedByteToken(0); 408 409 /////////////////////////////////////////////////////////////////// 410 //// protected methods //// 411 412 /** Return a ScalarToken containing the absolute value of the 413 * value of this token. If this token contains a non-negative 414 * number, it is returned directly; otherwise, a new token is is 415 * return. Note that it is explicitly allowable to return this 416 * token, since the units are the same. Since we have defined 417 * the byte as ranging from 0 through 255, its absolute value is 418 * equal to itself. Although this method does not actually do 419 * anything, it is included to make the UnsignedByteToken interface 420 * compatible with the interfaces of the other types. 421 * @return An UnsignedByteToken. 422 */ 423 @Override 424 protected ScalarToken _absolute() { 425 return this; 426 } 427 428 /** Return a new token whose value is the value of the argument 429 * Token added to the value of this Token. It is assumed that 430 * the type of the argument is an UnsignedByteToken. Overflow is handled 431 * by subtracting 256 so that the resulting sum falls in the 432 * range 0 through 255. 433 * @param rightArgument The token to add to this token. 434 * @return A new UnsignedByteToken containing the result. 435 */ 436 @Override 437 protected ScalarToken _add(ScalarToken rightArgument) { 438 byte sum = (byte) (_value 439 + ((UnsignedByteToken) rightArgument).byteValue()); 440 return new UnsignedByteToken(sum); 441 } 442 443 /** Returns a token representing the bitwise AND of this token and 444 * the given token. It is assumed that the type of the argument is 445 * UnsignedByteToken. 446 * @param rightArgument The UnsignedByteToken to bitwise AND with 447 * this one. 448 * @return The bitwise AND. 449 */ 450 @Override 451 protected ScalarToken _bitwiseAnd(ScalarToken rightArgument) { 452 byte sum = (byte) (_value 453 & ((UnsignedByteToken) rightArgument).byteValue()); 454 return new UnsignedByteToken(sum); 455 } 456 457 /** Returns a token representing the bitwise NOT of this token. 458 * @return The bitwise NOT of this token. 459 */ 460 @Override 461 protected ScalarToken _bitwiseNot() { 462 UnsignedByteToken result = new UnsignedByteToken((byte) ~_value); 463 return result; 464 } 465 466 /** Returns a token representing the bitwise OR of this token and 467 * the given token. It is assumed that the type of the argument is 468 * UnsignedByteToken. 469 * @param rightArgument The UnsignedByteToken to bitwise OR with 470 * this one. 471 * @return The bitwise OR. 472 */ 473 @Override 474 protected ScalarToken _bitwiseOr(ScalarToken rightArgument) { 475 byte sum = (byte) (_value 476 | ((UnsignedByteToken) rightArgument).byteValue()); 477 return new UnsignedByteToken(sum); 478 } 479 480 /** Returns a token representing the bitwise XOR of this token and 481 * the given token. It is assumed that the type of the argument is 482 * UnsignedByteToken. 483 * @param rightArgument The UnsignedByteToken to bitwise XOR with 484 * this one. 485 * @return The bitwise XOR. 486 */ 487 @Override 488 protected ScalarToken _bitwiseXor(ScalarToken rightArgument) { 489 byte sum = (byte) (_value 490 ^ ((UnsignedByteToken) rightArgument).byteValue()); 491 return new UnsignedByteToken(sum); 492 } 493 494 /** Return a new token whose value is the value of this token 495 * divided by the value of the argument token. It is assumed that 496 * the type of the argument is an UnsignedByteToken. The result will be 497 * a byte containing the quotient. For example, 255 divided by 498 * 10 returns 25. This method does not test for or attempt to 499 * prevent division by 0. 500 * @param rightArgument The token to divide this token by. 501 * @return A new UnsignedByteToken containing the result. 502 */ 503 @Override 504 protected ScalarToken _divide(ScalarToken rightArgument) { 505 byte quotient = (byte) (unsignedConvert(_value) / unsignedConvert( 506 ((UnsignedByteToken) rightArgument).byteValue())); 507 return new UnsignedByteToken(quotient); 508 } 509 510 /** Test whether the value of this token is close to the first argument, 511 * where "close" means that the distance between them is less than 512 * or equal to the second argument. It is assumed that the argument is 513 * an UnsignedByteToken. 514 * @param rightArgument The token to compare to this token. 515 * @param epsilon The distance. 516 * @return A true-valued token if the first argument is close to 517 * this token. 518 */ 519 @Override 520 protected BooleanToken _isCloseTo(ScalarToken rightArgument, 521 double epsilon) { 522 long right = ((UnsignedByteToken) rightArgument).longValue(); 523 long left = longValue(); 524 long distance = Math.round(Math.floor(epsilon)); 525 526 if (right > left + distance || right < left - distance) { 527 return BooleanToken.FALSE; 528 } else { 529 return BooleanToken.TRUE; 530 } 531 } 532 533 /** Test for ordering of the values of this Token and the argument 534 * Token. It is assumed that the type of the argument is 535 * UnsignedByteToken. 536 * @param rightArgument The token to add to this token. 537 * @return A new Token containing the result. 538 */ 539 @Override 540 protected BooleanToken _isLessThan(ScalarToken rightArgument) { 541 UnsignedByteToken convertedArgument = (UnsignedByteToken) rightArgument; 542 return BooleanToken.getInstance(unsignedConvert( 543 _value) < unsignedConvert(convertedArgument.byteValue())); 544 } 545 546 /** Return a new token whose value is the value of this token 547 * modulo the value of the argument token. It is assumed that 548 * the type of the argument is UnsignedByteToken. This method does not 549 * test for or attempt to prevent division by 0. 550 * @param rightArgument The token to modulo this token by. 551 * @return A new UnsignedByteToken containing the result. 552 */ 553 @Override 554 protected ScalarToken _modulo(ScalarToken rightArgument) { 555 byte remainder = (byte) (unsignedConvert(_value) % unsignedConvert( 556 ((UnsignedByteToken) rightArgument).byteValue())); 557 return new UnsignedByteToken(remainder); 558 } 559 560 /** Return a new token whose value is the value of this token 561 * multiplied by the value of the argument token. It is assumed 562 * that the type of the argument is UnsignedByteToken. Overflow is 563 * handled by subtracting the multiple of 256 which puts the 564 * result into the range 0 through 255. In other words, return 565 * the product modulo 256. 566 * @param rightArgument The token to multiply this token by. 567 * @return A new UnsignedByteToken containing the product modulo 256. 568 */ 569 @Override 570 protected ScalarToken _multiply(ScalarToken rightArgument) { 571 byte product = (byte) (unsignedConvert(_value) * unsignedConvert( 572 ((UnsignedByteToken) rightArgument).byteValue())); 573 return new UnsignedByteToken(product); 574 } 575 576 /** Return a new token whose value is the value of the argument 577 * token subtracted from the value of this token. It is assumed 578 * that the type of the argument is UnsignedByteToken. Underflow is 579 * handled by adding 256 to the result if it is less than 0. 580 * Thus the result is always in the range 0 through 255. 581 * @param rightArgument The token to subtract from this token. 582 * @return A new UnsignedByteToken containing the difference modulo 256. 583 */ 584 @Override 585 protected ScalarToken _subtract(ScalarToken rightArgument) { 586 byte difference = (byte) (unsignedConvert(_value) - unsignedConvert( 587 ((UnsignedByteToken) rightArgument).byteValue())); 588 return new UnsignedByteToken(difference); 589 } 590 591 /////////////////////////////////////////////////////////////////// 592 //// private variables //// 593 private byte _value; 594}