【Delphi】AXMLPrinter ,Android XML

找这个的人肯定知道这是干什么的。没错,我花了半天时间将Java代码改写成了Delphi,在D2007下调试通过。

废话不多说,上代码:

{*******************************************************}
{                                                       }
{       AXMLPrinter (Android XML反编译)                 }
{                                                       }
{       版权所有 (C) 2015 YangYxd                       }
{                                                       }
{*******************************************************}

unit YxdAXMLPrinter;

interface

uses
  SysUtils, Classes;
  
const
  CHUNK_TYPE = $1C0001;
  CHUNK_AXML_FILE = 524291;
  CHUNK_RESOURCEIDS = 524672;
  CHUNK_XML_FIRST = 1048832;
  CHUNK_XML_START_NAMESPACE = 1048832;
  CHUNK_XML_END_NAMESPACE = 1048833;
  CHUNK_XML_START_TAG = 1048834;
  CHUNK_XML_END_TAG = 1048835;
  CHUNK_XML_TEXT = 1048836;
  CHUNK_XML_LAST = 1048836;

const
  RADIX_MULTS: array [0..3] of Double = (
        0.0039063, 3.051758E-005, 1.192093E-007, 4.656613E-010);
    DIMENSION_UNITS: array [0..7] of String = (
        'px', 'dip', 'sp', 'pt', 'in', 'mm', '', '');
    FRACTION_UNITS: array [0..7] of String = (
        '%', '%p', '', '', '', '', '', '');

type
  TIntegers = array of Integer;
type
  TIntReader = class(TObject)
  private
    FStream: TStream;
    FBigEndian: Boolean;
    FPosition: Integer;
  protected
  public
    constructor Create; overload;
    constructor Create(AStream: TStream; bigEndian: Boolean); overload;
    constructor Create(const AFileName: string; bigEndian: Boolean); overload;
    destructor Destroy; override;

    procedure reset(AStream: TStream; bigEndian: Boolean);
    procedure Close();

    function readByte(): ShortInt;
    function readShort(): ShortInt;
    function readInt(): Integer; overload;
    function readInt(ALen: Integer): Integer; overload;
    function readIntArray(ALen: Integer): TIntegers; overload;
    procedure readIntArray(var AData: TIntegers); overload;
    procedure readIntArray(var AData: TIntegers; AOffset, ALen: Integer); overload;
    function readByteArray(ALen: Integer): TBytes;
    procedure skip(bytes: Integer);
    procedure skipInt();
    function available(): Integer;

    property Stream: TStream read FStream;
    property IsBigEndian: Boolean read FBigEndian write FBigEndian;
    property Position: Integer read FPosition write FPosition;
  end;

type
  TStringBlock = class
  private
    FStringOffset: TIntegers;
    FStrings: TIntegers;
    function GetCount: Integer;
    function GetString(index: Integer): string;
  protected
    FStyleOffset: TIntegers;
    FStyles: TIntegers;
  public
    constructor Create(); 
    destructor Destroy; override;
    class function read(reader: TIntReader): TStringBlock;
    function find(const str: string): Integer;
    function getShort(const datas: TIntegers; offset: Integer): Integer;
    property Count: Integer read GetCount;
    property Items[index: Integer]: string read GetString;
  end;

type
  TNamespaceStack = class;
  TXmlPullParser = class(TObject)
  private
    m_operational: Boolean;
    m_strings: TStringBlock;
    m_reader: TIntReader;
    m_resourceIDs: TIntegers;
    m_namespaces: TNamespaceStack;
    m_decreaseDepth: Boolean;
    m_event: Integer;
    m_lineNumber: Integer;
    m_name: Integer;
    m_namespaceUri: Integer;
    m_attributes: TIntegers;
    m_idAttribute: Integer;
    m_classAttribute: Integer;
    m_styleAttribute: Integer;

    procedure doNext();
  protected
  public
    constructor Create; virtual;
    destructor Destroy; override;

    procedure Open(AStream: TStream); overload;
    procedure Open(const AFileName: string); overload;
    procedure Close();

    class function getPackage(id: Integer): string;
    class function complexToFloat(complex: Integer): Double;

    // 读取 APK 文件中zip解压后的 AndroidManifest.xml 文件获取基本
    // 信息 (包名、版本名称、版本代码)
    class function ReadAndroidManifestFile(const AFileName: string;
      var packageName, versionName: string; var versionCode: Integer): Boolean; overload;
    // 读取 APK 文件中zip解压后的 AndroidManifest.xml 文件获取基本
    // 信息 (包名、版本名称、版本代码)
    class function ReadAndroidManifestFile(AStream: TStream;
      var packageName, versionName: string; var versionCode: Integer): Boolean; overload;

    function next(): Integer;
    function nextToken(): Integer;
    function nextTag(): Integer;
    function nextText(): string;
    procedure require(atype: Integer; const namespace, name: string);
    function getDepth(): Integer;
    function getEventType(): Integer;
    function getLineNumber(): Integer;
    function getName(): string;
    function getText(): string;
    function getNamespace(): string;
    function getPrefix(): string;
    function getPositionDescription(): string;
    function getNamespaceCount(depth: Integer): Integer;
    function getNamespacePrefix(apos: Integer): string;
    function getNamespaceUri(apos: Integer): string;
    function getClassAttribute(): string;
    function getIdAttribute(): string;
    function getIdAttributeResourceValue(defaultValue: Integer = 0): Integer;
    function getStyleAttribute(): Integer;
    function getAttributeCount(): Integer;
    function getAttributeNamespace(index: Integer): string;
    function getAttributePrefix(index: Integer): string;
    function getAttributeName(index: Integer): string;
    function getAttributeNameResource(index: Integer) :Integer;
    function getAttributeValueType(index: Integer): Integer;
    function getAttributeValueData(index: Integer): Integer;
    function getAttributeValue(index: Integer): string; overload;
    function getAttributeBooleanValue(index: Integer; defaultValue: Boolean = false): Boolean; overload;
    function getAttributeFloatValue(index: Integer; defaultValue: Double = 0): Double; overload;
    function getAttributeIntValue(index: Integer; defaultValue: Integer = 0): Integer; overload;
    function getAttributeUnsignedIntValue(index: Integer; defaultValue: Cardinal = 0): Cardinal; overload;
    function getAttributeResourceValue(index: Integer; defaultValue: Integer = 0): Integer; overload;
    function getAttributeValue(const namespace, attribute: string): string; overload;
    function getAttributeBooleanValue(const namespace, attribute: string; defaultValue: Boolean = False): Boolean; overload;
    function getAttributeFloatValue(const namespace, attribute: string; defaultValue: Double = 0): Double; overload;
    function getAttributeIntValue(const namespace, attribute: string; defaultValue: Integer = 0): Integer; overload;
    function getAttributeUnsignedIntValue(const namespace, attribute: string; defaultValue: Cardinal = 0): Cardinal; overload;
    function getAttributeResourceValue(const namespace, attribute: string; defaultValue: Integer = 0): Integer; overload;
    function getAttributeListValue(index: Integer; options: array of string; defaultValue: Integer = 0): Integer; overload;
    function getAttributeListValue(const namespace, attribute: string; options: array of string; defaultValue: Integer = 0): Integer; overload;
    function getAttributeType(index: Integer): string;
    function isAttributeDefault(index: Integer): Boolean;
    function getInputEncoding(): string;
    function getColumnNumber(): Integer;
    function isEmptyElementTag(): Boolean;
    function isWhitespace(): Boolean;
    function getProperty(const name: string): TObject;
    function getFeature(const feature: string): Boolean;
    function getStrings(): TStringBlock;
    function getAttributeOffset(index: Integer): Integer;
    function findAttribute(const namespace, attribute: string): Integer;
    function getAttributeValueEx(index: Integer): string;

    procedure resetEventInfo();
  end;

  TNamespaceStack = class
  private
    m_data: TIntegers;
    m_dataLength, m_count, m_depth: Integer;
  public
    constructor Create;
    procedure reset();
    function getTotalCount(): Integer;
    function getCurrentCount(): Integer;
    function getAccumulatedCount(depth: Integer): Integer;
    procedure push(prefix, uri: Integer);
    function pop(prefix, uri: Integer): Boolean; overload;
    function pop(): Boolean; overload;
    function getPrefix(index: Integer): Integer;
    function getUri(Index: Integer): Integer;
    function findPrefix(uri: Integer): Integer;
    function findUri(prefix: Integer): Integer;
    function getDepth(): Integer;
    procedure increaseDepth();
    procedure decreaseDepth();
    procedure ensureDataCapacity(capacity: Integer);
    function find(prefixOrUri: Integer; prefix: Boolean): Integer;
    function get(index: Integer; prefix: Boolean): Integer;      
  end;

procedure readCheckType(reader: TIntReader; expectedType: Integer);

implementation

resourcestring
  CS_EOFException = 'EOF Exception.';
  CS_IllegalArgumentException = 'Illegal Argument Exception.';

const
  NO_NAMESPACE = '';
  START_DOCUMENT = 0;
  END_DOCUMENT = 1;
  START_TAG = 2;
  END_TAG = 3;
  TEXT = 4;
  CDSECT = 5;
  ENTITY_REF = 6;
  IGNORABLE_WHITESPACE = 7;
  PROCESSING_INSTRUCTION = 8;
  COMMENT = 9;
  DOCDECL = 10;
  TYPES: array [0..10] of string = (
    'START_DOCUMENT',
    'END_DOCUMENT',
    'START_TAG',
    'END_TAG',
    'TEXT',
    'CDSECT',
    'ENTITY_REF',
    'IGNORABLE_WHITESPACE',
    'PROCESSING_INSTRUCTION',
    'COMMENT',
    'DOCDECL');

const
  FEATURE_PROCESS_NAMESPACES = 'http://xmlpull.org/v1/doc/features.html#process-namespaces';
  FEATURE_REPORT_NAMESPACE_ATTRIBUTES = 'http://xmlpull.org/v1/doc/features.html#report-namespace-prefixes';
  FEATURE_PROCESS_DOCDECL = 'http://xmlpull.org/v1/doc/features.html#process-docdecl';
  FEATURE_VALIDATION = 'http://xmlpull.org/v1/doc/features.html#validation';

const
  E_NOT_SUPPORTED = 'Method is not supported.';
  ATTRIBUTE_IX_NAMESPACE_URI = 0;
  ATTRIBUTE_IX_NAME = 1;
  ATTRIBUTE_IX_VALUE_STRING = 2;
  ATTRIBUTE_IX_VALUE_TYPE = 3;
  ATTRIBUTE_IX_VALUE_DATA = 4;
  ATTRIBUTE_LENGHT = 5;

procedure readCheckType(reader: TIntReader; expectedType: Integer);
var
  atype: Integer;
begin
  atype := reader.readInt;
  if atype <> expectedType then
    raise Exception.Create('Expected chunk of type 0x' + IntToHex(expectedType, 6) +
      ', read 0x' + IntToHex(atype, 6) + '.');
end;

procedure MoveMemory(Destination: Pointer; Source: Pointer; Length: Cardinal); inline;
begin
  Move(Source^, Destination^, Length);
end;

{ TIntReader }

。。。

下载地址: http://pan.baidu.com/s/1sjK895r 密码: aq7c

如发现有Bug,请记录在这里留言告诉我。