* Accuracy ::= SEQUENCE { * seconds INTEGER OPTIONAL, * millis [0] INTEGER (1..999) OPTIONAL, * micros [1] INTEGER (1..999) OPTIONAL * } * * * @package asn1 * @subpackage tsp * * @link http://tools.ietf.org/html/rfc3161#section-2.4.2 RFC 3161: Time-Stamp Protocol */ class TSPAccuracy implements ASN1DEREncodable { private $seconds; private $millis; private $micros; /** * Constructs a new isntance of TSPAccuracy. */ public function __construct() { } /** * Decodes the given ASN1Sequence as TSPAccuracy. * * @throws GTException * @param ASN1Sequence $object TSPAccuracy encoded as ASN1Sequence * @return void */ public function decode($object) { if (!$object instanceof ASN1Sequence) { throw new GTException("Expecting an ASN1Sequence"); } if ($object->getObjectCount() < 1 || $object->getObjectCount() > 3) { throw new GTException("Invalid number of elements in sequence"); } for ($i = 0; $i < $object->getObjectCount(); $i++) { $item = $object->getObjectAt($i); if ($item instanceof ASN1Integer) { if (!is_null($this->seconds)) { throw new GTException("Unexpected ASN1Integer: {$item->getValue()}"); } if ($i != 0) { throw new GTException("Unexpected ASN1Integer: {$item->getValue()}"); } $this->seconds = $item->getValue(); } else if ($item instanceof ASN1Tag) { switch ($item->getTagValue()) { case 0: // millis if (!is_null($this->millis)) { throw new GTException("Unexpected TAG value: 0"); } $millis = $item->getObjectAs(ASN1_TAG_INTEGER); if (!$millis instanceof ASN1Integer) { throw new GTException("Expecting an ASN1Integer"); } if ((int) $millis->getValue() < 1) { throw new GTException("Invalid value for millis: {$millis->getValue()}"); } if ((int) $millis->getValue() > 999) { throw new GTException("Invalid value for millis: {$millis->getValue()}"); } $this->millis = $millis->getValue(); break; case 1: // micros if (!is_null($this->micros)) { throw new GTException("Unexpected TAG value: 1"); } $micros = $item->getObjectAs(ASN1_TAG_INTEGER); if (!$micros instanceof ASN1Integer) { throw new GTException("Expecting an ASN1Integer"); } if ((int) $micros->getValue() < 1) { throw new GTException("Invalid value for micros: {$micros->getValue()}"); } if ((int) $micros->getValue() > 999) { throw new GTException("Invalid value for micros: {$micros->getValue()}"); } $this->micros = $micros->getValue(); default: throw new GTException("Unexpected TAG value: {$item->getTagValue()}"); } } else { throw new GTException("Unexpected ASN1 type: " . get_class($item)); } } } /** * Encodes this TSPAccuracy using DER. * * @return array byte array that contains the DER encoding of this TSPAccuracy */ public function encodeDER() { $sequence = new ASN1Sequence(); if ($this->seconds != null) { $sequence->add(new ASN1Integer($this->seconds)); } if ($this->millis != null) { $tag = new ASN1Tag(); $tag->setExplicit(true); $tag->setTagClass(ASN1_TAG_CONTEXT); $tag->setTagType(ASN1_TAG_CONSTRUCTED); $tag->setTagValue(0); $tag->setObject(new ASN1Integer($this->millis)); $sequence->add($tag); } if ($this->micros != null) { $tag = new ASN1Tag(); $tag->setExplicit(true); $tag->setTagClass(ASN1_TAG_CONTEXT); $tag->setTagType(ASN1_TAG_CONSTRUCTED); $tag->setTagValue(1); $tag->setObject(new ASN1Integer($this->micros)); $sequence->add($tag); } return $sequence->encodeDER(); } /** * Gets this TSPAccuracy formatted as string. * * @return string formatted TSPAccuracy */ public function getFormatted() { $accuracy = new GTBigInteger(0); if (!is_null($this->seconds)) { $accuracy = $accuracy->add(new GTBigInteger($this->seconds)); } $accuracy = $accuracy->mul(new GTBigInteger(1000)); if (!is_null($this->millis)) { $accuracy = $accuracy->add(new GTBigInteger($this->millis)); } $accuracy = $accuracy->mul(new GTBigInteger(1000)); if (!is_null($this->micros)) { $accuracy = $accuracy->add(new GTBigInteger($this->micros)); } $zero = new GTBigInteger(0); if ($accuracy->mod(1000000)->comp($zero) == 0) { return "{$accuracy->div(new GTBigInteger(1000000))->getValue()}s"; } else if ($accuracy->mod(1000)->comp($zero) == 0) { return "{$accuracy->div(new GTBigInteger(1000))->getValue()}ms"; } else { return "{$accuracy->getValue()}us"; } } } ?>