Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2010-2024 60East Technologies Inc., All Rights Reserved.
//
// This computer software is owned by 60East Technologies Inc. and is
// protected by U.S. copyright laws and other laws and by international
// treaties. This computer software is furnished by 60East Technologies
// Inc. pursuant to a written license agreement and may be used, copied,
// transmitted, and stored only in accordance with the terms of such
// license agreement and with the inclusion of the above copyright notice.
// This computer software or any other copies thereof may not be provided
// or otherwise made available to any other person.
//
// U.S. Government Restricted Rights. This computer software: (a) was
// developed at private expense and is in all respects the proprietary
// information of 60East Technologies Inc.; (b) was not developed with
// government funds; (c) is a trade secret of 60East Technologies Inc.
// for all purposes of the Freedom of Information Act; and (d) is a
// commercial item and thus, pursuant to Section 12.212 of the Federal
// Acquisition Regulations (FAR) and DFAR Supplement Section 227.7202,
// Government's use, duplication or disclosure of the computer software
// is subject to the restrictions set forth by 60East Technologies Inc..
//
////////////////////////////////////////////////////////////////////////////
package com.crankuptheamps.client.fields;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.zip.CRC32;
/**
* Field data for a {@link com.crankuptheamps.client.Message} consisting of the bookmark.
* This is the AMPS Bookmark for the Message.
*/
public class BookmarkField extends StringField implements Cloneable
{
/**
* The character used to separate components of a bookmark, and to
* separate bookmarks from each other in a list.
*/
public static final char SEPARATOR_CHAR = '|';
public static final int MAX_BOOKMARK_LENGTH = 42;
public static final int MAX_TIMESTAMP_LENGTH = 24;
public static final int MIN_TIMESTAMP_LENGTH = 10;
/**
* Overrides the base classes' initial default size for the byte and
* char conversion buffers used by this instance. Defaults to 42 for
* this class since bookmark fields are usually no larger than 40 bytes.
*
* @return Returns a default size of 42.
*/
@Override
protected int getConversionBufInitialSize() { return 42; }
/**
* Constructor with specified buffer, position, and length.
* @param buffer The byte array containing the bookmark field.
* @param position The starting position of the bookmark field
* in the buffer.
* @param length The length of the bookmark field.
*/
protected BookmarkField(byte[] buffer, int position, int length)
{
super(buffer, position, length);
}
/**
* Default constructor.
*/
public BookmarkField()
{
}
/**
* Indicates whether this bookmark value appears to be a timestamp.
*
* @return True if the value looks like an AMPS ISO-8601 timestamp.
*/
public boolean isTimestamp()
{
return length >= MIN_TIMESTAMP_LENGTH
&& buffer[position + 8] == (int)'T';
}
/**
* Indicates whether this bookmark value appears to be a range,
* using only a simple check for brackets or parentheses.
*
* @return True if the value looks like a range.
*/
public boolean isRange()
{
if (length >= 5) {
int pos = position;
while (buffer[pos] == ' ') {
if (++pos >= position + length) return false;
}
if (buffer[pos] == '(' || buffer[pos] == '[') {
pos = position + length - 1;
}
while (buffer[pos] == ' ') {
if (--pos <= position) return false;
}
if (buffer[pos] == ')' || buffer[pos] == ']') {
return true;
}
}
return false;
}
/**
* Gets the publisher id for this bookmark.
* @return Returns the publisher id for this bookmark.
*/
public long getPublisherId()
{
if (isTimestamp() || isRange()) return 0;
long result = 0;
for(int i = this.position; i < this.position + this.length; i++)
{
if( this.buffer[i] == (int)SEPARATOR_CHAR )
{
break;
}
result *= 10;
result += this.buffer[i] - 48;
}
return result;
}
/**
* Gets the sequence number for this bookmark.
* @return Returns the sequence number for this bookmark.
*/
public long getSequenceNumber()
{
if (isTimestamp() || isRange()) return 0;
long result = 0;
int i = this.position;
for(; i < this.position + this.length; i++)
{
if( this.buffer[i] == (int)SEPARATOR_CHAR )
{
break;
}
}
for(i = i+1; i < this.position + this.length; i++)
{
if( this.buffer[i] == (int)SEPARATOR_CHAR )
{
break;
}
result *= 10;
result += this.buffer[i] - 48;
}
return result;
}
/**
* Compare two signed long values as unsigned long values;
* the publisherId_ and sequence are signed in java, but the actual values
* are unsigned, so we have to do some work to compare them.
* @param seqLeft_ The value being compared.
* @param seqRight_ The value to compare to.
* @return true if seqLeft_ is less than seqRight_ as unsigned long values.
*/
public static boolean unsignedLongLess(long seqLeft_, long seqRight_)
{
final BigInteger offset = BigInteger.valueOf(Long.MAX_VALUE)
.shiftLeft(1).add(BigInteger.valueOf(2));
if(seqLeft_<0 || seqRight_<0)
{
BigInteger left = offset.add(BigInteger.valueOf(seqLeft_));
BigInteger right = offset.add(BigInteger.valueOf(seqRight_));
return left.compareTo(right) < 0;
}
else
{
return seqLeft_ < seqRight_;
}
}
/**
* Compare two signed long values as unsigned long values;
* the publisherId_ and sequence are signed in java, but the actual values
* are unsigned, so we have to do some work to compare them.
* @param seqLeft_ The value being compared.
* @param seqRight_ The value to compare to.
* @return true if seqLeft_ is less than or equal to seqRight_ as unsigned long values.
*/
public static boolean unsignedLongLessEqual(long seqLeft_, long seqRight_)
{
final BigInteger offset = BigInteger.valueOf(Long.MAX_VALUE)
.shiftLeft(1).add(BigInteger.valueOf(2));
if(seqLeft_<0 || seqRight_<0)
{
BigInteger left = offset.add(BigInteger.valueOf(seqLeft_));
BigInteger right = offset.add(BigInteger.valueOf(seqRight_));
return left.compareTo(right) <= 0;
}
else
{
return seqLeft_ <= seqRight_;
}
}
public boolean isBookmarkList()
{
for (int comma=position; comma parseBookmarkList()
{
ArrayList bookmarks = new ArrayList();
int start = position;
int comma = position;
for ( ; comma start) {
bookmarks.add(new BookmarkField(buffer, start, comma-start));
}
return bookmarks;
}
protected final CRC32 c = new CRC32();
/**
* Calculates the hash code for the bookmark field.
*
* @return The hash code of the bookmark field.
*/
public int hashCode()
{
c.reset();
c.update(buffer, position, length);
return (int)c.getValue();
}
/**
* Provides a way to duplicate this object and retain its specific type (and hashcode() implementation).
*/
public BookmarkField clone()
{
byte[] copy = null;
if (buffer != null) {
copy = new byte[length];
System.arraycopy(buffer, position, copy, 0, length);
}
return new BookmarkField(copy, 0, length);
}
/**
* Override base class's copy() method appropriately, so we don't inadvertently mix
* BookmarkFields and Fields up -- they have different hashCode implementations.
*/
public BookmarkField copy()
{
return clone();
}
/**
* Checks if the bookmark field is equal to another object.
*
* @param object_ The object to compare.
* @return {@code true} if the bookmark field is equal to the specified object, {@code false} otherwise.
*/
@Override
public boolean equals(Object object_)
{
return super.equals(object_);
}
}