1 jls.loader.provide('jls.lang.Struct');
  2 
  3 jls.loader.require('jls.lang.ByteBuffer');
  4 
  5 jls.lang.Struct = jls.lang.Class.create( /** @lends jls.lang.Struct.prototype */
  6 {
  7     /**
  8      * Creates a structure.
  9      * 
 10      * @param {Array} structDef The structure definition.
 11      * @param {jls.lang.ByteBuffer} [buffer] The buffer to use for this structure.
 12      * @constructs
 13      * @class This class represents a structure. A structure specifies the format of a record,
 14      * including the names and types of its members, and the order in which they are stored.
 15      */
 16     initialize : function(structDef, buffer) {
 17         structDef = structDef || [];
 18         this._struct = {};
 19         var position = 0;
 20         for (var i = 0; i < structDef.length; i++) {
 21             var def = structDef[i];
 22             if (! (def.type in jls.lang.Struct.TYPE_SIZE)) {
 23                 throw new jls.lang.Exception('Invalid type ' + def.type);
 24             }
 25             var size = jls.lang.Struct.TYPE_SIZE[def.type];
 26             var length = ('length' in def) ? def.length : 1;
 27             this._struct[def.name] = {
 28                 position: position,
 29                 type: def.type,
 30                 length: length
 31             };
 32             position += size * length;
 33             //jls.logger.warn('Struct() ' + def.name + ', ' + def.type + ', ' + size + ', ' + position);
 34         }
 35         this._size = position;
 36         this._buffer = buffer || jls.lang.ByteBuffer.allocate(this._size);
 37     },
 38     /**
 39      * Returns the buffer.
 40      *
 41      * @returns {jls.lang.ByteBuffer} The buffer.
 42      */
 43     buffer : function() {
 44         return this._buffer;
 45     },
 46     /**
 47      * Returns the size of the struct.
 48      *
 49      * @returns {Number} The size.
 50      */
 51     size : function() {
 52         return this._size;
 53     },
 54     /**
 55      * Gets a field in this structure.
 56      *
 57      * @param {String} name The field name.
 58      * @param {Number} [index] The index of the value to get.
 59      * @returns {Number|String} The field value.
 60      */
 61     get : function(name, index) {
 62         if (! (name in this._struct)) {
 63             throw new jls.lang.Exception('Invalid name ' + name);
 64         }
 65         var d = this._struct[name];
 66         this._buffer.setPosition(d.position);
 67         switch (d.type) {
 68         case 'SignedByte':
 69             return this._buffer.getByte(true);
 70         case 'UnsignedByte':
 71             return this._buffer.getByte(false);
 72         case 'SignedShort':
 73             return this._buffer.getShort(true);
 74         case 'UnsignedShort':
 75             return this._buffer.getShort(false);
 76         case 'SignedInt':
 77             return this._buffer.getInt(true);
 78         case 'UnsignedInt':
 79             return this._buffer.getInt(false);
 80         case 'SignedLong':
 81             return this._buffer.getLong(true);
 82         case 'UnsignedLong':
 83             return this._buffer.getLong(false);
 84         case 'Pointer':
 85             return this._buffer.getPointer();
 86         }
 87     },
 88     /**
 89      * Puts a field in this structure.
 90      *
 91      * @param {String} name The field name.
 92      * @param {Number|String} value The field value to set.
 93      * @param {Number} [index] The index of the value to get.
 94      * @returns {jls.lang.Struct} This structure.
 95      */
 96     put : function(name, value, index) {
 97         if (! (name in this._struct)) {
 98             throw new jls.lang.Exception('Invalid name ' + name);
 99         }
100         //jls.logger.warn('Struct.put("' + name + '", ' + value + ')');
101         var d = this._struct[name]
102         this._buffer.setPosition(d.position);
103         switch (d.type) {
104         case 'SignedByte':
105         case 'UnsignedByte':
106             this._buffer.putByte(value);
107             break;
108         case 'SignedShort':
109         case 'UnsignedShort':
110             this._buffer.putShort(value);
111             break;
112         case 'SignedInt':
113         case 'UnsignedInt':
114             this._buffer.putInt(value);
115             break;
116         case 'SignedLong':
117         case 'UnsignedLong':
118             this._buffer.putLong(value);
119             break;
120         case 'Pointer':
121             this._buffer.putPointer(value);
122             break;
123         }
124         return this;
125     }
126 });
127 
128 Object.extend(jls.lang.Struct, /** @lends jls.lang.Struct */
129 {
130     TYPE_SIZE : {
131         'SignedByte': 1,
132         'UnsignedByte': 1,
133         'SignedShort': 2,
134         'UnsignedShort': 2,
135         'SignedInt': 4,
136         'UnsignedInt': 4,
137         'SignedLong': 8,
138         'UnsignedLong': 8,
139         'Pointer': jls.lang.ByteBuffer.POINTER_SIZE
140     }
141 });
142 
143