utility.pas 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2016 by Free Pascal development team
  4. utility.library functions for Amiga OS 4.x
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. {$PACKRECORDS 2}
  12. {$IFNDEF FPC_DOTTEDUNITS}
  13. unit utility;
  14. {$ENDIF FPC_DOTTEDUNITS}
  15. interface
  16. {$IFDEF FPC_DOTTEDUNITS}
  17. uses
  18. Amiga.Core.Exec;
  19. {$ELSE FPC_DOTTEDUNITS}
  20. uses
  21. exec;
  22. {$ENDIF FPC_DOTTEDUNITS}
  23. type
  24. PClockData = ^TClockData;
  25. TClockData = record
  26. sec: Word; // 0..59
  27. min: Word; // 0..59
  28. hour: Word; // 0..23
  29. mday: Word; // 1..31
  30. month: Word; // 1..12
  31. year: Word; // 1978..
  32. wday: Word; // 0..6; 0 = Sunday
  33. end;
  34. // PHook/THook relocated to Exec
  35. // Namespace definitions
  36. type
  37. // The named object structure
  38. PNamedObject = ^TNamedObject;
  39. TNamedObject = record
  40. no_Object: APTR; // Your pointer, for whatever you want
  41. end;
  42. const
  43. // Tags for AllocNamedObject()
  44. // enAllocNamedObjectTags
  45. ANO_NameSpace = 4000; // Tag to define namespace
  46. ANO_UserSpace = 4001; // tag to define userspace
  47. ANO_Priority = 4002; // tag to define priority
  48. ANO_Flags = 4003; // tag to define flags
  49. // Flags for tag ANO_Flags
  50. // enANOFlagBits
  51. NSB_NODUPS = 0;
  52. NSB_CASE = 1;
  53. // enANOFlags
  54. NSF_NODUPS = 1 shl NSB_NODUPS; // Default allow duplicates
  55. NSF_CASE = 1 shl NSB_CASE; // Default to caseless...
  56. { Control attributes for Pack/UnpackStructureTags() }
  57. { PackTable definition:
  58. *
  59. * The PackTable is a simple array of LONGWORDS that are evaluated by
  60. * PackStructureTags() and UnpackStructureTags().
  61. *
  62. * The table contains compressed information such as the tag offset from
  63. * the base tag. The tag offset has a limited range so the base tag is
  64. * defined in the first longword.
  65. *
  66. * After the first longword, the fields look as follows:
  67. *
  68. * +--------- 1 = signed, 0 = unsigned (for bits, 1=inverted boolean)
  69. * |
  70. * | +------ 00 = Pack/Unpack, 10 = Pack, 01 = Unpack, 11 = special
  71. * | / \
  72. * | | | +-- 00 = Byte, 01 = Integer, 10 = Long, 11 = Bit
  73. * | | | / \
  74. * | | | | | /----- For bit operations: 1 = TAG_EXISTS is TRUE
  75. * | | | | | |
  76. * | | | | | | /-------------------- Tag offset from base tag value
  77. * | | | | | | | \
  78. * m n n o o p q q q q q q q q q q r r r s s s s s s s s s s s s s
  79. * \ | | |
  80. * Bit offset (for bit operations) ----/ | |
  81. * \ |
  82. * Offset into data structure -----------------------------------/
  83. *
  84. * A -1 longword signifies that the next longword will be a new base tag
  85. *
  86. * A 0 longword signifies that it is the end of the pack table.
  87. *
  88. * What this implies is that there are only 13-bits of address offset
  89. * and 10 bits for tag offsets from the base tag. For most uses this
  90. * should be enough, but when this is not, either multiple pack tables
  91. * or a pack table with extra base tags would be able to do the trick.
  92. * The goal here was to make the tables small and yet flexible enough to
  93. * handle most cases.
  94. }
  95. const
  96. PSTB_SIGNED = 31;
  97. PSTB_UNPACK = 30; // Note that these are active low...
  98. PSTB_PACK = 29; // Note that these are active low...
  99. PSTB_EXISTS = 26; // Tag exists bit true flag hack...
  100. PSTF_SIGNED = 1 shl PSTB_SIGNED;
  101. PSTF_UNPACK = 1 shl PSTB_UNPACK;
  102. PSTF_PACK = 1 shl PSTB_PACK;
  103. PSTF_EXISTS = 1 shl PSTB_EXISTS;
  104. // *********************************************************************
  105. PKCTRL_PACKUNPACK = $00000000;
  106. PKCTRL_PACKONLY = $40000000;
  107. PKCTRL_UNPACKONLY = $20000000;
  108. PKCTRL_BYTE = $80000000;
  109. PKCTRL_WORD = $88000000;
  110. PKCTRL_LONG = $90000000;
  111. PKCTRL_UBYTE = $00000000;
  112. PKCTRL_UWORD = $08000000;
  113. PKCTRL_ULONG = $10000000;
  114. PKCTRL_BIT = $18000000;
  115. PKCTRL_FLIPBIT = $98000000;
  116. // *********************************************************************
  117. // Tags are a general mechanism of extensible data arrays for parameter
  118. // specification and property inquiry. In practice, tags are used in arrays,
  119. // or chain of arrays.
  120. // PTagItem/TTagItem/TAG relocated to Exec
  121. // constants for Tag.ti_Tag, control tag values
  122. const
  123. TAG_DONE = 0; // terminates array of TagItems. ti_Data unused
  124. TAG_END = 0; // synonym for TAG_DONE
  125. TAG_IGNORE = 1; // ignore this item, not end of array
  126. TAG_MORE = 2; // ti_Data is pointer to another array of TagItems note that this tag terminates the current array
  127. TAG_SKIP = 3; // skip this and the next ti_Data items
  128. // differentiates user tags from control tags
  129. TAG_USER = DWord($80000000); { differentiates user tags from system tags}
  130. { If the TAG_USER bit is set in a tag number, it tells utility.library that
  131. the tag is not a control tag (like TAG_DONE, TAG_IGNORE, TAG_MORE) and is
  132. instead an application tag. "USER" means a client of utility.library in
  133. general, including system code like Intuition or ASL, it has nothing to do
  134. with user code.}
  135. // Tag filter logic specifiers for use with FilterTagItems()
  136. // enTagLogic
  137. TAGFILTER_AND = 0; // exclude everything but filter hits
  138. TAGFILTER_NOT = 1; // exclude only filter hits
  139. // Mapping types for use with MapTags()
  140. // enTagMap
  141. MAP_REMOVE_NOT_FOUND = 0; // remove tags that aren't in mapList
  142. MAP_KEEP_NOT_FOUND = 1; // keep tags that aren't in mapList
  143. type
  144. PUtilityBase = ^TUtilityBase;
  145. TUtilityBase = record
  146. ub_LibNode: TLibrary;
  147. ub_Language: Byte; // Private, for lowlevel.library
  148. ub_Reserved: Byte;
  149. end;
  150. //**********************************************************************
  151. // Flags used by the UTF-8 functions. */
  152. const
  153. UTF_INVALID_SUBST_FFFD = 1 shl 0;
  154. // Do not abort decoding when an invalid UTF-8 sequence is encountered,
  155. // instead, substitute the invalid byte sequence with the special
  156. // $FFFD character. (inverse ? on square background)
  157. type
  158. // *********************************************************************
  159. // Lists with probabilistic balancing
  160. PSkipList = ^TSkipList;
  161. TSkipList = record
  162. sl_Error: LongInt; // If an insertion fails, here is why
  163. end;
  164. PSkipNode = ^TSkipNode;
  165. TSkipNode = record
  166. sn_Reserved: APTR;
  167. sn_Key: APTR; // Unique key associated with this node
  168. end;
  169. // *********************************************************************
  170. // Self-organizing binary trees
  171. PSplayTree = ^TSplayTree;
  172. TSplayTree = record
  173. st_Error: LongInt; // If an insertion fails, here is why
  174. end;
  175. PSplayNode = ^TSplayNode;
  176. TSplayNode = record
  177. sn_UserData: APTR; // Points to user data area for this node
  178. end;
  179. const
  180. // *********************************************************************
  181. // Error codes that may be returned by the insertion functions.
  182. // enErrorCodes
  183. INSERTNODE_OUT_OF_MEMORY = 1; // Not enough memory
  184. INSERTNODE_DUPLICATE_KEY = 2; // Key is not unique
  185. INSERTNODE_TOO_SHORT = 3; // Node size must be at least as large as sizeof(TSkipNode)
  186. // *********************************************************************
  187. // Context information to be passed around between the different SHA-1
  188. // calculation routines. When the digest has been calculated, you fill
  189. // find it stored in the 'mdsha_Code' member (all 160 bits of it).
  190. type
  191. PMessageDigest_SHA = ^TMessageDigest_SHA;
  192. TMessageDigest_SHA = record
  193. mdsha_Code: array[0..19] of Byte;
  194. mdsha_Reserved: array[0..327] of Byte;
  195. end;
  196. PRandomState = ^TRandomState;
  197. TRandomState = record
  198. rs_High: LongInt;
  199. rs_Low: LongInt;
  200. end;
  201. var
  202. UtilityBase: pUtilityBase;
  203. function UtilityObtain(): LongWord; syscall IUtility 60;
  204. function UtilityRelease(): LongWord; syscall IUtility 64;
  205. procedure UtilityExpunge(); syscall IUtility 68;
  206. function UtilityClone(): PInterface; syscall IUtility 72;
  207. function AllocateTagItems(NumTags: LongWord): PTagItem; syscall IUtility 76;
  208. procedure ApplyTagChanges(List: PTagItem; const ChangeList: PTagItem); syscall IUtility 80;
  209. function CloneTagItems(const Original: PTagItem): PTagItem; syscall IUtility 84;
  210. procedure FilterTagChanges(Changelist: PTagItem; OriginalList: PTagItem; Apply: LongWord); syscall IUtility 88;
  211. function FilterTagItems(Taglist: PTagItem; const FilterArray: PLongWord; Logic: LongWord): LongWord; syscall IUtility 92;
  212. function FindTagItem(TagValue: Tag; const TagList: PTagItem): PTagItem; syscall IUtility 96;
  213. procedure FreeTagItems(TagList: PTagItem); syscall IUtility 100;
  214. function GetTagData(TagValue: Tag; DefaultValue: LongWord; const TagList: PTagItem): LongWord; syscall IUtility 104;
  215. procedure MapTags(TagList: PTagItem; const Maplist: PTagItem; MapType: LongWord); syscall IUtility 108;
  216. function NextTagItem(ItemPtr: PPTagItem): PTagItem; overload; syscall IUtility 112;
  217. function NextTagItem(var Item: PTagItem): PTagItem; overload; syscall IUtility 112;
  218. function PackBoolTags(InitialFlags: LongWord; const TagList: PTagItem; const Boolmap: PTagItem) : LongWord; syscall IUtility 116;
  219. procedure RefreshTagItemClones(Clone: PTagItem; const OriginalTagItems : PTagItem); syscall IUtility 120;
  220. function TagInArray(TagValue: Tag; const TagArray: PLongWord): LongBool; syscall IUtility 124;
  221. function CallHookPkt(Hook: PHook; Obj: APTR; Message_: APTR): LongWord; syscall IUtility 128;
  222. // 132 CallHook
  223. function AddNamedObject(NameSpace: PNamedObject; Obj: PNamedObject): LongBool; syscall IUtility 136;
  224. function AllocNamedObjectA(const Name: STRPTR; const TagList: PTagItem): PNamedObject; syscall IUtility 140;
  225. // 144 AllocNamedObject
  226. function AttemptRemNamedObject(Obj: PNamedObject): LongInt; syscall IUtility 148;
  227. function FindNamedObject(NameSpace: PNamedObject; const Name: STRPTR; PreviousObject: PNamedObject): PNamedObject; syscall IUtility 152;
  228. procedure FreeNamedObject(Obj: PNamedObject); syscall IUtility 156;
  229. function NamedObjectName(Obj: PNamedObject): STRPTR; syscall IUtility 160;
  230. procedure ReleaseNamedObject(Obj: PNamedObject); syscall IUtility 164;
  231. procedure RemNamedObject(Obj: PNamedObject; Message_: PMessage); syscall IUtility 168;
  232. procedure Amiga2Date(DateAmiga: LongWord; Cd: PClockData); syscall IUtility 172;
  233. function CheckDate(const Date: PClockData): LongWord; syscall IUtility 176;
  234. function Date2Amiga(const Date: PClockData): LongWord; syscall IUtility 180;
  235. function CreateSkipList(Hook: PHook; MaxLevels: LongInt): PSkipList; syscall IUtility 184;
  236. procedure DeleteSkipList(SkipList: PSkipList); syscall IUtility 188;
  237. function FindSkipNode(SkipList: PSkipList; Key: APTR): PSkipList; syscall IUtility 192;
  238. function GetFirstSkipNode(SkipList: PSkipList): PSkipList; syscall IUtility 196;
  239. function GetNextSkipNode(SkipList: PSkipList): PSkipList; syscall IUtility 200;
  240. function InsertSkipNode(SkipList: PSkipList): PSkipList; syscall IUtility 204;
  241. function RemoveSkipNode(SkipList: PSkipList; Key: APTR): LongBool; syscall IUtility 208;
  242. function CreateSplayTree(CompareHook: PHook): PSplayTree; syscall IUtility 212;
  243. procedure DeleteSplayTree(SplayTree: PSplayTree); syscall IUtility 216;
  244. function FindSplayNode(SplayTree: PSplayTree; Key: APTR): PSplayTree; syscall IUtility 220;
  245. function InsertSplayNode(SplayTree: PSplayTree; Key: APTR; DateSize: LongWord): PSplayTree; syscall IUtility 224;
  246. function RemoveSplayNode(SplayTree: PSplayTree; Key: APTR): PSplayTree; syscall IUtility 228;
  247. function FindNameNC(List: PList; const Name: PAnsiChar): PNode; syscall IUtility 232;
  248. function GetUniqueID : LongWord; syscall IUtility 236;
  249. procedure MessageDigest_SHA_Final(SHAs: PMessageDigest_SHA); syscall IUtility 240;
  250. procedure MessageDigest_SHA_Init(SHAs: PMessageDigest_SHA); syscall IUtility 244;
  251. procedure MessageDigest_SHA_Update(SHAs: PMessageDigest_SHA; Data: APTR; NumBytes: LongInt); syscall IUtility 248;
  252. function PackStructureTags(Pack: APTR; const PackTable: PLongWord; const TagList: PTagItem): LongWord; syscall IUtility 252;
  253. function UnpackStructureTags(const Pack: APTR; const PackTable: PLongWord; TagList: PTagItem): LongWord; syscall IUtility 256;
  254. function Random(State: PRandomState): LongWord; syscall IUtility 260;
  255. function SetMem(Destination: APTR; FillChar: Byte; Length: LongInt): APTR; syscall IUtility 264;
  256. function Stricmp(const S1: STRPTR; const S2: STRPTR): LongInt; syscall IUtility 268;
  257. function Strlcpy(Dst: STRPTR; const Src: STRPTR; Size: LongInt): LongInt; syscall IUtility 272;
  258. function Strlcat(Dst: STRPTR; const Src: STRPTR; Size: LongInt): LongInt; syscall IUtility 276;
  259. function Strnicmp(const S1: STRPTR; const S2: STRPTR; n: LongInt): LongInt; syscall IUtility 280;
  260. function ToLower(c: AnsiChar): LongWord; syscall IUtility 284;
  261. function ToUpper(c: AnsiChar): LongWord; syscall IUtility 288;
  262. function VASPrintf(const Fmt: STRPTR; Args: APTR): STRPTR; syscall IUtility 292;
  263. // 296 ASPrintf
  264. function VSNPrintf(Buffer: STRPTR; BufferSize: LongInt; const Fmt: STRPTR; Args: APTR): STRPTR; syscall IUtility 300;
  265. // 304 SNPrintf
  266. procedure ClearMem(Destination: APTR; Size: LongWord); syscall IUtility 308;
  267. procedure MoveMem(const Source: APTR; Destination: APTR; Size: LongWord); syscall IUtility 312;
  268. function Strlen(const String_: STRPTR): LongWord; syscall IUtility 316;
  269. function UTF8toUCS4(const UTF8Source: STRPTR; UCS4Destination: PLongInt; UCS4DestinationSize: LongInt; Flags: LongWord): LongInt; syscall IUtility 320;
  270. function UCS4toUTF8(const UCS4Source: PLongInt; UTF8Destination: STRPTR; UTF8DestinationSize: LongInt; Flags: LongWord): LongInt; syscall IUtility 324;
  271. function UTF8Strnicmp(const UTF8String1: STRPTR; const UTF8String2: STRPTR; MaxUCSchars: LongInt): LongInt; syscall IUtility 328;
  272. function UTF8Stricmp(const UTF8String1: STRPTR; const UTF8String2: STRPTR): LongInt; syscall IUtility 332;
  273. function UTF8Count(const UTF8String: STRPTR; Validate: LongInt): LongInt; syscall IUtility 336;
  274. function UCS4Count(const UCS4String: PLongInt; Validate: LongInt): LongInt; syscall IUtility 340;
  275. function UTF8Encode(UCS4: LongInt; Buffer: STRPTR; BufSize: LongInt; Flags: LongWord): LongInt; syscall IUtility 344;
  276. function UTF8Decode(const UTF8PPTR: PSTRPTR; Flags: LongWord): LongInt; syscall IUtility 348;
  277. function UCS4ToLower(UCS4In: LongInt): LongInt; syscall IUtility 352;
  278. function UCS4ToUpper(UCS4In: LongInt): LongInt; syscall IUtility 356;
  279. function UCS4Valid(UCS4: LongInt): LongInt; syscall IUtility 360;
  280. function AllocNamedObject(Name: STRPTR; const Tags: array of PtrUInt): PNamedObject; inline;
  281. function CallHook(Hook: PHook; Obj: APTR; Params: array of PtrUInt): LongWord; inline;
  282. function TAG_(value: pointer): PtrUInt; overload; inline;
  283. function TAG_(value: PAnsiChar): PtrUInt; overload; inline;
  284. function TAG_(value: boolean): PtrUInt; overload; inline;
  285. function TAG_(value: LongInt): PtrUInt; overload; inline;
  286. function AsTag(value: pointer): PtrUInt; overload; inline;
  287. function AsTag(value: PAnsiChar): PtrUInt; overload; inline;
  288. function AsTag(value: boolean): PtrUInt; overload; inline;
  289. function AsTag(value: LongInt): PtrUInt; overload; inline;
  290. implementation
  291. function AllocNamedObject(Name: STRPTR; const Tags: array of PtrUInt): PNamedObject; inline;
  292. begin
  293. AllocNamedObject := AllocNamedObjectA(Name, @Tags);
  294. end;
  295. function CallHook(Hook: PHook; Obj: APTR; Params: array of PtrUInt): LongWord; inline;
  296. begin
  297. CallHook := CallHookPkt(Hook, Obj, @Params);
  298. end;
  299. function TAG_(value: pointer): PtrUInt; inline;
  300. begin
  301. TAG_:=PtrUInt(value);
  302. end;
  303. function TAG_(value: PAnsiChar): PtrUInt; inline;
  304. begin
  305. TAG_:=PtrUInt(value);
  306. end;
  307. function TAG_(value: boolean): PtrUInt; inline;
  308. begin
  309. if value then
  310. TAG_ := LTrue
  311. else
  312. TAG_ := LFalse;
  313. end;
  314. function TAG_(value: LongInt): PtrUInt; inline;
  315. begin
  316. TAG_:=PtrUInt(value);
  317. end;
  318. function AsTag(value: pointer): PtrUInt; inline;
  319. begin
  320. AsTag:=PtrUInt(value);
  321. end;
  322. function AsTag(value: PAnsiChar): PtrUInt; inline;
  323. begin
  324. AsTag:=PtrUInt(value);
  325. end;
  326. function AsTag(value: boolean): PtrUInt; inline;
  327. begin
  328. if value then
  329. AsTag := LTrue
  330. else
  331. AsTag := LFalse;
  332. end;
  333. function AsTag(value: LongInt): PtrUInt; inline;
  334. begin
  335. AsTag:=PtrUInt(value);
  336. end;
  337. initialization
  338. UtilityBase := _UtilityBase;
  339. end.