XMLObjects.Mod 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. MODULE XMLObjects; (** AUTHOR "swalthert"; PURPOSE "XML collections and enumerators"; *)
  2. IMPORT
  3. Strings;
  4. TYPE
  5. String = Strings.String;
  6. Collection* = OBJECT
  7. PROCEDURE GetNumberOfElements*(): LONGINT;
  8. BEGIN
  9. RETURN 0
  10. END GetNumberOfElements;
  11. PROCEDURE GetEnumerator*(): Enumerator;
  12. BEGIN
  13. RETURN NIL
  14. END GetEnumerator;
  15. PROCEDURE Add*(p: ANY);
  16. END Add;
  17. PROCEDURE Remove*(p: ANY);
  18. END Remove;
  19. END Collection;
  20. ListElem = OBJECT
  21. VAR
  22. elem: ANY;
  23. next: ListElem;
  24. PROCEDURE &Init*(elem : ANY);
  25. BEGIN
  26. SELF.elem := elem;
  27. next := NIL;
  28. END Init;
  29. END ListElem;
  30. List* = OBJECT (Collection)
  31. VAR
  32. first, last: ListElem;
  33. nofElems: LONGINT;
  34. PROCEDURE & Init*;
  35. BEGIN
  36. nofElems := 0
  37. END Init;
  38. PROCEDURE GetNumberOfElements*(): LONGINT;
  39. BEGIN
  40. RETURN nofElems
  41. END GetNumberOfElements;
  42. PROCEDURE GetEnumerator*(): Enumerator;
  43. VAR le: ListEnumerator;
  44. BEGIN
  45. NEW(le, SELF);
  46. RETURN le
  47. END GetEnumerator;
  48. PROCEDURE Add*(p: ANY);
  49. VAR newListElem: ListElem;
  50. BEGIN {EXCLUSIVE}
  51. IF p # NIL THEN
  52. NEW(newListElem, p);
  53. IF last = NIL THEN
  54. first := newListElem;
  55. last := newListElem
  56. ELSE
  57. last.next := newListElem;
  58. last := last.next
  59. END;
  60. INC(nofElems)
  61. END
  62. END Add;
  63. PROCEDURE Remove*(p: ANY);
  64. VAR le: ListElem;
  65. BEGIN {EXCLUSIVE}
  66. IF (p # NIL) & (first # NIL) THEN
  67. IF first.elem = p THEN
  68. first := first.next; DEC(nofElems)
  69. ELSE
  70. le := first;
  71. WHILE (le.next # NIL) & (le.next.elem # p) DO
  72. le := le.next
  73. END;
  74. IF le.next # NIL THEN (* le.next.elem = o *)
  75. le.next := le.next.next; DEC(nofElems)
  76. END
  77. END
  78. END
  79. END Remove;
  80. END List;
  81. PTRArray* = POINTER TO ARRAY OF ANY;
  82. ArrayCollection* = OBJECT (Collection)
  83. VAR
  84. elems: PTRArray;
  85. nofElems: LONGINT;
  86. PROCEDURE &Init*;
  87. BEGIN
  88. nofElems := 0;
  89. NEW(elems, 1)
  90. END Init;
  91. PROCEDURE GetNumberOfElements*(): LONGINT;
  92. BEGIN
  93. RETURN nofElems
  94. END GetNumberOfElements;
  95. PROCEDURE GetEnumerator*(): Enumerator;
  96. VAR ace: ArrayEnumerator;
  97. BEGIN
  98. NEW(ace, elems);
  99. RETURN ace
  100. END GetEnumerator;
  101. PROCEDURE Grow;
  102. VAR i: LONGINT; oldElems: PTRArray;
  103. BEGIN
  104. oldElems := elems;
  105. NEW(elems, 2 * LEN(elems));
  106. FOR i := 0 TO nofElems - 1 DO
  107. elems[i] := oldElems[i]
  108. END
  109. END Grow;
  110. PROCEDURE Add*(p: ANY);
  111. BEGIN {EXCLUSIVE}
  112. IF p # NIL THEN
  113. IF nofElems = LEN(elems) THEN Grow() END;
  114. elems[nofElems] := p;
  115. INC(nofElems)
  116. END
  117. END Add;
  118. PROCEDURE Remove*(p: ANY);
  119. VAR i: LONGINT;
  120. BEGIN {EXCLUSIVE}
  121. i := 0;
  122. WHILE (i < nofElems) & (elems[i] # p) DO
  123. INC(i)
  124. END;
  125. IF i < nofElems THEN
  126. WHILE (i < nofElems - 1) DO
  127. elems[i] := elems[i + 1]; INC(i)
  128. END;
  129. DEC(nofElems); elems[nofElems] := NIL
  130. END
  131. END Remove;
  132. PROCEDURE GetElement*(i: LONGINT): ANY;
  133. BEGIN
  134. IF (0 <= i) & (i < nofElems) THEN RETURN elems[i]
  135. ELSE RETURN NIL
  136. END
  137. END GetElement;
  138. PROCEDURE Invert*(ptr1, ptr2: ANY): BOOLEAN;
  139. VAR pos1, pos2, i: LONGINT; ptr: ANY;
  140. BEGIN {EXCLUSIVE}
  141. i := 0; pos1 := -1; pos2 := -1;
  142. WHILE (i < nofElems) & ((pos1 < 0) OR (pos2 < 0)) DO
  143. IF elems[i] = ptr1 THEN pos1 := i END;
  144. IF elems[i] = ptr2 THEN pos2 := i END;
  145. INC(i)
  146. END;
  147. IF (pos1 >= 0) & (pos2 >= 0) & (pos1 # pos2) THEN
  148. ptr := elems[pos1]; elems[pos1] := elems[pos2]; elems[pos2] := ptr;
  149. RETURN TRUE
  150. END;
  151. RETURN FALSE
  152. END Invert;
  153. PROCEDURE GetElementPos*(ptr: ANY): LONGINT;
  154. VAR i: LONGINT;
  155. BEGIN
  156. WHILE i < nofElems DO
  157. IF elems[i] = ptr THEN RETURN i END;
  158. INC(i)
  159. END;
  160. RETURN -1
  161. END GetElementPos;
  162. PROCEDURE MoveUp*(ptr: ANY; i: LONGINT): BOOLEAN;
  163. VAR p: ANY;
  164. BEGIN {EXCLUSIVE}
  165. IF ptr # NIL THEN i := GetElementPos(ptr) END;
  166. IF (i > 0) & (i < nofElems) THEN
  167. p := elems[i]; elems[i] := elems[i-1]; elems[i-1] := p;
  168. RETURN TRUE
  169. END;
  170. RETURN FALSE
  171. END MoveUp;
  172. PROCEDURE MoveDown*(ptr: ANY; i: LONGINT): BOOLEAN;
  173. VAR p: ANY;
  174. BEGIN {EXCLUSIVE}
  175. IF ptr # NIL THEN i := GetElementPos(ptr) END;
  176. IF (i >=0) & (i < nofElems-1) THEN
  177. p := elems[i]; elems[i] := elems[i+1]; elems[i+1] := p;
  178. RETURN TRUE
  179. END;
  180. RETURN FALSE
  181. END MoveDown;
  182. END ArrayCollection;
  183. Enumerator* = OBJECT
  184. PROCEDURE HasMoreElements*(): BOOLEAN;
  185. BEGIN
  186. RETURN FALSE
  187. END HasMoreElements;
  188. PROCEDURE GetNext*(): ANY;
  189. BEGIN
  190. RETURN NIL
  191. END GetNext;
  192. PROCEDURE Reset*;
  193. END Reset;
  194. END Enumerator;
  195. ListEnumerator* = OBJECT (Enumerator)
  196. VAR
  197. coll: List;
  198. current: ListElem;
  199. PROCEDURE & Init*(list: List);
  200. BEGIN
  201. coll := list;
  202. current := list.first
  203. END Init;
  204. PROCEDURE HasMoreElements*(): BOOLEAN;
  205. BEGIN
  206. RETURN current # NIL
  207. END HasMoreElements;
  208. PROCEDURE GetNext*(): ANY;
  209. VAR p: ANY;
  210. BEGIN
  211. IF HasMoreElements() THEN p := current.elem; current := current.next; ELSE p := NIL; END;
  212. RETURN p
  213. END GetNext;
  214. PROCEDURE Reset*;
  215. BEGIN
  216. Init(coll)
  217. END Reset;
  218. END ListEnumerator;
  219. ArrayEnumerator* = OBJECT (Enumerator)
  220. VAR
  221. array: PTRArray;
  222. current: LONGINT;
  223. PROCEDURE & Init*(array: PTRArray);
  224. BEGIN
  225. SELF.array := array;
  226. current := 0
  227. END Init;
  228. PROCEDURE HasMoreElements*(): BOOLEAN;
  229. BEGIN
  230. RETURN (current < LEN(array)) & (array[current] # NIL)
  231. END HasMoreElements;
  232. PROCEDURE GetNext*(): ANY;
  233. VAR p: ANY;
  234. BEGIN
  235. IF HasMoreElements() THEN
  236. p := array[current]; INC(current);
  237. ELSE
  238. p := NIL;
  239. END;
  240. RETURN p
  241. END GetNext;
  242. PROCEDURE Reset*;
  243. BEGIN
  244. Init(array)
  245. END Reset;
  246. END ArrayEnumerator;
  247. Dictionary* = OBJECT
  248. PROCEDURE GetNumberOfElements*(): LONGINT;
  249. BEGIN
  250. RETURN 0
  251. END GetNumberOfElements;
  252. PROCEDURE Get*(key: ARRAY OF CHAR): ANY;
  253. END Get;
  254. PROCEDURE GetEnumerator*(): Enumerator;
  255. BEGIN
  256. RETURN NIL
  257. END GetEnumerator;
  258. PROCEDURE Add*(key: ARRAY OF CHAR; p: ANY);
  259. END Add;
  260. PROCEDURE Remove*(key: ARRAY OF CHAR);
  261. END Remove;
  262. END Dictionary;
  263. StringArray = POINTER TO ARRAY OF String;
  264. ArrayDict* = OBJECT (Dictionary)
  265. VAR
  266. nofElems: LONGINT;
  267. keys: StringArray;
  268. elems: PTRArray;
  269. PROCEDURE & Init*;
  270. BEGIN
  271. nofElems := 0;
  272. NEW(keys, 16);
  273. NEW(elems, 16)
  274. END Init;
  275. PROCEDURE GetNumberOfElements*(): LONGINT;
  276. BEGIN
  277. RETURN nofElems
  278. END GetNumberOfElements;
  279. PROCEDURE Get*(key: ARRAY OF CHAR): ANY;
  280. VAR i: LONGINT;
  281. BEGIN
  282. i := 0;
  283. WHILE (i < nofElems) & (keys[i]^ # key) DO
  284. INC(i)
  285. END;
  286. IF i < nofElems THEN RETURN elems[i]
  287. ELSE RETURN NIL
  288. END
  289. END Get;
  290. PROCEDURE GetEnumerator*(): Enumerator;
  291. VAR ace: ArrayEnumerator;
  292. BEGIN
  293. NEW(ace, elems);
  294. RETURN ace
  295. END GetEnumerator;
  296. PROCEDURE Grow;
  297. VAR i: LONGINT; oldKeys: StringArray; oldElems: PTRArray;
  298. BEGIN
  299. oldKeys := keys; oldElems := elems;
  300. NEW(keys, 2 * LEN(keys)); NEW(elems, 2 * LEN(elems));
  301. FOR i := 0 TO nofElems - 1 DO
  302. keys[i] := oldKeys[i]; elems[i] := oldElems[i]
  303. END
  304. END Grow;
  305. PROCEDURE Add*(key: ARRAY OF CHAR; p: ANY);
  306. BEGIN {EXCLUSIVE}
  307. IF Get(key) = NIL THEN
  308. IF nofElems = LEN(elems) THEN Grow() END;
  309. NEW(keys[nofElems], StringLength(key) + 1); COPY(key, keys[nofElems]^);
  310. elems[nofElems] := p;
  311. INC(nofElems)
  312. END
  313. END Add;
  314. PROCEDURE Remove*(key: ARRAY OF CHAR);
  315. VAR i: LONGINT;
  316. BEGIN {EXCLUSIVE}
  317. i := 0;
  318. WHILE (i < nofElems) & (keys[i]^ # key) DO
  319. INC(i)
  320. END;
  321. IF i < nofElems THEN
  322. WHILE (i < nofElems - 1) DO
  323. elems[i] := elems[i + 1];
  324. keys[i] := keys[i + 1];
  325. INC(i)
  326. END;
  327. DEC(nofElems); keys[nofElems] := NIL; elems[nofElems] := NIL
  328. END
  329. END Remove;
  330. END ArrayDict;
  331. PROCEDURE StringLength(CONST string: ARRAY OF CHAR): LONGINT;
  332. VAR i, l: LONGINT;
  333. BEGIN
  334. i := 0; l := LEN(string);
  335. WHILE (i < l) & (string[i] # 0X) DO
  336. INC(i)
  337. END;
  338. RETURN i
  339. END StringLength;
  340. END XMLObjects.