1 // Copyright (C) 2007  Harlan Iverson <h.iverson at gmail.com>
  2 //
  3 // This program is free software; you can redistribute it and/or
  4 // modify it under the terms of the GNU General Public License
  5 // as published by the Free Software Foundation; either version 2
  6 // of the License, or (at your option) any later version.
  7 //
  8 // This program is distributed in the hope that it will be useful,
  9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 11 // GNU General Public License for more details.
 12 //
 13 // You should have received a copy of the GNU General Public License
 14 // along with this program; if not, write to the Free Software
 15 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 16 
 17 
 18 
 19 
 20 
 21 
 22 /**
 23  * Implements a key sequence as described by XEP-0124, section 15.
 24  * @see #_initKeys
 25  * @constructor
 26  */
 27 function KeySequence(length) {
 28     this._keys = [];
 29     this._idx = null;
 30     this._seed = null;
 31     
 32 	this._initKeys( length );	
 33 }
 34 
 35 KeySequence.prototype = {
 36 	/**
 37 	 * Get the next key in the sequence, or throw an error if there are 
 38 	 * none left (since keys are pre-generated).
 39 	 * @return {String} 
 40 	 */
 41 	getNextKey: function() { 
 42 		if( this._idx < 0 ) {
 43 			// TODO throw some kind of error
 44 			return null;
 45 		}
 46 		return this._keys[this._idx--]; 
 47 	},
 48 	
 49 	/**
 50 	 * Returns true if this is the last key in the sequence. A new
 51 	 * sequence will need to be generated. This is the responsibility
 52 	 * of the user of the class at this point.
 53 	 */
 54 	isLastKey: function() { 
 55 		return (this._idx == 0); 
 56 	},
 57 	
 58 	/**
 59 	 * Returns true if this is the first key in a new sequence.
 60 	 */
 61 	isFirstKey: function() {
 62 		return (this._idx == this.getSize() - 1);
 63 	},
 64 	
 65 	/**
 66 	 * Get the size of the key sequence.
 67 	 */
 68 	getSize: function() { 
 69 		return this._keys.length; 
 70 	},
 71 	
 72 	reset: function() {
 73 		this._initKeys( this.getSize() );
 74 	},
 75 
 76     /**
 77      * Initialize a list of keys to use for requests.
 78      */
 79 	_initKeys: function(length) {
 80 		this._keys = [];
 81 		this._seed = this._createNewSeed();
 82 		this._idx = length - 1;
 83 	
 84 		var prevKey = this._seed;
 85 		for (var i = 0; i < length; i++) {
 86 			this._keys[i] = this._hash(prevKey);
 87 			prevKey = this._keys[i];
 88 		}
 89 	},
 90 
 91 	/**
 92 	 * Return a seed to use for generating a new sequence of keys.
 93 	 * Currently implemented to use Math.random().
 94 	 */
 95 	_createNewSeed: function() {
 96 		return Math.random();
 97 	},
 98 	
 99 	/**
100 	 * Used to hash the value of each key. Spec says it must be sha1-hex,
101 	 * so that's what it used.
102 	 */
103 	_hash: function( value ) {
104 		return hex_sha1( value );
105 	}
106 }
107