123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- {
- $Id$
- This file is part of the Free Pascal run time library.
- Copyright (c) 2000 by Florian Klaempfl
- member of the Free Pascal development team.
- This unit implements several classes for charset conversions
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
- This program 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.
- **********************************************************************}
- {$mode objfpc}
- unit charset;
- interface
- type
- tunicodechar = word;
- tunicodestring = ^tunicodechar;
- tcsconvert = class
- // !!!!!!1constructor create;
- end;
- tunicodecharmappingflag = (umf_noinfo,umf_leadbyte,umf_undefined,
- umf_unused);
- punicodecharmapping = ^tunicodecharmapping;
- tunicodecharmapping = record
- unicode : tunicodechar;
- flag : tunicodecharmappingflag;
- reserved : byte;
- end;
- punicodemap = ^tunicodemap;
- tunicodemap = record
- cpname : shortstring;
- map : punicodecharmapping;
- lastchar : longint;
- next : punicodemap;
- internalmap : boolean;
- end;
- tcp2unicode = class(tcsconvert)
- end;
- function loadunicodemapping(const cpname,f : string) : punicodemap;
- procedure registermapping(p : punicodemap);
- implementation
- var
- mappings : punicodemap;
- function loadunicodemapping(const cpname,f : string) : punicodemap;
- var
- data : punicodecharmapping;
- datasize : longint;
- t : text;
- s,hs : string;
- scanpos,charpos,unicodevalue : longint;
- code : word;
- flag : tunicodecharmappingflag;
- p : punicodemap;
- lastchar : longint;
- begin
- lastchar:=-1;
- loadunicodemapping:=nil;
- datasize:=256;
- getmem(data,sizeof(tunicodecharmapping)*datasize);
- assign(t,f);
- {$I-}
- reset(t);
- {$I+}
- if ioresult<>0 then
- begin
- freemem(data,sizeof(tunicodecharmapping)*datasize);
- exit;
- end;
- readln(t,s);
- while not(eof(t)) do
- begin
- if (s[1]='0') and (s[2]='x') then
- begin
- flag:=umf_unused;
- scanpos:=3;
- hs:='$';
- while s[scanpos] in ['0'..'9','A'..'F','a'..'f'] do
- begin
- hs:=hs+s[scanpos];
- inc(scanpos);
- end;
- val(hs,charpos,code);
- if code<>0 then
- begin
- freemem(data,sizeof(tunicodecharmapping)*datasize);
- close(t);
- exit;
- end;
- while not(s[scanpos] in ['0','#']) do
- inc(scanpos);
- if s[scanpos]='#' then
- begin
- { special char }
- unicodevalue:=$ffff;
- hs:=copy(s,scanpos,length(s)-scanpos+1);
- if hs='#DBCS LEAD BYTE' then
- flag:=umf_leadbyte;
- end
- else
- begin
- { C hex prefix }
- inc(scanpos,2);
- hs:='$';
- while s[scanpos] in ['0'..'9','A'..'F','a'..'f'] do
- begin
- hs:=hs+s[scanpos];
- inc(scanpos);
- end;
- val(hs,unicodevalue,code);
- if code<>0 then
- begin
- freemem(data,sizeof(tunicodecharmapping)*datasize);
- close(t);
- exit;
- end;
- if charpos>datasize then
- begin
- { allocate 1024 bytes more because }
- { if we need more than 256 entries it's }
- { probably a mbcs with a lot of }
- { entries }
- datasize:=charpos+1024;
- reallocmem(data,sizeof(tunicodecharmapping)*datasize);
- end;
- flag:=umf_noinfo;
- end;
- data[charpos].flag:=flag;
- data[charpos].unicode:=unicodevalue;
- if charpos>lastchar then
- lastchar:=charpos;
- end;
- readln(t,s);
- end;
- close(t);
- new(p);
- p^.lastchar:=lastchar;
- p^.cpname:=cpname;
- p^.internalmap:=false;
- p^.next:=nil;
- p^.map:=data;
- loadunicodemapping:=p;
- end;
- procedure registermapping(p : punicodemap);
- begin
- p^.next:=mappings;
- mappings:=p;
- end;
- var
- hp : punicodemap;
- initialization
- mappings:=nil;
- finalization
- while assigned(mappings) do
- begin
- hp:=mappings^.next;
- if not(mappings^.internalmap) then
- begin
- freemem(mappings^.map);
- dispose(mappings);
- end;
- mappings:=hp;
- end;
- end.
- {
- $Log$
- Revision 1.1 2000-08-17 07:29:39 florian
- + initial revision
- }
|