unit _netconst;

interface

uses
  SysUtils,Types,Classes;

type
  TNetworkProgressStart=procedure (msg:string) of Object;
  TNetworkProgressRefresh=procedure (RefStatus,RefProgress:boolean;Status:string;Size,Pos:integer) of Object;
  TNetworkProgressEnd=procedure of Object;

// for Analizer
const DateMin=37469; // 2002-08-01
var
  DateMax:integer;

type
  TNeedFile=record
    Port:integer;
    Host:string;
    BufferSize:integer;
    URL:string;
    UserAgent:string;
    WriteFileSize:integer; // 0で常時チェック無効
    WriteFileCheckSum:dword; // $00000000で常時チェック無効
    WriteFilename:string; // 空文字列でBufferに保持のみ
  end;

type
  TUPD=record
    Application:string;
    Version,LastVersion:single;
    UserAgent:string;
    Host:string;
    Port:integer;
    HomePageURL,UpdateURL,ArchiveURL,LastArchiveURL:string;
    WindowClass,WindowTitle:string;
    UpdateText:string;
  end;

type
  TCFG=record
    Application:string;
    Version:single;
    UserAgent:string;
    HomePageURL,BBSURL,SkinUploadBBSURL:string;
    Host:string;
    Port:integer;
    UpdateURL:string;
    BasePath:string;
    MXDRV_PDXURL,FMPPMD_PCMURL:string;
    CatalogDataSize:dword;
    //---
    CatalogURL,CatalogBasePath,CatalogSeek,RankingURL,RankingPath:string;
    MXDRV_PDXPath,FMPPMD_PCMPath:string;
    MusicPath:string;
    PCMFileListURL,PCMFileListFilename:string;
    VoteSendURL:string;
    VoteDataURL,VoteDataFilename:string;
  end;

const SocketVersion='0.1b';
const NetCachePath='NetCache213\';

const HT:char=char($09);
const CR:char=char($0d);
const LF:char=char($0a);
const SP:char=char($20);
const CRLF:string=char($0d)+char($0a);

const ResultUserWait=-2;
const ResultNowProcess=-1;
const ResultSuccess=0;
const ResultFileSizeMismatch=1;
const ResultFlleCheckSumMismatch=2;
const ResultFileTransferError=3;
const ResultTimeout=4;
const Result404Error=5;
const ResultSocketError=6;
const ResultNetworkError=255;

const hsNoError                =0;
const hmNoError                ='';
const hsErrorResponse          =1;
const hmErrorResponse          ='HTTP/???';
const hsAddressInUse           =10048;
const hmAddressInUse           ='アドレスが使用中です。';
const hsAddressNotAvailable    =10049;
const hmAddressNotAvailable    ='アドレスを取得できません。';
const hsNetworkSubsystemFailed =10050;
const hmNetworkSubsystemFailed ='ネットワークサブシステムが失敗しました。';
const hsNetworkUnreachable     =10051;
const hmNetworkUnreachable     ='ネットワークにアクセスできません。';
const hsNetReset               =10052;
const hmNetReset               ='接続のタイムアウトが発生しました。';
const hsConnectAborted         =10053;
const hmConnectAborted         ='接続処理が中止されました。';
const hsConnectionReset        =10054;
const hmConnectionReset        ='接続がリモート側からリセットされました。';
const hsAlreadyConnected       =10056;
const hmAlreadyConnected       ='ソケットは既に接続されています。';
const hsNotConnected           =10057;
const hmNotConnected           ='ソケットは接続されていません。';
const hsSocketShutdown         =10058;
const hmSocketShutdown         ='ソケットは終了しています。';
const hsTimedout               =10060;
const hmTimedout               ='ソケットは終了しました。';
const hsConnectionRefused      =10061;
const hmConnectionRefused      ='接続は拒否されました。';
const hsHostDown               =10064;
const hmHostDown               ='ホストがダウンしています。';
const hsHostUnreach            =10065;
const hmHostUnreach            ='ホストへのルートが存在しません。';
const hsProcessLimit           =10067;
const hmProcessLimit           ='プロセスが多すぎます。';
const hsNotReady               =10091;
const hmNotReady               ='通信するための準備ができていません。';
const hsVersionNotSupported    =10092;
const hmVersionNotSupported    ='指定されたバージョンがサポートされていません。';
const hsNotInitialized         =10093;
const hmNotInitialized         ='Wsock32.dll が初期化されていません。';
const hsHostNotFound           =11001;
const hmHostNotFound           ='ホストが見つかりません。';
const hsHostNotFoundTryAgain   =11002;
const hmHostNotFoundTryAgain   ='ホストが見つかりません。';
const hsNonRecoverableError    =11003;
const hmNonRecoverableError    ='回復不能なエラーです。';
const hsNoData                 =11004;
const hmNoData                 ='データがありません。';

function ConvPath2URL(BasePath,path:string):string;
function ConvURL2Filename(url:string):string;
function ConvDecordPercent(url:string):string;
function GetNetworkErrorMessage(NetworkErrorCode:integer):string;
function GetCheckSum(const buf:array of byte;const count:integer):dword;
procedure LoadUPDfromFile(var UPD:TUPD;UPDFilename:string);
procedure LoadUPDfromBuffer(var UPD:TUPD;const buf:array of byte;const count:integer);
procedure LoadCFGfromFile(var CFG:TCFG;CFGFilename:string);
procedure LoadCFGfromBuffer(var CFG:TCFG;const buf:array of byte;const count:integer);

implementation

function ConvPath2URL(BasePath,path:string):string;
var
  url:string;
  pos:integer;
begin
  url:=copy(path,4,255); // '#:\'を外す

  while (ansipos('\',url)<>0) do begin
    pos:=ansipos('\',url);
    url[pos]:='/';
  end;

  while (ansipos(' ',url)<>0) do begin
    pos:=ansipos(' ',url);
    url:=copy(url,1,pos-1)+'%20'+copy(url,pos+1,255);
  end;

  while (ansipos('#',url)<>0) do begin
    pos:=ansipos('#',url);
    url:=copy(url,1,pos-1)+'%23'+copy(url,pos+1,255);
  end;

  result:=BasePath+url;
end;

function ConvURL2Filename(url:string):string;
var
  pos:integer;
begin
  while (ansipos('/',url)<>0) do begin
    pos:=ansipos('/',url);
    url[pos]:='\';
  end;

  while (ansipos('\\',url)<>0) do begin
    pos:=ansipos('\\',url);
    url:=copy(url,1,pos-1)+'\'+copy(url,pos+2,255);
  end;

  if copy(url,1,1)='\' then url:=copy(url,2,length(url));

  result:=url;
end;

function ConvDecordPercent(url:string):string;
var
  pos:integer;
begin
  while (ansipos('%20',url)<>0) do begin
    pos:=ansipos('%20',url);
    url:=copy(url,1,pos-1)+' '+copy(url,pos+3,255);
  end;

  while (ansipos('%23',url)<>0) do begin
    pos:=ansipos('%23',url);
    url:=copy(url,1,pos-1)+'#'+copy(url,pos+3,255);
  end;

  result:=url;
end;

function GetNetworkErrorMessage(NetworkErrorCode:integer):string;
begin
  case NetworkErrorCode of
    hsAddressInUse:           Result:=hmAddressInUse;
    hsAddressNotAvailable:    Result:=hmAddressNotAvailable;
    hsNetworkSubsystemFailed: Result:=hmNetworkSubsystemFailed;
    hsNetworkUnreachable:     Result:=hmNetworkUnreachable;
    hsNetReset:               Result:=hmNetReset;
    hsConnectAborted:         Result:=hmConnectAborted;
    hsConnectionReset:        Result:=hmConnectionReset;
    hsAlreadyConnected:       Result:=hmAlreadyConnected;
    hsNotConnected:           Result:=hmNotConnected;
    hsSocketShutdown:         Result:=hmSocketShutdown;
    hsTimedout:               Result:=hmTimedout;
    hsConnectionRefused:      Result:=hmConnectionRefused;
    hsHostDown:               Result:=hmHostDown;
    hsHostUnreach:            Result:=hmHostUnreach;
    hsProcessLimit:           Result:=hmProcessLimit;
    hsNotReady:               Result:=hmNotReady;
    hsVersionNotSupported:    Result:=hmVersionNotSupported;
    hsNotInitialized:         Result:=hmNotInitialized;
    hsHostNotFound:           Result:=hmHostNotFound;
    hsHostNotFoundTryAgain:   Result:=hmHostNotFoundTryAgain;
    hsNonRecoverableError:    Result:=hmNonRecoverableError;
    hsNoData:                 Result:=hmNoData;
    else
    Result:=hmNoData;
  end;
end;

function GetCheckSum(const buf:array of byte;const count:integer):dword;
var
  cnt:integer;
begin
  result:=0;

  for cnt:=0 to count-1 do begin
    inc(result,buf[cnt]);
    result:=result and $7fffffff; // 実効31bit
  end;
end;

procedure LoadUPDfromFile(var UPD:TUPD;UPDFilename:string);
var
  BufferCount:integer;
  Buffer:array of byte;
  fs:TFileStream;
begin
  fs:=TFileStream.Create(UPDFilename,fmOpenRead	or fmShareDenyWrite);
  BufferCount:=fs.Size;
  SetLength(Buffer,BufferCount+1);
  fs.ReadBuffer(Buffer[0],BufferCount);
  fs.Free;

  LoadUPDFromBuffer(UPD,Buffer,BufferCount);
end;

procedure LoadUPDfromBuffer(var UPD:TUPD;const buf:array of byte;const count:integer);
var
  cnt:integer;
  txt:string;
  str:TStrings;
begin
  txt:='';
  for cnt:=0 to count-1 do begin
    txt:=txt+char(buf[cnt]);
  end;

  str:=TStringList.Create;
  str.Text:=txt;
  with UPD do begin
    Application:=str.Values['Application'];
    Version:=StrToFloatDef(str.Values['Version'],-1);
    LastVersion:=StrToFloatDef(str.Values['LastVersion'],-1);
    UserAgent:=str.Values['UserAgent'];
    HomePageURL:=str.Values['HomePageURL'];
    Host:=str.Values['Host'];
    Port:=StrToIntDef(str.Values['Port'],11080);
    UpdateURL:=str.Values['UpdateURL'];
    ArchiveURL:=str.Values['ArchiveURL'];
    LastArchiveURL:=str.Values['LastArchiveURL'];
    WindowClass:=str.Values['WindowClass'];
    WindowTitle:=str.Values['WindowTitle'];
    UpdateText:=str.Values['UpdateText'];
  end;
  str.Free;
end;

procedure LoadCFGfromFile(var CFG:TCFG;CFGFilename:string);
var
  BufferCount:integer;
  Buffer:array of byte;
  fs:TFileStream;
begin
  fs:=TFileStream.Create(CFGFilename,fmOpenRead or fmShareDenyWrite);
  BufferCount:=fs.Size;
  SetLength(Buffer,BufferCount+1);
  fs.ReadBuffer(Buffer[0],BufferCount);
  fs.Free;

  LoadCFGFromBuffer(CFG,Buffer,BufferCount);
end;

procedure LoadCFGfromBuffer(var CFG:TCFG;const buf:array of byte;const count:integer);
var
  cnt:integer;
  txt:string;
  str:TStrings;
begin
  txt:='';
  for cnt:=0 to count-1 do begin
    txt:=txt+char(buf[cnt]);
  end;

  str:=TStringList.Create;
  str.Text:=txt;
  with CFG do begin
    Application:=str.Values['Application'];
    Version:=StrToFloatDef(str.Values['Version'],-1);
    UserAgent:=str.Values['UserAgent'];
    HomePageURL:=str.Values['HomePageURL'];
    BBSURL:=str.Values['BBSURL'];
    SkinUploadBBSURL:=str.Values['SkinUploadBBSURL'];
    Host:=str.Values['Host'];
    Port:=StrToIntDef(str.Values['Port'],11080);
    UpdateURL:=str.Values['UpdateURL'];
    BasePath:=str.Values['BasePath'];
    MXDRV_PDXURL:=str.Values['MXDRV_PDXURL'];
    FMPPMD_PCMURL:=str.Values['FMPPMD_PCMURL'];
    CatalogDataSize:=StrToIntDef(str.Values['CatalogDataSize'],0);
  end;
  str.Free;
end;

end.



