doublecmd/components/chsdet/src/nsCodingStateMachine.pas
2012-08-19 15:11:56 +00:00

129 lines
3.6 KiB
ObjectPascal

// +----------------------------------------------------------------------+
// | chsdet - Charset Detector Library |
// +----------------------------------------------------------------------+
// | Copyright (C) 2006, Nick Yakowlew http://chsdet.sourceforge.net |
// +----------------------------------------------------------------------+
// | Based on Mozilla sources http://www.mozilla.org/projects/intl/ |
// +----------------------------------------------------------------------+
// | This library is free software; you can redistribute it and/or modify |
// | it under the terms of the GNU General Public License as published by |
// | the Free Software Foundation; either version 2 of the License, or |
// | (at your option) any later version. |
// | This library is distributed in the hope that it will be useful |
// | but WITHOUT ANY WARRANTY; without even the implied warranty of |
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
// | See the GNU Lesser General Public License for more details. |
// | http://www.opensource.org/licenses/lgpl-license.php |
// +----------------------------------------------------------------------+
//
// $Id: nsCodingStateMachine.pas,v 1.3 2007/05/26 13:09:38 ya_nick Exp $
unit nsCodingStateMachine;
{$R-}
interface
uses
nsCore;
type
nsSMState = (
eStart = 0,
eError = 1,
eItsMe = 2
);
(*state machine model*)
type
SMModel = record
classTable: Pointer; //nsPkgInt;
classFactor: PRUint32;
stateTable: Pointer; //nsPkgInt;
charLenTable: Pointer; // pByteArray; // array of byte; // pPRUint32;
CharsetID: eInternalCharsetID;
end;
pSMModel = ^SMModel;
type
TnsCodingStateMachine = class (TObject)
protected
mCurrentState: nsSMState;
mCurrentCharLen: PRUint32;
mCurrentBytePos: PRUint32;
mModel: SMModel;
public
Enabled: Boolean;
constructor Create(sm: SMModel);
destructor Destroy; override;
function NextState(c: char): nsSMState;
function GetCurrentCharLen: PRUint32;
procedure Reset;
function GetCharsetID: eInternalCharsetID;
property LangModel: SMModel read mModel;
end;
implementation
{ TnsCodingStateMachine }
constructor TnsCodingStateMachine.Create(sm: SMModel);
begin
mCurrentState:= eStart;
mModel := sm;
Enabled := true;
end;
destructor TnsCodingStateMachine.Destroy;
begin
mModel.classTable := nil;
mModel.stateTable := nil;
mModel.charLenTable := nil;
inherited;
end;
function TnsCodingStateMachine.NextState(c: char): nsSMState;
var
byteCls: PRUint32;
begin
if not Enabled then
begin
Result := eError;
exit;
end;
(*for each byte we get its class , if it is first byte, we also get byte length*)
byteCls := pByteArray(mModel.classTable)[integer(c)];
if mCurrentState = eStart then
begin
mCurrentBytePos := 0;
mCurrentCharLen := pByteArray(mModel.charLenTable)[byteCls];
end;
(*from byte's class and stateTable, we get its next state*)
mCurrentState := nsSMState(pByteArray(mModel.stateTable)[cardinal(mCurrentState) * mModel.classFactor + byteCls]);
inc(mCurrentBytePos);
//if mCurrentBytePos > mCurrentCharLen then
// mCurrentState := eError;
Result:= mCurrentState;
end;
function TnsCodingStateMachine.GetCurrentCharLen: PRUint32;
begin
Result:= mCurrentCharLen;
end;
procedure TnsCodingStateMachine.Reset;
begin
mCurrentState:= eStart;
end;
function TnsCodingStateMachine.GetCharsetID: eInternalCharsetID;
begin
Result:= mModel.CharsetID;
end;
end.