utility.pas 16 KB

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