hackedteam/rcs-console

View on GitHub
src/jp/shichiseki/exif/IFDEntry.as

Summary

Maintainability
Test Coverage
package jp.shichiseki.exif {
    import flash.utils.ByteArray;
    /**
     * The IFDEntry class is an entry in an IFD. The IFDEntry class contains type, name, id
     * and data of the entry.
     */
    public class IFDEntry {
        private static const TAG_TYPES:Object = {
            1: {name:"BYTE", size:1, reader: readByteHandler},
            2: {name:"ASCII", size:1, reader: readStringHandler},
            3: {name:"SHORT", size:2, reader: readShortHandler},
            4: {name:"LONG", size:4, reader: readLongHandler},
            5: {name:"RATIONAL", size:8, reader: readRationalHandler},
            7: {name:"UNDEFINED", size:1, reader: readByteHandler},
            9: {name:"SLONG", size:4, reader: readSLongHandler},
            10: {name:"SRATIONAL", size:8, reader: readSRationalHandler}
        };

        private var _tagID:uint;

        /**
         * Indicates the tagID of this entry.
         */
        public function get tagID():uint { return _tagID; }

        private var _tag:XMLList;
        /**
         *Indicates the tag of this entry.
         */
        public function get tag():XMLList { return _tag; }

        private var _tagName:String;
        /**
         * Indicates the tag name of this entry.
         */
        public function get tagName():String { return tag.@field_name.toString() || _tagName }

        private var _typeID:uint;
        /**
         * Indicates the type ID of this entry.
         */
        public function get typeID():uint { return _typeID; }

        private var _type:Object;
        /**
         * Indicates the type of this entry.
         */
        public function get type():Object { return _type; }

        private var _data:Object;
        /**
         * Indicates the data of this entry.
         */
        public function get data():Object { return _data; }
        private var _numData:uint;

        /**
         * Constructor.
         */
        public function IFDEntry(stream:ByteArray, tagSet:XML, offset:uint) {
            var nextPosition:uint;

            _tagID = stream.readUnsignedShort();
            _tag = tagSet.tag.(parseInt(@id, 16) == tagID);
            _tagName = "0x" + _tagID.toString(16);
            if (!tag.@field_name.toString())
                _tagName = "UnknownTag_" + _tagName;
            _typeID = stream.readUnsignedShort();
            _type = TAG_TYPES[_typeID];
            _numData = stream.readUnsignedInt();
            nextPosition = stream.position + 4;

            if (!type) {
                trace("unrecognizable tag id=" + tagID + " type=" + typeID);
                _data = null;
            } else {
                if (_numData * type.size > 4)
                    stream.position = stream.readUnsignedInt() + offset;
                readContent(stream);
            }
                
            stream.position = nextPosition;
        }

        private function readContent(stream:ByteArray):void {
            if (_typeID == 2) {
                _data = readStringHandler(stream, _numData);
            } else if (_numData == 1) {
                _data = type.reader(stream);
            } else {
                _data = new Array();
                for (var i:uint = 0; i < _numData; i++) {
                    _data.push(type.reader(stream));
                }
            }
        }
    
        private static function readStringHandler(stream:ByteArray, length:uint):String {
      return stream.readUTFBytes(length);
    }

    private static function readByteHandler(stream:ByteArray):uint {
      return stream.readUnsignedByte();
    }

    private static function readShortHandler(stream:ByteArray):uint {
      return stream.readUnsignedShort();
    }

    private static function readLongHandler(stream:ByteArray):uint {
      return stream.readUnsignedInt();
    }

    private static function readSLongHandler(stream:ByteArray):int {
      return stream.readInt();
    }

    private static function readRationalHandler(stream:ByteArray):Number {
      var denominator:uint = stream.readUnsignedInt();
      var numerator:uint = stream.readUnsignedInt();
      return Number(denominator) / Number(numerator);
    }

    private static function readSRationalHandler(stream:ByteArray):Number {
      var denominator:int = stream.readInt();
      var numerator:int = stream.readInt();
      return Number(denominator) / Number(numerator);
    }
    }
}