summaryrefslogtreecommitdiffstats
path: root/akregator/src/mk4storage
diff options
context:
space:
mode:
Diffstat (limited to 'akregator/src/mk4storage')
-rw-r--r--akregator/src/mk4storage/Makefile.am30
-rw-r--r--akregator/src/mk4storage/akregator_mk4storage_plugin.desktop109
-rw-r--r--akregator/src/mk4storage/feedstoragemk4impl.cpp871
-rw-r--r--akregator/src/mk4storage/feedstoragemk4impl.h107
-rw-r--r--akregator/src/mk4storage/metakit/CHANGES1690
-rw-r--r--akregator/src/mk4storage/metakit/Makefile.am1
-rw-r--r--akregator/src/mk4storage/metakit/README153
-rw-r--r--akregator/src/mk4storage/metakit/include/mk4.h1078
-rw-r--r--akregator/src/mk4storage/metakit/include/mk4.inl874
-rw-r--r--akregator/src/mk4storage/metakit/include/mk4dll.h112
-rw-r--r--akregator/src/mk4storage/metakit/include/mk4io.h66
-rw-r--r--akregator/src/mk4storage/metakit/include/mk4str.h181
-rw-r--r--akregator/src/mk4storage/metakit/include/mk4str.inl299
-rw-r--r--akregator/src/mk4storage/metakit/src/Makefile.am10
-rw-r--r--akregator/src/mk4storage/metakit/src/borc.h33
-rw-r--r--akregator/src/mk4storage/metakit/src/column.cpp1533
-rw-r--r--akregator/src/mk4storage/metakit/src/column.h212
-rw-r--r--akregator/src/mk4storage/metakit/src/column.inl89
-rw-r--r--akregator/src/mk4storage/metakit/src/custom.cpp1066
-rw-r--r--akregator/src/mk4storage/metakit/src/custom.h63
-rw-r--r--akregator/src/mk4storage/metakit/src/derived.cpp1003
-rw-r--r--akregator/src/mk4storage/metakit/src/derived.h25
-rw-r--r--akregator/src/mk4storage/metakit/src/field.cpp119
-rw-r--r--akregator/src/mk4storage/metakit/src/field.h64
-rw-r--r--akregator/src/mk4storage/metakit/src/field.inl37
-rw-r--r--akregator/src/mk4storage/metakit/src/fileio.cpp434
-rw-r--r--akregator/src/mk4storage/metakit/src/format.cpp1341
-rw-r--r--akregator/src/mk4storage/metakit/src/format.h23
-rw-r--r--akregator/src/mk4storage/metakit/src/gnuc.h13
-rw-r--r--akregator/src/mk4storage/metakit/src/handler.cpp500
-rw-r--r--akregator/src/mk4storage/metakit/src/handler.h150
-rw-r--r--akregator/src/mk4storage/metakit/src/handler.inl90
-rw-r--r--akregator/src/mk4storage/metakit/src/header.h215
-rw-r--r--akregator/src/mk4storage/metakit/src/mfc.h34
-rw-r--r--akregator/src/mk4storage/metakit/src/msvc.h39
-rw-r--r--akregator/src/mk4storage/metakit/src/mwcw.h31
-rw-r--r--akregator/src/mk4storage/metakit/src/persist.cpp1185
-rw-r--r--akregator/src/mk4storage/metakit/src/persist.h127
-rw-r--r--akregator/src/mk4storage/metakit/src/remap.cpp1154
-rw-r--r--akregator/src/mk4storage/metakit/src/remap.h26
-rw-r--r--akregator/src/mk4storage/metakit/src/std.cpp84
-rw-r--r--akregator/src/mk4storage/metakit/src/std.h63
-rw-r--r--akregator/src/mk4storage/metakit/src/store.cpp587
-rw-r--r--akregator/src/mk4storage/metakit/src/store.h114
-rw-r--r--akregator/src/mk4storage/metakit/src/store.inl20
-rw-r--r--akregator/src/mk4storage/metakit/src/string.cpp304
-rw-r--r--akregator/src/mk4storage/metakit/src/table.cpp160
-rw-r--r--akregator/src/mk4storage/metakit/src/univ.cpp227
-rw-r--r--akregator/src/mk4storage/metakit/src/univ.h115
-rw-r--r--akregator/src/mk4storage/metakit/src/univ.inl126
-rw-r--r--akregator/src/mk4storage/metakit/src/view.cpp1271
-rw-r--r--akregator/src/mk4storage/metakit/src/viewx.cpp857
-rw-r--r--akregator/src/mk4storage/metakit/src/win.h33
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/b00.txt3
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/b01.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/b02.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/b03.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/b04.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/b05.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/b06.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/b07.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/b08.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/b09.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/b10.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/b11.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/b12.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/b13.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/b14.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/b15.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/b16.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/b17.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/b18.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/b19.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/b20.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/b21.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/b22.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/b23.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/b24.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/b25.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/b26.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/b27.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/c01.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/c02.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/c03.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/c04.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/c05.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/c06.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/c07.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/c08.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/c09.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/c10.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/c11.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/c12.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/c13.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/c14.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/c15.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/c16.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/c17.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/c18.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/c19.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/c20.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/c21.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/c22.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/d01.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/d01a.txt4
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/d01b.txt19
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/e01.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/e01a.txt5
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/e02.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/e02a.txt5
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/e03.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/e03a.txt5
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/e04.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/e04a.txt5
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/e05.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/e05a.txt1
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/e06.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/e06a.txt5
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/f01.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/f01a.txt8
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/f02.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/f02a.txt5
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/f03.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/f03a.txt4
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/f04.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/f04a.txt8
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/f05.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/f05a.txt8
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/f06.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/f07.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/f07a.txt3
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/f08.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/f08a.txt6
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/f09.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/f09a.txt13
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/f10.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/f10a.txt13
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/f11.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/f11a.txt1
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/l00.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/l00a.txt4
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/l01.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/l01a.txt9003
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/l02.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/l02a.txt3503
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/l03.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/l03a.txt1503
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/l03b.txt1503
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/l04.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/l04a.txt1503
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/l05.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/l05a.txt4
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/l06.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/l06a.txt1371
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/l07.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/l07a.txt4
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/m01.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/m02.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/m02a.txt22
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/m03.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/m03a.txt55
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/m04.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/m04a.txt9
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/m05.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/m05a.txt4012
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/m06.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/m06a.txt2963
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/m07.txt63
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/n01.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/n02.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/n03.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/n04.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/n05.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/n06.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/n07.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/n08.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/n09.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/n10.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/n11.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/n12.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/n13.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/n14.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/n14a.txt15
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/r00.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/r00a.txt253
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/r01.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/r01a.txt18
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/r02.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/r02a.txt8
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/r03.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/r03a.txt8
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/r04.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/r04a.txt3
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/reversed.txt14
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s00.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s00a.txt3
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s01.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s01a.txt6
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s02.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s02a.txt6
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s03.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s03a.txt6
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s04.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s04a.txt18
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s05.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s05a.txt4
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s06.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s06a.txt5
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s07.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s07a.txt4
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s08.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s08a.txt4
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s09.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s09a.txt4
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s09b.txt4
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s10.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s10a.txt18
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s10b.txt18
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s10c.txt21
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s11.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s11a.txt4
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s12.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s12a.txt3
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s13.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s13a.txt13
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s14.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s14a.txt6
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s15.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s15a.txt7
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s16.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s16a.txt6
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s17.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s17a.txt6
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s18.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s18a.txt1
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s19.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s19a.txt1
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s20.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s20a.txt1
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s21.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s21a.txt10
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s22.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s22a.txt6
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s23.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s23a.txt1
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s24.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s24a.txt45
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s25.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s25a.txt6
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s26.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s26a.txt4
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s27.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s27a.txt4
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s28.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s28a.txt7
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s29.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s29a.txt3
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s30.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s30a.txt6
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s31.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s31a.txt6
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s32.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s32a.txt4
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s33.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s33a.txt6
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s33b.txt6
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s33c.txt6
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s34.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s34a.txt4
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s35.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s35a.txt4
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s36.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s36a.txt4
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s36b.txt4
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s37.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s37a.txt4
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s38.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s38a.txt7
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s39.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s39a.txt4
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s40.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s40a.txt4
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s41.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s41a.txt8
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s42.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s43.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s43a.txt5
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s44.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s44a.txt4
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s45.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s45a.txt7
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s46.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s46a.txt15
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s47.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s48.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s48a.txt5
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s48b.txt5
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s49.txt2
-rw-r--r--akregator/src/mk4storage/metakit/tests/ok/s49a.txt7
-rw-r--r--akregator/src/mk4storage/metakit/tests/regress.cpp269
-rw-r--r--akregator/src/mk4storage/metakit/tests/regress.h145
-rw-r--r--akregator/src/mk4storage/metakit/tests/tbasic1.cpp268
-rw-r--r--akregator/src/mk4storage/metakit/tests/tbasic2.cpp218
-rw-r--r--akregator/src/mk4storage/metakit/tests/tcusto1.cpp277
-rw-r--r--akregator/src/mk4storage/metakit/tests/tcusto2.cpp441
-rw-r--r--akregator/src/mk4storage/metakit/tests/tdiffer.cpp52
-rw-r--r--akregator/src/mk4storage/metakit/tests/textend.cpp195
-rw-r--r--akregator/src/mk4storage/metakit/tests/tformat.cpp306
-rw-r--r--akregator/src/mk4storage/metakit/tests/tlimits.cpp282
-rw-r--r--akregator/src/mk4storage/metakit/tests/tmapped.cpp244
-rw-r--r--akregator/src/mk4storage/metakit/tests/tnotify.cpp444
-rw-r--r--akregator/src/mk4storage/metakit/tests/tresize.cpp289
-rw-r--r--akregator/src/mk4storage/metakit/tests/tstore1.cpp180
-rw-r--r--akregator/src/mk4storage/metakit/tests/tstore2.cpp326
-rw-r--r--akregator/src/mk4storage/metakit/tests/tstore3.cpp366
-rw-r--r--akregator/src/mk4storage/metakit/tests/tstore4.cpp323
-rw-r--r--akregator/src/mk4storage/metakit/tests/tstore5.cpp286
-rw-r--r--akregator/src/mk4storage/mk4config.kcfg18
-rw-r--r--akregator/src/mk4storage/mk4config.kcfgc6
-rw-r--r--akregator/src/mk4storage/mk4confwidget.cpp92
-rw-r--r--akregator/src/mk4storage/mk4confwidget.h48
-rw-r--r--akregator/src/mk4storage/mk4confwidgetbase.ui178
-rw-r--r--akregator/src/mk4storage/mk4plugin.cpp50
-rw-r--r--akregator/src/mk4storage/mk4plugin.h49
-rw-r--r--akregator/src/mk4storage/storagefactorymk4impl.cpp71
-rw-r--r--akregator/src/mk4storage/storagefactorymk4impl.h53
-rw-r--r--akregator/src/mk4storage/storagemk4impl.cpp402
-rw-r--r--akregator/src/mk4storage/storagemk4impl.h130
328 files changed, 51798 insertions, 0 deletions
diff --git a/akregator/src/mk4storage/Makefile.am b/akregator/src/mk4storage/Makefile.am
new file mode 100644
index 000000000..4f2ebfae5
--- /dev/null
+++ b/akregator/src/mk4storage/Makefile.am
@@ -0,0 +1,30 @@
+kde_module_LTLIBRARIES = libakregator_mk4storage_plugin.la
+
+SUBDIRS = metakit
+
+INCLUDES = \
+ -I$(top_srcdir)/akregator/src \
+ -I$(top_srcdir)/akregator/src/mk4storage/metakit/include \
+ $(all_includes)
+
+libakregator_mk4storage_plugin_la_LIBADD = \
+ $(top_builddir)/akregator/src/mk4storage/metakit/src/libmetakitlocal.la \
+ $(top_builddir)/akregator/src/librss/librsslocal.la \
+ ../libakregatorprivate.la \
+ $(LIB_KFILE) \
+ $(LIB_KDECORE)
+
+libakregator_mk4storage_plugin_la_LDFLAGS = \
+ $(KDE_PLUGIN) \
+ $(all_libraries)
+
+libakregator_mk4storage_plugin_la_SOURCES = feedstoragemk4impl.cpp \
+ storagemk4impl.cpp \
+ storagefactorymk4impl.cpp \
+ mk4plugin.cpp
+
+METASOURCES = AUTO
+
+kde_services_DATA = akregator_mk4storage_plugin.desktop
+
+kde_kcfg_DATA = mk4config.kcfg
diff --git a/akregator/src/mk4storage/akregator_mk4storage_plugin.desktop b/akregator/src/mk4storage/akregator_mk4storage_plugin.desktop
new file mode 100644
index 000000000..c7d899a7a
--- /dev/null
+++ b/akregator/src/mk4storage/akregator_mk4storage_plugin.desktop
@@ -0,0 +1,109 @@
+[Desktop Entry]
+Type=Service
+Name=Metakit storage backend
+Name[af]=Metakit stoor agterkant
+Name[bg]=Приставка за архивиране Metakit
+Name[ca]=Dorsal de emmagatzematge Metakit
+Name[cs]=Metakit úložiště
+Name[da]=Metakit lagringsgrænseflade
+Name[de]=Metakit Archiv-Modul
+Name[el]=Σύστημα υποστήριξης αποθήκευσης Metakit
+Name[eo]=Metakit datumstora maŝino
+Name[es]=Dorsal de almacenamiento Metakit
+Name[et]=Metakiti salvestamisrakendus
+Name[eu]=Metakit-en biltegiratze euskarria
+Name[fa]=پشتیبان ذخیره‌گاه Metakit
+Name[fi]=Metakit-tallennusajuri
+Name[fr]=Stockage avec Metakit
+Name[fy]=Metakit-opslachefterein
+Name[gl]=Manexador do almacenador Metakit
+Name[hu]=Metakit tároló
+Name[is]=Metakit geymslu bakendi
+Name[it]=Backend archiviazione metakit
+Name[ja]=メタキットストレージバックエンド
+Name[ka]=Metakit მეხსიერების ბუფერი
+Name[kk]=Metakit архивтеу бағдарламасы
+Name[km]=កម្មវិធី​ខាង​ក្រោយ​សម្រាប់​រក្សាទុក (Metakit)
+Name[ko]=Metakit 저장소 백엔드
+Name[lt]=Metakit saugojimo programinė sąsaja
+Name[ms]=Hujung belakang storan Metakit
+Name[nb]=Metakit lagringsbakstykke
+Name[nds]=Metakit-Archivmoduul
+Name[ne]=मेटाकिट भण्डारण ब्याकइन्ड
+Name[nl]=Metakit-opslagbackend
+Name[nn]=Metakit-lagringsbakstykke
+Name[pl]=System przechowywania Metakit
+Name[pt]=Infra-estrutura de armazenamento Metakit
+Name[pt_BR]=Mecanismo de armazenamento Metakit
+Name[ru]=Движок Metakit
+Name[sl]=Shranjevanje Metakit
+Name[sr]=Систем за смештање Мета комплета
+Name[sr@Latn]=Sistem za smeštanje Meta kompleta
+Name[sv]=Metakit lagringsgränssnitt
+Name[tr]=Metakit depolama arka ucu
+Name[uk]=Програма зберігання Metakit
+Name[zh_CN]=Metakit 存储后端
+Name[zh_TW]=Metakit 儲存後端介面
+X-KDE-Library=libakregator_mk4storage_plugin
+Comment=Plugin for Akregator
+Comment[af]=Inprop module vir Akregator
+Comment[be]=Утулка для Akregator
+Comment[bg]=Приставка за Akregator
+Comment[br]=Lugent evit Akregator
+Comment[ca]=Endollable per a l'Akregator
+Comment[cs]=Modul pro Akregator
+Comment[de]=Modul für Akregator
+Comment[el]=Πρόσθετο για το Akregator
+Comment[eo]=Kromprogramo por Akregator
+Comment[es]=Extensión para Akregator
+Comment[et]=Akregatori plugin
+Comment[eu]=Akregator-en plugina
+Comment[fa]=وصله برای Akregator
+Comment[fi]=Liitännäinen Akregatoriin
+Comment[fr]=Module pour Akregator
+Comment[fy]=Plugin foar Akregator
+Comment[ga]=Breiseán Akregator
+Comment[gl]=Extensión para Akregator
+Comment[he]=תוסף עבור Akregator
+Comment[hu]=Akregator bővítőmodul
+Comment[is]=Íforrit fyrir Akregator
+Comment[it]=Plugin per Akregator
+Comment[ja]=Akregator 用プラグイン
+Comment[ka]=Akregator-ის მოდული
+Comment[kk]=Akregator-дың плагин модулі
+Comment[km]=កម្មវិធី​ជំនួយ Akregator
+Comment[ko]=Akregator 플러그인
+Comment[lt]=Akregator skirtas priedas
+Comment[mk]=Приклучок за Akregator
+Comment[ms]=Plugin untuk Akregator
+Comment[nb]=Programtillegg for Akregator
+Comment[nds]=Moduul för Akregator
+Comment[ne]=एक्रिगेटरका लागि प्लगइन
+Comment[nl]=Plugin voor Akregator
+Comment[nn]=Programtillegg til Akregator
+Comment[pl]=Wtyczka dla Akregatora
+Comment[pt]='Plugin' para o Akregator
+Comment[pt_BR]=Plug-in para o Akregator
+Comment[ru]=Модуль Akregator
+Comment[se]=Lassemoduvla Akregatorii
+Comment[sk]=Modul pre Akregator
+Comment[sl]=Vstavek za Akregator
+Comment[sr]=Прикључак за Akregator
+Comment[sr@Latn]=Priključak za Akregator
+Comment[sv]=Insticksprogram för Akregator
+Comment[tr]=Akregator Eklentisi
+Comment[uk]=Втулок для Akregator
+Comment[uz]=Akregator uchun plagin
+Comment[uz@cyrillic]=Akregator учун плагин
+Comment[zh_CN]=Akregator 插件
+Comment[zh_TW]=Akregator 外掛程式
+ServiceTypes=Akregator/Plugin
+
+X-KDE-akregator-plugintype=storage
+X-KDE-akregator-name=metakit
+X-KDE-akregator-authors=Frank Osterfeld
+X-KDE-akregator-email=frank.osterfeld@kdemail.net
+X-KDE-akregator-rank=255
+X-KDE-akregator-version=1
+X-KDE-akregator-framework-version=1
+
diff --git a/akregator/src/mk4storage/feedstoragemk4impl.cpp b/akregator/src/mk4storage/feedstoragemk4impl.cpp
new file mode 100644
index 000000000..521f9f326
--- /dev/null
+++ b/akregator/src/mk4storage/feedstoragemk4impl.cpp
@@ -0,0 +1,871 @@
+/*
+ This file is part of Akregator.
+
+ Copyright (C) 2005 Frank Osterfeld <frank.osterfeld@kdemail.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ As a special exception, permission is given to link this program
+ with any edition of Qt, and distribute the resulting executable,
+ without including the source code for Qt in the source distribution.
+*/
+
+#include "feedstoragemk4impl.h"
+#include "storagemk4impl.h"
+
+#include "../article.h"
+#include "../utils.h"
+#include "../librss/article.h"
+#include "../librss/document.h"
+#include <mk4.h>
+
+#include <qdom.h>
+#include <qfile.h>
+
+#include <kdebug.h>
+#include <kglobal.h>
+#include <kstandarddirs.h>
+
+namespace Akregator {
+namespace Backend {
+
+class FeedStorageMK4Impl::FeedStorageMK4ImplPrivate
+{
+ public:
+ FeedStorageMK4ImplPrivate() :
+ modified(false),
+ pguid("guid"),
+ ptitle("title"),
+ pdescription("description"),
+ plink("link"),
+ pcommentsLink("commentsLink"),
+ ptag("tag"),
+ pEnclosureType("enclosureType"),
+ pEnclosureUrl("enclosureUrl"),
+ pcatTerm("catTerm"),
+ pcatScheme("catScheme"),
+ pcatName("catName"),
+ pauthor("author"),
+ phash("hash"),
+ pguidIsHash("guidIsHash"),
+ pguidIsPermaLink("guidIsPermaLink"),
+ pcomments("comments"),
+ pstatus("status"),
+ ppubDate("pubDate"),
+ pHasEnclosure("hasEnclosure"),
+ pEnclosureLength("enclosureLength"),
+ ptags("tags"),
+ ptaggedArticles("taggedArticles"),
+ pcategorizedArticles("categorizedArticles"),
+ pcategories("categories")
+ {}
+
+ QString url;
+ c4_Storage* storage;
+ StorageMK4Impl* mainStorage;
+ c4_View archiveView;
+
+ c4_Storage* catStorage;
+ c4_View catView;
+ c4_Storage* tagStorage;
+ c4_View tagView;
+ bool autoCommit;
+ bool modified;
+ bool taggingEnabled;
+ bool convert;
+ QString oldArchivePath;
+ c4_StringProp pguid, ptitle, pdescription, plink, pcommentsLink, ptag, pEnclosureType, pEnclosureUrl, pcatTerm, pcatScheme, pcatName, pauthor;
+ c4_IntProp phash, pguidIsHash, pguidIsPermaLink, pcomments, pstatus, ppubDate, pHasEnclosure, pEnclosureLength;
+ c4_ViewProp ptags, ptaggedArticles, pcategorizedArticles, pcategories;
+};
+
+void FeedStorageMK4Impl::convertOldArchive()
+{
+ if (!d->convert)
+ return;
+
+ d->convert = false;
+ QFile file(d->oldArchivePath);
+
+ if ( !file.open(IO_ReadOnly) )
+ return;
+
+ QTextStream stream(&file);
+ stream.setEncoding(QTextStream::UnicodeUTF8);
+ QString data=stream.read();
+ QDomDocument xmldoc;
+
+ if (!xmldoc.setContent(data))
+ return;
+
+ RSS::Document doc(xmldoc);
+
+ RSS::Article::List d_articles = doc.articles();
+ RSS::Article::List::ConstIterator it = d_articles.begin();
+ RSS::Article::List::ConstIterator en = d_articles.end();
+
+ int unr = 0;
+ for (; it != en; ++it)
+ {
+ Article a(*it, this);
+ if (a.status() != Article::Read)
+ unr++;
+ }
+
+ setUnread(unr);
+ markDirty();
+ commit();
+}
+
+FeedStorageMK4Impl::FeedStorageMK4Impl(const QString& url, StorageMK4Impl* main)
+{
+ d = new FeedStorageMK4ImplPrivate;
+ d->autoCommit = main->autoCommit();
+ d->url = url;
+ d->mainStorage = main;
+ d->taggingEnabled = main->taggingEnabled();
+
+ QString url2 = url;
+
+ if (url.length() > 255)
+ {
+ url2 = url.left(200) + QString::number(Akregator::Utils::calcHash(url), 16);
+ }
+
+ kdDebug() << url2 << endl;
+ QString t = url2;
+ QString t2 = url2;
+ QString filePath = main->archivePath() +"/"+ t.replace("/", "_").replace(":", "_");
+ d->oldArchivePath = KGlobal::dirs()->saveLocation("data", "akregator/Archive/") + t2.replace("/", "_").replace(":", "_") + ".xml";
+
+ d->convert = !QFile::exists(filePath + ".mk4") && QFile::exists(d->oldArchivePath);
+ d->storage = new c4_Storage((filePath + ".mk4").local8Bit(), true);
+
+ d->archiveView = d->storage->GetAs("articles[guid:S,title:S,hash:I,guidIsHash:I,guidIsPermaLink:I,description:S,link:S,comments:I,commentsLink:S,status:I,pubDate:I,tags[tag:S],hasEnclosure:I,enclosureUrl:S,enclosureType:S,enclosureLength:I,categories[catTerm:S,catScheme:S,catName:S],author:S]");
+
+ c4_View hash = d->storage->GetAs("archiveHash[_H:I,_R:I]");
+ d->archiveView = d->archiveView.Hash(hash, 1); // hash on guid
+
+ d->tagStorage = 0;
+
+ if (d->taggingEnabled)
+ {
+ d->tagStorage = new c4_Storage((filePath + ".mk4___TAGS").local8Bit(), true);
+ d->tagView = d->tagStorage->GetAs("tagIndex[tag:S,taggedArticles[guid:S]]");
+ hash = d->tagStorage->GetAs("archiveHash[_H:I,_R:I]");
+ d->tagView = d->tagView.Hash(hash, 1); // hash on tag
+ }
+ //d->catStorage = new c4_Storage((filePath + ".mk4___CATEGORIES").local8Bit(), true);
+ //d->catView = d->catStorage->GetAs("catIndex[catTerm:S,catScheme:S,catName:S,categorizedArticles[guid:S]]");
+}
+
+
+FeedStorageMK4Impl::~FeedStorageMK4Impl()
+{
+ delete d->storage;
+ if (d->taggingEnabled)
+ delete d->tagStorage;
+// delete d->catStorage;
+ delete d; d = 0;
+}
+
+void FeedStorageMK4Impl::markDirty()
+{
+ if (!d->modified)
+ {
+ d->modified = true;
+ // Tell this to mainStorage
+ d->mainStorage->markDirty();
+ }
+}
+
+void FeedStorageMK4Impl::commit()
+{
+ if (d->modified)
+ {
+ d->storage->Commit();
+ if (d->taggingEnabled)
+ d->tagStorage->Commit();
+// d->catStorage->Commit();
+ }
+ d->modified = false;
+}
+
+void FeedStorageMK4Impl::rollback()
+{
+ d->storage->Rollback();
+ if (d->taggingEnabled)
+ d->tagStorage->Rollback();
+// d->catStorage->Rollback();
+}
+
+void FeedStorageMK4Impl::close()
+{
+ if (d->autoCommit)
+ commit();
+}
+int FeedStorageMK4Impl::unread()
+{
+ return d->mainStorage->unreadFor(d->url);
+}
+void FeedStorageMK4Impl::setUnread(int unread)
+{
+ d->mainStorage->setUnreadFor(d->url, unread);
+}
+
+int FeedStorageMK4Impl::totalCount()
+{
+ return d->mainStorage->totalCountFor(d->url);
+}
+
+void FeedStorageMK4Impl::setTotalCount(int total)
+{
+ d->mainStorage->setTotalCountFor(d->url, total);
+}
+
+int FeedStorageMK4Impl::lastFetch()
+{
+ return d->mainStorage->lastFetchFor(d->url);
+}
+
+void FeedStorageMK4Impl::setLastFetch(int lastFetch)
+{
+ d->mainStorage->setLastFetchFor(d->url, lastFetch);
+}
+
+QStringList FeedStorageMK4Impl::articles(const QString& tag)
+{
+ QStringList list;
+ if (tag.isNull()) // return all articles
+ {
+ int size = d->archiveView.GetSize();
+ for (int i = 0; i < size; i++) // fill with guids
+ list += QString(d->pguid(d->archiveView.GetAt(i)));
+ }
+ else if (d->taggingEnabled)
+ {
+ c4_Row tagrow;
+ d->ptag(tagrow) = tag.utf8().data();
+ int tagidx = d->tagView.Find(tagrow);
+ if (tagidx != -1)
+ {
+ tagrow = d->tagView.GetAt(tagidx);
+ c4_View tagView = d->ptaggedArticles(tagrow);
+ int size = tagView.GetSize();
+ for (int i = 0; i < size; i++)
+ list += QString(d->pguid(tagView.GetAt(i)));
+ }
+
+ }
+ return list;
+}
+
+QStringList FeedStorageMK4Impl::articles(const Category& cat)
+{
+ QStringList list;
+ /*
+ c4_Row catrow;
+ d->pcatTerm(catrow) = cat.term.utf8().data();
+ d->pcatScheme(catrow) = cat.scheme.utf8().data();
+
+ int catidx = d->catView.Find(catrow);
+ if (catidx != -1)
+ {
+ catrow = d->catView.GetAt(catidx);
+ c4_View catView = d->pcategorizedArticles(catrow);
+ int size = catView.GetSize();
+ for (int i = 0; i < size; i++)
+ list += QString(d->pguid(catView.GetAt(i)));
+ }
+ */
+ return list;
+}
+
+void FeedStorageMK4Impl::addEntry(const QString& guid)
+{
+ c4_Row row;
+ d->pguid(row) = guid.ascii();
+ if (!contains(guid))
+ {
+ d->archiveView.Add(row);
+ markDirty();
+ setTotalCount(totalCount()+1);
+ }
+}
+
+bool FeedStorageMK4Impl::contains(const QString& guid)
+{
+ return findArticle(guid) != -1;
+}
+
+int FeedStorageMK4Impl::findArticle(const QString& guid)
+{
+ c4_Row findrow;
+ d->pguid(findrow) = guid.ascii();
+ return d->archiveView.Find(findrow);
+}
+
+void FeedStorageMK4Impl::deleteArticle(const QString& guid)
+{
+
+ int findidx = findArticle(guid);
+ if (findidx != -1)
+ {
+ QStringList list = tags(guid);
+ for (QStringList::ConstIterator it = list.begin(); it != list.end(); ++it)
+ removeTag(guid, *it);
+ setTotalCount(totalCount()-1);
+ d->archiveView.RemoveAt(findidx);
+ markDirty();
+ }
+}
+
+int FeedStorageMK4Impl::comments(const QString& guid)
+{
+ int findidx = findArticle(guid);
+ return findidx != -1 ? d->pcomments(d->archiveView.GetAt(findidx)) : 0;
+}
+
+QString FeedStorageMK4Impl::commentsLink(const QString& guid)
+{
+ int findidx = findArticle(guid);
+ return findidx != -1 ? QString(d->pcommentsLink(d->archiveView.GetAt(findidx))) : "";
+}
+
+bool FeedStorageMK4Impl::guidIsHash(const QString& guid)
+{
+ int findidx = findArticle(guid);
+ return findidx != -1 ? d->pguidIsHash(d->archiveView.GetAt(findidx)) : false;
+}
+
+bool FeedStorageMK4Impl::guidIsPermaLink(const QString& guid)
+{
+ int findidx = findArticle(guid);
+ return findidx != -1 ? d->pguidIsPermaLink(d->archiveView.GetAt(findidx)) : false;
+}
+
+uint FeedStorageMK4Impl::hash(const QString& guid)
+{
+ int findidx = findArticle(guid);
+ return findidx != -1 ? d->phash(d->archiveView.GetAt(findidx)) : 0;
+}
+
+
+void FeedStorageMK4Impl::setDeleted(const QString& guid)
+{
+ int findidx = findArticle(guid);
+ if (findidx == -1)
+ return;
+
+ c4_Row row;
+ row = d->archiveView.GetAt(findidx);
+ QStringList list = tags(guid);
+ for (QStringList::ConstIterator it = list.begin(); it != list.end(); ++it)
+ removeTag(guid, *it);
+ d->pdescription(row) = "";
+ d->ptitle(row) = "";
+ d->plink(row) = "";
+ d->pauthor(row) = "";
+ d->pcommentsLink(row) = "";
+ d->archiveView.SetAt(findidx, row);
+ markDirty();
+}
+
+QString FeedStorageMK4Impl::link(const QString& guid)
+{
+ int findidx = findArticle(guid);
+ return findidx != -1 ? QString(d->plink(d->archiveView.GetAt(findidx))) : "";
+}
+
+uint FeedStorageMK4Impl::pubDate(const QString& guid)
+{
+ int findidx = findArticle(guid);
+ return findidx != -1 ? d->ppubDate(d->archiveView.GetAt(findidx)) : 0;
+}
+
+int FeedStorageMK4Impl::status(const QString& guid)
+{
+ int findidx = findArticle(guid);
+ return findidx != -1 ? d->pstatus(d->archiveView.GetAt(findidx)) : 0;
+}
+
+void FeedStorageMK4Impl::setStatus(const QString& guid, int status)
+{
+ int findidx = findArticle(guid);
+ if (findidx == -1)
+ return;
+ c4_Row row;
+ row = d->archiveView.GetAt(findidx);
+ d->pstatus(row) = status;
+ d->archiveView.SetAt(findidx, row);
+ markDirty();
+}
+
+QString FeedStorageMK4Impl::title(const QString& guid)
+{
+ int findidx = findArticle(guid);
+ return findidx != -1 ? QString::fromUtf8(d->ptitle(d->archiveView.GetAt(findidx))) : "";
+}
+
+QString FeedStorageMK4Impl::description(const QString& guid)
+{
+ int findidx = findArticle(guid);
+ return findidx != -1 ? QString::fromUtf8(d->pdescription(d->archiveView.GetAt(findidx))) : "";
+}
+
+
+void FeedStorageMK4Impl::setPubDate(const QString& guid, uint pubdate)
+{
+ int findidx = findArticle(guid);
+ if (findidx == -1)
+ return;
+ c4_Row row;
+ row = d->archiveView.GetAt(findidx);
+ d->ppubDate(row) = pubdate;
+ d->archiveView.SetAt(findidx, row);
+ markDirty();
+}
+
+void FeedStorageMK4Impl::setGuidIsHash(const QString& guid, bool isHash)
+{
+ int findidx = findArticle(guid);
+ if (findidx == -1)
+ return;
+ c4_Row row;
+ row = d->archiveView.GetAt(findidx);
+ d->pguidIsHash(row) = isHash;
+ d->archiveView.SetAt(findidx, row);
+ markDirty();
+}
+
+void FeedStorageMK4Impl::setLink(const QString& guid, const QString& link)
+{
+ int findidx = findArticle(guid);
+ if (findidx == -1)
+ return;
+ c4_Row row;
+ row = d->archiveView.GetAt(findidx);
+ d->plink(row) = !link.isEmpty() ? link.ascii() : "";
+ d->archiveView.SetAt(findidx, row);
+ markDirty();
+}
+
+void FeedStorageMK4Impl::setHash(const QString& guid, uint hash)
+{
+ int findidx = findArticle(guid);
+ if (findidx == -1)
+ return;
+ c4_Row row;
+ row = d->archiveView.GetAt(findidx);
+ d->phash(row) = hash;
+ d->archiveView.SetAt(findidx, row);
+ markDirty();
+}
+
+void FeedStorageMK4Impl::setTitle(const QString& guid, const QString& title)
+{
+ int findidx = findArticle(guid);
+ if (findidx == -1)
+ return;
+ c4_Row row;
+ row = d->archiveView.GetAt(findidx);
+ d->ptitle(row) = !title.isEmpty() ? title.utf8().data() : "";
+ d->archiveView.SetAt(findidx, row);
+ markDirty();
+}
+
+void FeedStorageMK4Impl::setDescription(const QString& guid, const QString& description)
+{
+ int findidx = findArticle(guid);
+ if (findidx == -1)
+ return;
+ c4_Row row;
+ row = d->archiveView.GetAt(findidx);
+ d->pdescription(row) = !description.isEmpty() ? description.utf8().data() : "";
+ d->archiveView.SetAt(findidx, row);
+ markDirty();
+}
+
+void FeedStorageMK4Impl::setAuthor(const QString& guid, const QString& author)
+{
+ int findidx = findArticle(guid);
+ if (findidx == -1)
+ return;
+ c4_Row row;
+ row = d->archiveView.GetAt(findidx);
+ d->pauthor(row) = !author.isEmpty() ? author.utf8().data() : "";
+ d->archiveView.SetAt(findidx, row);
+ markDirty();
+}
+
+QString FeedStorageMK4Impl::author(const QString& guid)
+{
+ int findidx = findArticle(guid);
+ return findidx != -1 ? QString::fromUtf8(d->pauthor(d->archiveView.GetAt(findidx))) : "";
+}
+
+
+void FeedStorageMK4Impl::setCommentsLink(const QString& guid, const QString& commentsLink)
+{
+ int findidx = findArticle(guid);
+ if (findidx == -1)
+ return;
+ c4_Row row;
+ row = d->archiveView.GetAt(findidx);
+ d->pcommentsLink(row) = !commentsLink.isEmpty() ? commentsLink.utf8().data() : "";
+ d->archiveView.SetAt(findidx, row);
+ markDirty();
+}
+
+void FeedStorageMK4Impl::setComments(const QString& guid, int comments)
+{
+ int findidx = findArticle(guid);
+ if (findidx == -1)
+ return;
+ c4_Row row;
+ row = d->archiveView.GetAt(findidx);
+ d->pcomments(row) = comments;
+ d->archiveView.SetAt(findidx, row);
+ markDirty();
+}
+
+
+void FeedStorageMK4Impl::setGuidIsPermaLink(const QString& guid, bool isPermaLink)
+{
+ int findidx = findArticle(guid);
+ if (findidx == -1)
+ return;
+ c4_Row row;
+ row = d->archiveView.GetAt(findidx);
+ d->pguidIsPermaLink(row) = isPermaLink;
+ d->archiveView.SetAt(findidx, row);
+ markDirty();
+}
+
+void FeedStorageMK4Impl::addCategory(const QString& /*guid*/, const Category& /*cat*/)
+{
+ return;
+ /*
+ int findidx = findArticle(guid);
+ if (findidx == -1)
+ return;
+
+ c4_Row row;
+ row = d->archiveView.GetAt(findidx);
+ c4_View catView = d->pcategories(row);
+ c4_Row findrow;
+
+ d->pcatTerm(findrow) = cat.term.utf8().data();
+ d->pcatScheme(findrow) = cat.scheme.utf8().data();
+
+ int catidx = catView.Find(findrow);
+ if (catidx == -1)
+ {
+ d->pcatName(findrow) = cat.name.utf8().data();
+ catidx = catView.Add(findrow);
+ d->pcategories(row) = catView;
+ d->archiveView.SetAt(findidx, row);
+
+ // add to category->articles index
+ c4_Row catrow;
+ d->pcatTerm(catrow) = cat.term.utf8().data();
+ d->pcatScheme(catrow) = cat.scheme.utf8().data();
+ d->pcatName(catrow) = cat.name.utf8().data();
+
+ int catidx2 = d->catView.Find(catrow);
+
+ if (catidx2 == -1)
+ {
+ catidx2 = d->catView.Add(catrow);
+ }
+
+ c4_Row catrow2 = d->catView.GetAt(catidx2);
+ c4_View catView2 = d->pcategorizedArticles(catrow2);
+
+ c4_Row row3;
+ d->pguid(row3) = guid.ascii();
+ int guididx = catView2.Find(row3);
+ if (guididx == -1)
+ {
+ guididx = catView2.Add(row3);
+ catView2.SetAt(guididx, row3);
+ d->pcategorizedArticles(catrow2) = catView2;
+ d->catView.SetAt(catidx2, catrow2);
+ }
+
+ markDirty();
+ }
+ */
+}
+
+QValueList<Category> FeedStorageMK4Impl::categories(const QString& /*guid*/)
+{
+
+ QValueList<Category> list;
+ return list;
+ /*
+ if (!guid.isNull()) // return categories for an article
+ {
+ int findidx = findArticle(guid);
+ if (findidx == -1)
+ return list;
+
+ c4_Row row;
+ row = d->archiveView.GetAt(findidx);
+ c4_View catView = d->pcategories(row);
+ int size = catView.GetSize();
+
+ for (int i = 0; i < size; ++i)
+ {
+ Category cat;
+
+ cat.term = QString::fromUtf8(d->pcatTerm(catView.GetAt(i)));
+ cat.scheme = QString::fromUtf8(d->pcatScheme(catView.GetAt(i)));
+ cat.name = QString::fromUtf8(d->pcatName(catView.GetAt(i)));
+
+ list += cat;
+ }
+ }
+ else // return all categories in the feed
+ {
+ int size = d->catView.GetSize();
+ for (int i = 0; i < size; i++)
+ {
+ c4_Row row = d->catView.GetAt(i);
+
+ Category cat;
+ cat.term = QString(d->pcatTerm(row));
+ cat.scheme = QString(d->pcatScheme(row));
+ cat.name = QString(d->pcatName(row));
+
+ list += cat;
+ }
+ }
+
+ return list;*/
+}
+
+void FeedStorageMK4Impl::addTag(const QString& guid, const QString& tag)
+{
+ if (!d->taggingEnabled)
+ return;
+
+ int findidx = findArticle(guid);
+ if (findidx == -1)
+ return;
+
+ c4_Row row;
+ row = d->archiveView.GetAt(findidx);
+ c4_View tagView = d->ptags(row);
+ c4_Row findrow;
+ d->ptag(findrow) = tag.utf8().data();
+ int tagidx = tagView.Find(findrow);
+ if (tagidx == -1)
+ {
+ tagidx = tagView.Add(findrow);
+ d->ptags(row) = tagView;
+ d->archiveView.SetAt(findidx, row);
+
+ // add to tag->articles index
+ c4_Row tagrow;
+ d->ptag(tagrow) = tag.utf8().data();
+ int tagidx2 = d->tagView.Find(tagrow);
+ if (tagidx2 == -1)
+ tagidx2 = d->tagView.Add(tagrow);
+ tagrow = d->tagView.GetAt(tagidx2);
+ c4_View tagView2 = d->ptaggedArticles(tagrow);
+
+ c4_Row row3;
+ d->pguid(row3) = guid.ascii();
+ int guididx = tagView2.Find(row3);
+ if (guididx == -1)
+ {
+ guididx = tagView2.Add(row3);
+ tagView2.SetAt(guididx, row3);
+ d->ptaggedArticles(tagrow) = tagView2;
+ d->tagView.SetAt(tagidx2, tagrow);
+ }
+ markDirty();
+ }
+}
+
+void FeedStorageMK4Impl::removeTag(const QString& guid, const QString& tag)
+{
+ if (!d->taggingEnabled)
+ return;
+
+ int findidx = findArticle(guid);
+ if (findidx == -1)
+ return;
+
+ c4_Row row;
+ row = d->archiveView.GetAt(findidx);
+ c4_View tagView = d->ptags(row);
+ c4_Row findrow;
+ d->ptag(findrow) = tag.utf8().data();
+ int tagidx = tagView.Find(findrow);
+ if (tagidx != -1)
+ {
+ tagView.RemoveAt(tagidx);
+ d->ptags(row) = tagView;
+ d->archiveView.SetAt(findidx, row);
+
+ // remove from tag->articles index
+ c4_Row tagrow;
+ d->ptag(tagrow) = tag.utf8().data();
+ int tagidx2 = d->tagView.Find(tagrow);
+ if (tagidx2 != -1)
+ {
+ tagrow = d->tagView.GetAt(tagidx2);
+ c4_View tagView2 = d->ptaggedArticles(tagrow);
+
+ c4_Row row3;
+ d->pguid(row3) = guid.ascii();
+ int guididx = tagView2.Find(row3);
+ if (guididx != -1)
+ {
+ tagView2.RemoveAt(guididx);
+ d->ptaggedArticles(tagrow) = tagView2;
+ d->tagView.SetAt(tagidx2, tagrow);
+ }
+ }
+
+ markDirty();
+ }
+}
+
+QStringList FeedStorageMK4Impl::tags(const QString& guid)
+{
+ QStringList list;
+
+ if (!d->taggingEnabled)
+ return list;
+
+ if (!guid.isNull()) // return tags for an articles
+ {
+ int findidx = findArticle(guid);
+ if (findidx == -1)
+ return list;
+
+ c4_Row row;
+ row = d->archiveView.GetAt(findidx);
+ c4_View tagView = d->ptags(row);
+ int size = tagView.GetSize();
+
+ for (int i = 0; i < size; ++i)
+ list += QString::fromUtf8(d->ptag(tagView.GetAt(i)));
+ }
+ else // return all tags in the feed
+ {
+ int size = d->tagView.GetSize();
+ for (int i = 0; i < size; i++)
+ list += QString(d->ptag(d->tagView.GetAt(i)));
+ }
+
+ return list;
+}
+
+void FeedStorageMK4Impl::add(FeedStorage* source)
+{
+ QStringList articles = source->articles();
+ for (QStringList::ConstIterator it = articles.begin(); it != articles.end(); ++it)
+ copyArticle(*it, source);
+ setUnread(source->unread());
+ setLastFetch(source->lastFetch());
+ setTotalCount(source->totalCount());
+}
+
+void FeedStorageMK4Impl::copyArticle(const QString& guid, FeedStorage* source)
+{
+ if (!contains(guid))
+ addEntry(guid);
+ setComments(guid, source->comments(guid));
+ setCommentsLink(guid, source->commentsLink(guid));
+ setDescription(guid, source->description(guid));
+ setGuidIsHash(guid, source->guidIsHash(guid));
+ setGuidIsPermaLink(guid, source->guidIsPermaLink(guid));
+ setHash(guid, source->hash(guid));
+ setLink(guid, source->link(guid));
+ setPubDate(guid, source->pubDate(guid));
+ setStatus(guid, source->status(guid));
+ setTitle(guid, source->title(guid));
+ setAuthor(guid, source->author(guid));
+
+ QStringList tags = source->tags(guid);
+ for (QStringList::ConstIterator it = tags.begin(); it != tags.end(); ++it)
+ addTag(guid, *it);
+}
+
+void FeedStorageMK4Impl::setEnclosure(const QString& guid, const QString& url, const QString& type, int length)
+{
+ int findidx = findArticle(guid);
+ if (findidx == -1)
+ return;
+ c4_Row row;
+ row = d->archiveView.GetAt(findidx);
+ d->pHasEnclosure(row) = true;
+ d->pEnclosureUrl(row) = !url.isEmpty() ? url.utf8().data() : "";
+ d->pEnclosureType(row) = !type.isEmpty() ? type.utf8().data() : "";
+ d->pEnclosureLength(row) = length;
+
+ d->archiveView.SetAt(findidx, row);
+ markDirty();
+}
+
+void FeedStorageMK4Impl::removeEnclosure(const QString& guid)
+{
+ int findidx = findArticle(guid);
+ if (findidx == -1)
+ return;
+ c4_Row row;
+ row = d->archiveView.GetAt(findidx);
+ d->pHasEnclosure(row) = false;
+ d->pEnclosureUrl(row) = "";
+ d->pEnclosureType(row) = "";
+ d->pEnclosureLength(row) = -1;
+
+ d->archiveView.SetAt(findidx, row);
+ markDirty();
+}
+
+void FeedStorageMK4Impl::enclosure(const QString& guid, bool& hasEnclosure, QString& url, QString& type, int& length)
+{
+ int findidx = findArticle(guid);
+ if (findidx == -1)
+ {
+ hasEnclosure = false;
+ url = QString::null;
+ type = QString::null;
+ length = -1;
+ return;
+ }
+ c4_Row row = d->archiveView.GetAt(findidx);
+ hasEnclosure = d->pHasEnclosure(row);
+ url = d->pEnclosureUrl(row);
+ type = d->pEnclosureType(row);
+ length = d->pEnclosureLength(row);
+}
+
+void FeedStorageMK4Impl::clear()
+{
+ d->storage->RemoveAll();
+ if (d->taggingEnabled)
+ d->tagStorage->RemoveAll();
+ setUnread(0);
+ markDirty();
+}
+
+} // namespace Backend
+} // namespace Akregator
diff --git a/akregator/src/mk4storage/feedstoragemk4impl.h b/akregator/src/mk4storage/feedstoragemk4impl.h
new file mode 100644
index 000000000..d27933d0f
--- /dev/null
+++ b/akregator/src/mk4storage/feedstoragemk4impl.h
@@ -0,0 +1,107 @@
+/*
+ This file is part of Akregator.
+
+ Copyright (C) 2005 Frank Osterfeld <frank.osterfeld@kdemail.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ As a special exception, permission is given to link this program
+ with any edition of Qt, and distribute the resulting executable,
+ without including the source code for Qt in the source distribution.
+*/
+#ifndef FEEDSTORAGEMK4IMPL_H
+#define FEEDSTORAGEMK4IMPL_H
+
+#include "feedstorage.h"
+namespace Akregator {
+namespace Backend {
+
+class StorageMK4Impl;
+class FeedStorageMK4Impl : public FeedStorage
+{
+ public:
+ FeedStorageMK4Impl(const QString& url, StorageMK4Impl* main);
+ virtual ~FeedStorageMK4Impl();
+
+
+ virtual void add(FeedStorage* source);
+ virtual void copyArticle(const QString& guid, FeedStorage* source);
+ virtual void clear();
+
+ virtual int unread();
+ virtual void setUnread(int unread);
+ virtual int totalCount();
+ virtual int lastFetch();
+ virtual void setLastFetch(int lastFetch);
+
+ virtual QStringList articles(const QString& tag=QString::null);
+
+ virtual QStringList articles(const Category& cat);
+
+ virtual bool contains(const QString& guid);
+ virtual void addEntry(const QString& guid);
+ virtual void deleteArticle(const QString& guid);
+ virtual int comments(const QString& guid);
+ virtual QString commentsLink(const QString& guid);
+ virtual void setCommentsLink(const QString& guid, const QString& commentsLink);
+ virtual void setComments(const QString& guid, int comments);
+ virtual bool guidIsHash(const QString& guid);
+ virtual void setGuidIsHash(const QString& guid, bool isHash);
+ virtual bool guidIsPermaLink(const QString& guid);
+ virtual void setGuidIsPermaLink(const QString& guid, bool isPermaLink);
+ virtual uint hash(const QString& guid);
+ virtual void setHash(const QString& guid, uint hash);
+ virtual void setDeleted(const QString& guid);
+ virtual QString link(const QString& guid);
+ virtual void setLink(const QString& guid, const QString& link);
+ virtual uint pubDate(const QString& guid);
+ virtual void setPubDate(const QString& guid, uint pubdate);
+ virtual int status(const QString& guid);
+ virtual void setStatus(const QString& guid, int status);
+ virtual QString title(const QString& guid);
+ virtual void setTitle(const QString& guid, const QString& title);
+ virtual QString description(const QString& guid);
+ virtual void setDescription(const QString& guid, const QString& description);
+ virtual void setEnclosure(const QString& guid, const QString& url, const QString& type, int length);
+ virtual void removeEnclosure(const QString& guid);
+ virtual void enclosure(const QString& guid, bool& hasEnclosure, QString& url, QString& type, int& length);
+
+ virtual void addTag(const QString& guid, const QString& tag);
+ virtual void removeTag(const QString& guid, const QString& tag);
+ virtual QStringList tags(const QString& guid=QString::null);
+
+ virtual void addCategory(const QString& guid, const Category& category);
+ virtual QValueList<Category> categories(const QString& guid=QString::null);
+
+ virtual void setAuthor(const QString& guid, const QString& author);
+ virtual QString author(const QString& guid);
+
+ virtual void close();
+ virtual void commit();
+ virtual void rollback();
+
+ virtual void convertOldArchive();
+ private:
+ void markDirty();
+ /** finds article by guid, returns -1 if not in archive **/
+ int findArticle(const QString& guid);
+ void setTotalCount(int total);
+ class FeedStorageMK4ImplPrivate;
+ FeedStorageMK4ImplPrivate* d;
+};
+
+}
+}
+#endif // FEEDSTORAGEMK4IMPL_H
diff --git a/akregator/src/mk4storage/metakit/CHANGES b/akregator/src/mk4storage/metakit/CHANGES
new file mode 100644
index 000000000..160c4bad9
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/CHANGES
@@ -0,0 +1,1690 @@
+2004-01-26 ############################################ MK 2.4.9.3
+
+ Maintenance release, consolidates past 9 months of changes/tweaks.
+
+ Fixed test for "__name__" in python/metakit.py to run a quick test.
+
+2004-01-22 Fixed refcount problem with temp rows in Mk4tcl
+
+ This was a long-standing bug: "mk::row create" did not work right
+ because the tracking of temporary rows was completely messed up.
+ Added test case for Tcl (mk6.8), fixes FB14, BTS#78, and BTS#29.
+
+2004-01-21 Documentation updates
+
+ Updated copyright notices to 2004, and udated to Doxygen 1.3.5 for
+ a new set of C++ documentation. In anticipation of next release.
+
+2004-01-20 Don't trip over duplicate property names
+
+ Added code in c4_Field constructor to avoid crashing when there is a
+ duplicate property name in the format description string. Duplicate
+ names are now ignored (there is no good way to report errors at this
+ point). Avoids an even bigger problem: conflicting property types.
+
+ Added test s49 to detect this case (FB20, reported by Brian Kelley).
+
+2004-01-18 Fixed rare but very serious subview resizing bug
+
+ Fixed rare but serious file damaging bug, when resizing a comitted
+ subview to empty, committing, and then resizing back to containing
+ data. Added new s48 test to force this bug to the surface.
+
+ Fortunately this usage pattern *never* happens in blocked views!
+ Fixes are at the end of c4_FormatV::Insert and c4_FormatV::Remove.
+
+2004-01-16 Gracefully deal with bad property type specifiers
+
+ When GetAs is a called with a bad description, such as for example
+ "myview[name:A]", the release code would crash on a null pointer
+ dereference at some point. Changed so the code now treats any type
+ it does not know about as "I" (works a bit better than using "S").
+
+ The debug build still hits an assertion, as before. Added s47 test.
+
+2004-01-03 Fixed typo in PyView.cpp
+
+ Forgot to fix closing brace after the 2003-12-11 mods.
+
+2003-12-21 Fixed Mk4too sorting on subview of length 1
+
+ There was a silly bug when sorting on subviews in the new Mk4too
+ interface (not in Mk4tcl), which returns a view, instead of a list
+ of integers. In the case of 1 row, optimization was done wrongly,
+ omitting the sort as well as the remapping. Fixed.
+
+ Oomk needs to be patched to work around this (don't sort if n=1).
+
+2003-12-13 Tweak to avoid two unisgned/signed compiler warnings
+
+ In remap.cpp, compiled in debug mode on Win32 (DWORD vs. t4_i32).
+
+2003-12-11 Checked in numerous changes to Mk4py by Nicholas Riley
+
+ All changes are local to the python/directory - for details, see
+ http://www.equi4.com/pipermail/metakit/2003-September/001407.html
+ With a big thank you to Nicholas for contributing these improvements.
+
+2003-11-23 Bumped to Python 2.3, doc tweaks, lots of name fixes
+
+ Adjusted makefile to now look for Python 2.3 by default.
+ Regenerated config files. Fixed obsolete links in the doc files.
+
+ Got rid of tons of Metakit "interCap" cases, should be Metakit.
+ This affects a huge number of source files and one #define (which
+ has been defined twice for compatibility: d4_MetakitLibraryVersion).
+ Use "cvs diff -i" to see real changes, other than case swapping.
+
+2003-10-28 Get rid of --enable-python, check in c22.txt
+
+ It's not valid, but some files mentioned it. Use --with-python.
+ Forgot to check in the new c22.txt file added earlier this month.
+
+2003-10-16 Added note to Tcl docs
+
+ Added a note to doc/tcl.html on how to load a MK datafiles stored in
+ another one, as needed when using VFS for example.
+
+2003-10-10 Added c22 test
+
+ Added test to make sure groubpy/select bug is not present in the C++
+ core (bts #75 reports the bug found for Mk4tcl/Mk4too).
+
+2003-10-01 Fixed bugs in Tcl test suite
+
+ The tests in tcl/test/ were incorrectly closing non-test datafiles,
+ such as the "exe" one open while tclkit runs, and needed when a
+ slave is created which needs to re-run init.tcl etc from VFS.
+
+2003-09-30 Python 2.3.1 & cleanup
+
+ Tweaked PWONumber.h and PyRowRef.cpp and MSVC6 project so it can
+ compile Mk4py for Python 2.3.1 again. Windows binary uploaded.
+
+ Removed the win/msvc60/tests/ directory, it's no longer needed.
+
+2003-09-20 Autoconf and libtool rebuilds
+
+ In an attempt to stay ahead of version trouble and other nonsense,
+ the autoconf / configure and libtool files have been regenerated.
+ Autoconf is at 2.57 and libtoolize is at 1.4.3 on this dev system.
+
+2003-08-26 Documentation fix
+
+ Fixed install comments for Mk4py, as reported in bts #59.
+
+2003-07-17 Fixes to Mk4py (Gordon)
+
+ Fix crash when db.description(nm) is called for missing view "nm".
+ Fix wrap - for the special case of wrapping a list of primitives
+ (eg, ints, floats, strings) in a single property "view".
+
+2003-07-11 Fix for Linux not finding .lai file
+
+ Posted for RH 8.0 on MK mailing list by Jeff Web on July 3rd.
+
+2003-07-01 Fixed "Metakit" (preferred) vs "Metakit" (obsolete)
+
+ Get rid of InterCappedWords. Time to grow up, d00d...
+
+2003-06-06 Fix to Mk4py for case (in)sensitivity.
+
+ When using a dict (or keyword args), makeRow now gets the
+ names from the dict's keys and gets the properties by name.
+ This allows case insensitive matching. Note that using an
+ instance still requires that the instance attributes have
+ names that match (case sensitive) with the view.
+
+2003-05-15 Add distutils setup.py script (Gordon).
+
+ Tested on Linux & Windows (MSVC).
+ You can now do a plain configure / make (without python)
+ then cd python; python setup.py build | install
+
+2003-05-08 Fixed array bound bug when not using mmap-ed files
+
+ There was an incorrect test, when dealing with a new file and
+ memory mapping is not enabled (which is uncommon, these days).
+ Thanks to V Demarco for catching and resolving this bug.
+
+2003-04-28 Sourceforge
+
+ Synced to SF's CVS, see http://sourceforge.net/projects/metakit
+
+2003-04-25 Autoconf/libtool update
+
+ Did "autoreconf -force" with autoconf 2.5.7 and libtool 1.4.3, as
+ suggested by Gerfried Fuchs/Ryan Murray. Some Makefile.in tweaks.
+
+2003-04-22 Fixes to Mk4py (Gordon).
+
+ Make view.append(instance) work again.
+ Fix recursively adding subview data.
+ Make properties compare properly.
+ Initial (incomplete) unittest based test script.
+
+2003-03-16 ############################################ MK 2.4.9.2
+
+ Also allow passing pairs to "mk::row append" as a list (Mk4tcl).
+
+2003-03-10 Fixes for sparc64 configure and AIX strcasecmp
+
+ Both changes contributed by Andreas Kupries.
+
+2003-03-07 Fix more bugs in blocked view, add 64-bit Sparc support
+
+ The blocked viewer deletion was STILL incorrect. Fixed bad offset
+ calculations, added several more assertion checks, and added a new
+ m07 test case which checks for numerous cases of deletion overlap,
+ i.e. cases where multi-row deletions cross subview boundaries.
+
+ Added __sparc9 #define to mk4.h (thanks again, Andreas K)
+
+2003-03-05 Fixed two potential races in C++ threaded build
+
+ There was a serious bug in view.cpp, whereby Unix (p)thread locks
+ were non-functional in release mode (#define NDEBUG). Yikes!
+
+ In addition the logic was flawed (both Unix and Windows), failing to
+ protect from indexing while sPropNames / sPropCounts were being
+ resized (i.e. a realloc). Added explicit locking to all affected
+ paths, and removed the now obsolete count locks (i.e. AddRef).
+
+ Thanks to Murat Berk for chasing this and explaining the problem.
+
+ This bug "only" affects C++ builds. Tcl and Python each have an
+ extra layer on top which means there can be no races inside MK.
+
+2003-03-03 ############################################ MK 2.4.9.1
+
+ Moving to a new 4-level bugfix release number.
+
+2003-03-02 Fixes to Mk4py (gmcm)
+
+ Modify some recent patches that were Python 2.2 only so they would
+ still work with 2.1. Add a view.properties() method (returning a
+ dict of propname -> Property) for cases where a property is masked
+ by a method name.
+
+2003-03-01 Reverted changes in Mk4py/scxx, avoid Mk4tcl warning
+
+ One was in SCXX, PWONumber.h - ouch and apologies (jcw). Changed
+ comparison logic in mk4too.cpp (64-bit ints, new code).
+
+2003-02-28 Fixed relaxed layout in Mk4tcl, several Mk4py fixes
+
+ Use list operators to convert a Tcl layout to MK format. This used
+ to crash, Tcl test 6.7 added to verify the fix. Changed test 3.1 to
+ use a different notation for nested defs (^).
+
+ Added to ViewerAsSeq, to allow v1+v2+v3 (thanks Michael Scharf).
+ Also fixed several mem leaks - thx again!
+
+2003-02-27 Added support for HPUX aCC "long long"
+
+ Added #ifdef's to mk4.h to match autoconf HAVE_LONG_LONG settings.
+ Tweaks to configure.in by Andreas K to better support HP/UX (thx!).
+
+2003-02-26 Added 64-bit int support to Mk4tcl, fix mingw
+
+ The "L" type was not exposed, though Tcl >= 8.4 has "wide" ints!
+ Will now support 64-bit ints, if built against a Tcl 8.4+ header, but
+ still defaults to without for use in Tcl's <= 8.3.
+
+ Fix _strdup #ifdef in univ.cpp when compiled from mingw on win32.
+
+2003-02-24 Break was missing in switch Mk4py
+
+ Fixed a serious problem, which must have come from editing too
+ wildly (Mk4py needs a test suite!).
+
+2003-02-20 Remove a stray include, remove CR's
+
+ Remove "#include <stdio.h>" from remap.cpp, leftover from debugging.
+ Also removed CR's left behind from editing under Windows (doh!).
+
+2003-02-18 ############################################## MK 2.4.9
+
+ This is mostly a bug fix release (some features added to Mk4tcl).
+
+2003-02-18 Fixed a bug in blocked view deletion, and hash byteorder
+
+ There was an off-by-one error in the deletion of multiple rows
+ which span more than an entire subview block. Test m06 is ok now.
+ Also added consistency checks (when compiled in debug mode).
+
+ Fixed a too-strict assertion in mk4tcl.cpp, Item destructor.
+
+ Fixed a byte-order sensitivity in hash views for numeric properties.
+
+2003-02-17 Configure tweaks for hpux/ia64
+
+ Re-instated hpux changes by A. Kupries, for ia64, also -lpthread.
+
+2003-02-14 Bug found in blocked viewer modification
+
+ Added test m06 to catch a problem first detected in the Tcl test
+ suite (test 5.7) - recoded to C++. This is a show-stopper for the
+ upcoming 2.4.9 release - fixing it is now a top priority.
+
+2003-02-14 Some changes to OO interface in Tcl
+
+ The OO "select" cmd now returns a view, not a list of row #'s.
+ Added "product" and "rename" operators, they were not exposed.
+
+2003-02-14 Enable stdio buffering
+
+ On platforms where stdio is used, the setbuf(..., 0) calls have been
+ removed (fileio.cpp). This improves performance, and lets caller set
+ up whatever buffering they like.
+
+2003-02-07 Tweaks to restore broken MK ports
+
+ Fixes by A. Kupries to fix MK builds I broke (Itanium/HPUX).
+
+2003-02-07 Changed code to avoid compiler warning
+
+ In remap.cpp, LookDict(), add return at end to avoid a mistaken
+ compiler warning (on AIX 5.1). No effect on runtime behavior.
+
+2003-02-02 Work around optimizer bug in gcc 3.2.1
+
+ The sign-extension in c4_ColOfInts::Get_16r was not being done right
+ with -O2 on Linux. This only manifests itself with files having
+ reversed bytes (e.g. PowerPC/Mac). Changed code to use a local temp
+ buffer instead. This bug was the reason why some starkits failed to
+ load when created on Mac and used on Linux.
+
+2003-01-24 Fixed cleanup order bug in Mk4tcl
+
+ There was a long-standing bug in Mk4tcl, in which cleanup order of
+ MkPath objects caused them to access their MkWorkspace parent even
+ though it was already deleted. This may have caused some of the
+ crash-on-exit bugs in the past.
+
+2003-01-22 Add missing -lstdc++
+
+ For unknown reasons, the current make failed to produce shared libs
+ with libstdc++ linked in - manually added to LDFLAGS again.
+
+2003-01-19 Tweak to temp object use
+
+ Two changes in handler.cpp to avoid bug in compilers which get the
+ cleanup logic of temp objects wrong (thx, Dan Gregory).
+
+2003-01-17 Add synonym for mk4tcl "info" command
+
+ To avoid a name clash, "$view info" can now also be written as
+ "$view properties" (or an abbreviation of that).
+
+2003-01-16 Allow access to root view in Mk4tcl
+
+ Access to root view (i.e. the storage object itself) was not
+ allowed - added a small change to allow this (MkPath::AttachView).
+
+2003-01-15 Use strdup
+
+ On Unix, use strdup i.s.o own code for _strdup, see univ.cpp.
+ Perhaps it's time to start reversing the names, and make unix std.
+
+2003-01-10 Build improvements, Mk4py long and Mac improvements
+
+ Merged changes submitted by Nicholas Riley (thanks!) into CVS:
+ - changes to build Mk4py on MacOS X (framework/dylib)
+ - support 'L' fields, handle overflow, throw exceptions
+ - the beginnings of a test suite for Mk4py (in python/test/)
+
+ Separated PPC and 68K projects (Mac classic), because PPC is now
+ built with 8.3 (Carbon support), while 68K requires 6.3. The x86
+ cross-compile-from-mac projects have been dropped.
+
+2003-01-09 String compare tweak, Mac Carbon runtime mmap code
+
+ Use strcasecmp on unix, instead of own code (string.cpp).
+
+ Added code based on Paul Snively's contributed patch to recognize
+ running under OSX, so carbon apps can benefit from mmapped files.
+ All changes are within fileio.cpp, requires CW8 to build this way.
+ Added "PPC Carbon" target to cw.mcp, derived from "PPC DLL" one.
+
+2002-12-23 Tweak for Borland builder 5 & 6
+
+ Changed #ifdef line 22 in univ.cpp (fix by S. Cusack).
+
+2002-12-09 Fixed bug in selection view change propagation
+
+ Fixed a bug when a row is inserted in a view on which a selection
+ depends, when the inserted position is not part of the derived one.
+ This looks like an oversight in 2.3/2.4 changes, and must have been
+ in there for quite some time. Added new n14 test to verify this.
+
+2002-12-02 Fixed bug in MK old-file format conversion
+
+ Fixed bug in on-the-fly conversion of old 1.x/2.0.x format files.
+
+2002-11-24 Fixed Mk4tcl threaded build
+
+ Release and reclaim mutex lock while calling eval inside loops.
+ Added "--enable-threads" option to configure script.
+
+2002-11-22 Configure tweak for HPUX/Itanium
+
+ Removed ia64 check in configure.in, now that libtool has been fixed.
+
+2002-11-16 Tweaks to compile on Mac
+
+ Small changes to the source code to avoid errors from the MWCW 8.x
+ compilers. Omit stricmp and strdup with CW version >= 8.
+
+2002-11-04 Fixed typo in Makefile
+
+ This prevented Mk4py from getting installed (thanks F. Majid).
+
+2002-11-03 ############################################## MK 2.4.8
+
+ Reverted non-portable change in Makefile to copy to "Mk4tcl.*".
+
+2002-10-28 Workaround for bugs on ARM/WinCE and HP/UX, Mk4tcl/WinCE
+
+ Turn off c4_ColofInts::Set_8i optimization when compiling for ARM on
+ WinCE using EVC3. All regression tests now pass (on ARM & x86emu).
+
+ On HP/UX, enable copying in fileio.cpp, line 265, so a write is not
+ done directly from a mmap'ed file (this can hang a process, hard).
+
+ Added a "mktcl" subproject to msevc3, to build "Mk4tcl.dll".
+
+2002-10-27 Added multi-thread support for Unix
+
+ Added changes to support same appartment-threading model on Unix as
+ on Win32 (pthreads based). This merely adds support to allow safe
+ use of the current "each datafile in one thread" design on Unix. All
+ changes in view.cpp (thank you, M. Berk). Define q4_MULTI to enable.
+
+2002-10-26 Merged WinCE changes
+
+ Merged changes to build MK for WinCE using MS Embedded VC 3.0.
+ These changes are based on Joseph Tate's modifications (thanks!).
+
+2002-10-21 Updated autoconf & libtool (on teevie)
+
+ Files in unix/ regenerated with autoconf 2.53a and libtool 1.4.1.
+
+2002-10-16 Added "dup" subcommand to Mk4tcl OO
+
+ There was no way to duplicate a view in the mk4tcl OO interface.
+ Needed to properly deal with re-use / ref counts - added "dup".
+
+2002-10-11 Cast widened in Mk4tcl, support q4_TINY def for Mk4tcl
+
+ Changed cast from int to long, to avoid compiler warning on some
+ 64-bit machines (mk4tcl.cpp, line 2013).
+
+ Remove float/double code when q4_TINY is defined, also in Mk4tcl.
+
+2002-10-10 Makefile tweaks
+
+ Removed duplicate flags from CXXFLAGS definition.
+
+2002-10-09 Fixed blocked/subview bug, tweak for the ARM platform
+
+ Blocked viewers were not doing the right thing when rows had subviews
+ in them - fixed the logic, and add a new m05 test to verify it all.
+
+ Fixed a signed-char bug which prevented MK from passing all tests on
+ the ARM, in this case the Compaq iPaq PDA with Linux and gcc 2.95.4.
+
+2002-10-07 Tweak to prevent gcc compiler bug
+
+ Added intermediate temp var in derived.cpp to prevent gcc -O failure.
+
+2002-10-04 Config and makefile adjustments
+
+ Adjusted configure.in to use ".sl" for HP-UX, and ".dll" for Cygwin.
+
+ Changed "install -d" to "mkdir -p" (2x) in Makefile.in, since the
+ former is not supported by all incarnations of install (A Kupries).
+
+ Added @CXXFLAGS@ to the end of "CXXFLAGS =" lines in Makefile.in,
+ as suggested by Donal K. Fellows. Used for his IRIX(64) builds.
+
+ Added logic to build properly on HP-UX, including a small assembly
+ file (!) which allows loading C++ shared lib from C, as needed in
+ Tcl - with thanks to Andreas Kupries for solving and patching this.
+
+2002-09-25 Build tweaks for Mac OS X
+
+ Applied patches by Daniel Steffen to deal with ".dylib" (thanks!).
+
+ Use -O i.s.o. -O2, which caused test b27 to fail on OS X (gcc 3.1).
+
+2002-09-09 More 64-bit platforms recognized
+
+ Added #ifdefs for more 64-bit platforms, thanks to Reinhard Max.
+
+2002-09-08 Make tweaks for HP-UX
+
+ Tweaks to build on HP-UX / 9000 (added __hpux #ifdef in header.h).
+
+2002-09-03 Fixed Mac OSX build problem
+
+ Compile Mk4tcl lib with stubs only if building the shared lib.
+ Ignore strip errors (fails with Mk4tcl.so on OSX / dyld libs).
+
+2002-07-01 Python and Tcl installation improved
+
+ Now installs Python Mk4py.so and metakit.py in the most common dir
+ location by default, i.e. "/usr/local/lib/python2.2/site-packages".
+ Locations can be overridden through $pyincludedir and $pylibdir.
+
+ For Tcl, "make install" now constructs a standard package dir, i.e.
+ "/usr/local/lib/Mk4tcl/" with entries "Mk4tcl.so" and "pkgIndex.tcl".
+ Locations can be overridden through $tclincludedir and $tcllibdir.
+
+2002-05-30 ############################################## MK 2.4.7
+
+ Fix CONST84 logic so source compiles under both Tcl 8.3 and 8.4.
+ Fix creation of tests/CVS/ so diff in regression tests won't fail.
+
+2002-05-14 Fixed an adaptive int insert/delete bug
+
+ Another bug in the 2.3/2.4 codebase, related to adaptive integers.
+
+ Symptom: one int entry has incorrect bytes after insert/delete.
+
+ Scenario: ints are 1..8 bits, and an odd number are added/removed,
+ leaving an odd-sized internal "gap". Then store a 16/32 bit value,
+ forcing resizing. Once this is done, there will be one value which
+ cannot be properly read or set because its data is split *across* the
+ gap (commit is ok and removes the problem). Fix in column.{h,cpp},
+ with a new regression test s46 added to make sure things are ok now.
+
+ Let's hope that this is truly the *last* deeply embarrassing bug...
+
+2002-05-06 ############################################## MK 2.4.6
+
+ Recent bug fix was critical enough to warrant a new revision.
+ It is safest to avoid using versions 2.4.2 .. 2.4.5 altogether.
+
+2002-05-05 Fixed major bug in string/bytes after multiple commits
+
+ Finally found a way to reproduce spurious bugs reported in the latest
+ revisions. It turns out that one of the optimizations of the past 2
+ months (no exact details) caused memo's to be tracked incorrectly in
+ their free space use. This causes trouble with strings over 10 Kb
+ (or smaller if there are over 1000 rows).
+
+ The bug is forced by new (frightfully short) test cases s44 + s45.
+ Fixed by performing a slightly less agressive optimization in the
+ c4_FormatB::Commit (which is also shared with strings, type 'S').
+
+ Removed a "--exclude" from diff, which is not portable enough.
+
+2002-05-01 Added support for Windows CE
+
+ Patches submitted by Joseph Tate (thank you!), with minor tweaks.
+
+2002-04-29 ############################################## MK 2.4.5
+
+ Various bug fixes, fixed a number of platform issues.
+
+2002-04-28 Fix small-int re-use view bug
+
+ A nasty bug was reported by VPI which caused upper bytes to be
+ truncated from int values. The problem appears when storing ints of
+ 1..4 bits in a view, then clearing the view (so a gap is placed past
+ the end of the column), then adding a row with an int of 2 or more
+ bytes. This uncovered a bug in forgetting to truncate columns with
+ sub-byte int storage. Now fixed, added regression test s43.
+
+ This bug could also have affected string and byte storage, since
+ these use int columns to store item sizes. Under very specific
+ conditions, it may have lead to truncated or even mixed-up values.
+
+2002-04-27 Fix nested mk4tcl loop bug
+
+ Loops would exit prematurely when nested - due to objc/objv being
+ overwritten in the inner loop. Affects mk4tcl.cpp and mk4too.cpp.
+
+2002-04-10 Fix bug introduced in recent blocked viewer optimization
+
+ Murphy was at it again. The bug affected the way row inserts and
+ deletes were done, and can cause incorrect data to be copied. It is
+ relatively hard to reproduce (the test dataset was 12 Mb), but the
+ change explains things fully and is in fact very small.
+
+2002-04-02 Fix bug in debug code
+
+ In remap.cpp line 531, a debug assertion was moved in the wrong way.
+
+2002-04-01 Backed out to libtool 1.4d, fix test diff and Tcl const
+
+ Backed out to the more official 1.4d release of libtool (instead of
+ the CVS version, which is adding "tags" we will not need anyway).
+ The unix/Makefile.in has been simplified, back to how it used to be.
+
+ Fixed the "diff" call at the end of "make test" so that it no longer
+ generates extra output if things match and now fails if they do not.
+
+ Added fix to allow compiling mk4tcl.cpp with "pre-constified" Tcl
+ code, thanks to a tip by Don Porter (see "grep CONST84 mk4tcl.*").
+
+2002-03-31 ############################################## MK 2.4.4
+
+ Various bug fixes and (blocked view) performance enhacements.
+
+2002-03-28 More blocked optimizations, IRIX tweaks
+
+ Switched Slot() to binary search. This seems to slow down a few
+ percentage point for smaller views, but with 5 millions rows this is
+ reported to make a huge difference (from code by Zhang Dehua).
+
+ Added header "bool" fix by Erik Hofman so MK compiles on IRIX (SGI).
+
+2002-03-27 Added definitions for AIX
+
+ Added six operators defs before c4_Cursor class, to avoid compile
+ errors on AIX. With apologies to Murat Berk for taking so long...
+
+2002-03-26 Re-instated the c4_View::RelocateRows operation
+
+ Re-enabled code which supports efficient moves of rows from one view
+ to another - avoiding copying of subviews. Strings/memos are still
+ being copied for now. Also moved a slow test out into a new call
+ "c4_View::IsCompatibleWith", this must be checked to make sure that
+ RelocateRows can work. Passing incompatible views will still cause
+ an assertion in debug mode, but must be avoided in release builds.
+
+ This change ought to have a dramatic effect on inserts/deletes for
+ blocked views with large subviews. Added examples/blockdels.tcl to
+ thoroughly exercise this new code and all boundary conditions.
+
+2002-03-22 Fixed a serious bug in serialization code
+
+ When serializing string/bytes columns with large strings using the
+ c4_Storage::SaveTo function, memo's would sometimes not be written,
+ leading to a *damaged* datafile (and incorrect free-space tracking).
+
+2002-03-15 Better configure logic, "mk::view layout" fix
+
+ Many tweaks to configures, makes, and libtool setup. Get rid of the
+ library version numbers and the special Mk4*.so targets. Instead of
+ Mk4tcl.so use libmk4tcl.so (likewise Mk4py.so is now libmk4py.so).
+
+ Fixed "mk::view layout", it was broken by the 10-2-2002 change.
+
+2002-03-13 Extend partial access 'B' usage
+
+ Added code to Access and Modify to simulate partial data access the
+ hard way when the underlying view does not support it (c4_Bytes
+ only), i.e. copy via full temp. Added test s41, doing partial access
+ on a blocked view.
+
+2002-03-12 Add test for serialized input
+
+ The c4_Storage::LoadFrom() call (mk::file load) can be tricky. After
+ a commit, the header is adjusted so that reading from the start
+ works. This is not the case in commit-extend mode, where a load will
+ read th state as it was before extending - it cannot know there is
+ more.
+
+ Added test s40 to verify this case. Also reorged a few more files
+ (tbasics and tstore4 split into 2 each).
+
+ Added test in mk4tl.cpp so LoadFrom failure generates an error
+ return, instead of being ignored.
+
+2002-03-10 Tweaked March 8 fix a tad further
+
+ The workaround implemented below wasn't 100% complete.
+
+2002-03-08 Workaround for file extend on Win
+
+ There seems to be a bug when extending a file on at least NT4 with
+ NTFS (file server works fine). When extending the file in such a way
+ that a gap is created to save new data during commit, the file
+ appears to get rounded up to the next 512-byte boundary. At that
+ point, the datafile no longer has a valid end marker and is sort of
+ corrupt.
+
+ Wrote workaround for Win32 builds, see persist.cpp notes names "March
+ 8, 2002". One way to force this bug is to run "mkhash Dmhs 250000" -
+ after row 150000, it asserts on bad filesize when built in debug mode
+ and run on NTFS.
+
+2002-02-19 Fixed over-aggressive optimization
+
+ Change made on Feb 7 was releasing too many objects in a commit,
+ causing it to detach empty top-level views, even when in use. Fixed,
+ added s39 to test for this case.
+
+2002-02-10 Improve Mk4tcl's "mk::view layout"
+
+ Avoid crash when asking for the layout of a non-existent view. Now
+ returns an error instead.
+
+2002-02-07 Fast commit with many empty subviews
+
+ Avoid creating subviews when committing, if these are empty anyway.
+ Added new s38 test for this case.
+
+2002-02-02 Small optimizations
+
+ Changed a few c4_Property instances to const& references to avoid
+ copying (2 in view.cpp, 2 in custom.cpp).
+
+2002-02-01 ############################################## MK 2.4.3
+
+ Bug-fix release, mostly.
+
+ Python include path now upgraded to python2.2 (was 2.1).
+
+2002-01-31 Cross-platform serialization, Tcl
+
+ There was a bug with serializing a datafile (SaveTo) when it was
+ created on a platform with reverse endian-ness. Fixed so serialized
+ data also flags reversed byte order.
+
+ Tweaks to fix const changes in the latest Tcl cvs branch. Fixed a
+ recently-introduced UTF8 path bug in mk4tcl.cpp.
+
+2001-12-21 Optimized GetAs
+
+ Now that GetAs is used so much more, optimize the common case where a
+ description does not require restructuring. Can lead to order-of
+ magnitude speed improvement in cases where a storage contains many
+ views.
+
+2001-12-20 Fixed bug in Locate, comparison issue
+
+ Testing for the Mk4py changes uncovered a serious bug in
+ c4_View::Locate, causing it to sometimes return zero, even if there
+ are matching rows (thanks, Gordon).
+
+ But a very fundamental weakness also showed up, being that row
+ comparisons (and that includes the C++ operators) have the confusing
+ property of not being symmetric in all cases. The problem occurs
+ when left- and right-hand sides do not contain the same (number of)
+ properties. In that case, the *left-hand* row participating in the
+ comparison determines which properties take part in a comparison.
+
+ In the case of Locate, this caused improper comparisons. And it is
+ very easy to get bitten by this, such as here: c4_RowRef key = ...;
+ int n = view.Search(key); bool match = n >= 0 && view[n] == key; The
+ above code is *wrong*. The last line needs to be: bool match = n >=
+ 0 && key == view[n];
+
+ This is very clearly a design mistake. Comparisons should have been
+ *either* implemented *or* named differently.
+
+ A new "m04" test has been added to the regression suite.
+
+2001-12-19 Changes to mk4py by Gordon McMillan
+
+ Several changes and cleanups. Mk4py now has logic to track different
+ view categories, e.g. to make sure a R/O view is not being written
+ to. This should greatly reduce the number of silently ignored
+ incorrect calls, as well as crashes, and will produce appropriate
+ error messages instead.
+
+2001-12-18 Cleanup
+
+ Cleaned up source comments and got rid of yet more warnings.
+
+2001-12-14 Fixed yet another case of crash-on-exit
+
+ The new Unmapped() code of 2.4.2 forgot one case of cleaning up,
+ which has now been fixed (in c4_FormatB::Commit).
+
+2001-12-12 ############################################## MK 2.4.2
+
+ Better portability, hashing improved
+
+ This release marks the consolidation of a number of changes, mostly
+ relating to better portability & hashing. The speed of commits with
+ many strings and subviews should be notably better. The Tcl
+ extension no longer needs a "stub" library to compile (it now has
+ that code itself), just std headers.
+
+2001-12-08 Changes to commit cleanup, Mac stuff
+
+ Changed the logic of how ReleaseAllSegments gets called at the end of
+ commits. There was at least one case of leaving a column pointing
+ into mapped file space when it was about to be remapped. This should
+ fix a very long-tanding bug which shows itself as freeing unallocated
+ memory during commit or cleanup of the storage object.
+
+ Changes to test coding and PyRowRef.cpp to deal with builds on
+ Macintosh (different issues for MacOS 9 and MacOS X). The
+ mac/cw.sea.hqx project has been upgraded to MW CW 6.3. Verified Tcl
+ 8.3.2 and Python 2.1.1 builds with CW6 on Mac.
+
+2001-12-06 Tweaks to Tcl interface
+
+ More robust, added "$vw loop var ... {body}" object command. The
+ "$vw size" command now takes an optional newsize arg.
+
+2001-12-04 Tweaks to makefile and configure
+
+ Tweaks, in preparation of an upcoming 2.4.2 release.
+
+2001-12-03 Changes in M4py, avoid gcc problem, hash
+
+ The "-fomit-frame-pointer" option for gcc has been turned off,
+ because it causes problems with exception handling in Mk4py. All
+ failures in Mk4py now propagate properly to Python AFAIK.
+
+ Simplified Mk4py - by removing a layer of exception handler classes
+ in scxx. Errors now set info and throw a plain int.
+
+ The mkhash.cpp sample program exposed a problem with multi-key
+ hashing: the order of properties in the search key must match exactly
+ the order in the hash view itself. For now, this has been left as is
+ (it's easy to do, once you are aware of it).
+
+2001-11-30 Win MT fix, commit tweak, indent cleanup
+
+ Drop static buffer in fileio.cpp (DataWrite), uses stack now, so the
+ code can be used in MT context even on Win 95/98. It does more
+ copying than would be needed for NT (2K?), alas.
+
+ More changes in c4_FormatB::Commit to properly detect memo use in
+ blocked views. The recent changes introduced a bug which shows up
+ only with blocked views and large string/bytes items. Reported by
+ Steve Baxter with demo, new "m02" regression test.
+
+ Changed fileio.cpp to turn off file buffering, this avoids a few
+ reads when writing and seeking a lot. It does not have as big an
+ impact as one might expect, but every little bit helps.
+
+ Cleaned up new 2-space indentation in several source files.
+
+ Added new "mk::file space" in Mk4tcl, to inspect the current file
+ space usage. This is only intended for internal testing.
+
+2001-11-28 Fixed memory leak in string/memo cleanup
+
+ There was a mem-leak in c4_FormatB::Commit which showed up due to
+ yesterday's more extensive testing. Only showed up after a commit,
+ in string columns with widely varying item sizes. This caused
+ regression test s37 to fail in MFC-debug compile.
+
+2001-11-27 Major performance bug fix, and MT strings
+
+ A serious problem has been resolved, which slowed down commits, and
+ prevented blocked views from committing efficiently. The reason was
+ that for string props, the string size was always being saved anew,
+ even if no changes in that view took place. This did not affect
+ proper operation, just speed, and was most noticeable with many
+ (sub-)views containing many string props.
+
+ The solution is in src/format.cpp, the examples/mkhash.cpp code was
+ further adjusted to better expose and measure the effects. Thanks to
+ P. Baspeyras and S. Baxter for helping me resolve it.
+
+ Another change was to alter the way empty strings are allocated in
+ the src/string.cpp code, making it compatible with multi- threaded
+ use and removing the remaining memory leak.
+
+2001-11-26 Fix in assertion check (blocked view)
+
+ Corrected an off-by-one bug. Only shows up with debugging on, since
+ it's inside an assert(). Thanks to Steve Baxter.
+
+2001-11-25 More arg checking in Mk4py, locate
+
+ Added more checks against incorrect usage, based on sample code by
+ Mitch Chapman. The "throw" code appears to be inconsistent when
+ called at top of *some* calls, using a workaround for now.
+
+ Added "view.locate(key)" wrapper, returns (pos,count) tuple.
+
+ Various source code formatting adjustments (indents and such).
+
+2001-11-04 Added alternate calls to c4_CustomViewer
+
+ Added extra defs to "mk4.h" of Lookup and InsertRows which take a
+ "const c4_RowRef&" i.s.o. a c4_Cursor. Inlined in "mk4.inl". The
+ "c4_Cursor" datatype might one day become obsolete.
+
+2001-11-03 Removed tcl/kit/ and copyright notices
+
+ Removed the entire tcl/kit/ tree, Tclkit will be distributed as
+ separate package from now on (the 2.4.1 release still builds ok).
+
+ Also replaced all copyright notices by version Id's and an URL.
+
+2001-11-02 Fixed partial memo commit bug, makefile fix
+
+ Modifying a small item as memo (i.e. through Modify) properly
+ committed a change, but subsequently left an incorrect pointer after
+ the commit. Fixed, and added test s37 to catch this case.
+
+ Don't strip symbols from installed static libs (whoops!).
+
+2001-10-31 Fixed Mk4py error flag clear on delete
+
+ When deleting rows, a slice was constructed from a PWOSequence, which
+ generates an otherwise harmless error when its length is checked.
+ The flag was not cleared, causing errors in subsequent Python
+ statements. Changed to a PWOTuple in PyView.cpp (2x).
+
+2001-10-26 Fixed Mk4tcl re-open test
+
+ The tcl/test/mk1basic.tcl test #6 was reporting open failure on
+ non-Linux systems. Fixed, the code works, the message was wrong.
+
+2001-10-19 Rearranged some demo files, Lua binding
+
+ Rearranged some of the demos/samples from the python/ and tcl/ areas,
+ and placed them in examples/ instead, for consistency.
+
+ Added "selmap.tcl" to illustrate how to turn select into a view.
+
+ Added a basic Lua binding (incomplete, but it's a start) in lua/.
+
+2001-10-18 Fixed recent hash bug, and add to ordered
+
+ The recent "fix" to deal with hash misses introduced a huge bug,
+ causing the mapping to be recalculated on each insertion.
+
+ Adding to an ordered view did not always work, because the code was
+ based on SetAtGrow, which is not suitable for an ordered view in
+ which the row position is determined implicitly. Fixed by changing
+ c4_View::Add to use c4_View::InsertAt instead.
+
+2001-10-14 ############################################## MK 2.4.1
+
+ Custom-extended Tclkit, and threading
+
+ Minor kitInit.c change allows wrapping apps as a "custom-extended"
+ version of Tclkit. Enable threaded Tcl build on Unix.
+
+ This release consolidates the most recent fixes and code tweaks.
+
+2001-09-27 Fix temp storage open in Mk4tcl
+
+ A recent change made it impossible to open temporary storages from
+ Tcl ("mk::file open db") - <blush> - now fixed again.
+
+2001-09-19 Bug fixes
+
+ Fixed a problem during commit, when memo's are modified, causing them
+ to be stored inline again. This caused a late reference to mapped
+ memory - leading to intermittent crashes on commit.
+
+ Changes/fixes in mk4tcl.cpp, to prevent a problem when a datafile is
+ re-opened again under the same name later on. Old references could
+ in some cases end up stale - leading to crashes much later.
+
+2001-09-05 Bug fixes
+
+ Hashing bug fixed: failed to terminate when looking for a missing key
+ after a hash collision. The fill count was not being tracked
+ properly to enforce that there is always at least one unused slot.
+
+ Fixed bug when setting a string from a higher row: the data gets
+ trashed, because too little copying was done while creating a gap.
+ This bug may have led to some other cases of "damaged" datafiles.
+ Solved by copying input data in c4_FormatB::SetOne().
+
+ Fixed long-standing bug with commit-after-load, by now doing a full
+ view/subview copy. This is inefficient, but it avoids all sorts of
+ mapping/strategy problems. This also fixes test s33 (at last!).
+
+ Added regression tests b27, c21, m01, and s36 to check above fixes.
+
+2001-06-29 ############################################## MK 2.4.0
+
+ More changes to the Mk4py interface
+
+ - allow setting a row to a value if the row has a single property
+ - there is an unexplained crash when setting slices with wrong type
+
+2001-06-22 Changes to the Mk4py interface
+
+ Modifications and fixes gratefully accepted from John Barnard:
+ - c4_LongProp support ('L' datatype)
+ - row.__attrs__ returns the list of all properties
+ - row.__view__ returns the container view of the row
+ - row.__index__ returns current position in view
+ - view.setsize(n) added, extends/truncates number of rows
+ - generalized makerow to allow any sequence, not just lists
+
+ Changed PyRowRef to inc/dec the reference it has to the underlying
+ view. Should prevent dangling pointer problems, such as deleting a
+ storage while rows are still in use. This adds a little overhead.
+
+ Fixed a PyErr_Clear issue when accessing non-existent properties.
+
+2001-06-12 Close DB filedesc on exec
+
+ Added an fcntl call to fileio.cpp, so that on Unix database file
+ decriptors are closed on exec (relevant when doing "exec ... &").
+
+2001-05-30 Fixed mem-leak in Mk4tcl
+
+ A long-standing bug, in TclSelector::ExactKeyProps.
+
+2001-05-28 Security fix in Tclkit
+
+ See end of the tcl/kit/README file for deatils.
+
+2001-03-30 Fixed long-standing commit bug
+
+ There was an intermittent bug in c4_Persist::Commit, when properties
+ were "restructured away" (dropped). The bug was hard to track down,
+ because it depended on what address ranges the O/S assigned to
+ mem-maps. Might also fix other spurious commit/exit crashes.
+
+2001-03-29 ############################################## MK 2.3.4
+
+ The "last" release candidate
+
+ Now checked into its *new* CVS home at equi4.com. Mailings list(s)
+ have also been moved to this site.
+
+2001-03-28 Fix Win build, broken on Mar 27
+
+ Dropped kBufMax from mk4.h, it caused compiler errors in MSVC6 -
+ switched to "sizeof" in a couple of places. This error was
+ introduced by the double-fix of 3/27.
+
+2001-03-28 Allow builds of Tclkit with Sun CC
+
+ Integrated a few changes provided by D.J. Hagberg. Note: the
+ M-solaris.sh and M-dyn.sh scripts need to be manually edited when
+ choosing between CC and gcc.
+
+2001-03-27 Double-alignment bug on Solaris
+
+ Two changes (c4_Bytes in mk4.h and src/column.h) to fix an alignment
+ problem for 8-byte doubles on Solaris. This caused tests b17, b23,
+ b24, s22, and s28 to fail.
+
+2001-03-26 Fixed cross-platform commit bug
+
+ There was a nasty bug in the 2.3.x code, which wrote incorrect field
+ sizes when committing to a datafile with a different byte order
+ (i.e. created on a machine using different endian-ness from the one
+ doing commit).
+
+2001-02-14 Removed file events from Tclkit
+
+ Changed kit/rechan.cpp to not generate file events. This avoids a
+ bug in Tclkit whereby an open file can generate a continuous stream
+ of file events as long as the file is open - the console will seem
+ to be frozen, though "close $file" does work and fixes it.
+
+2000-12-13 Added missing c4_LongRef export
+
+ Added a line in mk4dll.h to resolve references to the new
+ c4_LongProp/c4_LongRef datatype on Windows.
+
+2000-12-04 Fixed conversion bug
+
+ There was a bug in c4_FormatV::OldDefine, causing MK to crash when
+ trying to convert an old-format file with empty subviews in it. Bug
+ introduced on 14 Nov.
+
+2000-12-02 Fixes in Tclkit code
+
+ Fixed a Tcl-level bug causing memory leaks for all compressed files
+ stored with MK opened for reading.
+
+ Disabled event sources (mk4tcl.cpp and rechan.cpp) to avoid a GUI
+ freeze-up while a fake file is open.
+
+2000-11-16 Simplified c4_Storage
+
+ Made some changes so that a c4_Storage no longer has a separate
+ c4_Persist* copy. As a result, a storage can now be reconstructed
+ from any root-level view. This generalizes views, and prepares for
+ a merge.
+
+2000-11-14 Fixed mem leak in conversion code
+
+ The conversion code from pre 2.3 files had a memory leak in
+ c4_FormatV::OldDefine, causing f06 to leak, as well as several
+ subsequent erroneous leak reports. Changed a few "new" to "d4_new"
+ calls along the way.
+
+ Remove FlipBytes members, they are no longer needed.
+
+2000-11-08 Tclkit now in the distribution
+
+ The "Tclkit" project has been merged into Metakit. Details and
+ updated build info at "tcl/kit/README". The SourceForge CVS
+ repository is up to date again.
+
+ Mk4py: improved number conversion and error handling.
+
+2000-11-03 ############################################## MK 2.3.3
+
+ First final release candidate
+
+ Yes, there will probably be a second one as well...
+
+2000-10-31 Improved error handling
+
+ More logic added to catch errors in flush and streams. This affects
+ the C++ core as well as Mk4py and Mk4tcl. API of c4_Stream::Write
+ changed to return success flag.
+
+2000-10-30 Added autocommit call to Mk4tcl
+
+ To better support VFS, Mk4tcl now has a new command "mk::file
+ autocommit <db>" to force commit on close.
+
+2000-10-26 Changes to compile with Borland C++
+
+ Minor tweaks to compile with Borland C++ Builder 4.0, which does not
+ support "long long". A new Kitviewer has been built (new code to
+ replace c4_View::Describe).
+
+2000-10-03 Fixes for Alpha Unix
+
+ Moved _item in column.h up to fix alignment sensitivity. Config.h
+ did not get SIZE_LONG right on Alpha Unix (0?).
+
+2000-09-27 Contributed fixes and Python 2.0b2
+
+ Adjusted makefile to build with Python 2.0b2 release.
+
+ Source code tweaks to avoid DEC CXX 5.7 compiler errors. Add
+ no-inherit flags for Win32 to not leak file handles.
+
+2000-08-27 Allow derived row deletes in Mk4py
+
+ Added code to PyView.cpp to handle deletes (and slice deletes) in
+ derived views, see "examples/derived.py".
+
+2000-07-30 Major auto-convert 1.8.6 file bug
+
+ Bug in on-the-fly conversion of bytes properties ('B') in pre-2.0
+ datafiles (i.e. 1.8.6 and earlier) resolved.
+
+ Unfortunately, this bug can not be 100% unambiguously fixed. The
+ new code *will* properly detect most cases, and convert both 1.8.6
+ and 2.0 datafiles on the fly, but especially for views with only a
+ few rows and at most a few bytes of data per row - the conversion
+ *might* fail.
+
+ In this case, MK will have to be compiled with a define to force it
+ to either assume all old datafiles are 1.8.6 (-Dq4_OLD_IS_PRE_V2),
+ or to assume that they are always 2.0 (-Dq4_OLD_IS_ALWAYS_V2). If
+ you are currently using MK 1.8.6, then you should *skip* the update
+ to 2.01, and consider updating to 2.3.x. This way you never have
+ any 2.0 files around, and can force all your code to handle 1.8.6
+ files properly (by using "-Dq4_OLD_IS_PRE_V2").
+
+ See src/format.cpp, c4_FormatB::OldDefine for details.
+
+ This bug *only* applies to bytes properties in pre-2.0 data files.
+ Conversion of 2.0x files is unaffected.
+
+2000-07-25 Fixed new self-referential views
+
+ The new recursive / self-referential view definition style has been
+ fixed, e.g. "view[data:S,self[^]]" will now let you store a tree of
+ arbitrary depth, with each 'self' subview having data and self
+ properties. See the demo in "examples/selfref.py" to see how this
+ all works.
+
+2000-07-22 Fixed bug in double restructuring
+
+ Solved a very long-standing bug in restructuring, which caused
+ incorrect (non-zero, small) default values when a c4_DoubleProp was
+ added to a view which already had rows.
+
+2000-07-18 Added remapwith and pair to Mk4py
+
+ Exposed C++'s c4_View::RemapWith as v1.remapwith(v2), and
+ c4_View::Pair as v1.pair(v2) in the Mk4py Python binding. Added
+ pair.py, remap.py, and wrap.py in "examples/" dir.
+
+2000-07-12 Added metakit.py wrapper
+
+ Added "metakit.py" script to wrap Mk4py, including a new
+ metakit.dump() to pretty-print views. More utility code will be
+ added over time. The preferred way to use Metakit from Python is
+ now "import metakit".
+
+2000-07-06 Conversion fix, warning cleanup
+
+ Fixed on-the fly conversion of old datafiles. The free space was
+ not managed properly - changed to never touch any data inside the
+ file during conversion.
+
+ Some source code change to get the compile through gcc flags
+ "-fguiding-decls -Wall -pedantic -Wno-unused". The only remaining
+ complaint is about using "long long".
+
+2000-07-04 MkSQL subtree, "indexed" mapped viewer
+
+ Added the sql and mksql subtrees to the distribution, with Gordon
+ McMillan's MkSQL engine, written in Python. The "isql.py" script is
+ a simple interactive shell around it.
+
+ Started work on a new viewer which maintains a persistent index (as
+ a one-int-prop permutation), see src/remap.cpp.
+
+2000-07-03 Mk4tcl fixes
+
+ Fixed view rename problem and "delete end" (Matt Newman). Adjusted
+ the tests in tcl/test/mk5object.tcl accordingly.
+
+2000-06-30 Tequila fixes
+
+ Close fix and failure handler (Steve Landers).
+
+2000-06-29 ############################################## MK 2.3.2
+
+ First beta release
+
+ The new release is 99% feature-complete. What remains is to further
+ document C++/Python/Tcl use and to fix bugs.
+
+ Python sample code in "python/aside.py" and "python/find.py". Tcl
+ samples in "tcl/test/mk5object.tcl" and "tcl/mapped.tcl".
+
+2000-06-28 Hash/blocked/ordered: changes and fixes
+
+ Changed hash insertion to insert at specified position. This makes
+ it possible to use hashes "under" ordered views. For best
+ performance, insert rows at end of hash views.
+
+2000-06-26 Documentation, example, Mk4tcl OO fixes
+
+ Moved C++ member documentation out of "mk4.h" header. Added
+ examples/ directory, with a find.py timing example. Fixed bugs in
+ new Mk4tcl: "$vw find" and "$vw delete end". Added tests for new
+ Mk4tcl OO interface: ":mk5object.test".
+
+2000-06-16 Improved modifiable custom viewers
+
+ The Pair and Slice viewers now support set/insert/remove, while
+ RemapWith/Concat/Rename support setting values.
+
+2000-06-15 Many changes to the Tcl code, hashing
+
+ Contributed by Matt Newman, it adds support for most custom viewers,
+ including the new hash etc. Added a fast find. Caveat: most old
+ custom viewers are still not modifiable.
+
+ Hash calculation improved, far less collisions than before.
+
+ Blocked viewer seems to work. Ordered on top is sub-optimal.
+
+2000-06-12 GetUpperLimit, Blocked, Ordered, mk4too
+
+ Removed c4_View::GetUpperLimit (it's equivalent to GetSize-1 and was
+ not being used anywhere).
+
+ Start implementing c4_BlockedViewer, a simple balanced/blocked
+ nested data structure. Also started on a c4_OrderedViewer, which
+ keeps the underlying view sorted during changes. These two can be
+ combined to implement an efficient 2-level btree.
+
+ Adopted code by Matt Newman for oo-cmd's for Mk4tcl views. First
+ trials work, started to extend with new custom viewers.
+
+2000-06-09 Change case of a few Mk4py members
+
+ Changed all top-level members in the Python interface to lower case:
+ storage, property, view, wrap (will break existing code).
+
+ Fix bounds check in Mk4tcl.cpp for commit/rollback (new code).
+
+ Whoops, forgot to add new src/remap.{h,cpp} to the cvs tree.
+
+2000-06-08 Implemented hash lookup
+
+ Added a new virtual c4_Sequence::RestrictSearch, which lets a view
+ take over searching (used by c4_View::Find). The result is that the
+ new hash viewer gives a huge speedup for finds. Find requests which
+ require linear scanning are unaffected.
+
+2000-06-07 Documentation extraction based on Doxygen
+
+ The automatically generated output from Doxygen is working out well
+ and looking pretty, added "src/doxy.h" with more comments.
+
+2000-06-05 Started hash and btree custom viewers
+
+ The hash implementation is nearly done, also usable from Python.
+ Btrees are being implemented as fixed 2-level for now.
+
+2000-06-01 Fixes
+
+ Fixed crash when opening missing file r/o new in 2.3.1 alpha. Fixed
+ incorrect on-the-fly-conversion of 2.0 format subviews. Added
+ "storage.aside(storage)" to the Python interface.
+
+2000-05-30 Fixed commit-aside
+
+ The new commit-aside code was botched by recent changes. Fixed
+ SetAside to pick up new root seq, changed by implicit rollback.
+ Note that a commit-aside is not finished until you *also* commit the
+ secondary file containing all newly generated changes.
+
+ Fixed bug in c4_BytesRef::Access, introduced in 2.3.1 alpha.
+
+2000-05-29 Added new 64-bit long datatype
+
+ Added support for 64-bit longs (type 'L'), and c4_LongProp, etc.
+ This type is not autosizing, it always uses 8 bytes per entry. Uses
+ "long long" or "__int64", else defines struct with 2 longs. This is
+ not yet correct for platforms which have no 64b ints. No regression
+ tests or Python/Tcl interfaces yet.
+
+2000-05-28 Better file mark scanning
+
+ Added c4_Strategy::EndOfData, to determine the logical end of a
+ Metakit datafile. This call can be used to check whether a file
+ contains any data, and whether a commit-extend has been performed.
+ Old-style scripted documents (with preamble) can now be opened.
+ Changed strategy class, DataSeek has been merged with read/write.
+ Removed c4_LoadContext, LoadIt member moved to c4_Persist.
+
+2000-05-27 Tweaked configuration define's
+
+ Make the release build the default (no assertions, use inlines).
+ Enable booleans for gnuc by default (it's pretty standard by now).
+ Added extra include path to better find Python's includes.
+
+2000-05-26 Fixed Tcl dependency
+
+ Changed configure script to no longer look for Tcl if the
+ "--with-tcl=..." parameter is not specified.
+
+2000-05-25 ############################################## MK 2.3.1
+
+ First alpha release
+
+ Officially, this is "Metakit 2.3.1 alpha" (ignore "2.3.0" in mk4.h).
+ All alpha's are 2.3.1 (beta's will be 2.3.2, finals start at 2.3.5).
+ Builds on Linux/Mac/Win appear ok - as do Mk4py, Mk4tcl, and Tclkit.
+
+2000-05-06 Massive changes to the core
+
+ To summarize the main issues: management info is now stored in such
+ a way that it need not be read in right away - file open is now
+ instant. The S(tring) datatype is now stored as B, making it far
+ more scalable (API/use is unchanged). Storage objects now derived
+ from views, both can be initialized from a stream (data will be kept
+ in a buffer, beware of potentially large memory use).
+
+ Several file format changes are "for future expansion".
+
+2000-05-05 Fixed builds without Tcl
+
+ In 2.0.1, the make would fail if there was no Tcl to build with, or
+ not an appropriate release. Changed Makefile to report and skip Tcl
+ builds in that case.
+
+2000-04-06 Fixed a nasty restructure/mmap bug
+
+ When a property is deleted by a restructure, then committed, then
+ later committed again, a problem can cause MK to crash. It has only
+ been detected in debug builds, but the problem turns out to be a
+ fundamental one (only happens with memory-mapped files, if the file
+ is resized). Fix in next rel (c4_HandlerSeq::DetachFromStorage).
+
+2000-04-02 Memo properties are no longer needed
+
+ The M datatype is gone from the public API (and now illegal).
+ Everything binary should now be stored in B(ytes) properties, which
+ then adaptively decide which internal format to use, based on a
+ simple heuristic (which will be refined later). Existing datafiles
+ will automatically convert from M to B. The partial Access and
+ Modify calls now also work on B items.
+
+2000-03-30 Minor change in c4_Strategy
+
+ Dropped the _keepAfterCommit flag in c4_Strategy, it probably has
+ never been used and it interferes with new features.
+
+2000-03-27 Change in API for creating storages
+
+ It is no longer possible to create a storage and define its
+ structure with a single call. Instead, open a storage in r/w mode
+ (i.e. "1") and then call the (now public) SetStructure member to
+ define the structure of all views. This change is necessary to
+ prepare for the upcoming "commit-aside" logic.
+
+2000-03-23 File format changes (in progress)
+
+ The new file format has an incompatible header, so old code will not
+ recognize new datafiles. Major changes are: added a file tail
+ marker, the serialized format is now a very good way to compress
+ datafiles, since it can be efficiently opened in on-demand/mmap'ed
+ mode. The new format supports several planned features. Code to
+ convert existing files on-the-fly will be added before this change
+ is released.
+
+2000-03-19 Added c4_Strategy::FileSize
+
+ The Strategy::FileSize call is used for a file format change.
+
+2000-03-18 Added c4_View::Locate
+
+ Locate returns the number of matching rows, and optionally the
+ position of the first one, using binary search. Like the
+ c4_View::Search function, it requires the view to be sorted.
+
+2000-03-17 ############################################## MK 2.01
+
+ Maintenance release, it's solid
+
+ Updated MK version number to 2.01, this maintenance release
+ represents a very stable version.
+
+ Small change to b07 test to avoid evaluation order problems.
+
+ Added unix/metakit.spec file for RPM, thanks to Sean Summers.
+
+2000-03-16 Drop Store, fix deep copy, drop segments
+
+ c4_Storage::Store never worked properly under all conditions. It's
+ been deprecated for some time and has now been removed. Made a
+ handful of changes to test- and demo code to drop it.
+
+ Duplicating a view with deep copy never worked, because it used the
+ buggy Store call as well. Changed to use recursion.
+
+ Dropped support for segmented tree-walk storage, which hasn't been
+ used since 1.5 (use a commit with 2.0 to convert files). This is
+ necessary to prepare for some file format changes.
+
+2000-03-15 Modifiable custom viewers, other tweaks
+
+ A start has been made with making custom viewers updatable. The new
+ methods are Set, InsertAt, RemoveAt, and Move, but the number of
+ viewers which implement this is still limited. Mk4py has been
+ adjusted to allow "set" on wrapped views.
+
+ Removed c4_Strategy::DataLoad, it was only used in one place. Small
+ optimization of the 2 calls to c4_Streamer::NextByte. Get rid of /
+ disallow read calls on memory mapped files.
+
+2000-03-14 Makefile tweaks, non-commits smarter
+
+ Changed from --enable-tcl to --with-tcl=DIR, because the old
+ approach only worked with Tcl installed in a standard place.
+
+ Commits of a R/O file now fail. Also, if no changes have been made,
+ a commit will no longer write anything to file.
+
+2000-03-13 Several new commands added to Mk4py
+
+ Several changes were submitted by Gordon McMillan, which add better
+ support for his upcoming SQL engine.
+
+2000-03-12 Allow embedding MK datafile at end of EXE
+
+ Mk4tcl was changed to look for an optional trailer for quick access
+ to the start offset. This makes it possible to append datafiles to
+ executables, even if they are larger than 4 Kb.
+
+2000-02-29 Fixed rare bug with lots of memo fields
+
+ There was a bug in free space management (persist.cpp), which can
+ only occur when exactly 7500 free space gaps are present, and a
+ commit crosses the threshold. There was also a small mistake in
+ that same code causing a bit of free space waste.
+
+2000-02-24 Added proxy support to Tequila
+
+ Tequila can now be used as basic client/server setup for Tcl
+ scripts. See tcl/tequila/README for details and an example.
+
+2000-02-04 Fixed mk::views (Mk4tcl)
+
+ The mk::views command failed to list the first view in the file
+ (this bug was introduced by changes in MK 1.99).
+
+2000-01-02 Adjusted y2k
+
+ Copyright and license dates adjusted.
+
+1999-12-26 More Mk4py changes
+
+ Added sortrev, and fixed "select(low,high)". Docs updated.
+
+1999-12-23 New view operators in Mk4py
+
+ Added rename, project, groupby, and counts operators to Mk4py.
+ These were already part of the C++ core.
+
+1999-12-22 Avoid GetId inline warning
+
+ Reordered GetId in "mk4.inl" to avoid (harmless) inline warning.
+
+1999-12-21 Checked-in Catfish and Kitviewer sources
+
+ Added win/catfish and win/kitviewer areas. Catfish was built with
+ MSVC 1.52, so the win/msvc152 area has also been added.
+
+ Kitviewer requires Borland C++ Builder 4.0 to build (using VCL), it
+ has been adjusted to now also recognize scripted documents.
+
+1999-12-20 Bug fix in set-after-get situations
+
+ A bug has surfaced when setting string/byte/memo values which span a
+ 4 Kb block boundary. The bug can only happen if data is first
+ fetched and subsequently changed. The affected code is in
+ src/format.cpp (3x). Added Tcl test 5.5 to catch this.
+
+1999-12-19 Mac tweaks
+
+ Changes to make the Mac versions build from the CVS repository. The
+ Mac can also cross-compile Windows libraries using MWCW 5.
+
+1999-12-17 Add the Tequila example
+
+ Added the Tequila global Tcl array data server, see tcl/tequila/.
+
+1999-12-15 MK 2.0 Official Open Source release
+
+ Removed a bad assertion from FormatX::Compare.
+
+ Several new services set up on the excellent SourceForge.com site.
+
+1999-12-14 Documentation added
+
+ The C++ API documentation has been added to the distribution, as
+ well as a document describing the file format details of Metakit.
+
+1999-12-13 Bug fix affecting c4_View::Description
+
+ There was a problem with c4_ViewScanner::Describe, due to a change
+ from c4_String to (const char*). Now c4_View::Store works again.
+
+1999-12-12 MK 1.99 New release, as open source software
+
+ The major change is that Metakit has been released as open source
+ software, based on the liberal X/MIT-style license. Commercial
+ support remains unchanged for all recent commercial customers, and
+ for those who purchase the Enterprise License. The Universal Source
+ license has been terminated, because full source code is now freely
+ downloadable by anyone from the website.
+
+ Sources and documentation files have been adjusted accordingly.
+
+1999-12-08 MK 1.9h Bool support for gcc/egcs, minor fix
+
+ Clear _field after delete in c4_HandlerSeq::DefineRoot. This
+ triggered an assertion on Linux, when compiled in debug mode.
+
+ Added pre-processor logic to detect whether gcc supports bools.
+
+ Removed all indentation from #define's, #ifdef's, etc. This was
+ done after a report that some compilers can get confused by this.
+
+1999-12-06 Derived view row copy fix
+
+ There was a problem when using SetAt with derived views as source,
+ due to a remapping problem. Fixed viewx.cpp, added new test b25.
+
+1999-11-25 MK 1.9g Makefile changes, thread-safe Mk4tcl
+
+ Renamed options to --enable-python and --enable-tcl, both now off by
+ default, since most people probably don't want to enable both.
+
+ The new "-shared" changes to make Mk4tcl thread-safe have been
+ folded into the main source code.
+
+1999-11-22 Channel improvements Mk4tcl
+
+ There was a close conflict in mk::channel, also several changes to
+ improve mk::channel fileevent handling.
+
+1999-11-19 Bug fix in Mk4tcl
+
+ There was an array overrun when mk::get was called without fields.
+ Added code to avoid this.
+
+1999-11-11 Mk4tcl exit handling
+
+ Simplified Mk4tcl exit handling, fixes "interp delete" crash. Added
+ new mk5fixed.4 test to catch this case.
+
+1999-11-10 Mk4tcl shared and multi-threaded access
+
+ Made a first experimental version of Mk4tcl (1.2.1, not announced)
+ which allows sharing a database between interpreters and threads.
+
+1999-11-09 STL, MkWrap, compare caching
+
+ Tweaked the makefile to support STL builds (also adjusted README).
+
+ Fixed bug in MkWrap, calling storage.description() without args.
+
+ Yet more fixes in comparisons, this is all one problem, caused by
+ changes in caching for ints, floats, and doubles. Added B24 test.
+ These (last?) problems occurred in custom / compound views.
+
+1999-11-08 MK 1.9f Fixed sort comparisons
+
+ There was a cache problem with comparisons of int / float / double
+ sorts. Fixed, also added new B23 regression test to check for it.
+
+1999-11-07 Little nasty details
+
+ Tweaked some make/project files. All regress tests and Tcl tests
+ now reported to really work on Solaris, Linux, Windows, and Mac.
+ Regression tests required more memory on Mac to get past L03 case.
+
+1999-11-06 MK 1.9e Big oops: Mk4tcl and MkWrap were broken!
+
+ Fixed a c4_Strategy / c4_FileStrategy mixup in Mk4tcl and MkWrap.
+
+1999-11-05 Simplify c4_Storage
+
+ Moved state out of c4_Storage and into c4_Persist, to prepare for
+ multi-thread wrappers. Made a new, simpler design to achieve that.
+
+1999-11-04 MK 1.9d Factor out stdio dependencies
+
+ Moved all stdio dependencies out of core into new "fileio.cpp" src.
+ The mk4.h header no longer includes <stdio.h>, added new "mk4io.h"
+ header with a c4_FileStrategy class, derived from c4_Strategy.
+
+ Also factored c4_Stream/c4_FileStream out of the c4_Strategy class.
+ This alters the API slightly, but makes it 100% portable/embeddable.
+
+ Added "tcl/iohan.tcl", a simple wrapper for generic storage access:
+ locally, on a FTP server, in a local MK datafile, or using a remote
+ Tequila server (see http://www.equi4.com/tclkit/tequila.html).
+
+1999-11-03 Improved detach/restructure handling
+
+ Changed detach to drop all persistent formathandlers, but leave the
+ number of rows intact. It will be much faster to destroy columns
+ than to delete (and propagate) rows. The result is that a pointer
+ to a view of which the underlying storage object goes away will end
+ up with the same number of rows as before, but no properties at all.
+
+ Fixed a problem which would have occurred when properties are being
+ "restructured away" and then committed. The solution is to check
+ for this and delete all such properties at commit time.
+
+ Moved Buffer() out of c4_HandlerSeq and c4_CustomSeq, and made the
+ new version in c4_Sequence allocate the c4_Bytes object lazily.
+ Faster, and decreases sequence object size (for lots of subviews).
+
+ Mk4tcl, mk::layout now returns the proper layout even if the views
+ are empty. Solved by adding extra arg to c4_Storage::Description,
+ to return structure of a single top-level view. Fixes "mk8basic.1",
+ and the returned string now has one bogus list layer stripped off.
+
+ MkWrap also adjusted with optional arg for storage.description().
+
+1999-11-02 New Wrap code in MkWrap
+
+ MkWrap, added new Wrap(seq,props,byPos) member, a c4_CustomViewer
+ which wraps any Python sequence as MK view (for use in joins, etc).
+
+1999-11-01 MK 1.9c Mk4tcl changes
+
+ Mk4tcl, several changes: added "-size" option to mk::get to return
+ the size of prop value without fetching it (see new basic.9 test).
+ Added "-globnc" for case-insensitive globbing (for regexp, this is
+ available through the new (?i) metasytnax of Tcl 8.2 (see basic.10).
+
+1999-10-31 MK 1.9b Solved shared lib unload with Tcl 8.2
+
+ Changed property symbol table setup to avoid static initializers, to
+ work around a problem with shared library cleanup from Tcl 8.2.
+ Added new c4_Property::CleanupInternalData call to clean up 100%
+ (this code need not usually be called, only if memory is tracked).
+ This fixes the crash-on-exit bug in Mk4tcl (Linux and Solaris).
+
+1999-10-29 Make support for MkWrap and Mk4tcl
+
+ Both MSVC and MWCW now also build Mk4tcl and MkWrap extensions. The
+ MWCW project compiles for Win and Mac *on* either Win or Mac.
+ Makefile extended to build Mk4tcl and MkWrap, added dist target.
+ Updated to latest Perceps 3.5 beta, started generating docs again.
+
+1999-10-27 MK 1.9a New build / directory structure
+
+ Completely reworked the directory structure to simplify all builds.
+ Created new "builds/" area for all intermediate and output files.
+ New MSVC 6.0 project structure created in "win/msvc60/".
+
+ Moved Mk4tcl to the "tcl/" top-level directory, and MkWrap to the
+ "python/" dir. The MkWrap code has been removed from the project.
+
+ Removed c4_View::Match and the regular expression package, since it
+ can just as efficiently be done with a wrapper around MK, now that
+ string results no longer allocate a temporary copy.
+
+ Started writing a Tcl-based test suite for use with Mk4tcl.
+
+MAJOR CHANGE SINCE 1.8.6
+
+ Merge handler.cpp and format.cpp classes to get rid of special-cased
+ in-memory version of handlers. This has major effects on how data
+ is kept for unattached views (they still exist, but no longer
+ special). The code is leaner and meaner, it passes all regression
+ tests.
+
+ALSO LISTED IN THE RELEASE HISTORY
+
+ Added c4_MemoRef::Access and c4_Memoref::Modify for partial access
+ to memo fields. Avoids copying and allows inserts/deletes anywhere.
+ MkWrap and Mk4tcl have both been extended to allow using Memo fields
+ for simulated file IO (mk::channel for Tcl, MkMemoIO.py for Python).
+
+ Added c4_Reference::GetSize to determine the size of a value without
+ accessing it. For ints, returns negated bit width if 1/2/4 bits.
+
+ Added experimental c4_View::RelocateRows to move rows from one view
+ to another (both must be in same storage, with the same structure).
+ Moves do not involve any data copying w.r.t. subviews and memo's.
+
+The old release history is at http://www.equi4.com/metakit/history.html
+
+# vim: tw=72
diff --git a/akregator/src/mk4storage/metakit/Makefile.am b/akregator/src/mk4storage/metakit/Makefile.am
new file mode 100644
index 000000000..af437a64d
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = src
diff --git a/akregator/src/mk4storage/metakit/README b/akregator/src/mk4storage/metakit/README
new file mode 100644
index 000000000..21edd0fc2
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/README
@@ -0,0 +1,153 @@
+The Metakit Library 2.4.9.3 Jan 2004
+==============================================================================
+
+
+WHAT IT IS - Metakit is an embeddable database which runs on Unix, Windows,
+ Macintosh, and other platforms. It lets you build applications which
+ store their data efficiently, in a portable way, and which will not need a
+ complex runtime installation. In terms of the data model, Metakit takes
+ the middle ground between RDBMS, OODBMS, and flat-file databases - yet it
+ is quite different from each of them.
+
+TECHNOLOGY - Everything is stored variable-sized yet with efficient positional
+ row access. Changing an existing datafile structure is as simple as re-
+ opening it with that new structure. All changes are transacted, including
+ restructuring. You can mix and match software written in C++, Python,
+ and Tcl. Things can't get much more flexible...
+
+CORE - The Metakit core library is written in C++. It has a code footprint of
+ just over 100 Kb on Windows. It can be used as DLL, or linked statically.
+ Debug builds include extensive assertion checks to catch problems early.
+
+PYTHON - The binding for Python is called "Mk4py". It uses SCXX by Gordon
+ McMillan as C++ glue interface. The source is in directory "python/".
+
+TCL/TK - The MK extension for Tcl is called "Mk4tcl". It is being used in a
+ number of commercial projects. The source is in directory "tcl/".
+
+LICENSE AND SUPPORT - Metakit is now distributed as open source software (the
+ X/MIT-style license is at the end of this document). Commercial support
+ is available through an Enterprise License, see the URL mentioned below.
+
+DOCUMENTATION - All documentation uses HTML. The main page is "Metakit.html",
+ which leads to the rest of the documentation in the "doc/" directory.
+ The C++ API Reference is extracted from the source code using Doxygen.
+
+WEBSITE URLS - The main pages on the world wide web, for news and downloads:
+ Homepage: http://www.equi4.com/metakit.html
+ Python news: http://www.equi4.com/metakit/python.html
+ Tcl/Tk news: http://www.equi4.com/metakit/tcl.html
+ License info: http://www.equi4.com/mklicense.html
+ Contact info: http://www.equi4.com/contact.html
+
+ACKNOWLEDGEMENTS - Thanks to everyone who has helped shape and extend Metakit,
+ including Kyrill Denisenko, Mark Roseman, Gordon McMillan, Matt Newman,
+ Christian Tismer, John Bushakra, Steve Landers, Jacob Levy, John Barnard,
+ Nicholas Riley, Brian Kelley, and many more people who have reported bugs
+ and helped fix them. Last but not least, many thanks to all enterprise
+ license customers and all my clients for funding Metakit work.
+
+
+INSTALLATION
+============
+
+(NOTE to Python users: ignore this and do "cd python; python setup.py ...")
+
+All platform builds and language bindings are designed to work from a single
+common "builds/" directory. Where possible, that is - it turns out to be
+impossible to keep build side-effects limited to *just* this directory
+(CodeWarrior can't be told where to place its temp data, and Visual C++ still
+alters a few files next to the project ".dsw" file, to name two offenders).
+
+UNIX
+
+ It is no longer advised to build the Unix code in the "unix/" directory.
+ Instead, you should perform the following steps:
+ % cd builds
+ % ../unix/configure
+ % make
+ % make test
+ And optionally (this only installs the core lib, not script extensions):
+ % make install
+
+ By switching to the "builds/" directory, you will keep the distribution
+ directory tree 100% unaltered. All changes are made in this subdir, and
+ all final build results are left behind in this same subdir.
+
+ To build with STL containers and strings, you can do the following:
+ make CXXFLAGS='-Dq4_STD' test # add -O3 etc, as needed
+
+ To build the Mk4tcl extension on Unix, change the configure to:
+ % ../unix/configure --with-tcl=<dir-where-tclConfig.sh-is>
+
+ Use "../unix/configure --help" to find out about all the other settings.
+
+WINDOWS
+
+ There is a "win/" directory which contains subdirectories for a number of
+ compiler systems. Metakit has been built with many different compilers
+ in the past (Microsoft, Borland, Watcom, Symantec, Metrowerks, Optima),
+ only a few are maintained (there are 12 configurations for MSVC6 alone!).
+
+ The MS Visual C++ 6.0 project is "win/msvc60/mksrc.dsw", with subprojects
+ for the C++ demo (mkdemo), building dll's (mkdll), static libs (mklib),
+ regression tests (mktest), as well as Tcl (mktcl) and Python (mkpython).
+ It has been set up to place all intermediate files and final results in
+ the "builds/" subdirectory, even though you'll launch it from "win/".
+
+ To build with STL containers and strings under MSVC, define "q4_STD".
+ To build with MFC containers and strings under MSVC, define "q4_MFC".
+
+ The Metrowerks Codewarrior project is in the "mac/" directory, and can be
+ used to build both Mac and Windows versions (on either Mac *or* Windows).
+ The core libraries are built with "mac/cw5.mcp", demos / tests are built
+ with "cw5apps.mcp", Tcl is "cw5tcl.mcp", and Python is "cw5python.mcp".
+
+ The Borland C++ Builder projects have not yet been incorporated in this
+ release, but the "KitViewer" application is an example of how to use BCB.
+
+ The Cygwin build (B20.1 / gcc 2.95.2) is different, because it uses the
+ unix autoconf system, and must be launched as described above for UNIX.
+ I have upgraded to the latest development of libtool to be able to build
+ DLL's with Cygwin. You can build the "-mno-cygwin" version by editing
+ the Makefile by hand and adding that option to CXXFLAGS.
+
+ Rob Bloodgood adds that the following GCC options are for maximum code
+ efficiency on x86 hardware: "-O2 -m486 -malign-loops=2 -malign-jumps=2".
+ I have not yet tried this myself, but am passing on the tip.
+
+MACINTOSH CLASSIC
+
+ The Mac version requires Metrowerks CodeWarrior 6. See the info above
+ in the Windows section (MWCW is multi-platform). The projects are all
+ located in the "mac/" folder, which is also where MWCW will place its own
+ "... Data" folders with intermediate results. As with all other setups,
+ final results are made to end up in the "builds/" directory.
+
+
+LICENSE AND COPYRIGHT STATEMENT
+===============================
+
+Copyright (c) 1996-2004 Jean-Claude Wippler
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
+
+==============================================================================
+-- Jean-Claude Wippler <jcw@equi4.com>
diff --git a/akregator/src/mk4storage/metakit/include/mk4.h b/akregator/src/mk4storage/metakit/include/mk4.h
new file mode 100644
index 000000000..33016dba0
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/include/mk4.h
@@ -0,0 +1,1078 @@
+// mk4.h --
+// $Id$
+// This is part of Metakit, see http://www.equi4.com/metakit/
+
+/** @file
+ * Main Metakit library include file
+ */
+
+#ifndef __MK4_H__
+#define __MK4_H__
+
+//---------------------------------------------------------------------------
+//
+// TITLE
+//
+// The Metakit Library, by Jean-Claude Wippler, Equi4 Software, NL.
+//
+// DESCRIPTION
+//
+// Structured data storage with commit / rollback and on-demand loading.
+//
+// ACKNOWLEDGEMENTS
+//
+// To Liesbeth and Myra, for making this possible.
+//
+//---------------------------------------------------------------------------
+//
+// NAMING CONVENTIONS PREFIX REMARKS
+//
+// Compile time options q4_ Always defined as 1 or 0, capitalized
+// Preprocessor defines d4_ Use with "#ifdef" or "#if defined()"
+// Classes c4_ Classes, listed at start of headers
+// Typedefs t4_ Type definitions, if outside classes
+// Global functions f4_ Internal, these are rarely defined
+//
+// Member functions Start in uppercase
+// Instance variables _ And start in lowercase
+// Static members _ And start in uppercase
+//
+// Local variable names Start in lowercase
+// Formal parameter names Start lowercase, end with underscore
+//
+//---------------------------------------------------------------------------
+
+ /// Current release = 100 * major + 10 * minor + maintenance
+#define d4_MetakitLibraryVersion 249 // 2.4.9.3 release, Jan 26, 2004
+#define d4_MetaKitLibraryVersion d4_MetakitLibraryVersion // compat, yuck
+
+//---------------------------------------------------------------------------
+// Declarations in this file
+
+ class c4_View; // a view on underlying data
+ class c4_Cursor; // an index into a view
+ class c4_RowRef; // a reference to a row
+ class c4_Row; // one row in a view
+ class c4_Bytes; // used to pass around generic data
+ class c4_Storage; // manages view persistence
+ class c4_CustomViewer; // used for customizable views
+ class c4_Stream; // abstract stream class
+ class c4_Strategy; // system and file interface
+
+ class c4_Property; // for access inside rows
+ class c4_IntProp;
+ class c4_LongProp;
+ class c4_FloatProp;
+ class c4_DoubleProp;
+ class c4_StringProp;
+ class c4_BytesProp;
+ class c4_ViewProp;
+
+ // Everything below is part of the implementation, not for public use
+
+ class c4_Sequence; // a collection of rows
+
+ class c4_Reference; // refers to the actual data values
+ class c4_IntRef;
+ class c4_LongRef;
+ class c4_FloatRef;
+ class c4_DoubleRef;
+ class c4_BytesRef;
+ class c4_StringRef;
+ class c4_ViewRef;
+
+ class c4_Dependencies; // not defined here
+ class c4_Handler; // not defined here
+ class c4_Notifier; // not defined here
+ class c4_Persist; // not defined here
+
+//---------------------------------------------------------------------------
+
+ // determine whether we need to include "mk4dll.h" to link as DLL
+#if defined (MKDLL_EXPORTS) && !defined (q4_KITDLL)
+#define q4_KITDLL 1
+#endif
+
+ // omit floats and doubles in small model 16-bit Intel builds
+#if defined (_DOS) && defined (_M_I86SM) && !defined (q4_TINY)
+#define q4_TINY 1
+#endif
+
+ // and here's the other end of the scale...
+#if !defined (_WIN32) && !defined (q4_LONG64)
+#if (defined (_PA_RISC2_0) && defined(__hpux)) || defined (__powerpc64__) || defined(__sparcv9) || \
+ defined (__x86_64__) || defined (__s390x__) || defined (__alpha) || defined (__mips64) || \
+ (defined (__ia64) && (!defined (__HP_aCC) || defined(__LP64__)))
+#define q4_LONG64 1
+#endif
+#endif
+
+ // default to inlining for maximum performance
+#if !defined (q4_INLINE)
+#define q4_INLINE 1
+#endif
+
+//---------------------------------------------------------------------------
+
+ // Borland C++ and C++ Builder
+#if defined (__BORLANDC__)
+ // by default, if runtime is linked as a DLL, then so is Metakit
+#if defined (_RTLDLL) && !defined (q4_KITDLL)
+#define q4_KITDLL 1
+#endif
+
+ // Borland 5.0 supports the bool datatype
+#if __BORLANDC__ >= 0x500
+#define q4_BOOL 1
+#endif
+#endif // __BORLANDC__
+
+ // IRIX supports the bool datatype
+ // define before gcc to cover both the gcc and MipsPRO compiler
+#if defined (sgi)
+#define q4_BOOL 1
+#undef bool
+#undef true
+#undef false
+#endif
+
+ // GNU gcc/egcs
+#if defined (__GNUC__)
+#ifndef q4_BOOL
+#define q4_BOOL 1
+#endif
+#ifndef HAVE_LONG_LONG
+#define HAVE_LONG_LONG 1
+#endif
+#endif
+
+ // HP aCC
+#if defined (__HP_aCC)
+#ifndef HAVE_LONG_LONG
+#define HAVE_LONG_LONG 1
+#endif
+#endif
+
+ // Metrowerks CodeWarrior
+#if defined (__MWERKS__)
+#if __option(bool)
+#define q4_BOOL 1 // bool datatype is optionally supported
+ // undef, these conflict with c4_Storage::c4_Storage overloading
+#undef bool
+#undef true
+#undef false
+#endif
+#endif
+
+ // Microsoft Visual C++
+#if defined (_MSC_VER)
+ // MSVC 5.0 supports the bool datatype, MSVC 4.x has no namespaces
+#if _MSC_VER >= 1100
+#define q4_BOOL 1
+#define LONG_LONG __int64
+#else
+#define q4_NO_NS 1
+#endif
+
+ // a kludge to avoid having to use ugly DLL exprt defs in this header
+#pragma warning(disable: 4273) // inconsistent dll linkage
+#endif // _MSC_VER
+
+//---------------------------------------------------------------------------
+// Other definitions needed by the public Metakit library header files
+
+#if !q4_BOOL && !q4_STD // define a bool datatype
+#define false 0
+#define true 1
+#define bool int
+#endif
+
+#if q4_KITDLL // add declaration specifiers
+#include "mk4dll.h"
+#endif
+
+#if q4_INLINE // enable inline expansion
+#define d4_inline inline
+#else
+#define d4_inline
+#endif
+
+typedef unsigned char t4_byte; // create typedefs for t4_byte, etc.
+
+#if q4_LONG64
+typedef int t4_i32; // if longs are 64b, then int must be 32b
+#else
+typedef long t4_i32; // if longs aren't 64b, then they are 32b
+#endif
+
+#if q4_LONG64 // choose a way to represent 64b integers
+typedef long t4_i64;
+#elif defined (LONG_LONG)
+typedef LONG_LONG t4_i64;
+#elif HAVE_LONG_LONG
+typedef long long t4_i64;
+#else
+struct t4_i64 { long l1; long l2; };
+bool operator== (const t4_i64 a_, const t4_i64 b_);
+bool operator< (const t4_i64 a_, const t4_i64 b_);
+#endif
+
+//---------------------------------------------------------------------------
+
+class c4_View
+{
+protected:
+ c4_Sequence* _seq;
+
+public:
+/* Construction / destruction / assignment */
+ c4_View (c4_Sequence* =0);
+ c4_View (c4_CustomViewer*);
+ c4_View (c4_Stream*);
+ c4_View (const c4_Property& property_);
+ c4_View (const c4_View&);
+ ~c4_View ();
+
+ c4_View& operator= (const c4_View&);
+ c4_Persist* Persist() const; // added 16-11-2000 to simplify c4_Storage
+
+/* Getting / setting the number of rows */
+ int GetSize() const;
+ void SetSize(int, int =-1);
+
+ void RemoveAll();
+
+/*: Getting / setting individual elements */
+ c4_RowRef GetAt(int) const;
+ c4_RowRef operator[] (int) const;
+
+ void SetAt(int, const c4_RowRef&);
+ c4_RowRef ElementAt(int);
+
+ bool GetItem(int, int, c4_Bytes&) const;
+ void SetItem(int, int, const c4_Bytes&) const;
+
+/* These can increase the number of rows */
+ void SetAtGrow(int, const c4_RowRef&);
+ int Add(const c4_RowRef&);
+
+/* Insertion / deletion of rows */
+ void InsertAt(int, const c4_RowRef&, int =1);
+ void RemoveAt(int, int =1);
+ void InsertAt(int, const c4_View&);
+
+ bool IsCompatibleWith(const c4_View&) const;
+ void RelocateRows(int, int, c4_View&, int);
+
+/* Dealing with the properties of this view */
+ int NumProperties() const;
+ const c4_Property& NthProperty(int) const;
+ int FindProperty(int);
+ int FindPropIndexByName(const char*) const;
+ c4_View Duplicate() const;
+ c4_View Clone() const;
+ int AddProperty(const c4_Property&);
+ c4_View operator, (const c4_Property&) const;
+
+ const char* Description() const;
+
+/* Derived views */
+ c4_View Sort() const;
+ c4_View SortOn(const c4_View&) const;
+ c4_View SortOnReverse(const c4_View&, const c4_View&) const;
+
+ c4_View Select(const c4_RowRef&) const;
+ c4_View SelectRange(const c4_RowRef&, const c4_RowRef&) const;
+
+ c4_View Project(const c4_View&) const;
+ c4_View ProjectWithout(const c4_View&) const;
+
+ int GetIndexOf(const c4_RowRef&) const;
+ int RestrictSearch(const c4_RowRef&, int&, int&);
+
+/* Custom views */
+ c4_View Slice(int, int =-1, int =1) const;
+ c4_View Product(const c4_View&) const;
+ c4_View RemapWith(const c4_View&) const;
+ c4_View Pair(const c4_View&) const;
+ c4_View Concat(const c4_View&) const;
+ c4_View Rename(const c4_Property&, const c4_Property&) const;
+
+ c4_View GroupBy(const c4_View&, const c4_ViewProp&) const;
+ c4_View Counts(const c4_View&, const c4_IntProp&) const;
+ c4_View Unique() const;
+
+ c4_View Union(const c4_View&) const;
+ c4_View Intersect(const c4_View&) const;
+ c4_View Different(const c4_View&) const;
+ c4_View Minus(const c4_View&) const;
+
+ c4_View JoinProp(const c4_ViewProp&, bool =false) const;
+ c4_View Join(const c4_View&, const c4_View&, bool =false) const;
+
+ c4_View ReadOnly() const;
+ c4_View Hash(const c4_View&, int =1) const;
+ c4_View Blocked() const;
+ c4_View Ordered(int =1) const;
+ c4_View Indexed(const c4_View&, const c4_View&, bool =false) const;
+
+/* Searching */
+ int Find(const c4_RowRef&, int =0) const;
+ int Search(const c4_RowRef&) const;
+ int Locate(const c4_RowRef&, int* =0) const;
+
+/* Comparing view contents */
+ int Compare(const c4_View&) const;
+
+ friend bool operator== (const c4_View&, const c4_View&);
+ friend bool operator!= (const c4_View&, const c4_View&);
+ friend bool operator< (const c4_View&, const c4_View&);
+ friend bool operator> (const c4_View&, const c4_View&);
+ friend bool operator<= (const c4_View&, const c4_View&);
+ friend bool operator>= (const c4_View&, const c4_View&);
+
+protected:
+ void _IncSeqRef();
+ void _DecSeqRef();
+
+ /// View references are allowed to peek inside view objects
+ friend class c4_ViewRef;
+
+ // DROPPED: Structure() const;
+ // DROPPED: Description(const c4_View& view_);
+};
+
+//---------------------------------------------------------------------------
+
+#if defined(os_aix) && defined(compiler_ibmcxx) && (compiler_ibmcxx > 500)
+ bool operator== (const c4_RowRef& a_, const c4_RowRef& b_);
+ bool operator!= (const c4_RowRef& a_, const c4_RowRef& b_);
+ bool operator<= (const c4_RowRef& a_, const c4_RowRef& b_);
+ bool operator>= (const c4_RowRef& a_, const c4_RowRef& b_);
+ bool operator> (const c4_RowRef& a_, const c4_RowRef& b_);
+ bool operator< (const c4_RowRef& a_, const c4_RowRef& b_);
+#endif
+
+class c4_Cursor
+{
+public:
+ /// Pointer to the sequence
+ c4_Sequence* _seq;
+ /// Current index into the sequence
+ int _index;
+
+/* Construction / destruction / dereferencing */
+ /// Construct a new cursor
+ c4_Cursor (c4_Sequence&, int);
+
+ /// Dereference this cursor to "almost" a row
+ c4_RowRef operator* () const;
+
+ /// This is the same as *(cursor + offset)
+ c4_RowRef operator[] (int) const;
+
+/* Stepping the iterator forwards / backwards */
+ /// Pre-increment the cursor
+ c4_Cursor& operator++ ();
+ /// Post-increment the cursor
+ c4_Cursor operator++ (int);
+ /// Pre-decrement the cursor
+ c4_Cursor& operator-- ();
+ /// Post-decrement the cursor
+ c4_Cursor operator-- (int);
+
+ /// Advance by a given offset
+ c4_Cursor& operator+= (int);
+ /// Back up by a given offset
+ c4_Cursor& operator-= (int);
+
+ /// Subtract a specified offset
+ c4_Cursor operator- (int) const;
+ /// Return the distance between two cursors
+ int operator- (c4_Cursor) const;
+
+ /// Add specified offset
+ friend c4_Cursor operator+ (c4_Cursor, int);
+ /// Add specified offset to cursor
+ friend c4_Cursor operator+ (int, c4_Cursor);
+
+/* Comparing row positions */
+ /// Return true if both cursors are equal
+ friend bool operator== (c4_Cursor, c4_Cursor);
+ /// Return true if both cursors are not equal
+ friend bool operator!= (c4_Cursor, c4_Cursor);
+ /// True if first cursor is less than second cursor
+ friend bool operator< (c4_Cursor, c4_Cursor);
+ /// True if first cursor is greater than second cursor
+ friend bool operator> (c4_Cursor, c4_Cursor);
+ /// True if first cursor is less or equal to second cursor
+ friend bool operator<= (c4_Cursor, c4_Cursor);
+ /// True if first cursor is greater or equal to second cursor
+ friend bool operator>= (c4_Cursor, c4_Cursor);
+
+/* Comparing row contents */
+ /// Return true if the contents of both rows are equal
+ friend bool operator== (const c4_RowRef&, const c4_RowRef&);
+ /// Return true if the contents of both rows are not equal
+ friend bool operator!= (const c4_RowRef&, const c4_RowRef&);
+ /// True if first row is less than second row
+ friend bool operator< (const c4_RowRef&, const c4_RowRef&);
+ /// True if first row is greater than second row
+ friend bool operator> (const c4_RowRef&, const c4_RowRef&);
+ /// True if first row is less or equal to second row
+ friend bool operator<= (const c4_RowRef&, const c4_RowRef&);
+ /// True if first row is greater or equal to second row
+ friend bool operator>= (const c4_RowRef&, const c4_RowRef&);
+};
+
+//---------------------------------------------------------------------------
+
+class c4_RowRef
+{
+ /// A row reference is a cursor in disguise
+ c4_Cursor _cursor;
+
+public:
+/* General operations */
+ /// Assign the value of another row to this one
+ c4_RowRef operator= (const c4_RowRef&);
+ /// Return the cursor associated to this row
+ c4_Cursor operator& () const;
+ /// Return the underlying container view
+ c4_View Container() const;
+
+protected:
+ /// Constructor, not for general use
+ c4_RowRef (c4_Cursor);
+
+ friend class c4_Cursor;
+ friend class c4_Row;
+};
+
+//---------------------------------------------------------------------------
+/// An entry in a collection with copy semantics.
+//
+// Rows can exist by themselves and as contents of views. Row assignment
+// implies that a copy of the contents of the originating row is made.
+//
+// A row is implemented as an unattached view with exactly one element.
+
+class c4_Row : public c4_RowRef
+{
+public:
+ /// Construct a row with no properties
+ c4_Row ();
+ /// Construct a row from another one
+ c4_Row (const c4_Row&);
+ /// Construct a row copy from a row reference
+ c4_Row (const c4_RowRef&);
+ /// Destructor
+ ~c4_Row ();
+
+ /// Assign a copy of another row to this one
+ c4_Row& operator= (const c4_Row&);
+ /// Copy another row to this one
+ c4_Row& operator= (const c4_RowRef&);
+
+ /// Add all properties and values into this row
+ void ConcatRow(const c4_RowRef&);
+ /// Return a new row which is the concatenation of two others
+ friend c4_Row operator+ (const c4_RowRef&, const c4_RowRef&);
+
+private:
+ static c4_Cursor Allocate();
+ static void Release(c4_Cursor);
+};
+
+//---------------------------------------------------------------------------
+
+class c4_Bytes
+{
+ union {
+ t4_byte _buffer [16];
+ double _aligner; // on a Sparc, the int below wasn't enough...
+ };
+
+ t4_byte* _contents;
+ int _size;
+ bool _copy;
+
+public:
+ c4_Bytes ();
+ c4_Bytes (const void*, int);
+ c4_Bytes (const void*, int, bool);
+ c4_Bytes (const c4_Bytes&);
+ ~c4_Bytes ();
+
+ c4_Bytes& operator= (const c4_Bytes&);
+ void Swap(c4_Bytes&);
+
+ int Size() const;
+ const t4_byte* Contents() const;
+
+ t4_byte* SetBuffer(int);
+ t4_byte* SetBufferClear(int);
+
+ friend bool operator== (const c4_Bytes&, const c4_Bytes&);
+ friend bool operator!= (const c4_Bytes&, const c4_Bytes&);
+
+private:
+ void _MakeCopy();
+ void _LoseCopy();
+};
+
+//---------------------------------------------------------------------------
+
+class c4_Storage : public c4_View
+{
+public:
+ /// Construct streaming-only storage object
+ c4_Storage ();
+ /// Construct a storage using the specified strategy handler
+ c4_Storage (c4_Strategy&, bool =false, int =1);
+ /// Construct a storage object, keeping the current structure
+ c4_Storage (const char*, int);
+ /// Reconstruct a storage object from a suitable view
+ c4_Storage (const c4_View&);
+ /// Destructor, usually closes file, but does not commit by default
+ ~c4_Storage ();
+
+ void SetStructure(const char*);
+ bool AutoCommit(bool =true);
+ c4_Strategy& Strategy() const;
+ const char* Description(const char* =0);
+
+ bool SetAside(c4_Storage&);
+ c4_Storage* GetAside() const;
+
+ bool Commit(bool =false);
+ bool Rollback(bool =false);
+
+ c4_ViewRef View(const char*);
+ c4_View GetAs(const char*);
+
+ bool LoadFrom(c4_Stream&);
+ void SaveTo(c4_Stream&);
+
+ //DROPPED: c4_Storage (const char* filename_, const char* description_);
+ //DROPPED: c4_View Store(const char* name_, const c4_View& view_);
+ //DROPPED: c4_HandlerSeq& RootTable() const;
+ //DROPPED: c4_RowRef xContents() const;
+
+private:
+ void Initialize(c4_Strategy&, bool, int);
+};
+
+//---------------------------------------------------------------------------
+
+class c4_Property
+{
+ short _id;
+ char _type;
+
+public:
+ /// Construct a new property with the give type and id
+ c4_Property (char, int);
+ /// Construct a new property with the give type and name
+ c4_Property (char, const char*);
+ ~c4_Property ();
+
+ c4_Property (const c4_Property&);
+ void operator= (const c4_Property&);
+
+ const char* Name() const;
+ char Type() const;
+
+ int GetId() const;
+
+ c4_Reference operator() (const c4_RowRef&) const;
+
+ void Refs(int) const;
+
+ c4_View operator, (const c4_Property&) const;
+
+ static void CleanupInternalData();
+};
+
+ /// Integer properties.
+class c4_IntProp : public c4_Property
+{
+public:
+ /// Construct a new property
+ c4_IntProp (const char*);
+ /// Destructor
+ ~c4_IntProp ();
+
+ /// Get or set an integer property in a row
+ c4_IntRef operator() (const c4_RowRef&) const;
+ /// Get an integer property in a row
+ t4_i32 Get(const c4_RowRef&) const;
+ /// Set an integer property in a row
+ void Set(const c4_RowRef&, t4_i32) const;
+
+ /// Creates a row with one integer, shorthand for AsRow.
+ c4_Row operator[] (t4_i32) const;
+ /// Creates a row with one integer.
+ c4_Row AsRow(t4_i32) const;
+};
+
+#if !q4_TINY
+
+ /// Long int properties.
+class c4_LongProp : public c4_Property
+{
+public:
+ /// Construct a new property
+ c4_LongProp (const char*);
+ /// Destructor
+ ~c4_LongProp ();
+
+ /// Get or set a long int property in a row
+ c4_LongRef operator() (const c4_RowRef&) const;
+ /// Get a long int property in a row
+ t4_i64 Get(const c4_RowRef&) const;
+ /// Set a long int property in a row
+ void Set(const c4_RowRef&, t4_i64) const;
+
+ /// Creates a row with one long int, shorthand for AsRow.
+ c4_Row operator[] (t4_i64) const;
+ /// Creates a row with one long int.
+ c4_Row AsRow(t4_i64) const;
+};
+
+ /// Floating point properties.
+class c4_FloatProp : public c4_Property
+{
+public:
+ /// Construct a new property
+ c4_FloatProp (const char*);
+ /// Destructor
+ ~c4_FloatProp ();
+
+ /// Get or set a floating point property in a row
+ c4_FloatRef operator() (const c4_RowRef&) const;
+ /// Get a floating point property in a row
+ double Get(const c4_RowRef&) const;
+ /// Set a floating point property in a row
+ void Set(const c4_RowRef&, double) const;
+
+ /// Create a row with one floating point value, shorthand for AsRow
+ c4_Row operator[] (double) const;
+ /// Create a row with one floating point value
+ c4_Row AsRow(double) const;
+};
+
+ /// Double precision properties.
+class c4_DoubleProp : public c4_Property
+{
+public:
+ /// Construct a new property.
+ c4_DoubleProp (const char*);
+ /// Destructor
+ ~c4_DoubleProp ();
+
+ /// Get or set a double precision property in a row
+ c4_DoubleRef operator() (const c4_RowRef&) const;
+ /// Get a double precision property in a row
+ double Get(const c4_RowRef&) const;
+ /// Set a double precision property in a row
+ void Set(const c4_RowRef&, double) const;
+
+ /// Create a row with one double precision value, shorthand for AsRow
+ c4_Row operator[] (double) const;
+ /// Create a row with one double precision value
+ c4_Row AsRow(double) const;
+};
+#endif // !q4_TINY
+
+ /// String properties.
+class c4_StringProp : public c4_Property
+{
+public:
+ /// Construct a new property
+ c4_StringProp (const char*);
+ /// Destructor
+ ~c4_StringProp ();
+
+ /// Get or set a string property in a row
+ c4_StringRef operator() (const c4_RowRef&) const;
+ /// Get a string property in a row
+ const char* Get(const c4_RowRef&) const;
+ /// Set a string property in a row
+ void Set(const c4_RowRef&, const char*) const;
+
+ /// Create a row with one string, shorthand for AsRow
+ c4_Row operator[] (const char*) const;
+ /// Create a row with one string
+ c4_Row AsRow(const char*) const;
+};
+
+ /// Binary properties.
+class c4_BytesProp : public c4_Property
+{
+public:
+ /// Construct a new property
+ c4_BytesProp (const char*);
+ /// Destructor
+ ~c4_BytesProp ();
+
+ /// Get or set a bytes property in a row
+ c4_BytesRef operator() (const c4_RowRef&) const;
+ /// Get a bytes property in a row
+ c4_Bytes Get(const c4_RowRef&) const;
+ /// Set a bytes property in a row
+ void Set(const c4_RowRef&, const c4_Bytes&) const;
+
+ /// Create a row with one bytes object, shorthand for AsRow
+ c4_Row operator[] (const c4_Bytes&) const;
+ /// Create a row with one bytes object
+ c4_Row AsRow(const c4_Bytes&) const;
+};
+
+ /// View properties.
+class c4_ViewProp : public c4_Property
+{
+public:
+ /// Construct a new property
+ c4_ViewProp (const char*);
+ /// Destructor
+ ~c4_ViewProp ();
+
+ /// Get or set a view property in a row
+ c4_ViewRef operator() (const c4_RowRef&) const;
+ /// Get a view property in a row
+ c4_View Get(const c4_RowRef&) const;
+ /// Set a view property in a row
+ void Set(const c4_RowRef&, const c4_View&) const;
+
+ /// Create a row with one view, shorthand for AsRow
+ c4_Row operator[] (const c4_View&) const;
+ /// Create a row with one view
+ c4_Row AsRow(const c4_View&) const;
+};
+
+//---------------------------------------------------------------------------
+
+class c4_CustomViewer
+{
+protected:
+ /// Constructor, must be overriden in derived class
+ c4_CustomViewer ();
+public:
+ /// Destructor
+ virtual ~c4_CustomViewer ();
+
+ /// Return the structure of this view (initialization, called once)
+ virtual c4_View GetTemplate() = 0;
+ /// Return the number of rows in this view
+ virtual int GetSize() = 0;
+ int Lookup(const c4_RowRef&, int&);
+ virtual int Lookup(c4_Cursor, int&);
+ /// Fetch one data item, return it as a generic data value
+ virtual bool GetItem(int, int, c4_Bytes&) = 0;
+ virtual bool SetItem(int, int, const c4_Bytes&);
+ bool InsertRows(int, const c4_RowRef&, int =1);
+ virtual bool InsertRows(int, c4_Cursor, int =1);
+ virtual bool RemoveRows(int, int =1);
+};
+
+//---------------------------------------------------------------------------
+/// A stream is a virtual helper class to serialize in binary form.
+
+class c4_Stream
+{
+public:
+ virtual ~c4_Stream ();
+
+ /// Fetch some bytes sequentially
+ virtual int Read(void*, int) = 0;
+ /// Store some bytes sequentially
+ virtual bool Write(const void*, int) = 0;
+};
+
+//---------------------------------------------------------------------------
+/// A strategy encapsulates code dealing with the I/O system interface.
+
+class c4_Strategy
+{
+public:
+ c4_Strategy ();
+ virtual ~c4_Strategy ();
+
+ virtual bool IsValid() const;
+ virtual int DataRead(t4_i32, void*, int);
+ virtual void DataWrite(t4_i32, const void*, int);
+ virtual void DataCommit(t4_i32);
+ virtual void ResetFileMapping();
+ virtual t4_i32 FileSize();
+ virtual t4_i32 FreshGeneration();
+
+ void SetBase(t4_i32);
+ t4_i32 EndOfData(t4_i32 =-1);
+
+ /// True if the storage format is not native (default is false)
+ bool _bytesFlipped;
+ /// Error code of last failed I/O operation, zero if I/O was ok
+ int _failure;
+ /// First byte in file mapping, zero if not active
+ const t4_byte* _mapStart;
+ /// Number of bytes filled with active data
+ t4_i32 _dataSize;
+ /// All file positions are relative to this offset
+ t4_i32 _baseOffset;
+ /// The root position of the shallow tree walks
+ t4_i32 _rootPos;
+ /// The size of the root column
+ t4_i32 _rootLen;
+};
+
+//---------------------------------------------------------------------------
+/// A sequence is an abstract base class for views on ranges of records.
+//
+// Sequences represent arrays of rows (or indexed collections / tables).
+// Insertion and removal of entries is allowed, but could take linear time.
+// A reference count is maintained to decide when the object should go away.
+
+class c4_Sequence
+{
+ /// Reference count
+ int _refCount;
+ /// Pointer to dependency list, or null if nothing depends on this
+ c4_Dependencies* _dependencies;
+
+protected:
+ /// Optimization: cached property index
+ int _propertyLimit;
+ /// Optimization: property map for faster access
+ short* _propertyMap; // see c4_HandlerSeq::Reset()
+ /// allocated on first use by c4_Sequence::Buffer()
+ c4_Bytes* _tempBuf;
+
+public:
+/* General */
+ /// Abstract constructor
+ c4_Sequence ();
+
+ virtual int Compare(int, c4_Cursor) const;
+ virtual bool RestrictSearch(c4_Cursor, int&, int&);
+ void SetAt(int, c4_Cursor);
+ virtual int RemapIndex(int, const c4_Sequence*) const;
+
+/* Reference counting */
+ void IncRef();
+ void DecRef();
+ int NumRefs() const;
+
+/* Adding / removing rows */
+ /// Return the current number of rows
+ virtual int NumRows() const = 0;
+ void Resize(int, int =-1);
+
+ virtual void InsertAt(int, c4_Cursor, int =1);
+ virtual void RemoveAt(int, int =1);
+ virtual void Move(int, int);
+
+/* Properties */
+ int NthPropId(int) const;
+ int PropIndex(int);
+ int PropIndex(const c4_Property&);
+
+ /// Return the number of data handlers in this sequence
+ virtual int NumHandlers() const = 0;
+ /// Return a reference to the N-th handler in this sequence
+ virtual c4_Handler& NthHandler(int) const = 0;
+ /// Return the context of the N-th handler in this sequence
+ virtual const c4_Sequence* HandlerContext(int) const = 0;
+ /// Add the specified data handler to this sequence
+ virtual int AddHandler(c4_Handler*) = 0;
+ /// Create a handler of the appropriate type
+ virtual c4_Handler* CreateHandler(const c4_Property&) = 0;
+
+ virtual const char* Description();
+
+/* Element access */
+ /// Return width of specified data item
+ virtual int ItemSize(int, int);
+ /// Retrieve one data item from this sequence
+ virtual bool Get(int, int, c4_Bytes&);
+ /// Store a data item into this sequence
+ virtual void Set(int, const c4_Property&, const c4_Bytes&);
+
+/* Dependency notification */
+ void Attach(c4_Sequence*);
+ void Detach(c4_Sequence*);
+ /// Return a pointer to the dependencies, or null
+ c4_Dependencies* GetDependencies() const;
+
+ virtual c4_Notifier* PreChange(c4_Notifier&);
+ virtual void PostChange(c4_Notifier&);
+
+ const char* UseTempBuffer(const char*);
+
+protected:
+ virtual ~c4_Sequence ();
+
+ void ClearCache();
+
+public: //! for c4_Table::Sequence setup
+ virtual void SetNumRows(int) = 0;
+ virtual c4_Persist* Persist() const;
+
+ c4_Bytes& Buffer();
+
+private:
+ c4_Sequence (const c4_Sequence&); // not implemented
+ void operator= (const c4_Sequence&); // not implemented
+};
+
+//---------------------------------------------------------------------------
+/// A reference is used to get or set typed data, using derived classes.
+//
+// Objects of this class are only intended to be used as a temporary handle
+// while getting and setting properties in a row. They are normally only
+// constructed as result of function overload operators: "property (row)".
+
+class c4_Reference
+{
+protected:
+ /// The cursor which points to the data
+ c4_Cursor _cursor;
+ /// The property associated to this reference
+ const c4_Property& _property;
+
+public:
+ /// Constructor
+ c4_Reference (const c4_RowRef&, const c4_Property&);
+
+ /// Assignment of one data item
+ c4_Reference& operator= (const c4_Reference&);
+
+ /// Return width of the referenced data item
+ int GetSize() const;
+ /// Retrieve the value of the referenced data item
+ bool GetData(c4_Bytes&) const;
+ /// Store a value into the referenced data item
+ void SetData(const c4_Bytes&) const;
+
+ /// Return true if the contents of both references is equal
+ friend bool operator== (const c4_Reference&, const c4_Reference&);
+ /// Return true if the contents of both references is not equal
+ friend bool operator!= (const c4_Reference&, const c4_Reference&);
+
+private:
+ void operator& () const; // not implemented
+};
+
+//---------------------------------------------------------------------------
+
+ /// Used to get or set integer values.
+class c4_IntRef : public c4_Reference
+{
+public:
+ /// Constructor
+ c4_IntRef (const c4_Reference&);
+ /// Get the value as integer
+ operator t4_i32 () const;
+ /// Set the value to the specified integer
+ c4_IntRef& operator= (t4_i32);
+};
+
+#if !q4_TINY
+
+ /// Used to get or set long int values.
+class c4_LongRef : public c4_Reference
+{
+public:
+ /// Constructor
+ c4_LongRef (const c4_Reference&);
+ /// Get the value as long int
+ operator t4_i64 () const;
+ /// Set the value to the specified long int
+ c4_LongRef& operator= (t4_i64);
+};
+
+ /// Used to get or set floating point values.
+class c4_FloatRef : public c4_Reference
+{
+public:
+ /// Constructor
+ c4_FloatRef (const c4_Reference&);
+ /// Get the value as floating point
+ operator double () const;
+ /// Set the value to the specified floating point
+ c4_FloatRef& operator= (double);
+};
+
+ /// Used to get or set double precision values.
+class c4_DoubleRef : public c4_Reference
+{
+public:
+ /// Constructor
+ c4_DoubleRef (const c4_Reference&);
+ /// Get the value as floating point
+ operator double () const;
+ /// Set the value to the specified floating point
+ c4_DoubleRef& operator= (double);
+};
+
+#endif // !q4_TINY
+
+ /// Used to get or set binary object values.
+class c4_BytesRef : public c4_Reference
+{
+public:
+ /// Constructor
+ c4_BytesRef (const c4_Reference&);
+ /// Get the value as binary object
+ operator c4_Bytes () const;
+ /// Set the value to the specified binary object
+ c4_BytesRef& operator= (const c4_Bytes&);
+
+ /// Fetch data from the memo field, up to end if length is zero
+ c4_Bytes Access(t4_i32, int =0) const;
+ /// Store data, resize by diff_ bytes, return true if successful
+ bool Modify(const c4_Bytes&, t4_i32, int =0) const;
+};
+
+ /// Used to get or set string values.
+class c4_StringRef : public c4_Reference
+{
+public:
+ /// Constructor
+ c4_StringRef (const c4_Reference&);
+ /// Get the value as string
+ operator const char* () const;
+ /// Set the value to the specified string
+ c4_StringRef& operator= (const char*);
+};
+
+ /// Used to get or set view values.
+class c4_ViewRef : public c4_Reference
+{
+public:
+ /// Constructor
+ c4_ViewRef (const c4_Reference&);
+ /// Get the value as view
+ operator c4_View () const;
+ /// Set the value to the specified view
+ c4_ViewRef& operator= (const c4_View&);
+};
+
+//---------------------------------------------------------------------------
+// Debug logging option, can generate log of changes for one/all properties
+
+#if q4_LOGPROPMODS
+FILE* f4_LogPropMods(FILE* fp_, int propId_);
+#else
+#define f4_LogPropMods(a,b) 0
+#endif
+
+//---------------------------------------------------------------------------
+
+#if q4_INLINE
+#include "mk4.inl"
+#endif
+
+//---------------------------------------------------------------------------
+
+#endif // __MK4_H__
diff --git a/akregator/src/mk4storage/metakit/include/mk4.inl b/akregator/src/mk4storage/metakit/include/mk4.inl
new file mode 100644
index 000000000..1c717a367
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/include/mk4.inl
@@ -0,0 +1,874 @@
+// mk4.inl --
+// $Id$
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit/
+
+/** @file
+ * Public definitions which are usually inlined
+ */
+
+/////////////////////////////////////////////////////////////////////////////
+// Reordered inlines so they are always defined before their first use
+
+d4_inline c4_Cursor c4_RowRef::operator& () const
+{
+ return _cursor;
+}
+
+/** Return a unique id for this property
+ *
+ * A property object in fact merely represents an entry in a globally
+ * maintained symbol table. Each property is assigned a unique id,
+ * which remains valid as long as some reference to that property
+ * exists. In general, property id's remain unique as long as the
+ * application runs. Do not store id's on file, since they are
+ * not guaranteed to remain the same across program invocations.
+ * All properties with the same name are given the same id.
+ */
+d4_inline int c4_Property::GetId() const
+{
+ return _id;
+}
+
+//////////////////////////////////////////////////////////////////////////////////
+
+#if !q4_LONG64 && !defined (LONG_LONG) && !HAVE_LONG_LONG
+
+d4_inline bool operator== (const t4_i64 a_, const t4_i64 b_)
+{
+ return a_.l1 == b_.l1 && a_.l2 == b_.l2;
+}
+
+d4_inline bool operator< (const t4_i64 a_, const t4_i64 b_)
+{
+ return a_.l2 < b_.l2 || a_.l2 == b_.l2 && a_.l2 < b_.l2;
+}
+
+#endif
+
+//////////////////////////////////////////////////////////////////////////////////
+// c4_View
+
+/// Returns the number of entries in this view.
+d4_inline int c4_View::GetSize() const
+{
+ return _seq->NumRows();
+}
+
+/** Change the size of this view
+ * Since views act like dynamic arrays, you can quickly
+ * change their size. Increasing the size will append rows
+ * with zero/empty values, while decreasing it will delete
+ * the last rows. The growBy_ parameter is currently unused.
+ */
+d4_inline void c4_View::SetSize(int newSize_, int growBy_)
+{
+ _seq->Resize(newSize_, growBy_);
+}
+
+/// Removes all entries (sets size to zero).
+d4_inline void c4_View::RemoveAll()
+{
+ SetSize(0);
+}
+
+/// Return a pointer to the persistence handler, or zero
+d4_inline c4_Persist* c4_View::Persist() const
+{
+ return _seq->Persist();
+}
+
+/**
+ * Change the value of the specified entry. If the new value has
+ * other properties, these will be added to the underlying view.
+ *
+ * @param index_ the zero-based row index
+ * @param newElem_ the row to copy to this view
+ */
+d4_inline void c4_View::SetAt(int index_, const c4_RowRef& newElem_)
+{
+ _seq->SetAt(index_, &newElem_);
+}
+
+/**
+ * Insert a copy of the contents of another view. This is identical to
+ * inserting the specified number of default entries and then setting
+ * each of them to the new element value passed as argument.
+ */
+d4_inline void c4_View::InsertAt(
+ int index_, ///< zero-based row index
+ const c4_RowRef& newElem_, ///< the value to insert
+ int count_ ///< number of copies to insert, must be > 0
+ )
+{
+ _seq->InsertAt(index_, &newElem_, count_);
+}
+
+/**
+ * Remove entries starting at the given index. Entries which have
+ * other view references may cause these views to be deleted if their
+ * reference counts drop to zero because of this removal.
+ *
+ * @param index_ the zero-based row index
+ * @param count_ the number of entries to remove
+ */
+d4_inline void c4_View::RemoveAt(int index_, int count_)
+{
+ _seq->RemoveAt(index_, count_);
+}
+
+/** Return the number of properties present in this view.
+ * @return A non-negative integer
+ */
+d4_inline int c4_View::NumProperties() const
+{
+ return _seq->NumHandlers();
+}
+
+/** Find the index of a property, given its id
+ * @param propId_ Unique id associated to a specific propoerty
+ * @return The index of the property, or -1 of it was not found
+ */
+d4_inline int c4_View::FindProperty(int propId_)
+{
+ return _seq->PropIndex(propId_);
+}
+
+ /// Return a decription if there is a fixed structure, else zero
+d4_inline const char* c4_View::Description() const
+{
+ return _seq->Description();
+}
+
+ /// Increase the reference count of the associated sequence
+d4_inline void c4_View::_IncSeqRef()
+{
+ _seq->IncRef();
+}
+
+ /// Decrease the reference count of the associated sequence
+d4_inline void c4_View::_DecSeqRef()
+{
+ _seq->DecRef();
+}
+
+/// Destructor, decrements reference count
+d4_inline c4_View::~c4_View ()
+{
+ _DecSeqRef();
+}
+
+ /// Return true if the contents of both views are equal
+d4_inline bool operator== (const c4_View& a_, const c4_View& b_)
+{
+ return a_.GetSize() == b_.GetSize() && a_.Compare(b_) == 0;
+}
+
+ /// Return true if the contents of both views are not equal
+d4_inline bool operator!= (const c4_View& a_, const c4_View& b_)
+{
+ return !(a_ == b_);
+}
+
+ /// True if first view is less than second view
+d4_inline bool operator< (const c4_View& a_, const c4_View& b_)
+{
+ return a_.Compare(b_) < 0;
+}
+
+ /// True if first view is greater than second view
+d4_inline bool operator> (const c4_View& a_, const c4_View& b_)
+{
+ return b_ < a_;
+}
+
+ /// True if first view is less or equal to second view
+d4_inline bool operator<= (const c4_View& a_, const c4_View& b_)
+{
+ return !(b_ < a_);
+}
+
+ /// True if first view is greater or equal to second view
+d4_inline bool operator>= (const c4_View& a_, const c4_View& b_)
+{
+ return !(a_ < b_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_Cursor
+
+/** Constructs a new cursor.
+ *
+ * Cursor cannot be created without an underlying view, but you could
+ * define a global "nullView" object and then initialize the cursor with
+ * "&nullView[0]". This works because cursors need not point to a valid row.
+ */
+d4_inline c4_Cursor::c4_Cursor (c4_Sequence& seq_, int index_)
+ : _seq (&seq_), _index (index_)
+{
+}
+
+/// Pre-increments the cursor.
+d4_inline c4_Cursor& c4_Cursor::operator++ ()
+{
+ ++_index;
+ return *this;
+}
+
+/// Post-increments the cursor.
+d4_inline c4_Cursor c4_Cursor::operator++ (int)
+{
+ return c4_Cursor (*_seq, _index++);
+}
+
+/// Pre-decrements the cursor.
+d4_inline c4_Cursor& c4_Cursor::operator-- ()
+{
+ --_index;
+ return *this;
+}
+
+/// Post-decrements the cursor.
+d4_inline c4_Cursor c4_Cursor::operator-- (int)
+{
+ return c4_Cursor (*_seq, _index--);
+}
+
+/// Advances by a given offset.
+d4_inline c4_Cursor& c4_Cursor::operator+= (int offset_)
+{
+ _index += offset_;
+ return *this;
+}
+
+/// Backs up by a given offset.
+d4_inline c4_Cursor& c4_Cursor::operator-= (int offset_)
+{
+ _index -= offset_;
+ return *this;
+}
+
+/// Subtracts a specified offset.
+d4_inline c4_Cursor c4_Cursor::operator- (int offset_) const
+{
+ return c4_Cursor (*_seq, _index - offset_);
+}
+
+/// Returns the distance between two cursors.
+d4_inline int c4_Cursor::operator- (c4_Cursor cursor_) const
+{
+ return _index - cursor_._index;
+}
+
+/// Add a specified offset.
+d4_inline c4_Cursor operator+ (c4_Cursor cursor_, int offset_)
+{
+ return c4_Cursor (*cursor_._seq, cursor_._index + offset_);
+}
+
+/// Adds specified offset to cursor.
+d4_inline c4_Cursor operator+ (int offset_, c4_Cursor cursor_)
+{
+ return cursor_ + offset_;
+}
+
+d4_inline bool operator== (c4_Cursor a_, c4_Cursor b_)
+{
+ return a_._seq == b_._seq && a_._index == b_._index;
+}
+
+d4_inline bool operator!= (c4_Cursor a_, c4_Cursor b_)
+{
+ return !(a_ == b_);
+}
+
+d4_inline bool operator< (c4_Cursor a_, c4_Cursor b_)
+{
+ return a_._seq < b_._seq ||
+ a_._seq == b_._seq && a_._index < b_._index;
+}
+
+d4_inline bool operator> (c4_Cursor a_, c4_Cursor b_)
+{
+ return b_ < a_;
+}
+
+d4_inline bool operator<= (c4_Cursor a_, c4_Cursor b_)
+{
+ return !(b_ < a_);
+}
+
+d4_inline bool operator>= (c4_Cursor a_, c4_Cursor b_)
+{
+ return !(a_ < b_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_RowRef
+
+d4_inline c4_RowRef::c4_RowRef (c4_Cursor cursor_)
+ : _cursor (cursor_)
+{
+}
+
+d4_inline c4_RowRef c4_RowRef::operator= (const c4_RowRef& rowRef_)
+{
+ if (_cursor != rowRef_._cursor)
+ _cursor._seq->SetAt(_cursor._index, &rowRef_);
+
+ return *this;
+}
+
+d4_inline c4_View c4_RowRef::Container() const
+{
+ return _cursor._seq;
+}
+
+d4_inline bool operator== (const c4_RowRef& a_, const c4_RowRef& b_)
+{
+ return (&a_)._seq->Compare((&a_)._index, &b_) == 0;
+}
+
+d4_inline bool operator!= (const c4_RowRef& a_, const c4_RowRef& b_)
+{
+ return !(a_ == b_);
+}
+
+d4_inline bool operator< (const c4_RowRef& a_, const c4_RowRef& b_)
+{
+ // 25-5-1998: don't exchange a and b, this comparison is -not- symmetric
+ return (&a_)._seq->Compare((&a_)._index, &b_) < 0;
+}
+
+d4_inline bool operator> (const c4_RowRef& a_, const c4_RowRef& b_)
+{
+ // 25-5-1998: don't exchange a and b, this comparison is -not- symmetric
+ return (&a_)._seq->Compare((&a_)._index, &b_) > 0;
+}
+
+d4_inline bool operator<= (const c4_RowRef& a_, const c4_RowRef& b_)
+{
+ return !(a_ > b_);
+}
+
+d4_inline bool operator>= (const c4_RowRef& a_, const c4_RowRef& b_)
+{
+ return !(a_ < b_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_Bytes
+
+ /// Construct an empty binary object
+d4_inline c4_Bytes::c4_Bytes ()
+ : _size (0), _copy (false)
+{
+ _contents = 0; // moved out of intializers for DEC CXX 5.7
+}
+
+ /// Construct an object with contents, no copy
+d4_inline c4_Bytes::c4_Bytes (const void* buf_, int len_)
+ : _size (len_), _copy (false)
+{
+ _contents = (t4_byte*) buf_; // moved out of intializers for DEC CXX 5.7
+}
+
+/// Returns a pointer to the contents.
+d4_inline const t4_byte* c4_Bytes::Contents() const
+{
+ return _contents;
+}
+
+/// Returns the number of bytes of its contents.
+d4_inline int c4_Bytes::Size() const
+{
+ return _size;
+}
+
+d4_inline void c4_Bytes::_LoseCopy()
+{
+ if (_copy)
+ delete [] (char*) _contents;
+}
+
+/// Returns true if the contents of both objects is not equal.
+d4_inline bool operator!= (const c4_Bytes& a_, const c4_Bytes& b_)
+{
+ return !(a_ == b_);
+}
+
+/// Destructor, if a copy was made, it will be released here.
+d4_inline c4_Bytes::~c4_Bytes ()
+{
+ _LoseCopy();
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_Reference
+
+d4_inline c4_Reference::c4_Reference (const c4_RowRef& rowRef_,
+ const c4_Property& prop_)
+ : _cursor (&rowRef_), _property (prop_)
+{
+}
+
+d4_inline int c4_Reference::GetSize() const
+{
+ return _cursor._seq->ItemSize(_cursor._index, _property.GetId());
+}
+
+d4_inline bool c4_Reference::GetData(c4_Bytes& buf_) const
+{
+ return _cursor._seq->Get(_cursor._index, _property.GetId(), buf_);
+}
+
+d4_inline void c4_Reference::SetData(const c4_Bytes& buf_) const
+{
+ _cursor._seq->Set(_cursor._index, _property, buf_);
+}
+
+d4_inline bool operator!= (const c4_Reference& a_, const c4_Reference& b_)
+{
+ return !(a_ == b_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_IntRef
+
+d4_inline c4_IntRef::c4_IntRef (const c4_Reference& value_)
+ : c4_Reference (value_)
+{
+}
+
+/////////////////////////////////////////////////////////////////////////////
+#if !q4_TINY
+/////////////////////////////////////////////////////////////////////////////
+// c4_LongRef
+
+d4_inline c4_LongRef::c4_LongRef (const c4_Reference& value_)
+ : c4_Reference (value_)
+{
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_FloatRef
+
+d4_inline c4_FloatRef::c4_FloatRef (const c4_Reference& value_)
+ : c4_Reference (value_)
+{
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_DoubleRef
+
+d4_inline c4_DoubleRef::c4_DoubleRef (const c4_Reference& value_)
+ : c4_Reference (value_)
+{
+}
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // !q4_TINY
+/////////////////////////////////////////////////////////////////////////////
+// c4_BytesRef
+
+d4_inline c4_BytesRef::c4_BytesRef (const c4_Reference& value_)
+ : c4_Reference (value_)
+{
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_StringRef
+
+d4_inline c4_StringRef::c4_StringRef (const c4_Reference& value_)
+ : c4_Reference (value_)
+{
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_ViewRef
+
+d4_inline c4_ViewRef::c4_ViewRef (const c4_Reference& value_)
+ : c4_Reference (value_)
+{
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_Property
+
+d4_inline c4_Property::c4_Property (char type_, int id_)
+ : _id ((short) id_), _type (type_)
+{
+}
+
+ /// Get or set this untyped property in a row
+d4_inline c4_Reference c4_Property::operator() (const c4_RowRef& rowRef_) const
+{
+ return c4_Reference (rowRef_, *this);
+}
+
+ /// Return a view like the first, with a property appended to it
+d4_inline c4_View c4_Property::operator, (const c4_Property& prop_) const
+{
+ return c4_View (*this), prop_;
+}
+
+ /// Return the type of this property
+d4_inline char c4_Property::Type() const
+{
+ return _type;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_IntProp
+
+d4_inline c4_IntProp::c4_IntProp (const char* name_)
+ : c4_Property ('I', name_)
+{
+}
+
+d4_inline c4_IntProp::~c4_IntProp ()
+{
+}
+
+d4_inline c4_IntRef c4_IntProp::operator() (const c4_RowRef& rowRef_) const
+{
+ return c4_Reference (rowRef_, *this);
+}
+
+d4_inline t4_i32 c4_IntProp::Get(const c4_RowRef& rowRef_) const
+{
+ return operator() (rowRef_);
+}
+
+d4_inline void c4_IntProp::Set(const c4_RowRef& rowRef_, t4_i32 value_) const
+{
+ operator() (rowRef_) = value_;
+}
+
+d4_inline c4_Row c4_IntProp::AsRow(t4_i32 value_) const
+{
+ c4_Row row;
+ operator() (row) = value_;
+ return row;
+}
+
+d4_inline c4_Row c4_IntProp::operator[] (t4_i32 value_) const
+{
+ return AsRow(value_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+#if !q4_TINY
+/////////////////////////////////////////////////////////////////////////////
+// c4_LongProp
+
+d4_inline c4_LongProp::c4_LongProp (const char* name_)
+ : c4_Property ('L', name_)
+{
+}
+
+d4_inline c4_LongProp::~c4_LongProp ()
+{
+}
+
+d4_inline c4_LongRef c4_LongProp::operator() (const c4_RowRef& rowRef_) const
+{
+ return c4_Reference (rowRef_, *this);
+}
+
+d4_inline t4_i64 c4_LongProp::Get(const c4_RowRef& rowRef_) const
+{
+ return operator() (rowRef_);
+}
+
+d4_inline void c4_LongProp::Set(const c4_RowRef& rowRef_, t4_i64 value_) const
+{
+ operator() (rowRef_) = value_;
+}
+
+d4_inline c4_Row c4_LongProp::AsRow(t4_i64 value_) const
+{
+ c4_Row row;
+ operator() (row) = value_;
+ return row;
+}
+
+d4_inline c4_Row c4_LongProp::operator[] (t4_i64 value_) const
+{
+ return AsRow(value_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_FloatProp
+
+d4_inline c4_FloatProp::c4_FloatProp (const char* name_)
+ : c4_Property ('F', name_)
+{
+}
+
+d4_inline c4_FloatProp::~c4_FloatProp ()
+{
+}
+
+d4_inline c4_FloatRef c4_FloatProp::operator() (const c4_RowRef& rowRef_) const
+{
+ return c4_Reference (rowRef_, *this);
+}
+
+d4_inline double c4_FloatProp::Get(const c4_RowRef& rowRef_) const
+{
+ return operator() (rowRef_);
+}
+
+d4_inline void c4_FloatProp::Set(const c4_RowRef& rowRef_, double value_) const
+{
+ operator() (rowRef_) = value_;
+}
+
+d4_inline c4_Row c4_FloatProp::AsRow(double value_) const
+{
+ c4_Row row;
+ operator() (row) = value_;
+ return row;
+}
+
+d4_inline c4_Row c4_FloatProp::operator[] (double value_) const
+{
+ return AsRow(value_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_DoubleProp
+
+d4_inline c4_DoubleProp::c4_DoubleProp (const char* name_)
+ : c4_Property ('D', name_)
+{
+}
+
+d4_inline c4_DoubleProp::~c4_DoubleProp ()
+{
+}
+
+d4_inline c4_DoubleRef c4_DoubleProp::operator() (const c4_RowRef& rowRef_) const
+{
+ return c4_Reference (rowRef_, *this);
+}
+
+d4_inline double c4_DoubleProp::Get(const c4_RowRef& rowRef_) const
+{
+ return operator() (rowRef_);
+}
+
+d4_inline void c4_DoubleProp::Set(const c4_RowRef& rowRef_, double value_) const
+{
+ operator() (rowRef_) = value_;
+}
+
+d4_inline c4_Row c4_DoubleProp::AsRow(double value_) const
+{
+ c4_Row row;
+ operator() (row) = value_;
+ return row;
+}
+
+d4_inline c4_Row c4_DoubleProp::operator[] (double value_) const
+{
+ return AsRow(value_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // !q4_TINY
+/////////////////////////////////////////////////////////////////////////////
+// c4_BytesProp
+
+d4_inline c4_BytesProp::c4_BytesProp (const char* name_)
+ : c4_Property ('B', name_)
+{
+}
+
+d4_inline c4_BytesProp::~c4_BytesProp ()
+{
+}
+
+d4_inline c4_BytesRef c4_BytesProp::operator() (const c4_RowRef& rowRef_) const
+{
+ return c4_Reference (rowRef_, *this);
+}
+
+d4_inline c4_Bytes c4_BytesProp::Get(const c4_RowRef& rowRef_) const
+{
+ return operator() (rowRef_);
+}
+
+d4_inline void c4_BytesProp::Set(const c4_RowRef& rowRef_, const c4_Bytes& value_) const
+{
+ operator() (rowRef_) = value_;
+}
+
+d4_inline c4_Row c4_BytesProp::AsRow(const c4_Bytes& value_) const
+{
+ c4_Row row;
+ operator() (row) = value_;
+ return row;
+}
+
+d4_inline c4_Row c4_BytesProp::operator[] (const c4_Bytes& value_) const
+{
+ return AsRow(value_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_StringProp
+
+d4_inline c4_StringProp::c4_StringProp (const char* name_)
+ : c4_Property ('S', name_)
+{
+}
+
+d4_inline c4_StringProp::~c4_StringProp ()
+{
+}
+
+d4_inline c4_StringRef c4_StringProp::operator() (const c4_RowRef& rowRef_) const
+{
+ return c4_Reference (rowRef_, *this);
+}
+
+d4_inline const char* c4_StringProp::Get(const c4_RowRef& rowRef_) const
+{
+ return operator() (rowRef_);
+}
+
+d4_inline void c4_StringProp::Set(const c4_RowRef& rowRef_, const char* value_) const
+{
+ operator() (rowRef_) = value_;
+}
+
+d4_inline c4_Row c4_StringProp::AsRow(const char* value_) const
+{
+ c4_Row row;
+ operator() (row) = value_;
+ return row;
+}
+
+d4_inline c4_Row c4_StringProp::operator[] (const char* value_) const
+{
+ return AsRow(value_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_ViewProp
+
+d4_inline c4_ViewProp::c4_ViewProp (const char* name_)
+ : c4_Property ('V', name_)
+{
+}
+
+d4_inline c4_ViewProp::~c4_ViewProp ()
+{
+}
+
+d4_inline c4_ViewRef c4_ViewProp::operator() (const c4_RowRef& rowRef_) const
+{
+ return c4_Reference (rowRef_, *this);
+}
+
+d4_inline c4_View c4_ViewProp::Get(const c4_RowRef& rowRef_) const
+{
+ return operator() (rowRef_);
+}
+
+d4_inline void c4_ViewProp::Set(const c4_RowRef& rowRef_, const c4_View& value_) const
+{
+ operator() (rowRef_) = value_;
+}
+
+d4_inline c4_Row c4_ViewProp::AsRow(const c4_View& value_) const
+{
+ c4_Row row;
+ operator() (row) = value_;
+ return row;
+}
+
+d4_inline c4_Row c4_ViewProp::operator[] (const c4_View& value_) const
+{
+ return AsRow(value_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_Strategy
+
+ /// True if we can do I/O with this object
+d4_inline bool c4_Strategy::IsValid() const
+{
+ return false;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_CustomViewer
+
+d4_inline c4_CustomViewer::c4_CustomViewer()
+{
+}
+
+d4_inline int c4_CustomViewer::Lookup(const c4_RowRef& r_, int& n_)
+{
+ return Lookup(&r_, n_); // c4_Cursor
+}
+
+d4_inline bool c4_CustomViewer::InsertRows(int p_, const c4_RowRef& r_, int n_)
+{
+ return InsertRows(p_, &r_, n_); // c4_Cursor
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_Sequence
+
+d4_inline c4_Dependencies* c4_Sequence::GetDependencies() const
+{
+ return _dependencies;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Reordered inlines so they are always used after their definition
+
+/// Dereferences this cursor to "almost" a row.
+d4_inline c4_RowRef c4_Cursor::operator* () const
+{
+ return *(c4_Cursor*) this; // cast avoids a const problem with BCPP 4.52
+}
+
+/// This is the same as *(cursor + offset).
+d4_inline c4_RowRef c4_Cursor::operator[] (int offset_) const
+{
+ return *(*this + offset_);
+}
+
+/// Returns a reference to specified entry, for use as RHS or LHS
+d4_inline c4_RowRef c4_View::GetAt(int index_) const
+{
+ return * c4_Cursor (*_seq, index_);
+}
+
+/** Element access, shorthand for GetAt
+ * @return A reference to the specified row in the view.
+ * This reference can be used on either side of the assignment operator.
+ */
+d4_inline c4_RowRef c4_View::operator[] (
+ int index_ ///< zero-based row index
+ ) const
+{
+ return GetAt(index_);
+}
+
+/** Element access, shorthand for GetAt
+ * @return A reference to the specified row in the view.
+ * This reference can be used on either side of the assignment operator.
+ */
+d4_inline c4_RowRef c4_View::ElementAt(
+ int index_ ///< zero-based row index
+ )
+{
+ return GetAt(index_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/akregator/src/mk4storage/metakit/include/mk4dll.h b/akregator/src/mk4storage/metakit/include/mk4dll.h
new file mode 100644
index 000000000..979971fac
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/include/mk4dll.h
@@ -0,0 +1,112 @@
+// mk4dll.h --
+// $Id$
+// This is part of Metakit, see http://www.equi4.com/metakit/
+//
+// Import declarations for DLLs
+
+#ifndef __MK4_H__
+#error This file is included by "mk4.h", it cannot be used standalone
+#endif
+
+#ifndef d4_DLL
+#ifdef _WIN32
+#ifdef _USRDLL
+#define d4_DLL __declspec(dllexport)
+#else
+#define d4_DLL __declspec(dllimport)
+#endif
+#else
+#define d4_DLL
+#endif
+#endif
+
+#ifndef d4_DLLSPEC
+#ifdef _MSC_VER
+#define d4_DLLSPEC(t) d4_DLL t
+#else
+#define d4_DLLSPEC(t) t d4_DLL
+#endif
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// Declarations in this file
+
+ class d4_DLL c4_Bytes;
+ class d4_DLL c4_BytesProp;
+ class d4_DLL c4_BytesRef;
+ class d4_DLL c4_Cursor;
+ class d4_DLL c4_CustomViewer;
+ class d4_DLL c4_DoubleProp;
+ class d4_DLL c4_DoubleRef;
+ class d4_DLL c4_FileStrategy;
+ class d4_DLL c4_FileStream;
+ class d4_DLL c4_FloatProp;
+ class d4_DLL c4_FloatRef;
+ class d4_DLL c4_IntProp;
+ class d4_DLL c4_IntRef;
+ class d4_DLL c4_LongRef;
+ class d4_DLL c4_Property;
+ class d4_DLL c4_Reference;
+ class d4_DLL c4_Row;
+ class d4_DLL c4_RowRef;
+ class d4_DLL c4_Sequence;
+ class d4_DLL c4_Storage;
+ class d4_DLL c4_Strategy;
+ class d4_DLL c4_Stream;
+ class d4_DLL c4_StringProp;
+ class d4_DLL c4_StringRef;
+ class d4_DLL c4_View;
+ class d4_DLL c4_ViewProp;
+ class d4_DLL c4_ViewRef;
+
+#if !q4_MFC
+ class d4_DLL c4_String;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+
+ d4_DLLSPEC(bool) operator== (const c4_View& a_, const c4_View& b_);
+ d4_DLLSPEC(bool) operator!= (const c4_View& a_, const c4_View& b_);
+ d4_DLLSPEC(bool) operator< (const c4_View& a_, const c4_View& b_);
+ d4_DLLSPEC(bool) operator> (const c4_View& a_, const c4_View& b_);
+ d4_DLLSPEC(bool) operator<= (const c4_View& a_, const c4_View& b_);
+ d4_DLLSPEC(bool) operator>= (const c4_View& a_, const c4_View& b_);
+
+ d4_DLLSPEC(bool) operator== (c4_Cursor a_, c4_Cursor b_);
+ d4_DLLSPEC(bool) operator!= (c4_Cursor a_, c4_Cursor b_);
+ d4_DLLSPEC(bool) operator< (c4_Cursor a_, c4_Cursor b_);
+ d4_DLLSPEC(bool) operator> (c4_Cursor a_, c4_Cursor b_);
+ d4_DLLSPEC(bool) operator<= (c4_Cursor a_, c4_Cursor b_);
+ d4_DLLSPEC(bool) operator>= (c4_Cursor a_, c4_Cursor b_);
+ d4_DLLSPEC(c4_Cursor) operator+ (c4_Cursor cursor_, int offset_);
+ d4_DLLSPEC(c4_Cursor) operator+ (int offset_, c4_Cursor cursor_);
+
+ d4_DLLSPEC(bool) operator== (const c4_RowRef& a_, const c4_RowRef& b_);
+ d4_DLLSPEC(bool) operator!= (const c4_RowRef& a_, const c4_RowRef& b_);
+ d4_DLLSPEC(bool) operator< (const c4_RowRef& a_, const c4_RowRef& b_);
+ d4_DLLSPEC(bool) operator> (const c4_RowRef& a_, const c4_RowRef& b_);
+ d4_DLLSPEC(bool) operator<= (const c4_RowRef& a_, const c4_RowRef& b_);
+ d4_DLLSPEC(bool) operator>= (const c4_RowRef& a_, const c4_RowRef& b_);
+ d4_DLLSPEC(c4_Row) operator+ (const c4_RowRef& a_, const c4_RowRef& b_);
+
+ d4_DLLSPEC(bool) operator== (const c4_Bytes& a_, const c4_Bytes& b_);
+ d4_DLLSPEC(bool) operator!= (const c4_Bytes& a_, const c4_Bytes& b_);
+
+ d4_DLLSPEC(bool) operator== (const c4_Reference&, const c4_Reference&);
+ d4_DLLSPEC(bool) operator!= (const c4_Reference&, const c4_Reference&);
+
+#if !q4_MFC
+ d4_DLLSPEC(c4_String) operator+ (const c4_String&, const c4_String&);
+ d4_DLLSPEC(c4_String) operator+ (const c4_String&, const char*);
+ d4_DLLSPEC(c4_String) operator+ (const char*, const c4_String&);
+
+ d4_DLLSPEC(bool) operator== (const c4_String&, const c4_String&);
+ d4_DLLSPEC(bool) operator!= (const c4_String&, const c4_String&);
+ d4_DLLSPEC(bool) operator== (const c4_String& s1, const char* s2);
+ d4_DLLSPEC(bool) operator== (const char* s1, const c4_String& s2);
+ d4_DLLSPEC(bool) operator!= (const c4_String& s1, const char* s2);
+ d4_DLLSPEC(bool) operator!= (const char* s1, const c4_String& s2);
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+
diff --git a/akregator/src/mk4storage/metakit/include/mk4io.h b/akregator/src/mk4storage/metakit/include/mk4io.h
new file mode 100644
index 000000000..d70db9c52
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/include/mk4io.h
@@ -0,0 +1,66 @@
+// mk4io.h --
+// $Id$
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit/
+
+/** @file
+ * Declaration of the file stream and strategy classes.
+ */
+
+#ifndef __MK4IO_H__
+#define __MK4IO_H__
+
+#include <stdio.h>
+
+/////////////////////////////////////////////////////////////////////////////
+/// A file stream can be used to serialize using the stdio library.
+
+class c4_FileStream : public c4_Stream
+{
+public:
+ c4_FileStream (FILE* stream_, bool owned_ =false);
+ virtual ~c4_FileStream ();
+
+ virtual int Read(void* buffer_, int length_);
+ virtual bool Write(const void* buffer_, int length_);
+
+ FILE* _stream;
+ bool _owned;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+/// A file strategy encapsulates code dealing with all file I/O.
+
+class c4_FileStrategy : public c4_Strategy
+{
+public:
+ /// Construct a new strategy object
+ c4_FileStrategy (FILE* file_ =0);
+ virtual ~c4_FileStrategy ();
+
+ /// True if we can do I/O with this object
+ virtual bool IsValid() const;
+ /// Open a data file by name
+ virtual bool DataOpen(const char* fileName_, int mode_);
+ /// Read a number of bytes
+ virtual int DataRead(t4_i32 pos_, void* buffer_, int length_);
+ /// Write a number of bytes, return true if successful
+ virtual void DataWrite(t4_i32 pos_, const void* buffer_, int length_);
+ /// Flush and truncate file
+ virtual void DataCommit(t4_i32 newSize_);
+ /// Support for memory-mapped files
+ virtual void ResetFileMapping();
+ /// Report total size of the datafile
+ virtual t4_i32 FileSize();
+ /// Return a good value to use as fresh generation counter
+ virtual t4_i32 FreshGeneration();
+
+protected:
+ /// Pointer to file object
+ FILE* _file;
+ /// Pointer to same file object, if it must be deleted at end
+ FILE* _cleanup;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+#endif // __MK4IO_H__
diff --git a/akregator/src/mk4storage/metakit/include/mk4str.h b/akregator/src/mk4storage/metakit/include/mk4str.h
new file mode 100644
index 000000000..7124a29ea
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/include/mk4str.h
@@ -0,0 +1,181 @@
+// mk4str.h --
+// $Id$
+// This is part of Metakit, see http://www.equi4.com/metakit/
+
+/** @file
+ * Declarations of the string package.
+ */
+
+#ifndef __MK4STR_H__
+#define __MK4STR_H__
+
+/////////////////////////////////////////////////////////////////////////////
+
+#if q4_MFC // Microsoft Foundation Classes
+
+#ifdef _WINDOWS
+#include <afxwin.h>
+#else
+#include <afxcoll.h>
+#endif
+
+#if _MSC_VER == 800
+// MSVC 1.52 thinks a typedef has no constructor, use define instead
+#define c4_String CString
+#elif _MSC_VER >= 1300
+// VC 7.0 does not like "class" (6-2-2002, Zhang Dehua)
+typedef CString c4_String;
+#else
+typedef class CString c4_String;
+#endif
+
+#elif q4_STD // STL and standard strings
+
+#include <string>
+
+#if !defined (d4_std) // the default is to use namespaces
+#define d4_std std
+#endif
+
+ /// STL-based string class, modeled after the MFC version
+class c4_String : public d4_std::string
+{
+ typedef d4_std::string string;
+
+public:
+ c4_String ();
+ c4_String (char ch, int nDup =1);
+ c4_String (const char* str);
+ c4_String (const void* ptr, int len);
+ c4_String (const d4_std::string& s);
+ c4_String (const c4_String& s);
+ ~c4_String ();
+
+ const c4_String& operator= (const c4_String&);
+
+ operator const char* () const;
+
+ char operator[] (int i) const;
+
+ friend c4_String operator+ (const c4_String&, const c4_String&);
+ friend c4_String operator+ (const c4_String&, const char*);
+ friend c4_String operator+ (const char*, const c4_String&);
+
+ const c4_String& operator+= (const c4_String& s);
+ const c4_String& operator+= (const char* s);
+
+ int GetLength() const;
+ bool IsEmpty() const;
+ void Empty();
+
+ c4_String Mid(int nFirst, int nCount =25000) const;
+ c4_String Left(int nCount) const;
+ c4_String Right(int nCount) const;
+
+ int Compare(const char* str) const;
+ int CompareNoCase(const char* str) const;
+
+ bool operator< (const c4_String& str) const;
+
+ int Find(char ch) const;
+ int ReverseFind(char ch) const;
+ int FindOneOf(const char* set) const;
+
+ int Find(const char* sub) const;
+
+ c4_String SpanIncluding(const char* set) const;
+ c4_String SpanExcluding(const char* set) const;
+};
+
+bool operator== (const c4_String&, const c4_String&);
+bool operator!= (const c4_String&, const c4_String&);
+
+d4_inline bool operator== (const c4_String& s1, const char* s2);
+d4_inline bool operator== (const char* s1, const c4_String& s2);
+
+d4_inline bool operator!= (const c4_String& s1, const char* s2);
+d4_inline bool operator!= (const char* s1, const c4_String& s2);
+
+#else // Universal replacement classes
+
+ /// An efficient string class, modeled after the MFC version
+class c4_String
+{
+public:
+ c4_String ();
+ c4_String (char ch, int nDup =1);
+ c4_String (const char* str);
+ c4_String (const unsigned char* str);
+ c4_String (const void* ptr, int len);
+ c4_String (const c4_String& s);
+ ~c4_String ();
+
+ const c4_String& operator= (const c4_String&);
+
+ operator const char* () const;
+ operator const unsigned char* () const;
+
+ char operator[] (int i) const;
+
+ friend c4_String operator+ (const c4_String&, const c4_String&);
+ friend c4_String operator+ (const c4_String&, const char*);
+ friend c4_String operator+ (const char*, const c4_String&);
+// friend c4_String operator+ (const c4_String&, char);
+// friend c4_String operator+ (char, const c4_String&);
+
+ const c4_String& operator+= (const c4_String& s);
+ const c4_String& operator+= (const char* s);
+// const c4_String& operator+= (char c);
+
+ int GetLength() const;
+ bool IsEmpty() const;
+ void Empty(); // free up the data
+
+ c4_String Mid(int nFirst, int nCount =25000) const;
+ c4_String Left(int nCount) const; // first nCount chars
+ c4_String Right(int nCount) const; // last nCount chars
+
+ friend bool operator== (const c4_String&, const c4_String&); // memcmp
+ friend bool operator!= (const c4_String&, const c4_String&); // opposite
+
+ // only defined for strings having no zero bytes inside them:
+
+ int Compare(const char* str) const; // strcmp
+ int CompareNoCase(const char* str) const; // stricmp
+
+ bool operator< (const c4_String& str) const;
+
+ int Find(char ch) const; // strchr
+ int ReverseFind(char ch) const; // strrchr
+ int FindOneOf(const char* set) const; // strpbrk
+
+ int Find(const char* sub) const; // strstr
+
+ c4_String SpanIncluding(const char* set) const; // strspn
+ c4_String SpanExcluding(const char* set) const; // strcspn
+
+private:
+ void Init(const void* p, int n);
+ const char* Data() const;
+ int FullLength() const;
+
+ unsigned char* _value;
+};
+
+bool operator== (const c4_String& s1, const char* s2);
+bool operator== (const char* s1, const c4_String& s2);
+
+bool operator!= (const c4_String& s1, const char* s2);
+bool operator!= (const char* s1, const c4_String& s2);
+
+#endif // q4_MFC elif q4_STD else q4_UNIV
+
+/////////////////////////////////////////////////////////////////////////////
+
+#if q4_INLINE
+#include "mk4str.inl"
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+
+#endif // __MK4STR_H__
diff --git a/akregator/src/mk4storage/metakit/include/mk4str.inl b/akregator/src/mk4storage/metakit/include/mk4str.inl
new file mode 100644
index 000000000..4f95fa514
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/include/mk4str.inl
@@ -0,0 +1,299 @@
+// mk4str.inl --
+// $Id$
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit/
+
+/** @file
+ * Members of the string package which are usually inlined
+ */
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_String
+
+#if q4_MFC // Microsoft Foundation Classes
+
+#elif q4_STD // STL and standard strings
+
+/// Construct empty string
+d4_inline c4_String::c4_String ()
+{
+}
+
+d4_inline c4_String::c4_String (char ch_, int nDup_)
+ : string (nDup_, ch_)
+{
+}
+
+d4_inline c4_String::c4_String (const char* str_)
+ : string (str_)
+{
+}
+
+d4_inline c4_String::c4_String (const void* ptr_, int len_)
+ : string ((const char*) ptr_, len_)
+{
+}
+
+d4_inline c4_String::c4_String (const d4_std::string& s_)
+ : string (s_)
+{
+}
+
+d4_inline c4_String::c4_String (const c4_String& s_)
+ : string (s_)
+{
+}
+
+d4_inline c4_String::~c4_String ()
+{
+}
+
+d4_inline const c4_String& c4_String::operator= (const c4_String& s_)
+{
+ *(string*) this = s_;
+ return *this;
+}
+
+d4_inline c4_String::operator const char* () const
+{
+ return c_str();
+}
+
+d4_inline char c4_String::operator[] (int i) const
+{
+ return at(i);
+}
+
+d4_inline c4_String operator+ (const c4_String& a_, const c4_String& b_)
+{
+ return (d4_std::string) a_ + (d4_std::string) b_;
+}
+
+d4_inline c4_String operator+ (const c4_String& a_, const char* b_)
+{
+ return (d4_std::string) a_ + (d4_std::string) b_;
+}
+
+d4_inline c4_String operator+ (const char* a_, const c4_String& b_)
+{
+ return (d4_std::string) a_ + (d4_std::string) b_;
+}
+
+d4_inline const c4_String& c4_String::operator+= (const c4_String& s_)
+{
+ *(string*) this += s_;
+ return *this;
+}
+
+d4_inline const c4_String& c4_String::operator+= (const char* s_)
+{
+ *(string*) this += s_;
+ return *this;
+}
+
+d4_inline int c4_String::GetLength() const
+{
+ return length();
+}
+
+d4_inline bool c4_String::IsEmpty() const
+{
+ return empty();
+}
+
+d4_inline void c4_String::Empty()
+{
+ erase();
+}
+
+d4_inline c4_String c4_String::Left(int nCount_) const
+{
+ if (nCount_ > length())
+ nCount_ = length();
+ return substr(0, nCount_);
+}
+
+d4_inline c4_String c4_String::Right(int nCount_) const
+{
+ if (nCount_ > length())
+ nCount_ = length();
+ return substr(length() - nCount_, nCount_);
+}
+
+d4_inline int c4_String::Compare(const char* str_) const
+{
+ return compare(str_);
+}
+
+d4_inline bool c4_String::operator< (const c4_String& str_) const
+{
+ return compare(str_) < 0;
+}
+
+d4_inline int c4_String::Find(char ch_) const
+{
+ return find(ch_);
+}
+
+d4_inline int c4_String::ReverseFind(char ch_) const
+{
+ return rfind(ch_);
+}
+
+d4_inline int c4_String::FindOneOf(const char* set_) const
+{
+ return find_first_of(set_);
+}
+
+d4_inline int c4_String::Find(const char* sub_) const
+{
+ return find(sub_);
+}
+
+d4_inline c4_String c4_String::SpanIncluding(const char* set_) const
+{
+ return substr(0, find_first_not_of(set_));
+}
+
+d4_inline c4_String c4_String::SpanExcluding(const char* set_) const
+{
+ return substr(0, find_first_of(set_));
+}
+
+d4_inline bool operator== (const c4_String& a_, const c4_String& b_)
+{
+ return (d4_std::string) a_ == (d4_std::string) b_;
+}
+
+d4_inline bool operator!= (const c4_String& a_, const c4_String& b_)
+{
+ return (d4_std::string) a_ != (d4_std::string) b_;
+}
+
+d4_inline bool operator== (const c4_String& a_, const char* b_)
+{
+ return (d4_std::string) a_ == (d4_std::string) b_;
+}
+
+d4_inline bool operator== (const char* a_, const c4_String& b_)
+{
+ return (d4_std::string) a_ == (d4_std::string) b_;
+}
+
+d4_inline bool operator!= (const c4_String& a_, const char* b_)
+{
+ return (d4_std::string) a_ != (d4_std::string) b_;
+}
+
+d4_inline bool operator!= (const char* a_, const c4_String& b_)
+{
+ return (d4_std::string) a_ != (d4_std::string) b_;
+}
+
+#else // Universal replacement classes
+
+/// Construct empty string
+d4_inline c4_String::c4_String ()
+{
+ Init(0, 0);
+}
+
+/// Construct string from Pascal-style <count,chars...> data
+d4_inline c4_String::c4_String (const unsigned char* ptr)
+{
+ Init(ptr + 1, ptr ? *ptr : 0);
+}
+
+/// Construct string from a specified area in memory
+d4_inline c4_String::c4_String (const void* ptr, int len)
+{
+ Init(ptr, len);
+}
+
+d4_inline const c4_String& c4_String::operator+= (const c4_String& s)
+{
+ return *this = *this + s;
+}
+
+d4_inline const c4_String& c4_String::operator+= (const char* s)
+{
+ return *this += (c4_String) s;
+}
+
+d4_inline const char* c4_String::Data() const
+{
+ return (const char*) (_value + 2);
+}
+
+d4_inline c4_String::operator const char* () const
+{
+ return Data();
+}
+
+d4_inline c4_String::operator const unsigned char* () const
+{
+ return (unsigned char*) Data() - 1;
+}
+
+d4_inline char c4_String::operator[] (int i) const
+{
+ return Data()[i];
+}
+
+d4_inline int c4_String::GetLength() const
+{
+ return _value[1] != 255 ? _value[1] : FullLength();
+}
+
+d4_inline bool c4_String::IsEmpty() const
+{
+ return GetLength() == 0;
+}
+
+d4_inline void c4_String::Empty()
+{
+ *this = "";
+}
+
+d4_inline bool c4_String::operator< (const c4_String& a) const
+{
+ return Compare(a) < 0;
+}
+
+d4_inline c4_String operator+ (const char* a, const c4_String& b)
+{
+ return (c4_String) a + b;
+}
+
+d4_inline c4_String operator+ (const c4_String& a, const char* b)
+{
+ return a + (c4_String) b;
+}
+
+d4_inline bool operator== (const char* a, const c4_String& b)
+{
+ return b.Compare(a) == 0;
+}
+
+d4_inline bool operator== (const c4_String& a, const char* b)
+{
+ return a.Compare(b) == 0;
+}
+
+d4_inline bool operator!= (const c4_String& a, const c4_String& b)
+{
+ return !(a == b);
+}
+
+d4_inline bool operator!= (const char* a, const c4_String& b)
+{
+ return b.Compare(a) != 0;
+}
+
+d4_inline bool operator!= (const c4_String& a, const char* b)
+{
+ return a.Compare(b) != 0;
+}
+
+#endif // q4_UNIV
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/akregator/src/mk4storage/metakit/src/Makefile.am b/akregator/src/mk4storage/metakit/src/Makefile.am
new file mode 100644
index 000000000..e428fe930
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/src/Makefile.am
@@ -0,0 +1,10 @@
+INCLUDES = -I$(srcdir)/../include
+
+noinst_LTLIBRARIES = libmetakitlocal.la
+
+noinst_HEADERS = borc.h column.h column.inl custom.h derived.h field.h field.inl format.h gnuc.h handler.h handler.inl header.h mfc.h \
+ msvc.h mwcw.h persist.h remap.h std.h store.h store.inl univ.h univ.inl win.h
+
+libmetakitlocal_la_SOURCES = column.cpp custom.cpp derived.cpp field.cpp fileio.cpp format.cpp handler.cpp persist.cpp remap.cpp std.cpp store.cpp \
+ string.cpp table.cpp univ.cpp view.cpp viewx.cpp
+
diff --git a/akregator/src/mk4storage/metakit/src/borc.h b/akregator/src/mk4storage/metakit/src/borc.h
new file mode 100644
index 000000000..2b881fc90
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/src/borc.h
@@ -0,0 +1,33 @@
+// borc.h --
+// $Id$
+// This is part of Metakit, see http://www.equi4.com/metakit/
+
+/** @file
+ * Configuration header for Borland C++
+ */
+
+#define q4_BORC 1
+
+ // get rid of several common warning messages
+#if !q4_STRICT
+#pragma warn -aus // 'identifier' is assigned a value that is never used
+#pragma warn -par // Parameter 'parameter' is never used.
+#pragma warn -sig // Conversion may lose significant digits
+#pragma warn -use // 'identifier' declared but never used
+#endif
+
+#if __BORLANDC__ >= 0x500
+#define q4_BOOL 1 // supports the bool datatype
+ // undo previous defaults, because q4_BOOL is not set early enough
+#undef false
+#undef true
+#undef bool
+#endif
+
+#if !defined (q4_EXPORT)
+#define q4_EXPORT 1 // requires export/import specifiers
+#endif
+
+#if defined (__MT__)
+#define q4_MULTI 1 // uses multi-threading
+#endif
diff --git a/akregator/src/mk4storage/metakit/src/column.cpp b/akregator/src/mk4storage/metakit/src/column.cpp
new file mode 100644
index 000000000..2d191c645
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/src/column.cpp
@@ -0,0 +1,1533 @@
+// column.cpp --
+// $Id$
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit/
+
+/** @file
+ * Implements c4_Column, c4_ColOfInts, and c4_ColIter
+ */
+
+#include "header.h"
+#include "column.h"
+#include "persist.h"
+
+#if !q4_INLINE
+#include "column.inl"
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+
+#if !HAVE_MEMMOVE && !HAVE_BCOPY
+ // in case we have no library memmove, or one that can't handle overlap
+
+ void f4_memmove (void* to_, const void* from_, int n_)
+ {
+ char* to = (char*) to_;
+ const char* from = (const char*) from_;
+
+ if (to + n_ <= from || from + n_ <= to)
+ memcpy(to, from, n_);
+ else if (to < from)
+ while (--n_ >= 0)
+ *to++ = *from++;
+ else if (to > from)
+ while (--n_ >= 0)
+ to[n_] = from[n_];
+ }
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_Column
+
+c4_Column::c4_Column (c4_Persist* persist_)
+ : _position (0), _size (0), _persist (persist_), _gap (0),
+ _slack (0), _dirty (false)
+{
+}
+
+#if q4_CHECK
+
+ // debugging version to verify that the internal data is consistent
+ void c4_Column::Validate() const
+ {
+ d4_assert(0 <= _slack && _slack < kSegMax);
+
+ if (_segments.GetSize() == 0)
+ return; // ok, not initialized
+
+ d4_assert(_gap <= _size);
+
+ int n = fSegIndex(_size + _slack);
+ d4_assert(n == _segments.GetSize() - 1);
+
+ t4_byte* p = (t4_byte*) _segments.GetAt(n);
+
+ if (fSegRest(_size + _slack) == 0)
+ d4_assert(p == 0);
+ else
+ d4_assert(p != 0);
+
+ while (--n >= 0) {
+ t4_byte* p = (t4_byte*) _segments.GetAt(n);
+ d4_assert(p != 0);
+ }
+ }
+
+#else
+
+ // nothing, so inline this thing to avoid even the calling overhead
+ d4_inline void c4_Column::Validate() const
+ {
+ }
+
+#endif
+
+c4_Column::~c4_Column ()
+{
+ Validate();
+ ReleaseAllSegments();
+
+ // this is needed to remove this column from the cache
+ d4_assert(_slack == 0);
+ FinishSlack();
+
+ _slack = -1; // bad value in case we try to set up again (!)
+}
+
+c4_Strategy& c4_Column::Strategy() const
+{
+ d4_assert(_persist != 0);
+
+ return _persist->Strategy();
+}
+
+bool c4_Column::IsMapped() const
+{
+ return _position > 1 && _persist != 0 && Strategy()._mapStart != 0;
+}
+
+bool c4_Column::UsesMap(const t4_byte* ptr_) const
+{
+ // the most common falsifying case is checked first
+ return _persist != 0 && ptr_ >= Strategy()._mapStart &&
+ Strategy()._dataSize != 0 && // added 2003-05-08, thx V DeMarco
+ ptr_ - Strategy()._mapStart < Strategy()._dataSize;
+}
+
+bool c4_Column::RequiresMap() const
+{
+ if (_persist != 0 && Strategy()._mapStart != 0)
+ for (int i = _segments.GetSize(); --i >= 0; )
+ if (UsesMap((t4_byte*) _segments.GetAt(i)))
+ return true;
+ return false;
+}
+
+void c4_Column::ReleaseSegment(int index_)
+{
+ t4_byte* p = (t4_byte*) _segments.GetAt(index_);
+ if (!UsesMap(p))
+ delete [] p;
+}
+
+void c4_Column::ReleaseAllSegments()
+{
+ //for (int i = 0; i < _segments.GetSize(); ++i)
+ for (int i = _segments.GetSize(); --i >= 0; )
+ ReleaseSegment(i); // last one might be a null pointer
+
+ _segments.SetSize(0);
+
+ _gap = 0;
+ _slack = 0;
+
+ if (_size == 0)
+ _position = 0;
+
+ _dirty = false;
+}
+
+ //@func Define where data is on file, or setup buffers (opt cleared).
+void c4_Column::SetLocation(t4_i32 pos_, t4_i32 size_)
+{
+ d4_assert(size_ > 0 || pos_ == 0);
+
+ ReleaseAllSegments();
+
+ _position = pos_;
+ _size = size_;
+
+ // There are two position settings:
+ //
+ // 0 = raw buffer, no file access
+ // >1 = file position from where data can be loaded on demand
+
+ _dirty = pos_ == 0;
+}
+
+void c4_Column::PullLocation(const t4_byte*& ptr_)
+{
+ d4_assert(_segments.GetSize() == 0);
+
+ _size = PullValue(ptr_);
+ _position = 0;
+ if (_size > 0) {
+ _position = PullValue(ptr_);
+ if (_position > 0) {
+ d4_assert(_persist != 0);
+ _persist->OccupySpace(_position, _size);
+ }
+ }
+
+ _dirty = false;
+}
+
+ //@func How many contiguous bytes are there at a specified position.
+int c4_Column::AvailAt(t4_i32 offset_) const
+{
+ d4_assert(offset_ <= _size);
+ d4_assert(_gap <= _size);
+
+ t4_i32 limit = _gap;
+
+ if (offset_ >= _gap) {
+ offset_ += _slack;
+ limit = _size + _slack;
+ }
+
+ int count = kSegMax - fSegRest(offset_);
+ if (offset_ + count > limit)
+ count = (int) (limit - offset_);
+
+ // either some real data or it must be at the very end of all data
+ d4_assert(0 < count && count <= kSegMax ||
+ count == 0 && offset_ == _size + _slack);
+ return count;
+}
+
+void c4_Column::SetupSegments()
+{
+ d4_assert(_segments.GetSize() == 0);
+ d4_assert(_gap == 0);
+ d4_assert(_slack == 0);
+
+ // The last entry in the _segments array is either a partial block
+ // or a null pointer, so calling "fSegIndex(_size)" is always allowed.
+
+ int n = fSegIndex(_size) + 1;
+ _segments.SetSize(n);
+
+ // treat last block differently if it is a partial entry
+ int last = n;
+ if (fSegRest(_size))
+ --last; // this block is partial, size is 1 .. kSegMax-1
+ else
+ --n; // the last block is left as a null pointer
+
+ int id = -1;
+ if (_position < 0) { // special aside id, figure out the real position
+ d4_assert(_persist != 0);
+ id = ~_position;
+ _position = _persist->LookupAside(id);
+ d4_assert(_position >= 0);
+ }
+
+ if (IsMapped()) {
+ // setup for mapped files is quick, just fill in the pointers
+ d4_assert(_position > 1);
+ d4_assert(_position + (n-1) * kSegMax <= Strategy()._dataSize);
+ const t4_byte* map = Strategy()._mapStart + _position;
+
+ for (int i = 0; i < n; ++i) {
+ _segments.SetAt(i, (t4_byte*) map); // loses const
+ map += kSegMax;
+ }
+ } else {
+ int chunk = kSegMax;
+ t4_i32 pos = _position;
+
+ // allocate buffers, load them if necessary
+ for (int i = 0; i < n; ++i) {
+ if (i == last)
+ chunk = fSegRest(_size);
+
+ t4_byte* p = d4_new t4_byte [chunk];
+ _segments.SetAt(i, p);
+
+ if (_position > 0) {
+ d4_dbgdef(int n =)
+ Strategy().DataRead(pos, p, chunk);
+ d4_assert(n == chunk);
+ pos += chunk;
+ }
+ }
+ }
+
+ if (id >= 0) {
+ d4_assert(_persist != 0);
+ _persist->ApplyAside(id, *this);
+ }
+
+ Validate();
+}
+
+ //@func Makes sure the requested data is in a modifiable buffer.
+t4_byte* c4_Column::CopyNow(t4_i32 offset_)
+{
+ d4_assert(offset_ <= _size);
+
+ _dirty = true;
+
+ const t4_byte* ptr = LoadNow(offset_);
+ if (UsesMap(ptr)) {
+ if (offset_ >= _gap)
+ offset_ += _slack;
+
+ // this will only force creation of a buffer
+ ptr = CopyData(offset_, offset_, 0);
+ d4_assert(!UsesMap(ptr));
+ }
+
+ return (t4_byte*) ptr;
+}
+
+ //@func Copies data, creating a buffer if needed. Must be in single segment.
+t4_byte* c4_Column::CopyData(t4_i32 to_, t4_i32 from_, int count_)
+{
+ int i = fSegIndex(to_);
+ t4_byte* p = (t4_byte*) _segments.GetAt(i);
+
+ if (UsesMap(p)) {
+ int n = kSegMax;
+ if (fSegOffset(i) + n > _size + _slack)
+ n = (int) (_size + _slack - fSegOffset(i));
+
+ d4_assert(n > 0);
+
+ t4_byte* q = d4_new t4_byte [n];
+ memcpy(q, p, n); // some copying can be avoided, overwritten below...
+ _segments.SetAt(i, q);
+
+ p = q;
+ }
+
+ p += fSegRest(to_);
+
+ if (count_ > 0) {
+ d4_assert(fSegIndex(to_ + count_ - 1) == i);
+
+ const t4_byte* src = (const t4_byte*) _segments.GetAt(fSegIndex(from_));
+ d4_memmove(p, src + fSegRest(from_), count_);
+ }
+
+ return p;
+}
+
+ /*
+ * Resizing a segmented vector can be a complicated operation.
+ * For now, simply making it work in all cases is the first priority.
+ *
+ * A major simplification - and good performance improvement - is caused
+ * by the trick of maintaining a "gap" in the data, which can be "moved"
+ * around to allow fast insertion as well as simple (delayed) deletion.
+ *
+ * The only complexity comes from the fact that the gap must end up being
+ * less than one full segment in size. Therefore, insertion and removal
+ * across segment boundaries needs to handle a variety of situations.
+ *
+ * Since complete segments can be inserted quickly, this approach avoids
+ * lots of copying when consecutive insertions/deletions are clustered.
+ * Even random changes move half as much (on average) as without a gap.
+ *
+ * The price is the overhead of up to one segment of empty space, and the
+ * complexity of this code (all the magic is within this c4_Column class).
+ */
+
+void c4_Column::MoveGapUp(t4_i32 dest_)
+{
+ d4_assert(dest_ <= _size);
+ d4_assert(_gap < dest_);
+ d4_assert(_slack > 0);
+
+ // forward loop to copy contents down, in little pieces if need be
+ while (_gap < dest_) {
+ int n = kSegMax - fSegRest(_gap);
+ t4_i32 curr = _gap + n;
+ if (curr > dest_)
+ curr = dest_;
+
+ // copy to [_gap..curr), which is inside one segment
+ d4_assert(_gap < curr);
+ d4_assert(fSegIndex(_gap) == fSegIndex(curr - 1));
+
+ // copy from [_gap + _slack .. curr + _slack), of the same size
+ t4_i32 fromBeg = _gap + _slack;
+ t4_i32 fromEnd = curr + _slack;
+
+ while (fromBeg < fromEnd) {
+ int k = kSegMax - fSegRest(fromBeg);
+ if (fromBeg + k > fromEnd)
+ k = (int) (fromEnd - fromBeg);
+
+ d4_assert(k > 0);
+
+ CopyData(_gap, fromBeg, k);
+
+ _gap += k;
+ fromBeg += k;
+ }
+
+ _gap = curr;
+ }
+
+ d4_assert(_gap == dest_);
+}
+
+void c4_Column::MoveGapDown(t4_i32 dest_)
+{
+ d4_assert(dest_ <= _size);
+ d4_assert(_gap > dest_);
+ d4_assert(_slack > 0);
+
+ // reverse loop to copy contents up, in little pieces if need be
+ t4_i32 toEnd = _gap + _slack;
+ t4_i32 toBeg = dest_ + _slack;
+
+ while (toEnd > toBeg) {
+ int n = fSegRest(toEnd);
+ t4_i32 curr = toEnd - (n ? n : kSegMax);
+ if (curr < toBeg)
+ curr = toBeg;
+
+ // copy to [curr..toEnd), which is inside one segment
+ d4_assert(curr < toEnd);
+ d4_assert(fSegIndex(curr) == fSegIndex(toEnd - 1));
+
+ // copy from [fromBeg .. _gap), which has the same size
+ t4_i32 fromBeg = _gap - (toEnd - curr);
+
+ while (_gap > fromBeg) {
+ int k = fSegRest(_gap);
+ if (k == 0)
+ k = kSegMax;
+ if (_gap - k < fromBeg)
+ k = (int) (_gap - fromBeg);
+
+ d4_assert(k > 0);
+
+ toEnd -= k;
+ _gap -= k;
+
+ CopyData(toEnd, _gap, k);
+ }
+ }
+
+ d4_assert(_gap == dest_);
+}
+
+void c4_Column::MoveGapTo(t4_i32 pos_)
+{
+ d4_assert(pos_ <= _size);
+
+ if (_slack == 0) // if there is no real gap, then just move it
+ _gap = pos_;
+ else if (_gap < pos_) // move the gap up, ie. some bytes down
+ MoveGapUp(pos_);
+ else if (_gap > pos_) // move the gap down, ie. some bytes up
+ if (_gap - pos_ > _size - _gap + fSegRest(pos_)) {
+ RemoveGap(); // it's faster to get rid of the gap instead
+ _gap = pos_;
+ }
+ else // normal case, move some bytes up
+ MoveGapDown(pos_);
+
+ d4_assert(_gap == pos_);
+
+ Validate();
+}
+
+void c4_Column::RemoveGap()
+{
+ if (_slack > 0) {
+ if (_gap < _size)
+ MoveGapUp(_size);
+
+ d4_assert(_gap == _size); // the gap is now at the end
+ d4_assert(_slack < kSegMax);
+
+ // Case 1: gap is at start of segment
+ // ==================================
+ //
+ // G G+S
+ //
+ // | |
+ // :----+xx:
+ // | |
+ //
+ // i i+1 (limit)
+ //
+ // Case 2: gap is inside segment
+ // =============================
+ //
+ // G G+S
+ //
+ // | |
+ // :--+--+x:
+ // | |
+ //
+ // i i+1 (limit)
+ //
+ // Case 3: gap runs to end of segment
+ // ==================================
+ //
+ // G G+S
+ //
+ // | |
+ // :--+----:0000000:
+ // | | |
+ //
+ // i i+1 i+2 (limit)
+ //
+ // Case 4: gap is across two segments
+ // ==================================
+ //
+ // G G+S
+ //
+ // | |
+ // :--+----:-+xxxxx:
+ // | | |
+ //
+ // i i+1 i+2 (limit)
+
+ int i = fSegIndex(_gap);
+ int n = fSegRest(_gap);
+
+ if (n == 0) { // case 1
+ ReleaseSegment(i);
+ _segments.SetAt(i, 0);
+ } else {
+ if (n + _slack > kSegMax) // case 4
+ ReleaseSegment(i+1);
+
+ // truncate rest of segment
+ t4_byte* p = d4_new t4_byte [n];
+ memcpy(p, _segments.GetAt(i), n);
+
+ ReleaseSegment(i);
+ _segments.SetAt(i, p);
+ _segments.SetSize(i + 1);
+ }
+
+ _slack = 0;
+ }
+
+ Validate();
+}
+
+void c4_Column::Grow(t4_i32 off_, t4_i32 diff_)
+{
+ d4_assert(off_ <= _size);
+ d4_assert(diff_ > 0);
+
+ if (_segments.GetSize() == 0)
+ SetupSegments();
+
+ Validate();
+
+ _dirty = true;
+
+ // move the gap so it starts where we want to insert
+ MoveGapTo(off_);
+
+ t4_i32 bigSlack = _slack;
+ if (bigSlack < diff_) { // only do more if this isn't good enough
+ // number of segments to insert
+ int n = fSegIndex(diff_ - _slack + kSegMax - 1);
+ d4_assert(n > 0);
+
+ int i1 = fSegIndex(_gap);
+ int i2 = fSegIndex(_gap + _slack);
+
+ bool moveBack = false;
+
+ if (i2 > i1) // cases 3 and 4
+ ++i1;
+ else if (fSegRest(_gap)) // case 2
+ moveBack = true;
+
+ _segments.InsertAt(i1, 0, n);
+ for (int i = 0; i < n; ++i)
+ _segments.SetAt(i1 + i, d4_new t4_byte [(int) kSegMax]);
+
+ bigSlack += fSegOffset(n);
+
+ if (moveBack) {
+ d4_assert(i1 == fSegIndex(_gap));
+
+ // we have inserted too low, move bytes in front of gap back
+ CopyData(fSegOffset(i1), fSegOffset(i1 + n), fSegRest(_gap));
+ }
+ }
+
+ d4_assert(diff_ <= bigSlack && bigSlack < diff_ + kSegMax);
+
+ _gap += diff_;
+ _slack = (int) (bigSlack - diff_);
+ _size += diff_;
+
+ FinishSlack();
+}
+
+void c4_Column::Shrink(t4_i32 off_, t4_i32 diff_)
+{
+ d4_assert(off_ <= _size);
+ d4_assert(diff_ > 0);
+
+ if (_segments.GetSize() == 0)
+ SetupSegments();
+
+ Validate();
+
+ _dirty = true;
+
+ // the simplification here is that we have in fact simply *two*
+ // gaps and we must merge them together and end up with just one
+
+ if (_slack > 0) {
+ if (_gap < off_) // if too low, move the gap up
+ MoveGapTo(off_);
+ else if (off_ + diff_ < _gap) // if too high, move down to end
+ MoveGapTo(off_ + diff_);
+
+ // the gap is now inside, or adjacent to, the deleted area
+ d4_assert(off_ <= _gap && _gap <= off_ + diff_);
+ }
+
+ _gap = off_;
+
+ // check whether the merged gap would cross a segment boundary
+ int i1 = fSegIndex(_gap);
+ int i2 = fSegIndex(_gap + _slack + diff_);
+
+ // drop complete segments, not a partially filled boundary
+ if (fSegRest(_gap))
+ ++i1;
+
+ // moved up (was after the next if in the 1.7 May 28 build)
+ _slack += diff_;
+ _size -= diff_;
+
+ int n = i2 - i1;
+ if (n > 0) {
+ for (int i = i1; i < i2; ++i)
+ ReleaseSegment(i);
+
+ _segments.RemoveAt(i1, n);
+
+ // the logic in 1.7 of May 28 was warped (the assert "fix" was wrong)
+ d4_assert(_slack >= fSegOffset(n));
+ _slack -= fSegOffset(n);
+ }
+
+ d4_assert(0 <= _slack && _slack < 2 * kSegMax);
+
+ // if the gap is at the end, get rid of a partial segment after it
+ if (_gap == _size) {
+ int i = fSegIndex(_size + _slack);
+ if (i != fSegIndex(_gap)) {
+ d4_assert(i == fSegIndex(_gap) + 1);
+ d4_assert(i == _segments.GetSize() - 1);
+
+ ReleaseSegment(i);
+ _segments.SetAt(i, 0);
+
+ _slack -= fSegRest(_size + _slack);
+
+ d4_assert(_slack < kSegMax);
+ d4_assert(fSegRest(_gap + _slack) == 0);
+ }
+ }
+
+ // the slack may still be too large to leave as is
+ if (_slack >= kSegMax) {
+ // move the bytes just after the end of the gap one segment down
+ int x = fSegRest(_gap + _slack);
+ int r = kSegMax - x;
+ if (_gap + r > _size)
+ r = (int) (_size - _gap);
+
+ CopyData(_gap, _gap + _slack, r);
+
+ int i = fSegIndex(_gap + kSegMax - 1);
+ ReleaseSegment(i);
+
+ if (r + x < kSegMax)
+ _segments.SetAt(i, 0);
+ else
+ _segments.RemoveAt(i);
+
+ _slack -= r + x;
+ _gap += r;
+ }
+
+ // if we have no data anymore, make sure not to use the file map either
+ if (_size == 0 && _slack > 0)
+ CopyNow(0);
+
+ FinishSlack();
+}
+
+void c4_Column::FinishSlack()
+{
+ Validate();
+
+ // optimization: if partial end segment easily fits in slack, move it down
+ t4_i32 gapEnd = _gap + _slack;
+ if (!fSegRest(gapEnd) && gapEnd >= _size + 500) {
+ // slack is at least 500 bytes more than the partial end segment
+ // also, the gap must end exactly on a segment boundary
+ int i = fSegIndex(gapEnd);
+ d4_assert(i == _segments.GetSize() - 1);
+
+ int n = _size - _gap;
+ CopyData(gapEnd - n, gapEnd, n);
+
+ ReleaseSegment(i);
+ _segments.SetAt(i, 0);
+
+ _slack -= n;
+ d4_assert(_slack >= 500);
+
+ Validate();
+ }
+}
+
+void c4_Column::SaveNow(c4_Strategy& strategy_, t4_i32 pos_)
+{
+ if (_segments.GetSize() == 0)
+ SetupSegments();
+
+ // write all segments
+ c4_ColIter iter (*this, 0, _size);
+ while (iter.Next(kSegMax)) {
+ int n = iter.BufLen();
+ strategy_.DataWrite(pos_, iter.BufLoad(), n);
+ if (strategy_._failure != 0)
+ break;
+ pos_ += n;
+ }
+}
+
+const t4_byte* c4_Column::FetchBytes(t4_i32 pos_, int len_, c4_Bytes& buffer_, bool forceCopy_)
+{
+ d4_assert(len_ > 0);
+ d4_assert(pos_ + len_ <= ColSize());
+ d4_assert(0 <= _slack && _slack < kSegMax);
+
+ c4_ColIter iter (*this, pos_, pos_ + len_);
+ iter.Next();
+
+ // most common case, all bytes are inside the same segment
+ if (!forceCopy_ && iter.BufLen() == len_)
+ return iter.BufLoad();
+
+ t4_byte* p = buffer_.SetBuffer(len_);
+ do {
+ d4_assert(iter.BufLen() > 0);
+ memcpy(p, iter.BufLoad(), iter.BufLen());
+ p += iter.BufLen();
+ } while (iter.Next());
+ d4_assert(p == buffer_.Contents() + len_);
+
+ return buffer_.Contents();
+}
+
+void c4_Column::StoreBytes(t4_i32 pos_, const c4_Bytes& buffer_)
+{
+ int n = buffer_.Size();
+ if (n > 0) {
+ d4_assert(pos_ + n <= ColSize());
+
+ c4_ColIter iter (*this, pos_, pos_ + n);
+
+ const t4_byte* p = buffer_.Contents();
+ while (iter.Next(n)) {
+ d4_assert(iter.BufLen() > 0);
+ memcpy(iter.BufSave(), p, iter.BufLen());
+ p += iter.BufLen();
+ }
+ d4_assert(p == buffer_.Contents() + n);
+ }
+}
+
+ /*
+ PushValue and PullValue deal with variable-sized storage of
+ one unsigned integer value of up to 32 bits. Depending on the
+ magnitude of the integer, 1..6 bytes are used to represent it.
+ Each byte holds 7 significant bits and one continuation bit.
+ This saves storage, but it is also byte order independent.
+ Negative values are stored as a zero byte plus positive value.
+ */
+
+t4_i32 c4_Column::PullValue(const t4_byte*& ptr_)
+{
+ t4_i32 mask = *ptr_ ? 0 : ~0;
+
+ t4_i32 v = 0;
+ for (;;) {
+ v = (v << 7) + *ptr_;
+ if (*ptr_++ & 0x80)
+ break;
+ }
+
+ return mask ^ (v - 0x80); // oops, last byte had bit 7 set
+}
+
+void c4_Column::PushValue(t4_byte*& ptr_, t4_i32 v_)
+{
+ if (v_ < 0) {
+ v_ = ~v_;
+ *ptr_++ = 0;
+ }
+
+ int n = 0;
+ do
+ n += 7;
+ while ((v_ >> n) && n < 32);
+
+ while (n) {
+ n -= 7;
+ t4_byte b = (t4_byte) ((v_ >> n) & 0x7F);
+ if (!n)
+ b |= 0x80; // set bit 7 on the last byte
+ *ptr_++ = b;
+ }
+}
+
+void c4_Column::InsertData(t4_i32 index_, t4_i32 count_, bool clear_)
+{
+ d4_assert(index_ <= ColSize());
+
+ if (count_ > 0) {
+ Grow(index_, count_);
+
+ // clear the contents, in separate chunks if necessary
+ if (clear_) {
+ c4_ColIter iter (*this, index_, index_ + count_);
+ while (iter.Next())
+ memset(iter.BufSave(), 0, iter.BufLen());
+ }
+ }
+}
+
+void c4_Column::RemoveData(t4_i32 index_, t4_i32 count_)
+{
+ d4_assert(index_ + count_ <= ColSize());
+
+ if (count_ > 0)
+ Shrink(index_, count_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void c4_ColOfInts::Get_0b(int)
+{
+ *(t4_i32*) _item = 0;
+}
+
+void c4_ColOfInts::Get_1b(int index_)
+{
+ t4_i32 off = index_ >> 3;
+ d4_assert(off < ColSize());
+
+ *(t4_i32*) _item = (*LoadNow(off) >> (index_ & 7)) & 0x01;
+}
+
+void c4_ColOfInts::Get_2b(int index_)
+{
+ t4_i32 off = index_ >> 2;
+ d4_assert(off < ColSize());
+
+ *(t4_i32*) _item = (*LoadNow(off) >> ((index_ & 3) << 1)) & 0x03;
+}
+
+void c4_ColOfInts::Get_4b(int index_)
+{
+ t4_i32 off = index_ >> 1;
+ d4_assert(off < ColSize());
+
+ *(t4_i32*) _item = (*LoadNow(off) >> ((index_ & 1) << 2)) & 0x0F;
+}
+
+void c4_ColOfInts::Get_8i(int index_)
+{
+ t4_i32 off = index_;
+ d4_assert(off < ColSize());
+
+ *(t4_i32*) _item = *(const signed char*) LoadNow(off);
+}
+
+void c4_ColOfInts::Get_16i(int index_)
+{
+ t4_i32 off = index_ * (t4_i32) 2;
+ d4_assert(off + 2 <= ColSize());
+
+ const t4_byte* vec = LoadNow(off);
+
+ _item[0] = vec[0];
+ _item[1] = vec[1];
+
+ *(t4_i32*) _item = *(const short*) _item;
+}
+
+void c4_ColOfInts::Get_16r(int index_)
+{
+ t4_i32 off = index_ * (t4_i32) 2;
+ d4_assert(off + 2 <= ColSize());
+
+ const t4_byte* vec = LoadNow(off);
+
+ // 2003-02-02 - gcc 3.2.1 on linux (!) fails to compile this
+ // sign-extension trick properly, use a temp buffer instead:
+ //*(t4_i32*) _item = *(const short*) _item;
+
+ t4_byte temp[2];
+ temp[1] = vec[0];
+ temp[0] = vec[1];
+ *(t4_i32*) _item = *(const short*) temp;
+}
+
+void c4_ColOfInts::Get_32i(int index_)
+{
+ t4_i32 off = index_ * (t4_i32) 4;
+ d4_assert(off + 4 <= ColSize());
+
+ const t4_byte* vec = LoadNow(off);
+
+ _item[0] = vec[0];
+ _item[1] = vec[1];
+ _item[2] = vec[2];
+ _item[3] = vec[3];
+}
+
+void c4_ColOfInts::Get_32r(int index_)
+{
+ t4_i32 off = index_ * (t4_i32) 4;
+ d4_assert(off + 4 <= ColSize());
+
+ const t4_byte* vec = LoadNow(off);
+
+ _item[3] = vec[0];
+ _item[2] = vec[1];
+ _item[1] = vec[2];
+ _item[0] = vec[3];
+}
+
+void c4_ColOfInts::Get_64i(int index_)
+{
+ t4_i32 off = index_ * (t4_i32) 8;
+ d4_assert(off + 8 <= ColSize());
+
+ const t4_byte* vec = LoadNow(off);
+
+ for (int i = 0; i < 8; ++i)
+ _item[i] = vec[i];
+}
+
+void c4_ColOfInts::Get_64r(int index_)
+{
+ t4_i32 off = index_ * (t4_i32) 8;
+ d4_assert(off + 8 <= ColSize());
+
+ const t4_byte* vec = LoadNow(off);
+
+ for (int i = 0; i < 8; ++i)
+ _item[7-i] = vec[i];
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+ static int fBitsNeeded(t4_i32 v)
+ {
+ if ((v >> 4) == 0) {
+ static int bits[] = { 0, 1, 2, 2, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4 };
+ return bits[(int) v];
+ }
+
+ if (v < 0) // first flip all bits if bit 31 is set
+ v = ~ v; // ... bit 31 is now always zero
+
+ // then check if bits 15-31 used (32b), 7-31 used (16b), else (8b)
+ return v >> 15 ? 32 : v >> 7 ? 16 : 8;
+ }
+
+bool c4_ColOfInts::Set_0b(int, const t4_byte* item_)
+{
+ t4_i32 v = *(const t4_i32*) item_;
+ return v == 0;
+}
+
+bool c4_ColOfInts::Set_1b(int index_, const t4_byte* item_)
+{
+ t4_i32 v = *(const t4_i32*) item_;
+
+ t4_i32 off = index_ >> 3;
+ d4_assert(off < ColSize());
+
+ index_ &= 7;
+
+ t4_byte* p = CopyNow(off);
+ *p = (*p & ~(1 << index_)) | (((t4_byte) v & 1) << index_);
+
+ return (v >> 1) == 0;
+}
+
+bool c4_ColOfInts::Set_2b(int index_, const t4_byte* item_)
+{
+ t4_i32 v = *(const t4_i32*) item_;
+
+ t4_i32 off = index_ >> 2;
+ d4_assert(off < ColSize());
+
+ const int n = (index_ & 3) << 1;
+
+ t4_byte* p = CopyNow(off);
+ *p = (*p & ~(0x03 << n)) | (((t4_byte) v & 0x03) << n);
+
+ return (v >> 2) == 0;
+}
+
+bool c4_ColOfInts::Set_4b(int index_, const t4_byte* item_)
+{
+ t4_i32 v = *(const t4_i32*) item_;
+
+ t4_i32 off = index_ >> 1;
+ d4_assert(off < ColSize());
+
+ const int n = (index_ & 1) << 2;
+
+ t4_byte* p = CopyNow(off);
+ *p = (*p & ~(0x0F << n)) | (((t4_byte) v & 0x0F) << n);
+
+ return (v >> 4) == 0;
+}
+
+// avoid a bug in MS EVC 3.0's code gen for ARM (i.e. WinCE)
+#ifdef _ARM_
+#pragma optimize("g",off)
+#endif
+
+bool c4_ColOfInts::Set_8i(int index_, const t4_byte* item_)
+{
+ t4_i32 v = *(const t4_i32*) item_;
+
+ t4_i32 off = index_;
+ d4_assert(off < ColSize());
+
+ *(char*) CopyNow(off) = (char) v;
+
+ return v == (signed char) v;
+}
+
+#ifdef _ARM_
+#pragma optimize("",on)
+#endif
+
+bool c4_ColOfInts::Set_16i(int index_, const t4_byte* item_)
+{
+ t4_i32 v = *(const t4_i32*) item_;
+
+ t4_i32 off = index_ * (t4_i32) 2;
+ d4_assert(off + 2 <= ColSize());
+
+ *(short*) CopyNow(off) = (short) v;
+
+ return v == (short) v;
+}
+
+bool c4_ColOfInts::Set_16r(int index_, const t4_byte* item_)
+{
+ t4_i32 v = *(const t4_i32*) item_;
+
+ t4_byte buf [2];
+ *(short*) buf = (short) v;
+
+ t4_i32 off = index_ * (t4_i32) 2;
+ d4_assert(off + 2 <= ColSize());
+
+ t4_byte* vec = CopyNow(off);
+
+ vec[1] = buf[0];
+ vec[0] = buf[1];
+
+ return v == (short) v;
+}
+
+bool c4_ColOfInts::Set_32i(int index_, const t4_byte* item_)
+{
+ t4_i32 v = *(const t4_i32*) item_;
+
+ t4_i32 off = index_ * (t4_i32) 4;
+ d4_assert(off + 4 <= ColSize());
+
+ *(t4_i32*) CopyNow(off) = (t4_i32) v;
+
+ return true;
+}
+
+bool c4_ColOfInts::Set_32r(int index_, const t4_byte* item_)
+{
+ t4_i32 off = index_ * (t4_i32) 4;
+ d4_assert(off + 4 <= ColSize());
+
+ t4_byte* vec = CopyNow(off);
+
+ vec[3] = item_[0];
+ vec[2] = item_[1];
+ vec[1] = item_[2];
+ vec[0] = item_[3];
+
+ return true;
+}
+
+bool c4_ColOfInts::Set_64i(int index_, const t4_byte* item_)
+{
+ t4_i32 off = index_ * (t4_i32) 8;
+ d4_assert(off + 8 <= ColSize());
+
+ t4_byte* vec = CopyNow(off);
+
+ for (int i = 0; i < 8; ++i)
+ vec[i] = item_[i];
+
+ return true;
+}
+
+bool c4_ColOfInts::Set_64r(int index_, const t4_byte* item_)
+{
+ t4_i32 off = index_ * (t4_i32) 8;
+ d4_assert(off + 8 <= ColSize());
+
+ t4_byte* vec = CopyNow(off);
+
+ for (int i = 0; i < 8; ++i)
+ vec[7-i] = item_[i];
+
+ return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_ColOfInts::c4_ColOfInts (c4_Persist* persist_, int width_)
+ : c4_Column (persist_),
+ _getter (&c4_ColOfInts::Get_0b), _setter (&c4_ColOfInts::Set_0b),
+ _currWidth (0), _dataWidth (width_), _numRows (0), _mustFlip (false)
+{
+}
+
+void c4_ColOfInts::ForceFlip()
+{
+ _mustFlip = true;
+}
+
+int c4_ColOfInts::RowCount() const
+{
+ d4_assert(_numRows >= 0);
+
+ return _numRows;
+}
+
+int c4_ColOfInts::CalcAccessWidth(int numRows_, t4_i32 colSize_)
+{
+ d4_assert(numRows_ > 0);
+
+ int w = (int) ((colSize_ << 3) / numRows_);
+
+ // deduce sub-byte sizes for small vectors, see c4_ColOfInts::Set
+ if (numRows_ <= 7 && 0 < colSize_ && colSize_ <= 6) {
+ static t4_byte realWidth [][6] = {
+ // sz = 1: 2: 3: 4: 5: 6:
+ { 8, 16, 1, 32, 2, 4 }, // n = 1
+ { 4, 8, 1, 16, 2, 0 }, // n = 2
+ { 2, 4, 8, 1, 0, 16 }, // n = 3
+ { 2, 4, 0, 8, 1, 0 }, // n = 4
+ { 1, 2, 4, 0, 8, 0 }, // n = 5
+ { 1, 2, 4, 0, 0, 8 }, // n = 6
+ { 1, 2, 0, 4, 0, 0 }, // n = 7
+ };
+
+ w = realWidth [numRows_-1] [(int) colSize_ - 1];
+ d4_assert(w > 0);
+ }
+
+ return (w & (w - 1)) == 0 ? w : -1;
+}
+
+void c4_ColOfInts::SetRowCount(int numRows_)
+{
+ _numRows = numRows_;
+ if (numRows_ > 0) {
+ int w = CalcAccessWidth(numRows_, ColSize());
+ d4_assert(w >= 0);
+ SetAccessWidth(w);
+ }
+}
+
+void c4_ColOfInts::FlipBytes()
+{
+ if (_currWidth > 8) {
+ int step = _currWidth >> 3;
+
+ c4_ColIter iter (*this, 0, ColSize());
+ while (iter.Next(step)) {
+ t4_byte* data = iter.BufSave();
+ d4_assert(data != 0);
+
+ for (int j = 0; j < step; ++j) {
+ t4_byte c = data[j];
+ data[j] = data[step-j-1];
+ data[step-j-1] = c;
+ }
+ }
+ }
+}
+
+void c4_ColOfInts::SetAccessWidth(int bits_)
+{
+ d4_assert((bits_ & (bits_ - 1)) == 0);
+
+ int l2bp1 = 0; // "log2 bits plus one" needed to represent value
+ while (bits_) {
+ ++l2bp1;
+ bits_ >>= 1;
+ }
+ d4_assert(0 <= l2bp1 && l2bp1 < 8);
+
+ _currWidth = (1 << l2bp1) >> 1;
+
+ if (l2bp1 > 4 && (_mustFlip || Persist() != 0 && Strategy()._bytesFlipped))
+ l2bp1 += 3; // switch to the trailing entries for byte flipping
+
+ // Metrowerks Codewarrior 11 is dumb, it requires the "&c4_ColOfInts::"
+
+ static tGetter gTab [] =
+ {
+ &c4_ColOfInts::Get_0b, // 0: 0 bits/entry
+ &c4_ColOfInts::Get_1b, // 1: 1 bits/entry
+ &c4_ColOfInts::Get_2b, // 2: 2 bits/entry
+ &c4_ColOfInts::Get_4b, // 3: 4 bits/entry
+
+ &c4_ColOfInts::Get_8i, // 4: 8 bits/entry
+ &c4_ColOfInts::Get_16i, // 5: 16 bits/entry
+ &c4_ColOfInts::Get_32i, // 6: 32 bits/entry
+ &c4_ColOfInts::Get_64i, // 7: 64 bits/entry
+
+ &c4_ColOfInts::Get_16r, // 8: 16 bits/entry, reversed
+ &c4_ColOfInts::Get_32r, // 9: 32 bits/entry, reversed
+ &c4_ColOfInts::Get_64r, // 10: 64 bits/entry, reversed
+ };
+
+ static tSetter sTab [] =
+ {
+ &c4_ColOfInts::Set_0b, // 0: 0 bits/entry
+ &c4_ColOfInts::Set_1b, // 1: 1 bits/entry
+ &c4_ColOfInts::Set_2b, // 2: 2 bits/entry
+ &c4_ColOfInts::Set_4b, // 3: 4 bits/entry
+
+ &c4_ColOfInts::Set_8i, // 4: 8 bits/entry
+ &c4_ColOfInts::Set_16i, // 5: 16 bits/entry
+ &c4_ColOfInts::Set_32i, // 6: 32 bits/entry
+ &c4_ColOfInts::Set_64i, // 7: 64 bits/entry
+
+ &c4_ColOfInts::Set_16r, // 8: 16 bits/entry, reversed
+ &c4_ColOfInts::Set_32r, // 9: 32 bits/entry, reversed
+ &c4_ColOfInts::Set_64r, // 10: 64 bits/entry, reversed
+ };
+
+ d4_assert(l2bp1 < sizeof gTab / sizeof *gTab);
+
+ _getter = gTab[l2bp1];
+ _setter = sTab[l2bp1];
+
+ d4_assert(_getter != 0 && _setter != 0);
+}
+
+int c4_ColOfInts::ItemSize(int)
+{
+ return _currWidth >= 8 ? _currWidth >> 3 : - _currWidth;
+}
+
+const void* c4_ColOfInts::Get(int index_, int& length_)
+{
+ d4_assert(sizeof _item >= _dataWidth);
+
+ (this->*_getter)(index_);
+
+ length_ = _dataWidth;
+ return _item;
+}
+
+void c4_ColOfInts::Set(int index_, const c4_Bytes& buf_)
+{
+ d4_assert(buf_.Size() == _dataWidth);
+
+ if ((this->*_setter)(index_, buf_.Contents()))
+ return;
+
+ d4_assert(buf_.Size() == sizeof (t4_i32));
+
+ int n = fBitsNeeded(*(const t4_i32*) buf_.Contents());
+ if (n > _currWidth) {
+ int k = RowCount();
+
+ t4_i32 oldEnd = ColSize();
+ t4_i32 newEnd = ((t4_i32) k * n + 7) >> 3;
+
+ if (newEnd > oldEnd) {
+ InsertData(oldEnd, newEnd - oldEnd, _currWidth == 0);
+
+ // 14-5-2002: need to get rid of gap in case it risks not being a
+ // multiple of the increased size (bug, see s46 regression test)
+ //
+ // Example scenario: gap size is odd, data gets resized to 2/4-byte
+ // ints, data at end fits without moving gap to end, then we end
+ // up with a vector that has an int split *across* the gap - this
+ // commits just fine, but access to that split int is now bad.
+ //
+ // Lesson: need stricter/simpler consistency, it's way too complex!
+ if (n > 8)
+ RemoveGap();
+ }
+
+ // data value exceeds width, expand to new size and repeat
+ if (_currWidth > 0) {
+ d4_assert(n % _currWidth == 0); // must be expanding by a multiple
+
+ // To expand, we start by inserting a new appropriate chunk
+ // at the end, and expand the entries in place (last to first).
+
+ tGetter oldGetter = _getter;
+ SetAccessWidth(n);
+
+ d4_assert(sizeof _item >= _dataWidth);
+
+ // this expansion in place works because it runs backwards
+ while (--k >= 0) {
+ (this->*oldGetter)(k);
+ (this->*_setter)(k, _item);
+ }
+ } else {
+ if (_dataWidth > (int) sizeof (t4_i32))
+ n = _dataWidth << 3; // don't trust setter result, use max instead
+
+ SetAccessWidth(n);
+ }
+
+ // now repeat the failed call to _setter
+ /* bool f = */ (this->*_setter)(index_, buf_.Contents());
+ //? d4_assert(f);
+ }
+}
+
+t4_i32 c4_ColOfInts::GetInt(int index_)
+{
+ int n;
+ const void* p = Get(index_, n);
+ d4_assert(n == sizeof (t4_i32));
+ return *(const t4_i32*) p;
+}
+
+void c4_ColOfInts::SetInt(int index_, t4_i32 value_)
+{
+ Set(index_, c4_Bytes (&value_, sizeof value_));
+}
+
+int c4_ColOfInts::DoCompare(const c4_Bytes& b1_, const c4_Bytes& b2_)
+{
+ d4_assert(b1_.Size() == sizeof (t4_i32));
+ d4_assert(b2_.Size() == sizeof (t4_i32));
+
+ t4_i32 v1 = *(const t4_i32*) b1_.Contents();
+ t4_i32 v2 = *(const t4_i32*) b2_.Contents();
+
+ return v1 == v2 ? 0 : v1 < v2 ? -1 : +1;
+}
+
+void c4_ColOfInts::Insert(int index_, const c4_Bytes& buf_, int count_)
+{
+ d4_assert(buf_.Size() == _dataWidth);
+ d4_assert(count_ > 0);
+
+ bool clear = true;
+ const t4_byte* ptr = buf_.Contents();
+
+ for (int i = 0; i < _dataWidth; ++i)
+ if (*ptr++) {
+ clear = false;
+ break;
+ }
+
+ ResizeData(index_, count_, clear);
+
+ if (!clear)
+ while (--count_ >= 0)
+ Set(index_++, buf_);
+}
+
+void c4_ColOfInts::Remove(int index_, int count_)
+{
+ d4_assert(count_ > 0);
+
+ ResizeData(index_, - count_);
+}
+
+void c4_ColOfInts::ResizeData(int index_, int count_, bool clear_)
+{
+ _numRows += count_;
+
+ if (!(_currWidth & 7)) { // not 1, 2, or 4
+ const t4_i32 w = (t4_i32) (_currWidth >> 3);
+ if (count_ > 0)
+ InsertData(index_ * w, count_ * w, clear_);
+ else
+ RemoveData(index_ * w, - count_ * w);
+ return;
+ }
+
+ d4_assert(_currWidth == 1 || _currWidth == 2 || _currWidth == 4);
+
+ /* _currwidth 1: 2: 4:
+ * shiftPos 3 2 1 shift the offset right this much
+ * maskPos 7 3 1 mask the offset with this
+ */
+
+ const int shiftPos = _currWidth == 4 ? 1 : 4 - _currWidth;
+ const int maskPos = (1 << shiftPos) - 1;
+
+ // the following code is similar to c4_Column::Resize, but at bit level
+
+ // turn insertion into deletion by inserting entire bytes
+ if (count_ > 0) {
+ unsigned off = (unsigned) index_ >> shiftPos;
+ int gapBytes = (count_ + maskPos) >> shiftPos;
+
+ InsertData(off, gapBytes, clear_);
+
+ // oops, we might have inserted too low by a few entries
+ const int bits = (index_ & maskPos) * _currWidth;
+ if (bits) {
+ const int maskLow = (1 << bits) - 1;
+
+ // move the first few bits to start of inserted range
+ t4_byte* p = CopyNow(off + gapBytes);
+ t4_byte one = *p & maskLow;
+ *p &= ~maskLow;
+
+ * CopyNow(off) = one;
+ }
+
+ index_ += count_;
+ count_ -= gapBytes << shiftPos;
+ d4_assert(count_ <= 0);
+ }
+
+ // now perform a deletion using a forward loop to copy down
+ if (count_ < 0) {
+ c4_Bytes temp;
+
+ while (index_ < _numRows) {
+ int length;
+ const void* ptr = Get(index_ - count_, length);
+ Set(index_++, c4_Bytes (ptr, length));
+ }
+ }
+ else {
+ d4_assert(count_ == 0);
+ }
+
+ FixSize(false);
+}
+
+void c4_ColOfInts::FixSize(bool fudge_)
+{
+ int n = RowCount();
+ t4_i32 needBytes = ((t4_i32) n * _currWidth + 7) >> 3;
+
+ // use a special trick to mark sizes less than 1 byte in storage
+ if (fudge_ && 1 <= n && n <= 4 && (_currWidth & 7)) {
+ const int shiftPos = _currWidth == 4 ? 1 : 4 - _currWidth;
+
+ static t4_byte fakeSizes [3][4] = { // n: 1: 2: 3: 4:
+ { 6, 1, 2, 2 }, // 4-bit entries: 4b 8b 12b 16b
+ { 5, 5, 1, 1 }, // 2-bit entries: 2b 4b 6b 8b
+ { 3, 3, 4, 5 }, // 1-bit entries: 1b 2b 3b 4b
+ };
+
+ // The idea is to use an "impossible" size (ie. 5, for n = 2)
+ // to give information about the current bit packing density.
+ d4_assert(needBytes <= 2);
+ needBytes = fakeSizes [shiftPos-1] [n-1];
+ }
+
+ t4_i32 currSize = ColSize();
+
+ if (needBytes < currSize)
+ RemoveData(needBytes, currSize - needBytes);
+ else if (needBytes > currSize)
+ InsertData(currSize, needBytes - currSize, true);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+bool c4_ColIter::Next()
+{
+ _pos += _len;
+
+ _len = _column.AvailAt(_pos);
+ _ptr = _column.LoadNow(_pos);
+
+ if (!_ptr)
+ _len = 0;
+ else if (_pos + _len >= _limit)
+ _len = _limit - _pos;
+ else { // 19990831 - optimization to avoid most copying
+ // while the end is adjacent to the next segment, extend it
+ while (_ptr + _len == _column.LoadNow(_pos + _len)) {
+ int n = _column.AvailAt(_pos + _len);
+ if (n == 0)
+ break; // may be a short column (strings)
+
+ _len += n;
+
+ if (_pos + _len >= _limit) {
+ _len = _limit - _pos;
+ break;
+ }
+ }
+ }
+
+ return _len > 0;
+}
+
+bool c4_ColIter::Next(int max_)
+{
+ _pos += _len;
+
+ _len = _column.AvailAt(_pos);
+ _ptr = _column.LoadNow(_pos);
+
+ if (!_ptr)
+ _len = 0;
+ else if (_pos + _len > _limit)
+ _len = _limit - _pos;
+
+ if (_len <= 0)
+ return false;
+
+ if (_len > max_)
+ _len = max_;
+
+ return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/akregator/src/mk4storage/metakit/src/column.h b/akregator/src/mk4storage/metakit/src/column.h
new file mode 100644
index 000000000..3f6e4f157
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/src/column.h
@@ -0,0 +1,212 @@
+// column.h --
+// $Id$
+// This is part of Metakit, see http://www.equi4.com/metakit/
+
+/** @file
+ * Definition of the column classes
+ */
+
+#ifndef __COLUMN_H__
+#define __COLUMN_H__
+
+/////////////////////////////////////////////////////////////////////////////
+// Declarations in this file
+
+ class c4_Column; // a column in a table
+ class c4_ColIter; // an iterator over column data
+ class c4_ColCache; // manages a cache for columns
+
+ class c4_Persist; // not defined here
+ class c4_Strategy; // not defined here
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_Column
+{
+ c4_PtrArray _segments;
+ t4_i32 _position;
+ t4_i32 _size;
+ c4_Persist* _persist;
+ t4_i32 _gap;
+ int _slack;
+ bool _dirty;
+
+public:
+ c4_Column (c4_Persist* persist_);
+ //: Constructs a column using the specified persistence manager.
+ ~c4_Column ();
+
+ void SetBuffer(t4_i32);
+ //: Allocate a new buffer of the specified size.
+
+ c4_Persist* Persist() const;
+ //: Returns persistence manager for this column, or zero.
+ c4_Strategy& Strategy() const;
+ //: Returns the associated strategy pointer.
+ t4_i32 Position() const;
+ //: Special access for the DUMP program.
+ t4_i32 ColSize() const;
+ //: Returns the number of bytes as stored on disk.
+ bool IsDirty() const;
+ //: Returns true if contents needs to be saved.
+
+ void SetLocation(t4_i32, t4_i32);
+ //: Sets the position and size of this column on file.
+ void PullLocation(const t4_byte*& ptr_);
+ //: Extract position and size of this column.
+
+ int AvailAt(t4_i32 offset_) const;
+ //: Returns number of bytes we can access at once.
+ const t4_byte* LoadNow(t4_i32);
+ //: Makes sure the data is loaded into memory.
+ t4_byte* CopyNow(t4_i32);
+ //: Makes sure a copy of the data is in memory.
+ void Grow(t4_i32, t4_i32);
+ //: Grows the buffer by inserting space.
+ void Shrink(t4_i32, t4_i32);
+ //: Shrinks the buffer by removing space.
+ void SaveNow(c4_Strategy&, t4_i32 pos_);
+ //: Save the buffer to file.
+
+ const t4_byte* FetchBytes(t4_i32 pos_, int len_, c4_Bytes& buffer_, bool forceCopy_);
+ //: Returns pointer to data, use buffer only if non-contiguous.
+ void StoreBytes(t4_i32 pos_, const c4_Bytes& buffer_);
+ //: Stores a copy of the buffer in the column.
+
+ bool RequiresMap() const;
+ void ReleaseAllSegments();
+
+ static t4_i32 PullValue(const t4_byte*& ptr_);
+ static void PushValue(t4_byte*& ptr_, t4_i32 v_);
+
+ void InsertData(t4_i32 index_, t4_i32 count_, bool clear_);
+ void RemoveData(t4_i32 index_, t4_i32 count_);
+ void RemoveGap();
+
+ enum { kSegBits = 12, kSegMax = 1 << kSegBits, kSegMask = kSegMax - 1 };
+
+private:
+ static int fSegIndex(t4_i32 offset_);
+ static t4_i32 fSegOffset(int index_);
+ static int fSegRest(t4_i32 offset_);
+
+ bool UsesMap(const t4_byte*) const;
+ bool IsMapped() const;
+
+ void ReleaseSegment(int);
+ void SetupSegments();
+ void Validate() const;
+ void FinishSlack();
+
+ void MoveGapUp(t4_i32 pos_);
+ void MoveGapDown(t4_i32 pos_);
+ void MoveGapTo(t4_i32 pos_);
+
+ t4_byte* CopyData(t4_i32, t4_i32, int);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_ColOfInts : public c4_Column
+{
+public:
+ c4_ColOfInts (c4_Persist* persist_, int width_ =sizeof (t4_i32));
+
+ int RowCount() const;
+ void SetRowCount(int numRows_);
+
+ void FlipBytes();
+
+ int ItemSize(int index_);
+ const void* Get(int index_, int& length_);
+ void Set(int index_, const c4_Bytes& buf_);
+
+ t4_i32 GetInt(int index_);
+ void SetInt(int index_, t4_i32 value_);
+
+ void Insert(int index_, const c4_Bytes& buf_, int count_);
+ void Remove(int index_, int count_);
+
+ static int CalcAccessWidth(int numRows_, t4_i32 colSize_);
+
+ void SetAccessWidth(int bits_);
+ void FixSize(bool fudge_);
+ void ForceFlip();
+
+ static int DoCompare(const c4_Bytes& b1_, const c4_Bytes& b2_);
+
+private:
+ typedef void (c4_ColOfInts::*tGetter) (int);
+ typedef bool (c4_ColOfInts::*tSetter) (int, const t4_byte*);
+
+ void Get_0b(int index_);
+ void Get_1b(int index_);
+ void Get_2b(int index_);
+ void Get_4b(int index_);
+ void Get_8i(int index_);
+ void Get_16i(int index_);
+ void Get_16r(int index_);
+ void Get_32i(int index_);
+ void Get_32r(int index_);
+ void Get_64i(int index_);
+ void Get_64r(int index_);
+
+ bool Set_0b(int index_, const t4_byte* item_);
+ bool Set_1b(int index_, const t4_byte* item_);
+ bool Set_2b(int index_, const t4_byte* item_);
+ bool Set_4b(int index_, const t4_byte* item_);
+ bool Set_8i(int index_, const t4_byte* item_);
+ bool Set_16i(int index_, const t4_byte* item_);
+ bool Set_16r(int index_, const t4_byte* item_);
+ bool Set_32i(int index_, const t4_byte* item_);
+ bool Set_32r(int index_, const t4_byte* item_);
+ bool Set_64i(int index_, const t4_byte* item_);
+ bool Set_64r(int index_, const t4_byte* item_);
+
+ void ResizeData(int index_, int count_, bool clear_ =false);
+
+ tGetter _getter;
+ tSetter _setter;
+
+ union {
+ t4_byte _item[8]; // holds temp result (careful with alignment!)
+ double _aligner; // needed for SPARC
+ };
+
+ int _currWidth; // number of bits used for one entry (0..64)
+ int _dataWidth; // number of bytes used for passing a value along
+ int _numRows;
+ bool _mustFlip;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_ColIter
+{
+ c4_Column& _column;
+ t4_i32 _limit;
+ t4_i32 _pos;
+ int _len;
+ const t4_byte* _ptr;
+
+public:
+ c4_ColIter (c4_Column& col_, t4_i32 offset_, t4_i32 limit_);
+// ~c4_ColIter ();
+
+ bool Next();
+ bool Next(int max_);
+
+ const t4_byte* BufLoad() const;
+ t4_byte* BufSave();
+ int BufLen() const;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+#if q4_INLINE
+#include "column.inl"
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+
+#endif
diff --git a/akregator/src/mk4storage/metakit/src/column.inl b/akregator/src/mk4storage/metakit/src/column.inl
new file mode 100644
index 000000000..58f34437e
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/src/column.inl
@@ -0,0 +1,89 @@
+// column.inl --
+// $Id$
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit/
+
+/** @file
+ * Inlined members of the column classes
+ */
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_Column
+
+d4_inline int c4_Column::fSegIndex(t4_i32 offset_)
+{
+ // limited by max array: 1 << (kSegBits + 15) with 16-bit ints
+ return (int) (offset_ >> kSegBits);
+}
+
+d4_inline t4_i32 c4_Column::fSegOffset(int index_)
+{
+ return (t4_i32) index_ << kSegBits;
+}
+
+d4_inline int c4_Column::fSegRest(t4_i32 offset_)
+{
+ return ((int) offset_ & kSegMask);
+}
+
+d4_inline c4_Persist* c4_Column::Persist() const
+{
+ return _persist;
+}
+
+d4_inline t4_i32 c4_Column::Position() const
+{
+ return _position;
+}
+
+d4_inline t4_i32 c4_Column::ColSize() const
+{
+ return _size;
+}
+
+d4_inline bool c4_Column::IsDirty() const
+{
+ return _dirty;
+}
+
+d4_inline void c4_Column::SetBuffer(t4_i32 length_)
+{
+ SetLocation(0, length_);
+ _dirty = true;
+}
+
+d4_inline const t4_byte* c4_Column::LoadNow(t4_i32 offset_)
+{
+ if (_segments.GetSize() == 0)
+ SetupSegments();
+
+ if (offset_ >= _gap)
+ offset_ += _slack;
+
+ t4_byte* ptr = (t4_byte*) _segments.GetAt(fSegIndex(offset_));
+ return ptr + fSegRest(offset_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_ColIter
+
+d4_inline c4_ColIter::c4_ColIter (c4_Column& col_, t4_i32 offset_, t4_i32 limit_)
+ : _column (col_), _limit (limit_), _pos (offset_), _len (0), _ptr (0)
+{
+}
+
+d4_inline const t4_byte* c4_ColIter::BufLoad() const
+{
+ return _ptr;
+}
+
+d4_inline t4_byte* c4_ColIter::BufSave()
+{
+ return _column.CopyNow(_pos);
+}
+
+d4_inline int c4_ColIter::BufLen() const
+{
+ return _len;
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/akregator/src/mk4storage/metakit/src/custom.cpp b/akregator/src/mk4storage/metakit/src/custom.cpp
new file mode 100644
index 000000000..a6275cea7
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/src/custom.cpp
@@ -0,0 +1,1066 @@
+// custom.cpp --
+// $Id$
+// This is part of Metakit, see http://www.equi4.com/metakit/
+
+/** @file
+ * Implementation of many custom viewer classes
+ */
+
+#include "header.h"
+
+#include "custom.h"
+#include "format.h"
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_CustomHandler : public c4_Handler
+{
+ c4_CustomSeq* _seq;
+
+public:
+ c4_CustomHandler (const c4_Property& prop_, c4_CustomSeq* seq_);
+ virtual ~c4_CustomHandler ();
+
+ virtual int ItemSize(int index_);
+ virtual const void* Get(int index_, int& length_);
+ virtual void Set(int index_, const c4_Bytes& buf_);
+
+ virtual void Insert(int index_, const c4_Bytes& buf_, int count_);
+ virtual void Remove(int index_, int count_);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_CustomHandler::c4_CustomHandler (const c4_Property& prop_,
+ c4_CustomSeq* seq_)
+ : c4_Handler (prop_), _seq (seq_)
+{
+ d4_assert(_seq != 0);
+}
+
+c4_CustomHandler::~c4_CustomHandler ()
+{
+}
+
+int c4_CustomHandler::ItemSize(int index_)
+{
+ c4_Bytes& buf = _seq->Buffer();
+
+ int colnum = _seq->PropIndex(Property().GetId());
+ d4_assert(colnum >= 0);
+
+ if (!_seq->DoGet(index_, colnum, buf))
+ return 0;
+
+ return buf.Size();
+}
+
+const void* c4_CustomHandler::Get(int index_, int& length_)
+{
+ c4_Bytes& buf = _seq->Buffer();
+
+ int colnum = _seq->PropIndex(Property().GetId());
+ d4_assert(colnum >= 0);
+
+ if (!_seq->DoGet(index_, colnum, buf))
+ ClearBytes(buf);
+
+ length_ = buf.Size();
+ return buf.Contents();
+}
+
+void c4_CustomHandler::Set(int index_, const c4_Bytes& buf_)
+{
+ int colnum = _seq->PropIndex(Property().GetId());
+ d4_assert(colnum >= 0);
+
+ _seq->DoSet(index_, colnum, buf_);
+}
+
+void c4_CustomHandler::Insert(int, const c4_Bytes&, int)
+{
+ d4_assert(0); //! not yet
+}
+
+void c4_CustomHandler::Remove(int, int)
+{
+ d4_assert(0); //! not yet
+}
+
+c4_Handler* c4_CustomSeq::CreateHandler(const c4_Property& prop_)
+{
+ return d4_new c4_CustomHandler (prop_, this);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_CustomSeq::c4_CustomSeq (c4_CustomViewer* viewer_)
+ : c4_HandlerSeq (0), _viewer (viewer_), _inited (false)
+{
+ d4_assert(_viewer != 0);
+
+ // set up handlers to match a template obtained from the viewer
+ c4_View v = viewer_->GetTemplate();
+
+ for (int i = 0; i < v.NumProperties(); ++i)
+ PropIndex(v.NthProperty(i));
+
+ _inited = true;
+}
+
+c4_CustomSeq::~c4_CustomSeq ()
+{
+ delete _viewer;
+}
+
+int c4_CustomSeq::NumRows() const
+{
+ return _inited ? _viewer->GetSize() : 0;
+}
+
+bool c4_CustomSeq::RestrictSearch(c4_Cursor cursor_, int& pos_, int& count_)
+{
+ if (count_ > 0)
+ {
+ int n;
+ int o = _viewer->Lookup(cursor_, n);
+ // a -1 result means: "don't know, please scan all"
+ if (o < 0)
+ return count_ > 0;
+
+ if (n > 0)
+ {
+ if (pos_ < o)
+ {
+ count_ -= o - pos_;
+ pos_ = o;
+ }
+
+ if (pos_ + count_ > o + n)
+ count_ = o + n - pos_;
+
+ if (count_ > 0)
+ return true;
+ }
+ }
+
+ count_ = 0;
+ return false;
+}
+
+void c4_CustomSeq::InsertAt(int p_, c4_Cursor c_, int n_)
+{
+ _viewer->InsertRows(p_, c_, n_);
+}
+
+void c4_CustomSeq::RemoveAt(int p_, int n_)
+{
+ _viewer->RemoveRows(p_, n_);
+}
+
+void c4_CustomSeq::Move(int, int)
+{
+ d4_assert(false); //! not yet
+}
+
+bool c4_CustomSeq::DoGet(int row_, int col_, c4_Bytes& buf_) const
+{
+ d4_assert(_inited);
+
+ return _viewer->GetItem(row_, col_, buf_);
+}
+
+void c4_CustomSeq::DoSet(int row_, int col_, const c4_Bytes& buf_)
+{
+ d4_assert(_inited);
+
+ d4_dbgdef(const bool f =)
+ _viewer->SetItem(row_, col_, buf_);
+ d4_assert(f);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+/** @class c4_CustomViewer
+ *
+ * Abstract base class for definition of custom views.
+ *
+ * A custom view is a view which can be accessed like any other view, using
+ * row and property operations, but which is fully managed by a customized
+ * "viewer" class. The viewer will eventually handle all requests for the
+ * view, such as defining its structure and size, as well as providing the
+ * actual data values when requested.
+ *
+ * Custom views cannot propagate changes.
+ *
+ * To implement a custom view, you must derive your viewer from this base
+ * class and define each of the virtual members. Then create a new object
+ * of this type on the heap and pass it to the c4_View constructor. Your
+ * viewer will automatically be destroyed when the last reference to its
+ * view goes away. See the DBF2MK sample code for an example of a viewer.
+ */
+
+c4_CustomViewer::~c4_CustomViewer ()
+{
+}
+
+ /// Locate a row in this view, try to use native searches
+int c4_CustomViewer::Lookup(c4_Cursor, int& count_)
+{
+ count_ = GetSize();
+ return 0; // not implemented, return entire view range
+}
+
+ /// Store one data item, supplied as a generic data value
+bool c4_CustomViewer::SetItem(int, int, const c4_Bytes&)
+{
+ return false; // default is not modifiable
+}
+
+ /// Insert one or more copies of a row (if possible)
+bool c4_CustomViewer::InsertRows(int, c4_Cursor, int)
+{
+ return false; // default is not modifiable
+}
+
+ /// Remove one or more rows (this is not always possible)
+bool c4_CustomViewer::RemoveRows(int, int)
+{
+ return false; // default is not modifiable
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_SliceViewer : public c4_CustomViewer
+{
+ c4_View _parent;
+ int _first, _limit, _step;
+
+public:
+ c4_SliceViewer (c4_Sequence& seq_, int first_, int limit_, int step_);
+ virtual ~c4_SliceViewer ();
+
+ virtual c4_View GetTemplate();
+ virtual int GetSize();
+ virtual bool GetItem(int row_, int col_, c4_Bytes& buf_);
+ bool SetItem(int row_, int col_, const c4_Bytes& buf_);
+ virtual bool InsertRows(int pos_, c4_Cursor value_, int count_=1);
+ virtual bool RemoveRows(int pos_, int count_=1);
+};
+
+c4_SliceViewer::c4_SliceViewer (c4_Sequence& seq_, int first_, int limit_, int step_)
+ : _parent (&seq_), _first (first_), _limit (limit_), _step (step_)
+{
+ d4_assert(_step != 0);
+}
+
+c4_SliceViewer::~c4_SliceViewer ()
+{
+}
+
+c4_View c4_SliceViewer::GetTemplate()
+{
+ return _parent.Clone(); // could probably return _parent just as well
+}
+
+int c4_SliceViewer::GetSize()
+{
+ int n = _limit >= 0 ? _limit : _parent.GetSize();
+ if (n < _first)
+ n = _first;
+
+ int k = _step < 0 ? -_step : _step;
+ return (n - _first + k - 1) / k;
+}
+
+bool c4_SliceViewer::GetItem(int row_, int col_, c4_Bytes& buf_)
+{
+ row_ = _first + _step * (_step > 0 ? row_ : row_ - GetSize() + 1);
+
+ return _parent.GetItem(row_, col_, buf_);
+}
+
+bool c4_SliceViewer::SetItem(int row_, int col_, const c4_Bytes& buf_)
+{
+ row_ = _first + _step * (_step > 0 ? row_ : row_ - GetSize() + 1);
+
+ _parent.SetItem(row_, col_, buf_);
+ return true;
+}
+
+bool c4_SliceViewer::InsertRows(int pos_, c4_Cursor value_, int count_)
+{
+ if (_step != 1)
+ return false;
+
+ pos_ = _first + _step * (_step > 0 ? pos_ : pos_ - GetSize() + 1);
+ if (_limit >= 0)
+ _limit += count_;
+
+ _parent.InsertAt(pos_, *value_, count_);
+ return true;
+}
+
+bool c4_SliceViewer::RemoveRows(int pos_, int count_)
+{
+ if (_step != 1)
+ return false;
+
+ pos_ = _first + _step * (_step > 0 ? pos_ : pos_ - GetSize() + 1);
+ if (_limit >= 0)
+ _limit -= count_;
+
+ _parent.RemoveAt(pos_, count_);
+ return true;
+}
+
+c4_CustomViewer* f4_CustSlice(c4_Sequence& seq_, int first_, int limit_, int step_)
+{
+ return d4_new c4_SliceViewer (seq_, first_, limit_, step_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_ProductViewer : public c4_CustomViewer
+{
+ c4_View _parent, _argView, _template;
+
+public:
+ c4_ProductViewer (c4_Sequence& seq_, const c4_View& view_);
+ virtual ~c4_ProductViewer ();
+
+ virtual c4_View GetTemplate();
+ virtual int GetSize();
+ virtual bool GetItem(int row_, int col_, c4_Bytes& buf_);
+};
+
+c4_ProductViewer::c4_ProductViewer (c4_Sequence& seq_, const c4_View& view_)
+ : _parent (&seq_), _argView (view_), _template (_parent.Clone())
+{
+ for (int i = 0; i < _argView.NumProperties(); ++i)
+ _template.AddProperty(_argView.NthProperty(i));
+}
+
+c4_ProductViewer::~c4_ProductViewer ()
+{
+}
+
+c4_View c4_ProductViewer::GetTemplate()
+{
+ return _template;
+}
+
+int c4_ProductViewer::GetSize()
+{
+ return _parent.GetSize() * _argView.GetSize();
+}
+
+bool c4_ProductViewer::GetItem(int row_, int col_, c4_Bytes& buf_)
+{
+ c4_View v = _parent;
+
+ if (col_ < v.NumProperties())
+ {
+ row_ /= _argView.GetSize();
+ }
+ else
+ {
+ v = _argView;
+ row_ %= _argView.GetSize();
+ col_ = v.FindProperty(_template.NthProperty(col_).GetId());
+
+ d4_assert(col_ >= 0);
+ }
+
+ return v.GetItem(row_, col_, buf_);
+}
+
+c4_CustomViewer* f4_CustProduct(c4_Sequence& seq_, const c4_View& view_)
+{
+ return d4_new c4_ProductViewer (seq_, view_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_RemapWithViewer : public c4_CustomViewer
+{
+ c4_View _parent, _argView;
+
+public:
+ c4_RemapWithViewer (c4_Sequence& seq_, const c4_View& view_);
+ virtual ~c4_RemapWithViewer ();
+
+ virtual c4_View GetTemplate();
+ virtual int GetSize();
+ virtual bool GetItem(int row_, int col_, c4_Bytes& buf_);
+ bool SetItem(int row_, int col_, const c4_Bytes& buf_);
+};
+
+c4_RemapWithViewer::c4_RemapWithViewer (c4_Sequence& seq_, const c4_View& view_)
+ : _parent (&seq_), _argView (view_)
+{
+}
+
+c4_RemapWithViewer::~c4_RemapWithViewer ()
+{
+}
+
+c4_View c4_RemapWithViewer::GetTemplate()
+{
+ return _parent.Clone(); // could probably return _parent just as well
+}
+
+int c4_RemapWithViewer::GetSize()
+{
+ return _argView.GetSize();
+}
+
+bool c4_RemapWithViewer::GetItem(int row_, int col_, c4_Bytes& buf_)
+{
+ const c4_Property& map = _argView.NthProperty(0);
+ d4_assert(map.Type() == 'I');
+
+ row_ = ((const c4_IntProp&) map) (_argView[row_]);
+
+ return _parent.GetItem(row_, col_, buf_);
+}
+
+bool c4_RemapWithViewer::SetItem(int row_, int col_, const c4_Bytes& buf_)
+{
+ const c4_Property& map = _argView.NthProperty(0);
+ d4_assert(map.Type() == 'I');
+
+ row_ = ((const c4_IntProp&) map) (_argView[row_]);
+
+ _parent.SetItem(row_, col_, buf_);
+ return true;
+}
+
+c4_CustomViewer* f4_CustRemapWith(c4_Sequence& seq_, const c4_View& view_)
+{
+ return d4_new c4_RemapWithViewer (seq_, view_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_PairViewer : public c4_CustomViewer
+{
+ c4_View _parent, _argView, _template;
+
+public:
+ c4_PairViewer (c4_Sequence& seq_, const c4_View& view_);
+ virtual ~c4_PairViewer ();
+
+ virtual c4_View GetTemplate();
+ virtual int GetSize();
+ virtual bool GetItem(int row_, int col_, c4_Bytes& buf_);
+ bool SetItem(int row_, int col_, const c4_Bytes& buf_);
+ virtual bool InsertRows(int pos_, c4_Cursor value_, int count_=1);
+ virtual bool RemoveRows(int pos_, int count_=1);
+};
+
+c4_PairViewer::c4_PairViewer (c4_Sequence& seq_, const c4_View& view_)
+ : _parent (&seq_), _argView (view_), _template (_parent.Clone())
+{
+ for (int i = 0; i < _argView.NumProperties(); ++i)
+ _template.AddProperty(_argView.NthProperty(i));
+}
+
+c4_PairViewer::~c4_PairViewer ()
+{
+}
+
+c4_View c4_PairViewer::GetTemplate()
+{
+ return _template;
+}
+
+int c4_PairViewer::GetSize()
+{
+ return _parent.GetSize();
+}
+
+bool c4_PairViewer::GetItem(int row_, int col_, c4_Bytes& buf_)
+{
+ c4_View v = _parent;
+
+ if (col_ >= v.NumProperties())
+ {
+ v = _argView;
+ col_ = v.FindProperty(_template.NthProperty(col_).GetId());
+ d4_assert(col_ >= 0);
+ }
+
+ return v.GetItem(row_, col_, buf_);
+}
+
+bool c4_PairViewer::SetItem(int row_, int col_, const c4_Bytes& buf_)
+{
+ c4_View v = _parent;
+
+ if (col_ >= v.NumProperties())
+ {
+ v = _argView;
+ col_ = v.FindProperty(_template.NthProperty(col_).GetId());
+ d4_assert(col_ >= 0);
+ }
+
+ v.SetItem(row_, col_, buf_);
+ return true;
+}
+
+bool c4_PairViewer::InsertRows(int pos_, c4_Cursor value_, int count_)
+{
+ _parent.InsertAt(pos_, *value_, count_);
+ _argView.InsertAt(pos_, *value_, count_);
+ return true;
+}
+
+bool c4_PairViewer::RemoveRows(int pos_, int count_)
+{
+ _parent.RemoveAt(pos_, count_);
+ _argView.RemoveAt(pos_, count_);
+ return true;
+}
+
+c4_CustomViewer* f4_CustPair(c4_Sequence& seq_, const c4_View& view_)
+{
+ return d4_new c4_PairViewer (seq_, view_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_ConcatViewer : public c4_CustomViewer
+{
+ c4_View _parent, _argView;
+
+public:
+ c4_ConcatViewer (c4_Sequence& seq_, const c4_View& view_);
+ virtual ~c4_ConcatViewer ();
+
+ virtual c4_View GetTemplate();
+ virtual int GetSize();
+ virtual bool GetItem(int row_, int col_, c4_Bytes& buf_);
+ bool SetItem(int row_, int col_, const c4_Bytes& buf_);
+};
+
+c4_ConcatViewer::c4_ConcatViewer (c4_Sequence& seq_, const c4_View& view_)
+ : _parent (&seq_), _argView (view_)
+{
+}
+
+c4_ConcatViewer::~c4_ConcatViewer ()
+{
+}
+
+c4_View c4_ConcatViewer::GetTemplate()
+{
+ return _parent.Clone(); // could probably return _parent just as well
+}
+
+int c4_ConcatViewer::GetSize()
+{
+ return _parent.GetSize() + _argView.GetSize();
+}
+
+bool c4_ConcatViewer::GetItem(int row_, int col_, c4_Bytes& buf_)
+{
+ c4_View v = _parent;
+
+ if (row_ >= _parent.GetSize())
+ {
+ v = _argView;
+ row_ -= _parent.GetSize();
+ col_ = v.FindProperty(_parent.NthProperty(col_).GetId());
+
+ if (col_ < 0)
+ return false;
+ }
+
+ return v.GetItem(row_, col_, buf_);
+}
+
+bool c4_ConcatViewer::SetItem(int row_, int col_, const c4_Bytes& buf_)
+{
+ c4_View v = _parent;
+
+ if (row_ >= _parent.GetSize())
+ {
+ v = _argView;
+ row_ -= _parent.GetSize();
+ col_ = v.FindProperty(_parent.NthProperty(col_).GetId());
+ d4_assert(col_ >= 0);
+ }
+
+ v.SetItem(row_, col_, buf_);
+ return true;
+}
+
+c4_CustomViewer* f4_CustConcat(c4_Sequence& seq_, const c4_View& view_)
+{
+ return d4_new c4_ConcatViewer (seq_, view_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_RenameViewer : public c4_CustomViewer
+{
+ c4_View _parent, _template;
+
+public:
+ c4_RenameViewer (c4_Sequence& seq_, const c4_Property& old_,
+ const c4_Property& new_);
+ virtual ~c4_RenameViewer ();
+
+ virtual c4_View GetTemplate();
+ virtual int GetSize();
+ virtual bool GetItem(int row_, int col_, c4_Bytes& buf_);
+ virtual bool SetItem(int row_, int col_, const c4_Bytes& buf_);
+ //virtual bool InsertRows(int pos_, c4_Cursor value_, int count_=1);
+ //virtual bool RemoveRows(int pos_, int count_=1);
+};
+
+c4_RenameViewer::c4_RenameViewer (c4_Sequence& seq_, const c4_Property& old_,
+ const c4_Property& new_)
+ : _parent (&seq_)
+{
+ for (int i = 0; i < _parent.NumProperties(); ++i)
+ {
+ const c4_Property& prop = _parent.NthProperty(i);
+ _template.AddProperty(prop.GetId() == old_.GetId() ? new_ : prop);
+ }
+}
+
+c4_RenameViewer::~c4_RenameViewer ()
+{
+}
+
+c4_View c4_RenameViewer::GetTemplate()
+{
+ return _template;
+}
+
+int c4_RenameViewer::GetSize()
+{
+ return _parent.GetSize();
+}
+
+bool c4_RenameViewer::GetItem(int row_, int col_, c4_Bytes& buf_)
+{
+ return _parent.GetItem(row_, col_, buf_);
+}
+
+bool c4_RenameViewer::SetItem(int row_, int col_, const c4_Bytes& buf_)
+{
+ _parent.SetItem(row_, col_, buf_);
+ return true;
+}
+
+c4_CustomViewer* f4_CustRename(c4_Sequence& seq_, const c4_Property& old_,
+ const c4_Property& new_)
+{
+ return d4_new c4_RenameViewer (seq_, old_, new_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_GroupByViewer : public c4_CustomViewer
+{
+ c4_View _parent, _keys, _sorted, _temp;
+ c4_Property _result;
+ c4_DWordArray _map;
+
+ int ScanTransitions(int lo_, int hi_,
+ t4_byte* flags_, const c4_View& match_) const;
+
+public:
+ c4_GroupByViewer (c4_Sequence& seq_, const c4_View& keys_,
+ const c4_Property& result_);
+ virtual ~c4_GroupByViewer ();
+
+ virtual c4_View GetTemplate();
+ virtual int GetSize();
+ virtual bool GetItem(int row_, int col_, c4_Bytes& buf_);
+};
+
+c4_GroupByViewer::c4_GroupByViewer (c4_Sequence& seq_, const c4_View& keys_,
+ const c4_Property& result_)
+ : _parent (&seq_), _keys (keys_), _result (result_)
+{
+ _sorted = _parent.SortOn(_keys);
+ int n = _sorted.GetSize();
+
+ c4_Bytes temp;
+ t4_byte* buf = temp.SetBufferClear(n);
+
+ int groups = 0;
+ if (n > 0)
+ {
+ ++buf[0]; // the first entry is always a transition
+ groups = 1 + ScanTransitions(1, n, buf, _sorted.Project(_keys));
+ }
+
+ // set up a map pointing to each transition
+ _map.SetSize(groups + 1);
+ int j = 0;
+
+ for (int i = 0; i < n; ++i)
+ if (buf[i])
+ _map.SetAt(j++, i);
+
+ // also append an entry to point just past the end
+ _map.SetAt(j, n);
+
+ d4_assert(_map.GetAt(0) == 0);
+ d4_assert(j == groups);
+}
+
+c4_GroupByViewer::~c4_GroupByViewer ()
+{
+}
+
+int c4_GroupByViewer::ScanTransitions(int lo_, int hi_,
+ t4_byte* flags_, const c4_View& match_) const
+{
+ d4_assert(lo_ > 0);
+
+ int m = hi_ - lo_;
+ d4_assert(m >= 0);
+
+ // done if nothing left or if entire range is identical
+ if (m == 0 || match_ [lo_-1] == match_ [hi_-1])
+ return 0;
+
+ // range has a transition, done if it is exactly of size one
+ if (m == 1)
+ {
+ ++(flags_[lo_]);
+ return 1;
+ }
+
+ // use binary splitting if the range has enough entries
+ if (m >= 5)
+ return ScanTransitions(lo_, lo_ + m / 2, flags_, match_) +
+ ScanTransitions(lo_ + m / 2, hi_, flags_, match_);
+
+ // else use a normal linear scan
+ int n = 0;
+
+ for (int i = lo_; i < hi_; ++i)
+ if (match_ [i] != match_ [i-1])
+ {
+ ++(flags_[i]);
+ ++n;
+ }
+
+ return n;
+}
+
+c4_View c4_GroupByViewer::GetTemplate()
+{
+ c4_View v = _keys.Clone();
+ v.AddProperty(_result);
+
+ return v;
+}
+
+int c4_GroupByViewer::GetSize()
+{
+ d4_assert(_map.GetSize() > 0);
+
+ return _map.GetSize() - 1;
+}
+
+bool c4_GroupByViewer::GetItem(int row_, int col_, c4_Bytes& buf_)
+{
+ if (col_ < _keys.NumProperties())
+ return _sorted.GetItem(_map.GetAt(row_), col_, buf_);
+
+ d4_assert(col_ == _keys.NumProperties());
+
+ t4_i32 count;
+ switch (_result.Type())
+ {
+ case 'I': count = _map.GetAt(row_ + 1) - _map.GetAt(row_);
+ buf_ = c4_Bytes (&count, sizeof count, true);
+ break;
+ case 'V': _temp = _sorted.Slice(_map.GetAt(row_), _map.GetAt(row_ + 1))
+ .ProjectWithout(_keys);
+ buf_ = c4_Bytes (&_temp, sizeof _temp, true);
+ break;
+ default: d4_assert(0);
+ }
+
+ return true;
+}
+
+c4_CustomViewer* f4_CustGroupBy(c4_Sequence& seq_, const c4_View& template_,
+ const c4_Property& result_)
+{
+ return d4_new c4_GroupByViewer (seq_, template_, result_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_JoinPropViewer : public c4_CustomViewer
+{
+ c4_View _parent, _template;
+ c4_ViewProp _sub;
+ int _subPos, _subWidth;
+ c4_DWordArray _base, _offset;
+
+public:
+ c4_JoinPropViewer (c4_Sequence& seq_, const c4_ViewProp& sub_, bool outer_);
+ virtual ~c4_JoinPropViewer ();
+
+ virtual c4_View GetTemplate();
+ virtual int GetSize();
+ virtual bool GetItem(int row_, int col_, c4_Bytes& buf_);
+};
+
+c4_JoinPropViewer::c4_JoinPropViewer (c4_Sequence& seq_,
+ const c4_ViewProp& sub_, bool outer_)
+ : _parent (&seq_),
+ _sub (sub_), _subPos (_parent.FindProperty(sub_.GetId())), _subWidth (0)
+{
+ d4_assert(_subPos >= 0);
+
+ for (int k = 0; k < _parent.NumProperties(); ++k)
+ {
+ if (k != _subPos)
+ _template.AddProperty(_parent.NthProperty(k));
+ else // if there are no rows, then this join does very little anyway
+ //! OOPS: if this is an unattached view, then the subviews can differ
+ if (_parent.GetSize() > 0)
+ {
+ c4_View view = sub_ (_parent[0]);
+ for (int l = 0; l < view.NumProperties(); ++l)
+ {
+ _template.AddProperty(view.NthProperty(l));
+ ++_subWidth;
+ }
+ }
+ }
+
+ _base.SetSize(0, 5);
+ _offset.SetSize(0, 5);
+
+ for (int i = 0; i < _parent.GetSize(); ++i)
+ {
+ c4_View v = _sub (_parent[i]);
+
+ int n = v.GetSize();
+ if (n == 0 && outer_)
+ {
+ _base.Add(i);
+ _offset.Add(~ (t4_i32) 0); // special null entry for outer joins
+ }
+ else
+ for (int j = 0; j < n; ++j)
+ {
+ _base.Add(i);
+ _offset.Add(j);
+ }
+ }
+}
+
+c4_JoinPropViewer::~c4_JoinPropViewer ()
+{
+}
+
+c4_View c4_JoinPropViewer::GetTemplate()
+{
+ return _template;
+}
+
+int c4_JoinPropViewer::GetSize()
+{
+ return _base.GetSize();
+}
+
+bool c4_JoinPropViewer::GetItem(int row_, int col_, c4_Bytes& buf_)
+{
+ c4_View v = _parent;
+ int r = _base.GetAt(row_);
+
+ if (col_ >= _subPos)
+ if (col_ >= _subPos + _subWidth)
+ {
+ col_ -= _subWidth - 1;
+ }
+ else
+ {
+ v = _sub (_parent[r]);
+ r = _offset.GetAt(row_);
+ if (r < 0)
+ return false; // if this is a null row in an outer join
+
+ col_ = v.FindProperty(_template.NthProperty(col_).GetId());
+ if (col_ < 0)
+ return false; // if subview doesn't have all properties
+ }
+
+ return v.GetItem(r, col_, buf_);
+}
+
+c4_CustomViewer* f4_CustJoinProp(c4_Sequence& seq_,
+ const c4_ViewProp& sub_, bool outer_)
+{
+ return d4_new c4_JoinPropViewer (seq_, sub_, outer_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_JoinViewer : public c4_CustomViewer
+{
+ c4_View _parent, _argView, _template;
+ c4_DWordArray _base, _offset;
+
+public:
+ c4_JoinViewer (c4_Sequence& seq_, const c4_View& keys_,
+ const c4_View& view_, bool outer_);
+ virtual ~c4_JoinViewer ();
+
+ virtual c4_View GetTemplate();
+ virtual int GetSize();
+ virtual bool GetItem(int row_, int col_, c4_Bytes& buf_);
+};
+
+c4_JoinViewer::c4_JoinViewer (c4_Sequence& seq_,const c4_View& keys_,
+ const c4_View& view_, bool outer_)
+ : _parent (&seq_), _argView (view_.SortOn(keys_))
+{
+ // why not in GetTemplate, since we don't need to know this...
+ _template = _parent.Clone();
+ for (int l = 0; l < _argView.NumProperties(); ++l)
+ _template.AddProperty(_argView.NthProperty(l));
+
+ c4_View sorted = _parent.SortOn(keys_).Project(keys_);
+ c4_View temp = _argView.Project(keys_);
+
+ _base.SetSize(0, 5);
+ _offset.SetSize(0, 5);
+
+ int j = 0, n = 0;
+
+ for (int i = 0; i < sorted.GetSize(); ++i)
+ {
+ int orig = _parent.GetIndexOf(sorted[i]);
+ d4_assert(orig >= 0);
+
+ if (i > 0 && sorted[i] == sorted[i-1])
+ {
+ // if last key was same, repeat the same join
+ int last = _offset.GetSize() - n;
+ for (int k = 0; k < n; ++k)
+ {
+ _base.Add(orig);
+ _offset.Add(_offset.GetAt(last + k));
+ }
+ }
+ else // no, this is a new combination
+ {
+ bool match = false;
+
+ // advance until the temp view entry is >= this sorted entry
+ while (j < temp.GetSize())
+ if (sorted[i] <= temp[j])
+ {
+ match = sorted[i] == temp[j];
+ break;
+ }
+ else
+ ++j;
+
+ n = 0;
+
+ if (match)
+ {
+ do {
+ _base.Add(orig);
+ _offset.Add(j);
+ ++n;
+ } while (++j < temp.GetSize() && temp[j] == temp[j-1]);
+ }
+ else if (outer_)
+ {
+ // no match, add an entry anyway if this is an outer join
+ _base.Add(orig);
+ _offset.Add(~ (t4_i32) 0); // special null entry
+ ++n;
+ }
+ }
+ }
+}
+
+c4_JoinViewer::~c4_JoinViewer ()
+{
+}
+
+c4_View c4_JoinViewer::GetTemplate()
+{
+ return _template;
+}
+
+int c4_JoinViewer::GetSize()
+{
+ return _base.GetSize();
+}
+
+bool c4_JoinViewer::GetItem(int row_, int col_, c4_Bytes& buf_)
+{
+ c4_View v = _parent;
+ int r = _base.GetAt(row_);
+
+ if (col_ >= v.NumProperties())
+ {
+ v = _argView;
+ r = _offset.GetAt(row_);
+ if (r < 0)
+ return false; // if this is a null row in an outer join
+
+ col_ = v.FindProperty(_template.NthProperty(col_).GetId());
+ if (col_ < 0)
+ return false; // if second view doesn't have all properties
+ }
+
+ return v.GetItem(r, col_, buf_);
+}
+
+#if 0
+bool c4_JoinViewer::GetItem(int row_, int col_, c4_Bytes& buf_)
+{
+ c4_View v = _parent;
+
+ int o = 0;
+ int r = _offset.GetAt(row_);
+
+ if (r < 0)
+ {
+ o = ~r;
+ if (o == 0)
+ return false; // if this is a null row in an outer join
+ r -= o;
+ }
+
+ if (col_ >= v.NumProperties())
+ {
+ v = _argView;
+ r = _o;
+
+ col_ = v.FindProperty(_template.NthProperty(col_));
+ if (col_ < 0)
+ return false; // if second view doesn't have all properties
+ }
+
+ return v.GetItem(r, col_, buf_);
+}
+#endif
+
+c4_CustomViewer* f4_CustJoin(c4_Sequence& seq_, const c4_View& keys_,
+ const c4_View& view_, bool outer_)
+{
+ return d4_new c4_JoinViewer (seq_, keys_, view_, outer_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/akregator/src/mk4storage/metakit/src/custom.h b/akregator/src/mk4storage/metakit/src/custom.h
new file mode 100644
index 000000000..80555d3b6
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/src/custom.h
@@ -0,0 +1,63 @@
+// custom.h --
+// $Id$
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit/
+
+/** @file
+ * Encapsulation of many custom viewer classes
+ */
+
+#ifndef __CUSTOM_H__
+#define __CUSTOM_H__
+
+#ifndef __FIELD_H__
+#include "field.h"
+#endif
+#ifndef __STORE_H__
+#include "handler.h"
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_CustomSeq : public c4_HandlerSeq
+{
+ c4_CustomViewer* _viewer;
+ bool _inited;
+
+public:
+ c4_CustomSeq (c4_CustomViewer* viewer_);
+ virtual ~c4_CustomSeq ();
+
+ virtual int NumRows() const;
+
+ virtual bool RestrictSearch(c4_Cursor, int&, int&);
+
+ virtual void InsertAt(int, c4_Cursor, int =1);
+ virtual void RemoveAt(int, int =1);
+ virtual void Move(int from_, int);
+
+ bool DoGet(int row_, int col_, c4_Bytes& buf_) const;
+ void DoSet(int row_, int col_, const c4_Bytes& buf_);
+
+private: // this *is* used, as override
+ virtual c4_Handler* CreateHandler(const c4_Property&);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+ extern c4_CustomViewer* f4_CustSlice(c4_Sequence&, int, int , int);
+ extern c4_CustomViewer* f4_CustProduct(c4_Sequence&, const c4_View&);
+ extern c4_CustomViewer* f4_CustRemapWith(c4_Sequence&, const c4_View&);
+ extern c4_CustomViewer* f4_CustPair(c4_Sequence&, const c4_View&);
+ extern c4_CustomViewer* f4_CustConcat(c4_Sequence&, const c4_View&);
+ extern c4_CustomViewer* f4_CustRename(c4_Sequence&,
+ const c4_Property&, const c4_Property&);
+ extern c4_CustomViewer* f4_CustGroupBy(c4_Sequence&,
+ const c4_View&, const c4_Property&);
+ extern c4_CustomViewer* f4_CustJoinProp(c4_Sequence&,
+ const c4_ViewProp&, bool);
+ extern c4_CustomViewer* f4_CustJoin(c4_Sequence&,
+ const c4_View&, const c4_View&, bool);
+
+/////////////////////////////////////////////////////////////////////////////
+
+#endif
diff --git a/akregator/src/mk4storage/metakit/src/derived.cpp b/akregator/src/mk4storage/metakit/src/derived.cpp
new file mode 100644
index 000000000..3baf5e3e7
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/src/derived.cpp
@@ -0,0 +1,1003 @@
+// derived.cpp --
+// $Id$
+// This is part of Metakit, see http://www.equi4.com/metakit/
+
+/** @file
+ * Derived views are virtual views which track changes
+ */
+
+#include "header.h"
+#include "handler.h"
+#include "store.h"
+#include "derived.h"
+
+#include <stdlib.h> // qsort
+
+/////////////////////////////////////////////////////////////////////////////
+// Implemented in this file
+
+// class c4_Sequence;
+ class c4_DerivedSeq;
+ class c4_FilterSeq;
+ class c4_SortSeq;
+ class c4_ProjectSeq;
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_FilterSeq : public c4_DerivedSeq
+{
+protected:
+ c4_DWordArray _rowMap;
+ c4_DWordArray _revMap;
+ c4_Row _lowRow;
+ c4_Row _highRow;
+ c4_Bytes _rowIds;
+
+protected:
+ c4_FilterSeq (c4_Sequence& seq_);
+ virtual ~c4_FilterSeq ();
+
+ void FixupReverseMap();
+ int PosInMap(int index_) const;
+ bool Match(int index_, c4_Sequence& seq_,
+ const int* =0, const int* =0) const;
+ bool MatchOne(int prop_, const c4_Bytes& data_) const;
+
+public:
+ c4_FilterSeq (c4_Sequence& seq_, c4_Cursor low_, c4_Cursor high_);
+
+ virtual int RemapIndex(int, const c4_Sequence*) const;
+
+ virtual int NumRows() const;
+
+ virtual int Compare(int, c4_Cursor) const;
+ virtual bool Get(int, int, c4_Bytes&);
+
+ virtual void InsertAt(int, c4_Cursor, int =1);
+ virtual void RemoveAt(int, int =1);
+ virtual void Set(int, const c4_Property&, const c4_Bytes&);
+ virtual void SetSize(int);
+
+ virtual c4_Notifier* PreChange(c4_Notifier& nf_);
+ virtual void PostChange(c4_Notifier& nf_);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_FilterSeq::c4_FilterSeq (c4_Sequence& seq_)
+ : c4_DerivedSeq (seq_)
+{
+ _rowMap.SetSize(_seq.NumRows());
+ _revMap.SetSize(_seq.NumRows());
+ d4_assert(NumRows() == _seq.NumRows());
+
+ for (int i = 0; i < NumRows(); ++i)
+ {
+ _rowMap.SetAt(i, i);
+ _revMap.SetAt(i, i);
+ }
+}
+
+c4_FilterSeq::c4_FilterSeq (c4_Sequence& seq_, c4_Cursor low_,
+ c4_Cursor high_)
+ : c4_DerivedSeq (seq_), _lowRow (*low_), _highRow (*high_)
+{
+ d4_assert((&_lowRow)._index == 0);
+ d4_assert((&_highRow)._index == 0);
+
+ // use a sneaky way to obtain the sequence pointers and indices
+ c4_Sequence* lowSeq = (& _lowRow)._seq;
+ c4_Sequence* highSeq = (& _highRow)._seq;
+ d4_assert(lowSeq && highSeq);
+
+ // prepare column numbers to avoid looking them up on every row
+ // lowCols is a vector of column numbers to use for the low limits
+ // highCols is a vector of column numbers to use for the high limits
+ int nl = lowSeq->NumHandlers(), nh = highSeq->NumHandlers();
+ c4_Bytes lowVec, highVec;
+ int* lowCols = (int*) lowVec.SetBufferClear(nl * sizeof (int));
+ int* highCols = (int*) highVec.SetBufferClear(nh * sizeof (int));
+
+ for (int il = 0; il < nl; ++il)
+ lowCols[il] = seq_.PropIndex(lowSeq->NthPropId(il));
+ for (int ih = 0; ih < nh; ++ih)
+ highCols[ih] = seq_.PropIndex(highSeq->NthPropId(ih));
+
+ // set _rowIds flag buffer for fast matching
+ {
+ int max = -1;
+
+ {
+ for (int i1 = 0; i1 < nl; ++i1)
+ {
+ int n = lowSeq->NthPropId(i1);
+ if (max < n)
+ max = n;
+ }
+ for (int i2 = 0; i2 < nh; ++i2)
+ {
+ int n = highSeq->NthPropId(i2);
+ if (max < n)
+ max = n;
+ }
+ }
+
+ t4_byte* p = _rowIds.SetBufferClear(max + 1);
+
+ {
+ for (int i1 = 0; i1 < nl; ++i1)
+ p[lowSeq->NthPropId(i1)] |= 1;
+ for (int i2 = 0; i2 < nh; ++i2)
+ p[highSeq->NthPropId(i2)] |= 2;
+ }
+ }
+
+ // now go through all rows and select the ones that are in range
+
+ _rowMap.SetSize(_seq.NumRows()); // avoid growing, use safe upper bound
+
+ int n = 0;
+
+ for (int i = 0; i < _seq.NumRows(); ++i)
+ if (Match(i, _seq, lowCols, highCols))
+ _rowMap.SetAt(n++, i);
+
+ _rowMap.SetSize(n);
+
+ FixupReverseMap();
+}
+
+c4_FilterSeq::~c4_FilterSeq ()
+{
+}
+
+void c4_FilterSeq::FixupReverseMap()
+{
+ int n = _seq.NumRows();
+
+ _revMap.SetSize(0);
+
+ if (n > 0)
+ {
+ _revMap.InsertAt(0, ~ (t4_i32) 0, n); //!
+
+ for (int i = 0; i < _rowMap.GetSize(); ++i)
+ _revMap.SetAt((int) _rowMap.GetAt(i), i);
+ }
+}
+
+bool c4_FilterSeq::MatchOne(int prop_, const c4_Bytes& data_) const
+{
+ d4_assert(prop_ < _rowIds.Size());
+
+ t4_byte flag = _rowIds.Contents()[prop_];
+ d4_assert(flag);
+
+ if (flag & 1)
+ {
+ c4_Sequence* lowSeq = (& _lowRow)._seq;
+
+ c4_Handler& h = lowSeq->NthHandler(lowSeq->PropIndex(prop_));
+ if (h.Compare(0, data_) > 0)
+ return false;
+ }
+
+ if (flag & 2)
+ {
+ c4_Sequence* highSeq = (& _highRow)._seq;
+
+ c4_Handler& h = highSeq->NthHandler(highSeq->PropIndex(prop_));
+ if (h.Compare(0, data_) < 0)
+ return false;
+ }
+
+ return true;
+}
+
+bool c4_FilterSeq::Match(int index_, c4_Sequence& seq_,
+ const int* lowCols_, const int* highCols_) const
+{
+ // use a sneaky way to obtain the sequence pointers and indices
+ c4_Sequence* lowSeq = (& _lowRow)._seq;
+ c4_Sequence* highSeq = (& _highRow)._seq;
+ d4_assert(lowSeq && highSeq);
+
+ int nl = lowSeq->NumHandlers(), nh = highSeq->NumHandlers();
+
+ c4_Bytes data;
+
+ // check each of the lower limits
+ for (int cl = 0; cl < nl; ++cl)
+ {
+ c4_Handler& hl = lowSeq->NthHandler(cl);
+
+ int n = lowCols_ ? lowCols_[cl]
+ : seq_.PropIndex(lowSeq->NthPropId(cl));
+ if (n >= 0)
+ {
+ c4_Handler& h = seq_.NthHandler(n);
+ const c4_Sequence* hc = seq_.HandlerContext(n);
+ int i = seq_.RemapIndex(index_, hc);
+
+ h.GetBytes(i, data);
+ }
+ else
+ hl.ClearBytes(data);
+
+ if (hl.Compare(0, data) > 0)
+ return false;
+ }
+
+ // check each of the upper limits
+ for (int ch = 0; ch < nh; ++ch)
+ {
+ c4_Handler& hh = highSeq->NthHandler(ch);
+
+ int n = highCols_ ? highCols_[ch]
+ : seq_.PropIndex(highSeq->NthPropId(ch));
+ if (n >= 0)
+ {
+ c4_Handler& h = seq_.NthHandler(n);
+ const c4_Sequence* hc = seq_.HandlerContext(n);
+ int i = seq_.RemapIndex(index_, hc);
+
+ h.GetBytes(i, data);
+ }
+ else
+ hh.ClearBytes(data);
+
+ if (hh.Compare(0, data) < 0)
+ return false;
+ }
+
+ return true;
+}
+
+int c4_FilterSeq::RemapIndex(int index_, const c4_Sequence* seq_) const
+{
+ return seq_ == this ? index_
+ : _seq.RemapIndex((int) _rowMap.GetAt(index_), seq_);
+}
+
+int c4_FilterSeq::NumRows() const
+{
+ return _rowMap.GetSize();
+}
+
+int c4_FilterSeq::Compare(int index_, c4_Cursor cursor_) const
+{
+ return _seq.Compare((int) _rowMap.GetAt(index_), cursor_);
+}
+
+bool c4_FilterSeq::Get(int index_, int propId_, c4_Bytes& bytes_)
+{
+ return _seq.Get((int) _rowMap.GetAt(index_), propId_, bytes_);
+}
+
+void c4_FilterSeq::InsertAt(int, c4_Cursor, int)
+{
+ d4_assert(0);
+}
+
+void c4_FilterSeq::RemoveAt(int, int)
+{
+ d4_assert(0);
+}
+
+void c4_FilterSeq::Set(int, const c4_Property&, const c4_Bytes&)
+{
+ d4_assert(0);
+}
+
+void c4_FilterSeq::SetSize(int)
+{
+ d4_assert(0);
+}
+
+int c4_FilterSeq::PosInMap(int index_) const
+{
+ int i = 0;
+
+ while (i < NumRows())
+ if ((int) _rowMap.GetAt(i) >= index_)
+ break;
+ else
+ ++i;
+
+ return i;
+}
+
+c4_Notifier* c4_FilterSeq::PreChange(c4_Notifier& nf_)
+{
+ if (!GetDependencies())
+ return 0;
+
+ c4_Notifier* chg = d4_new c4_Notifier (this);
+
+ bool pass = false;
+
+ switch (nf_._type)
+ {
+ case c4_Notifier::kSet:
+ pass = nf_._propId >= _rowIds.Size() ||
+ _rowIds.Contents()[nf_._propId] == 0;
+ // fall through...
+
+ case c4_Notifier::kSetAt:
+ {
+ int r = (int) _revMap.GetAt(nf_._index);
+
+ bool includeRow = r >= 0;
+ if (!pass)
+ if (nf_._type == c4_Notifier::kSetAt)
+ {
+ d4_assert(nf_._cursor != 0);
+ includeRow = Match(nf_._cursor->_index,
+ *nf_._cursor->_seq);
+ }
+ else // set just one property, and it's not in a row yet
+ includeRow = MatchOne(nf_._propId, *nf_._bytes);
+
+ if (r >= 0 && !includeRow)
+ chg->StartRemoveAt(r, 1);
+ else if (r < 0 && includeRow)
+ chg->StartInsertAt(PosInMap(nf_._index), *nf_._cursor, 1);
+ else if (includeRow)
+ {
+ d4_assert(r >= 0);
+
+ if (nf_._type == c4_Notifier::kSetAt)
+ chg->StartSetAt(r, *nf_._cursor);
+ else
+ chg->StartSet(r, nf_._propId, *nf_._bytes);
+ }
+ }
+ break;
+
+ case c4_Notifier::kInsertAt:
+ {
+ int i = PosInMap(nf_._index);
+
+ d4_assert(nf_._cursor != 0);
+ if (Match(nf_._cursor->_index, *nf_._cursor->_seq))
+ chg->StartInsertAt(i, *nf_._cursor, nf_._count);
+ }
+ break;
+
+ case c4_Notifier::kRemoveAt:
+ {
+ int i = PosInMap(nf_._index);
+ int j = PosInMap(nf_._index + nf_._count);
+ d4_assert(j >= i);
+
+ if (j > i)
+ chg->StartRemoveAt(i, j - i);
+ }
+ break;
+
+ case c4_Notifier::kMove:
+ {
+ int i = PosInMap(nf_._index);
+ bool inMap = i < NumRows() && (int) _rowMap.GetAt(i) == nf_._index;
+
+ if (inMap && nf_._index != nf_._count)
+ chg->StartMove(i, PosInMap(nf_._count));
+ }
+ break;
+ }
+
+ return chg;
+}
+
+void c4_FilterSeq::PostChange(c4_Notifier& nf_)
+{
+ bool pass = false;
+
+ switch (nf_._type)
+ {
+ case c4_Notifier::kSet:
+ pass = nf_._propId >= _rowIds.Size() ||
+ _rowIds.Contents()[nf_._propId] == 0;
+ // fall through...
+
+ case c4_Notifier::kSetAt:
+ {
+ int r = (int) _revMap.GetAt(nf_._index);
+
+ bool includeRow = r >= 0;
+ if (!pass)
+ if (nf_._type == c4_Notifier::kSetAt)
+ {
+ d4_assert(nf_._cursor != 0);
+ includeRow = Match(nf_._cursor->_index,
+ *nf_._cursor->_seq);
+ }
+ else // set just one property, and it's not in a row yet
+ includeRow = MatchOne(nf_._propId, *nf_._bytes);
+
+ if (r >= 0 && !includeRow)
+ _rowMap.RemoveAt(r);
+ else if (r < 0 && includeRow)
+ _rowMap.InsertAt(PosInMap(nf_._index), nf_._index);
+ else
+ break;
+
+ FixupReverseMap();
+ }
+ break;
+
+ case c4_Notifier::kInsertAt:
+ {
+ int i = PosInMap(nf_._index);
+
+ if (Match(nf_._index, _seq))
+ {
+ _rowMap.InsertAt(i, 0, nf_._count);
+
+ for (int j = 0; j < nf_._count; ++j)
+ _rowMap.SetAt(i++, nf_._index + j);
+ }
+
+ while (i < NumRows())
+ _rowMap.ElementAt(i++) += nf_._count;
+
+ FixupReverseMap();
+ }
+ break;
+
+ case c4_Notifier::kRemoveAt:
+ {
+ int i = PosInMap(nf_._index);
+ int j = PosInMap(nf_._index + nf_._count);
+ d4_assert(j >= i);
+
+ if (j > i)
+ _rowMap.RemoveAt(i, j - i);
+
+ while (i < NumRows())
+ _rowMap.ElementAt(i++) -= nf_._count;
+
+ FixupReverseMap();
+ }
+ break;
+
+ case c4_Notifier::kMove:
+ {
+ int i = PosInMap(nf_._index);
+ bool inMap = i < NumRows() && (int) _rowMap.GetAt(i) == nf_._index;
+
+ if (inMap && nf_._index != nf_._count)
+ {
+ int j = PosInMap(nf_._count);
+
+ _rowMap.RemoveAt(i);
+
+ if (j > i)
+ --j;
+
+ _rowMap.InsertAt(j, nf_._count);
+
+ FixupReverseMap();
+ }
+ }
+ break;
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_SortSeq : public c4_FilterSeq
+{
+public:
+ typedef t4_i32 T;
+
+ c4_SortSeq (c4_Sequence& seq_, c4_Sequence* down_);
+ virtual ~c4_SortSeq ();
+
+ virtual c4_Notifier* PreChange(c4_Notifier& nf_);
+ virtual void PostChange(c4_Notifier& nf_);
+
+private:
+ struct c4_SortInfo
+ {
+ c4_Handler* _handler;
+ const c4_Sequence* _context;
+ c4_Bytes _buffer;
+
+ int CompareOne(c4_Sequence& seq_, T a, T b)
+ {
+ _handler->GetBytes(seq_.RemapIndex((int) b, _context), _buffer, true);
+ return _handler->Compare(seq_.RemapIndex((int) a, _context), _buffer);
+ }
+ };
+
+ bool LessThan(T a, T b);
+ bool TestSwap( T& first , T& second );
+ void MergeSortThis( T* ar, int size , T scratch[] );
+ void MergeSort( T ar[] , int size );
+
+ virtual int Compare(int, c4_Cursor) const;
+ int PosInMap(c4_Cursor cursor_) const;
+
+ c4_SortInfo* _info;
+ c4_Bytes _down;
+ int _width;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+bool c4_SortSeq::LessThan(T a, T b)
+{
+ if (a == b)
+ return false;
+
+ // go through each of the columns and compare values, but since
+ // handler access is used, we must be careful to remap indices
+
+ c4_SortInfo* info;
+
+ for (info = _info; info->_handler; ++info)
+ {
+ int f = info->CompareOne(_seq, a, b);
+ if (f)
+ {
+ int n = info - _info;
+ if (_width < n)
+ _width = n;
+
+ return (_down.Contents()[n] ? -f : f) < 0;
+ }
+ }
+
+ _width = info - _info;
+ return a < b;
+}
+
+inline bool c4_SortSeq::TestSwap( T& first , T& second )
+{
+ if ( LessThan( second , first ) )
+ {
+ T temp = first; first = second; second = temp;
+ return true;
+ }
+
+ return false;
+}
+
+void c4_SortSeq::MergeSortThis( T* ar, int size , T scratch[] )
+{
+ switch( size )
+ {
+ //Handle the special cases for speed:
+ case 2:
+ TestSwap( ar[ 0 ] , ar[ 1 ] );
+ break;
+
+ case 3:
+ TestSwap( ar[ 0 ] , ar[ 1 ] );
+ if ( TestSwap( ar[ 1 ] , ar[ 2 ] ) )
+ TestSwap( ar[ 0 ] , ar[ 1 ] );
+ break;
+
+ case 4:
+ //Gotta optimize this....
+ TestSwap( ar[ 0 ] , ar[ 1 ] );
+ TestSwap( ar[ 2 ] , ar[ 3 ] );
+ TestSwap( ar[ 0 ] , ar[ 2 ] );
+ TestSwap( ar[ 1 ] , ar[ 3 ] );
+ TestSwap( ar[ 1 ] , ar[ 2 ] );
+ break;
+
+ //Gotta do special case for list of five.
+
+ default:
+ //Subdivide the list, recurse, and merge
+ {
+ int s1 = size / 2;
+ int s2 = size - s1;
+ T* from1_ = scratch;
+ T* from2_ = scratch + s1;
+ MergeSortThis( from1_ , s1 , ar );
+ MergeSortThis( from2_ , s2 , ar + s1 );
+
+ T* to1_ = from1_ + s1;
+ T* to2_ = from2_ + s2;
+
+ for (;;)
+ {
+ if ( LessThan( *from1_, *from2_) )
+ {
+ *ar++ = *from1_++;
+
+ if (from1_ >= to1_)
+ {
+ while( from2_ < to2_ )
+ *ar++ = *from2_++;
+ break;
+ }
+ }
+ else
+ {
+ *ar++ = *from2_++;
+
+ if (from2_ >= to2_)
+ {
+ while( from1_ < to1_ )
+ *ar++ = *from1_++;
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+
+void c4_SortSeq::MergeSort( T ar[] , int size )
+{
+ if ( size > 1 )
+ {
+ T* scratch = d4_new T [size];
+ memcpy(scratch , ar , size * sizeof (T));
+ MergeSortThis(ar , size , scratch);
+ delete [] scratch;
+ }
+}
+
+c4_SortSeq::c4_SortSeq (c4_Sequence& seq_, c4_Sequence* down_)
+ : c4_FilterSeq (seq_), _info (0), _width (-1)
+{
+ d4_assert(NumRows() == seq_.NumRows());
+
+ if (NumRows() > 0)
+ {
+ // down is a vector of flags, true to sort in reverse order
+ char* down = (char*) _down.SetBufferClear(NumHandlers());
+
+ // set the down flag for all properties to be sorted in reverse
+ if (down_)
+ for (int i = 0; i < NumHandlers(); ++i)
+ if (down_->PropIndex(NthPropId(i)) >= 0)
+ down[i] = 1;
+
+ _width = -1;
+ int n = NumHandlers() + 1;
+ _info = d4_new c4_SortInfo [n];
+
+ int j;
+
+ for (j = 0; j < NumHandlers(); ++j)
+ {
+ _info[j]._handler = & _seq.NthHandler(j);
+ _info[j]._context = _seq.HandlerContext(j);
+ }
+
+ _info[j]._handler = 0;
+
+ // everything is ready, go sort the row index vector
+ MergeSort((T*) &_rowMap.ElementAt(0), NumRows());
+
+ delete [] _info;
+ _info = 0;
+
+ FixupReverseMap();
+ }
+}
+
+c4_SortSeq::~c4_SortSeq ()
+{
+ d4_assert(!_info);
+}
+
+int c4_SortSeq::Compare(int index_, c4_Cursor cursor_) const
+{
+ d4_assert(cursor_._seq != 0);
+
+ const char* down = (const char*) _down.Contents();
+ d4_assert(_down.Size() <= NumHandlers());
+
+ c4_Bytes data;
+
+ for (int colNum = 0; colNum < NumHandlers(); ++colNum)
+ {
+ c4_Handler& h = NthHandler(colNum);
+ const c4_Sequence* hc = HandlerContext(colNum);
+
+ if (!cursor_._seq->Get(cursor_._index, h.PropId(), data))
+ h.ClearBytes(data);
+
+ int f = h.Compare(RemapIndex(index_, hc), data);
+ if (f != 0)
+ return colNum < _down.Size() && down[colNum] ? -f : +f;
+ }
+
+ return 0;
+}
+
+int c4_SortSeq::PosInMap(c4_Cursor cursor_) const
+{
+ int i = 0;
+
+ while (i < NumRows())
+ if (Compare(i, cursor_) >= 0)
+ break;
+ else
+ ++i;
+
+ d4_assert(i == NumRows() || Compare(i, cursor_) >= 0);
+ return i;
+}
+
+c4_Notifier* c4_SortSeq::PreChange(c4_Notifier& /*nf_*/)
+{
+ if (!GetDependencies())
+ return 0;
+
+#if 0
+ c4_Notifier* chg = d4_new c4_Notifier (this);
+
+ switch (nf_._type)
+ {
+ case c4_Notifier::kSetAt:
+ case c4_Notifier::kSet:
+ {
+ d4_assert(0); // also needs nested propagation
+
+ /*
+ change can require a move *and* a change of contents
+ */
+ }
+ break;
+
+ case c4_Notifier::kInsertAt:
+ {
+ d4_assert(0); // this case isn't really difficult
+ }
+ break;
+
+ case c4_Notifier::kRemoveAt:
+ {
+ d4_assert(0); // nested propagation is too difficult for now
+ // i.e. can only use sort as last derived view
+ /*
+ possible solution:
+
+ if 1 row, simple
+ else if contig in map, also simple
+ else propagate reorder first, then delete contig
+
+ it can be done here, as multiple notifications,
+ by simulating n-1 SetAt's of first row in others
+ needs some map juggling, allow temp dup entries?
+
+ or perhaps more consistent with n separate removes
+ */
+ }
+ break;
+
+ case c4_Notifier::kMove:
+ {
+ // incorrect: may need to move if recnum matters (recs same)
+ }
+ break;
+ }
+
+ return chg;
+#endif
+
+// d4_assert(0); // fail, cannot handle a view dependent on this one yet
+ return 0;
+}
+
+void c4_SortSeq::PostChange(c4_Notifier& nf_)
+{
+ switch (nf_._type)
+ {
+ case c4_Notifier::kSet:
+ if (_seq.PropIndex(nf_._propId) > _width)
+ break; // cannot affect sort order, valuable optimization
+
+ case c4_Notifier::kSetAt:
+ {
+ int oi = (int) _revMap.GetAt(nf_._index);
+ d4_assert(oi >= 0);
+
+ c4_Cursor cursor (_seq, nf_._index);
+
+ // move the entry if the sort order has been disrupted
+ if ((oi > 0 && Compare(oi - 1, cursor) > 0) ||
+ (oi+1 < NumRows() && Compare(oi+1, cursor) < 0))
+ {
+ _rowMap.RemoveAt(oi);
+ _rowMap.InsertAt(PosInMap(cursor), nf_._index);
+
+ FixupReverseMap();
+ }
+
+ _width = NumHandlers(); // sorry, no more optimization
+ }
+ break;
+
+ case c4_Notifier::kInsertAt:
+ {
+ // if cursor was not set, it started out as a single Set
+ c4_Cursor cursor (_seq, nf_._index);
+ if (nf_._cursor)
+ cursor = *nf_._cursor;
+
+ for (int n = 0; n < NumRows(); ++n)
+ if ((int) _rowMap.GetAt(n) >= nf_._index)
+ _rowMap.ElementAt(n) += nf_._count;
+
+ int i = PosInMap(cursor);
+ _rowMap.InsertAt(i, 0, nf_._count);
+
+ for (int j = 0; j < nf_._count; ++j)
+ _rowMap.SetAt(i++, nf_._index + j);
+
+ FixupReverseMap();
+
+ _width = NumHandlers(); // sorry, no more optimization
+ }
+ break;
+
+ case c4_Notifier::kRemoveAt:
+ {
+ int lo = nf_._index;
+ int hi = nf_._index + nf_._count;
+
+ int j = 0;
+ for (int i = 0; i < NumRows(); ++i)
+ {
+ int n = (int) _rowMap.GetAt(i);
+
+ if (n >= hi)
+ _rowMap.ElementAt(i) -= nf_._count;
+
+ if (!(lo <= n && n < hi))
+ _rowMap.SetAt(j++, _rowMap.GetAt(i));
+ }
+
+ d4_assert(j + nf_._count == NumRows());
+ _rowMap.SetSize(j);
+
+ FixupReverseMap();
+
+ _width = NumHandlers(); // sorry, no more optimization
+ }
+ break;
+
+ case c4_Notifier::kMove:
+ {
+ // incorrect: may need to move if recnum matters (recs same)
+ }
+ break;
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_ProjectSeq : public c4_DerivedSeq
+{
+ c4_DWordArray _colMap; // a bit large, but bytes would be too small
+ bool _frozen;
+ int _omitCount; // if > 0 then this is a dynamic "project without"
+
+public:
+ c4_ProjectSeq (c4_Sequence& seq_, c4_Sequence& in_, bool, c4_Sequence* out_);
+ virtual ~c4_ProjectSeq ();
+
+ virtual int NumHandlers() const;
+ virtual c4_Handler& NthHandler(int) const;
+ virtual const c4_Sequence* HandlerContext(int) const;
+ virtual int AddHandler(c4_Handler*);
+
+ virtual bool Get(int, int, c4_Bytes&);
+ virtual void Set(int, const c4_Property&, const c4_Bytes&);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_ProjectSeq::c4_ProjectSeq (c4_Sequence& seq_, c4_Sequence& in_,
+ bool reorder_, c4_Sequence* out_)
+ : c4_DerivedSeq (seq_), _frozen (!reorder_ && !out_), _omitCount (0)
+{
+ // build the array with column indexes
+ for (int j = 0; j < in_.NumHandlers(); ++j)
+ {
+ int propId = in_.NthPropId(j);
+ int idx = _seq.PropIndex(propId);
+
+ // if the j'th property is in the sequence, add it
+ if (idx >= 0)
+ {
+ // but only if it's not in the out_ view
+ if (out_ && out_->PropIndex(propId) >= 0)
+ ++_omitCount;
+ else
+ _colMap.Add(idx);
+ }
+ }
+
+ // if only reordering, append remaining columns from original view
+ if (reorder_)
+ {
+ for (int i = 0; i < _seq.NumHandlers(); ++i)
+ {
+ int propId = _seq.NthPropId(i);
+
+ // only consider properties we did not deal with before
+ if (in_.PropIndex(propId) < 0)
+ _colMap.Add(i);
+ }
+
+ d4_assert(_colMap.GetSize() == _seq.NumHandlers());
+ }
+}
+
+c4_ProjectSeq::~c4_ProjectSeq ()
+{
+}
+
+int c4_ProjectSeq::NumHandlers() const
+{
+ return _frozen ? _colMap.GetSize() : _seq.NumHandlers() - _omitCount;
+}
+
+c4_Handler& c4_ProjectSeq::NthHandler(int colNum_) const
+{
+ int n = colNum_ < _colMap.GetSize() ? _colMap.GetAt(colNum_) : colNum_;
+ return _seq.NthHandler(n);
+}
+
+const c4_Sequence* c4_ProjectSeq::HandlerContext(int colNum_) const
+{
+ int n = colNum_ < _colMap.GetSize() ? _colMap.GetAt(colNum_) : colNum_;
+ return _seq.HandlerContext(n);
+}
+
+int c4_ProjectSeq::AddHandler(c4_Handler* handler_)
+{
+ int n = _seq.AddHandler(handler_);
+ return _frozen ? _colMap.Add(n) : n - _omitCount;
+}
+
+bool c4_ProjectSeq::Get(int index_, int propId_, c4_Bytes& buf_)
+{
+ // fixed in 1.8: check that the property is visible
+ return PropIndex(propId_) >= 0 && _seq.Get(index_, propId_, buf_);
+}
+
+void c4_ProjectSeq::Set(int index_, const c4_Property& prop_, const c4_Bytes& bytes_)
+{
+ int n = _seq.NumHandlers();
+ _seq.Set(index_, prop_, bytes_);
+
+ // if the number of handlers changed, then one must have been added
+ if (n != _seq.NumHandlers())
+ {
+ d4_assert(n == _seq.NumHandlers() - 1);
+
+ if (_frozen)
+ _colMap.Add(n);
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_Sequence* f4_CreateFilter(c4_Sequence& seq_, c4_Cursor l_, c4_Cursor h_)
+{
+ return d4_new c4_FilterSeq (seq_, l_, h_);
+}
+
+c4_Sequence* f4_CreateSort(c4_Sequence& seq_, c4_Sequence* down_)
+{
+ return d4_new c4_SortSeq (seq_, down_);
+}
+
+c4_Sequence* f4_CreateProject(c4_Sequence& seq_, c4_Sequence& in_,
+ bool reorder_, c4_Sequence* out_)
+{
+ return d4_new c4_ProjectSeq (seq_, in_, reorder_, out_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/akregator/src/mk4storage/metakit/src/derived.h b/akregator/src/mk4storage/metakit/src/derived.h
new file mode 100644
index 000000000..8bd934fc9
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/src/derived.h
@@ -0,0 +1,25 @@
+// derived.h --
+// $Id$
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit/
+
+/** @file
+ * Encapsulation of derived view classes
+ */
+
+#ifndef __DERIVED_H__
+#define __DERIVED_H__
+
+/////////////////////////////////////////////////////////////////////////////
+// Declarations in this file
+
+ class c4_Cursor; // not defined here
+ class c4_Sequence; // not defined here
+
+ extern c4_Sequence* f4_CreateFilter(c4_Sequence&, c4_Cursor, c4_Cursor);
+ extern c4_Sequence* f4_CreateSort(c4_Sequence&, c4_Sequence* =0);
+ extern c4_Sequence* f4_CreateProject(c4_Sequence&, c4_Sequence&,
+ bool, c4_Sequence* =0);
+
+/////////////////////////////////////////////////////////////////////////////
+
+#endif
diff --git a/akregator/src/mk4storage/metakit/src/field.cpp b/akregator/src/mk4storage/metakit/src/field.cpp
new file mode 100644
index 000000000..3867d6b5c
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/src/field.cpp
@@ -0,0 +1,119 @@
+// field.cpp --
+// $Id$
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit/
+
+/** @file
+ * Implementation of the field structure tree
+ */
+
+#include "header.h"
+#include "field.h"
+
+#include <stdlib.h> // strtol
+
+#if !q4_INLINE
+#include "field.inl"
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// Implemented in this file
+
+ class c4_Field;
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_Field
+
+c4_Field::c4_Field (const char*& description_, c4_Field* parent_)
+ : _type (0)
+{
+ _indirect = this;
+
+ size_t n = strcspn(description_, ",[]");
+ const char* p = strchr(description_, ':');
+
+ if (p != 0 && p < description_ + n) {
+ _name = c4_String (description_, p - description_);
+ _type = p[1] & ~0x20; // force to upper case
+ } else {
+ _name = c4_String (description_, n);
+ _type = 'S';
+ }
+
+ description_ += n;
+
+ if (*description_ == '[') {
+ ++description_;
+ _type = 'V';
+
+ if (*description_ == '^') {
+ ++description_;
+ _indirect = parent_;
+ d4_assert(*description_ == ']');
+ }
+
+ if (*description_ == ']')
+ ++description_;
+ else
+ do {
+ // 2004-01-20 ignore duplicate property names
+ // (since there is no good way to report errors at this point)
+ c4_Field* sf = d4_new c4_Field (description_, this);
+ for (int i = 0; i < NumSubFields(); ++i)
+ if (SubField(i).Name().CompareNoCase(sf->Name()) == 0) {
+ delete sf;
+ sf = 0;
+ break;
+ }
+ if (sf != 0)
+ _subFields.Add(sf);
+ } while (*description_++ == ',');
+ }
+}
+
+c4_Field::~c4_Field ()
+{
+ if (_indirect == this) {
+ //better? for (int i = NumSubFields(); --i >= 0 ;)
+ for (int i = 0; i < NumSubFields(); ++i) {
+ c4_Field* sf = & SubField(i);
+ if (sf != this) // careful with recursive subfields
+ delete sf;
+ }
+ }
+}
+
+c4_String c4_Field::Description(bool anonymous_) const
+{
+ c4_String s = anonymous_ ? "?" : (const char*) Name();
+
+ if (Type() == 'V')
+ s += "[" + DescribeSubFields(anonymous_) + "]";
+ else {
+ s += ":";
+ s += (c4_String) Type();
+ }
+
+ return s;
+}
+
+c4_String c4_Field::DescribeSubFields(bool) const
+{
+ d4_assert(Type() == 'V');
+
+ if (_indirect != this)
+ return "^";
+
+ c4_String s;
+ char c = 0;
+
+ for (int i = 0; i < NumSubFields(); ++i) {
+ if (c != 0)
+ s += (c4_String) c;
+ s += SubField(i).Description();
+ c = ',';
+ }
+
+ return s;
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/akregator/src/mk4storage/metakit/src/field.h b/akregator/src/mk4storage/metakit/src/field.h
new file mode 100644
index 000000000..5dfc25736
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/src/field.h
@@ -0,0 +1,64 @@
+// field.h --
+// $Id$
+// This is part of Metakit, see http://www.equi4.com/metakit/
+
+/** @file
+ * Core class to represent fields
+ */
+
+#ifndef __FIELD_H__
+#define __FIELD_H__
+
+#ifndef __K4CONF_H__
+#error Please include "k4conf.h" before this header file
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_Field
+{
+ c4_PtrArray _subFields;
+ c4_String _name;
+ char _type;
+ c4_Field* _indirect;
+
+public:
+/* Construction / destruction */
+ c4_Field (const char*&, c4_Field* =0);
+ //: Constructs a new field.
+ ~c4_Field ();
+
+/* Repeating and compound fields */
+ int NumSubFields() const;
+ //: Returns the number of subfields.
+ c4_Field& SubField(int) const;
+ //: Returns the description of each subfield.
+ bool IsRepeating() const;
+ //: Returns true if this field contains subtables.
+
+/* Field name and description */
+ const c4_String& Name() const;
+ //: Returns name of this field.
+ char Type() const;
+ //: Returns the type description of this field, if any.
+ char OrigType() const;
+ //: Similar, but report types which were originall 'M' as well.
+ c4_String Description(bool anonymous_ =false) const;
+ //: Describes the structure, omit names if anonymous.
+ c4_String DescribeSubFields(bool anonymous_ =false) const;
+ //: Describes just the subfields, omit names if anonymous.
+
+private:
+ c4_Field (const c4_Field&); // not implemented
+ void operator= (const c4_Field&); // not implemented
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+#if q4_INLINE
+#include "field.inl"
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+
+#endif
diff --git a/akregator/src/mk4storage/metakit/src/field.inl b/akregator/src/mk4storage/metakit/src/field.inl
new file mode 100644
index 000000000..823e626e3
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/src/field.inl
@@ -0,0 +1,37 @@
+// field.inl --
+// $Id$
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit/
+
+/** @file
+ * Inlined members of the field class
+ */
+
+d4_inline bool c4_Field::IsRepeating() const
+{
+ return _type == 'V';
+}
+
+d4_inline int c4_Field::NumSubFields() const
+{
+ return _indirect->_subFields.GetSize();
+}
+
+d4_inline c4_Field& c4_Field::SubField(int index_) const
+{
+ return *(c4_Field*) _indirect->_subFields.GetAt(index_);
+}
+
+d4_inline const c4_String& c4_Field::Name() const
+{
+ return _name;
+}
+
+d4_inline char c4_Field::OrigType() const
+{
+ return _type;
+}
+
+d4_inline char c4_Field::Type() const
+{
+ return _type == 'M' ? 'B' : _type;
+}
diff --git a/akregator/src/mk4storage/metakit/src/fileio.cpp b/akregator/src/mk4storage/metakit/src/fileio.cpp
new file mode 100644
index 000000000..28ff7dca0
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/src/fileio.cpp
@@ -0,0 +1,434 @@
+// fileio.cpp --
+// $Id$
+// This is part of Metakit, see http://www.equi4.com/metakit/
+
+/** @file
+ * Implementation of c4_FileStrategy and c4_FileStream
+ */
+
+#include "header.h"
+#include "mk4io.h"
+
+#if q4_WIN32
+#if q4_MSVC && !q4_STRICT
+#pragma warning(disable: 4201) // nonstandard extension used : ...
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#if !defined (q4_WINCE)
+#include <io.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#endif
+#endif
+
+#if q4_UNIX && HAVE_MMAP
+#include <sys/types.h>
+#include <sys/mman.h>
+#endif
+
+#if q4_UNIX
+#include <unistd.h>
+#include <fcntl.h>
+#endif
+
+#if q4_WINCE
+#define _get_osfhandle(x) x
+#endif
+
+#ifndef _O_NOINHERIT
+#define _O_NOINHERIT 0
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// The "Carbon" version of a build on Macintosh supports running under
+// either MacOS 7..9 (which has no mmap), or MacOS X (which has mmap).
+// The logic below was adapted from a contribution by Paul Snively, it
+// decides at run time which case it is, and switches I/O calls to match.
+
+#if defined (q4_CARBON) && q4_CARBON
+//#if q4_MAC && !defined (__MACH__) && (!q4_MWCW || __MWERKS__ >= 0x3000)
+#undef HAVE_MMAP
+#define HAVE_MMAP 1
+
+#include <CFBundle.h>
+#include <Folders.h>
+
+#define PROT_NONE 0x00
+#define PROT_READ 0x01
+#define PROT_WRITE 0x02
+#define PROT_EXEC 0x04
+
+#define MAP_SHARED 0x0001
+#define MAP_PRIVATE 0x0002
+
+#define MAP_FIXED 0x0010
+#define MAP_RENAME 0x0020
+#define MAP_NORESERVE 0x0040
+#define MAP_INHERIT 0x0080
+#define MAP_NOEXTEND 0x0100
+#define MAP_HASSEMAPHORE 0x0200
+
+typedef unsigned long t4_u32;
+
+static t4_u32 sfwRefCount = 0;
+static CFBundleRef systemFramework = NULL;
+
+static char* fake_mmap(char*, t4_u32, int, int, int, long long)
+ { return (char*) -1L; }
+static int fake_munmap(char*, t4_u32)
+ { return 0; }
+
+static FILE* (*my_fopen)(const char*,const char*) = fopen;
+static int (*my_fclose)(FILE*) = fclose;
+static long (*my_ftell)(FILE*) = ftell;
+static int (*my_fseek)(FILE*,long,int) = fseek;
+static t4_u32 (*my_fread)(void* ptr,t4_u32,t4_u32,FILE*) = fread;
+static t4_u32 (*my_fwrite)(const void* ptr,t4_u32,t4_u32,FILE*) = fwrite;
+static int (*my_ferror)(FILE*) = ferror;
+static int (*my_fflush)(FILE*) = fflush;
+static int (*my_fileno)(FILE*) = fileno;
+static char* (*my_mmap)(char*,t4_u32,int,int,int,long long) = fake_mmap;
+static int (*my_munmap)(char*,t4_u32) = fake_munmap;
+
+static void InitializeIO()
+{
+ if (sfwRefCount++) return; // race condition, infinitesimal risk
+
+ FSRef theRef;
+ if (FSFindFolder(kOnAppropriateDisk, kFrameworksFolderType,
+ false, &theRef) == noErr) {
+ CFURLRef fw = CFURLCreateFromFSRef(kCFAllocatorSystemDefault, &theRef);
+ if (fw) {
+ CFURLRef bd =
+ CFURLCreateCopyAppendingPathComponent(kCFAllocatorSystemDefault,
+ fw, CFSTR("System.framework"), false);
+ CFRelease(fw);
+ if (bd) {
+ systemFramework = CFBundleCreate(kCFAllocatorSystemDefault, bd);
+ CFRelease(bd);
+ }
+ }
+ if (!systemFramework || !CFBundleLoadExecutable(systemFramework))
+ return;
+#define F(x) CFBundleGetFunctionPointerForName(systemFramework, CFSTR(#x))
+ my_fopen = (FILE* (*)(const char*,const char*)) F(fopen);
+ my_fclose = (int (*)(FILE*)) F(fclose);
+ my_ftell = (long (*)(FILE*)) F(ftell);
+ my_fseek = (int (*)(FILE*,long,int)) F(fseek);
+ my_fread = (t4_u32 (*)(void* ptr,t4_u32,t4_u32,FILE*)) F(fread);
+ my_fwrite = (t4_u32 (*)(const void* ptr,t4_u32,t4_u32,FILE*)) F(fwrite);
+ my_ferror = (int (*)(FILE*)) F(ferror);
+ my_fflush = (int (*)(FILE*)) F(fflush);
+ my_fileno = (int (*)(FILE*)) F(fileno);
+ my_mmap = (char* (*)(char*,t4_u32,int,int,int,long long)) F(mmap);
+ my_munmap = (int (*)(char*,t4_u32)) F(munmap);
+#undef F
+ d4_assert(my_fopen && my_fclose && my_ftell && my_fseek &&
+ my_fread && my_fwrite && my_ferror && my_fflush &&
+ my_fileno && my_mmap && my_munmap);
+ }
+}
+
+static void FinalizeIO()
+{
+ if (--sfwRefCount) return; // race condition, infinitesimal risk
+
+ if (systemFramework) {
+ CFBundleUnloadExecutable(systemFramework);
+ CFRelease(systemFramework);
+ systemFramework = 0;
+ }
+}
+
+#define fopen my_fopen
+#define fclose my_fclose
+#define ftell my_ftell
+#define fseek my_fseek
+#define fread my_fread
+#define fwrite my_fwrite
+#define ferror my_ferror
+#define fflush my_fflush
+#define fileno my_fileno
+#define mmap my_mmap
+#define munmap my_munmap
+
+#else
+
+#define InitializeIO()
+#define FinalizeIO()
+
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+
+#if q4_CHECK
+#include <stdlib.h>
+
+void f4_AssertionFailed(const char* cond_, const char* file_, int line_)
+{
+ fprintf(stderr, "Assertion failed: %s (file %s, line %d)\n",
+ cond_, file_, line_);
+ abort();
+}
+
+#endif //q4_CHECK
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_FileStream
+
+c4_FileStream::c4_FileStream (FILE* stream_, bool owned_)
+ : _stream (stream_), _owned (owned_)
+{
+}
+
+c4_FileStream::~c4_FileStream ()
+{
+ if (_owned)
+ fclose(_stream);
+}
+
+int c4_FileStream::Read(void* buffer_, int length_)
+{
+ d4_assert(_stream != 0);
+
+ return (int) fread(buffer_, 1, length_, _stream);
+}
+
+bool c4_FileStream::Write(const void* buffer_, int length_)
+{
+ d4_assert(_stream != 0);
+
+ return (int) fwrite(buffer_, 1, length_, _stream) == length_;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_FileStrategy
+
+c4_FileStrategy::c4_FileStrategy (FILE* file_)
+ : _file (file_), _cleanup (0)
+{
+ InitializeIO();
+ ResetFileMapping();
+}
+
+c4_FileStrategy::~c4_FileStrategy ()
+{
+ _file = 0;
+ ResetFileMapping();
+
+ if (_cleanup)
+ fclose(_cleanup);
+
+ d4_assert(_mapStart == 0);
+ FinalizeIO();
+}
+
+bool c4_FileStrategy::IsValid() const
+{
+ return _file != 0;
+}
+
+t4_i32 c4_FileStrategy::FileSize()
+{
+ d4_assert(_file != 0);
+
+ long size = -1;
+
+ long old = ftell(_file);
+ if (old >= 0 && fseek(_file, 0, 2) == 0) {
+ long pos = ftell(_file);
+ if (fseek(_file, old, 0) == 0)
+ size = pos;
+ }
+
+ if (size < 0)
+ _failure = ferror(_file);
+
+ return size;
+}
+
+t4_i32 c4_FileStrategy::FreshGeneration()
+{
+ d4_assert(false);
+ return 0;
+}
+
+void c4_FileStrategy::ResetFileMapping()
+{
+#if q4_WIN32
+ if (_mapStart != 0) {
+ _mapStart -= _baseOffset;
+ d4_dbgdef(BOOL g =)
+ ::UnmapViewOfFile((char*) _mapStart);
+ d4_assert(g);
+ _mapStart = 0;
+ _dataSize = 0;
+ }
+
+ if (_file != 0) {
+ t4_i32 len = FileSize();
+
+ if (len > 0) {
+ FlushFileBuffers((HANDLE) _get_osfhandle(_fileno(_file)));
+ HANDLE h = ::CreateFileMapping((HANDLE) _get_osfhandle(_fileno(_file)),
+ 0, PAGE_READONLY, 0, len, 0);
+ d4_assert(h); // check for errors, but can continue without mapping
+
+ if (h) {
+ _mapStart = (t4_byte*) ::MapViewOfFile(h, FILE_MAP_READ, 0, 0, len);
+ d4_assert(_mapStart != 0);
+
+ if (_mapStart != 0) {
+ _mapStart += _baseOffset;
+ _dataSize = len - _baseOffset;
+ }
+
+ d4_dbgdef(BOOL f =)
+ ::CloseHandle(h);
+ d4_assert(f);
+ }
+ }
+ }
+#elif HAVE_MMAP
+ if (_mapStart != 0) {
+ _mapStart -= _baseOffset;
+ munmap((char*) _mapStart, _baseOffset + _dataSize); // also loses const
+ _mapStart = 0;
+ _dataSize = 0;
+ }
+
+ if (_file != 0) {
+ t4_i32 len = FileSize();
+
+ if (len > 0) {
+ _mapStart = (const t4_byte*) mmap(0, len, PROT_READ, MAP_SHARED,
+ fileno(_file), 0);
+ if (_mapStart != (void*) -1L) {
+ _mapStart += _baseOffset;
+ _dataSize = len - _baseOffset;
+ } else
+ _mapStart = 0;
+ }
+ }
+#endif
+}
+
+bool c4_FileStrategy::DataOpen(const char* fname_, int mode_)
+{
+ d4_assert(!_file);
+
+#if q4_WIN32 && !q4_BORC && !q4_WINCE
+ int flags = _O_BINARY | _O_NOINHERIT | (mode_ > 0 ? _O_RDWR : _O_RDONLY);
+ int fd = _open(fname_, flags);
+ if (fd != -1)
+ _cleanup = _file = _fdopen(fd, mode_ > 0 ? "r+b" : "rb");
+#else
+ _cleanup = _file = fopen(fname_, mode_ > 0 ? "r+b" : "rb");
+#if q4_UNIX
+ if (_file != 0)
+ fcntl(fileno(_file), F_SETFD, FD_CLOEXEC);
+#endif //q4_UNIX
+#endif //q4_WIN32 && !q4_BORC && !q4_WINCE
+
+ if (_file != 0) {
+ ResetFileMapping();
+ return true;
+ }
+
+ if (mode_ > 0) {
+#if q4_WIN32 && !q4_BORC && !q4_WINCE
+ fd = _open(fname_, flags | _O_CREAT, _S_IREAD | _S_IWRITE);
+ if (fd != -1)
+ _cleanup = _file = _fdopen(fd, "w+b");
+#else
+ _cleanup = _file = fopen(fname_, "w+b");
+#if q4_UNIX
+ if (_file != 0)
+ fcntl(fileno(_file), F_SETFD, FD_CLOEXEC);
+#endif //q4_UNIX
+#endif //q4_WIN32 && !q4_BORC && !q4_WINCE
+ }
+
+ //d4_assert(_file != 0);
+ return false;
+}
+
+int c4_FileStrategy::DataRead(t4_i32 pos_, void* buf_, int len_)
+{
+ d4_assert(_baseOffset + pos_ >= 0);
+ d4_assert(_file != 0);
+
+ //printf("DataRead at %d len %d\n", pos_, len_);
+ return fseek(_file, _baseOffset + pos_, 0) != 0 ? -1 :
+ (int) fread(buf_, 1, len_, _file);
+}
+
+void c4_FileStrategy::DataWrite(t4_i32 pos_, const void* buf_, int len_)
+{
+ d4_assert(_baseOffset + pos_ >= 0);
+ d4_assert(_file != 0);
+#if 0
+ if (_mapStart <= buf_ && buf_ < _mapStart + _dataSize) {
+ printf("DataWrite %08x at %d len %d (map %d)\n", buf_, pos_, len_,
+ (const t4_byte*) buf_ - _mapStart + _baseOffset);
+ } else {
+ printf("DataWrite %08x at %d len %d\n", buf_, pos_, len_);
+ }
+ fprintf(stderr, " _mapStart %08x _dataSize %d buf_ %08x len_ %d _baseOffset %d\n",
+ _mapStart, _dataSize, buf_, len_, _baseOffset);
+ printf(" _mapStart %08x _dataSize %d buf_ %08x len_ %d _baseOffset %d\n",
+ _mapStart, _dataSize, buf_, len_, _baseOffset);
+ fflush(stdout);
+#endif
+
+#if q4_WIN32 || __hpux || __MACH__
+// if (buf_ >= _mapStart && buf_ <= _mapLimit - len_)
+
+ // a horrendous hack to allow file mapping for Win95 on network drive
+ // must use a temp buf to avoid write from mapped file to same file
+ //
+ // 6-Feb-1999 -- this workaround is not thread safe
+ // 30-Nov-2001 -- changed to use the stack so now it is
+ // 28-Oct-2002 -- added HP/UX to the mix, to avoid hard lockup
+ char tempBuf [4096];
+ d4_assert(len_ <= sizeof tempBuf);
+ buf_ = memcpy(tempBuf, buf_, len_);
+#endif
+
+ if (fseek(_file, _baseOffset + pos_, 0) != 0 ||
+ (int) fwrite(buf_, 1, len_, _file) != len_) {
+ _failure = ferror(_file);
+ d4_assert(_failure != 0);
+ d4_assert(true); // always force an assertion failure in debug mode
+ }
+}
+
+void c4_FileStrategy::DataCommit(t4_i32 limit_)
+{
+ d4_assert(_file != 0);
+
+ if (fflush(_file) < 0) {
+ _failure = ferror(_file);
+ d4_assert(_failure != 0);
+ d4_assert(true); // always force an assertion failure in debug mode
+ return;
+ }
+
+ if (limit_ > 0) {
+#if 0 // can't truncate file in a portable way!
+ // unmap the file first, WinNT is more picky about this than Win95
+ FILE* save = _file;
+
+ _file = 0;
+ ResetFileMapping();
+ _file = save;
+
+ _file->SetLength(limit_); // now we can resize the file
+#endif
+ ResetFileMapping(); // remap, since file length may have changed
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/akregator/src/mk4storage/metakit/src/format.cpp b/akregator/src/mk4storage/metakit/src/format.cpp
new file mode 100644
index 000000000..aa23e7391
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/src/format.cpp
@@ -0,0 +1,1341 @@
+// format.cpp --
+// $Id$
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit/
+
+/** @file
+ * Format handlers deal with the representation of data
+ */
+
+#include "header.h"
+#include "handler.h"
+#include "column.h"
+#include "format.h"
+#include "persist.h"
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_FormatHandler : public c4_Handler
+{
+ c4_HandlerSeq& _owner;
+
+public:
+ c4_FormatHandler (const c4_Property& prop_, c4_HandlerSeq& owner_);
+ virtual ~c4_FormatHandler ();
+
+ virtual bool IsPersistent() const;
+
+protected:
+ c4_HandlerSeq& Owner() const;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_FormatHandler
+
+c4_FormatHandler::c4_FormatHandler (const c4_Property& prop_, c4_HandlerSeq& owner_)
+ : c4_Handler (prop_), _owner (owner_)
+{
+}
+
+c4_FormatHandler::~c4_FormatHandler ()
+{
+}
+
+d4_inline c4_HandlerSeq& c4_FormatHandler::Owner() const
+{
+ return _owner;
+}
+
+bool c4_FormatHandler::IsPersistent() const
+{
+ return _owner.Persist() != 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_FormatX : public c4_FormatHandler
+{
+public:
+ c4_FormatX (const c4_Property& prop_, c4_HandlerSeq& seq_,
+ int width_ =sizeof (t4_i32));
+
+ virtual void Define(int, const t4_byte**);
+ virtual void OldDefine(char type_, c4_Persist&);
+ virtual void FlipBytes();
+
+ virtual int ItemSize(int index_);
+ virtual const void* Get(int index_, int& length_);
+ virtual void Set(int index_, const c4_Bytes& buf_);
+
+ virtual void Insert(int index_, const c4_Bytes& buf_, int count_);
+ virtual void Remove(int index_, int count_);
+
+ virtual void Commit(c4_SaveContext& ar_);
+
+ virtual void Unmapped();
+
+ static int DoCompare(const c4_Bytes& b1_, const c4_Bytes& b2_);
+
+protected:
+ c4_ColOfInts _data;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_FormatX::c4_FormatX (const c4_Property& p_, c4_HandlerSeq& s_, int w_)
+ : c4_FormatHandler (p_, s_), _data (s_.Persist(), w_)
+{
+}
+
+int c4_FormatX::DoCompare(const c4_Bytes& b1_, const c4_Bytes& b2_)
+{
+ return c4_ColOfInts::DoCompare(b1_, b2_);
+}
+
+void c4_FormatX::Commit(c4_SaveContext& ar_)
+{
+ _data.FixSize(true);
+ ar_.CommitColumn(_data);
+ //_data.FixSize(false);
+}
+
+void c4_FormatX::Define(int rows_, const t4_byte** ptr_)
+{
+ if (ptr_ != 0)
+ _data.PullLocation(*ptr_);
+
+ _data.SetRowCount(rows_);
+}
+
+void c4_FormatX::OldDefine(char, c4_Persist& pers_)
+{
+ pers_.FetchOldLocation(_data);
+ _data.SetRowCount(Owner().NumRows());
+}
+
+void c4_FormatX::FlipBytes()
+{
+ _data.FlipBytes();
+}
+
+int c4_FormatX::ItemSize(int index_)
+{
+ return _data.ItemSize(index_);
+}
+
+const void* c4_FormatX::Get(int index_, int& length_)
+{
+ return _data.Get(index_, length_);
+}
+
+void c4_FormatX::Set(int index_, const c4_Bytes& buf_)
+{
+ _data.Set(index_, buf_);
+}
+
+void c4_FormatX::Insert(int index_, const c4_Bytes& buf_, int count_)
+{
+ _data.Insert(index_, buf_, count_);
+}
+
+void c4_FormatX::Remove(int index_, int count_)
+{
+ _data.Remove(index_, count_);
+}
+
+void c4_FormatX::Unmapped()
+{
+ _data.ReleaseAllSegments();
+}
+
+/////////////////////////////////////////////////////////////////////////////
+#if !q4_TINY
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_FormatL : public c4_FormatX
+{
+public:
+ c4_FormatL (const c4_Property& prop_, c4_HandlerSeq& seq_);
+
+ virtual void Define(int, const t4_byte**);
+
+ static int DoCompare(const c4_Bytes& b1_, const c4_Bytes& b2_);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_FormatL::c4_FormatL (const c4_Property& prop_, c4_HandlerSeq& seq_)
+ : c4_FormatX (prop_, seq_, sizeof (t4_i64))
+{
+ // force maximum size, autosizing more than 32 bits won't work
+ _data.SetAccessWidth(8 * sizeof (t4_i64));
+}
+
+int c4_FormatL::DoCompare(const c4_Bytes& b1_, const c4_Bytes& b2_)
+{
+ d4_assert(b1_.Size() == sizeof (t4_i64));
+ d4_assert(b2_.Size() == sizeof (t4_i64));
+
+ t4_i64 v1 = *(const t4_i64*) b1_.Contents();
+ t4_i64 v2 = *(const t4_i64*) b2_.Contents();
+
+ return v1 == v2 ? 0 : v1 < v2 ? -1 : +1;
+}
+
+void c4_FormatL::Define(int rows_, const t4_byte** ptr_)
+{
+ if (ptr_ == 0 && rows_ > 0) {
+ d4_assert(_data.ColSize() == 0);
+ _data.InsertData(0, rows_ * sizeof (t4_i64), true);
+ }
+
+ c4_FormatX::Define(rows_, ptr_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_FormatF : public c4_FormatX
+{
+public:
+ c4_FormatF (const c4_Property& prop_, c4_HandlerSeq& seq_);
+
+ static int DoCompare(const c4_Bytes& b1_, const c4_Bytes& b2_);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_FormatF::c4_FormatF (const c4_Property& prop_, c4_HandlerSeq& seq_)
+ : c4_FormatX (prop_, seq_, sizeof (float))
+{
+}
+
+int c4_FormatF::DoCompare(const c4_Bytes& b1_, const c4_Bytes& b2_)
+{
+ d4_assert(b1_.Size() == sizeof (float));
+ d4_assert(b2_.Size() == sizeof (float));
+
+ float v1 = *(const float*) b1_.Contents();
+ float v2 = *(const float*) b2_.Contents();
+
+ return v1 == v2 ? 0 : v1 < v2 ? -1 : +1;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_FormatD : public c4_FormatX
+{
+public:
+ c4_FormatD (const c4_Property& prop_, c4_HandlerSeq& seq_);
+
+ virtual void Define(int, const t4_byte**);
+
+ static int DoCompare(const c4_Bytes& b1_, const c4_Bytes& b2_);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_FormatD::c4_FormatD (const c4_Property& prop_, c4_HandlerSeq& seq_)
+ : c4_FormatX (prop_, seq_, sizeof (double))
+{
+ // force maximum size, autosizing more than 32 bits won't work
+ _data.SetAccessWidth(8 * sizeof (double));
+}
+
+int c4_FormatD::DoCompare(const c4_Bytes& b1_, const c4_Bytes& b2_)
+{
+ d4_assert(b1_.Size() == sizeof (double));
+ d4_assert(b2_.Size() == sizeof (double));
+
+ double v1 = *(const double*) b1_.Contents();
+ double v2 = *(const double*) b2_.Contents();
+
+ return v1 == v2 ? 0 : v1 < v2 ? -1 : +1;
+}
+
+void c4_FormatD::Define(int rows_, const t4_byte** ptr_)
+{
+ if (ptr_ == 0 && rows_ > 0) {
+ d4_assert(_data.ColSize() == 0);
+ _data.InsertData(0, rows_ * sizeof (double), true);
+ }
+
+ c4_FormatX::Define(rows_, ptr_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // !q4_TINY
+/////////////////////////////////////////////////////////////////////////////
+
+/*
+ Byte properties are used for raw bytes and for indirect (memo) data.
+
+ There are two columns: the actual data and the item sizes. If the data
+ is indirect, then the size is stored as a negative value.
+
+ In addition, there is an in-memory-only vector of columns (_memos).
+ Columns are created when asked for, and stay around until released with
+ a commit call. If the column object exists and is not dirty, then it
+ is either a real column (size < 0), or simply a duplicate of the data
+ stored inline as bytes.
+*/
+
+class c4_FormatB : public c4_FormatHandler
+{
+public:
+ c4_FormatB (const c4_Property& prop_, c4_HandlerSeq& seq_);
+ virtual ~c4_FormatB ();
+
+ virtual void Define(int, const t4_byte**);
+ virtual void OldDefine(char type_, c4_Persist&);
+ virtual void Commit(c4_SaveContext& ar_);
+
+ virtual int ItemSize(int index_);
+ virtual const void* Get(int index_, int& length_);
+ virtual void Set(int index_, const c4_Bytes& buf_);
+
+ virtual void Insert(int index_, const c4_Bytes& buf_, int count_);
+ virtual void Remove(int index_, int count_);
+
+ virtual c4_Column* GetNthMemoCol(int index_, bool alloc_);
+
+ virtual void Unmapped();
+
+ static int DoCompare(const c4_Bytes& b1_, const c4_Bytes& b2_);
+
+protected:
+ const void* GetOne(int index_, int& length_);
+ void SetOne(int index_, const c4_Bytes& buf_, bool ignoreMemos_ =false);
+
+private:
+ t4_i32 Offset(int index_) const;
+ bool ShouldBeMemo(int length_) const;
+ int ItemLenOffCol(int index_, t4_i32& off_, c4_Column*& col_);
+ bool CommitItem(c4_SaveContext& ar_, int index_);
+ void InitOffsets(c4_ColOfInts& sizes_);
+
+ c4_Column _data;
+ c4_ColOfInts _sizeCol; // 2001-11-27: keep, to track position on disk
+ c4_Column _memoCol; // 2001-11-27: keep, to track position on disk
+ c4_DWordArray _offsets;
+ c4_PtrArray _memos;
+ bool _recalc; // 2001-11-27: remember when to redo _{size,memo}Col
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_FormatB::c4_FormatB (const c4_Property& prop_, c4_HandlerSeq& seq_)
+ : c4_FormatHandler (prop_, seq_), _data (seq_.Persist()),
+ _sizeCol (seq_.Persist()), _memoCol (seq_.Persist()), _recalc (false)
+{
+ _offsets.SetSize(1, 100);
+ _offsets.SetAt(0, 0);
+}
+
+c4_FormatB::~c4_FormatB ()
+{
+ // cleanup allocated columns
+ //better? for (int i = _memos.GetSize(); --i >= 0 ;)
+ for (int i = 0; i < _memos.GetSize(); ++i)
+ delete (c4_Column*) _memos.GetAt(i);
+}
+
+d4_inline t4_i32 c4_FormatB::Offset(int index_) const
+{
+ d4_assert((t4_i32) _offsets.GetAt(_offsets.GetSize() - 1) == _data.ColSize());
+ d4_assert(_offsets.GetSize() == _memos.GetSize() + 1);
+ d4_assert(index_ < _offsets.GetSize());
+
+ // extend offset vectors for missing empty entries at end
+ int n = _offsets.GetSize();
+ d4_assert(n > 0);
+
+ if (index_ >= n)
+ index_ = n - 1;
+
+ return _offsets.GetAt(index_);
+}
+
+d4_inline bool c4_FormatB::ShouldBeMemo(int length_) const
+{
+ // items over 10000 bytes are always memos
+ // items up to 100 bytes are never memos
+ //
+ // else, memo only if the column would be under 1 Mb
+ // (assuming all items had the same size as this one)
+ //
+ // the effect is that as the number of rows increases,
+ // smaller and smaller items get turned into memos
+ //
+ // note that items which are no memo right now stay
+ // as is, and so do memos which have not been modified
+
+ int rows = _memos.GetSize() + 1; // avoids divide by zero
+ return length_ > 10000 || length_ > 100 && length_ > 1000000 / rows;
+}
+
+int c4_FormatB::ItemLenOffCol(int index_, t4_i32& off_, c4_Column*& col_)
+{
+ col_ = (c4_Column*) _memos.GetAt(index_);
+ if (col_ != 0) {
+ off_ = 0;
+ return col_->ColSize();
+ }
+
+ col_ = &_data;
+ off_ = Offset(index_);
+ return Offset(index_ + 1) - off_;
+}
+
+c4_Column* c4_FormatB::GetNthMemoCol(int index_, bool alloc_)
+{
+ t4_i32 start;
+ c4_Column* col;
+ int n = ItemLenOffCol(index_, start, col);
+
+ if (col == &_data && alloc_) {
+ col = d4_new c4_Column (_data.Persist());
+ _memos.SetAt(index_, col);
+
+ if (n > 0)
+ if (_data.IsDirty()) {
+ c4_Bytes temp;
+ _data.FetchBytes(start, n, temp, true);
+ col->SetBuffer(n);
+ col->StoreBytes(0, temp);
+ }
+ else
+ col->SetLocation(_data.Position() + start, n);
+ }
+
+ return col;
+}
+
+void c4_FormatB::Unmapped()
+{
+ _data.ReleaseAllSegments();
+ _sizeCol.ReleaseAllSegments();
+ _memoCol.ReleaseAllSegments();
+
+ for (int i = 0; i < _memos.GetSize(); ++i) {
+ c4_Column* cp = (c4_Column*) _memos.GetAt(i);
+ if (cp != 0)
+ cp->ReleaseAllSegments();
+ }
+}
+
+void c4_FormatB::Define(int, const t4_byte** ptr_)
+{
+ d4_assert(_memos.GetSize() == 0);
+
+ if (ptr_ != 0) {
+ _data.PullLocation(*ptr_);
+ if (_data.ColSize() > 0)
+ _sizeCol.PullLocation(*ptr_);
+ _memoCol.PullLocation(*ptr_);
+ }
+
+ // everything below this point could be delayed until use
+ // in that case, watch out that column space use is properly tracked
+
+ InitOffsets(_sizeCol);
+
+ if (_memoCol.ColSize() > 0) {
+ c4_Bytes walk;
+ _memoCol.FetchBytes(0, _memoCol.ColSize(), walk, true);
+
+ const t4_byte* p = walk.Contents();
+
+ for (int row = 0; p < walk.Contents() + walk.Size(); ++row) {
+ row += c4_Column::PullValue(p);
+ d4_assert(row < _memos.GetSize());
+
+ c4_Column* mc = d4_new c4_Column (_data.Persist());
+ d4_assert(mc != 0);
+ _memos.SetAt(row, mc);
+
+ mc->PullLocation(p);
+ }
+
+ d4_assert(p == walk.Contents() + walk.Size());
+ }
+}
+
+void c4_FormatB::OldDefine(char type_, c4_Persist& pers_)
+{
+ int rows = Owner().NumRows();
+
+ c4_ColOfInts sizes (_data.Persist());
+
+ if (type_ == 'M') {
+ InitOffsets(sizes);
+
+ c4_ColOfInts szVec (_data.Persist());
+ pers_.FetchOldLocation(szVec);
+ szVec.SetRowCount(rows);
+
+ c4_ColOfInts posVec (_data.Persist());
+ pers_.FetchOldLocation(posVec);
+ posVec.SetRowCount(rows);
+
+ for (int r = 0; r < rows; ++r) {
+ t4_i32 sz = szVec.GetInt(r);
+ if (sz > 0) {
+ c4_Column* mc = d4_new c4_Column (_data.Persist());
+ d4_assert(mc != 0);
+ _memos.SetAt(r, mc);
+
+ mc->SetLocation(posVec.GetInt(r), sz);
+ }
+ }
+ } else {
+ pers_.FetchOldLocation(_data);
+
+ if (type_ == 'B') {
+ pers_.FetchOldLocation(sizes);
+
+#if !q4_OLD_IS_ALWAYS_V2
+
+ // WARNING - HUGE HACK AHEAD - THIS IS NOT 100% FULLPROOF!
+ //
+ // The above is correct for MK versions 2.0 and up, but *NOT*
+ // for MK 1.8.6 datafiles, which store sizes first (OUCH!!!).
+ // This means that there is not a 100% safe way to auto-convert
+ // both 1.8.6 and 2.0 files - since there is no way to detect
+ // unambiguously which version a datafile is. All we can do,
+ // is to carefully check both vectors, and *hope* that only one
+ // of them is valid as sizes vector. This problem applies to
+ // the 'B' (bytes) property type only, and only pre 2.0 files.
+ //
+ // To build a version which *always* converts assuming 1.8.6,
+ // add flag "-Dq4_OLD_IS_PRE_V2" to the compiler command line.
+ // Conversely, "-Dq4_OLD_IS_ALWAYS_V2" forces 2.0 conversion.
+
+ if (rows > 0) {
+ t4_i32 s1 = sizes.ColSize();
+ t4_i32 s2 = _data.ColSize();
+
+#if !q4_OLD_IS_PRE_V2
+ // if the size vector is clearly impossible, swap vectors
+ bool fix = c4_ColOfInts::CalcAccessWidth(rows, s1) < 0;
+
+ // if the other vector might be valid as well, check further
+ if (!fix && c4_ColOfInts::CalcAccessWidth(rows, s2) >= 0) {
+ sizes.SetRowCount(rows);
+ t4_i32 total = 0;
+ for (int i = 0; i < rows; ++i) {
+ t4_i32 w = sizes.GetInt(i);
+ if (w < 0 || total > s2) {
+ total = -1;
+ break;
+ }
+ total += w;
+ }
+
+ // if the sizes don't add up, swap vectors
+ fix = total != s2;
+ }
+
+ if (fix)
+#endif
+ {
+ t4_i32 p1 = sizes.Position();
+ t4_i32 p2 = _data.Position();
+ _data.SetLocation(p1, s1);
+ sizes.SetLocation(p2, s2);
+ }
+ }
+#endif
+ InitOffsets(sizes);
+ } else {
+ d4_assert(type_ == 'S');
+
+ sizes.SetRowCount(rows);
+
+ t4_i32 pos = 0;
+ t4_i32 lastEnd = 0;
+ int k = 0;
+
+ c4_ColIter iter (_data, 0, _data.ColSize());
+ while (iter.Next()) {
+ const t4_byte* p = iter.BufLoad();
+ for (int j = 0; j < iter.BufLen(); ++j)
+ if (!p[j]) {
+ sizes.SetInt(k++, pos + j + 1 - lastEnd);
+ lastEnd = pos + j + 1;
+ }
+
+ pos += iter.BufLen();
+ }
+
+ d4_assert(pos == _data.ColSize());
+
+ if (lastEnd < pos) { // last entry had no zero byte
+ _data.InsertData(pos++, 1, true);
+ sizes.SetInt(k, pos - lastEnd);
+ }
+
+ InitOffsets(sizes);
+
+ // get rid of entries with just a null byte
+ for (int r = 0; r < rows; ++r)
+ if (c4_FormatB::ItemSize(r) == 1)
+ SetOne(r, c4_Bytes ());
+ }
+ }
+}
+
+void c4_FormatB::InitOffsets(c4_ColOfInts& sizes_)
+{
+ int rows = Owner().NumRows();
+
+ if (sizes_.RowCount() != rows) {
+ sizes_.SetRowCount(rows);
+ }
+
+ _memos.SetSize(rows);
+ _offsets.SetSize(rows + 1);
+
+ if (_data.ColSize() > 0) {
+ t4_i32 total = 0;
+
+ for (int r = 0; r < rows; ++r) {
+ int n = sizes_.GetInt(r);
+ d4_assert(n >= 0);
+ total += n;
+ _offsets.SetAt(r + 1, total);
+ }
+
+ d4_assert(total == _data.ColSize());
+ }
+
+}
+
+int c4_FormatB::ItemSize(int index_)
+{
+ t4_i32 start;
+ c4_Column* col;
+ return ItemLenOffCol(index_, start, col);
+}
+
+const void* c4_FormatB::GetOne(int index_, int& length_)
+{
+ t4_i32 start;
+ c4_Column* cp;
+ length_ = ItemLenOffCol(index_, start, cp);
+ d4_assert(length_ >= 0);
+
+ if (length_ == 0)
+ return "";
+
+ return cp->FetchBytes(start, length_, Owner().Buffer(), false);
+}
+
+const void* c4_FormatB::Get(int index_, int& length_)
+{
+ return GetOne(index_, length_);
+}
+
+void c4_FormatB::SetOne(int index_, const c4_Bytes& xbuf_, bool ignoreMemos_)
+{
+ // this fixes bug in 2.4.0 when copying string from higher row
+ // TODO: this fix is very conservative, figure out when to copy
+ // (can probably look at pointer to see whether it's from us)
+ int sz = xbuf_.Size();
+ c4_Bytes buf_ (xbuf_.Contents(), sz, 0 < sz && sz <= c4_Column::kSegMax);
+
+ c4_Column* cp = &_data;
+ t4_i32 start = Offset(index_);
+ int len = Offset(index_ + 1) - start;
+
+ if (!ignoreMemos_ && _memos.GetAt(index_) != 0)
+ len = ItemLenOffCol(index_, start, cp);
+
+ int m = buf_.Size();
+ int n = m - len;
+
+ if (n > 0)
+ cp->Grow(start, n);
+ else if (n < 0)
+ cp->Shrink(start, - n);
+ else if (m == 0)
+ return; // no size change and no contents
+
+ _recalc = true;
+
+ cp->StoreBytes(start, buf_);
+
+ if (n && cp == &_data) { // if size has changed
+ int k = _offsets.GetSize() - 1;
+
+ // if filling in an empty entry at end: extend offsets first
+ if (m > 0 && index_ >= k) {
+ _offsets.InsertAt(k, _offsets.GetAt(k), index_ - k + 1);
+
+ k = index_ + 1;
+ d4_assert(k == _offsets.GetSize() - 1);
+ }
+
+ // adjust following entry offsets
+ while (++index_ <= k)
+ _offsets.ElementAt(index_) += n;
+ }
+
+ d4_assert((t4_i32) _offsets.GetAt(_offsets.GetSize() - 1) == _data.ColSize());
+}
+
+void c4_FormatB::Set(int index_, const c4_Bytes& buf_)
+{
+ SetOne(index_, buf_);
+}
+
+int c4_FormatB::DoCompare(const c4_Bytes& b1_, const c4_Bytes& b2_)
+{
+ int n = b1_.Size();
+ if (n > b2_.Size())
+ n = b2_.Size();
+
+ int f = memcmp(b1_.Contents(), b2_.Contents(), n);
+ return f ? f : b1_.Size() - b2_.Size();
+}
+
+void c4_FormatB::Insert(int index_, const c4_Bytes& buf_, int count_)
+{
+ d4_assert(count_ > 0);
+
+ _recalc = true;
+
+ int m = buf_.Size();
+ t4_i32 off = Offset(index_);
+
+ _memos.InsertAt(index_, 0, count_);
+
+ // insert the appropriate number of bytes
+ t4_i32 n = count_ * (t4_i32) m;
+ if (n > 0) {
+ _data.Grow(off, n);
+
+ // store as many copies as needed, but may have to do it in chunks
+ int spos = 0;
+
+ c4_ColIter iter (_data, off, off + n);
+ while (iter.Next(m - spos)) {
+ memcpy(iter.BufSave(), buf_.Contents() + spos, iter.BufLen());
+
+ spos += iter.BufLen();
+ if (spos >= m)
+ spos = 0;
+ }
+
+ d4_assert(spos == 0); // must have copied an exact multiple of the data
+ }
+
+ // define offsets of the new entries
+ _offsets.InsertAt(index_, 0, count_);
+ d4_assert(_offsets.GetSize() <= _memos.GetSize() + 1);
+
+ while (--count_ >= 0) {
+ _offsets.SetAt(index_++, off);
+ off += m;
+ }
+
+ d4_assert(index_ < _offsets.GetSize());
+
+ // adjust all following entries
+ while (index_ < _offsets.GetSize())
+ _offsets.ElementAt(index_++) += n;
+
+ d4_assert((t4_i32) _offsets.GetAt(index_ - 1) == _data.ColSize());
+ d4_assert(index_ <= _memos.GetSize() + 1);
+}
+
+void c4_FormatB::Remove(int index_, int count_)
+{
+ _recalc = true;
+
+ t4_i32 off = Offset(index_);
+ t4_i32 n = Offset(index_ + count_) - off;
+ d4_assert(n >= 0);
+
+ // remove the columns, if present
+ for (int i = 0; i < count_; ++i)
+ delete (c4_Column*) _memos.GetAt(index_ + i);
+ _memos.RemoveAt(index_, count_);
+
+ if (n > 0)
+ _data.Shrink(off, n);
+
+ _offsets.RemoveAt(index_, count_);
+
+ d4_assert(index_ < _offsets.GetSize());
+
+ // adjust all following entries
+ while (index_ < _offsets.GetSize())
+ _offsets.ElementAt(index_++) -= n;
+
+ d4_assert((t4_i32) _offsets.GetAt(index_ - 1) == _data.ColSize());
+ d4_assert(index_ <= _memos.GetSize() + 1);
+}
+
+void c4_FormatB::Commit(c4_SaveContext& ar_)
+{
+ int rows = _memos.GetSize();
+ d4_assert(rows > 0);
+
+ bool full = _recalc || ar_.Serializing();
+
+ if (!full)
+ for (int i = 0; i < rows; ++i) {
+ c4_Column* col = (c4_Column*) _memos.GetAt(i);
+ if (col != 0) {
+ full = true;
+ break;
+ }
+ }
+ d4_assert(_recalc || _sizeCol.RowCount() == rows);
+
+ if (full) {
+ _memoCol.SetBuffer(0);
+ _sizeCol.SetBuffer(0);
+ _sizeCol.SetAccessWidth(0);
+ _sizeCol.SetRowCount(rows);
+
+ int skip = 0;
+
+ c4_Column* saved = ar_.SetWalkBuffer(&_memoCol);
+
+ for (int r = 0; r < rows; ++r) {
+ ++skip;
+
+ t4_i32 start;
+ c4_Column* col;
+ int len = ItemLenOffCol(r, start, col);
+
+ bool oldMemo = col != &_data;
+ bool newMemo = ShouldBeMemo(len);
+
+ if (!oldMemo && newMemo) {
+ col = GetNthMemoCol(r, true);
+ d4_assert(col != &_data);
+ //? start = 0;
+ }
+
+ c4_Bytes temp;
+
+ if (newMemo) { // it now is a memo, inlined data will be empty
+ ar_.StoreValue(skip - 1);
+ skip = 0;
+ ar_.CommitColumn(*col);
+ } else if (!oldMemo) { // it was no memo, done if it hasn't become one
+ _sizeCol.SetInt(r, len);
+ continue;
+ } else { // it was a memo, but it no longer is
+ d4_assert(start == 0);
+ if (len > 0)
+ {
+ _sizeCol.SetInt(r, len);
+ col->FetchBytes(start, len, temp, true);
+ delete (c4_Column*) _memos.GetAt(r); // 28-11-2001: fix mem leak
+ _memos.SetAt(r, 0); // 02-11-2001: fix for use after commit
+ }
+ }
+
+ SetOne(r, temp, true); // bypass current memo pointer
+ }
+
+ ar_.SetWalkBuffer(saved);
+ }
+
+ ar_.CommitColumn(_data);
+
+ if (_data.ColSize() > 0) {
+ _sizeCol.FixSize(true);
+ ar_.CommitColumn(_sizeCol);
+ //_sizeCol.FixSize(false);
+ }
+
+ ar_.CommitColumn(_memoCol);
+
+ // need a way to find out when the data has been committed (on 2nd pass)
+ // both _sizeCol and _memoCol will be clean again when it has
+ // but be careful because dirty flag is only useful if size is nonzero
+ if (_recalc && !ar_.Serializing())
+ _recalc = _sizeCol.ColSize() > 0 && _sizeCol.IsDirty() ||
+ _memoCol.ColSize() > 0 && _memoCol.IsDirty();
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_FormatS : public c4_FormatB
+{
+public:
+ c4_FormatS (const c4_Property& prop_, c4_HandlerSeq& seq_);
+
+ virtual int ItemSize(int index_);
+ virtual const void* Get(int index_, int& length_);
+ virtual void Set(int index_, const c4_Bytes& buf_);
+
+ virtual void Insert(int index_, const c4_Bytes& buf_, int count_);
+
+ static int DoCompare(const c4_Bytes& b1_, const c4_Bytes& b2_);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_FormatS::c4_FormatS (const c4_Property& prop_, c4_HandlerSeq& seq_)
+ : c4_FormatB (prop_, seq_)
+{
+}
+
+int c4_FormatS::ItemSize(int index_)
+{
+ int n = c4_FormatB::ItemSize(index_) - 1;
+ return n >= 0 ? n : 0;
+}
+
+const void* c4_FormatS::Get(int index_, int& length_)
+{
+ const void* ptr = GetOne(index_, length_);
+
+ if (length_ == 0) {
+ length_ = 1;
+ ptr = "";
+ }
+
+ d4_assert(((const char*) ptr)[length_-1] == 0);
+ return ptr;
+}
+
+void c4_FormatS::Set(int index_, const c4_Bytes& buf_)
+{
+ int m = buf_.Size();
+ if (--m >= 0) {
+ d4_assert(buf_.Contents()[m] == 0);
+ if (m == 0) {
+ SetOne(index_, c4_Bytes ()); // don't store data for empty strings
+ return;
+ }
+ }
+
+ SetOne(index_, buf_);
+}
+
+int c4_FormatS::DoCompare(const c4_Bytes& b1_, const c4_Bytes& b2_)
+{
+ c4_String v1 ((const char*) b1_.Contents(), b1_.Size());
+ c4_String v2 ((const char*) b2_.Contents(), b2_.Size());
+
+ return v1.CompareNoCase(v2);
+}
+
+void c4_FormatS::Insert(int index_, const c4_Bytes& buf_, int count_)
+{
+ d4_assert(count_ > 0);
+
+ int m = buf_.Size();
+ if (--m >= 0) {
+ d4_assert(buf_.Contents()[m] == 0);
+ if (m == 0) {
+ c4_FormatB::Insert(index_, c4_Bytes (), count_);
+ return;
+ }
+ }
+
+ c4_FormatB::Insert(index_, buf_, count_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_FormatV : public c4_FormatHandler
+{
+public:
+ c4_FormatV (const c4_Property& prop_, c4_HandlerSeq& seq_);
+ virtual ~c4_FormatV ();
+
+ virtual void Define(int rows_, const t4_byte** ptr_);
+ virtual void OldDefine(char type_, c4_Persist&);
+ virtual void Commit(c4_SaveContext& ar_);
+
+ virtual void FlipBytes();
+
+ virtual int ItemSize(int index_);
+ virtual const void* Get(int index_, int& length_);
+ virtual void Set(int index_, const c4_Bytes& buf_);
+
+ virtual void Insert(int index_, const c4_Bytes& buf_, int count_);
+ virtual void Remove(int index_, int count_);
+
+ virtual void Unmapped();
+ virtual bool HasSubview(int index_);
+
+ static int DoCompare(const c4_Bytes& b1_, const c4_Bytes& b2_);
+
+private:
+ c4_HandlerSeq& At(int index_);
+ void Replace(int index_, c4_HandlerSeq* seq_);
+ void SetupAllSubviews();
+ void ForgetSubview(int index_);
+
+ c4_Column _data;
+ c4_PtrArray _subSeqs;
+ bool _inited;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_FormatV::c4_FormatV (const c4_Property& prop_, c4_HandlerSeq& seq_)
+ : c4_FormatHandler (prop_, seq_), _data (seq_.Persist()), _inited (false)
+{
+}
+
+c4_FormatV::~c4_FormatV ()
+{
+ for (int i = 0; i < _subSeqs.GetSize(); ++i)
+ ForgetSubview(i);
+}
+
+c4_HandlerSeq& c4_FormatV::At(int index_)
+{
+ d4_assert(_inited);
+
+ c4_HandlerSeq*& hs = (c4_HandlerSeq*&) _subSeqs.ElementAt(index_);
+ if (hs == 0) {
+ hs = d4_new c4_HandlerSeq (Owner(), this);
+ hs->IncRef();
+ }
+
+ return *hs;
+}
+
+void c4_FormatV::SetupAllSubviews()
+{
+ d4_assert(!_inited);
+ _inited = true;
+
+ if (_data.ColSize() > 0) {
+ c4_Bytes temp;
+ _data.FetchBytes(0, _data.ColSize(), temp, true);
+ const t4_byte* ptr = temp.Contents();
+
+ for (int r = 0; r < _subSeqs.GetSize(); ++r) {
+ // don't materialize subview if it is empty
+ // duplicates code which is in c4_HandlerSeq::Prepare
+ const t4_byte* p2 = ptr;
+ d4_dbgdef(t4_i32 sias =)
+ c4_Column::PullValue(p2);
+ d4_assert(sias == 0); // not yet
+
+ if (c4_Column::PullValue(p2) > 0)
+ At(r).Prepare(&ptr, false);
+ else
+ ptr = p2;
+ }
+
+ d4_assert(ptr == temp.Contents() + temp.Size());
+ }
+}
+
+void c4_FormatV::Define(int rows_, const t4_byte** ptr_)
+{
+ if (_inited) {
+ // big oops: a root handler already contains data
+
+ for (int i = 0; i < _subSeqs.GetSize(); ++i)
+ ForgetSubview(i);
+
+ _inited = false;
+ }
+
+ _subSeqs.SetSize(rows_);
+ if (ptr_ != 0)
+ _data.PullLocation(*ptr_);
+}
+
+void c4_FormatV::OldDefine(char, c4_Persist& pers_)
+{
+ int rows = Owner().NumRows();
+ _subSeqs.SetSize(rows);
+
+ for (int i = 0; i < rows; ++i) {
+ int n = pers_.FetchOldValue();
+ if (n) {
+ // 14-11-2000: do not create again (this causes a mem leak)
+ // 04-12-2000: but do create if absent (fixes occasional crash)
+ c4_HandlerSeq* hs = (c4_HandlerSeq*) _subSeqs.GetAt(i);
+ if (hs == 0) {
+ hs = d4_new c4_HandlerSeq (Owner(), this);
+ _subSeqs.SetAt(i, hs);
+ hs->IncRef();
+ }
+ hs->SetNumRows(n);
+ hs->OldPrepare();
+ }
+ }
+}
+
+void c4_FormatV::FlipBytes()
+{
+ if (!_inited)
+ SetupAllSubviews();
+
+ for (int i = 0; i < _subSeqs.GetSize(); ++i)
+ At(i).FlipAllBytes();
+}
+
+int c4_FormatV::ItemSize(int index_)
+{
+ if (!_inited)
+ SetupAllSubviews();
+
+ // 06-02-2002: avoid creating empty subview
+ c4_HandlerSeq* hs = (c4_HandlerSeq*&) _subSeqs.ElementAt(index_);
+ return hs == 0 ? 0 : hs->NumRows();
+}
+
+const void* c4_FormatV::Get(int index_, int& length_)
+{
+ if (!_inited)
+ SetupAllSubviews();
+
+ At(index_); // forces existence of a real entry
+ c4_HandlerSeq*& e = (c4_HandlerSeq*&) _subSeqs.ElementAt(index_);
+
+ length_ = sizeof (c4_HandlerSeq**);
+ return &e;
+}
+
+void c4_FormatV::Set(int index_, const c4_Bytes& buf_)
+{
+ d4_assert(buf_.Size() == sizeof (c4_Sequence*));
+
+ if (!_inited)
+ SetupAllSubviews();
+
+ c4_HandlerSeq* value = *(c4_HandlerSeq* const*) buf_.Contents();
+
+ if (value != & At(index_))
+ Replace(index_, value);
+}
+
+void c4_FormatV::Replace(int index_, c4_HandlerSeq* seq_)
+{
+ if (!_inited)
+ SetupAllSubviews();
+
+ c4_HandlerSeq*& curr = (c4_HandlerSeq*&) _subSeqs.ElementAt(index_);
+ if (seq_ == curr)
+ return;
+
+ if (curr != 0) {
+ d4_assert(&curr->Parent() == &Owner());
+ curr->DetachFromParent();
+ curr->DetachFromStorage(true);
+
+ curr->DecRef();
+ curr = 0;
+ }
+
+ if (seq_) {
+ int n = seq_->NumRows();
+
+ c4_HandlerSeq& t = At(index_);
+ d4_assert(t.NumRows() == 0);
+
+ t.Resize(n);
+
+ c4_Bytes data;
+
+ // this dest seq has only the persistent handlers
+ // and maybe in a different order
+ // create any others we need as temporary properties
+ for (int i = 0; i < seq_->NumHandlers(); ++i) {
+ c4_Handler& h1 = seq_->NthHandler(i);
+
+ int j = t.PropIndex(h1.Property());
+ d4_assert(j >= 0);
+
+ c4_Handler& h2 = t.NthHandler(j);
+
+ for (int k = 0; k < n; ++k)
+ if (seq_->Get(k, h1.PropId(), data))
+ h2.Set(k, data);
+ }
+ }
+}
+
+int c4_FormatV::DoCompare(const c4_Bytes& b1_, const c4_Bytes& b2_)
+{
+ d4_assert(b1_.Size() == sizeof (c4_Sequence*));
+ d4_assert(b2_.Size() == sizeof (c4_Sequence*));
+
+ c4_View v1 = *(c4_Sequence* const*) b1_.Contents();
+ c4_View v2 = *(c4_Sequence* const*) b2_.Contents();
+
+ return v1.Compare(v2);
+}
+
+void c4_FormatV::Insert(int index_, const c4_Bytes& buf_, int count_)
+{
+ d4_assert(buf_.Size() == sizeof (c4_Sequence*));
+ d4_assert(count_ > 0);
+
+ // can only insert an empty entry!
+ d4_assert(*(c4_Sequence* const*) buf_.Contents() == 0);
+
+ if (!_inited)
+ SetupAllSubviews();
+
+ _subSeqs.InsertAt(index_, 0, count_);
+ _data.SetBuffer(0); // 2004-01-18 force dirty
+}
+
+void c4_FormatV::Remove(int index_, int count_)
+{
+ d4_assert(count_ > 0);
+
+ if (!_inited)
+ SetupAllSubviews();
+
+ for (int i = 0; i < count_; ++i)
+ ForgetSubview(index_ + i);
+
+ _subSeqs.RemoveAt(index_, count_);
+ _data.SetBuffer(0); // 2004-01-18 force dirty
+}
+
+void c4_FormatV::Unmapped()
+{
+ if (_inited)
+ for (int i = 0; i < _subSeqs.GetSize(); ++i)
+ if (HasSubview(i)) {
+ c4_HandlerSeq& hs = At(i);
+ hs.UnmappedAll();
+ if (hs.NumRefs() == 1 && hs.NumRows() == 0)
+ ForgetSubview(i);
+ }
+
+ _data.ReleaseAllSegments();
+}
+
+bool c4_FormatV::HasSubview(int index_)
+{
+ if (!_inited)
+ SetupAllSubviews();
+
+ return _subSeqs.ElementAt(index_) != 0;
+}
+
+void c4_FormatV::ForgetSubview(int index_)
+{
+ c4_HandlerSeq*& seq = (c4_HandlerSeq*&) _subSeqs.ElementAt(index_);
+ if (seq != 0) {
+ d4_assert(&seq->Parent() == &Owner());
+ seq->DetachFromParent();
+ seq->DetachFromStorage(true);
+ seq->UnmappedAll();
+ seq->DecRef();
+ seq = 0;
+ }
+}
+
+void c4_FormatV::Commit(c4_SaveContext& ar_)
+{
+ if (!_inited)
+ SetupAllSubviews();
+
+ int rows = _subSeqs.GetSize();
+ d4_assert(rows > 0);
+
+ c4_Column temp (0);
+ c4_Column* saved = ar_.SetWalkBuffer(&temp);
+
+ for (int r = 0; r < rows; ++r)
+ if (HasSubview(r)) {
+ c4_HandlerSeq& hs = At(r);
+ ar_.CommitSequence(hs, false);
+ if (hs.NumRefs() == 1 && hs.NumRows() == 0)
+ ForgetSubview(r);
+ } else {
+ ar_.StoreValue(0); // sias
+ ar_.StoreValue(0); // row count
+ }
+
+ ar_.SetWalkBuffer(saved);
+
+ c4_Bytes buf;
+ temp.FetchBytes(0, temp.ColSize(), buf, true);
+
+ bool changed = temp.ColSize() != _data.ColSize();
+
+ if (!changed) {
+ c4_Bytes buf2;
+ _data.FetchBytes(0, _data.ColSize(), buf2, true);
+ changed = buf != buf2;
+ }
+
+ if (changed) {
+ _data.SetBuffer(buf.Size());
+ _data.StoreBytes(0, buf);
+ }
+
+ ar_.CommitColumn(_data);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_Handler* f4_CreateFormat(const c4_Property& prop_, c4_HandlerSeq& seq_)
+{
+ switch (prop_.Type()) {
+ case 'I': return d4_new c4_FormatX (prop_, seq_);
+#if !q4_TINY
+ case 'L': return d4_new c4_FormatL (prop_, seq_);
+ case 'F': return d4_new c4_FormatF (prop_, seq_);
+ case 'D': return d4_new c4_FormatD (prop_, seq_);
+#endif
+ case 'B': return d4_new c4_FormatB (prop_, seq_);
+ case 'S': return d4_new c4_FormatS (prop_, seq_);
+ case 'V': return d4_new c4_FormatV (prop_, seq_);
+ }
+
+ d4_assert(0);
+ // 2004-01-16 turn bad definition type into an int property to avoid crash
+ return d4_new c4_FormatX (c4_IntProp (prop_.Name()), seq_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+int f4_ClearFormat(char type_)
+{
+ switch (type_) {
+ case 'I': return sizeof (t4_i32);
+#if !q4_TINY
+ case 'L': return sizeof (t4_i64);
+ case 'F': return sizeof (float);
+ case 'D': return sizeof (double);
+#endif
+ case 'S': return 1;
+ case 'V': return sizeof (c4_Sequence*);
+ }
+
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+int f4_CompareFormat(char type_, const c4_Bytes& b1_, const c4_Bytes& b2_)
+{
+ switch (type_) {
+ case 'I': return c4_FormatX::DoCompare(b1_, b2_);
+#if !q4_TINY
+ case 'L': return c4_FormatL::DoCompare(b1_, b2_);
+ case 'F': return c4_FormatF::DoCompare(b1_, b2_);
+ case 'D': return c4_FormatD::DoCompare(b1_, b2_);
+#endif
+ case 'B': return c4_FormatB::DoCompare(b1_, b2_);
+ case 'S': return c4_FormatS::DoCompare(b1_, b2_);
+ case 'V': return c4_FormatV::DoCompare(b1_, b2_);
+ }
+
+ d4_assert(0);
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/akregator/src/mk4storage/metakit/src/format.h b/akregator/src/mk4storage/metakit/src/format.h
new file mode 100644
index 000000000..721e55484
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/src/format.h
@@ -0,0 +1,23 @@
+// format.h --
+// $Id$
+// This is part of Metakit, see http://www.equi4.com/metakit/
+
+/** @file
+ * Encapsulation of all format handlers
+ */
+
+#ifndef __FORMAT_H__
+#define __FORMAT_H__
+
+/////////////////////////////////////////////////////////////////////////////
+// Declarations in this file
+
+ class c4_Handler; // not defined here
+
+ extern c4_Handler* f4_CreateFormat(const c4_Property&, c4_HandlerSeq&);
+ extern int f4_ClearFormat(char);
+ extern int f4_CompareFormat(char, const c4_Bytes&, const c4_Bytes&);
+
+/////////////////////////////////////////////////////////////////////////////
+
+#endif
diff --git a/akregator/src/mk4storage/metakit/src/gnuc.h b/akregator/src/mk4storage/metakit/src/gnuc.h
new file mode 100644
index 000000000..da112ac6a
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/src/gnuc.h
@@ -0,0 +1,13 @@
+// gnuc.h --
+// $Id$
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit/
+
+/** @file
+ * Configuration header for GNU C++
+ */
+
+#define q4_GNUC 1
+
+#if !defined (q4_BOOL)
+#define q4_BOOL 1
+#endif
diff --git a/akregator/src/mk4storage/metakit/src/handler.cpp b/akregator/src/mk4storage/metakit/src/handler.cpp
new file mode 100644
index 000000000..6c68c5c3f
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/src/handler.cpp
@@ -0,0 +1,500 @@
+// handler.cpp --
+// $Id$
+// This is part of Metakit, see http://www.equi4.com/metakit/
+
+/** @file
+ * Handlers store data in column-wise format
+ */
+
+#include "header.h"
+#include "handler.h"
+#include "format.h"
+#include "field.h"
+#include "column.h"
+#include "persist.h"
+
+#if !q4_INLINE
+#include "handler.inl"
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_Handler
+
+void c4_Handler::ClearBytes(c4_Bytes& buf_) const
+{
+ static char zeros[8];
+
+ int n = f4_ClearFormat(Property().Type());
+ d4_assert(n <= sizeof zeros);
+
+ buf_ = c4_Bytes (zeros, n);
+}
+
+int c4_Handler::Compare(int index_, const c4_Bytes& buf_)
+{
+ // create a copy for small data, since ints use a common _item buffer
+ c4_Bytes copy (buf_.Contents(), buf_.Size(), buf_.Size() <= 8);
+
+ c4_Bytes data;
+ GetBytes(index_, data);
+
+ return f4_CompareFormat(Property().Type(), data, copy);
+}
+
+void c4_Handler::Commit(c4_SaveContext&)
+{
+ d4_assert(0);
+}
+
+void c4_Handler::OldDefine(char, c4_Persist&)
+{
+ d4_assert(0);
+}
+
+ // this is how the old "Get" was, keep it until no longer needed
+void c4_Handler::GetBytes(int index_, c4_Bytes& buf_, bool copySmall_)
+{
+ int n;
+ const void* p = Get(index_, n);
+ buf_ = c4_Bytes (p, n, copySmall_ && n <= 8);
+}
+
+void c4_Handler::Move(int from_, int to_)
+{
+ if (from_ != to_) {
+ c4_Bytes data;
+ GetBytes(from_, data);
+
+ Remove(from_, 1);
+
+ if (to_ > from_)
+ --to_;
+
+ Insert(to_, data, 1);
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_HandlerSeq
+
+c4_HandlerSeq::c4_HandlerSeq (c4_Persist* persist_)
+ : _persist (persist_), _field (0), _parent (0), _numRows (0)
+{
+}
+
+c4_HandlerSeq::c4_HandlerSeq (c4_HandlerSeq& owner_, c4_Handler* handler_)
+ : _persist (owner_.Persist()), _field (owner_.FindField(handler_)),
+ _parent (&owner_), _numRows (0)
+{
+ for (int i = 0; i < NumFields(); ++i) {
+ c4_Field& field = Field(i);
+ c4_Property prop (field.Type(), field.Name());
+
+ d4_dbgdef(int n =)
+ AddHandler(f4_CreateFormat(prop, *this));
+ d4_assert(n == i);
+ }
+}
+
+c4_HandlerSeq::~c4_HandlerSeq ()
+{
+ const bool rootLevel = _parent == this;
+ c4_Persist* pers = _persist;
+
+ if (rootLevel && pers != 0)
+ pers->DoAutoCommit();
+
+ DetachFromParent();
+ DetachFromStorage(true);
+
+ for (int i = 0; i < NumHandlers(); ++i)
+ delete & NthHandler(i);
+ _handlers.SetSize(0);
+
+ ClearCache();
+
+ if (rootLevel) {
+ delete _field;
+
+ d4_assert(pers != 0);
+ delete pers;
+ }
+}
+
+c4_Persist* c4_HandlerSeq::Persist() const
+{
+ return _persist;
+}
+
+void c4_HandlerSeq::DefineRoot()
+{
+ d4_assert(_field == 0);
+ d4_assert(_parent == 0);
+
+ SetNumRows(1);
+
+ const char* desc = "[]";
+ _field = d4_new c4_Field (desc);
+ d4_assert(!*desc);
+
+ _parent = this;
+}
+
+c4_Handler* c4_HandlerSeq::CreateHandler(const c4_Property& prop_)
+{
+ return f4_CreateFormat(prop_, *this);
+}
+
+c4_Field& c4_HandlerSeq::Definition() const
+{
+ d4_assert(_field != 0);
+
+ return *_field;
+}
+
+void c4_HandlerSeq::DetachFromParent()
+{
+ if (_field != 0) {
+ const char* desc = "[]";
+ c4_Field f (desc);
+ d4_assert(!*desc);
+ Restructure(f, false);
+ _field = 0;
+ }
+
+ _parent = 0;
+}
+
+void c4_HandlerSeq::DetachFromStorage(bool full_)
+{
+ if (_persist != 0) {
+ int limit = full_ ? 0 : NumFields();
+
+ // get rid of all handlers which might do I/O
+ for (int c = NumHandlers(); --c >= 0; ) {
+ c4_Handler& h = NthHandler(c);
+
+ // all nested fields are detached recursively
+ if (IsNested(c))
+ for (int r = 0; r < NumRows(); ++r)
+ if (h.HasSubview(r))
+ SubEntry(c, r).DetachFromStorage(full_);
+
+ if (c >= limit) {
+ if (h.IsPersistent()) {
+ delete &h;
+ _handlers.RemoveAt(c);
+ ClearCache();
+ }
+ }
+ }
+
+ if (full_) {
+ //UnmappedAll();
+ _persist = 0;
+ }
+ }
+}
+
+void c4_HandlerSeq::DetermineSpaceUsage()
+{
+ for (int c = 0; c < NumFields(); ++c)
+ if (IsNested(c)) {
+ c4_Handler& h = NthHandler(c);
+ for (int r = 0; r < NumRows(); ++r)
+ if (h.HasSubview(r))
+ SubEntry(c, r).DetermineSpaceUsage();
+ }
+}
+
+void c4_HandlerSeq::SetNumRows(int numRows_)
+{
+ d4_assert(_numRows >= 0);
+
+ _numRows = numRows_;
+}
+
+int c4_HandlerSeq::AddHandler(c4_Handler* handler_)
+{
+ d4_assert(handler_ != 0);
+
+ return _handlers.Add(handler_);
+}
+
+const char* c4_HandlerSeq::Description()
+{
+ // 19-01-2003: avoid too dense code, since Sun CC seems to choke on it
+ //return _field != 0 ? UseTempBuffer(Definition().DescribeSubFields()) : 0;
+ if (_field == 0)
+ return 0;
+ c4_String s = _field->DescribeSubFields();
+ return UseTempBuffer(s);
+}
+
+void c4_HandlerSeq::Restructure(c4_Field& field_, bool remove_)
+{
+ //d4_assert(_field != 0);
+
+ // all nested fields must be set up, before we shuffle them around
+ for (int k = 0; k < NumHandlers(); ++k)
+ if (IsNested(k)) {
+ c4_Handler& h = NthHandler(k);
+ for (int n = 0; n < NumRows(); ++n)
+ if (h.HasSubview(n))
+ SubEntry(k, n);
+ }
+
+ for (int i = 0; i < field_.NumSubFields(); ++i) {
+ c4_Field& nf = field_.SubField(i);
+ c4_Property prop (nf.Type(), nf.Name());
+
+ int n = PropIndex(prop.GetId());
+ if (n == i)
+ continue;
+
+ if (n < 0) {
+ _handlers.InsertAt(i, f4_CreateFormat(prop, *this));
+ NthHandler(i).Define(NumRows(), 0);
+ } else {
+ // move the handler to the front
+ d4_assert(n > i);
+ _handlers.InsertAt(i, _handlers.GetAt(n));
+ _handlers.RemoveAt(++n);
+ }
+
+ ClearCache(); // we mess with the order of handler, keep clearing it
+
+ d4_assert(PropIndex(prop.GetId()) == i);
+ }
+
+ c4_Field* ofld = _field;
+ // special case if we're "restructuring a view out of persistence", see below
+
+ _field = remove_ ? 0 : &field_;
+
+ // let handler do additional init once all have been prepared
+ //for (int n = 0; n < NumHandlers(); ++n)
+ // NthHandler(n).Define(NumRows(), 0);
+
+ const char* desc = "[]";
+ c4_Field temp (desc);
+
+ // all nested fields are restructured recursively
+ for (int j = 0; j < NumHandlers(); ++j)
+ if (IsNested(j)) {
+ c4_Handler& h = NthHandler(j);
+ for (int n = 0; n < NumRows(); ++n)
+ if (h.HasSubview(n)) {
+ c4_HandlerSeq& seq = SubEntry(j, n);
+ if (j < NumFields())
+ seq.Restructure(field_.SubField(j), false);
+ else if (seq._field != 0)
+ seq.Restructure(temp, true);
+ }
+ }
+
+ if (_parent == this)
+ delete ofld; // the root table owns its field structure tree
+}
+
+int c4_HandlerSeq::NumFields() const
+{
+ return _field != 0 ? _field->NumSubFields() : 0;
+}
+
+char c4_HandlerSeq::ColumnType(int index_) const
+{
+ return NthHandler(index_).Property().Type();
+}
+
+bool c4_HandlerSeq::IsNested(int index_) const
+{
+ return ColumnType(index_) == 'V';
+}
+
+c4_Field& c4_HandlerSeq::Field(int index_) const
+{
+ d4_assert(_field != 0);
+
+ return _field->SubField(index_);
+}
+
+void c4_HandlerSeq::Prepare(const t4_byte** ptr_, bool selfDesc_)
+{
+ if (ptr_ != 0) {
+ d4_dbgdef(t4_i32 sias =)
+ c4_Column::PullValue(*ptr_);
+ d4_assert(sias == 0); // not yet
+
+ if (selfDesc_) {
+ t4_i32 n = c4_Column::PullValue(*ptr_);
+ if (n > 0) {
+ c4_String s = "[" + c4_String ((const char*) *ptr_, n) + "]";
+ const char* desc = s;
+
+ c4_Field* f = d4_new c4_Field (desc);
+ d4_assert(!*desc);
+
+ Restructure(*f, false);
+ *ptr_ += n;
+ }
+ }
+
+ int rows = (int) c4_Column::PullValue(*ptr_);
+ if (rows > 0) {
+ SetNumRows(rows);
+
+ for (int i = 0; i < NumFields(); ++i)
+ NthHandler(i).Define(rows, ptr_);
+ }
+ }
+}
+
+void c4_HandlerSeq::OldPrepare()
+{
+ d4_assert(_persist != 0);
+
+ for (int i = 0; i < NumFields(); ++i) {
+ char origType = _field->SubField(i).OrigType();
+ NthHandler(i).OldDefine(origType, *_persist);
+ }
+}
+
+void c4_HandlerSeq::FlipAllBytes()
+{
+ for (int i = 0; i < NumHandlers(); ++i) {
+ c4_Handler& h = NthHandler(i);
+ h.FlipBytes();
+ }
+}
+
+ // New 19990903: swap rows in tables without touching the memo fields
+ // or subviews on disk. This is used by the new c4_View::RelocateRows.
+
+void c4_HandlerSeq::ExchangeEntries(int srcPos_, c4_HandlerSeq& dst_, int dstPos_)
+{
+ d4_assert(NumHandlers() == dst_.NumHandlers());
+
+ c4_Bytes t1, t2;
+
+ for (int col = 0; col < NumHandlers(); ++col)
+ {
+ if (IsNested(col))
+ {
+ d4_assert(dst_.IsNested(col));
+
+ int n;
+ c4_HandlerSeq** e1 = (c4_HandlerSeq**) NthHandler(col).Get(srcPos_, n);
+ c4_HandlerSeq** e2 = (c4_HandlerSeq**) dst_.NthHandler(col).Get(dstPos_, n);
+ d4_assert(*e1 != 0 && *e2 != 0);
+
+ // swap the two entries
+ c4_HandlerSeq* e = *e1;
+ *e1 = *e2;
+ *e2 = e;
+
+ // shorthand, *after* the swap
+ c4_HandlerSeq& t1 = SubEntry(col, srcPos_);
+ c4_HandlerSeq& t2 = dst_.SubEntry(col, dstPos_);
+
+ // adjust the parents
+ t1._parent = this;
+ t2._parent = &dst_;
+
+ // reattach the proper field structures
+ t1.Restructure(Field(col), false);
+ t2.Restructure(dst_.Field(col), false);
+ }
+ else
+ {
+ d4_assert(ColumnType(col) == dst_.ColumnType(col));
+
+ c4_Handler& h1 = NthHandler(col);
+ c4_Handler& h2 = dst_.NthHandler(col);
+
+#if 0 // memo's are 'B' now, but tricky to deal with, so copy them for now
+ if (ColumnType(col) == 'M')
+ {
+ c4_Column* c1 = h1.GetNthMemoCol(srcPos_, true);
+ c4_Column* c2 = h2.GetNthMemoCol(dstPos_, true);
+
+ t4_i32 p1 = c1 ? c1->Position() : 0;
+ t4_i32 p2 = c2 ? c2->Position() : 0;
+
+ t4_i32 s1 = c1 ? c1->ColSize() : 0;
+ t4_i32 s2 = c2 ? c2->ColSize() : 0;
+
+ d4_assert(false); // broken
+ //!h1.SetNthMemoPos(srcPos_, p2, s2, c2);
+ //!h2.SetNthMemoPos(dstPos_, p1, s1, c1);
+ }
+#endif
+ // 10-4-2002: Need to use copies in case either item points into
+ // memory that could move, or if access re-uses a shared buffer.
+ // The special cases are sufficiently tricky that it's NOT being
+ // optimized for now (temp bufs, mmap ptrs, c4_Bytes buffering).
+
+ int n1, n2;
+ const void* p1 = h1.Get(srcPos_, n1);
+ const void* p2 = h2.Get(dstPos_, n2);
+
+ c4_Bytes t1 (p1, n1, true);
+ c4_Bytes t2 (p2, n2, true);
+
+ h1.Set(srcPos_, t2);
+ h2.Set(dstPos_, t1);
+ }
+ }
+}
+
+c4_HandlerSeq& c4_HandlerSeq::SubEntry(int col_, int row_) const
+{
+ d4_assert(IsNested(col_));
+
+ c4_Bytes temp;
+ NthHandler(col_).GetBytes(row_, temp);
+
+ d4_assert(temp.Size() == sizeof (c4_HandlerSeq**));
+ c4_HandlerSeq** p = (c4_HandlerSeq**) temp.Contents(); // loses const
+
+ d4_assert(p != 0 && *p != 0);
+
+ return **p;
+}
+
+c4_Field* c4_HandlerSeq::FindField(const c4_Handler* handler_)
+{
+ for (int i = 0; i < NumFields(); ++i)
+ if (handler_ == &NthHandler(i))
+ return &Field(i);
+ return 0;
+}
+
+void c4_HandlerSeq::UnmappedAll()
+{
+ for (int i = 0; i < NumFields(); ++i)
+ NthHandler(i).Unmapped();
+}
+
+ // construct meta view from a pre-parsed field tree structure
+ // this will one day be converted to directly parse the description string
+void c4_HandlerSeq::BuildMeta(int parent_, int colnum_, c4_View& meta_,
+ const c4_Field& field_)
+{
+ c4_IntProp pP ("P"), pC ("C");
+ c4_ViewProp pF ("F");
+ c4_StringProp pN ("N"), pT ("T");
+
+ int n = meta_.Add(pP [parent_] + pC [colnum_]);
+ c4_View fields = pF (meta_[n]);
+
+ for (int i = 0; i < field_.NumSubFields(); ++i) {
+ const c4_Field& f = field_.SubField(i);
+ char type = f.Type();
+ fields.Add(pN [f.Name()] + pT [c4_String (&type, 1)]);
+ if (type == 'V')
+ BuildMeta(n, i, meta_, f);
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/akregator/src/mk4storage/metakit/src/handler.h b/akregator/src/mk4storage/metakit/src/handler.h
new file mode 100644
index 000000000..6003f625d
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/src/handler.h
@@ -0,0 +1,150 @@
+// handler.h --
+// $Id$
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit/
+
+/** @file
+ * Definition of the main handler classes
+ */
+
+#ifndef __HANDLER_H__
+#define __HANDLER_H__
+
+/////////////////////////////////////////////////////////////////////////////
+// Declarations in this file
+
+ class c4_Handler; // data representation handler
+
+// class c4_Sequence;
+ class c4_HandlerSeq; // a sequence built from handlers
+
+ class c4_Column; // not defined here
+ class c4_Field; // not defined here
+ class c4_Persist; // not defined here
+ class c4_SaveContext; // not defined here
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_Handler
+{
+ c4_Property _property;
+
+public:
+ c4_Handler (const c4_Property& _prop);
+ //: Constructor (this is an abstract base class).
+ virtual ~c4_Handler ();
+
+ virtual void Define(int, const t4_byte**);
+ //: Called when the corresponding table has been fully defined.
+ virtual void FlipBytes();
+ //: Called to reverse the internal byte order of foreign data.
+ virtual void Commit(c4_SaveContext& ar_);
+ //: Commit the associated column(s) to file.
+ virtual void OldDefine(char, c4_Persist&);
+
+ const c4_Property& Property() const;
+ //: Returns the property associated with this handler.
+ int PropId() const;
+ //: Returns the id of the property associated with this handler.
+
+ void ClearBytes(c4_Bytes& buf_) const;
+ //: Returns the default value for items of this type.
+
+ virtual int ItemSize(int index_) = 0;
+ //: Return width of specified data item.
+ void GetBytes(int index_, c4_Bytes& buf_, bool copySmall_ =false);
+ //: Used for backward compatibility, should probably be replaced.
+ virtual const void* Get(int index_, int& length_) = 0;
+ //: Retrieves the data item at the specified index.
+ virtual void Set(int index_, const c4_Bytes& buf_) = 0;
+ //: Stores a new data item at the specified index.
+
+ int Compare(int index_, const c4_Bytes& buf_);
+ //: Compares an entry with a specified data item.
+
+ virtual void Insert(int index_, const c4_Bytes& buf_, int count_) = 0;
+ //: Inserts 1 or more data items at the specified index.
+ virtual void Remove(int index_, int count_) = 0;
+ //: Removes 1 or more data items at the specified index.
+ void Move(int from_, int to_);
+ //: Move a data item to another position.
+
+ virtual c4_Column* GetNthMemoCol(int index_, bool alloc_ =false);
+ //: Special access to underlying data of memo entries
+
+ virtual bool IsPersistent() const;
+ //: True if this handler might do I/O to satisfy fetches
+
+ virtual void Unmapped();
+ //: Make sure this handler stops using file mappings
+
+ virtual bool HasSubview(int index_);
+ //: True if this subview has materialized into an object
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_HandlerSeq : public c4_Sequence
+{
+ c4_PtrArray _handlers;
+ c4_Persist* _persist;
+ c4_Field* _field;
+ c4_HandlerSeq* _parent;
+ int _numRows;
+
+public:
+ c4_HandlerSeq (c4_Persist*);
+ c4_HandlerSeq (c4_HandlerSeq& owner_, c4_Handler* handler_);
+
+ virtual int NumRows() const;
+ virtual void SetNumRows(int);
+
+ virtual int NumHandlers() const;
+ virtual c4_Handler& NthHandler(int) const;
+ virtual const c4_Sequence* HandlerContext(int) const;
+ virtual int AddHandler(c4_Handler*);
+
+ void DefineRoot();
+ void Restructure(c4_Field&, bool remove_);
+ void DetachFromParent();
+ void DetachFromStorage(bool full_);
+ void DetermineSpaceUsage();
+
+ c4_Field& Definition() const;
+ const char* Description();
+ c4_HandlerSeq& Parent() const;
+ virtual c4_Persist* Persist() const;
+
+ c4_Field& Field(int) const;
+ int NumFields() const;
+ char ColumnType(int index_) const;
+ bool IsNested(int) const;
+
+ void Prepare(const t4_byte** ptr_, bool selfDesc_);
+ void OldPrepare();
+
+ void FlipAllBytes();
+ void ExchangeEntries(int srcPos_, c4_HandlerSeq& dst_, int dstPos_);
+
+ c4_HandlerSeq& SubEntry(int, int) const;
+
+ c4_Field* FindField(const c4_Handler* handler_);
+
+ void UnmappedAll();
+
+ static void BuildMeta(int, int, c4_View&, const c4_Field&);
+
+protected:
+ virtual c4_Handler* CreateHandler(const c4_Property&);
+
+ virtual ~c4_HandlerSeq ();
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+#if q4_INLINE
+#include "handler.inl"
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+
+#endif
diff --git a/akregator/src/mk4storage/metakit/src/handler.inl b/akregator/src/mk4storage/metakit/src/handler.inl
new file mode 100644
index 000000000..75321f9c7
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/src/handler.inl
@@ -0,0 +1,90 @@
+// handler.inl --
+// $Id$
+// This is part of Metakit, see http://www.equi4.com/metakit/
+
+/** @file
+ * Inlined members of the handler classes
+ */
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_Handler
+
+d4_inline c4_Handler::c4_Handler (const c4_Property& prop_)
+ : _property (prop_)
+{
+}
+
+d4_inline c4_Handler::~c4_Handler ()
+{
+}
+
+d4_inline void c4_Handler::Define(int, const t4_byte**)
+{
+}
+
+d4_inline void c4_Handler::FlipBytes()
+{
+}
+
+d4_inline const c4_Property& c4_Handler::Property() const
+{
+ return _property;
+}
+
+d4_inline int c4_Handler::PropId() const
+{
+ return _property.GetId();
+}
+
+d4_inline c4_Column* c4_Handler::GetNthMemoCol(int, bool alloc_)
+{
+ return 0;
+}
+
+d4_inline bool c4_Handler::IsPersistent() const
+{
+ return false;
+}
+
+d4_inline void c4_Handler::Unmapped()
+{
+}
+
+d4_inline bool c4_Handler::HasSubview(int)
+{
+ return false;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_HandlerSeq
+
+d4_inline int c4_HandlerSeq::NumRows() const
+{
+ d4_assert(_numRows >= 0);
+
+ return _numRows;
+}
+
+d4_inline int c4_HandlerSeq::NumHandlers() const
+{
+ return _handlers.GetSize();
+}
+
+d4_inline c4_Handler& c4_HandlerSeq::NthHandler(int index_) const
+{
+ d4_assert(_handlers.GetAt(index_) != 0);
+
+ return *(c4_Handler*) _handlers.GetAt(index_);
+}
+
+d4_inline const c4_Sequence* c4_HandlerSeq::HandlerContext(int) const
+{
+ return this;
+}
+
+d4_inline c4_HandlerSeq& c4_HandlerSeq::Parent() const
+{
+ return *_parent;
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/akregator/src/mk4storage/metakit/src/header.h b/akregator/src/mk4storage/metakit/src/header.h
new file mode 100644
index 000000000..2f8648b8f
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/src/header.h
@@ -0,0 +1,215 @@
+// header.h --
+// $Id$
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit/
+
+/** @file
+ * The internal header included in all source files
+ */
+
+#ifndef __HEADER_H__
+#define __HEADER_H__
+
+/////////////////////////////////////////////////////////////////////////////
+
+#include "config.h"
+
+/////////////////////////////////////////////////////////////////////////////
+// A number of preprocessor options are used in the source code
+//
+// q4_DOS MS-DOS real-mode OS
+// q4_MAC Apple Macintosh OS
+// q4_UNIX Unix, any flavor
+// q4_VMS DEC OpenVMS OS
+// q4_WIN Microsoft Windows OS, any flavor
+// q4_WIN32 Microsoft Windows OS, 32-bit
+// q4_WINCE Microsoft Windows OS, embedded
+//
+// q4_MFC Microsoft MFC framework
+// q4_STD Standard STL version
+// q4_UNIV Universal version
+//
+// q4_BOOL compiler supports bool datatype
+// q4_CHECK enable assertion checks
+// q4_FIX manual header fix (see above)
+// q4_INLINE enable inline expansion
+// q4_KITDLL compile as DLL (shared library)
+// q4_MULTI compile for multi-threading
+// q4_NOLIB do not add automatic lib linkage (MSVC5)
+// q4_NO_NS don't use namespaces for STL
+// q4_OK assume all software is perfect
+// q4_STRICT do not disable any compiler warnings
+// q4_TINY small version, no floating point
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#define __K4CONF_H__ // skip section in "mk4.h", since we use "header.h"
+
+ // if neither MFC nor STD are specified, default to Universal version
+#if !q4_MFC && !q4_STD && !defined (q4_UNIV)
+#define q4_UNIV 1
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// You can either use '#define q4_xxx 1' to flag the choice of an OS, or
+// use a '#define d4_OS_H "file.h"' to force inclusion of a header later.
+
+#if defined (__MINGW32__)
+#define d4_OS_H "win.h"
+#elif defined (MSDOS) && defined (__GNUC__)
+#define q4_DOS 1
+#elif defined(unix) || defined(__unix__) || defined(__GNUC__) || \
+ defined(_AIX) || defined(__hpux)
+#define q4_UNIX 1
+#elif defined (__VMS)
+#define q4_VMS 1
+#elif defined (macintosh)
+#define q4_MAC 1
+#elif !defined (d4_OS_H)
+#define d4_OS_H "win.h"
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// Use '#define q4_xxx 1' to flag the choice of a CPU.
+
+#if defined (_M_I86) || defined (_M_IX86) || defined (i386)
+#define q4_I86 1
+#if defined (_M_I86SM)
+#define q4_TINY 1
+#endif
+#elif defined (__powerc)
+#define q4_PPC 1
+#elif defined (__alpha)
+#define q4_AXP 1
+#define q4_LONG64 1
+#elif defined (__VMS)
+#define q4_VAX 1
+#else
+#define q4_M68K 1
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// Use '#define q4_xxx 1' to flag the choice of an IDE, and optionally also
+// add '#include "file.h"' to force inclusion of a header file right here.
+
+#if defined (__BORLANDC__) // Borland C++
+#include "borc.h"
+#elif defined (__DECCXX) // DEC C++
+#define q4_DECC 1
+#elif defined (__GNUC__) // GNU C++
+#include "gnuc.h"
+#elif defined (__MWERKS__) // Metrowerks CodeWarrior C++
+#include "mwcw.h"
+#elif defined (_MSC_VER) // Microsoft Visual C++
+#include "msvc.h"
+#elif defined (__SC__) // Symantec C++
+#define q4_SYMC 1
+#elif defined (__WATCOMC__) // Watcom C++
+#define q4_WATC 1
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// Some of the options take precedence over others
+
+#if !q4_BOOL && !q4_STD // define a bool datatype
+#define false 0
+#define true 1
+#define bool int
+#endif
+
+#if !q4_CHECK // disable assertions
+#undef d4_assert
+#define d4_dbgdef(x)
+#define d4_assert(x)
+#endif
+
+#if q4_NO_NS // don't use namespaces
+#define d4_std
+#else
+#define d4_std std
+#endif
+
+#if HAVE_MEMMOVE
+#define d4_memmove(d,s,n) memmove(d,s,n)
+#elif HAVE_BCOPY
+#define d4_memmove(d,s,n) bcopy(s,d,n)
+#else
+#define d4_memmove f4_memmove
+extern void f4_memmove(void* d, const void* s, int n);
+#endif
+
+typedef unsigned char t4_byte; // create typedefs for t4_byte, etc.
+
+/////////////////////////////////////////////////////////////////////////////
+// Include header files which contain additional os/cpu/ide/fw specifics
+
+#ifdef d4_OS_H // operating system dependencies
+#include d4_OS_H
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// Several defines should always be set
+
+#ifndef d4_assert // assertion macro
+#include <assert.h>
+#define d4_assert assert
+#endif
+
+#ifndef d4_dbgdef // conditionally compiled
+#ifdef NDEBUG
+#define d4_dbgdef(x)
+#else
+#define d4_dbgdef(x) x
+#endif
+#endif
+
+#ifndef d4_new // heap allocator
+#define d4_new new
+#endif
+
+#ifndef d4_reentrant // thread-local storage
+#define d4_reentrant
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// Debug logging option, called internally where properties are modified
+
+#if q4_LOGPROPMODS
+void f4_DoLogProp(const c4_Handler*, int, const char*, int);
+#else
+#define f4_LogPropMods(a,b) 0
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// Public definitions, plus a few more framework-specific ones
+
+#include "mk4.h"
+
+#if q4_MFC
+#include "mfc.h"
+#elif q4_STD
+#include "std.h"
+#elif q4_UNIV
+#include "univ.h"
+#endif
+
+#ifdef _MSC_VER
+#pragma warning(disable: 4100 4127 4135 4244 4511 4512 4514)
+#endif
+
+#include <string.h>
+
+/////////////////////////////////////////////////////////////////////////////
+// Report unexpected combinations of settings
+
+#if !q4_FIX
+#if (q4_DOS+q4_MAC+q4_UNIX+q4_VMS+q4_WIN) != 1
+#error Exactly one operating system should have been defined
+#endif
+#if (q4_MFC+q4_STD+q4_UNIV) != 1
+#error Exactly one container library should have been defined
+#endif
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+
+#endif
diff --git a/akregator/src/mk4storage/metakit/src/mfc.h b/akregator/src/mk4storage/metakit/src/mfc.h
new file mode 100644
index 000000000..6e6d3e248
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/src/mfc.h
@@ -0,0 +1,34 @@
+// mfc.h --
+// $Id$
+// This is part of Metakit, see http://www.equi4.com/metakit/
+
+/** @file
+ * Configuration header for MFC-based builds
+ */
+
+#define q4_MFC 1
+
+#if q4_WIN && !q4_WIN32
+#include <afxwin.h>
+#else
+#include <afxcoll.h>
+#endif
+
+#undef d4_assert
+#define d4_assert ASSERT
+
+#undef d4_assertThis
+#define d4_assertThis d4_assert(AfxIsValidAddress(this, sizeof *this, FALSE))
+
+#undef d4_new
+#define d4_new DEBUG_NEW
+
+typedef class CString c4_String;
+typedef class CPtrArray c4_PtrArray;
+typedef class CDWordArray c4_DWordArray;
+typedef class CStringArray c4_StringArray;
+
+ // MSVC 1.52 thinks a typedef has no constructor, so use a define instead
+#if !q4_OK && q4_MSVC && _MSC_VER == 800
+#define c4_String CString
+#endif
diff --git a/akregator/src/mk4storage/metakit/src/msvc.h b/akregator/src/mk4storage/metakit/src/msvc.h
new file mode 100644
index 000000000..a53e8b6dc
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/src/msvc.h
@@ -0,0 +1,39 @@
+// msvc.h --
+// $Id$
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit/
+
+/** @file
+ * Configuration header for Microsoft Visual C++
+ */
+
+#define q4_MSVC 1
+
+ // get rid of several common warning messages
+#if !q4_STRICT
+//#pragma warning(disable: 4244) // conversion ..., possible loss of data
+//#pragma warning(disable: 4135) // conversion between diff. integral types
+//#pragma warning(disable: 4511) // copy constructor could not be generated
+//#pragma warning(disable: 4512) // assignment op could not be generated
+//#pragma warning(disable: 4514) // unreferenced inline removed
+#pragma warning(disable: 4710) // function ... not inlined
+#pragma warning(disable: 4711) // ... selected for automatic inline expansion
+#pragma warning(disable: 4100) // unreferenced formal parameter
+#endif
+
+#if _MSC_VER >= 1100
+#define q4_BOOL 1 // 5.0 supports the bool datatype
+#else
+#define q4_NO_NS 1 // 4.x doesn't use namespaces for STL
+#endif
+
+#if defined (_MT)
+#define q4_MULTI 1 // uses multi-threading
+#endif
+
+#if defined (_DEBUG) && !defined (q4_CHECK) // use assertions in debug build
+#define q4_CHECK 1
+#endif
+
+#if !q4_STD && !q4_UNIV && !defined (q4_MFC)
+#define d4_FW_H "mfc.h" // default for MSVC is to use MFC
+#endif
diff --git a/akregator/src/mk4storage/metakit/src/mwcw.h b/akregator/src/mk4storage/metakit/src/mwcw.h
new file mode 100644
index 000000000..1c863b967
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/src/mwcw.h
@@ -0,0 +1,31 @@
+// mwcw.h --
+// $Id$
+// This is part of Metakit, see http://www.equi4.com/metakit/
+
+/** @file
+ * Configuration header for Metrowerks CodeWarrior
+ */
+
+#define q4_MWCW 1
+
+/////////////////////////////////////////////////////////////////////////////
+
+#if q4_68K
+#if !__option(IEEEdoubles)
+#error Cannot build Metakit with 10-byte doubles
+#endif
+#endif
+
+#if __option(bool)
+#define q4_BOOL 1
+ // undo previous defaults, because q4_BOOL is not set early enough
+#undef false
+#undef true
+#undef bool
+#endif
+
+#undef _MSC_VER
+
+#pragma export on
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/akregator/src/mk4storage/metakit/src/persist.cpp b/akregator/src/mk4storage/metakit/src/persist.cpp
new file mode 100644
index 000000000..65a9e94eb
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/src/persist.cpp
@@ -0,0 +1,1185 @@
+// persist.cpp --
+// $Id$
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit/
+
+/** @file
+ * Implementation of the main file management classes
+ */
+
+#include "header.h"
+#include "column.h"
+#include "persist.h"
+#include "handler.h"
+#include "store.h"
+#include "field.h"
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_FileMark
+{
+ enum {
+ kStorageFormat = 0x4C4A, // b0 = 'J', b1 = <4C> (on Intel)
+ kReverseFormat = 0x4A4C // b0 = <4C>, b1 = 'J'
+ };
+
+ t4_byte _data [8];
+
+public:
+ c4_FileMark ();
+ c4_FileMark (t4_i32 pos_, bool flipped_, bool extend_);
+ c4_FileMark (t4_i32 pos_, int len_);
+
+ t4_i32 Offset() const;
+ t4_i32 OldOffset() const;
+
+ bool IsHeader() const;
+ bool IsOldHeader() const;
+ bool IsFlipped() const;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_FileMark::c4_FileMark ()
+{
+ d4_assert(sizeof *this == 8);
+}
+
+c4_FileMark::c4_FileMark (t4_i32 pos_, bool flipped_, bool extend_)
+{
+ d4_assert(sizeof *this == 8);
+ *(short*) _data = flipped_ ? kReverseFormat : kStorageFormat;
+ _data[2] = extend_ ? 0x0A : 0x1A;
+ _data[3] = 0;
+ t4_byte* p = _data + 4;
+ for (int i = 24; i >= 0; i -= 8)
+ *p++ = (t4_byte) (pos_ >> i);
+ d4_assert(p == _data + sizeof _data);
+}
+
+c4_FileMark::c4_FileMark (t4_i32 pos_, int len_)
+{
+ d4_assert(sizeof *this == 8);
+ t4_byte* p = _data;
+ *p++ = 0x80;
+ for (int j = 16; j >= 0; j -= 8)
+ *p++ = (t4_byte) (len_ >> j);
+ for (int i = 24; i >= 0; i -= 8)
+ *p++ = (t4_byte) (pos_ >> i);
+ d4_assert(p == _data + sizeof _data);
+}
+
+t4_i32 c4_FileMark::Offset() const
+{
+ t4_i32 v = 0;
+ for (int i = 4; i < 8; ++i)
+ v = (v << 8) + _data[i];
+ return v;
+}
+
+t4_i32 c4_FileMark::OldOffset() const
+{
+ t4_i32 v = 0;
+ for (int i = 8; --i >= 4; )
+ v = (v << 8) + _data[i];
+ return v;
+}
+
+bool c4_FileMark::IsHeader() const
+{
+ return (_data[0] == 'J' || _data[0] == 'L') &&
+ (_data[0] ^ _data[1]) == ('J' ^ 'L') && _data[2] == 0x1A;
+}
+
+bool c4_FileMark::IsOldHeader() const
+{
+ return IsHeader() && _data[3] == 0x80;
+}
+
+bool c4_FileMark::IsFlipped() const
+{
+ return *(short*) _data == kReverseFormat;
+
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_Allocator : public c4_DWordArray
+{
+public:
+ c4_Allocator ();
+
+ void Initialize(t4_i32 first_ =1);
+
+ t4_i32 AllocationLimit() const;
+
+ t4_i32 Allocate(t4_i32 len_);
+ void Occupy(t4_i32 pos_, t4_i32 len_);
+ void Release(t4_i32 pos_, t4_i32 len_);
+ void Dump(const char* str_);
+
+private:
+ int Locate(t4_i32 pos_) const;
+ void InsertPair(int i_, t4_i32 from_, t4_i32 to_);
+ t4_i32 ReduceFrags(int goal_, int sHi_, int sLo_);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Allocation of blocks is maintained in a separate data structure.
+// There is no allocation overhead in the allocation arena itself.
+//
+// A single vector of "walls" is maintained, sorted by position:
+//
+// * Each transition between free and allocated is a single entry.
+// The number of entries is <num-free-ranges> + <num-used-ranges>.
+// * By definition, free areas start at the positions indicated
+// by the entries on even indices. Allocated ones use odd entries.
+// * There is an extra <0,0> free slot at the very beginning. This
+// simplifies boundary conditions at the start of the arena.
+// * Position zero cannot be allocated, first slot starts at 1.
+//
+// Properties of this approach:
+//
+// * No allocation overhead for adjacent allocated areas. On the
+// other hand, the allocator does not know the size of used slots.
+// * Alternate function allows marking a specific range as occupied.
+// * Allocator can be initialized as either all free or all in-use.
+// * Allocation info contains only integers, it could be stored.
+// * To extend allocated slots: "occupy" extra bytes at the end.
+// * Generic: can be used for memory, disk files, and array entries.
+
+c4_Allocator::c4_Allocator ()
+{
+ Initialize();
+}
+
+void c4_Allocator::Initialize(t4_i32 first_)
+{
+ SetSize(0, 1000); // empty, and growing in large chunks
+ Add(0); // fake block at start
+ Add(0); // ... only used to avoid merging
+
+ // if occupied, add a tiny free slot at the end, else add entire range
+ const t4_i32 kMaxInt = 0x7fffffff;
+ if (first_ == 0)
+ first_ = kMaxInt;
+
+ Add(first_); // start at a nicely aligned position
+ Add(kMaxInt); // ... there is no limit on file size
+}
+
+t4_i32 c4_Allocator::Allocate(t4_i32 len_)
+{
+ // zero arg is ok, it simply returns first allocatable position
+ for (int i = 2; i < GetSize(); i += 2)
+ if (GetAt(i+1) >= GetAt(i) + len_) {
+ t4_i32 pos = GetAt(i);
+ if ((t4_i32) GetAt(i+1) > pos + len_)
+ ElementAt(i) += len_;
+ else
+ RemoveAt(i, 2);
+ return pos;
+ }
+
+ d4_assert(0);
+ return 0; // not reached
+}
+
+void c4_Allocator::Occupy(t4_i32 pos_, t4_i32 len_)
+{
+ d4_assert(pos_ > 0);
+ // note that zero size simply checks if there is any space to extend
+
+ int i = Locate(pos_);
+ d4_assert(0 < i && i < GetSize());
+
+ if (i % 2) { // allocation is not at start of free block
+ d4_assert((t4_i32) GetAt(i-1) < pos_);
+
+ if ((t4_i32) GetAt(i) == pos_ + len_) // allocate from end of free block
+ SetAt(i, pos_);
+ else // split free block in two
+ InsertPair(i, pos_, pos_ + len_);
+ }
+ else if ((t4_i32) GetAt(i) == pos_)
+/*
+ This side of the if used to be unconditional, but that was
+ incorrect if ReduceFrags gets called (which only happens with
+ severely fragmented files) - there are cases when allocation
+ leads to an occupy request of which the free space list knows
+ nothing about because it dropped small segments. The solution
+ is to silently "allow" such allocations - fixed 29-02-2000
+ Thanks to Andrew Kuchling for his help in chasing this bug.
+*/
+ { // else extend tail of allocated area
+ if ((t4_i32) GetAt(i+1) > pos_ + len_)
+ ElementAt(i) += len_; // move start of next free up
+ else
+ RemoveAt(i, 2); // remove this slot
+ }
+}
+
+void c4_Allocator::Release(t4_i32 pos, t4_i32 len)
+{
+ int i = Locate(pos + len);
+ d4_assert(0 < i && i < GetSize());
+ d4_assert(i % 2 == 0); // don't release inside a free block
+
+ if ((t4_i32) GetAt(i) == pos) // move start of next free down
+ ElementAt(i) -= len;
+ else if ((t4_i32) GetAt(i-1) == pos) // move end of previous free up
+ ElementAt(i-1) += len;
+ else // insert a new entry
+ InsertPair(i, pos, pos + len);
+
+ if (GetAt(i-1) == GetAt(i)) // merge if adjacent free
+ RemoveAt(i-1, 2);
+}
+
+t4_i32 c4_Allocator::AllocationLimit() const
+{
+ d4_assert(GetSize() >= 2);
+
+ return GetAt(GetSize() - 2);
+}
+
+int c4_Allocator::Locate(t4_i32 pos) const
+{
+ int lo = 0, hi = GetSize() - 1;
+
+ while (lo < hi) {
+ int i = (lo + hi) / 2;
+ if (pos < (t4_i32) GetAt(i))
+ hi = i - 1;
+ else if (pos > (t4_i32) GetAt(i))
+ lo = i + 1;
+ else
+ return i;
+ }
+
+ return lo < GetSize() && pos > (t4_i32) GetAt(lo) ? lo + 1 : lo;
+}
+
+void c4_Allocator::InsertPair(int i_, t4_i32 from_, t4_i32 to_)
+{
+ d4_assert(0 < i_);
+ d4_assert(i_ < GetSize());
+
+ d4_assert(from_ < to_);
+ d4_assert((t4_i32) GetAt(i_-1) < from_);
+ //!d4_assert(to_ < GetAt(i_));
+
+ if (to_ >= (t4_i32) GetAt(i_))
+ return; // ignore 2nd allocation of used area
+
+ InsertAt(i_, from_, 2);
+ SetAt(i_+1, to_);
+
+ // it's ok to have arrays up to some 30000 bytes
+ if (GetSize() > 7500)
+ ReduceFrags(5000, 12, 6);
+}
+
+t4_i32 c4_Allocator::ReduceFrags(int goal_, int sHi_, int sLo_)
+{
+ // drastic fail-safe measure: remove small gaps if vec gets too long
+ // this will cause some lost free space but avoids array overflow
+ // the lost space will most probably be re-used after the next commit
+
+ int limit = GetSize() - 2;
+ t4_i32 loss = 0;
+
+ // go through all entries and remove gaps under the given threshold
+ for (int shift = sHi_; shift >= sLo_; --shift) {
+ // the threshold is a fraction of the current size of the arena
+ t4_i32 threshold = AllocationLimit() >> shift;
+ if (threshold == 0)
+ continue;
+
+ int n = 2;
+ for (int i = n; i < limit; i += 2)
+ if ((t4_i32) GetAt(i+1) - (t4_i32) GetAt(i) > threshold) {
+ SetAt(n++, GetAt(i));
+ SetAt(n++, GetAt(i+1));
+ }
+ else
+ loss += GetAt(i+1) - GetAt(i);
+
+ limit = n;
+
+ // if (GetSize() < goal_) - suboptimal, fixed 29-02-2000
+ if (limit < goal_)
+ break; // got rid of enough entries, that's enough
+ }
+
+ int n = GetSize() - 2;
+ SetAt(limit++, GetAt(n++));
+ SetAt(limit++, GetAt(n));
+ SetSize(limit);
+
+ return loss;
+}
+
+#if q4_CHECK
+#include <stdio.h>
+
+void c4_Allocator::Dump(const char* str_)
+{
+ fprintf(stderr, "c4_Allocator::Dump, %d entries <%s>\n", GetSize(), str_);
+ for (int i = 2; i < GetSize(); i += 2)
+ fprintf(stderr, " %10ld .. %ld\n", GetAt(i-1), GetAt(i));
+ fprintf(stderr, "END\n");
+}
+
+#else
+
+void c4_Allocator::Dump(const char* str_) { }
+
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_Differ
+{
+public:
+ c4_Differ (c4_Storage& storage_);
+ ~c4_Differ ();
+
+ int NewDiffID();
+ void CreateDiff(int id_, c4_Column& col_);
+ t4_i32 BaseOfDiff(int id_);
+ void ApplyDiff(int id_, c4_Column& col_) const;
+
+ void GetRoot(c4_Bytes& buffer_);
+
+ c4_Storage _storage;
+ c4_View _diffs;
+ c4_View _temp;
+
+private:
+ void AddEntry(t4_i32, t4_i32, const c4_Bytes&);
+
+ c4_ViewProp pCols; // column info:
+ c4_IntProp pOrig; // original position
+ c4_ViewProp pDiff; // difference chunks:
+ c4_IntProp pKeep; // offset
+ c4_IntProp pResize; // length
+ c4_BytesProp pBytes; // data
+};
+
+c4_Differ::c4_Differ (c4_Storage& storage_)
+ : _storage (storage_), pCols ("_C"), pOrig ("_O"),
+ pDiff ("_D"), pKeep ("_K"), pResize ("_R"), pBytes ("_B")
+{
+ // weird names, to avoid clashing with existing ones (capitalization!)
+ _diffs = _storage.GetAs("_C[_O:I,_D[_K:I,_R:I,_B:B]]");
+}
+
+c4_Differ::~c4_Differ ()
+{
+ _diffs = c4_View ();
+}
+
+void c4_Differ::AddEntry(t4_i32 off_, t4_i32 len_, const c4_Bytes& data_)
+{
+ int n = _temp.GetSize();
+ _temp.SetSize(n + 1);
+ c4_RowRef r = _temp[n];
+
+ pKeep (r) = (t4_i32) off_;
+ pResize (r) = (t4_i32) len_;
+ pBytes (r).SetData(data_);
+}
+
+int c4_Differ::NewDiffID()
+{
+ int n = _diffs.GetSize();
+ _diffs.SetSize(n + 1);
+ return n;
+}
+
+void c4_Differ::CreateDiff(int id_, c4_Column& col_)
+{
+ _temp.SetSize(0);
+#if 0
+ t4_i32 offset = 0;
+ t4_i32 savedOff = 0;
+ t4_i32 savedLen = 0;
+
+ c4_Strategy* strat = col_.Persist() != 0 ? &col_.Strategy() : 0;
+
+ c4_ColIter iter (col_, 0, col_.ColSize());
+ while (iter.Next()) {
+ const t4_byte* p = iter.BufLoad();
+ if (strat != 0 && strat->_mapStart != 0 && p >= strat->_mapStart &&
+ p - strat->_mapStart < strat->_dataSize)
+ {
+ t4_i32 nextOff = p - strat->_mapStart;
+ if (savedLen == 0)
+ savedOff = nextOff;
+ if (nextOff == savedOff + savedLen) {
+ savedLen += iter.BufLen();
+ continue;
+ }
+
+ if (savedLen > 0)
+ AddEntry(savedOff, savedLen, c4_Bytes ());
+
+ savedOff = nextOff;
+ savedLen = iter.BufLen();
+ } else {
+ AddEntry(savedOff, savedLen, c4_Bytes (p, iter.BufLen()));
+ savedLen = 0;
+ }
+
+ offset += iter.BufLen();
+ }
+
+ c4_View diff = pDiff (_diffs[id_]);
+ if (_temp.GetSize() != diff.GetSize() || _temp != diff)
+#else
+ c4_Bytes t1;
+ const t4_byte* p = col_.FetchBytes(0, col_.ColSize(), t1, false);
+ AddEntry(0, 0, c4_Bytes (p, col_.ColSize()));
+#endif
+ pDiff (_diffs[id_]) = _temp;
+
+ pOrig (_diffs[id_]) = col_.Position();
+}
+
+t4_i32 c4_Differ::BaseOfDiff(int id_)
+{
+ d4_assert(0 <= id_ && id_ < _diffs.GetSize());
+
+ return pOrig (_diffs[id_]);
+}
+
+void c4_Differ::ApplyDiff(int id_, c4_Column& col_) const
+{
+ d4_assert(0 <= id_ && id_ < _diffs.GetSize());
+
+ c4_View diff = pDiff (_diffs[id_]);
+ t4_i32 offset = 0;
+
+ for (int n = 0; n < diff.GetSize(); ++n) {
+ c4_RowRef row (diff[n]);
+ offset += pKeep (row);
+
+ c4_Bytes data;
+ pBytes(row).GetData(data);
+
+ // the following code is a lot like c4_MemoRef::Modify
+ const t4_i32 change = pResize (row);
+ if (change < 0)
+ col_.Shrink(offset, -change);
+ else if (change > 0)
+ col_.Grow(offset, change);
+
+ col_.StoreBytes(offset, data);
+ offset += data.Size();
+ }
+
+ if (offset > col_.ColSize())
+ col_.Shrink(offset, offset - col_.ColSize());
+}
+
+void c4_Differ::GetRoot(c4_Bytes& buffer_)
+{
+ int last = _diffs.GetSize() - 1;
+ if (last >= 0) {
+ c4_Bytes temp;
+ c4_View diff = pDiff (_diffs[last]);
+ if (diff.GetSize() > 0)
+ pBytes (diff[0]).GetData(buffer_);
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_SaveContext::c4_SaveContext (c4_Strategy& strategy_, bool fullScan_,
+ int mode_, c4_Differ* differ_, c4_Allocator* space_)
+ : _strategy (strategy_), _walk (0), _differ (differ_), _space (space_),
+ _cleanup (0), _nextSpace (0), _preflight (true), _fullScan (fullScan_),
+ _mode (mode_), _nextPosIndex (0), _bufPtr (_buffer), _curr (_buffer),
+ _limit (_buffer)
+{
+ if (_space == 0)
+ _space = _cleanup = d4_new c4_Allocator;
+
+ _nextSpace = _mode == 1 ? d4_new c4_Allocator : _space;
+}
+
+c4_SaveContext::~c4_SaveContext ()
+{
+ delete _cleanup;
+ if (_nextSpace != _space)
+ delete _nextSpace;
+}
+
+bool c4_SaveContext::IsFlipped() const
+{
+ return _strategy._bytesFlipped;
+}
+
+bool c4_SaveContext::Serializing() const
+{
+ return _fullScan;
+}
+
+void c4_SaveContext::AllocDump(const char* str_, bool next_)
+{
+ c4_Allocator* ap = next_ ? _nextSpace : _space;
+ if (ap != 0)
+ ap->Dump(str_);
+}
+
+void c4_SaveContext::FlushBuffer()
+{
+ int n = _curr - _bufPtr;
+ if (_walk != 0 && n > 0) {
+ t4_i32 end = _walk->ColSize();
+ _walk->Grow(end, n);
+ _walk->StoreBytes(end, c4_Bytes (_bufPtr, n));
+ }
+
+ _curr = _bufPtr = _buffer;
+ _limit = _buffer + sizeof _buffer;
+}
+
+c4_Column* c4_SaveContext::SetWalkBuffer(c4_Column* col_)
+{
+ FlushBuffer();
+
+ c4_Column* prev = _walk;
+ _walk = col_;
+ return prev;
+}
+
+void c4_SaveContext::Write(const void* buf_, int len_)
+{
+ // use buffering if possible
+ if (_curr + len_ <= _limit) {
+ memcpy(_curr, buf_, len_);
+ _curr += len_;
+ } else {
+ FlushBuffer();
+ _bufPtr = (t4_byte*) buf_; // also loses const
+ _curr = _limit = _bufPtr + len_;
+ FlushBuffer();
+ }
+}
+
+void c4_SaveContext::StoreValue(t4_i32 v_)
+{
+ if (_walk == 0)
+ return;
+
+ if (_curr + 10 >= _limit)
+ FlushBuffer();
+
+ d4_assert(_curr + 10 < _limit);
+ c4_Column::PushValue(_curr, v_);
+}
+
+void c4_SaveContext::SaveIt(c4_HandlerSeq& root_, c4_Allocator** spacePtr_,
+ c4_Bytes& rootWalk_)
+{
+ d4_assert(_space != 0);
+
+ const t4_i32 size = _strategy.FileSize();
+ if (_strategy._failure != 0)
+ return;
+
+ const t4_i32 end = _fullScan ? 0 : size - _strategy._baseOffset;
+
+ if (_differ == 0) {
+ if (_mode != 1)
+ _space->Initialize();
+
+ // don't allocate anything inside the file in extend mode
+ if (_mode == 2 && end > 0) {
+ _space->Occupy(1, end - 1);
+ _nextSpace->Occupy(1, end - 1);
+ }
+
+ // the header is always reserved
+ _space->Occupy(1, 7);
+ _nextSpace->Occupy(1, 7);
+
+ if (end > 0) {
+ d4_assert(end >= 16);
+ _space->Occupy(end - 16, 16);
+ _nextSpace->Occupy(end - 16, 16);
+ _space->Occupy(end, 8);
+ _nextSpace->Occupy(end, 8);
+ }
+ }
+
+ //AllocDump("a1", false);
+ //AllocDump("a2", true);
+
+ // first pass allocates columns and constructs shallow walks
+ c4_Column walk (root_.Persist());
+ SetWalkBuffer(&walk);
+ CommitSequence(root_, true);
+ SetWalkBuffer(0);
+ CommitColumn(walk);
+
+ c4_Bytes tempWalk;
+ walk.FetchBytes(0, walk.ColSize(), tempWalk, true);
+
+ t4_i32 limit = _nextSpace->AllocationLimit();
+ d4_assert(limit >= 8 || _differ != 0);
+
+ bool changed = _fullScan || tempWalk != rootWalk_;
+
+ rootWalk_ = c4_Bytes (tempWalk.Contents(), tempWalk.Size(), true);
+
+ _preflight = false;
+
+ // special-case to avoid saving data if file is logically empty
+ // in that case, the data is 0x80 0x81 0x80 (plus the header)
+ if (!_fullScan && limit <= 11 && _differ == 0) {
+ _space->Initialize();
+ _nextSpace->Initialize();
+ changed = false;
+ }
+
+ if (!changed)
+ return;
+
+ //AllocDump("b1", false);
+ //AllocDump("b2", true);
+
+ if (_differ != 0) {
+ int n = _differ->NewDiffID();
+ _differ->CreateDiff(n, walk);
+ return;
+ }
+
+ d4_assert(_mode != 0 || _fullScan);
+
+ // this is the place where writing may start
+
+ // figure out where the new file ends and write a skip tail there
+ t4_i32 end0 = end;
+
+ // true if the file need not be extended due to internal free space
+ bool inPlace = end0 == limit - 8;
+ if (inPlace) {
+ d4_assert(!_fullScan);
+ _space->Release(end0, 8);
+ _nextSpace->Release(end0, 8);
+ end0 -= 16; // overwrite existing tail markers
+ } else {
+ c4_FileMark head (limit + 16 - end, _strategy._bytesFlipped, end > 0);
+ _strategy.DataWrite(end, &head, sizeof head);
+
+ if (end0 < limit)
+ end0 = limit; // create a gap
+ }
+
+ t4_i32 end1 = end0 + 8;
+ t4_i32 end2 = end1 + 8;
+
+ if (!_fullScan && !inPlace) {
+ c4_FileMark mark1 (end0, 0);
+ _strategy.DataWrite(end0, &mark1, sizeof mark1);
+#if q4_WIN32
+ /* March 8, 2002
+ * On at least NT4 with NTFS, extending a file can cause it to be
+ * rounded up further than expected. To prevent creating a bad
+ * file (since the file does then not end with a marker), the
+ * workaround it so simply accept the new end instead and rewrite.
+ * Note that between these two writes, the file is in a bad state.
+ */
+ t4_i32 realend = _strategy.FileSize() - _strategy._baseOffset;
+ if (realend > end1) {
+ end0 = limit = realend - 8;
+ end1 = realend;
+ end2 = realend + 8;
+ c4_FileMark mark1a (end0, 0);
+ _strategy.DataWrite(end0, &mark1a, sizeof mark1a);
+ }
+#endif
+ d4_assert(_strategy.FileSize() == _strategy._baseOffset + end1);
+ }
+
+ _space->Occupy(end0, 16);
+ _nextSpace->Occupy(end0, 16);
+
+ // strategy.DataCommit(0); // may be needed, need more info on how FS's work
+ // but this would need more work, since we can't adjust file-mapping here
+
+ // second pass saves the columns and structure to disk
+ CommitSequence(root_, true); // writes changed columns
+ CommitColumn(walk);
+
+ //! d4_assert(_curr == 0);
+ d4_assert(_nextPosIndex == _newPositions.GetSize());
+
+ if (_fullScan) {
+ c4_FileMark mark1 (limit, 0);
+ _strategy.DataWrite(_strategy.FileSize() - _strategy._baseOffset,
+ &mark1, sizeof mark1);
+
+ c4_FileMark mark2 (limit - walk.ColSize(), walk.ColSize());
+ _strategy.DataWrite(_strategy.FileSize() - _strategy._baseOffset,
+ &mark2, sizeof mark2);
+
+ return;
+ }
+
+ if (inPlace)
+ d4_assert(_strategy.FileSize() == _strategy._baseOffset + end2);
+ else {
+ // make sure the allocated size hasn't changed
+ d4_assert(_nextSpace->AllocationLimit() == limit + 16);
+ d4_assert(end0 >= limit);
+ d4_assert(_strategy.FileSize() - _strategy._baseOffset == end1);
+ }
+
+ if (walk.Position() == 0 || _strategy._failure != 0)
+ return;
+
+ _strategy.DataCommit(0);
+
+ c4_FileMark mark2 (walk.Position(), walk.ColSize());
+ _strategy.DataWrite(end1, &mark2, sizeof mark2);
+ d4_assert(_strategy.FileSize() - _strategy._baseOffset == end2);
+
+ // do not alter the file header in extend mode, unless it is new
+ if (!_fullScan && (_mode == 1 || end == 0)) {
+ _strategy.DataCommit(0);
+
+ c4_FileMark head (end2, _strategy._bytesFlipped, false);
+ d4_assert(head.IsHeader());
+ _strategy.DataWrite(0, &head, sizeof head);
+
+ // if the file became smaller, we could shrink it
+ if (limit + 16 < end0) {
+/*
+ Not yet, this depends on the strategy class being able to truncate, but
+ there is no way to find out whether it does (the solution is to write tail
+ markers in such a way that the file won't grow unnecessarily if it doesn't).
+
+ The logic will probably be:
+
+ * write new skip + commit "tails" at limit (no visible effect on file)
+ * overwrite commit tail at end with a skip to this new one (equivalent)
+ * replace header with one pointing to that internal new one (equivalent)
+ * flush (now the file is valid both truncated and not-yet-truncated
+
+ end = limit;
+*/
+ }
+ }
+
+ // if using memory mapped files, make sure the map is no longer in use
+ if (_strategy._mapStart != 0)
+ root_.UnmappedAll();
+
+ // commit and tell strategy object what the new file size is, this
+ // may be smaller now, if old data at the end is no longer referenced
+ _strategy.DataCommit(end2);
+
+ d4_assert(_strategy.FileSize() - _strategy._baseOffset == end2);
+
+ if (spacePtr_ != 0 && _space != _nextSpace) {
+ d4_assert(*spacePtr_ == _space);
+ delete *spacePtr_;
+ *spacePtr_ = _nextSpace;
+ _nextSpace = 0;
+ }
+}
+
+bool c4_SaveContext::CommitColumn(c4_Column& col_)
+{
+ bool changed = col_.IsDirty() || _fullScan;
+
+ t4_i32 sz = col_.ColSize();
+ StoreValue(sz);
+ if (sz > 0) {
+ t4_i32 pos = col_.Position();
+
+ if (_differ) {
+ if (changed) {
+ int n = pos < 0 ? ~pos : _differ->NewDiffID();
+ _differ->CreateDiff(n, col_);
+
+ d4_assert(n >= 0);
+ pos = ~n;
+ }
+ } else if (_preflight) {
+ if (changed)
+ pos = _space->Allocate(sz);
+
+ _nextSpace->Occupy(pos, sz);
+ _newPositions.Add(pos);
+ } else {
+ pos = _newPositions.GetAt(_nextPosIndex++);
+
+ if (changed)
+ col_.SaveNow(_strategy, pos);
+
+ if (!_fullScan)
+ col_.SetLocation(pos, sz);
+ }
+
+ StoreValue(pos);
+ }
+
+ return changed;
+}
+
+void c4_SaveContext::CommitSequence(c4_HandlerSeq& seq_, bool selfDesc_)
+{
+ StoreValue(0); // sias prefix
+
+ if (selfDesc_) {
+ c4_String desc = seq_.Description();
+ int k = desc.GetLength();
+ StoreValue(k);
+ Write((const char*) desc, k);
+ }
+
+ StoreValue(seq_.NumRows());
+ if (seq_.NumRows() > 0)
+ for (int i = 0; i < seq_.NumFields(); ++i)
+ seq_.NthHandler(i).Commit(*this);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+ // used for on-the-fly conversion of old-format datafiles
+ t4_byte* _oldBuf;
+ const t4_byte* _oldCurr;
+ const t4_byte* _oldLimit;
+ t4_i32 _oldSeek;
+
+
+c4_Persist::c4_Persist (c4_Strategy& strategy_, bool owned_, int mode_)
+ : _space (0), _strategy (strategy_), _root (0), _differ (0),
+ _fCommit (0), _mode (mode_), _owned (owned_), _oldBuf (0),
+ _oldCurr (0), _oldLimit (0), _oldSeek (-1)
+{
+ if (_mode == 1)
+ _space = d4_new c4_Allocator;
+}
+
+c4_Persist::~c4_Persist ()
+{
+ delete _differ;
+
+ if (_owned) {
+ if (_root != 0)
+ _root->UnmappedAll();
+ delete &_strategy;
+ }
+
+ delete _space;
+
+ if (_oldBuf != 0)
+ delete [] _oldBuf;
+}
+
+c4_HandlerSeq& c4_Persist::Root() const
+{
+ d4_assert(_root != 0);
+ return *_root;
+}
+
+void c4_Persist::SetRoot(c4_HandlerSeq* root_)
+{
+ d4_assert(_root == 0);
+ _root = root_;
+}
+
+c4_Strategy& c4_Persist::Strategy() const
+{
+ return _strategy;
+}
+
+bool c4_Persist::AutoCommit(bool flag_)
+{
+ bool prev = _fCommit != 0;
+ if (flag_)
+ _fCommit = &c4_Persist::Commit;
+ else
+ _fCommit = 0;
+ return prev;
+}
+
+void c4_Persist::DoAutoCommit()
+{
+ if (_fCommit != 0)
+ (this->*_fCommit)(false);
+}
+
+bool c4_Persist::SetAside(c4_Storage& aside_)
+{
+ delete _differ;
+ _differ = d4_new c4_Differ (aside_);
+ Rollback(false);
+ return true; //! true if the generation matches
+}
+
+c4_Storage* c4_Persist::GetAside() const
+{
+ return _differ != 0 ? &_differ->_storage : 0;
+}
+
+bool c4_Persist::Commit(bool full_)
+{
+ // 1-Mar-1999, new semantics! return success status of commits
+ _strategy._failure = 0;
+
+ if (!_strategy.IsValid())
+ return false;
+
+ if (_mode == 0 && (_differ == 0 || full_)) // can't commit to r/o file
+ return false; // note that _strategy._failure is *zero* in this case
+
+ c4_SaveContext ar (_strategy, false, _mode, full_ ? 0 : _differ, _space);
+
+ // get rid of temp properties which still use the datafile
+ if (_mode == 1)
+ _root->DetachFromStorage(false);
+
+ // 30-3-2001: moved down, fixes "crash every 2nd call of mkdemo/dbg"
+ ar.SaveIt(*_root, &_space, _rootWalk);
+ return _strategy._failure == 0;
+}
+
+bool c4_Persist::Rollback(bool full_)
+{
+ _root->DetachFromParent();
+ _root->DetachFromStorage(true);
+ _root = 0;
+
+ if (_space != 0)
+ _space->Initialize();
+
+ c4_HandlerSeq* seq = d4_new c4_HandlerSeq (this);
+ seq->DefineRoot();
+ SetRoot(seq);
+
+ if (full_) {
+ delete _differ;
+ _differ = 0;
+ }
+
+ LoadAll();
+
+ return _strategy._failure == 0;
+}
+
+bool c4_Persist::LoadIt(c4_Column& walk_)
+{
+ t4_i32 limit = _strategy.FileSize();
+ if (_strategy._failure != 0)
+ return false;
+
+ if (_strategy.EndOfData(limit) < 0) {
+ _strategy.SetBase(limit);
+ d4_assert(_strategy._failure == 0); // file is ok, but empty
+ return false;
+ }
+
+ if (_strategy._rootLen > 0)
+ walk_.SetLocation(_strategy._rootPos, _strategy._rootLen);
+
+ // if the file size has increased, we must remap
+ if (_strategy._mapStart != 0 &&
+ _strategy.FileSize() > _strategy._baseOffset + _strategy._dataSize)
+ _strategy.ResetFileMapping();
+
+ return true;
+}
+
+void c4_Persist::LoadAll()
+{
+ c4_Column walk (this);
+ if (!LoadIt(walk))
+ return;
+
+ if (_strategy._rootLen < 0) {
+ _oldSeek = _strategy._rootPos;
+ _oldBuf = d4_new t4_byte [512];
+ _oldCurr = _oldLimit = _oldBuf;
+
+ t4_i32 n = FetchOldValue();
+ d4_assert(n == 0);
+ n = FetchOldValue();
+ d4_assert(n > 0);
+
+ c4_Bytes temp;
+ t4_byte* buf = temp.SetBuffer(n);
+ d4_dbgdef(int n2 =)
+ OldRead(buf, n);
+ d4_assert(n2 == n);
+
+ c4_String s = "[" + c4_String ((const char*) buf, n) + "]";
+ const char* desc = s;
+
+ c4_Field* f = d4_new c4_Field (desc);
+ d4_assert(!*desc);
+
+ //?_root->DefineRoot();
+ _root->Restructure(*f, false);
+
+ _root->OldPrepare();
+
+ // don't touch data inside while converting the file
+ if (_strategy.FileSize() >= 0)
+ OccupySpace(1, _strategy.FileSize());
+ } else {
+ walk.FetchBytes(0, walk.ColSize(), _rootWalk, true);
+ if (_differ)
+ _differ->GetRoot(_rootWalk);
+
+ // define and fill the root table
+ const t4_byte* ptr = _rootWalk.Contents();
+ _root->Prepare(&ptr, true);
+ d4_assert(ptr == _rootWalk.Contents() + _rootWalk.Size());
+ }
+}
+
+t4_i32 c4_Persist::FetchOldValue()
+{
+ d4_assert(_oldSeek >= 0);
+
+ if (_oldCurr == _oldLimit) {
+ int n = OldRead(_oldBuf, 500);
+ _oldLimit = _oldCurr + n;
+ _oldBuf[n] = 0x80; // to force end
+ }
+
+ const t4_byte* p = _oldCurr;
+ t4_i32 value = c4_Column::PullValue(p);
+
+ if (p > _oldLimit) {
+ int k = _oldLimit - _oldCurr;
+ d4_assert(0 < k && k < 10);
+ memcpy(_oldBuf, _oldCurr, k);
+
+ int n = OldRead(_oldBuf + k, 500);
+ _oldCurr = _oldBuf + k;
+ _oldLimit = _oldCurr + n;
+ _oldBuf[n+k] = 0x80; // to force end
+
+ p = _oldCurr;
+ value = c4_Column::PullValue(p);
+ d4_assert(p <= _oldLimit);
+ }
+
+ _oldCurr = p;
+ return value;
+}
+
+void c4_Persist::FetchOldLocation(c4_Column& col_)
+{
+ d4_assert(_oldSeek >= 0);
+
+ t4_i32 sz = FetchOldValue();
+ if (sz > 0)
+ col_.SetLocation(FetchOldValue(), sz);
+}
+
+int c4_Persist::OldRead(t4_byte* buf_, int len_)
+{
+ d4_assert(_oldSeek >= 0);
+
+ t4_i32 newSeek = _oldSeek + _oldCurr - _oldLimit;
+ int n = _strategy.DataRead(newSeek, buf_, len_);
+ d4_assert(n > 0);
+ _oldSeek = newSeek + n;
+ _oldCurr = _oldLimit = _oldBuf;
+ return n;
+}
+
+c4_HandlerSeq* c4_Persist::Load(c4_Stream* stream_)
+{
+ d4_assert(stream_ != 0);
+
+ c4_FileMark head;
+ if (stream_->Read(&head, sizeof head) != sizeof head || !head.IsHeader())
+ return 0; // no data in file
+
+ //_oldStyle = head._data[3] == 0x80;
+ d4_assert(!head.IsOldHeader());
+
+ t4_i32 limit = head.Offset();
+
+ c4_StreamStrategy* strat = d4_new c4_StreamStrategy (limit);
+ strat->_bytesFlipped = head.IsFlipped();
+ strat->DataWrite(strat->FileSize() - strat->_baseOffset, &head, sizeof head);
+
+ while (strat->FileSize() - strat->_baseOffset < limit) {
+ char buffer [4096];
+ int n = stream_->Read(buffer, sizeof buffer);
+ d4_assert(n > 0);
+ strat->DataWrite(strat->FileSize() - strat->_baseOffset, buffer, n);
+ }
+
+ c4_Persist* pers = d4_new c4_Persist (*strat, true, 0);
+ c4_HandlerSeq* seq = d4_new c4_HandlerSeq (pers);
+ seq->DefineRoot();
+ pers->SetRoot(seq);
+
+ c4_Column walk (pers);
+ if (!pers->LoadIt(walk)) {
+ seq->IncRef();
+ seq->DecRef(); // a funny way to delete
+ return 0;
+ }
+
+ c4_Bytes tempWalk;
+ walk.FetchBytes(0, walk.ColSize(), tempWalk, true);
+
+ const t4_byte* ptr = tempWalk.Contents();
+ seq->Prepare(&ptr, true);
+ d4_assert(ptr == tempWalk.Contents() + tempWalk.Size());
+
+ return seq;
+}
+
+void c4_Persist::Save(c4_Stream* stream_, c4_HandlerSeq& root_)
+{
+ d4_assert(stream_ != 0);
+
+ c4_StreamStrategy strat (stream_);
+
+ // 31-01-2002: streaming must adopt byte order of origin datafile
+ c4_Persist* p = root_.Persist();
+ if (p != 0)
+ strat._bytesFlipped = p->Strategy()._bytesFlipped;
+
+ c4_SaveContext ar (strat, true, 0, 0, 0);
+ c4_Bytes tempWalk;
+ ar.SaveIt(root_, 0, tempWalk);
+}
+
+t4_i32 c4_Persist::LookupAside(int id_)
+{
+ d4_assert(_differ != 0);
+
+ return _differ->BaseOfDiff(id_);
+}
+
+void c4_Persist::ApplyAside(int id_, c4_Column& col_)
+{
+ d4_assert(_differ != 0);
+
+ _differ->ApplyDiff(id_, col_);
+}
+
+void c4_Persist::OccupySpace(t4_i32 pos_, t4_i32 len_)
+{
+ d4_assert(_mode != 1 || _space != 0);
+
+ if (_space != 0)
+ _space->Occupy(pos_, len_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/akregator/src/mk4storage/metakit/src/persist.h b/akregator/src/mk4storage/metakit/src/persist.h
new file mode 100644
index 000000000..61ef261ee
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/src/persist.h
@@ -0,0 +1,127 @@
+// persist.h --
+// $Id$
+// This is part of Metakit, see http://www.equi4.com/metakit/
+
+/** @file
+ * Definition of the core file management classes
+ */
+
+#ifndef __PERSIST_H__
+#define __PERSIST_H__
+
+/////////////////////////////////////////////////////////////////////////////
+// Declarations in this file
+
+ class c4_SaveContext; // wraps file commits
+ class c4_Persist; // persistent table storage
+
+ class c4_Allocator; // not defined here
+ class c4_Column; // not defined here
+ class c4_Differ; // not defined here
+ class c4_FileMark; // not defined here
+ class c4_Strategy; // not defined here
+ class c4_HandlerSeq; // not defined here
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_SaveContext
+{
+ c4_Strategy& _strategy;
+ c4_Column* _walk;
+ c4_Differ* _differ;
+
+ c4_Allocator* _space;
+ c4_Allocator* _cleanup;
+ c4_Allocator* _nextSpace;
+
+ bool _preflight;
+ bool _fullScan;
+ int _mode;
+
+ c4_DWordArray _newPositions;
+ int _nextPosIndex;
+
+ t4_byte* _bufPtr;
+ t4_byte* _curr;
+ t4_byte* _limit;
+ t4_byte _buffer [512];
+
+public:
+ c4_SaveContext (c4_Strategy& strategy_, bool fullScan_, int mode_,
+ c4_Differ* differ_, c4_Allocator* space_);
+ ~c4_SaveContext ();
+
+ void SaveIt(c4_HandlerSeq& root_, c4_Allocator** spacePtr_,
+ c4_Bytes& rootWalk_);
+
+ void StoreValue(t4_i32 v_);
+ bool CommitColumn(c4_Column& col_);
+ void CommitSequence(c4_HandlerSeq& seq_, bool selfDesc_);
+
+ c4_Column* SetWalkBuffer(c4_Column* walk_);
+ bool IsFlipped() const;
+
+ bool Serializing() const;
+ void AllocDump(const char*, bool =false);
+
+private:
+ void FlushBuffer();
+ void Write(const void* buf_, int len_);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_Persist
+{
+ c4_Allocator* _space;
+ c4_Strategy& _strategy;
+ c4_HandlerSeq* _root;
+ c4_Differ* _differ;
+ c4_Bytes _rootWalk;
+ bool (c4_Persist::*_fCommit) (bool);
+ int _mode;
+ bool _owned;
+
+ // used for on-the-fly conversion of old-format datafiles
+ t4_byte* _oldBuf;
+ const t4_byte* _oldCurr;
+ const t4_byte* _oldLimit;
+ t4_i32 _oldSeek;
+
+ int OldRead(t4_byte* buf_, int len_);
+
+public:
+ c4_Persist (c4_Strategy&, bool owned_, int mode_);
+ ~c4_Persist ();
+
+ c4_HandlerSeq& Root() const;
+ void SetRoot(c4_HandlerSeq* root_);
+ c4_Strategy& Strategy() const;
+
+ bool AutoCommit(bool =true);
+ void DoAutoCommit();
+
+ bool SetAside(c4_Storage& aside_);
+ c4_Storage* GetAside() const;
+
+ bool Commit(bool full_);
+ bool Rollback(bool full_);
+
+ bool LoadIt(c4_Column& walk_);
+ void LoadAll();
+
+ t4_i32 LookupAside(int id_);
+ void ApplyAside(int id_, c4_Column& col_);
+
+ void OccupySpace(t4_i32 pos_, t4_i32 len_);
+
+ t4_i32 FetchOldValue();
+ void FetchOldLocation(c4_Column& col_);
+
+ static c4_HandlerSeq* Load(c4_Stream*);
+ static void Save(c4_Stream*, c4_HandlerSeq& root_);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+#endif
diff --git a/akregator/src/mk4storage/metakit/src/remap.cpp b/akregator/src/mk4storage/metakit/src/remap.cpp
new file mode 100644
index 000000000..cc8175df2
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/src/remap.cpp
@@ -0,0 +1,1154 @@
+// remap.cpp --
+// $Id$
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit/
+
+/** @file
+* Mapping and remapping custom viewers
+*/
+
+#include "header.h"
+#include "remap.h"
+#include "handler.h"
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_ReadOnlyViewer : public c4_CustomViewer
+{
+ c4_View _base;
+
+public:
+ c4_ReadOnlyViewer (c4_Sequence& seq_) : _base (&seq_) { }
+ virtual ~c4_ReadOnlyViewer () { }
+
+ virtual c4_View GetTemplate() { return _base.Clone(); }
+ virtual int GetSize() { return _base.GetSize(); }
+
+ virtual int Lookup(c4_Cursor key_, int& count_)
+ { int pos = 0; count_ = _base.GetSize();
+ return _base.RestrictSearch(*key_, pos, count_); }
+
+ virtual bool GetItem(int row_, int col_, c4_Bytes& buf_)
+ { return _base.GetItem(row_, col_, buf_); }
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_HashViewer : public c4_CustomViewer
+{
+ c4_View _base;
+ c4_View _map;
+ int _numKeys;
+
+ c4_IntProp _pHash;
+ c4_IntProp _pRow;
+
+ bool KeySame(int row_, c4_Cursor cursor_) const;
+ t4_i32 CalcHash(c4_Cursor cursor_) const;
+ int LookDict(t4_i32 hash_, c4_Cursor cursor_) const;
+ void InsertDict(int row_);
+ void RemoveDict(int pos_);
+ bool DictResize(int minused);
+
+ int Row(int i_) const { return _pRow (_map[i_]); }
+ int Hash(int i_) const { return _pHash (_map[i_]); }
+
+ void SetRow(int i_, int v_) { _pRow (_map[i_]) = v_; }
+ void SetHash(int i_, int v_) { _pHash (_map[i_]) = v_; }
+
+ bool IsUnused(int) const;
+ bool IsDummy(int) const;
+ bool IsActive(int i_) const { return Row(i_) >= 0; }
+
+ int GetPoly() const;
+ void SetPoly(int v_);
+ int GetSpare() const;
+ void SetSpare(int v_);
+
+public:
+ c4_HashViewer (c4_Sequence& seq_, int numKeys_,
+ c4_Sequence* map_=0);
+ virtual ~c4_HashViewer ();
+
+ virtual c4_View GetTemplate();
+ virtual int GetSize();
+ virtual int Lookup(c4_Cursor key_, int& count_);
+ virtual bool GetItem(int row_, int col_, c4_Bytes& buf_);
+ virtual bool SetItem(int row_, int col_, const c4_Bytes& buf_);
+ virtual bool InsertRows(int pos_, c4_Cursor value_, int count_=1);
+ virtual bool RemoveRows(int pos_, int count_=1);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// The following contains code derived froms Python's dictionaries, hence:
+// Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
+// The Netherlands.
+// Reduced and turned into a fast C++ class by Christian Tismer, hence:
+// Copyright 1999 by Christian Tismer.
+// Vectorized and reorganized further by Jean-Claude Wippler.
+/////////////////////////////////////////////////////////////////////////////
+
+// Table of irreducible polynomials to efficiently cycle through
+// GF(2^n)-{0}, 2<=n<=30.
+
+static long s_polys[] = {
+ 4 + 3,
+ 8 + 3,
+ 16 + 3,
+ 32 + 5,
+ 64 + 3,
+ 128 + 3,
+ 256 + 29,
+ 512 + 17,
+ 1024 + 9,
+ 2048 + 5,
+ 4096 + 83,
+ 8192 + 27,
+ 16384 + 43,
+ 32768 + 3,
+ 65536 + 45,
+ 131072 + 9,
+ 262144 + 39,
+ 524288 + 39,
+ 1048576 + 9,
+ 2097152 + 5,
+ 4194304 + 3,
+ 8388608 + 33,
+ 16777216 + 27,
+ 33554432 + 9,
+ 67108864 + 71,
+ 134217728 + 39,
+ 268435456 + 9,
+ 536870912 + 5,
+ 1073741824 + 83,
+ 0
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_HashViewer::c4_HashViewer (c4_Sequence& seq_, int numKeys_,
+ c4_Sequence* map_)
+ : _base (&seq_), _map (map_), _numKeys (numKeys_),
+ _pHash ("_H"), _pRow ("_R")
+{
+ if (_map.GetSize() == 0)
+ _map.SetSize(1);
+
+ int poly = GetPoly();
+ if (poly == 0 || _map.GetSize() <= _base.GetSize())
+ DictResize(_base.GetSize());
+}
+
+c4_HashViewer::~c4_HashViewer ()
+{
+}
+
+bool c4_HashViewer::IsUnused(int row_) const
+{
+ c4_RowRef r = _map[row_];
+ return _pRow (r) < 0 && _pHash (r) == 0;
+}
+
+bool c4_HashViewer::IsDummy(int row_) const
+{
+ c4_RowRef r = _map[row_];
+ return _pRow (r) < 0 && _pHash (r) < 0;
+}
+
+int c4_HashViewer::GetPoly() const
+{
+ return Hash(_map.GetSize()-1);
+}
+
+void c4_HashViewer::SetPoly(int v_)
+{
+ SetHash(_map.GetSize()-1, v_);
+}
+
+int c4_HashViewer::GetSpare() const
+{
+ return Row(_map.GetSize()-1);
+}
+
+void c4_HashViewer::SetSpare(int v_)
+{
+ SetRow(_map.GetSize()-1, v_);
+}
+
+bool c4_HashViewer::KeySame(int row_, c4_Cursor cursor_) const
+{
+ for (int i = 0; i < _numKeys; ++i)
+ {
+ c4_Bytes buffer;
+ _base.GetItem(row_, i, buffer);
+
+ c4_Handler& h = cursor_._seq->NthHandler(i);
+ if (h.Compare(cursor_._index, buffer) != 0)
+ return false;
+ }
+
+ return true;
+}
+
+/// Create mapped view which is uses a second view for hashing
+t4_i32 c4_HashViewer::CalcHash(c4_Cursor cursor_) const
+{
+ c4_Bytes buffer, buf2;
+ const t4_i32 endian = 0x03020100;
+ t4_i32 hash = 0;
+
+ for (int i = 0; i < _numKeys; ++i)
+ {
+ c4_Handler& h = cursor_._seq->NthHandler(i);
+ cursor_._seq->Get(cursor_._index, h.PropId(), buffer);
+
+ // this code borrows from Python's stringobject.c/string_hash()
+ int len = buffer.Size();
+ if (len > 0)
+ {
+ const t4_byte* p = buffer.Contents();
+
+ // 20030218: careful to avoid endian-ness sensitivity
+ if (*(const t4_byte*) &endian) // true on big-endian systems
+ switch (h.Property().Type())
+ {
+ case 'I': case 'L': case 'F': case 'D':
+ {
+ t4_byte* q = buf2.SetBuffer(len);
+ for (int j = 0; j < len; ++j)
+ q[len-j-1] = p[j];
+ p = q;
+ }
+ }
+
+ long x = *p << 7;
+
+ // modifications are risky, this code avoid scanning huge blobs
+ if (len > 200)
+ len = 100;
+
+ while (--len >= 0)
+ x = (1000003 * x) ^ *p++;
+
+ if (buffer.Size() > 200)
+ {
+ len = 100;
+ p += buffer.Size() - 200;
+ while (--len >= 0)
+ x = (1000003 * x) ^ *p++;
+ }
+
+ x ^= buffer.Size();
+ hash ^= x ^ i;
+ }
+ }
+
+ if (hash == 0)
+ hash = -1;
+
+ return hash;
+}
+
+/*
+ * Types of slots:
+ * Unused: row = -1, hash = 0
+ * Dummy: row = -1, hash = -1
+ * Active: row >= 0
+ * There must be at least one Unused slot at all times.
+ */
+
+int c4_HashViewer::LookDict(t4_i32 hash_, c4_Cursor cursor_) const
+{
+ const unsigned int mask = _map.GetSize() - 2;
+ /* We must come up with (i, incr) such that 0 <= i < _size
+ and 0 < incr < _size and both are a function of hash */
+ int i = mask & ~hash_;
+ /* We use ~hash_ instead of hash_, as degenerate hash functions, such
+ as for ints <sigh>, can have lots of leading zeros. It's not
+ really a performance risk, but better safe than sorry. */
+ if (IsUnused(i) || Hash(i) == hash_ && KeySame(Row(i), cursor_))
+ return i;
+
+ int freeslot = IsDummy(i) ? i : -1;
+
+ /* Derive incr from hash_, just to make it more arbitrary. Note that
+ incr must not be 0, or we will get into an infinite loop.*/
+ unsigned incr = (hash_ ^ ((unsigned long) hash_ >> 3)) & mask;
+ if (!incr)
+ incr = mask;
+
+ int poly = GetPoly();
+ for (;;)
+ {
+ i = (i+incr) & mask;
+ if (IsUnused(i))
+ break;
+ if (Hash(i) == hash_ && KeySame(Row(i), cursor_))
+ return i;
+ if (freeslot == -1 && IsDummy(i))
+ freeslot = i;
+ /* Cycle through GF(2^n)-{0} */
+ incr = incr << 1;
+ if (incr > mask)
+ incr ^= poly; /* This will implicitely clear the highest bit */
+ }
+
+ return freeslot != -1 ? freeslot : i;
+}
+
+void c4_HashViewer::InsertDict(int row_)
+{
+ c4_Cursor cursor = &_base[row_];
+
+ t4_i32 hash = CalcHash(cursor);
+ int i = LookDict(hash, cursor);
+
+ if (IsDummy(i))
+ {
+ int n = GetSpare();
+ d4_assert(n > 0);
+ SetSpare(n - 1);
+ }
+
+ SetHash(i, hash);
+ SetRow(i, row_);
+}
+
+void c4_HashViewer::RemoveDict(int pos_)
+{
+ c4_Cursor key = &_base[pos_];
+ t4_i32 hash = CalcHash(key);
+ int i = LookDict(hash, key);
+ d4_assert(i >= 0);
+
+ d4_assert(Row(i) == pos_);
+
+ SetHash(i, -1);
+ SetRow(i, -1);
+
+ SetSpare(GetSpare() + 1);
+}
+
+bool c4_HashViewer::DictResize(int minused)
+{
+ int i, newsize, newpoly;
+ for (i = 0, newsize = 4; ; i++, newsize <<= 1) {
+ if (s_polys[i] == 0)
+ return false;
+ else if (newsize > minused) {
+ newpoly = s_polys[i];
+ break;
+ }
+ }
+
+ _map.SetSize(0);
+
+ c4_Row empty;
+ _pRow (empty) = -1;
+ _map.InsertAt(0, empty, newsize + 1);
+
+ SetPoly(newpoly);
+ SetSpare(0);
+
+ for (int j = 0; j < _base.GetSize(); ++j)
+ InsertDict(j);
+
+ return true;
+}
+
+c4_View c4_HashViewer::GetTemplate()
+{
+ return _base.Clone();
+}
+
+int c4_HashViewer::GetSize()
+{
+ return _base.GetSize();
+}
+
+int c4_HashViewer::Lookup(c4_Cursor key_, int& count_)
+{
+ // can only use hashing if the properties match the query
+ // XXX it appears that this loop takes some 300 uS!
+ c4_View kv = (*key_).Container();
+ for (int k = 0; k < _numKeys; ++k)
+ if (kv.FindProperty(_base.NthProperty(k).GetId()) < 0)
+ return -1;
+
+ t4_i32 hash = CalcHash(key_); // TODO should combine with above loop
+ int i = LookDict(hash, key_);
+
+ int row = Row(i);
+ count_ = row >= 0 && KeySame(row, key_) ? 1 : 0;
+ return count_ ? row : 0; // don't return -1, we *know* it's not there
+}
+
+bool c4_HashViewer::GetItem(int row_, int col_, c4_Bytes& buf_)
+{
+ return _base.GetItem(row_, col_, buf_);
+}
+
+bool c4_HashViewer::SetItem(int row_, int col_, const c4_Bytes& buf_)
+{
+ if (col_ < _numKeys)
+ {
+ c4_Bytes temp;
+ _base.GetItem(row_, col_, temp);
+ if (buf_ == temp)
+ return true; // this call will have no effect, just ignore it
+
+ RemoveDict(row_);
+ }
+
+ _base.SetItem(row_, col_, buf_);
+
+ if (col_ < _numKeys)
+ {
+ // careful if changing a key to one which is already present:
+ // in that case, delete the other row to preserve uniqueness
+ //
+ // Note: this is a tricky and confusing issue, because now the
+ // mere act of *setting* a property value can *delete* a row!
+ //
+ // The big problem here is that setting the rest of the values
+ // in a loop can end up *wrong*, if the row has moved down!!!
+ int n;
+ int i = Lookup(&_base[row_], n);
+ if (i >= 0 && n > 0)
+ {
+ RemoveRows(i, 1);
+ if (i < row_)
+ --row_;
+ }
+
+ InsertDict(row_);
+ }
+
+ return true;
+}
+
+bool c4_HashViewer::InsertRows(int pos_, c4_Cursor value_, int count_)
+{
+ d4_assert(count_ > 0);
+
+ int n;
+ int i = Lookup(value_, n);
+ if (i >= 0 && n > 0)
+ {
+ _base.SetAt(i, *value_); // replace existing
+ return true;
+ }
+
+ // adjust row numbers if the insertion is not at the end
+ //
+ // TODO this could be optimized to go through the rows which
+ // were moved up, and then adjusting the map through a lookup
+ // (probably better than full scan if pos_ is relatively high)
+ if (pos_ < _base.GetSize())
+ {
+ for (int r = 0; r < _map.GetSize() - 1; ++r)
+ {
+ int n2 = Row(r);
+ if (n2 >= pos_)
+ SetRow(r, n2 + 1);
+ }
+ }
+
+ _base.InsertAt(pos_, *value_);
+ InsertDict(pos_);
+
+ int used = _base.GetSize();
+ int fill = used + GetSpare();
+ if (fill * 3 >= (_map.GetSize() - 1) * 2 && !DictResize(used * 2))
+ return false; // bail out
+
+ d4_assert(_base.GetSize() + GetSpare() < _map.GetSize() - 1);
+ return true;
+}
+
+bool c4_HashViewer::RemoveRows(int pos_, int count_)
+{
+ while (--count_ >= 0)
+ {
+ // since the map persists, be somewhat more aggressive than the
+ // original code in resizing down when the map is getting empty
+ if (_base.GetSize() * 3 < _map.GetSize() - 1 &&
+ !DictResize(_base.GetSize()))
+ return false; // bail out
+
+ RemoveDict(pos_);
+
+ // move rows down for now
+ //
+ // optionally: consider replacing with last entry (much faster)
+ for (int r = 0; r < _map.GetSize() - 1; ++r)
+ {
+ int n = Row(r);
+ if (n > pos_)
+ SetRow(r, n - 1);
+ }
+
+ _base.RemoveAt(pos_, 1);
+ }
+
+ return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_BlockedViewer : public c4_CustomViewer
+{
+ enum { kLimit = 1000 };
+
+ c4_View _base;
+
+ c4_ViewProp _pBlock;
+ c4_DWordArray _offsets;
+
+ int Slot(int& pos_);
+ void Split(int block_, int row_);
+ void Merge(int block_);
+ void Validate() const;
+
+public:
+ c4_BlockedViewer (c4_Sequence& seq_);
+ virtual ~c4_BlockedViewer ();
+
+ virtual c4_View GetTemplate();
+ virtual int GetSize();
+ virtual bool GetItem(int row_, int col_, c4_Bytes& buf_);
+ virtual bool SetItem(int row_, int col_, const c4_Bytes& buf_);
+ virtual bool InsertRows(int pos_, c4_Cursor value_, int count_=1);
+ virtual bool RemoveRows(int pos_, int count_=1);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+#if q4_CHECK
+
+ // debugging version to verify that the internal data is consistent
+ void c4_BlockedViewer::Validate() const
+ {
+ d4_assert(_base.GetSize() >= 2);
+
+ int n = _base.GetSize() - 1;
+ d4_assert(_offsets.GetSize() == n);
+
+ int total = 0;
+ for (int i = 0; i < n; i++)
+ {
+ c4_View bv = _pBlock (_base[i]);
+ d4_assert(bv.GetSize() > 0 || i == 0);
+ total += bv.GetSize();
+ d4_assert((int) _offsets.GetAt(i) == total++);
+ }
+
+ c4_View be = _pBlock (_base[n]);
+ d4_assert(be.GetSize() == n - 1);
+ }
+
+#else
+
+ // nothing, so inline this thing to avoid even the calling overhead
+ d4_inline void c4_BlockedViewer::Validate() const
+ {
+ }
+
+#endif
+
+c4_BlockedViewer::c4_BlockedViewer (c4_Sequence& seq_)
+ : _base (&seq_), _pBlock ("_B")
+{
+ if (_base.GetSize() < 2)
+ _base.SetSize(2);
+
+ int n = _base.GetSize() - 1;
+ _offsets.SetSize(n);
+
+ int total = 0;
+ for (int i = 0; i < n; i++)
+ {
+ c4_View bv = _pBlock (_base[i]);
+ total += bv.GetSize();
+ _offsets.SetAt(i, total++);
+ }
+ Validate();
+}
+
+c4_BlockedViewer::~c4_BlockedViewer ()
+{
+}
+
+int c4_BlockedViewer::Slot(int& pos_)
+{
+ d4_assert(_offsets.GetSize() > 0);
+ d4_assert(pos_ <= (int) _offsets.GetAt(_offsets.GetSize() - 1));
+
+#if 0
+ const int n = _offsets.GetSize();
+
+ int h;
+ for (h = 0; h < n; ++h)
+ if (pos_ <= (t4_i32) _offsets.GetAt(h))
+ break;
+#else
+ // switch to binary search, adapted from code by Zhang Dehua, 28-3-2002
+ // slows down some 5%, but said to be much better with 5 million rows
+ int l = 0, h = _offsets.GetSize() - 1;
+ while (l < h) {
+ int m = l + (h - l) / 2;
+ if ((t4_i32) _offsets.GetAt(m) < pos_)
+ l = m + 1;
+ else
+ h = m;
+ }
+#endif
+
+ if (h > 0)
+ pos_ -= _offsets.GetAt(h-1) + 1;
+
+ return h;
+}
+
+void c4_BlockedViewer::Split(int bno_, int row_)
+{
+ int z = _base.GetSize() - 1;
+ d4_assert(bno_ < z);
+ c4_View bz = _pBlock (_base[z]);
+ c4_View bv = _pBlock (_base[bno_]);
+ d4_assert(row_ < bv.GetSize());
+
+ _offsets.InsertAt(bno_, _offsets.GetAt(bno_) - bv.GetSize() + row_);
+
+ _base.InsertAt(bno_+1, c4_Row ());
+ c4_View bn = _pBlock (_base[bno_+1]);
+
+ bv.RelocateRows(row_ + 1, -1, bn, 0);
+ bv.RelocateRows(row_, 1, bz, bno_);
+
+ Validate();
+}
+
+void c4_BlockedViewer::Merge(int bno_)
+{
+ int z = _base.GetSize() - 1;
+ c4_View bz = _pBlock (_base[z]);
+ c4_View bv1 = _pBlock (_base[bno_]);
+ c4_View bv2 = _pBlock (_base[bno_+1]);
+
+ _offsets.RemoveAt(bno_);
+
+ bz.RelocateRows(bno_, 1, bv1, -1);
+ bv2.RelocateRows(0, -1, bv1, -1);
+
+ _base.RemoveAt(bno_+1);
+
+ Validate();
+}
+
+c4_View c4_BlockedViewer::GetTemplate()
+{
+ c4_View bv = _pBlock (_base[0]);
+ return bv.Clone();
+}
+
+int c4_BlockedViewer::GetSize()
+{
+ int n = _offsets.GetAt(_offsets.GetSize() - 1);
+ d4_assert(n >= 0);
+ return n;
+}
+
+bool c4_BlockedViewer::GetItem(int row_, int col_, c4_Bytes& buf_)
+{
+ int orig = row_;
+
+ int i = Slot(row_);
+ d4_assert(0 <= i && i < _base.GetSize() - 1);
+
+ if ((t4_i32) _offsets.GetAt(i) == orig)
+ {
+ row_ = i;
+ i = _base.GetSize() - 1;
+ }
+
+ c4_View bv = _pBlock (_base[i]);
+ return bv.GetItem(row_, col_, buf_);
+}
+
+bool c4_BlockedViewer::SetItem(int row_, int col_, const c4_Bytes& buf_)
+{
+ int orig = row_;
+
+ int i = Slot(row_);
+ d4_assert(0 <= i && i < _base.GetSize() - 1);
+
+ if ((t4_i32) _offsets.GetAt(i) == orig)
+ {
+ row_ = i;
+ i = _base.GetSize() - 1;
+ }
+
+ c4_View bv = _pBlock (_base[i]);
+ bv.SetItem(row_, col_, buf_);
+ return true;
+}
+
+bool c4_BlockedViewer::InsertRows(int pos_, c4_Cursor value_, int count_)
+{
+ d4_assert(count_ > 0);
+
+ bool atEnd = pos_ == GetSize();
+
+ int z = _base.GetSize() - 1;
+ int i = Slot(pos_);
+ d4_assert(0 <= i && i < z);
+
+ c4_View bv = _pBlock (_base[i]);
+ d4_assert(0 <= pos_ && pos_ <= bv.GetSize());
+
+ bv.InsertAt(pos_, *value_, count_);
+ for (int j = i; j < z; ++j)
+ _offsets.SetAt(j, _offsets.GetAt(j) + count_);
+
+ // massive insertions are first split off
+ while (bv.GetSize() >= 2 * kLimit)
+ Split(i, bv.GetSize() - kLimit - 2);
+
+ if (bv.GetSize() > kLimit )
+ Split(i, atEnd ? kLimit - 1 : bv.GetSize() / 2); // 23-3-2002, from MB
+
+ Validate();
+
+ return true;
+}
+
+bool c4_BlockedViewer::RemoveRows(int pos_, int count_)
+{
+ d4_assert(count_ > 0);
+ d4_assert(pos_ + count_ <= GetSize());
+
+ int z = _base.GetSize() - 1;
+ int i = Slot(pos_);
+ d4_assert(0 <= i && i < z);
+
+ c4_View bv = _pBlock (_base[i]);
+ d4_assert(0 <= pos_ && pos_ <= bv.GetSize());
+
+ int todo = count_;
+
+ // optimize if the deletion goes past the end of this block...
+ int overshoot = pos_ + count_ - bv.GetSize();
+ if (overshoot > 0) {
+
+ // first, delete blocks which are going away completely
+ while (i+1 < _offsets.GetSize()) {
+ int nextsize = _offsets.GetAt(i+1) - _offsets.GetAt(i);
+ if (overshoot < nextsize)
+ break;
+ todo -= nextsize;
+ overshoot -= nextsize;
+
+ // drop the block and forget it ever existed
+ for (int j = i+1; j < z; ++j)
+ _offsets.SetAt(j, _offsets.GetAt(j) - nextsize);
+ _offsets.RemoveAt(i+1);
+
+ _base.RemoveAt(i+1);
+ --z;
+ c4_View bz = _pBlock (_base[z]);
+ bz.RemoveAt(i);
+
+ Validate();
+ }
+
+ // delete before merging, to avoid useless copying
+ if (overshoot > 1) {
+ c4_View bv2 = _pBlock (_base[i+1]);
+ bv2.RemoveAt(0, overshoot - 1);
+ todo -= overshoot - 1;
+
+ for (int j = i+1; j < z; ++j)
+ _offsets.SetAt(j, _offsets.GetAt(j) - (overshoot - 1));
+
+ // if the next block is filled enough, rotate the separator
+ // this avoids an expensive and unnecessary merge + split
+ if (bv2.GetSize() > kLimit / 2) {
+ c4_View bz = _pBlock (_base[z]);
+ bz[i] = bv2[0];
+ bv2.RemoveAt(0);
+ --todo;
+ d4_assert(pos_ + todo <= bv.GetSize());
+ d4_assert(i < _offsets.GetSize());
+
+ for (int j = i+1; j < z; ++j)
+ _offsets.SetAt(j, _offsets.GetAt(j) - 1);
+ }
+ }
+
+ // merge into one block
+ if (pos_ + todo > bv.GetSize()) {
+ d4_assert(i < z - 1);
+ Merge(i);
+ --z;
+ }
+ }
+ d4_assert(pos_ + todo <= bv.GetSize());
+
+ // now remove the rows and adjust offsets
+ if (todo > 0)
+ bv.RemoveAt(pos_, todo);
+
+ for (int j = i; j < z; ++j)
+ _offsets.SetAt(j, _offsets.GetAt(j) - todo);
+
+ // if the block underflows, merge it
+ if (bv.GetSize() < kLimit / 2) {
+ if (i > 0) // merge with predecessor, preferably
+ bv = _pBlock (_base[--i]);
+ if (i >= z - 1) // unless there is no successor to merge with
+ return true;
+ Merge(i);
+ }
+
+ // if the block overflows, split it
+ if (bv.GetSize() > kLimit )
+ Split(i, bv.GetSize() / 2);
+
+ Validate();
+
+ return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_OrderedViewer : public c4_CustomViewer
+{
+ c4_View _base;
+ int _numKeys;
+
+ int KeyCompare(int row_, c4_Cursor cursor_) const;
+
+public:
+ c4_OrderedViewer (c4_Sequence& seq_, int numKeys_);
+ virtual ~c4_OrderedViewer ();
+
+ virtual c4_View GetTemplate();
+ virtual int GetSize();
+ virtual int Lookup(c4_Cursor key_, int& count_);
+ virtual bool GetItem(int row_, int col_, c4_Bytes& buf_);
+ virtual bool SetItem(int row_, int col_, const c4_Bytes& buf_);
+ virtual bool InsertRows(int pos_, c4_Cursor value_, int count_=1);
+ virtual bool RemoveRows(int pos_, int count_=1);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_OrderedViewer::c4_OrderedViewer (c4_Sequence& seq_, int numKeys_)
+ : _base (&seq_), _numKeys (numKeys_)
+{
+}
+
+c4_OrderedViewer::~c4_OrderedViewer ()
+{
+}
+
+int c4_OrderedViewer::KeyCompare(int row_, c4_Cursor cursor_) const
+{
+ for (int i = 0; i < _numKeys; ++i)
+ {
+ c4_Bytes buffer;
+ _base.GetItem(row_, i, buffer);
+
+ c4_Handler& h = cursor_._seq->NthHandler(i);
+ int f = h.Compare(cursor_._index, buffer);
+ if (f != 0)
+ return f;
+ }
+
+ return 0;
+}
+
+c4_View c4_OrderedViewer::GetTemplate()
+{
+ return _base.Clone();
+}
+
+int c4_OrderedViewer::GetSize()
+{
+ return _base.GetSize();
+}
+
+int c4_OrderedViewer::Lookup(c4_Cursor key_, int& count_)
+{
+ // can only use bsearch if the properties match the query
+ // XXX with ord1.tcl (dict words), this loop takes 300 uS!
+ c4_View kv = (*key_).Container();
+ for (int k = 0; k < _numKeys; ++k)
+ if (kv.FindProperty(_base.NthProperty(k).GetId()) < 0)
+ return -1;
+
+#if 0 // Locate gets the count wrong, it seems 2000-06-15
+ int pos;
+ count_ = _base.Locate(*key_, &pos);
+#else
+ int pos = _base.Search(*key_);
+ count_ = pos < _base.GetSize() && KeyCompare(pos, key_) == 0 ? 1 : 0;
+#endif
+ return pos;
+}
+
+bool c4_OrderedViewer::GetItem(int row_, int col_, c4_Bytes& buf_)
+{
+ return _base.GetItem(row_, col_, buf_);
+}
+
+bool c4_OrderedViewer::SetItem(int row_, int col_, const c4_Bytes& buf_)
+{
+ if (col_ < _numKeys)
+ {
+ c4_Bytes temp;
+ _base.GetItem(row_, col_, temp);
+ if (buf_ == temp)
+ return true; // this call will have no effect, just ignore it
+ }
+
+ _base.SetItem(row_, col_, buf_);
+
+ if (col_ < _numKeys)
+ {
+ c4_Row copy = _base[row_];
+ // have to remove the row because it messes up searching
+ // it would be more efficient to search *around* this row
+ // or perhaps figure out new pos before changing any data
+ RemoveRows(row_);
+ InsertRows(0, &copy); // position is ignored
+ }
+
+ return true;
+}
+
+bool c4_OrderedViewer::InsertRows(int, c4_Cursor value_, int count_)
+{
+ d4_assert(count_ > 0);
+
+ int n;
+ int i = Lookup(value_, n);
+
+ // XXX if the lookup does not work, then insert as first element (!?)
+ d4_assert(i >= 0);
+ if (i < 0)
+ i = 0;
+
+ if (n == 0)
+ _base.InsertAt(i, *value_);
+ else
+ {
+ d4_assert(i < _base.GetSize());
+ _base.SetAt(i, *value_); // replace existing
+ }
+
+ return true;
+}
+
+bool c4_OrderedViewer::RemoveRows(int pos_, int count_)
+{
+ _base.RemoveAt(pos_, count_);
+ return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_IndexedViewer : public c4_CustomViewer
+{
+ c4_View _base;
+ c4_View _map;
+ c4_View _props;
+ bool _unique;
+ c4_IntProp _mapProp;
+
+ int KeyCompare(int row_, c4_Cursor cursor_) const;
+
+public:
+ c4_IndexedViewer (c4_Sequence& seq_, c4_Sequence& map_,
+ const c4_View& props_, bool unique_);
+ virtual ~c4_IndexedViewer ();
+
+ virtual c4_View GetTemplate();
+ virtual int GetSize();
+ virtual int Lookup(c4_Cursor key_, int& count_);
+ virtual bool GetItem(int row_, int col_, c4_Bytes& buf_);
+ virtual bool SetItem(int row_, int col_, const c4_Bytes& buf_);
+ virtual bool InsertRows(int pos_, c4_Cursor value_, int count_=1);
+ virtual bool RemoveRows(int pos_, int count_=1);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_IndexedViewer::c4_IndexedViewer (c4_Sequence& seq_, c4_Sequence& map_,
+ const c4_View& props_, bool unique_)
+ : _base (&seq_), _map (&map_), _props (props_), _unique (unique_),
+ _mapProp ((const c4_IntProp&) _map.NthProperty(0))
+{
+ int n = _base.GetSize();
+ if (_map.GetSize() != n)
+ {
+ c4_View sorted = _base.SortOn(_props);
+
+ _map.SetSize(n);
+ for (int i = 0; i < n; ++i)
+ _mapProp (_map[i]) = _base.GetIndexOf(sorted[i]);
+ }
+}
+
+c4_IndexedViewer::~c4_IndexedViewer ()
+{
+}
+
+int c4_IndexedViewer::KeyCompare(int row_, c4_Cursor cursor_) const
+{
+ int n = _props.NumProperties();
+ for (int i = 0; i < n; ++i)
+ {
+ c4_Bytes buffer;
+ _base.GetItem(row_, i, buffer);
+
+ c4_Handler& h = cursor_._seq->NthHandler(i);
+ int f = h.Compare(cursor_._index, buffer);
+ if (f != 0)
+ return f;
+ }
+
+ return 0;
+}
+
+c4_View c4_IndexedViewer::GetTemplate()
+{
+ return _base.Clone();
+}
+
+int c4_IndexedViewer::GetSize()
+{
+ return _base.GetSize();
+}
+
+int c4_IndexedViewer::Lookup(c4_Cursor key_, int& count_)
+{
+ // can only use bsearch if the properties match the query
+ // XXX with ord1.tcl (dict words), this loop takes 300 uS!
+ c4_View kv = (*key_).Container();
+ int n = _props.NumProperties();
+ for (int k = 0; k < n; ++k)
+ if (kv.FindProperty(_props.NthProperty(k).GetId()) < 0)
+ return -1;
+
+#if 0 // Locate gets the count wrong, it seems 2000-06-15
+ int pos;
+ count_ = _base.Locate(*key_, &pos);
+#else
+ int pos = _base.Search(*key_);
+ count_ = pos < _base.GetSize() && KeyCompare(pos, key_) == 0 ? 1 : 0;
+#endif
+ return pos;
+}
+
+bool c4_IndexedViewer::GetItem(int row_, int col_, c4_Bytes& buf_)
+{
+ return _base.GetItem(row_, col_, buf_);
+}
+
+bool c4_IndexedViewer::SetItem(int row_, int col_, const c4_Bytes& buf_)
+{
+ const int id = _base.NthProperty(col_).GetId();
+ const bool keyMod = _props.FindProperty(id) >= 0;
+
+ if (keyMod)
+ {
+ c4_Bytes temp;
+ _base.GetItem(row_, col_, temp);
+ if (buf_ == temp)
+ return true; // this call will have no effect, just ignore it
+ }
+
+ _base.SetItem(row_, col_, buf_);
+
+ if (keyMod)
+ {
+ // TODO adjust index
+ }
+
+ return true;
+}
+
+bool c4_IndexedViewer::InsertRows(int, c4_Cursor value_, int count_)
+{
+ d4_assert(count_ > 0);
+
+ if (_unique)
+ count_ = 1;
+
+ int n;
+ int i = Lookup(value_, n);
+
+ // XXX if the lookup does not work, then insert as first element (!?)
+ d4_assert(i >= 0);
+ if (i < 0)
+ i = 0;
+
+ if (n == 0)
+ _base.InsertAt(i, *value_);
+ else
+ {
+ d4_assert(i < _base.GetSize());
+ _base.SetAt(i, *value_); // replace existing
+ }
+
+ return true;
+}
+
+bool c4_IndexedViewer::RemoveRows(int pos_, int count_)
+{
+ _base.RemoveAt(pos_, count_);
+
+ int n = _map.GetSize();
+ while (--n >= 0)
+ {
+ int v = _mapProp (_map[n]);
+ if (v >= pos_)
+ if (v < pos_ + count_)
+ _map.RemoveAt(n);
+ else
+ _mapProp (_map[n]) = v - count_;
+ }
+
+ return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_CustomViewer* f4_CreateReadOnly(c4_Sequence& seq_)
+{
+ return d4_new c4_ReadOnlyViewer (seq_);
+}
+
+c4_CustomViewer* f4_CreateHash(c4_Sequence& seq_, int nk_, c4_Sequence* map_)
+{
+ return d4_new c4_HashViewer (seq_, nk_, map_);
+}
+
+c4_CustomViewer* f4_CreateBlocked(c4_Sequence& seq_)
+{
+ return d4_new c4_BlockedViewer (seq_);
+}
+
+c4_CustomViewer* f4_CreateOrdered(c4_Sequence& seq_, int nk_)
+{
+ return d4_new c4_OrderedViewer (seq_, nk_);
+}
+
+c4_CustomViewer* f4_CreateIndexed(c4_Sequence& seq_, c4_Sequence& map_,
+ const c4_View& props_, bool unique_)
+{
+ return d4_new c4_IndexedViewer (seq_, map_, props_, unique_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/akregator/src/mk4storage/metakit/src/remap.h b/akregator/src/mk4storage/metakit/src/remap.h
new file mode 100644
index 000000000..a435f853b
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/src/remap.h
@@ -0,0 +1,26 @@
+// remap.h --
+// $Id$
+// This is part of Metakit, see http://www.equi4.com/metakit/
+
+/** @file
+ * Encapsulation of the (re)mapping viewers
+ */
+
+#ifndef __REMAP_H__
+#define __REMAP_H__
+
+/////////////////////////////////////////////////////////////////////////////
+// Declarations in this file
+
+ class c4_Sequence; // not defined here
+
+ extern c4_CustomViewer* f4_CreateReadOnly(c4_Sequence&);
+ extern c4_CustomViewer* f4_CreateHash(c4_Sequence&, int, c4_Sequence* =0);
+ extern c4_CustomViewer* f4_CreateBlocked(c4_Sequence&);
+ extern c4_CustomViewer* f4_CreateOrdered(c4_Sequence&, int);
+ extern c4_CustomViewer* f4_CreateIndexed(c4_Sequence&, c4_Sequence&,
+ const c4_View&, bool =false);
+
+/////////////////////////////////////////////////////////////////////////////
+
+#endif
diff --git a/akregator/src/mk4storage/metakit/src/std.cpp b/akregator/src/mk4storage/metakit/src/std.cpp
new file mode 100644
index 000000000..135fe7766
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/src/std.cpp
@@ -0,0 +1,84 @@
+// std.cpp --
+// $Id$
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit/
+
+/** @file
+ * Implementation of STL-based strings and containers
+ */
+
+#include "header.h"
+
+#if q4_STD // until end of source
+/////////////////////////////////////////////////////////////////////////////
+
+#include "column.h" // c4_ColCache
+
+#if !q4_INLINE
+static char _mk4stdInl[] = "mk4str.inl";
+#include "mk4str.inl"
+#endif
+
+#if !q4_NO_NS
+using namespace std;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// Implemented in this file
+
+ class c4_String;
+
+/////////////////////////////////////////////////////////////////////////////
+
+#if !q4_MSVC && !q4_WATC
+
+ // MS C/C++ has this handy stricmp: a case-insensitive version of strcmp
+ // This version only works with 7-bit ASCII characters 0x00 through 0x7F
+
+ static int stricmp(const char* p1, const char* p2)
+ {
+ int c1, c2;
+
+#ifdef d4_USE_UNOPTIMIZED_CODE
+ do
+ {
+ c1 = tolower(*p1++);
+ c2 = tolower(*p2++);
+ } while (c1 != 0 && c1 == c2);
+#else
+ do
+ {
+ c1 = *p1++;
+ c2 = *p2++;
+ } while (c1 != 0 && (c1 == c2 || tolower(c1) == tolower(c2)));
+
+ c1 = tolower(c1);
+ c2 = tolower(c2);
+#endif
+
+ return c1 - c2;
+ }
+
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_String
+
+c4_String c4_String::Mid(int nFirst_, int nCount_) const
+{
+ int n = length();
+ if (nFirst_ > n)
+ nFirst_ = n;
+ if (nFirst_ + nCount_ > n)
+ nCount_ = n - nFirst_;
+
+ return substr(nFirst_, nCount_);
+}
+
+int c4_String::CompareNoCase(const char* str_) const
+{
+ // this is not very "standard library-ish" ...
+ return *(const string*) this == str_ ? 0 : stricmp(c_str(), str_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // q4_STD
diff --git a/akregator/src/mk4storage/metakit/src/std.h b/akregator/src/mk4storage/metakit/src/std.h
new file mode 100644
index 000000000..1d1937be3
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/src/std.h
@@ -0,0 +1,63 @@
+// std.h --
+// $Id$
+// This is part of Metakit, see http://www.equi4.com/metakit/
+
+/** @file
+ * Configuration header for STL-based builds
+ */
+
+#define q4_STD 1
+
+#include "mk4str.h"
+
+#include <vector>
+
+/////////////////////////////////////////////////////////////////////////////
+
+template<class T>
+class c4_ArrayT
+{
+#ifdef _MSC_VER
+ d4_std::vector< T, d4_std::allocator<T> > _vector;
+#else
+ d4_std::vector< T, d4_std::alloc > _vector;
+#endif
+
+public:
+ c4_ArrayT () { }
+ ~c4_ArrayT () { }
+
+ int GetSize() const { return _vector.size(); }
+ void SetSize(int nNewSize, int =-1) { _vector.resize(nNewSize); }
+
+ T GetAt(int nIndex) const { return _vector[nIndex]; }
+ T& ElementAt(int nIndex) { return _vector[nIndex]; }
+
+ void SetAt(int nIndex, const T& newElement)
+ {
+ _vector[nIndex] = newElement;
+ }
+
+ int Add(const T& newElement)
+ {
+ int n = _vector.size();
+ _vector.push_back(newElement);
+ return n;
+ }
+
+ void InsertAt(int nIndex, const T& newElement, int nCount =1)
+ {
+ _vector.insert(&_vector[nIndex], nCount, newElement);
+ }
+
+ void RemoveAt(int nIndex, int nCount =1)
+ {
+ _vector.erase(&_vector[nIndex], &_vector[nIndex+nCount]);
+ }
+};
+
+typedef c4_ArrayT<t4_i32> c4_DWordArray;
+typedef c4_ArrayT<void*> c4_PtrArray;
+typedef c4_ArrayT<c4_String> c4_StringArray;
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/akregator/src/mk4storage/metakit/src/store.cpp b/akregator/src/mk4storage/metakit/src/store.cpp
new file mode 100644
index 000000000..a32de665c
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/src/store.cpp
@@ -0,0 +1,587 @@
+// store.cpp --
+// $Id$
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit/
+
+/** @file
+ * Storage management and several other loose ends
+ */
+
+#include "header.h"
+#include "handler.h" // 19990906
+#include "store.h"
+#include "field.h"
+#include "persist.h"
+#include "format.h" // 19990906
+
+#include "mk4io.h" // 19991104
+
+#if !q4_INLINE
+#include "store.inl"
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_Dependencies::c4_Dependencies ()
+{
+ _refs.SetSize(0, 3); // a little optimization
+}
+
+c4_Dependencies::~c4_Dependencies ()
+{
+}
+
+void c4_Dependencies::Add(c4_Sequence* seq_)
+{
+ for (int i = 0; i < _refs.GetSize(); ++i)
+ d4_assert(_refs.GetAt(i) != seq_);
+
+ _refs.Add(seq_);
+}
+
+bool c4_Dependencies::Remove(c4_Sequence* seq_)
+{
+ int n = _refs.GetSize() - 1;
+ d4_assert(n >= 0);
+
+ for (int i = 0; i <= n; ++i)
+ if (_refs.GetAt(i) == seq_) {
+ _refs.SetAt(i, _refs.GetAt(n));
+ _refs.SetSize(n);
+ return n > 0;
+ }
+
+ d4_assert(0); // dependency not found
+ return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_Notifier::~c4_Notifier ()
+{
+ if (_type > kNone && _origin->GetDependencies()) {
+ c4_PtrArray& refs = _origin->GetDependencies()->_refs;
+
+ for (int i = 0; i < refs.GetSize(); ++i) {
+ c4_Sequence* seq = (c4_Sequence*) refs.GetAt(i);
+ d4_assert(seq != 0);
+
+ seq->PostChange(*this);
+
+ if (_chain && _chain->_origin == seq) {
+ c4_Notifier* next = _chain->_next;
+ _chain->_next = 0;
+
+ delete _chain;
+
+ _chain = next;
+ }
+ }
+ }
+
+ d4_assert(!_chain);
+ d4_assert(!_next);
+}
+
+void c4_Notifier::StartSetAt(int index_, c4_Cursor& cursor_)
+{
+ _type = kSetAt;
+ _index = index_;
+ _cursor = &cursor_;
+
+ Notify();
+}
+
+void c4_Notifier::StartInsertAt(int i_, c4_Cursor& cursor_, int n_)
+{
+ _type = kInsertAt;
+ _index = i_;
+ _cursor = &cursor_;
+ _count = n_;
+
+ Notify();
+}
+
+void c4_Notifier::StartRemoveAt(int index_, int count_)
+{
+ _type = kRemoveAt;
+ _index = index_;
+ _count = count_;
+
+ Notify();
+}
+
+void c4_Notifier::StartMove(int from_, int to_)
+{
+ _type = kMove;
+ _index = from_;
+ _count = to_;
+
+ Notify();
+}
+
+void c4_Notifier::StartSet(int i_, int propId_, const c4_Bytes& buf_)
+{
+ _type = kSet;
+ _index = i_;
+ _propId = propId_;
+ _bytes = &buf_;
+
+ Notify();
+}
+
+void c4_Notifier::Notify()
+{
+ d4_assert(_origin->GetDependencies() != 0);
+ c4_PtrArray& refs = _origin->GetDependencies()->_refs;
+
+ int n = refs.GetSize();
+ d4_assert(n > 0);
+
+ c4_Notifier** rover = &_chain;
+
+ for (int i = 0; i < n; ++i) {
+ c4_Sequence* seq = (c4_Sequence*) refs.GetAt(i);
+ d4_assert(seq != 0);
+
+ c4_Notifier* ptr = seq->PreChange(*this);
+ if (ptr) {
+ d4_assert(ptr->_origin == seq);
+
+ d4_assert(!*rover);
+ *rover = ptr;
+ rover = &ptr->_next;
+ }
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+/** @class c4_Storage
+ *
+ * Manager for persistent storage of view structures.
+ *
+ * The storage class uses a view, with additional functionality to be able
+ * to store and reload the data it contains (including nested subviews).
+ *
+ * By default, data is loaded on demand, i.e. whenever data which has
+ * not yet been referenced is used for the first time. Loading is limited
+ * to the lifetime of this storage object, since the storage object carries
+ * the file descriptor with it that is needed to access the data file.
+ *
+ * To save changes, call the Commit member. This is the only time
+ * that data is written to file - when using a read-only file simply avoid
+ * calling Commit.
+ *
+ * The LoadFromStream and SaveToStream members can be used to
+ * serialize the contents of this storage row using only sequential I/O
+ * (no seeking, only read or write calls).
+ *
+ * The data storage mechanism implementation provides fail-safe operation:
+ * if anything prevents Commit from completing its task, the last
+ * succesfully committed version of the saved data will be recovered on
+ * the next open. This also includes changes made to the table structure.
+ *
+ * The following code creates a view with 1 row and stores it on file:
+ * @code
+ * c4_StringProp pName ("Name");
+ * c4_IntProp pAge ("Age");
+ *
+ * c4_Storage storage ("myfile.dat", true);
+ * c4_View myView = storage.GetAs("Musicians[Name:S,Age:I]");
+ *
+ * myView.Add(pName ["John Williams"] + pAge [43]);
+ *
+ * storage.Commit();
+ * @endcode
+ */
+
+c4_Storage::c4_Storage ()
+{
+ // changed to r/o, now that commits don't crash on it anymore
+ Initialize(*d4_new c4_Strategy, true, 0);
+}
+
+c4_Storage::c4_Storage (c4_Strategy& strategy_, bool owned_, int mode_)
+{
+ Initialize(strategy_, owned_, mode_);
+ Persist()->LoadAll();
+}
+
+c4_Storage::c4_Storage (const char* fname_, int mode_)
+{
+ c4_FileStrategy* strat = d4_new c4_FileStrategy;
+ strat->DataOpen(fname_, mode_);
+
+ Initialize(*strat, true, mode_);
+ if (strat->IsValid())
+ Persist()->LoadAll();
+}
+
+c4_Storage::c4_Storage (const c4_View& root_)
+{
+ if (root_.Persist() != 0) // only restore if view was indeed persistent
+ *(c4_View*) this = root_;
+ else // if this was not possible, start with a fresh empty storage
+ Initialize(*d4_new c4_Strategy, true, 0);
+}
+
+c4_Storage::~c4_Storage ()
+{
+ // cannot unmap here, because there may still be an autocommit pending
+ //((c4_HandlerSeq*) _seq)->UnmapAll();
+}
+
+void c4_Storage::Initialize(c4_Strategy& strategy_, bool owned_, int mode_)
+{
+ c4_Persist* pers = d4_new c4_Persist (strategy_, owned_, mode_);
+ c4_HandlerSeq* seq = d4_new c4_HandlerSeq (pers);
+ seq->DefineRoot();
+ *(c4_View*) this = seq;
+ pers->SetRoot(seq);
+}
+
+ /// Get or set a named view in this storage object
+c4_ViewRef c4_Storage::View(const char* name_)
+{
+ /*
+ The easy solution would seem to be:
+
+ c4_ViewProp prop (name_);
+ return prop (Contents());
+
+ But this does not work, because the return value would point to
+ an object allocated on the stack.
+
+ Instead, make sure the view *has* such a property, and use the
+ one inside the c4_Handler for it (since this will stay around).
+ */
+
+// int n = _root->PropIndex(c4_ViewProp (name_));
+
+ c4_ViewProp prop (name_);
+ int n = AddProperty(prop);
+ d4_assert(n >= 0);
+
+ // the following is an expression of the form "property (rowref)"
+ return NthProperty(n) (GetAt(0));
+}
+
+ /// Get a named view, redefining it to match the given structure
+c4_View c4_Storage::GetAs(const char* description_)
+{
+ d4_assert(description_ != 0);
+
+ // Dec 2001: now that GetAs is being used so much more frequently,
+ // add a quick check to see whether restructuring is needed at all
+ const char* q = strchr(description_, '[');
+ if (q != 0) {
+ c4_String vname (description_, q - description_);
+ const char* d = Description(vname);
+ if (d != 0) {
+ c4_String desc (d);
+ if (("[" + desc + "]").CompareNoCase(q) == 0)
+ return View(vname);
+ }
+ }
+
+ c4_Field* field = d4_new c4_Field (description_);
+ d4_assert(field != 0);
+
+ d4_assert(!*description_);
+
+ c4_String name = field->Name();
+ d4_assert(!name.IsEmpty());
+
+ c4_Field& curr = Persist()->Root().Definition();
+
+ c4_String newField = "," + field->Description();
+ bool keep = newField.Find('[') >= 0;
+
+ c4_String newDef;
+
+ // go through all subfields
+ for (int i = 0; i < curr.NumSubFields(); ++i) {
+ c4_Field& of = curr.SubField(i);
+ if (of.Name().CompareNoCase(name) == 0) {
+ if (field->IsRepeating())
+ newDef += newField;
+ // else new is not a repeating entry, so drop this entire field
+
+ newField.Empty(); // don't append it later on
+ continue;
+ }
+
+ newDef += "," + of.Description(); // keep original field
+ }
+
+ if (keep) // added 19990824 ignore if deletion
+ newDef += newField; // appends new definition if not found earlier
+
+ delete field;
+
+ const char* p = newDef;
+ SetStructure(*p ? ++p : p); // skip the leading comma
+
+ if (!keep) // 19990916: avoid adding an empty view again
+ return c4_View ();
+
+ return View(name);
+}
+
+ /// Define the complete view structure of the storage
+void c4_Storage::SetStructure(const char* description_)
+{
+ d4_assert(description_ != 0);
+
+ if (description_ != Description()) {
+ c4_String s = "[" + c4_String (description_) + "]";
+ description_ = s;
+
+ c4_Field* field = d4_new c4_Field (description_);
+ d4_assert(!*description_);
+
+ d4_assert(field != 0);
+ Persist()->Root().Restructure(*field, false);
+ }
+}
+
+ /// Return the strategy object associated with this storage
+c4_Strategy& c4_Storage::Strategy() const
+{
+ return Persist()->Strategy();
+}
+
+ /// Return a description of the view structure (default is all)
+const char* c4_Storage::Description(const char* name_)
+{
+ if (name_ == 0 || *name_ == 0)
+ return c4_View::Description();
+
+ c4_View v = View(name_);
+ return v.Description();
+}
+
+ /// Define the storage to use for differential commits
+bool c4_Storage::SetAside(c4_Storage& aside_)
+{
+ c4_Persist* pers = Persist();
+ bool f = pers->SetAside(aside_);
+ // adjust our copy when the root view has been replaced
+ *(c4_View*) this = &pers->Root();
+ return f;
+}
+
+ /// Return storage used for differential commits, or null
+c4_Storage* c4_Storage::GetAside() const
+{
+ return Persist()->GetAside();
+}
+
+ /// Flush pending changes to file right now
+bool c4_Storage::Commit(bool full_)
+{
+ return Strategy().IsValid() && Persist()->Commit(full_);
+}
+
+/** (Re)initialize for on-demand loading
+ *
+ * Calling Rollback will cancel all uncommitted changes.
+ */
+bool c4_Storage::Rollback(bool full_)
+{
+ c4_Persist* pers = Persist();
+ bool f = Strategy().IsValid() && pers->Rollback(full_);
+ // adjust our copy when the root view has been replaced
+ *(c4_View*) this = &pers->Root();
+ return f;
+}
+
+ /// Set storage up to always call Commit in the destructor
+bool c4_Storage::AutoCommit(bool flag_)
+{
+ return Persist()->AutoCommit(flag_);
+}
+
+ /// Load contents from the specified input stream
+bool c4_Storage::LoadFrom(c4_Stream& stream_)
+{
+ c4_HandlerSeq* newRoot = c4_Persist::Load(&stream_);
+ if (newRoot == 0)
+ return false;
+
+ // fix commit-after-load bug, by using a full view copy
+ // this is inefficient, but avoids mapping/strategy problems
+ c4_View temp (newRoot);
+
+ SetSize(0);
+ SetStructure(temp.Description());
+ InsertAt(0, temp);
+
+ return true;
+}
+
+ /// Save contents to the specified output stream
+void c4_Storage::SaveTo(c4_Stream& stream_)
+{
+ c4_Persist::Save(&stream_, Persist()->Root());
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_DerivedSeq::c4_DerivedSeq (c4_Sequence& seq_)
+ : _seq (seq_)
+{
+ _seq.Attach(this);
+}
+
+c4_DerivedSeq::~c4_DerivedSeq ()
+{
+ _seq.Detach(this);
+}
+
+int c4_DerivedSeq::RemapIndex(int index_, const c4_Sequence* seq_) const
+{
+ return seq_ == this ? index_ : _seq.RemapIndex(index_, seq_);
+}
+
+int c4_DerivedSeq::NumRows() const
+{
+ return _seq.NumRows();
+}
+
+int c4_DerivedSeq::NumHandlers() const
+{
+ return _seq.NumHandlers();
+}
+
+c4_Handler& c4_DerivedSeq::NthHandler(int colNum_) const
+{
+ return _seq.NthHandler(colNum_);
+}
+
+const c4_Sequence* c4_DerivedSeq::HandlerContext(int colNum_) const
+{
+ return _seq.HandlerContext(colNum_);
+}
+
+int c4_DerivedSeq::AddHandler(c4_Handler* handler_)
+{
+ return _seq.AddHandler(handler_);
+}
+
+c4_Handler* c4_DerivedSeq::CreateHandler(const c4_Property& prop_)
+{
+ return _seq.CreateHandler(prop_);
+}
+
+void c4_DerivedSeq::SetNumRows(int size_)
+{
+ _seq.SetNumRows(size_);
+}
+
+c4_Notifier* c4_DerivedSeq::PreChange(c4_Notifier& nf_)
+{
+ if (!GetDependencies())
+ return 0;
+
+ c4_Notifier* chg = d4_new c4_Notifier (this);
+
+ switch (nf_._type)
+ {
+ case c4_Notifier::kSetAt:
+ chg->StartSetAt(nf_._index, *nf_._cursor);
+ break;
+
+ case c4_Notifier::kSet:
+ chg->StartSet(nf_._index, nf_._propId, *nf_._bytes);
+ break;
+
+ case c4_Notifier::kInsertAt:
+ chg->StartInsertAt(nf_._index, *nf_._cursor, nf_._count);
+ break;
+
+ case c4_Notifier::kRemoveAt:
+ chg->StartRemoveAt(nf_._index, nf_._count);
+ break;
+
+ case c4_Notifier::kMove:
+ chg->StartMove(nf_._index, nf_._count);
+ break;
+ }
+
+ return chg;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_StreamStrategy::c4_StreamStrategy (t4_i32 buflen_)
+ : _stream (0), _buffer (d4_new t4_byte [buflen_]), _buflen (buflen_), _position (0)
+{
+ _mapStart = _buffer;
+ _dataSize = buflen_;
+}
+
+c4_StreamStrategy::c4_StreamStrategy (c4_Stream* stream_)
+ : _stream (stream_), _buffer (0), _buflen (0), _position (0)
+{
+}
+
+c4_StreamStrategy::~c4_StreamStrategy ()
+{
+ _mapStart = 0;
+ _dataSize = 0;
+
+ if (_buffer != 0)
+ delete [] _buffer;
+}
+
+bool c4_StreamStrategy::IsValid() const
+{
+ return true;
+}
+
+int c4_StreamStrategy::DataRead(t4_i32 pos_, void* buffer_, int length_)
+{
+ if (_buffer != 0) {
+ d4_assert(pos_ <= _buflen);
+ _position = pos_ + _baseOffset;
+
+ if (length_ > _buflen - _position)
+ length_ = _buflen - _position;
+ if (length_ > 0)
+ memcpy(buffer_, _buffer + _position, length_);
+ } else {
+ d4_assert(_position == pos_ + _baseOffset);
+ length_ = _stream != 0 ? _stream->Read(buffer_, length_) : 0;
+ }
+
+ _position += length_;
+ return length_;
+}
+
+void c4_StreamStrategy::DataWrite(t4_i32 pos_, const void* buffer_, int length_)
+{
+ if (_buffer != 0) {
+ d4_assert(pos_ <= _buflen);
+ _position = pos_ + _baseOffset;
+
+ int n = length_;
+ if (n > _buflen - _position)
+ n = _buflen - _position;
+ if (n > 0)
+ memcpy(_buffer + _position, buffer_, n);
+ } else {
+ d4_assert(_position == pos_ + _baseOffset);
+ if (_stream != 0 && !_stream->Write(buffer_, length_))
+ ++_failure;
+ }
+
+ _position += length_;
+}
+
+t4_i32 c4_StreamStrategy::FileSize()
+{
+ return _position;
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/akregator/src/mk4storage/metakit/src/store.h b/akregator/src/mk4storage/metakit/src/store.h
new file mode 100644
index 000000000..c45d258ea
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/src/store.h
@@ -0,0 +1,114 @@
+// store.h --
+// $Id$
+// This is part of Metakit, see http://www.equi4.com/metakit/
+
+/** @file
+ * Definition of auxiliary storage management classes
+ */
+
+#ifndef __STORE_H__
+#define __STORE_H__
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_Dependencies
+{
+ c4_PtrArray _refs;
+
+public:
+ c4_Dependencies ();
+ ~c4_Dependencies ();
+
+ void Add(c4_Sequence* seq_);
+ bool Remove(c4_Sequence* seq_);
+
+ friend class c4_Notifier;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_Notifier
+{
+ c4_Sequence* _origin;
+ c4_Notifier* _chain;
+ c4_Notifier* _next;
+
+public:
+ enum { kNone, kSetAt, kInsertAt, kRemoveAt, kMove, kSet, kLimit };
+
+ c4_Notifier (c4_Sequence* origin_);
+ ~c4_Notifier ();
+
+ bool HasDependents() const;
+
+ void StartSetAt(int index_, c4_Cursor& cursor_);
+ void StartInsertAt(int index_, c4_Cursor& cursor_, int count_);
+ void StartRemoveAt(int index_, int count_);
+ void StartMove(int from_, int to_);
+ void StartSet(int index_, int propId_, const c4_Bytes& buf_);
+
+ int _type;
+ int _index;
+ int _propId;
+ int _count;
+ c4_Cursor* _cursor;
+ const c4_Bytes* _bytes;
+
+private:
+ void Notify();
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_DerivedSeq : public c4_Sequence
+{
+protected:
+ c4_Sequence& _seq;
+
+protected:
+ c4_DerivedSeq (c4_Sequence& seq_);
+ virtual ~c4_DerivedSeq ();
+
+public:
+ virtual int RemapIndex(int, const c4_Sequence*) const;
+
+ virtual int NumRows() const;
+ virtual void SetNumRows(int size_);
+
+ virtual int NumHandlers() const;
+ virtual c4_Handler& NthHandler(int) const;
+ virtual const c4_Sequence* HandlerContext(int) const;
+ virtual int AddHandler(c4_Handler*);
+ virtual c4_Handler* CreateHandler(const c4_Property&);
+
+ virtual c4_Notifier* PreChange(c4_Notifier& nf_);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_StreamStrategy : public c4_Strategy
+{
+ c4_Stream* _stream;
+ t4_byte* _buffer;
+ t4_i32 _buflen;
+ t4_i32 _position;
+public:
+ c4_StreamStrategy (t4_i32 buflen_);
+ c4_StreamStrategy (c4_Stream* stream_);
+ virtual ~c4_StreamStrategy ();
+
+ virtual bool IsValid() const;
+ virtual int DataRead(t4_i32 pos_, void* buffer_, int length_);
+ virtual void DataWrite(t4_i32 pos_, const void* buffer_, int length_);
+ virtual t4_i32 FileSize();
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+#if q4_INLINE
+#include "store.inl"
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+
+#endif
diff --git a/akregator/src/mk4storage/metakit/src/store.inl b/akregator/src/mk4storage/metakit/src/store.inl
new file mode 100644
index 000000000..191ee7de7
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/src/store.inl
@@ -0,0 +1,20 @@
+// store.inl --
+// $Id$
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit/
+
+/** @file
+ * Inlined members of the storage management classes
+ */
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_Notifier
+
+d4_inline c4_Notifier::c4_Notifier (c4_Sequence* origin_)
+ : _origin (origin_), _chain (0), _next (0),
+ _type (kNone), _index (0), _propId (0), _count (0),
+ _cursor (0), _bytes (0)
+{
+ d4_assert(_origin != 0);
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/akregator/src/mk4storage/metakit/src/string.cpp b/akregator/src/mk4storage/metakit/src/string.cpp
new file mode 100644
index 000000000..33c8836c8
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/src/string.cpp
@@ -0,0 +1,304 @@
+// string.cpp --
+// $Id$
+// This is part of Metakit, see http://www.equi4.com/metakit/
+
+/** @file
+ * yet another string implementation
+ */
+
+#include "header.h"
+
+/* these definitions could be used instead of header.h ...
+ #define q4_UNIV 1
+ #define d4_inline
+ #include "mk4str.h"
+ #define d4_reentrant
+ #define d4_assert(x)
+*/
+
+#if q4_UNIV // until end of source
+/////////////////////////////////////////////////////////////////////////////
+
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef _AIX
+#include <strings.h>
+#endif
+
+#if !q4_INLINE
+#include "mk4str.inl"
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+
+#if q4_MSVC || q4_WATC || q4_BORC || (q4_MWCW && __MWERKS__ < 0x3000)
+#define strcasecmp stricmp
+#elif q4_WINCE
+
+ // MS C/C++ has this handy stricmp: a case-insensitive version of strcmp
+ // This version only works with 7-bit ASCII characters 0x00 through 0x7F
+
+ static int stricmp(const char* p1, const char* p2)
+ {
+ int c1, c2;
+
+#ifdef d4_USE_UNOPTIMIZED_CODE
+ do
+ {
+ c1 = tolower(*p1++);
+ c2 = tolower(*p2++);
+ } while (c1 != 0 && c1 == c2);
+#else
+ do
+ {
+ c1 = *p1++;
+ c2 = *p2++;
+ } while (c1 != 0 && (c1 == c2 || tolower(c1) == tolower(c2)));
+
+ c1 = tolower(c1);
+ c2 = tolower(c2);
+#endif
+
+ return c1 - c2;
+ }
+
+#endif
+
+#if q4_WINCE
+ const char* strrchr(const char* p, char ch)
+ {
+ const char* q = 0;
+ while (*p)
+ if (*p++ == ch)
+ q = p;
+ return q;
+ }
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// This string class implement functionality which is very similar to that
+// provided by the CString class of the Microsoft Framework Classes (MFC).
+//
+// There are also several major differences:
+//
+// 1) This class uses reference counting to avoid massive copying.
+// Consequently, function return as well as assignment is very fast.
+// 2) Strings of up to 255 bytes can contain any data, even null bytes.
+// Longer strings can not contain any null bytes past position 255.
+// 3) This class can produce a "const char*" without overhead, but it
+// can also cast to the byte-counted "const unsigned char*" used
+// everywhere in Macintosh applications (as StringPtr, Str255, etc).
+// 4) This source code is not derived from Microsoft's code in any way.
+//
+// A good way to use this class, is to always use c4_String for function
+// return values and "const [unsigned] char*" for all parameters. Together,
+// these two choices will remove the need for nearly any messy casts.
+//
+// Note: MFC 4.0 has now adopted refcounts, and is a good alternative to
+// this code (but a bit bulkier, it also has Unicode support).
+
+ // 2001-11-27, stop releasing nullvec, to allow MT use
+ d4_reentrant static unsigned char* nullVec = 0;
+
+static int fInc(unsigned char* p)
+{
+ ++*p;
+ if (*p)
+ return 1;
+
+ --*p;
+ return 0;
+}
+
+inline static void fDec(unsigned char* p)
+{
+ --*p;
+ if (!*p && p != nullVec)
+ delete [] p;
+}
+
+c4_String::c4_String (char ch, int n /* =1 */)
+{
+ if (n < 0)
+ n = 0;
+
+ _value = new unsigned char [n + 3];
+
+ _value[0] = 1; // see Init() member
+ memset(_value + 2, ch, n);
+ _value[1] = (unsigned char) (n <= 255 ? n : 255);
+ _value[n+2] = 0;
+}
+
+c4_String::c4_String (const char* p)
+{
+ Init(p, p != 0 ? strlen(p) : 0);
+}
+
+c4_String::c4_String (const c4_String& s)
+{
+ if (fInc(s._value))
+ _value = s._value;
+ else
+ Init(s.Data(), s.GetLength());
+}
+
+c4_String::~c4_String ()
+{
+ fDec(_value);
+}
+
+const c4_String& c4_String::operator= (const c4_String& s)
+{
+ unsigned char* oldVal = _value;
+ if (fInc(s._value))
+ _value = s._value;
+ else
+ Init(s.Data(), s.GetLength());
+ fDec(oldVal);
+
+ return *this;
+}
+
+c4_String operator+ (const c4_String& a, const c4_String& b)
+{
+ const int aCnt = a.GetLength();
+ int sum = aCnt + b.GetLength();
+
+ c4_String result ('\0', sum); // set up correct size, then fix contents
+ memcpy(result._value + 2, a.Data(), aCnt);
+ memcpy(result._value + 2 + aCnt, b.Data(), sum - aCnt);
+
+ return result;
+}
+
+void c4_String::Init(const void* p, int n)
+{
+ if (p == NULL || n <= 0)
+ {
+ // Optimization to significantly speed-up init of empty strings:
+ // share a common entry, which avoids *LOTS* of tiny mem allocs.
+ //
+ // Especially "new [...] c4_String" will benefit a lot, as well as:
+ //
+ // c4_String s; // this would have caused a new allocation
+ // s = ... // then immediately drops the count back
+ //
+ // 2001/11/27: changed to never release this empty vector, for MT use
+ // the new logic is to completely ignore its ref count
+
+ if (!nullVec)
+ {
+ // obtain a valid new empty string buffer to keep around
+ unsigned char* nv = new unsigned char [3];
+ nv[0] = nv[1] = nv[2] = 0;
+ // only set static value after item is fully inited (avoid MT race)
+ nullVec = nv;
+ }
+
+ _value = nullVec; // use this buffer as our empty string
+ return; // done... that was quick, wasn't it?
+ }
+
+ _value = new unsigned char [n + 3];
+
+ _value[0] = 1; // many assumptions here: set the reference count to 1
+
+ if (n > 0)
+ memcpy(_value + 2, p, n);
+ _value[1] = (unsigned char) (n <= 255 ? n : 255);
+ _value[n+2] = 0;
+}
+
+int c4_String::FullLength() const
+{
+ int n = _value[1];
+ return n < 255 ? n : n + strlen((const char*) _value + 2 + 255);
+}
+
+c4_String c4_String::Mid(int nFirst, int nCount) const
+{
+ if (nFirst >= GetLength())
+ return c4_String ();
+
+ if (nFirst + nCount > GetLength())
+ nCount = GetLength() - nFirst;
+
+ if (nFirst == 0 && nCount == GetLength())
+ return *this;
+
+ return c4_String (Data() + nFirst, nCount);
+}
+
+c4_String c4_String::Left(int nCount) const
+{
+ if (nCount >= GetLength())
+ return *this;
+
+ return c4_String (Data(), nCount);
+}
+
+c4_String c4_String::Right(int nCount) const
+{
+ if (nCount >= GetLength())
+ return *this;
+
+ return c4_String (Data() + GetLength() - nCount, nCount);
+}
+
+bool operator== (const c4_String& a, const c4_String& b)
+{
+ return a._value == b._value || a.GetLength() == b.GetLength() &&
+ memcmp(a.Data(), b.Data(), a.GetLength()) == 0;
+}
+
+int c4_String::Compare(const char* str) const
+{
+ return Data() == str ? 0 : strcmp(Data(), str);
+}
+
+int c4_String::CompareNoCase(const char* str) const
+{
+ return Data() == str ? 0 : strcasecmp(Data(), str);
+}
+
+int c4_String::Find(char ch) const
+{
+ const char* p = strchr(Data(), ch);
+ return p != 0 ? p - Data() : -1;
+}
+
+int c4_String::ReverseFind(char ch) const
+{
+ const char* p = strrchr(Data(), ch);
+ return p != 0 ? p - Data() : -1;
+}
+
+int c4_String::FindOneOf(const char* set) const
+{
+ const char* p = strpbrk(Data(), set);
+ return p != 0 ? p - Data() : -1;
+}
+
+int c4_String::Find(const char* sub) const
+{
+ const char* p = strstr(Data(), sub);
+ return p != 0 ? p - Data() : -1;
+}
+
+c4_String c4_String::SpanIncluding(const char* set) const
+{
+ return Left(strspn(Data(), set));
+}
+
+c4_String c4_String::SpanExcluding(const char* set) const
+{
+ return Left(strcspn(Data(), set));
+}
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // q4_UNIV
diff --git a/akregator/src/mk4storage/metakit/src/table.cpp b/akregator/src/mk4storage/metakit/src/table.cpp
new file mode 100644
index 000000000..a857cee09
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/src/table.cpp
@@ -0,0 +1,160 @@
+// table.cpp --
+// $Id$
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit/
+
+/** @file
+ * Loose ends, these should be moved
+ */
+
+#include "header.h"
+#include "handler.h"
+#include "store.h"
+#include "field.h"
+#include "format.h"
+#include "persist.h"
+
+/////////////////////////////////////////////////////////////////////////////
+// Implemented in this file
+
+ class c4_Bytes;
+ class c4_HandlerSeq;
+
+/////////////////////////////////////////////////////////////////////////////
+
+/** @class c4_Bytes
+ *
+ * Generic data buffer, with optional automatic clean up.
+ *
+ * These objects are used to pass around untyped data without concern about
+ * clean-up. They know whether the bytes need to be de-allocated when these
+ * objects go out of scope. Small amounts of data are stored in the object.
+ *
+ * Objects of this class are used a lot within Metakit to manipulate its own
+ * data items generically. The c4_BytesProp class allows storing binary
+ * data explicitly in a file. If such data files must be portable, then the
+ * application itself must define a generic format to deal with byte order.
+ *
+ * How to store an object in binary form in a row (this is not portable):
+ * @code
+ * struct MyStruct { ... };
+ * MyStruct something;
+ *
+ * c4_BytesProp pData ("Data");
+ * c4_Row row;
+ *
+ * pData (row) = c4_Bytes (&something, sizeof something);
+ * @endcode
+ */
+
+ /// Construct an object with contents, optionally as a copy
+c4_Bytes::c4_Bytes (const void* buf_, int len_, bool copy_)
+ : _size (len_), _copy (copy_)
+{
+ _contents = (t4_byte*) buf_; // moved out of intializers for DEC CXX 5.7
+ if (_copy)
+ _MakeCopy();
+}
+
+ /// Copy constructor
+c4_Bytes::c4_Bytes (const c4_Bytes& src_)
+ : _size (src_._size), _copy (src_._copy)
+{
+ _contents = src_._contents; // moved out of intializers for DEC CXX 5.7
+ if (_copy || _contents == src_._buffer)
+ _MakeCopy();
+}
+
+ /// Assignment, this may make a private copy of contents
+c4_Bytes& c4_Bytes::operator= (const c4_Bytes& src_)
+{
+ if (&src_ != this)
+ {
+ _LoseCopy();
+
+ _contents = src_._contents;
+ _size = src_._size;
+ _copy = src_._copy;
+
+ if (_copy || _contents == src_._buffer)
+ _MakeCopy();
+ }
+
+ return *this;
+}
+
+ /// Swap the contents and ownership of two byte objects
+void c4_Bytes::Swap(c4_Bytes& bytes_)
+{
+ t4_byte* p = _contents;
+ int s = _size;
+ bool c = _copy;
+
+ _contents = bytes_._contents;
+ _size = bytes_._size;
+ _copy = bytes_._copy;
+
+ bytes_._contents = p;
+ bytes_._size = s;
+ bytes_._copy = c;
+
+ // if either one is using its local buffer, swap those too
+ if (_contents == bytes_._buffer || p == _buffer)
+ {
+ t4_byte t [sizeof _buffer];
+
+ memcpy(t, _buffer, sizeof _buffer);
+ memcpy(_buffer, bytes_._buffer, sizeof _buffer);
+ memcpy(bytes_._buffer, t, sizeof _buffer);
+
+ if (_contents == bytes_._buffer)
+ _contents = _buffer;
+
+ if (bytes_._contents == _buffer)
+ bytes_._contents = bytes_._buffer;
+ }
+}
+
+/// Define contents as a freshly allocated buffer of given size
+t4_byte* c4_Bytes::SetBuffer(int length_)
+{
+/* No substantial improvement measured:
+ Perhaps keep a correctly sized c4_Bytes object in each property?
+ It means c4_...Ref objects would need to store a pointer, not an id.
+
+ if (length_ == _size)
+ return _contents; // no work needed, get out fast
+*/
+ _LoseCopy();
+
+ _size = length_;
+ _copy = _size > (int) sizeof _buffer;
+
+ return _contents = _copy ? d4_new t4_byte [_size] : _buffer;
+}
+
+/// Allocate a buffer and fills its contents with zero bytes
+t4_byte* c4_Bytes::SetBufferClear(int length_)
+{
+ return (t4_byte*) memset(SetBuffer(length_), 0, length_);
+}
+
+void c4_Bytes::_MakeCopy()
+{
+ d4_assert(_contents != 0);
+
+ _copy = _size > (int) sizeof _buffer;
+
+ if (_size > 0)
+ _contents = (t4_byte*) memcpy(_copy ? d4_new t4_byte [_size]
+ : _buffer, _contents, _size);
+}
+
+/// Return true if the contents of both objects are equal
+bool operator== (const c4_Bytes& a_, const c4_Bytes& b_)
+{
+ return a_._contents == b_._contents ||
+ (a_._size == b_._size &&
+ memcmp(a_._contents, b_._contents, a_._size) == 0);
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/akregator/src/mk4storage/metakit/src/univ.cpp b/akregator/src/mk4storage/metakit/src/univ.cpp
new file mode 100644
index 000000000..81a73015a
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/src/univ.cpp
@@ -0,0 +1,227 @@
+// univ.cpp --
+// $Id$
+// This is part of Metakit, see http://www.equi4.com/metakit/
+
+/** @file
+ * A simple implementation of dynamic arrays
+ */
+
+#include "header.h"
+
+#if q4_UNIV // until end of source
+/////////////////////////////////////////////////////////////////////////////
+
+#include <stdlib.h> // malloc
+
+#if !q4_INLINE
+#include "univ.inl"
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+
+#if q4_UNIX || __MINGW32__
+#define _strdup strdup
+#elif !q4_BORC && !q4_MSVC && !q4_WATC && !(q4_MWCW && defined(_WIN32)) && \
+ !(q4_MWCW && __MWERKS__ >= 0x3000)
+
+ static char* _strdup(const char* p)
+ {
+ if (!p)
+ return 0;
+
+ char* s = (char*) malloc(strlen(p) + 1);
+ return strcpy(s, p);
+ }
+
+#endif
+
+ // The Borland C++ RTL does not want file handle objects to cross
+ // DLL boundaries, so we add special fopen/fclose hooks to this DLL.
+
+#if q4_BORC
+ #include <stdio.h>
+
+#if q4_WIN32
+ __declspec(dllexport) FILE*
+#else
+ FILE* __export
+#endif
+ f4_FileOpenInDLL(const char* name_, const char* mode_)
+ {
+ return fopen(name_, mode_);
+ }
+
+#if q4_WIN32
+ __declspec(dllexport)
+#else
+ int __export
+#endif
+ f4_FileCloseInDLL(FILE* file_)
+ {
+ return fclose(file_);
+ }
+
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_BaseArray
+
+c4_BaseArray::c4_BaseArray ()
+ : _data (0), _size (0)
+{
+}
+
+c4_BaseArray::~c4_BaseArray ()
+{
+ SetLength(0);
+}
+
+void c4_BaseArray::SetLength(int nNewSize)
+{
+ // 2001-11-25: use more granular allocation, as optimization
+ const int bits = 6;
+
+ if (((_size - 1) ^ (nNewSize - 1)) >> bits) {
+ const int n = (nNewSize + (1<<bits) - 1) & -(1<<bits);
+ _data = _data == 0 ? n == 0 ? (char*) 0
+ : (char*) malloc(n)
+ : n == 0 ? (free(_data), (char*) 0)
+ : (char*) realloc(_data, n);
+ }
+
+ d4_assert(_data != 0 || nNewSize == 0);
+
+ int n = _size;
+ _size = nNewSize;
+
+ if (nNewSize > n)
+ memset(GetData(n), 0, nNewSize - n);
+}
+
+void c4_BaseArray::Grow(int nIndex)
+{
+ if (nIndex > _size)
+ SetLength(nIndex);
+}
+
+void c4_BaseArray::InsertAt(int nIndex, int nCount)
+{
+ SetLength(_size + nCount);
+
+ int to = nIndex + nCount;
+ if (_size > to)
+ d4_memmove(GetData(to), GetData(nIndex), _size - to);
+}
+
+void c4_BaseArray::RemoveAt(int nIndex, int nCount)
+{
+ int from = nIndex + nCount;
+ if (_size > from)
+ d4_memmove(GetData(nIndex), GetData(from), _size - from);
+
+ SetLength(_size - nCount);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_DWordArray
+
+int c4_DWordArray::Add(t4_i32 newElement)
+{
+ int n = GetSize();
+ _vector.Grow(Off(n + 1));
+ SetAt(n, newElement);
+ return n;
+}
+
+void c4_DWordArray::InsertAt(int nIndex, t4_i32 newElement, int nCount)
+{
+ _vector.InsertAt(Off(nIndex), nCount * sizeof (t4_i32));
+
+ while (--nCount >= 0)
+ SetAt(nIndex++, newElement);
+}
+
+void c4_DWordArray::RemoveAt(int nIndex, int nCount)
+{
+ _vector.RemoveAt(Off(nIndex), nCount * sizeof (t4_i32));
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_PtrArray
+
+int c4_PtrArray::Add(void* newElement)
+{
+ int n = GetSize();
+ _vector.Grow(Off(n + 1));
+ SetAt(n, newElement);
+ return n;
+}
+
+void c4_PtrArray::InsertAt(int nIndex, void* newElement, int nCount)
+{
+ _vector.InsertAt(Off(nIndex), nCount * sizeof (void*));
+
+ while (--nCount >= 0)
+ SetAt(nIndex++, newElement);
+}
+
+void c4_PtrArray::RemoveAt(int nIndex, int nCount)
+{
+ _vector.RemoveAt(Off(nIndex), nCount * sizeof (void*));
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_StringArray
+
+c4_StringArray::~c4_StringArray()
+{
+ SetSize(0);
+}
+
+void c4_StringArray::SetSize(int nNewSize, int)
+{
+ int i = nNewSize;
+
+ while (i < GetSize())
+ SetAt(i++, 0);
+
+ _ptrs.SetSize(nNewSize);
+
+ while (i < GetSize())
+ _ptrs.SetAt(i++, "");
+}
+
+void c4_StringArray::SetAt(int nIndex, const char* newElement)
+{
+ char* s = (char*) _ptrs.GetAt(nIndex);
+ if (s && *s)
+ free(s);
+
+ _ptrs.SetAt(nIndex, newElement && *newElement? _strdup(newElement) : "");
+}
+
+int c4_StringArray::Add(const char* newElement)
+{
+ int n = _ptrs.Add(0);
+ SetAt(n, newElement);
+ return n;
+}
+
+void c4_StringArray::InsertAt(int nIndex, const char* newElement, int nCount)
+{
+ _ptrs.InsertAt(nIndex, 0, nCount);
+
+ while (--nCount >= 0)
+ SetAt(nIndex++, newElement);
+}
+
+void c4_StringArray::RemoveAt(int nIndex, int nCount)
+{
+ for (int i = 0; i < nCount; ++i)
+ SetAt(nIndex + i, 0);
+
+ _ptrs.RemoveAt(nIndex, nCount);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // q4_UNIV
diff --git a/akregator/src/mk4storage/metakit/src/univ.h b/akregator/src/mk4storage/metakit/src/univ.h
new file mode 100644
index 000000000..5558e8a4c
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/src/univ.h
@@ -0,0 +1,115 @@
+// univ.h --
+// $Id$
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit/
+
+/** @file
+ * Definition of the container classes
+ */
+
+#define q4_UNIV 1
+
+#include "mk4str.h"
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_BaseArray
+{
+public:
+ c4_BaseArray ();
+ ~c4_BaseArray ();
+
+ int GetLength() const;
+ void SetLength(int nNewSize);
+
+ const void* GetData(int nIndex) const;
+ void* GetData(int nIndex);
+
+ void Grow(int nIndex);
+
+ void InsertAt(int nIndex, int nCount);
+ void RemoveAt(int nIndex, int nCount);
+
+private:
+ char* _data;
+ int _size;
+// char _buffer[4];
+};
+
+class c4_PtrArray
+{
+public:
+ c4_PtrArray ();
+ ~c4_PtrArray ();
+
+ int GetSize() const;
+ void SetSize(int nNewSize, int nGrowBy = -1);
+
+ void* GetAt(int nIndex) const;
+ void SetAt(int nIndex, const void* newElement);
+ void*& ElementAt(int nIndex);
+
+ int Add(void* newElement);
+
+ void InsertAt(int nIndex, void* newElement, int nCount = 1);
+ void RemoveAt(int nIndex, int nCount = 1);
+
+private:
+ static int Off(int n_);
+
+ c4_BaseArray _vector;
+};
+
+class c4_DWordArray
+{
+public:
+ c4_DWordArray ();
+ ~c4_DWordArray ();
+
+ int GetSize() const;
+ void SetSize(int nNewSize, int nGrowBy = -1);
+
+ t4_i32 GetAt(int nIndex) const;
+ void SetAt(int nIndex, t4_i32 newElement);
+ t4_i32& ElementAt(int nIndex);
+
+ int Add(t4_i32 newElement);
+
+ void InsertAt(int nIndex, t4_i32 newElement, int nCount = 1);
+ void RemoveAt(int nIndex, int nCount = 1);
+
+private:
+ static int Off(int n_);
+
+ c4_BaseArray _vector;
+};
+
+class c4_StringArray
+{
+public:
+ c4_StringArray ();
+ ~c4_StringArray ();
+
+ int GetSize() const;
+ void SetSize(int nNewSize, int nGrowBy = -1);
+
+ const char* GetAt(int nIndex) const;
+ void SetAt(int nIndex, const char* newElement);
+// c4_String& ElementAt(int nIndex);
+
+ int Add(const char* newElement);
+
+ void InsertAt(int nIndex, const char* newElement, int nCount = 1);
+ void RemoveAt(int nIndex, int nCount = 1);
+
+private:
+ c4_PtrArray _ptrs;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+#if q4_INLINE
+ #include "univ.inl"
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+
diff --git a/akregator/src/mk4storage/metakit/src/univ.inl b/akregator/src/mk4storage/metakit/src/univ.inl
new file mode 100644
index 000000000..45b086fb2
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/src/univ.inl
@@ -0,0 +1,126 @@
+// univ.inl --
+// $Id$
+// This is part of Metakit, see http://www.equi4.com/metakit/
+
+/** @file
+ * Inlined members of the container classes
+ */
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_BaseArray
+
+d4_inline int c4_BaseArray::GetLength() const
+{
+ return _size;
+}
+
+d4_inline const void* c4_BaseArray::GetData(int nIndex) const
+{
+ return _data + nIndex;
+}
+
+d4_inline void* c4_BaseArray::GetData(int nIndex)
+{
+ return _data + nIndex;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_PtrArray
+
+d4_inline c4_PtrArray::c4_PtrArray ()
+{
+}
+
+d4_inline c4_PtrArray::~c4_PtrArray ()
+{
+}
+
+d4_inline int c4_PtrArray::Off(int n_)
+{
+ return n_ * sizeof (void*);
+}
+
+d4_inline int c4_PtrArray::GetSize() const
+{
+ return _vector.GetLength() / sizeof (void*);
+}
+
+d4_inline void c4_PtrArray::SetSize(int nNewSize, int)
+{
+ _vector.SetLength(Off(nNewSize));
+}
+
+d4_inline void* c4_PtrArray::GetAt(int nIndex) const
+{
+ return *(void* const*) _vector.GetData(Off(nIndex));
+}
+
+d4_inline void c4_PtrArray::SetAt(int nIndex, const void* newElement)
+{
+ *(const void**) _vector.GetData(Off(nIndex)) = newElement;
+}
+
+d4_inline void*& c4_PtrArray::ElementAt(int nIndex)
+{
+ return *(void**) _vector.GetData(Off(nIndex));
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_DWordArray
+
+d4_inline c4_DWordArray::c4_DWordArray ()
+{
+}
+
+d4_inline c4_DWordArray::~c4_DWordArray ()
+{
+}
+
+d4_inline int c4_DWordArray::Off(int n_)
+{
+ return n_ * sizeof (t4_i32);
+}
+
+d4_inline int c4_DWordArray::GetSize() const
+{
+ return _vector.GetLength() / sizeof (t4_i32);
+}
+
+d4_inline void c4_DWordArray::SetSize(int nNewSize, int)
+{
+ _vector.SetLength(Off(nNewSize));
+}
+
+d4_inline t4_i32 c4_DWordArray::GetAt(int nIndex) const
+{
+ return *(const t4_i32*) _vector.GetData(Off(nIndex));
+}
+
+d4_inline void c4_DWordArray::SetAt(int nIndex, t4_i32 newElement)
+{
+ *(t4_i32*) _vector.GetData(Off(nIndex)) = newElement;
+}
+
+d4_inline t4_i32& c4_DWordArray::ElementAt(int nIndex)
+{
+ return *(t4_i32*) _vector.GetData(Off(nIndex));
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_StringArray
+
+d4_inline c4_StringArray::c4_StringArray ()
+{
+}
+
+d4_inline int c4_StringArray::GetSize() const
+{
+ return _ptrs.GetSize();
+}
+
+d4_inline const char* c4_StringArray::GetAt(int nIndex) const
+{
+ return (const char*) _ptrs.GetAt(nIndex);
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/akregator/src/mk4storage/metakit/src/view.cpp b/akregator/src/mk4storage/metakit/src/view.cpp
new file mode 100644
index 000000000..af2fc9fa2
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/src/view.cpp
@@ -0,0 +1,1271 @@
+// view.cpp --
+// $Id$
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit/
+
+/** @file
+ * Implementation of main classes not involved in persistence
+ */
+
+#include "header.h"
+#include "derived.h"
+#include "custom.h"
+#include "store.h" // for RelocateRows
+#include "field.h" // for RelocateRows
+#include "persist.h"
+#include "remap.h"
+
+#if !q4_INLINE
+#include "mk4.inl"
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_ThreadLock
+
+class c4_ThreadLock
+{
+public:
+ c4_ThreadLock ();
+
+ class Hold
+ {
+ public:
+ Hold ();
+ ~Hold ();
+ };
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+#if q4_MULTI
+
+#if q4_WIN32
+
+/*
+ * On Win32, use a critical section to protect the global symbol table.
+ * Also uses special thread-safe calls to inc/dec all reference counts.
+ *
+ * This implementation replaces the previous use of TLS, which cannot
+ * be used without special tricks in dynamically loaded DLL's, as is
+ * required for OCX/ActiveX use (which uses LoadLibrary).
+ *
+ * Note: Could have used MFC's CCriticalSection and CSingleLock classes,
+ * but the code below is so trivial that it hardly matters.
+ */
+
+#if q4_MSVC && !q4_STRICT
+#pragma warning(disable: 4201) // nonstandard extension used : ...
+#endif
+#include <windows.h>
+
+ static CRITICAL_SECTION gCritSect;
+
+ c4_ThreadLock::c4_ThreadLock ()
+ {
+ InitializeCriticalSection(&gCritSect);
+ }
+
+ c4_ThreadLock::Hold::Hold ()
+ {
+ EnterCriticalSection(&gCritSect);
+ }
+
+ c4_ThreadLock::Hold::~Hold ()
+ {
+ LeaveCriticalSection(&gCritSect);
+ }
+
+#else /* q4_WIN32 */
+
+#include <pthread.h>
+
+ static pthread_mutex_t gMutex;
+
+ d4_inline c4_ThreadLock::c4_ThreadLock ()
+ {
+ pthread_mutex_init(&gMutex, 0);
+ }
+
+ d4_inline c4_ThreadLock::Hold::Hold ()
+ {
+ d4_dbgdef(int r =)
+ pthread_mutex_lock(&gMutex);
+ d4_assert(r == 0);
+ }
+
+ d4_inline c4_ThreadLock::Hold::~Hold ()
+ {
+ d4_dbgdef(int r =)
+ pthread_mutex_unlock(&gMutex);
+ d4_assert(r == 0);
+ }
+
+#endif /* q4_WIN32 */
+
+#else /* q4_MULTI */
+
+// All other implementations revert to the simple "thread-less" case.
+
+ d4_inline c4_ThreadLock::c4_ThreadLock ()
+ {
+ }
+
+ d4_inline c4_ThreadLock::Hold::Hold ()
+ {
+ }
+
+ d4_inline c4_ThreadLock::Hold::~Hold ()
+ {
+ }
+
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+
+#if q4_LOGPROPMODS
+
+ static FILE* sPropModsFile = 0;
+ static int sPropModsProp = -1;
+
+FILE* f4_LogPropMods(FILE* fp_, int propId_)
+{
+ FILE* prevfp = sPropModsFile;
+ sPropModsFile = fp_;
+ sPropModsProp = propId_;
+ return prevfp;
+}
+
+void f4_DoLogProp(const c4_Handler* hp_, int id_, const char* fmt_, int arg_)
+{
+ if (sPropModsFile != 0 && (sPropModsProp < 0 || sPropModsProp == id_)) {
+ fprintf(sPropModsFile, "handler 0x%x id %d: ", hp_, id_);
+ fprintf(sPropModsFile, fmt_, arg_);
+ }
+}
+
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+
+/** @class c4_View
+ *
+ * A collection of data rows. This is the central public data structure of
+ * Metakit (often called "table", "array", or "relation" in other systems).
+ *
+ * Views are smart pointers to the actual collections, setting a view to a new
+ * value does not alter the collection to which this view pointed previously.
+ *
+ * The elements of views can be referred to by their 0-based index, which
+ * produces a row-reference of type c4_RowRef. These row references can
+ * be copied, used to get or set properties, or dereferenced (in which case
+ * an object of class c4_Row is returned). Taking the address of a row
+ * reference produces a c4_Cursor, which acts very much like a pointer.
+ *
+ * The following code creates a view with 1 row and 2 properties:
+ * @code
+ * c4_StringProp pName ("name");
+ * c4_IntProp pAge ("age");
+ *
+ * c4_Row data;
+ * pName (data) = "John Williams";
+ * pAge (data) = 43;
+ *
+ * c4_View myView;
+ * myView.Add(row);
+ * @endcode
+ */
+
+/// Construct a view based on a sequence
+c4_View::c4_View (c4_Sequence* seq_)
+ : _seq (seq_)
+{
+ if (!_seq)
+ _seq = d4_new c4_HandlerSeq (0);
+
+ _IncSeqRef();
+}
+
+/// Construct a view based on a custom viewer
+c4_View::c4_View (c4_CustomViewer* viewer_)
+ : _seq (0)
+{
+ d4_assert(viewer_);
+
+ _seq = d4_new c4_CustomSeq (viewer_);
+
+ _IncSeqRef();
+}
+
+/// Construct a view based on an input stream
+c4_View::c4_View (c4_Stream* stream_)
+ : _seq (c4_Persist::Load(stream_))
+{
+ if (_seq == 0)
+ _seq = d4_new c4_HandlerSeq (0);
+
+ _IncSeqRef();
+}
+
+/// Construct an empty view with one property
+c4_View::c4_View (const c4_Property& prop_)
+ : _seq (d4_new c4_HandlerSeq (0))
+{
+ _IncSeqRef();
+
+ _seq->PropIndex(prop_);
+}
+
+/// Copy constructor
+c4_View::c4_View (const c4_View& view_)
+ : _seq (view_._seq)
+{
+ _IncSeqRef();
+}
+
+/// Makes this view the same as another one.
+c4_View& c4_View::operator= (const c4_View& view_)
+{
+ if (_seq != view_._seq) {
+ _DecSeqRef();
+ _seq = view_._seq;
+ _IncSeqRef();
+ }
+ return *this;
+}
+
+/** Get a single data item in a generic way
+ *
+ * This can be used to access view data in a generalized way.
+ * Useful for c4_CustomViewers which are based on other views.
+ * @return true if the item is non-empty
+ */
+bool c4_View::GetItem(int row_, int col_, c4_Bytes& buf_) const
+{
+ const c4_Property& prop = NthProperty(col_);
+ return prop (GetAt(row_)).GetData(buf_);
+}
+
+/// Set a single data item in a generic way
+void c4_View::SetItem(int row_, int col_, const c4_Bytes& buf_) const
+{
+ const c4_Property& prop = NthProperty(col_);
+ prop (GetAt(row_)).SetData(buf_);
+}
+
+/// Set an entry, growing the view if needed
+void c4_View::SetAtGrow(int index_, const c4_RowRef& newElem_)
+{
+ if (index_ >= GetSize())
+ SetSize(index_ + 1);
+
+ _seq->SetAt(index_, &newElem_);
+}
+
+/** Add a new entry, same as "SetAtGrow(GetSize(), ...)"
+ * @return the index of the newly added row
+ */
+int c4_View::Add(const c4_RowRef& newElem_)
+{
+ int i = GetSize();
+ InsertAt(i, newElem_);
+ return i;
+}
+
+/** Construct a new view with a copy of the data
+ *
+ * The copy is a deep copy, because subviews are always copied in full.
+ */
+c4_View c4_View::Duplicate() const
+{
+ // insert all rows, sharing any subviews as needed
+ c4_View result = Clone();
+ result.InsertAt(0, _seq);
+ return result;
+}
+
+/** Constructs a new view with the same structure but no data
+ *
+ * Structural information can only be maintain for the top level,
+ * subviews will be included but without any properties themselves.
+ */
+c4_View c4_View::Clone() const
+{
+ c4_View view;
+
+ for (int i = 0; i < NumProperties(); ++i)
+ view._seq->PropIndex(NthProperty(i));
+
+ return view;
+}
+
+/** Adds a property column to a view if not already present
+ * @return 0-based column position of the property
+ */
+int c4_View::AddProperty(const c4_Property& prop_)
+{
+ return _seq->PropIndex(prop_);
+}
+
+/** Returns the N-th property (using zero-based indexing)
+ * @return reference to the specified property
+ */
+const c4_Property& c4_View::NthProperty(
+ int index_ ///< the zero-based property index
+ ) const
+{
+ return _seq->NthHandler(index_).Property();
+}
+
+/** Find the index of a property, given its name
+ * @return 0-based column index
+ * @retval -1 property not present in this view
+ */
+int c4_View::FindPropIndexByName(
+ const char* name_ ///< property name (case insensitive)
+ ) const
+{
+ // use a slow linear scan to find the untyped property by name
+ for (int i = 0; i < NumProperties(); ++i) {
+ c4_String s = NthProperty(i).Name();
+ if (s.CompareNoCase(name_) == 0)
+ return i;
+ }
+
+ return -1;
+}
+
+/** Defines a column for a property.
+ *
+ * The following code defines an empty view with three properties:
+ * @code
+ * c4_IntProp p1, p2, p3;
+ * c4_View myView = (p1, p2, p3);
+ * @endcode
+ * @return the new view object (without any data rows)
+ * @sa c4_Property
+ */
+c4_View c4_View::operator, (const c4_Property& prop_) const
+{
+ c4_View view = Clone();
+ view.AddProperty(prop_);
+ return view;
+}
+
+/// Insert copies of all rows of the specified view
+void c4_View::InsertAt(int index_, const c4_View& view_)
+{
+ int n = view_.GetSize();
+ if (n > 0) {
+ c4_Row empty;
+
+ InsertAt(index_, empty, n);
+
+ for (int i = 0; i < n; ++i)
+ SetAt(index_ + i, view_[i]);
+ }
+}
+
+bool c4_View::IsCompatibleWith(const c4_View& dest_) const
+{
+ // can't determine table without handlers (and can't be a table)
+ if (NumProperties() == 0 || dest_.NumProperties() == 0)
+ return false;
+
+ c4_Sequence* s1 = _seq;
+ c4_Sequence* s2 = dest_._seq;
+ c4_HandlerSeq* h1 = (c4_HandlerSeq*) s1->HandlerContext(0);
+ c4_HandlerSeq* h2 = (c4_HandlerSeq*) s2->HandlerContext(0);
+
+ // both must be real handler views, not derived ones
+ if (h1 != s1 || h2 != s2)
+ return false;
+
+ // both must not contain any temporary handlers
+ if (s1->NumHandlers() != h1->NumFields() ||
+ s2->NumHandlers() != h2->NumFields())
+ return false;
+
+ // both must be in the same storage
+ if (h1->Persist() == 0 || h1->Persist() != h2->Persist())
+ return false;
+
+ // both must have the same structure (is this expensive?)
+ c4_String d1 = h1->Definition().Description(true);
+ c4_String d2 = h1->Definition().Description(true);
+ return d1 == d2; // ignores all names
+}
+
+/** Move attached rows to somewhere else in same storage
+ *
+ * There is a lot of trickery going on here. The whole point of this
+ * code is that moving rows between (compatible!) subviews should not
+ * use copying when potentially large memo's and subviews are involved.
+ * In that case, the best solution is really to move pointers, not data.
+ */
+void c4_View::RelocateRows(int from_, int count_, c4_View& dest_, int pos_)
+{
+ if (count_ < 0)
+ count_ = GetSize() - from_;
+ if (pos_ < 0)
+ pos_ = dest_.GetSize();
+
+ d4_assert(0 <= from_ && from_ <= GetSize());
+ d4_assert(0 <= count_ && from_ + count_ <= GetSize());
+ d4_assert(0 <= pos_ && pos_ <= dest_.GetSize());
+
+ if (count_ > 0) {
+ // the destination must not be inside the source rows
+ d4_assert(&dest_ != this || from_ > pos_ || pos_ >= from_ + count_);
+
+ // this test is slow, so do it only as a debug check
+ d4_assert(IsCompatibleWith(dest_));
+
+ // make space, swap rows, drop originals
+ c4_Row empty;
+ dest_.InsertAt(pos_, empty, count_);
+
+ // careful if insert moves origin
+ if (&dest_ == this && pos_ <= from_)
+ from_ += count_;
+
+ for (int i = 0; i < count_; ++i)
+ ((c4_HandlerSeq*) _seq)->ExchangeEntries(from_ + i,
+ *(c4_HandlerSeq*) dest_._seq, pos_ + i);
+
+ RemoveAt(from_, count_);
+ }
+}
+
+/** Create view with all rows in natural (property-wise) order
+ *
+ * The result is virtual, it merely maintains a permutation to access the
+ * underlying view. This "derived" view uses change notification to track
+ * changes to the underlying view, but unfortunately there are some major
+ * limitations with this scheme - one of them being that deriving another
+ * view from this sorted one will not properly track changes.
+ */
+c4_View c4_View::Sort() const
+{
+ return f4_CreateSort(*_seq);
+}
+
+/** Create view sorted according to the specified properties
+ *
+ * The result is virtual, it merely maintains a permutation to access the
+ * underlying view. This "derived" view uses change notification to track
+ * changes to the underlying view, but unfortunately there are some major
+ * limitations with this scheme - one of them being that deriving another
+ * view from this sorted one will not properly track changes.
+ */
+c4_View c4_View::SortOn(const c4_View& up_) const
+{
+ c4_Sequence* seq = f4_CreateProject(*_seq, *up_._seq, true);
+
+ return f4_CreateSort(*seq);
+}
+
+/** Create sorted view, with some properties sorted in reverse
+ *
+ * The result is virtual, it merely maintains a permutation to access the
+ * underlying view. This "derived" view uses change notification to track
+ * changes to the underlying view, but unfortunately there are some major
+ * limitations with this scheme - one of them being that deriving another
+ * view from this sorted one will not properly track changes.
+ */
+c4_View c4_View::SortOnReverse(
+ const c4_View& up_, ///< the view which defines the sort order
+ const c4_View& down_ ///< subset of up_, defines reverse order
+ ) const
+{
+ c4_Sequence* seq = f4_CreateProject(*_seq, *up_._seq, true);
+
+ return f4_CreateSort(*seq, down_._seq);
+}
+
+/** Create view with rows matching the specified value
+ *
+ * The result is virtual, it merely maintains a permutation to access the
+ * underlying view. This "derived" view uses change notification to track
+ * changes to the underlying view, but this only works when based on views
+ * which properly generate change notifications (.e. raw views, other
+ * selections, and projections).
+ */
+c4_View c4_View::Select(const c4_RowRef& crit_) const
+{
+ return f4_CreateFilter(*_seq, &crit_, &crit_);
+}
+
+/** Create view with row values within the specified range
+ *
+ * The result is virtual, it merely maintains a permutation to access the
+ * underlying view. This "derived" view uses change notification to track
+ * changes to the underlying view, but this only works when based on views
+ * which properly generate change notifications (.e. raw views, other
+ * selections, and projections).
+ */
+c4_View c4_View::SelectRange(
+ const c4_RowRef& low_, ///< values of the lower bounds (inclusive)
+ const c4_RowRef& high_ ///< values of the upper bounds (inclusive)
+ ) const
+{
+ return f4_CreateFilter(*_seq, &low_, &high_);
+}
+
+/** Create view with the specified property arrangement
+ *
+ * The result is virtual, it merely maintains a permutation to access the
+ * underlying view. This "derived" view uses change notification to track
+ * changes to the underlying view, but this only works when based on views
+ * which properly generate change notifications (.e. raw views, selections,
+ * and other projections).
+ */
+c4_View c4_View::Project(const c4_View& in_) const
+{
+ return f4_CreateProject(*_seq, *in_._seq, false);
+}
+
+/** Create derived view with some properties omitted
+ *
+ * The result is virtual, it merely maintains a permutation to access the
+ * underlying view. This "derived" view uses change notification to track
+ * changes to the underlying view, but this only works when based on views
+ * which properly generate change notifications (.e. raw views, selections,
+ * and other projections).
+ */
+c4_View c4_View::ProjectWithout(const c4_View& out_) const
+{
+ return f4_CreateProject(*_seq, *_seq, false, out_._seq);
+}
+
+/** Create view which is a segment/slice (default is up to end)
+ *
+ * Returns a view which is a subset, either a contiguous range, or
+ * a "slice" with element taken from every step_ entries. If the
+ * step is negative, the same entries are returned, but in reverse
+ * order (start_ is still lower index, it'll then be returned last).
+ *
+ * This view operation is based on a custom viewer and is modifiable.
+ */
+c4_View c4_View::Slice(int first_, int limit_, int step_) const
+{
+ return f4_CustSlice(*_seq, first_, limit_, step_);
+}
+
+/** Create view which is the cartesian product with given view
+ *
+ * The cartesian product is defined as every combination of rows
+ * in both views. The number of entries is the product of the
+ * number of entries in the two views, properties which are present
+ * in both views will use the values defined in this view.
+ *
+ * This view operation is based on a read-only custom viewer.
+ */
+c4_View c4_View::Product(const c4_View& view_) const
+{
+ return f4_CustProduct(*_seq, view_);
+}
+
+/** Create view which remaps another given view
+ *
+ * Remapping constructs a view with the rows indicated by another
+ * view. The first property in the order_ view must be an int
+ * property with index values referring to this one. The size of
+ * the resulting view is determined by the order_ view and can
+ * differ, for example to act as a subset selection (if smaller).
+ *
+ * This view operation is based on a custom viewer and is modifiable.
+ */
+c4_View c4_View::RemapWith(const c4_View& view_) const
+{
+ return f4_CustRemapWith(*_seq, view_);
+}
+
+/** Create view which pairs each row with corresponding row
+ *
+ * This is like a row-by-row concatenation. Both views must have
+ * the same number of rows, the result has all properties from
+ * this view plus any other properties from the other view.
+ *
+ * This view operation is based on a custom viewer and is modifiable.
+ */
+c4_View c4_View::Pair(const c4_View& view_) const
+{
+ return f4_CustPair(*_seq, view_);
+}
+
+/** Create view with rows from another view appended
+ *
+ * Constructs a view which has all rows of this view, and all rows
+ * of the second view appended. The structure of the second view
+ * is assumed to be identical to this one. This operation is a bit
+ * similar to appending all rows from the second view, but it does
+ * not actually store the result anywhere, it just looks like it.
+ *
+ * This view operation is based on a custom viewer and is modifiable.
+ */
+c4_View c4_View::Concat(const c4_View& view_) const
+{
+ return f4_CustConcat(*_seq, view_);
+}
+
+/** Create view with one property renamed (must be of same type)
+ *
+ * This view operation is based on a custom viewer and is modifiable.
+ */
+c4_View c4_View::Rename(const c4_Property& old_, const c4_Property& new_) const
+{
+ return f4_CustRename(*_seq, old_, new_);
+}
+
+/** Create view with a subview, grouped by the specified properties
+ *
+ * This operation is similar to the SQL 'GROUP BY', but it takes
+ * advantage of the fact that Metakit supports nested views. The
+ * view returned from this member has one row per distinct group,
+ * with an extra view property holding the remaining properties.
+ * If there are N rows in the original view matching key X, then
+ * the result is a row for key X, with a subview of N rows. The
+ * properties of the subview are all the properties not in the key.
+ *
+ * This view operation is based on a read-only custom viewer.
+ */
+c4_View c4_View::GroupBy(
+ const c4_View& keys_, ///< properties in this view determine grouping
+ const c4_ViewProp& result_ ///< name of new subview defined in result
+ ) const
+{
+ return f4_CustGroupBy(*_seq, keys_, result_);
+}
+
+/** Create view with count of duplicates, when grouped by key
+ *
+ * This is similar to c4_View::GroupBy, but it determines only the
+ * number of rows in each group and does not create a nested view.
+ *
+ * This view operation is based on a read-only custom viewer.
+ */
+c4_View c4_View::Counts(
+ const c4_View& keys_, ///< properties in this view determine grouping
+ const c4_IntProp& result_ ///< new count property defined in result
+ ) const
+{
+ return f4_CustGroupBy(*_seq, keys_, result_); // third arg is c4_IntProp
+}
+
+/** Create view with all duplicate rows omitted
+ *
+ * This view operation is based on a read-only custom viewer.
+ */
+c4_View c4_View::Unique() const
+{
+ c4_IntProp count ("#N#");
+ return Counts(Clone(), count).ProjectWithout(count);
+}
+
+/** Create view which is the set union (assumes no duplicate rows)
+ *
+ * Calculates the set union. This will only work if both input
+ * views are sets, i.e. they have no duplicate rows in them.
+ *
+ * This view operation is based on a read-only custom viewer.
+ */
+c4_View c4_View::Union(const c4_View& view_) const
+{
+ return Concat(view_).Unique();
+}
+
+/** Create view with all rows also in the given view (no dups)
+ *
+ * Calculates the set intersection. This will only work if both
+ * input views are sets, i.e. they have no duplicate rows in them.
+ *
+ * This view operation is based on a read-only custom viewer.
+ */
+c4_View c4_View::Intersect(const c4_View& view_) const
+{
+ c4_View v = Concat(view_);
+
+ // assume neither view has any duplicates
+ c4_IntProp count ("#N#");
+ return v.Counts(Clone(), count).Select(count [2]).ProjectWithout(count);
+}
+
+/** Create view with all rows not in both views (no dups)
+ *
+ * Calculates the "XOR" of two sets. This will only work if both
+ * input views are sets, i.e. they have no duplicate rows in them.
+ *
+ * This view operation is based on a read-only custom viewer.
+ */
+c4_View c4_View::Different(const c4_View& view_) const
+{
+ c4_View v = Concat(view_);
+
+ // assume neither view has any duplicates
+ c4_IntProp count ("#N#");
+ return v.Counts(Clone(), count).Select(count [1]).ProjectWithout(count);
+}
+
+/** Create view with all rows not in the given view (no dups)
+ *
+ * Calculates set-difference of this view minus arg view. Result
+ * is a subset, unlike c4_View::Different. Will only work if both
+ * input views are sets, i.e. they have no duplicate rows in them.
+ *
+ * This view operation is based on a read-only custom viewer.
+ */
+c4_View c4_View::Minus(
+ const c4_View& view_ ///< the second view
+ ) const
+{
+ // inefficient: calculate difference, then keep only those in self
+ return Intersect(Different(view_));
+}
+
+/** Create view with a specific subview expanded, like a join
+ *
+ * This operation is the inverse of c4_View::GroupBy, expanding
+ * all rows in specified subview and returning a view which looks
+ * as if the rows in each subview were "expanded in place".
+ *
+ * This view operation is based on a read-only custom viewer.
+ */
+c4_View c4_View::JoinProp(
+ const c4_ViewProp& sub_, ///< name of the subview to expand
+ bool outer_ ///< true: keep rows with empty subviews
+ ) const
+{
+ return f4_CustJoinProp(*_seq, sub_, outer_);
+}
+
+/** Create view which is the relational join on the given keys
+ *
+ * This view operation is based on a read-only custom viewer.
+ */
+c4_View c4_View::Join(
+ const c4_View& keys_, ///< properties in this view determine the join
+ const c4_View& view_, ///< second view participating in the join
+ bool outer_ ///< true: keep rows with no match in second view
+ ) const
+{
+ // inefficient: calculate difference, then keep only those in self
+ return f4_CustJoin(*_seq, keys_, view_, outer_);
+}
+
+/** Create an identity view which only allows reading
+ *
+ * This view operation is based on a custom viewer.
+ */
+c4_View c4_View::ReadOnly() const
+{
+ return f4_CreateReadOnly(*_seq);
+}
+
+/** Create mapped view which adds a hash lookup layer
+ *
+ * This view creates and manages a special hash map view, to implement a
+ * fast find on the key. The key is defined to consist of the first
+ * numKeys_ properties of the underlying view.
+ *
+ * The map_ view must be empty the first time this hash view is used, so
+ * that Metakit can fill it based on whatever rows are already present in
+ * the underlying view. After that, neither the underlying view nor the
+ * map view may be modified other than through this hash mapping layer.
+ * The defined structure of the map view must be "_H:I,_R:I".
+ *
+ * This view is modifiable. Insertions and changes to key field properties
+ * can cause rows to be repositioned to maintain hash uniqueness. Careful:
+ * when a row is changed in such a way that its key is the same as in another
+ * row, that other row will be deleted from the view.
+ *
+ * Example of use:
+ * @code
+ * c4_View data = storage.GetAs("people[name:S,age:I]");
+ * c4_View datah = storage.GetAs("people_H[_H:I,_R:I]");
+ * c4_View hash = raw.Hash(datah, 1);
+ * ... hash.GetSize() ...
+ * hash.Add(...)
+ * @endcode
+ */
+c4_View c4_View::Hash(const c4_View& map_, int numKeys_) const
+{
+ return f4_CreateHash(*_seq, numKeys_, map_._seq);
+}
+
+/** Create mapped view which blocks its rows in two levels
+ *
+ * This view acts like a large flat view, even though the actual rows are
+ * stored in blocks, which are rebalanced automatically to maintain a good
+ * trade-off between block size and number of blocks.
+ *
+ * The underlying view must be defined with a single view property, with
+ * the structure of the subview being as needed. An example of a blocked
+ * view definition which will act like a single one containing 2 properties:
+ * @code
+ * c4_View raw = storage.GetAs("people[_B[name:S,age:I]]");
+ * c4_View flat = raw.Blocked();
+ * ... flat.GetSize() ...
+ * flat.InsertAt(...)
+ * @endcode
+ *
+ * This view operation is based on a custom viewer and is modifiable.
+ */
+c4_View c4_View::Blocked() const
+{
+ return f4_CreateBlocked(*_seq);
+}
+
+/** Create mapped view which keeps its rows ordered
+ *
+ * This is an identity view, which has as only use to inform Metakit that
+ * the underlying view can be considered to be sorted on its first numKeys_
+ * properties. The effect is that c4_View::Find will try to use binary
+ * search when the search includes key properties (results will be identical
+ * to unordered views, the find will just be more efficient).
+ *
+ * This view is modifiable. Insertions and changes to key field properties
+ * can cause rows to be repositioned to maintain the sort order. Careful:
+ * when a row is changed in such a way that its key is the same as in another
+ * row, that other row will be deleted from the view.
+ *
+ * This view can be combined with c4_View::Blocked, to create a 2-level
+ * btree structure.
+ */
+c4_View c4_View::Ordered(int numKeys_) const
+{
+ return f4_CreateOrdered(*_seq, numKeys_);
+}
+
+/** Create mapped view which maintains an index permutation
+ *
+ * This is an identity view which somewhat resembles the ordered view, it
+ * maintains a secondary "map" view to contain the permutation to act as
+ * an index. The indexed view presents the same order of rows as the
+ * underlying view, but the index map is set up in such a way that binary
+ * search is possible on the keys specified. When the "unique" parameter
+ * is true, insertions which would create a duplicate key are ignored.
+ *
+ * This view is modifiable. Careful: when a row is changed in such a way
+ * that its key is the same as in another row, that other row will be
+ * deleted from the view.
+ */
+c4_View c4_View::Indexed(const c4_View& map_, const c4_View& props_,
+ bool unique_) const
+{
+ return f4_CreateIndexed(*_seq, *map_._seq, props_, unique_);
+}
+
+/** Return the index of the specified row in this view (or -1)
+ *
+ * This function can be used to "unmap" an index of a derived view back
+ * to the original underlying view.
+ */
+int c4_View::GetIndexOf(const c4_RowRef& row_) const
+{
+ c4_Cursor cursor = &row_;
+
+ return cursor._seq->RemapIndex(cursor._index, _seq);
+}
+
+/// Restrict the search range for rows
+int c4_View::RestrictSearch(const c4_RowRef& c_, int& pos_, int& count_)
+{
+ return _seq->RestrictSearch(&c_, pos_, count_) ? 0 : ~0;
+}
+
+/** Find index of the the next entry matching the specified key.
+ *
+ * Defaults to linear search, but hash- and ordered-views will use a better
+ * algorithm if possible. Only the properties present in the search key
+ * are used to determine whether a row matches the key.
+ * @return position where match occurred
+ * @retval -1 if not found
+ */
+int c4_View::Find(
+ const c4_RowRef& crit_, ///< the value to look for
+ int start_ ///< the index to start with
+ ) const
+{
+ d4_assert(start_ >= 0);
+
+ c4_Row copy = crit_; // the lazy (and slow) solution: make a copy
+
+ int count = GetSize() - start_;
+ if (_seq->RestrictSearch(&copy, start_, count)) {
+ c4_View refView = copy.Container();
+ c4_Sequence* refSeq = refView._seq;
+ d4_assert(refSeq != 0);
+
+ c4_Bytes data;
+
+ for (int j = 0; j < count; ++j) {
+ int i;
+
+ for (i = 0; i < refSeq->NumHandlers(); ++i) {
+ c4_Handler& h = refSeq->NthHandler(i); // no context issues
+
+ if (!_seq->Get(start_ + j, h.PropId(), data))
+ h.ClearBytes(data);
+
+ if (h.Compare(0, data) != 0) // always row 0
+ break;
+ }
+
+ if (i == refSeq->NumHandlers())
+ return start_ + j;
+ }
+ }
+
+ return -1;
+}
+
+/** Search for a key, using the native sort order of the view
+ * @return position where found, or where it may be inserted,
+ * this position can also be just past the last row
+ */
+int c4_View::Search(const c4_RowRef& crit_) const
+{
+ int l = -1, u = GetSize();
+ while (l + 1 != u) {
+ const int m = (l + u) >> 1;
+ if (_seq->Compare(m, &crit_) < 0)
+ //if (crit_ > (*this)[m]) // Dec 2001: see comments below
+ l = m;
+ else
+ u = m;
+ }
+
+ return u;
+}
+
+/// Return number of matching keys, and pos of first one as arg
+int c4_View::Locate(const c4_RowRef& crit_, int* pos_) const
+{
+ // Dec 2001: fixed a problem with searching of partial rows.
+ //
+ // There is an *extremely* tricky issue in here, in that the
+ // comparison operator for rows is not symmetric. So in the
+ // general case, "a == b" is not euivalent to "b == a". This
+ // is without doubt a design mistake (and should have at least
+ // been named differently).
+ //
+ // The reason is that the number of properties in both rowrefs
+ // need not be the same. Only the properties of the leftmost
+ // rowref are compared against the other one. This also applies
+ // to the other comparisons, i.e. !=, <, >, <=, and >=.
+ //
+ // All Compare calls below have been changed to use comparisons
+ // in the proper order and now use "rowref <op> rowref" syntax.
+
+ c4_Cursor curr (*(c4_Sequence*) _seq, 0); // loses const
+
+ int l = -1, u = GetSize();
+ while (l + 1 != u) {
+ curr._index = (l + u) >> 1;
+ if (crit_ > *curr)
+ l = curr._index;
+ else
+ u = curr._index;
+ }
+
+ if (pos_ != 0)
+ *pos_ = u;
+
+ // only look for more if the search hit an exact match
+ curr._index = u;
+ if (u == GetSize() || crit_ != *curr)
+ return 0;
+
+ // as Jon Bentley wrote in DDJ Apr 2000, setting l2 to -1 is better than u
+ int l2 = -1, u2 = GetSize();
+ while (l2 + 1 != u2) {
+ curr._index = (l2 + u2) >> 1;
+ if (crit_ >= *curr)
+ l2 = curr._index;
+ else
+ u2 = curr._index;
+ }
+
+ return u2 - u;
+}
+
+/// Compare two views lexicographically (rows 0..N-1).
+int c4_View::Compare(const c4_View& view_) const
+{
+ if (_seq == view_._seq)
+ return 0;
+
+ int na = GetSize();
+ int nb = view_.GetSize();
+ int i;
+
+ for (i = 0; i < na && i < nb; ++i)
+ if (GetAt(i) != view_.GetAt(i))
+ return GetAt(i) < view_.GetAt(i) ? -1 : +1;
+
+ return na == nb ? 0 : i < na ? +1 : -1;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+/** @class c4_Cursor
+ *
+ * An iterator for collections of rows (views).
+ *
+ * Cursor objects can be used to point to specific entries in a view.
+ * A cursor acts very much like a pointer to a row in a view, and is
+ * returned when taking the address of a c4_RowRef. Dereferencing
+ * a cursor leads to the original row reference again. You can construct a
+ * cursor for a c4_Row, but since such rows are not part of a collection,
+ * incrementing or decrementing these cursors is meaningless (and wrong).
+ *
+ * The usual range of pointer operations can be applied to these objects:
+ * pre/post-increment and decrement, adding or subtracting integer offsets,
+ * as well as the full range of comparison operators. If two cursors
+ * point to entries in the same view, their difference can be calculated.
+ *
+ * As with regular pointers, care must be taken to avoid running off of
+ * either end of a view (the debug build includes assertions to check this).
+ */
+
+/** @class c4_RowRef
+ *
+ * Reference to a data row, can be used on either side of an assignment.
+ *
+ * Row references are created when dereferencing a c4_Cursor or when
+ * indexing an element of a c4_View. Assignment will change the
+ * corresponding item. Rows (objects of type c4_Row) are a special
+ * case of row references, consisting of a view with exactly one item.
+ *
+ * Internally, row references are very similar to cursors, in fact they are
+ * little more than a wrapper around them. The essential difference is one
+ * of semantics: comparing row references compares contents, copying row
+ * references copies the contents, whereas cursor comparison and copying
+ * deals with the pointer to the row, not its contents.
+ */
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_Row
+
+c4_Row::c4_Row ()
+ : c4_RowRef (* Allocate())
+{
+}
+
+c4_Row::c4_Row (const c4_Row& row_)
+ : c4_RowRef (* Allocate())
+{
+ operator= (row_);
+}
+
+c4_Row::c4_Row (const c4_RowRef& rowRef_)
+ : c4_RowRef (* Allocate())
+{
+ operator= (rowRef_);
+}
+
+c4_Row::~c4_Row ()
+{
+ Release(_cursor);
+}
+
+c4_Row& c4_Row::operator= (const c4_Row& row_)
+{
+ return operator= ((const c4_RowRef&) row_);
+}
+
+/// Assignment from a reference to a row.
+c4_Row& c4_Row::operator= (const c4_RowRef& rowRef_)
+{
+ d4_assert(_cursor._seq != 0);
+
+ if (_cursor != &rowRef_) {
+ d4_assert(_cursor._index == 0);
+ _cursor._seq->SetAt(0, &rowRef_);
+ }
+
+ return *this;
+}
+
+/// Adds all properties and values into this row.
+void c4_Row::ConcatRow(const c4_RowRef& rowRef_)
+{
+ d4_assert(_cursor._seq != 0);
+
+ c4_Cursor cursor = &rowRef_; // trick to access private rowRef_._cursor
+ d4_assert(cursor._seq != 0);
+
+ c4_Sequence& rhSeq = * cursor._seq;
+
+ c4_Bytes data;
+
+ for (int i = 0; i < rhSeq.NumHandlers(); ++i) {
+ c4_Handler& h = rhSeq.NthHandler(i);
+
+ h.GetBytes(cursor._index, data);
+ _cursor._seq->Set(_cursor._index, h.Property(), data);
+ }
+}
+
+c4_Row operator+ (const c4_RowRef& a_, const c4_RowRef& b_)
+{
+ c4_Row row = a_;
+ row.ConcatRow(b_);
+ return row;
+}
+
+c4_Cursor c4_Row::Allocate()
+{
+ c4_Sequence* seq = d4_new c4_HandlerSeq (0);
+ seq->IncRef();
+
+ seq->Resize(1);
+
+ return c4_Cursor (*seq, 0);
+}
+
+void c4_Row::Release(c4_Cursor row_)
+{
+ d4_assert(row_._seq != 0);
+ d4_assert(row_._index == 0);
+
+ row_._seq->DecRef();
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+/** @class c4_Property
+ *
+ * Base class for the basic data types.
+ *
+ * Property objects exist independently of view, row, and storage objects.
+ * They have a name and type, and can appear in any number of views.
+ * You will normally only use derived classes, to maintain strong typing.
+ */
+
+ // This is a workaround for the fact that the initialization order of
+ // static objects is not always adequate (implementation dependent).
+ // Extremely messy solution, to allow statically declared properties.
+ //
+ // These are the only static variables in the entire Metakit core lib.
+
+ static c4_ThreadLock* sThreadLock = 0;
+ static c4_StringArray* sPropNames = 0;
+ static c4_DWordArray* sPropCounts = 0;
+
+ /// Call this to get rid of some internal datastructues (on exit)
+ void c4_Property::CleanupInternalData()
+ {
+ delete sPropNames;
+ sPropNames = 0; // race
+
+ delete sPropCounts;
+ sPropCounts = 0; // race
+
+ delete sThreadLock;
+ sThreadLock = 0; // race
+ }
+
+c4_Property::c4_Property (char type_, const char* name_)
+ : _type (type_)
+{
+ if (sThreadLock == 0)
+ sThreadLock = d4_new c4_ThreadLock;
+
+ c4_ThreadLock::Hold lock; // grabs the lock until end of scope
+
+ if (sPropNames == 0)
+ sPropNames = d4_new c4_StringArray;
+
+ if (sPropCounts == 0)
+ sPropCounts = d4_new c4_DWordArray;
+
+ c4_String temp = name_;
+
+ _id = sPropNames->GetSize();
+ while (-- _id >= 0) {
+ const char* p = sPropNames->GetAt(_id);
+ // optimize for first char case-insensitive match
+ if (((*p ^ *name_) & ~0x20) == 0 && temp.CompareNoCase(p) == 0)
+ break;
+ }
+
+ if (_id < 0) {
+ int size = sPropCounts->GetSize();
+
+ for (_id = 0; _id < size; ++_id)
+ if (sPropCounts->GetAt(_id) == 0)
+ break;
+
+ if (_id >= size) {
+ sPropCounts->SetSize(_id + 1);
+ sPropNames->SetSize(_id + 1);
+ }
+
+ sPropCounts->SetAt(_id, 0);
+ sPropNames->SetAt(_id, name_);
+ }
+
+ Refs(+1);
+}
+
+c4_Property::c4_Property (const c4_Property& prop_)
+ : _id (prop_.GetId()), _type (prop_.Type())
+{
+ c4_ThreadLock::Hold lock;
+
+ d4_assert(sPropCounts != 0);
+ d4_assert(sPropCounts->GetAt(_id) > 0);
+
+ Refs(+1);
+}
+
+c4_Property::~c4_Property ()
+{
+ c4_ThreadLock::Hold lock;
+
+ Refs(-1);
+}
+
+void c4_Property::operator= (const c4_Property& prop_)
+{
+ c4_ThreadLock::Hold lock;
+
+ prop_.Refs(+1);
+ Refs(-1);
+
+ _id = prop_.GetId();
+ _type = prop_.Type();
+}
+
+ /// Return the name of this property
+const char* c4_Property::Name() const
+{
+ c4_ThreadLock::Hold lock;
+
+ d4_assert(sPropNames != 0);
+ return sPropNames->GetAt(_id);
+}
+
+/** Adjust the reference count
+ *
+ * This is part of the implementation and shouldn't normally be called.
+ * This code is only called with the lock held, and always thread-safe.
+ */
+void c4_Property::Refs(int diff_) const
+{
+ d4_assert(diff_ == -1 || diff_ == +1);
+
+ d4_assert(sPropCounts != 0);
+ sPropCounts->ElementAt(_id) += diff_;
+
+#if q4_CHECK
+ // get rid of the cache when the last property goes away
+ static t4_i32 sPropTotals;
+
+ sPropTotals += diff_;
+ if (sPropTotals == 0)
+ CleanupInternalData();
+#endif
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/akregator/src/mk4storage/metakit/src/viewx.cpp b/akregator/src/mk4storage/metakit/src/viewx.cpp
new file mode 100644
index 000000000..db30d14e5
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/src/viewx.cpp
@@ -0,0 +1,857 @@
+// viewx.cpp --
+// $Id$
+// This is part of Metakit, see http://www.equi4.com/metakit/
+
+/** @file
+ * Implements c4_Sequence, c4_Reference, and c4_...Ref
+ */
+
+#include "header.h"
+#include "handler.h"
+#include "store.h"
+#include "column.h"
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_Sequence::c4_Sequence ()
+ : _refCount (0), _dependencies (0), _propertyLimit (0), _tempBuf (0)
+{
+}
+
+c4_Sequence::~c4_Sequence ()
+{
+ d4_assert(_refCount == 0);
+
+ d4_assert(!_dependencies); // there can be no dependencies left
+
+ ClearCache();
+
+ delete _tempBuf;
+}
+
+c4_Persist* c4_Sequence::Persist() const
+{
+ return 0;
+}
+
+ /// Increment the reference count of this sequence
+void c4_Sequence::IncRef()
+{
+ ++_refCount;
+
+ d4_assert(_refCount != 0);
+}
+
+ /// Decrement the reference count, delete objects when last
+void c4_Sequence::DecRef()
+{
+ d4_assert(_refCount != 0);
+
+ if (--_refCount == 0)
+ delete this;
+}
+
+ /// Return the current reference count
+int c4_Sequence::NumRefs() const
+{
+ return _refCount;
+}
+
+ /// Compare the specified row with another one
+int c4_Sequence::Compare(int index_, c4_Cursor cursor_) const
+{
+ d4_assert(cursor_._seq != 0);
+
+ c4_Bytes data;
+
+ for (int colNum = 0; colNum < NumHandlers(); ++colNum)
+ {
+ c4_Handler& h = NthHandler(colNum);
+
+ const c4_Sequence* hc = HandlerContext(colNum);
+ int i = RemapIndex(index_, hc);
+
+ if (!cursor_._seq->Get(cursor_._index, h.PropId(), data))
+ h.ClearBytes(data);
+
+ int f = h.Compare(i, data);
+ if (f != 0)
+ return f;
+ }
+
+ return 0;
+}
+
+ /// Restrict the search range for rows
+bool c4_Sequence::RestrictSearch(c4_Cursor, int&, int&)
+{
+ return true;
+}
+
+ /// Replace the contents of a specified row
+void c4_Sequence::SetAt(int index_, c4_Cursor newElem_)
+{
+ d4_assert(newElem_._seq != 0);
+
+ c4_Bytes data;
+
+ c4_Notifier change (this);
+ if (GetDependencies())
+ change.StartSetAt(index_, newElem_);
+
+ for (int i = 0; i < newElem_._seq->NumHandlers(); ++i)
+ {
+ c4_Handler& h = newElem_._seq->NthHandler(i);
+
+ // added 06-12-1999 to do index remapping for derived seq's
+ const c4_Sequence* hc = newElem_._seq->HandlerContext(i);
+ int ri = newElem_._seq->RemapIndex(newElem_._index, hc);
+
+ h.GetBytes(ri, data);
+
+// Set(index_, cursor._seq->NthProperty(i), data);
+ int colNum = PropIndex(h.Property());
+ d4_assert(colNum >= 0);
+
+ NthHandler(colNum).Set(index_, data);
+ }
+
+ // if number of props in dest is larger after adding, clear the rest
+ // this way, new props get copied and undefined props get cleared
+ if (newElem_._seq->NumHandlers() < NumHandlers())
+ {
+ for (int j = 0; j < NumHandlers(); ++j)
+ {
+ c4_Handler& h = NthHandler(j);
+
+ // if the property does not appear in the source
+ if (newElem_._seq->PropIndex(h.PropId()) < 0)
+ {
+ h.ClearBytes(data);
+ h.Set(index_, data);
+ }
+ }
+ }
+}
+
+ /// Remap the index to an underlying view
+int c4_Sequence::RemapIndex(int index_, const c4_Sequence* seq_) const
+{
+ return seq_ == this ? index_ : -1;
+}
+
+ /// Gives access to a general purpose temporary buffer
+c4_Bytes& c4_Sequence::Buffer()
+{
+ if (_tempBuf == 0)
+ _tempBuf = d4_new c4_Bytes;
+ return *_tempBuf;
+}
+
+ // 1.8.5: extra buffer to hold returned description strings
+const char* c4_Sequence::UseTempBuffer(const char* str_)
+{
+ return strcpy((char*) Buffer().SetBuffer(strlen(str_) + 1), str_);
+}
+
+ /// Change number of rows, either by inserting or removing them
+void c4_Sequence::Resize(int newSize_, int)
+{
+ if (NumHandlers() > 0)
+ {
+ int diff = newSize_ - NumRows();
+
+ if (diff > 0)
+ {
+ c4_Row empty; // make sure this doesn't recurse, see below
+ InsertAt(NumRows(), &empty, diff);
+ }
+ else if (diff < 0)
+ RemoveAt(newSize_, - diff);
+ }
+ else // need special case to avoid recursion for c4_Row allocations
+ SetNumRows(newSize_);
+}
+
+ /// Insert one or more rows into this sequence
+void c4_Sequence::InsertAt(int index_, c4_Cursor newElem_, int count_)
+{
+ d4_assert(newElem_._seq != 0);
+
+ c4_Notifier change (this);
+ if (GetDependencies())
+ change.StartInsertAt(index_, newElem_, count_);
+
+ SetNumRows(NumRows() + count_);
+
+ c4_Bytes data;
+
+ for (int i = 0; i < newElem_._seq->NumHandlers(); ++i)
+ {
+ c4_Handler& h = newElem_._seq->NthHandler(i);
+
+ // added 06-12-1999 to do index remapping for derived seq's
+ const c4_Sequence* hc = newElem_._seq->HandlerContext(i);
+ int ri = newElem_._seq->RemapIndex(newElem_._index, hc);
+
+ h.GetBytes(ri, data);
+
+ int colNum = PropIndex(h.Property());
+ d4_assert(colNum >= 0);
+
+ if (h.Property().Type() == 'V')
+ {
+ // special treatment for subviews, insert empty, then overwrite
+ // changed 19990904 - probably fixes a long-standing limitation
+ c4_Bytes temp;
+ h.ClearBytes(temp);
+
+ c4_Handler& h2 = NthHandler(colNum);
+ h2.Insert(index_, temp, count_);
+ for (int j = 0; j < count_; ++j)
+ h2.Set(index_ + j, data);
+ }
+ else
+ NthHandler(colNum).Insert(index_, data, count_);
+ }
+
+ // if number of props in dest is larger after adding, clear the rest
+ // this way, new props get copied and undefined props get cleared
+ if (newElem_._seq->NumHandlers() < NumHandlers())
+ {
+ for (int j = 0; j < NumHandlers(); ++j)
+ {
+ c4_Handler& h = NthHandler(j);
+
+ // if the property does not appear in the source
+ if (newElem_._seq->PropIndex(h.PropId()) < 0)
+ {
+ h.ClearBytes(data);
+ h.Insert(index_, data, count_);
+ }
+ }
+ }
+}
+
+ /// Remove one or more rows from this sequence
+void c4_Sequence::RemoveAt(int index_, int count_)
+{
+ c4_Notifier change (this);
+ if (GetDependencies())
+ change.StartRemoveAt(index_, count_);
+
+ SetNumRows(NumRows() - count_);
+
+ //! careful, this does no index remapping, wrong for derived seq's
+ for (int i = 0; i < NumHandlers(); ++i)
+ NthHandler(i).Remove(index_, count_);
+}
+
+ /// Move a row to another position
+void c4_Sequence::Move(int from_, int to_)
+{
+ c4_Notifier change (this);
+ if (GetDependencies())
+ change.StartMove(from_, to_);
+
+ //! careful, this does no index remapping, wrong for derived seq's
+ for (int i = 0; i < NumHandlers(); ++i)
+ NthHandler(i).Move(from_, to_);
+}
+
+ /// Return the id of the N-th property
+int c4_Sequence::NthPropId(int index_) const
+{
+ return NthHandler(index_).PropId();
+}
+
+void c4_Sequence::ClearCache()
+{
+ if (_propertyLimit > 0)
+ {
+ delete [] _propertyMap; // property indexes may change
+ _propertyLimit = 0;
+ }
+}
+
+ /// Find the index of a property by its id
+int c4_Sequence::PropIndex(int propId_)
+{
+//! CACHING NOTE: derived views will fail if underlying view is restructured
+// still, this cache is kept, since sort will fail anyway...
+// The only safe change in these cases is adding new properties at the end.
+
+ // use the map for the fastest result once known
+ if (propId_ < _propertyLimit && _propertyMap[propId_] >= 0)
+ return _propertyMap[propId_];
+
+ // locate the property using a linear search, return if not present
+ int n = NumHandlers();
+ do
+ if (--n < 0)
+ return -1;
+ while (NthPropId(n) != propId_);
+
+ // if the map is too small, resize it (with a little slack)
+ if (propId_ >= _propertyLimit)
+ {
+ int round = (propId_ + 8) & ~0x07;
+ short* vec = d4_new short [round];
+
+ for (int i = 0; i < round; ++i)
+ vec[i] = i < _propertyLimit ? _propertyMap[i] : -1;
+
+ if (_propertyLimit > 0)
+ delete [] _propertyMap;
+
+ _propertyMap = vec;
+ _propertyLimit = round;
+ }
+
+ // we have a map, adjust the entry and return
+ return _propertyMap[propId_] = n;
+}
+
+ /// Find the index of a property, or create a new entry
+int c4_Sequence::PropIndex(const c4_Property& prop_)
+{
+ int pos = PropIndex(prop_.GetId());
+ if (pos >= 0)
+ {
+ d4_assert(NthHandler(pos).Property().Type() == prop_.Type());
+ return pos;
+ }
+
+ c4_Handler* h = CreateHandler(prop_);
+ d4_assert(h != 0);
+
+ int i = AddHandler(h);
+ if (i >= 0 && NumRows() > 0)
+ {
+ c4_Bytes data;
+ h->ClearBytes(data);
+ h->Insert(0, data, NumRows());
+ }
+
+ return i;
+}
+
+const char* c4_Sequence::Description()
+{
+ return 0;
+}
+
+int c4_Sequence::ItemSize(int index_, int propId_)
+{
+ int colNum = PropIndex(propId_);
+ return colNum >= 0 ? NthHandler(colNum).ItemSize(index_) : -1;
+}
+
+bool c4_Sequence::Get(int index_, int propId_, c4_Bytes& buf_)
+{
+ int colNum = PropIndex(propId_);
+ if (colNum < 0)
+ return false;
+
+ NthHandler(colNum).GetBytes(index_, buf_);
+ return true;
+}
+
+void c4_Sequence::Set(int index_, const c4_Property& prop_, const c4_Bytes& buf_)
+{
+ int colNum = PropIndex(prop_);
+ d4_assert(colNum >= 0);
+
+ c4_Handler& h = NthHandler(colNum);
+
+ c4_Notifier change (this);
+ if (GetDependencies())
+ change.StartSet(index_, prop_.GetId(), buf_);
+
+ if (buf_.Size())
+ h.Set(index_, buf_);
+ else
+ {
+ c4_Bytes empty;
+ h.ClearBytes(empty);
+ h.Set(index_, empty);
+ }
+}
+
+ /// Register a sequence to receive change notifications
+void c4_Sequence::Attach(c4_Sequence* child_)
+{
+ IncRef();
+
+ if (!_dependencies)
+ _dependencies = d4_new c4_Dependencies;
+
+ _dependencies->Add(child_);
+}
+
+ /// Unregister a sequence which received change notifications
+void c4_Sequence::Detach(c4_Sequence* child_)
+{
+ d4_assert(_dependencies != 0);
+
+ if (!_dependencies->Remove(child_))
+ {
+ delete _dependencies;
+ _dependencies = 0;
+ }
+
+ DecRef();
+}
+
+ /// Called just before a change is made to the sequence
+c4_Notifier* c4_Sequence::PreChange(c4_Notifier&)
+{
+ d4_assert(0); // should not be called, because it should not attach
+ return 0;
+}
+
+ /// Called after changes have been made to the sequence
+void c4_Sequence::PostChange(c4_Notifier&)
+{
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_Reference& c4_Reference::operator= (const c4_Reference& value_)
+{
+ c4_Bytes result;
+ value_.GetData(result);
+ SetData(result);
+
+ return *this;
+}
+
+bool operator== (const c4_Reference& a_, const c4_Reference& b_)
+{
+ c4_Bytes buf1;
+ bool f1 = a_.GetData(buf1);
+
+ c4_Bytes buf2;
+ bool f2 = b_.GetData(buf2);
+
+ // if absent, fill either with zero bytes to match length
+ if (!f1)
+ buf1.SetBufferClear(buf2.Size());
+ if (!f2)
+ buf2.SetBufferClear(buf1.Size());
+
+ return buf1 == buf2;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_IntRef::operator t4_i32 () const
+{
+ c4_Bytes result;
+ if (!GetData(result))
+ return 0;
+
+ d4_assert(result.Size() == sizeof (t4_i32));
+ return *(const t4_i32*) result.Contents();
+}
+
+c4_IntRef& c4_IntRef::operator= (t4_i32 value_)
+{
+ SetData(c4_Bytes (&value_, sizeof value_));
+ return *this;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+#if !q4_TINY
+/////////////////////////////////////////////////////////////////////////////
+
+c4_LongRef::operator t4_i64 () const
+{
+ c4_Bytes result;
+ if (!GetData(result))
+ {
+ static t4_i64 zero;
+ return zero;
+ }
+
+ d4_assert(result.Size() == sizeof (t4_i64));
+ return *(const t4_i64*) result.Contents();
+}
+
+c4_LongRef& c4_LongRef::operator= (t4_i64 value_)
+{
+ SetData(c4_Bytes (&value_, sizeof value_));
+ return *this;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_FloatRef::operator double () const
+{
+ c4_Bytes result;
+ if (!GetData(result))
+ return 0;
+
+ d4_assert(result.Size() == sizeof (float));
+ return *(const float*) result.Contents();
+}
+
+c4_FloatRef& c4_FloatRef::operator= (double value_)
+{
+ float v = (float) value_; // loses precision
+ SetData(c4_Bytes (&v, sizeof v));
+ return *this;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_DoubleRef::operator double () const
+{
+ c4_Bytes result;
+ if (!GetData(result))
+ return 0;
+
+ d4_assert(result.Size() == sizeof (double));
+ return *(const double*) result.Contents();
+}
+
+c4_DoubleRef& c4_DoubleRef::operator= (double value_)
+{
+ SetData(c4_Bytes (&value_, sizeof value_));
+ return *this;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // !q4_TINY
+/////////////////////////////////////////////////////////////////////////////
+
+c4_BytesRef::operator c4_Bytes () const
+{
+ c4_Bytes result;
+ GetData(result);
+
+ // the result must immediately be used, its lifetime may be limited
+ return result;
+}
+
+c4_BytesRef& c4_BytesRef::operator= (const c4_Bytes& value_)
+{
+ SetData(value_);
+ return *this;
+}
+
+c4_Bytes c4_BytesRef::Access(t4_i32 off_, int len_) const
+{
+ c4_Bytes& buffer = _cursor._seq->Buffer();
+
+ int colNum = _cursor._seq->PropIndex(_property.GetId());
+ if (colNum >= 0)
+ {
+ c4_Handler& h = _cursor._seq->NthHandler(colNum);
+ int sz = h.ItemSize(_cursor._index);
+ if (len_ == 0 || off_ + len_ > sz)
+ len_ = sz - off_;
+
+ c4_Column* col = h.GetNthMemoCol(_cursor._index, true);
+ if (col != 0)
+ {
+
+ if (len_ > 0) {
+ col->FetchBytes(off_, len_, buffer, true);
+ return buffer;
+ }
+ }
+ else // do it the hard way for custom/mapped views (2002-03-13)
+ {
+ c4_Bytes result;
+ GetData(result);
+ d4_assert(off_ + len_ <= result.Size());
+ return c4_Bytes (result.Contents() + off_, len_, true);
+ }
+ }
+
+ return c4_Bytes ();
+}
+
+bool c4_BytesRef::Modify(const c4_Bytes& buf_, t4_i32 off_, int diff_) const
+{
+ int colNum = _cursor._seq->PropIndex(_property.GetId());
+ if (colNum >= 0)
+ {
+ c4_Handler& h = _cursor._seq->NthHandler(colNum);
+ const int n = buf_.Size();
+ const t4_i32 limit = off_ + n; // past changed bytes
+ const t4_i32 overshoot = limit - h.ItemSize(_cursor._index);
+
+ if (diff_ < overshoot)
+ diff_ = overshoot;
+
+ c4_Column* col = h.GetNthMemoCol(_cursor._index, true);
+ if (col != 0)
+ {
+ if (diff_ < 0)
+ col->Shrink(limit, - diff_);
+ else if (diff_ > 0)
+ // insert bytes in the highest possible spot
+ // if a gap is created, it will contain garbage
+ col->Grow(overshoot > 0 ? col->ColSize() :
+ diff_ > n ? off_ : limit - diff_, diff_);
+
+ col->StoreBytes(off_, buf_);
+ }
+ else // do it the hard way for custom/mapped views (2002-03-13)
+ {
+ c4_Bytes orig;
+ GetData(orig);
+
+ c4_Bytes result;
+ t4_byte* ptr = result.SetBuffer(orig.Size() + diff_);
+
+ memcpy(ptr, orig.Contents(), off_);
+ memcpy(ptr + off_, buf_.Contents(), n);
+ memcpy(ptr + off_ + n, orig.Contents() + off_, orig.Size() - off_);
+
+ SetData(result);
+ }
+ return true;
+ }
+
+ return false;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_StringRef::operator const char* () const
+{
+ c4_Bytes result;
+ GetData(result);
+
+ return result.Size() > 0 ? (const char*) result.Contents() : "";
+}
+
+c4_StringRef& c4_StringRef::operator= (const char* value_)
+{
+ SetData(c4_Bytes (value_, strlen(value_) + 1));
+ return *this;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_ViewRef::operator c4_View () const
+{
+ c4_Bytes result;
+ if (!GetData(result))
+ return (c4_Sequence*) 0; // resolve ambiguity
+
+ d4_assert(result.Size() == sizeof (c4_Sequence*));
+ return *(c4_Sequence* const*) result.Contents();
+}
+
+c4_ViewRef& c4_ViewRef::operator= (const c4_View& value_)
+{
+ SetData(c4_Bytes (&value_._seq, sizeof value_._seq));
+ return *this;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_Stream::~c4_Stream ()
+{
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_Strategy::c4_Strategy ()
+ : _bytesFlipped (false), _failure (0),
+ _mapStart (0), _dataSize (0), _baseOffset (0), _rootPos (-1), _rootLen (-1)
+{
+}
+
+c4_Strategy::~c4_Strategy ()
+{
+ d4_assert(_mapStart == 0);
+}
+
+ /// Read a number of bytes
+int c4_Strategy::DataRead(t4_i32, void*, int)
+{
+/*
+ if (_mapStart != 0 && pos_ + length_ <= _dataSize)
+ {
+ memcpy(buffer_, _mapStart + pos_, length_);
+ return length_;
+ }
+*/
+ ++_failure;
+ return -1;
+}
+
+ /// Write a number of bytes, return true if successful
+void c4_Strategy::DataWrite(t4_i32, const void*, int)
+{
+ ++_failure;
+}
+
+ /// Flush and truncate file
+void c4_Strategy::DataCommit(t4_i32)
+{
+}
+
+ /// Override to support memory-mapped files
+void c4_Strategy::ResetFileMapping()
+{
+}
+
+ /// Report total size of the datafile
+t4_i32 c4_Strategy::FileSize()
+{
+ return _dataSize;
+}
+
+ /// Return a value to use as fresh generation counter
+t4_i32 c4_Strategy::FreshGeneration()
+{
+ return 1;
+}
+
+ /// Define the base offset where data is stored
+void c4_Strategy::SetBase(t4_i32 base_)
+{
+ t4_i32 off = base_ - _baseOffset;
+ _baseOffset = base_;
+ _dataSize -= off;
+ if (_mapStart != 0)
+ _mapStart += off;
+}
+
+/*
+ end_ is file position to start from (0 defaults to FileSize())
+
+ result is the logical end of the datafile (or -1 if no data)
+
+ This code uses a tiny state machine so all the code to read and decode
+ file marks is in one place within the loop.
+*/
+
+ /// Scan datafile head/tail markers, return logical end of data
+t4_i32 c4_Strategy::EndOfData(t4_i32 end_)
+{
+ enum { kStateAtEnd, kStateCommit, kStateHead, kStateOld, kStateDone };
+
+ t4_i32 pos = (end_ >= 0 ? end_ : FileSize()) - _baseOffset;
+ t4_i32 last = pos;
+ t4_i32 rootPos = 0;
+ t4_i32 rootLen = -1; // impossible value, flags old-style header
+ t4_byte mark [8];
+
+ for (int state = kStateAtEnd; state != kStateDone; )
+ {
+ pos -= 8;
+ if (pos + _baseOffset < 0 && state != kStateOld)
+ {
+ // bad offset, try old-style header from start of file
+ pos = - _baseOffset;
+ state = kStateOld;
+ }
+
+ if (DataRead(pos, &mark, sizeof mark) != sizeof mark)
+ return -1;
+
+ t4_i32 count = 0;
+ for (int i = 1; i < 4; ++i)
+ count = (count << 8) + mark[i];
+
+ t4_i32 offset = 0;
+ for (int j = 4; j < 8; ++j)
+ offset = (offset << 8) + mark[j];
+
+ const bool isSkipTail = mark[0] == 0x80 && count == 0 && offset > 0;
+ const bool isCommitTail = mark[0] == 0x80 && count > 0 && offset > 0;
+ const bool isHeader = (mark[0] == 'J' || mark[0] == 'L') &&
+ (mark[0] ^ mark[1]) == ('J' ^ 'L') &&
+ mark[2] == 0x1A;
+ switch (state)
+ {
+ case kStateAtEnd: // no commit tail found yet
+
+ if (isSkipTail)
+ {
+ pos -= offset;
+ last = pos;
+ }
+ else if (isCommitTail)
+ {
+ rootPos = offset;
+ rootLen = count;
+ state = kStateCommit;
+ }
+ else
+ {
+ pos = 8;
+ state = kStateOld;
+ }
+ break;
+
+ case kStateCommit: // commit tail must be preceded by skip tail
+
+ if (!isSkipTail)
+ return -1;
+ pos -= offset - 8;
+ state = kStateHead;
+ break;
+
+ case kStateHead: // fetch the header
+
+ if (!isHeader)
+ {
+ pos = 8;
+ state = kStateOld;
+ }
+ else
+ {
+ state = kStateDone;
+ }
+ break;
+
+ case kStateOld: // old format, look for header in first 4 Kb
+
+ if (isHeader && mark[3] == 0x80)
+ {
+ d4_assert(rootPos == 0);
+ for (int k = 8; --k >= 4; ) // old header is little-endian
+ rootPos = (rootPos << 8) + mark[k];
+ state = kStateDone;
+ }
+ else
+ {
+ pos += 16;
+ if (pos > 4096)
+ return -1;
+ }
+ break;
+ }
+ }
+
+ last += _baseOffset; // all seeks were relative to current offset
+
+ if (end_ >= 0) // if end was specified, then adjust this strategy object
+ {
+ _baseOffset += pos;
+ d4_assert(_baseOffset >= 0);
+ if (_mapStart != 0)
+ {
+ _mapStart += pos;
+ _dataSize -= pos;
+ }
+
+ _rootPos = rootPos;
+ _rootLen = rootLen;
+ }
+
+ d4_assert(mark[0] == 'J' || mark[1] == 'J');
+ _bytesFlipped = (char) *(const short*) mark != 'J';
+
+ return last;
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/akregator/src/mk4storage/metakit/src/win.h b/akregator/src/mk4storage/metakit/src/win.h
new file mode 100644
index 000000000..d27eb2445
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/src/win.h
@@ -0,0 +1,33 @@
+// win.h --
+// $Id$
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit/
+
+/** @file
+ * Configuration header for Windows builds
+ */
+
+#if defined (_MSDOS)
+#define q4_DOS 1
+#endif
+
+#if defined (_WINDOWS)
+#define q4_WIN 1
+#endif
+
+#if defined (_WIN32)
+#define q4_WIN32 1
+#endif
+
+#if defined (_WIN32_WCE) // check for Win CE
+#define q4_WINCE 1
+#define q4_WIN32 1
+#endif
+
+#if q4_WIN32 // WIN32 implies WIN
+#undef q4_WIN
+#define q4_WIN 1
+#endif
+
+#if q4_WIN // WIN implies not DOS, even for Win3
+#undef q4_DOS
+#endif
diff --git a/akregator/src/mk4storage/metakit/tests/ok/b00.txt b/akregator/src/mk4storage/metakit/tests/ok/b00.txt
new file mode 100644
index 000000000..6a37cfb5c
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/b00.txt
@@ -0,0 +1,3 @@
+>>> Should fail
+*** Failed: A(false) ***
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/b01.txt b/akregator/src/mk4storage/metakit/tests/ok/b01.txt
new file mode 100644
index 000000000..814999fb1
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/b01.txt
@@ -0,0 +1,2 @@
+>>> Should succeed
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/b02.txt b/akregator/src/mk4storage/metakit/tests/ok/b02.txt
new file mode 100644
index 000000000..ac0e86f67
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/b02.txt
@@ -0,0 +1,2 @@
+>>> Int property
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/b03.txt b/akregator/src/mk4storage/metakit/tests/ok/b03.txt
new file mode 100644
index 000000000..7f337457e
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/b03.txt
@@ -0,0 +1,2 @@
+>>> Float property
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/b04.txt b/akregator/src/mk4storage/metakit/tests/ok/b04.txt
new file mode 100644
index 000000000..741c5e87d
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/b04.txt
@@ -0,0 +1,2 @@
+>>> String property
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/b05.txt b/akregator/src/mk4storage/metakit/tests/ok/b05.txt
new file mode 100644
index 000000000..3abc4fc98
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/b05.txt
@@ -0,0 +1,2 @@
+>>> View property
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/b06.txt b/akregator/src/mk4storage/metakit/tests/ok/b06.txt
new file mode 100644
index 000000000..67a3a4402
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/b06.txt
@@ -0,0 +1,2 @@
+>>> View construction
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/b07.txt b/akregator/src/mk4storage/metakit/tests/ok/b07.txt
new file mode 100644
index 000000000..05bd95f60
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/b07.txt
@@ -0,0 +1,2 @@
+>>> Row manipulation
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/b08.txt b/akregator/src/mk4storage/metakit/tests/ok/b08.txt
new file mode 100644
index 000000000..1d6cd6e10
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/b08.txt
@@ -0,0 +1,2 @@
+>>> Row expressions
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/b09.txt b/akregator/src/mk4storage/metakit/tests/ok/b09.txt
new file mode 100644
index 000000000..6f3c20ddb
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/b09.txt
@@ -0,0 +1,2 @@
+>>> View manipulation
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/b10.txt b/akregator/src/mk4storage/metakit/tests/ok/b10.txt
new file mode 100644
index 000000000..55c9a3aac
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/b10.txt
@@ -0,0 +1,2 @@
+>>> View sorting
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/b11.txt b/akregator/src/mk4storage/metakit/tests/ok/b11.txt
new file mode 100644
index 000000000..16c5a04a1
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/b11.txt
@@ -0,0 +1,2 @@
+>>> View selection
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/b12.txt b/akregator/src/mk4storage/metakit/tests/ok/b12.txt
new file mode 100644
index 000000000..93e30ce6f
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/b12.txt
@@ -0,0 +1,2 @@
+>>> Add after remove
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/b13.txt b/akregator/src/mk4storage/metakit/tests/ok/b13.txt
new file mode 100644
index 000000000..d1a9a9b8e
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/b13.txt
@@ -0,0 +1,2 @@
+>>> Clear view entry
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/b14.txt b/akregator/src/mk4storage/metakit/tests/ok/b14.txt
new file mode 100644
index 000000000..f166c430c
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/b14.txt
@@ -0,0 +1,2 @@
+>>> Empty view outlives temp storage
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/b15.txt b/akregator/src/mk4storage/metakit/tests/ok/b15.txt
new file mode 100644
index 000000000..595ca0eb1
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/b15.txt
@@ -0,0 +1,2 @@
+>>> View outlives temp storage
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/b16.txt b/akregator/src/mk4storage/metakit/tests/ok/b16.txt
new file mode 100644
index 000000000..fb43bbf9d
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/b16.txt
@@ -0,0 +1,2 @@
+>>> View outlives cleared temp storage
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/b17.txt b/akregator/src/mk4storage/metakit/tests/ok/b17.txt
new file mode 100644
index 000000000..0c61591bb
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/b17.txt
@@ -0,0 +1,2 @@
+>>> Double property
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/b18.txt b/akregator/src/mk4storage/metakit/tests/ok/b18.txt
new file mode 100644
index 000000000..e9ff0b495
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/b18.txt
@@ -0,0 +1,2 @@
+>>> SetAtGrow usage
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/b19.txt b/akregator/src/mk4storage/metakit/tests/ok/b19.txt
new file mode 100644
index 000000000..99c176c63
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/b19.txt
@@ -0,0 +1,2 @@
+>>> Bytes property
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/b20.txt b/akregator/src/mk4storage/metakit/tests/ok/b20.txt
new file mode 100644
index 000000000..849ebf898
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/b20.txt
@@ -0,0 +1,2 @@
+>>> Search sorted view
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/b21.txt b/akregator/src/mk4storage/metakit/tests/ok/b21.txt
new file mode 100644
index 000000000..33cc19d26
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/b21.txt
@@ -0,0 +1,2 @@
+>>> Memo property
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/b22.txt b/akregator/src/mk4storage/metakit/tests/ok/b22.txt
new file mode 100644
index 000000000..c7612a0b9
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/b22.txt
@@ -0,0 +1,2 @@
+>>> Stored view references
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/b23.txt b/akregator/src/mk4storage/metakit/tests/ok/b23.txt
new file mode 100644
index 000000000..d8967bf62
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/b23.txt
@@ -0,0 +1,2 @@
+>>> Sort comparison fix
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/b24.txt b/akregator/src/mk4storage/metakit/tests/ok/b24.txt
new file mode 100644
index 000000000..dbf75a5c9
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/b24.txt
@@ -0,0 +1,2 @@
+>>> Custom view comparisons
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/b25.txt b/akregator/src/mk4storage/metakit/tests/ok/b25.txt
new file mode 100644
index 000000000..ab01b4fcc
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/b25.txt
@@ -0,0 +1,2 @@
+>>> Copy row from derived
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/b26.txt b/akregator/src/mk4storage/metakit/tests/ok/b26.txt
new file mode 100644
index 000000000..7fd6a5d37
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/b26.txt
@@ -0,0 +1,2 @@
+>>> Partial memo field access
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/b27.txt b/akregator/src/mk4storage/metakit/tests/ok/b27.txt
new file mode 100644
index 000000000..156a2c92c
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/b27.txt
@@ -0,0 +1,2 @@
+>>> Copy value to another row
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/c01.txt b/akregator/src/mk4storage/metakit/tests/ok/c01.txt
new file mode 100644
index 000000000..ce7ebb77c
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/c01.txt
@@ -0,0 +1,2 @@
+>>> Slice forward
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/c02.txt b/akregator/src/mk4storage/metakit/tests/ok/c02.txt
new file mode 100644
index 000000000..50b88f0f2
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/c02.txt
@@ -0,0 +1,2 @@
+>>> Slice backward
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/c03.txt b/akregator/src/mk4storage/metakit/tests/ok/c03.txt
new file mode 100644
index 000000000..4feea348b
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/c03.txt
@@ -0,0 +1,2 @@
+>>> Slice reverse
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/c04.txt b/akregator/src/mk4storage/metakit/tests/ok/c04.txt
new file mode 100644
index 000000000..64bf550a2
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/c04.txt
@@ -0,0 +1,2 @@
+>>> Cartesian product
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/c05.txt b/akregator/src/mk4storage/metakit/tests/ok/c05.txt
new file mode 100644
index 000000000..7fae13ec4
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/c05.txt
@@ -0,0 +1,2 @@
+>>> Remapping
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/c06.txt b/akregator/src/mk4storage/metakit/tests/ok/c06.txt
new file mode 100644
index 000000000..520d9f71c
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/c06.txt
@@ -0,0 +1,2 @@
+>>> Pairwise combination
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/c07.txt b/akregator/src/mk4storage/metakit/tests/ok/c07.txt
new file mode 100644
index 000000000..169aa5052
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/c07.txt
@@ -0,0 +1,2 @@
+>>> Concatenate views
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/c08.txt b/akregator/src/mk4storage/metakit/tests/ok/c08.txt
new file mode 100644
index 000000000..773e1e52a
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/c08.txt
@@ -0,0 +1,2 @@
+>>> Rename property
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/c09.txt b/akregator/src/mk4storage/metakit/tests/ok/c09.txt
new file mode 100644
index 000000000..2d577394d
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/c09.txt
@@ -0,0 +1,2 @@
+>>> GroupBy operation
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/c10.txt b/akregator/src/mk4storage/metakit/tests/ok/c10.txt
new file mode 100644
index 000000000..ddb98fef9
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/c10.txt
@@ -0,0 +1,2 @@
+>>> Counts operation
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/c11.txt b/akregator/src/mk4storage/metakit/tests/ok/c11.txt
new file mode 100644
index 000000000..6d70cd878
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/c11.txt
@@ -0,0 +1,2 @@
+>>> Unique operation
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/c12.txt b/akregator/src/mk4storage/metakit/tests/ok/c12.txt
new file mode 100644
index 000000000..d66e764c9
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/c12.txt
@@ -0,0 +1,2 @@
+>>> Union operation
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/c13.txt b/akregator/src/mk4storage/metakit/tests/ok/c13.txt
new file mode 100644
index 000000000..14f1e9721
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/c13.txt
@@ -0,0 +1,2 @@
+>>> Intersect operation
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/c14.txt b/akregator/src/mk4storage/metakit/tests/ok/c14.txt
new file mode 100644
index 000000000..3edcec0b4
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/c14.txt
@@ -0,0 +1,2 @@
+>>> Different operation
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/c15.txt b/akregator/src/mk4storage/metakit/tests/ok/c15.txt
new file mode 100644
index 000000000..c827c757a
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/c15.txt
@@ -0,0 +1,2 @@
+>>> Minus operation
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/c16.txt b/akregator/src/mk4storage/metakit/tests/ok/c16.txt
new file mode 100644
index 000000000..55d9f6990
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/c16.txt
@@ -0,0 +1,2 @@
+>>> View comparisons
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/c17.txt b/akregator/src/mk4storage/metakit/tests/ok/c17.txt
new file mode 100644
index 000000000..cd2ac75e4
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/c17.txt
@@ -0,0 +1,2 @@
+>>> Join operation
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/c18.txt b/akregator/src/mk4storage/metakit/tests/ok/c18.txt
new file mode 100644
index 000000000..dfdd45a89
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/c18.txt
@@ -0,0 +1,2 @@
+>>> Groupby sort fix
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/c19.txt b/akregator/src/mk4storage/metakit/tests/ok/c19.txt
new file mode 100644
index 000000000..469df00aa
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/c19.txt
@@ -0,0 +1,2 @@
+>>> JoinProp operation
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/c20.txt b/akregator/src/mk4storage/metakit/tests/ok/c20.txt
new file mode 100644
index 000000000..cea0b6516
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/c20.txt
@@ -0,0 +1,2 @@
+>>> Wide cartesian product
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/c21.txt b/akregator/src/mk4storage/metakit/tests/ok/c21.txt
new file mode 100644
index 000000000..679055b9c
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/c21.txt
@@ -0,0 +1,2 @@
+>>> Join on compound key
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/c22.txt b/akregator/src/mk4storage/metakit/tests/ok/c22.txt
new file mode 100644
index 000000000..1646d1a5d
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/c22.txt
@@ -0,0 +1,2 @@
+>>> Groupby with selection
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/d01.txt b/akregator/src/mk4storage/metakit/tests/ok/d01.txt
new file mode 100644
index 000000000..46092d8c7
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/d01.txt
@@ -0,0 +1,2 @@
+>>> Commit aside
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/d01a.txt b/akregator/src/mk4storage/metakit/tests/ok/d01a.txt
new file mode 100644
index 000000000..fb8a3f195
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/d01a.txt
@@ -0,0 +1,4 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 1 rows = p1:I
+ 0: 123
diff --git a/akregator/src/mk4storage/metakit/tests/ok/d01b.txt b/akregator/src/mk4storage/metakit/tests/ok/d01b.txt
new file mode 100644
index 000000000..1440d4ebb
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/d01b.txt
@@ -0,0 +1,19 @@
+ VIEW 1 rows = _C:V
+ 0: subview '_C'
+ VIEW 4 rows = _O:I _D:V
+ 0: 8
+ 0: subview '_D'
+ VIEW 1 rows = _K:I _R:I _B:B
+ 0: 0 0 (4b)
+ 1: 0
+ 1: subview '_D'
+ VIEW 1 rows = _K:I _R:I _B:B
+ 0: 0 0 (5b)
+ 2: 0
+ 2: subview '_D'
+ VIEW 1 rows = _K:I _R:I _B:B
+ 0: 0 0 (13b)
+ 3: 0
+ 3: subview '_D'
+ VIEW 1 rows = _K:I _R:I _B:B
+ 0: 0 0 (13b)
diff --git a/akregator/src/mk4storage/metakit/tests/ok/e01.txt b/akregator/src/mk4storage/metakit/tests/ok/e01.txt
new file mode 100644
index 000000000..665b9367d
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/e01.txt
@@ -0,0 +1,2 @@
+>>> Extend new file
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/e01a.txt b/akregator/src/mk4storage/metakit/tests/ok/e01a.txt
new file mode 100644
index 000000000..4f2b75602
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/e01a.txt
@@ -0,0 +1,5 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 2 rows = p1:I
+ 0: 123
+ 1: 456
diff --git a/akregator/src/mk4storage/metakit/tests/ok/e02.txt b/akregator/src/mk4storage/metakit/tests/ok/e02.txt
new file mode 100644
index 000000000..6dd7e4e44
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/e02.txt
@@ -0,0 +1,2 @@
+>>> Extend committing twice
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/e02a.txt b/akregator/src/mk4storage/metakit/tests/ok/e02a.txt
new file mode 100644
index 000000000..4f2b75602
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/e02a.txt
@@ -0,0 +1,5 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 2 rows = p1:I
+ 0: 123
+ 1: 456
diff --git a/akregator/src/mk4storage/metakit/tests/ok/e03.txt b/akregator/src/mk4storage/metakit/tests/ok/e03.txt
new file mode 100644
index 000000000..8d58f9062
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/e03.txt
@@ -0,0 +1,2 @@
+>>> Read during extend
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/e03a.txt b/akregator/src/mk4storage/metakit/tests/ok/e03a.txt
new file mode 100644
index 000000000..4f2b75602
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/e03a.txt
@@ -0,0 +1,5 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 2 rows = p1:I
+ 0: 123
+ 1: 456
diff --git a/akregator/src/mk4storage/metakit/tests/ok/e04.txt b/akregator/src/mk4storage/metakit/tests/ok/e04.txt
new file mode 100644
index 000000000..c5ab0c727
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/e04.txt
@@ -0,0 +1,2 @@
+>>> Extend during read
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/e04a.txt b/akregator/src/mk4storage/metakit/tests/ok/e04a.txt
new file mode 100644
index 000000000..2f613d763
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/e04a.txt
@@ -0,0 +1,5 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 2 rows = p1:I
+ 0: 123
+ 1: 123
diff --git a/akregator/src/mk4storage/metakit/tests/ok/e05.txt b/akregator/src/mk4storage/metakit/tests/ok/e05.txt
new file mode 100644
index 000000000..9314db303
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/e05.txt
@@ -0,0 +1,2 @@
+>>> Test memory mapping
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/e05a.txt b/akregator/src/mk4storage/metakit/tests/ok/e05a.txt
new file mode 100644
index 000000000..a28a7cae2
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/e05a.txt
@@ -0,0 +1 @@
+ VIEW 1 rows =
diff --git a/akregator/src/mk4storage/metakit/tests/ok/e06.txt b/akregator/src/mk4storage/metakit/tests/ok/e06.txt
new file mode 100644
index 000000000..62dc3218f
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/e06.txt
@@ -0,0 +1,2 @@
+>>> Rollback during extend
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/e06a.txt b/akregator/src/mk4storage/metakit/tests/ok/e06a.txt
new file mode 100644
index 000000000..4f2b75602
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/e06a.txt
@@ -0,0 +1,5 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 2 rows = p1:I
+ 0: 123
+ 1: 456
diff --git a/akregator/src/mk4storage/metakit/tests/ok/f01.txt b/akregator/src/mk4storage/metakit/tests/ok/f01.txt
new file mode 100644
index 000000000..412c99b76
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/f01.txt
@@ -0,0 +1,2 @@
+>>> Add view to format
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/f01a.txt b/akregator/src/mk4storage/metakit/tests/ok/f01a.txt
new file mode 100644
index 000000000..acb76114d
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/f01a.txt
@@ -0,0 +1,8 @@
+ VIEW 1 rows = a:V b:V
+ 0: subview 'a'
+ VIEW 1 rows = p1:I
+ 0: 123
+ 0: subview 'b'
+ VIEW 2 rows = p2:I
+ 0: 345
+ 1: 567
diff --git a/akregator/src/mk4storage/metakit/tests/ok/f02.txt b/akregator/src/mk4storage/metakit/tests/ok/f02.txt
new file mode 100644
index 000000000..8ed593070
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/f02.txt
@@ -0,0 +1,2 @@
+>>> Remove view from format
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/f02a.txt b/akregator/src/mk4storage/metakit/tests/ok/f02a.txt
new file mode 100644
index 000000000..700609bef
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/f02a.txt
@@ -0,0 +1,5 @@
+ VIEW 1 rows = b:V
+ 0: subview 'b'
+ VIEW 2 rows = p2:I
+ 0: 345
+ 1: 567
diff --git a/akregator/src/mk4storage/metakit/tests/ok/f03.txt b/akregator/src/mk4storage/metakit/tests/ok/f03.txt
new file mode 100644
index 000000000..461a5b7dc
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/f03.txt
@@ -0,0 +1,2 @@
+>>> Rollback format change
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/f03a.txt b/akregator/src/mk4storage/metakit/tests/ok/f03a.txt
new file mode 100644
index 000000000..fb8a3f195
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/f03a.txt
@@ -0,0 +1,4 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 1 rows = p1:I
+ 0: 123
diff --git a/akregator/src/mk4storage/metakit/tests/ok/f04.txt b/akregator/src/mk4storage/metakit/tests/ok/f04.txt
new file mode 100644
index 000000000..237a42f23
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/f04.txt
@@ -0,0 +1,2 @@
+>>> Rearrange format
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/f04a.txt b/akregator/src/mk4storage/metakit/tests/ok/f04a.txt
new file mode 100644
index 000000000..08b06c501
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/f04a.txt
@@ -0,0 +1,8 @@
+ VIEW 1 rows = b:V a:V
+ 0: subview 'b'
+ VIEW 2 rows = p2:I
+ 0: 345
+ 1: 567
+ 0: subview 'a'
+ VIEW 1 rows = p1:I
+ 0: 123
diff --git a/akregator/src/mk4storage/metakit/tests/ok/f05.txt b/akregator/src/mk4storage/metakit/tests/ok/f05.txt
new file mode 100644
index 000000000..f9fac025e
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/f05.txt
@@ -0,0 +1,2 @@
+>>> Nested reformat
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/f05a.txt b/akregator/src/mk4storage/metakit/tests/ok/f05a.txt
new file mode 100644
index 000000000..2f3891813
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/f05a.txt
@@ -0,0 +1,8 @@
+ VIEW 1 rows = a:V b:V
+ 0: subview 'a'
+ VIEW 1 rows = p1:I
+ 0: 123
+ 0: subview 'b'
+ VIEW 2 rows = p1:I p2:I
+ 0: 543 345
+ 1: 765 567
diff --git a/akregator/src/mk4storage/metakit/tests/ok/f06.txt b/akregator/src/mk4storage/metakit/tests/ok/f06.txt
new file mode 100644
index 000000000..039caebe6
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/f06.txt
@@ -0,0 +1,2 @@
+>>> Flip foreign data
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/f07.txt b/akregator/src/mk4storage/metakit/tests/ok/f07.txt
new file mode 100644
index 000000000..bf52b37b8
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/f07.txt
@@ -0,0 +1,2 @@
+>>> Automatic structure info (obsolete)
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/f07a.txt b/akregator/src/mk4storage/metakit/tests/ok/f07a.txt
new file mode 100644
index 000000000..79963d7b4
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/f07a.txt
@@ -0,0 +1,3 @@
+ VIEW 1 rows = dict:V
+ 0: subview 'dict'
+ VIEW 0 rows = parent:I index:I view:V
diff --git a/akregator/src/mk4storage/metakit/tests/ok/f08.txt b/akregator/src/mk4storage/metakit/tests/ok/f08.txt
new file mode 100644
index 000000000..d4e88f89a
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/f08.txt
@@ -0,0 +1,2 @@
+>>> Automatic storage format
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/f08a.txt b/akregator/src/mk4storage/metakit/tests/ok/f08a.txt
new file mode 100644
index 000000000..7a56c7fcf
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/f08a.txt
@@ -0,0 +1,6 @@
+ VIEW 1 rows = dict:V
+ 0: subview 'dict'
+ VIEW 3 rows = p1:S p2:S
+ 0: 'One' 'Two'
+ 1: '' ''
+ 2: 'One' 'Two'
diff --git a/akregator/src/mk4storage/metakit/tests/ok/f09.txt b/akregator/src/mk4storage/metakit/tests/ok/f09.txt
new file mode 100644
index 000000000..d1040e7ff
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/f09.txt
@@ -0,0 +1,2 @@
+>>> Partial restructuring
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/f09a.txt b/akregator/src/mk4storage/metakit/tests/ok/f09a.txt
new file mode 100644
index 000000000..c26f86755
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/f09a.txt
@@ -0,0 +1,13 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 10 rows = p1:I p2:I p3:I
+ 0: 1000 2000 3000
+ 1: 1001 0 0
+ 2: 1002 2002 0
+ 3: 1003 0 3003
+ 4: 1004 2004 0
+ 5: 1005 0 0
+ 6: 1006 2006 3006
+ 7: 1007 0 0
+ 8: 1008 2008 0
+ 9: 1009 0 3009
diff --git a/akregator/src/mk4storage/metakit/tests/ok/f10.txt b/akregator/src/mk4storage/metakit/tests/ok/f10.txt
new file mode 100644
index 000000000..848dbdddc
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/f10.txt
@@ -0,0 +1,2 @@
+>>> Committed restructuring
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/f10a.txt b/akregator/src/mk4storage/metakit/tests/ok/f10a.txt
new file mode 100644
index 000000000..c26f86755
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/f10a.txt
@@ -0,0 +1,13 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 10 rows = p1:I p2:I p3:I
+ 0: 1000 2000 3000
+ 1: 1001 0 0
+ 2: 1002 2002 0
+ 3: 1003 0 3003
+ 4: 1004 2004 0
+ 5: 1005 0 0
+ 6: 1006 2006 3006
+ 7: 1007 0 0
+ 8: 1008 2008 0
+ 9: 1009 0 3009
diff --git a/akregator/src/mk4storage/metakit/tests/ok/f11.txt b/akregator/src/mk4storage/metakit/tests/ok/f11.txt
new file mode 100644
index 000000000..583ec58ae
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/f11.txt
@@ -0,0 +1,2 @@
+>>> Delete missing view
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/f11a.txt b/akregator/src/mk4storage/metakit/tests/ok/f11a.txt
new file mode 100644
index 000000000..a28a7cae2
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/f11a.txt
@@ -0,0 +1 @@
+ VIEW 1 rows =
diff --git a/akregator/src/mk4storage/metakit/tests/ok/l00.txt b/akregator/src/mk4storage/metakit/tests/ok/l00.txt
new file mode 100644
index 000000000..b94a9a630
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/l00.txt
@@ -0,0 +1,2 @@
+>>> Lots of properties
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/l00a.txt b/akregator/src/mk4storage/metakit/tests/ok/l00a.txt
new file mode 100644
index 000000000..bb0f5c661
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/l00a.txt
@@ -0,0 +1,4 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 1 rows = p1:I p2:I p3:I p4:I p5:I p6:I p7:I p8:I p9:I p10:I p11:I p12:I p13:I p14:I p15:I p16:I p17:I p18:I p19:I p20:I p21:I p22:I p23:I p24:I p25:I p26:I p27:I p28:I p29:I p30:I p31:I p32:I p33:I p34:I p35:I p36:I p37:I p38:I p39:I p40:I p41:I p42:I p43:I p44:I p45:I p46:I p47:I p48:I p49:I p50:I p51:I p52:I p53:I p54:I p55:I p56:I p57:I p58:I p59:I p60:I p61:I p62:I p63:I p64:I p65:I p66:I p67:I p68:I p69:I p70:I p71:I p72:I p73:I p74:I p75:I p76:I p77:I p78:I p79:I p80:I p81:I p82:I p83:I p84:I p85:I p86:I p87:I p88:I p89:I p90:I p91:I p92:I p93:I p94:I p95:I p96:I p97:I p98:I p99:I p100:I p101:I p102:I p103:I p104:I p105:I p106:I p107:I p108:I p109:I p110:I p111:I p112:I p113:I p114:I p115:I p116:I p117:I p118:I p119:I p120:I p121:I p122:I p123:I p124:I p125:I p126:I p127:I p128:I p129:I p130:I p131:I p132:I p133:I p134:I p135:I p136:I p137:I p138:I p139:I p140:I p141:I p142:I p143:I p144:I p145:I p146:I p147:I p148:I p149:I
+ 0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 123 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
diff --git a/akregator/src/mk4storage/metakit/tests/ok/l01.txt b/akregator/src/mk4storage/metakit/tests/ok/l01.txt
new file mode 100644
index 000000000..842c943de
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/l01.txt
@@ -0,0 +1,2 @@
+>>> Over 32 Kb of integers
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/l01a.txt b/akregator/src/mk4storage/metakit/tests/ok/l01a.txt
new file mode 100644
index 000000000..69cad2436
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/l01a.txt
@@ -0,0 +1,9003 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 9000 rows = p1:I
+ 0: 1000000
+ 1: 1000001
+ 2: 1000002
+ 3: 1000003
+ 4: 1000004
+ 5: 1000005
+ 6: 1000006
+ 7: 1000007
+ 8: 1000008
+ 9: 1000009
+ 10: 1000010
+ 11: 1000011
+ 12: 1000012
+ 13: 1000013
+ 14: 1000014
+ 15: 1000015
+ 16: 1000016
+ 17: 1000017
+ 18: 1000018
+ 19: 1000019
+ 20: 1000020
+ 21: 1000021
+ 22: 1000022
+ 23: 1000023
+ 24: 1000024
+ 25: 1000025
+ 26: 1000026
+ 27: 1000027
+ 28: 1000028
+ 29: 1000029
+ 30: 1000030
+ 31: 1000031
+ 32: 1000032
+ 33: 1000033
+ 34: 1000034
+ 35: 1000035
+ 36: 1000036
+ 37: 1000037
+ 38: 1000038
+ 39: 1000039
+ 40: 1000040
+ 41: 1000041
+ 42: 1000042
+ 43: 1000043
+ 44: 1000044
+ 45: 1000045
+ 46: 1000046
+ 47: 1000047
+ 48: 1000048
+ 49: 1000049
+ 50: 1000050
+ 51: 1000051
+ 52: 1000052
+ 53: 1000053
+ 54: 1000054
+ 55: 1000055
+ 56: 1000056
+ 57: 1000057
+ 58: 1000058
+ 59: 1000059
+ 60: 1000060
+ 61: 1000061
+ 62: 1000062
+ 63: 1000063
+ 64: 1000064
+ 65: 1000065
+ 66: 1000066
+ 67: 1000067
+ 68: 1000068
+ 69: 1000069
+ 70: 1000070
+ 71: 1000071
+ 72: 1000072
+ 73: 1000073
+ 74: 1000074
+ 75: 1000075
+ 76: 1000076
+ 77: 1000077
+ 78: 1000078
+ 79: 1000079
+ 80: 1000080
+ 81: 1000081
+ 82: 1000082
+ 83: 1000083
+ 84: 1000084
+ 85: 1000085
+ 86: 1000086
+ 87: 1000087
+ 88: 1000088
+ 89: 1000089
+ 90: 1000090
+ 91: 1000091
+ 92: 1000092
+ 93: 1000093
+ 94: 1000094
+ 95: 1000095
+ 96: 1000096
+ 97: 1000097
+ 98: 1000098
+ 99: 1000099
+ 100: 1000100
+ 101: 1000101
+ 102: 1000102
+ 103: 1000103
+ 104: 1000104
+ 105: 1000105
+ 106: 1000106
+ 107: 1000107
+ 108: 1000108
+ 109: 1000109
+ 110: 1000110
+ 111: 1000111
+ 112: 1000112
+ 113: 1000113
+ 114: 1000114
+ 115: 1000115
+ 116: 1000116
+ 117: 1000117
+ 118: 1000118
+ 119: 1000119
+ 120: 1000120
+ 121: 1000121
+ 122: 1000122
+ 123: 1000123
+ 124: 1000124
+ 125: 1000125
+ 126: 1000126
+ 127: 1000127
+ 128: 1000128
+ 129: 1000129
+ 130: 1000130
+ 131: 1000131
+ 132: 1000132
+ 133: 1000133
+ 134: 1000134
+ 135: 1000135
+ 136: 1000136
+ 137: 1000137
+ 138: 1000138
+ 139: 1000139
+ 140: 1000140
+ 141: 1000141
+ 142: 1000142
+ 143: 1000143
+ 144: 1000144
+ 145: 1000145
+ 146: 1000146
+ 147: 1000147
+ 148: 1000148
+ 149: 1000149
+ 150: 1000150
+ 151: 1000151
+ 152: 1000152
+ 153: 1000153
+ 154: 1000154
+ 155: 1000155
+ 156: 1000156
+ 157: 1000157
+ 158: 1000158
+ 159: 1000159
+ 160: 1000160
+ 161: 1000161
+ 162: 1000162
+ 163: 1000163
+ 164: 1000164
+ 165: 1000165
+ 166: 1000166
+ 167: 1000167
+ 168: 1000168
+ 169: 1000169
+ 170: 1000170
+ 171: 1000171
+ 172: 1000172
+ 173: 1000173
+ 174: 1000174
+ 175: 1000175
+ 176: 1000176
+ 177: 1000177
+ 178: 1000178
+ 179: 1000179
+ 180: 1000180
+ 181: 1000181
+ 182: 1000182
+ 183: 1000183
+ 184: 1000184
+ 185: 1000185
+ 186: 1000186
+ 187: 1000187
+ 188: 1000188
+ 189: 1000189
+ 190: 1000190
+ 191: 1000191
+ 192: 1000192
+ 193: 1000193
+ 194: 1000194
+ 195: 1000195
+ 196: 1000196
+ 197: 1000197
+ 198: 1000198
+ 199: 1000199
+ 200: 1000200
+ 201: 1000201
+ 202: 1000202
+ 203: 1000203
+ 204: 1000204
+ 205: 1000205
+ 206: 1000206
+ 207: 1000207
+ 208: 1000208
+ 209: 1000209
+ 210: 1000210
+ 211: 1000211
+ 212: 1000212
+ 213: 1000213
+ 214: 1000214
+ 215: 1000215
+ 216: 1000216
+ 217: 1000217
+ 218: 1000218
+ 219: 1000219
+ 220: 1000220
+ 221: 1000221
+ 222: 1000222
+ 223: 1000223
+ 224: 1000224
+ 225: 1000225
+ 226: 1000226
+ 227: 1000227
+ 228: 1000228
+ 229: 1000229
+ 230: 1000230
+ 231: 1000231
+ 232: 1000232
+ 233: 1000233
+ 234: 1000234
+ 235: 1000235
+ 236: 1000236
+ 237: 1000237
+ 238: 1000238
+ 239: 1000239
+ 240: 1000240
+ 241: 1000241
+ 242: 1000242
+ 243: 1000243
+ 244: 1000244
+ 245: 1000245
+ 246: 1000246
+ 247: 1000247
+ 248: 1000248
+ 249: 1000249
+ 250: 1000250
+ 251: 1000251
+ 252: 1000252
+ 253: 1000253
+ 254: 1000254
+ 255: 1000255
+ 256: 1000256
+ 257: 1000257
+ 258: 1000258
+ 259: 1000259
+ 260: 1000260
+ 261: 1000261
+ 262: 1000262
+ 263: 1000263
+ 264: 1000264
+ 265: 1000265
+ 266: 1000266
+ 267: 1000267
+ 268: 1000268
+ 269: 1000269
+ 270: 1000270
+ 271: 1000271
+ 272: 1000272
+ 273: 1000273
+ 274: 1000274
+ 275: 1000275
+ 276: 1000276
+ 277: 1000277
+ 278: 1000278
+ 279: 1000279
+ 280: 1000280
+ 281: 1000281
+ 282: 1000282
+ 283: 1000283
+ 284: 1000284
+ 285: 1000285
+ 286: 1000286
+ 287: 1000287
+ 288: 1000288
+ 289: 1000289
+ 290: 1000290
+ 291: 1000291
+ 292: 1000292
+ 293: 1000293
+ 294: 1000294
+ 295: 1000295
+ 296: 1000296
+ 297: 1000297
+ 298: 1000298
+ 299: 1000299
+ 300: 1000300
+ 301: 1000301
+ 302: 1000302
+ 303: 1000303
+ 304: 1000304
+ 305: 1000305
+ 306: 1000306
+ 307: 1000307
+ 308: 1000308
+ 309: 1000309
+ 310: 1000310
+ 311: 1000311
+ 312: 1000312
+ 313: 1000313
+ 314: 1000314
+ 315: 1000315
+ 316: 1000316
+ 317: 1000317
+ 318: 1000318
+ 319: 1000319
+ 320: 1000320
+ 321: 1000321
+ 322: 1000322
+ 323: 1000323
+ 324: 1000324
+ 325: 1000325
+ 326: 1000326
+ 327: 1000327
+ 328: 1000328
+ 329: 1000329
+ 330: 1000330
+ 331: 1000331
+ 332: 1000332
+ 333: 1000333
+ 334: 1000334
+ 335: 1000335
+ 336: 1000336
+ 337: 1000337
+ 338: 1000338
+ 339: 1000339
+ 340: 1000340
+ 341: 1000341
+ 342: 1000342
+ 343: 1000343
+ 344: 1000344
+ 345: 1000345
+ 346: 1000346
+ 347: 1000347
+ 348: 1000348
+ 349: 1000349
+ 350: 1000350
+ 351: 1000351
+ 352: 1000352
+ 353: 1000353
+ 354: 1000354
+ 355: 1000355
+ 356: 1000356
+ 357: 1000357
+ 358: 1000358
+ 359: 1000359
+ 360: 1000360
+ 361: 1000361
+ 362: 1000362
+ 363: 1000363
+ 364: 1000364
+ 365: 1000365
+ 366: 1000366
+ 367: 1000367
+ 368: 1000368
+ 369: 1000369
+ 370: 1000370
+ 371: 1000371
+ 372: 1000372
+ 373: 1000373
+ 374: 1000374
+ 375: 1000375
+ 376: 1000376
+ 377: 1000377
+ 378: 1000378
+ 379: 1000379
+ 380: 1000380
+ 381: 1000381
+ 382: 1000382
+ 383: 1000383
+ 384: 1000384
+ 385: 1000385
+ 386: 1000386
+ 387: 1000387
+ 388: 1000388
+ 389: 1000389
+ 390: 1000390
+ 391: 1000391
+ 392: 1000392
+ 393: 1000393
+ 394: 1000394
+ 395: 1000395
+ 396: 1000396
+ 397: 1000397
+ 398: 1000398
+ 399: 1000399
+ 400: 1000400
+ 401: 1000401
+ 402: 1000402
+ 403: 1000403
+ 404: 1000404
+ 405: 1000405
+ 406: 1000406
+ 407: 1000407
+ 408: 1000408
+ 409: 1000409
+ 410: 1000410
+ 411: 1000411
+ 412: 1000412
+ 413: 1000413
+ 414: 1000414
+ 415: 1000415
+ 416: 1000416
+ 417: 1000417
+ 418: 1000418
+ 419: 1000419
+ 420: 1000420
+ 421: 1000421
+ 422: 1000422
+ 423: 1000423
+ 424: 1000424
+ 425: 1000425
+ 426: 1000426
+ 427: 1000427
+ 428: 1000428
+ 429: 1000429
+ 430: 1000430
+ 431: 1000431
+ 432: 1000432
+ 433: 1000433
+ 434: 1000434
+ 435: 1000435
+ 436: 1000436
+ 437: 1000437
+ 438: 1000438
+ 439: 1000439
+ 440: 1000440
+ 441: 1000441
+ 442: 1000442
+ 443: 1000443
+ 444: 1000444
+ 445: 1000445
+ 446: 1000446
+ 447: 1000447
+ 448: 1000448
+ 449: 1000449
+ 450: 1000450
+ 451: 1000451
+ 452: 1000452
+ 453: 1000453
+ 454: 1000454
+ 455: 1000455
+ 456: 1000456
+ 457: 1000457
+ 458: 1000458
+ 459: 1000459
+ 460: 1000460
+ 461: 1000461
+ 462: 1000462
+ 463: 1000463
+ 464: 1000464
+ 465: 1000465
+ 466: 1000466
+ 467: 1000467
+ 468: 1000468
+ 469: 1000469
+ 470: 1000470
+ 471: 1000471
+ 472: 1000472
+ 473: 1000473
+ 474: 1000474
+ 475: 1000475
+ 476: 1000476
+ 477: 1000477
+ 478: 1000478
+ 479: 1000479
+ 480: 1000480
+ 481: 1000481
+ 482: 1000482
+ 483: 1000483
+ 484: 1000484
+ 485: 1000485
+ 486: 1000486
+ 487: 1000487
+ 488: 1000488
+ 489: 1000489
+ 490: 1000490
+ 491: 1000491
+ 492: 1000492
+ 493: 1000493
+ 494: 1000494
+ 495: 1000495
+ 496: 1000496
+ 497: 1000497
+ 498: 1000498
+ 499: 1000499
+ 500: 1000500
+ 501: 1000501
+ 502: 1000502
+ 503: 1000503
+ 504: 1000504
+ 505: 1000505
+ 506: 1000506
+ 507: 1000507
+ 508: 1000508
+ 509: 1000509
+ 510: 1000510
+ 511: 1000511
+ 512: 1000512
+ 513: 1000513
+ 514: 1000514
+ 515: 1000515
+ 516: 1000516
+ 517: 1000517
+ 518: 1000518
+ 519: 1000519
+ 520: 1000520
+ 521: 1000521
+ 522: 1000522
+ 523: 1000523
+ 524: 1000524
+ 525: 1000525
+ 526: 1000526
+ 527: 1000527
+ 528: 1000528
+ 529: 1000529
+ 530: 1000530
+ 531: 1000531
+ 532: 1000532
+ 533: 1000533
+ 534: 1000534
+ 535: 1000535
+ 536: 1000536
+ 537: 1000537
+ 538: 1000538
+ 539: 1000539
+ 540: 1000540
+ 541: 1000541
+ 542: 1000542
+ 543: 1000543
+ 544: 1000544
+ 545: 1000545
+ 546: 1000546
+ 547: 1000547
+ 548: 1000548
+ 549: 1000549
+ 550: 1000550
+ 551: 1000551
+ 552: 1000552
+ 553: 1000553
+ 554: 1000554
+ 555: 1000555
+ 556: 1000556
+ 557: 1000557
+ 558: 1000558
+ 559: 1000559
+ 560: 1000560
+ 561: 1000561
+ 562: 1000562
+ 563: 1000563
+ 564: 1000564
+ 565: 1000565
+ 566: 1000566
+ 567: 1000567
+ 568: 1000568
+ 569: 1000569
+ 570: 1000570
+ 571: 1000571
+ 572: 1000572
+ 573: 1000573
+ 574: 1000574
+ 575: 1000575
+ 576: 1000576
+ 577: 1000577
+ 578: 1000578
+ 579: 1000579
+ 580: 1000580
+ 581: 1000581
+ 582: 1000582
+ 583: 1000583
+ 584: 1000584
+ 585: 1000585
+ 586: 1000586
+ 587: 1000587
+ 588: 1000588
+ 589: 1000589
+ 590: 1000590
+ 591: 1000591
+ 592: 1000592
+ 593: 1000593
+ 594: 1000594
+ 595: 1000595
+ 596: 1000596
+ 597: 1000597
+ 598: 1000598
+ 599: 1000599
+ 600: 1000600
+ 601: 1000601
+ 602: 1000602
+ 603: 1000603
+ 604: 1000604
+ 605: 1000605
+ 606: 1000606
+ 607: 1000607
+ 608: 1000608
+ 609: 1000609
+ 610: 1000610
+ 611: 1000611
+ 612: 1000612
+ 613: 1000613
+ 614: 1000614
+ 615: 1000615
+ 616: 1000616
+ 617: 1000617
+ 618: 1000618
+ 619: 1000619
+ 620: 1000620
+ 621: 1000621
+ 622: 1000622
+ 623: 1000623
+ 624: 1000624
+ 625: 1000625
+ 626: 1000626
+ 627: 1000627
+ 628: 1000628
+ 629: 1000629
+ 630: 1000630
+ 631: 1000631
+ 632: 1000632
+ 633: 1000633
+ 634: 1000634
+ 635: 1000635
+ 636: 1000636
+ 637: 1000637
+ 638: 1000638
+ 639: 1000639
+ 640: 1000640
+ 641: 1000641
+ 642: 1000642
+ 643: 1000643
+ 644: 1000644
+ 645: 1000645
+ 646: 1000646
+ 647: 1000647
+ 648: 1000648
+ 649: 1000649
+ 650: 1000650
+ 651: 1000651
+ 652: 1000652
+ 653: 1000653
+ 654: 1000654
+ 655: 1000655
+ 656: 1000656
+ 657: 1000657
+ 658: 1000658
+ 659: 1000659
+ 660: 1000660
+ 661: 1000661
+ 662: 1000662
+ 663: 1000663
+ 664: 1000664
+ 665: 1000665
+ 666: 1000666
+ 667: 1000667
+ 668: 1000668
+ 669: 1000669
+ 670: 1000670
+ 671: 1000671
+ 672: 1000672
+ 673: 1000673
+ 674: 1000674
+ 675: 1000675
+ 676: 1000676
+ 677: 1000677
+ 678: 1000678
+ 679: 1000679
+ 680: 1000680
+ 681: 1000681
+ 682: 1000682
+ 683: 1000683
+ 684: 1000684
+ 685: 1000685
+ 686: 1000686
+ 687: 1000687
+ 688: 1000688
+ 689: 1000689
+ 690: 1000690
+ 691: 1000691
+ 692: 1000692
+ 693: 1000693
+ 694: 1000694
+ 695: 1000695
+ 696: 1000696
+ 697: 1000697
+ 698: 1000698
+ 699: 1000699
+ 700: 1000700
+ 701: 1000701
+ 702: 1000702
+ 703: 1000703
+ 704: 1000704
+ 705: 1000705
+ 706: 1000706
+ 707: 1000707
+ 708: 1000708
+ 709: 1000709
+ 710: 1000710
+ 711: 1000711
+ 712: 1000712
+ 713: 1000713
+ 714: 1000714
+ 715: 1000715
+ 716: 1000716
+ 717: 1000717
+ 718: 1000718
+ 719: 1000719
+ 720: 1000720
+ 721: 1000721
+ 722: 1000722
+ 723: 1000723
+ 724: 1000724
+ 725: 1000725
+ 726: 1000726
+ 727: 1000727
+ 728: 1000728
+ 729: 1000729
+ 730: 1000730
+ 731: 1000731
+ 732: 1000732
+ 733: 1000733
+ 734: 1000734
+ 735: 1000735
+ 736: 1000736
+ 737: 1000737
+ 738: 1000738
+ 739: 1000739
+ 740: 1000740
+ 741: 1000741
+ 742: 1000742
+ 743: 1000743
+ 744: 1000744
+ 745: 1000745
+ 746: 1000746
+ 747: 1000747
+ 748: 1000748
+ 749: 1000749
+ 750: 1000750
+ 751: 1000751
+ 752: 1000752
+ 753: 1000753
+ 754: 1000754
+ 755: 1000755
+ 756: 1000756
+ 757: 1000757
+ 758: 1000758
+ 759: 1000759
+ 760: 1000760
+ 761: 1000761
+ 762: 1000762
+ 763: 1000763
+ 764: 1000764
+ 765: 1000765
+ 766: 1000766
+ 767: 1000767
+ 768: 1000768
+ 769: 1000769
+ 770: 1000770
+ 771: 1000771
+ 772: 1000772
+ 773: 1000773
+ 774: 1000774
+ 775: 1000775
+ 776: 1000776
+ 777: 1000777
+ 778: 1000778
+ 779: 1000779
+ 780: 1000780
+ 781: 1000781
+ 782: 1000782
+ 783: 1000783
+ 784: 1000784
+ 785: 1000785
+ 786: 1000786
+ 787: 1000787
+ 788: 1000788
+ 789: 1000789
+ 790: 1000790
+ 791: 1000791
+ 792: 1000792
+ 793: 1000793
+ 794: 1000794
+ 795: 1000795
+ 796: 1000796
+ 797: 1000797
+ 798: 1000798
+ 799: 1000799
+ 800: 1000800
+ 801: 1000801
+ 802: 1000802
+ 803: 1000803
+ 804: 1000804
+ 805: 1000805
+ 806: 1000806
+ 807: 1000807
+ 808: 1000808
+ 809: 1000809
+ 810: 1000810
+ 811: 1000811
+ 812: 1000812
+ 813: 1000813
+ 814: 1000814
+ 815: 1000815
+ 816: 1000816
+ 817: 1000817
+ 818: 1000818
+ 819: 1000819
+ 820: 1000820
+ 821: 1000821
+ 822: 1000822
+ 823: 1000823
+ 824: 1000824
+ 825: 1000825
+ 826: 1000826
+ 827: 1000827
+ 828: 1000828
+ 829: 1000829
+ 830: 1000830
+ 831: 1000831
+ 832: 1000832
+ 833: 1000833
+ 834: 1000834
+ 835: 1000835
+ 836: 1000836
+ 837: 1000837
+ 838: 1000838
+ 839: 1000839
+ 840: 1000840
+ 841: 1000841
+ 842: 1000842
+ 843: 1000843
+ 844: 1000844
+ 845: 1000845
+ 846: 1000846
+ 847: 1000847
+ 848: 1000848
+ 849: 1000849
+ 850: 1000850
+ 851: 1000851
+ 852: 1000852
+ 853: 1000853
+ 854: 1000854
+ 855: 1000855
+ 856: 1000856
+ 857: 1000857
+ 858: 1000858
+ 859: 1000859
+ 860: 1000860
+ 861: 1000861
+ 862: 1000862
+ 863: 1000863
+ 864: 1000864
+ 865: 1000865
+ 866: 1000866
+ 867: 1000867
+ 868: 1000868
+ 869: 1000869
+ 870: 1000870
+ 871: 1000871
+ 872: 1000872
+ 873: 1000873
+ 874: 1000874
+ 875: 1000875
+ 876: 1000876
+ 877: 1000877
+ 878: 1000878
+ 879: 1000879
+ 880: 1000880
+ 881: 1000881
+ 882: 1000882
+ 883: 1000883
+ 884: 1000884
+ 885: 1000885
+ 886: 1000886
+ 887: 1000887
+ 888: 1000888
+ 889: 1000889
+ 890: 1000890
+ 891: 1000891
+ 892: 1000892
+ 893: 1000893
+ 894: 1000894
+ 895: 1000895
+ 896: 1000896
+ 897: 1000897
+ 898: 1000898
+ 899: 1000899
+ 900: 1000900
+ 901: 1000901
+ 902: 1000902
+ 903: 1000903
+ 904: 1000904
+ 905: 1000905
+ 906: 1000906
+ 907: 1000907
+ 908: 1000908
+ 909: 1000909
+ 910: 1000910
+ 911: 1000911
+ 912: 1000912
+ 913: 1000913
+ 914: 1000914
+ 915: 1000915
+ 916: 1000916
+ 917: 1000917
+ 918: 1000918
+ 919: 1000919
+ 920: 1000920
+ 921: 1000921
+ 922: 1000922
+ 923: 1000923
+ 924: 1000924
+ 925: 1000925
+ 926: 1000926
+ 927: 1000927
+ 928: 1000928
+ 929: 1000929
+ 930: 1000930
+ 931: 1000931
+ 932: 1000932
+ 933: 1000933
+ 934: 1000934
+ 935: 1000935
+ 936: 1000936
+ 937: 1000937
+ 938: 1000938
+ 939: 1000939
+ 940: 1000940
+ 941: 1000941
+ 942: 1000942
+ 943: 1000943
+ 944: 1000944
+ 945: 1000945
+ 946: 1000946
+ 947: 1000947
+ 948: 1000948
+ 949: 1000949
+ 950: 1000950
+ 951: 1000951
+ 952: 1000952
+ 953: 1000953
+ 954: 1000954
+ 955: 1000955
+ 956: 1000956
+ 957: 1000957
+ 958: 1000958
+ 959: 1000959
+ 960: 1000960
+ 961: 1000961
+ 962: 1000962
+ 963: 1000963
+ 964: 1000964
+ 965: 1000965
+ 966: 1000966
+ 967: 1000967
+ 968: 1000968
+ 969: 1000969
+ 970: 1000970
+ 971: 1000971
+ 972: 1000972
+ 973: 1000973
+ 974: 1000974
+ 975: 1000975
+ 976: 1000976
+ 977: 1000977
+ 978: 1000978
+ 979: 1000979
+ 980: 1000980
+ 981: 1000981
+ 982: 1000982
+ 983: 1000983
+ 984: 1000984
+ 985: 1000985
+ 986: 1000986
+ 987: 1000987
+ 988: 1000988
+ 989: 1000989
+ 990: 1000990
+ 991: 1000991
+ 992: 1000992
+ 993: 1000993
+ 994: 1000994
+ 995: 1000995
+ 996: 1000996
+ 997: 1000997
+ 998: 1000998
+ 999: 1000999
+ 1000: 1001000
+ 1001: 1001001
+ 1002: 1001002
+ 1003: 1001003
+ 1004: 1001004
+ 1005: 1001005
+ 1006: 1001006
+ 1007: 1001007
+ 1008: 1001008
+ 1009: 1001009
+ 1010: 1001010
+ 1011: 1001011
+ 1012: 1001012
+ 1013: 1001013
+ 1014: 1001014
+ 1015: 1001015
+ 1016: 1001016
+ 1017: 1001017
+ 1018: 1001018
+ 1019: 1001019
+ 1020: 1001020
+ 1021: 1001021
+ 1022: 1001022
+ 1023: 1001023
+ 1024: 1001024
+ 1025: 1001025
+ 1026: 1001026
+ 1027: 1001027
+ 1028: 1001028
+ 1029: 1001029
+ 1030: 1001030
+ 1031: 1001031
+ 1032: 1001032
+ 1033: 1001033
+ 1034: 1001034
+ 1035: 1001035
+ 1036: 1001036
+ 1037: 1001037
+ 1038: 1001038
+ 1039: 1001039
+ 1040: 1001040
+ 1041: 1001041
+ 1042: 1001042
+ 1043: 1001043
+ 1044: 1001044
+ 1045: 1001045
+ 1046: 1001046
+ 1047: 1001047
+ 1048: 1001048
+ 1049: 1001049
+ 1050: 1001050
+ 1051: 1001051
+ 1052: 1001052
+ 1053: 1001053
+ 1054: 1001054
+ 1055: 1001055
+ 1056: 1001056
+ 1057: 1001057
+ 1058: 1001058
+ 1059: 1001059
+ 1060: 1001060
+ 1061: 1001061
+ 1062: 1001062
+ 1063: 1001063
+ 1064: 1001064
+ 1065: 1001065
+ 1066: 1001066
+ 1067: 1001067
+ 1068: 1001068
+ 1069: 1001069
+ 1070: 1001070
+ 1071: 1001071
+ 1072: 1001072
+ 1073: 1001073
+ 1074: 1001074
+ 1075: 1001075
+ 1076: 1001076
+ 1077: 1001077
+ 1078: 1001078
+ 1079: 1001079
+ 1080: 1001080
+ 1081: 1001081
+ 1082: 1001082
+ 1083: 1001083
+ 1084: 1001084
+ 1085: 1001085
+ 1086: 1001086
+ 1087: 1001087
+ 1088: 1001088
+ 1089: 1001089
+ 1090: 1001090
+ 1091: 1001091
+ 1092: 1001092
+ 1093: 1001093
+ 1094: 1001094
+ 1095: 1001095
+ 1096: 1001096
+ 1097: 1001097
+ 1098: 1001098
+ 1099: 1001099
+ 1100: 1001100
+ 1101: 1001101
+ 1102: 1001102
+ 1103: 1001103
+ 1104: 1001104
+ 1105: 1001105
+ 1106: 1001106
+ 1107: 1001107
+ 1108: 1001108
+ 1109: 1001109
+ 1110: 1001110
+ 1111: 1001111
+ 1112: 1001112
+ 1113: 1001113
+ 1114: 1001114
+ 1115: 1001115
+ 1116: 1001116
+ 1117: 1001117
+ 1118: 1001118
+ 1119: 1001119
+ 1120: 1001120
+ 1121: 1001121
+ 1122: 1001122
+ 1123: 1001123
+ 1124: 1001124
+ 1125: 1001125
+ 1126: 1001126
+ 1127: 1001127
+ 1128: 1001128
+ 1129: 1001129
+ 1130: 1001130
+ 1131: 1001131
+ 1132: 1001132
+ 1133: 1001133
+ 1134: 1001134
+ 1135: 1001135
+ 1136: 1001136
+ 1137: 1001137
+ 1138: 1001138
+ 1139: 1001139
+ 1140: 1001140
+ 1141: 1001141
+ 1142: 1001142
+ 1143: 1001143
+ 1144: 1001144
+ 1145: 1001145
+ 1146: 1001146
+ 1147: 1001147
+ 1148: 1001148
+ 1149: 1001149
+ 1150: 1001150
+ 1151: 1001151
+ 1152: 1001152
+ 1153: 1001153
+ 1154: 1001154
+ 1155: 1001155
+ 1156: 1001156
+ 1157: 1001157
+ 1158: 1001158
+ 1159: 1001159
+ 1160: 1001160
+ 1161: 1001161
+ 1162: 1001162
+ 1163: 1001163
+ 1164: 1001164
+ 1165: 1001165
+ 1166: 1001166
+ 1167: 1001167
+ 1168: 1001168
+ 1169: 1001169
+ 1170: 1001170
+ 1171: 1001171
+ 1172: 1001172
+ 1173: 1001173
+ 1174: 1001174
+ 1175: 1001175
+ 1176: 1001176
+ 1177: 1001177
+ 1178: 1001178
+ 1179: 1001179
+ 1180: 1001180
+ 1181: 1001181
+ 1182: 1001182
+ 1183: 1001183
+ 1184: 1001184
+ 1185: 1001185
+ 1186: 1001186
+ 1187: 1001187
+ 1188: 1001188
+ 1189: 1001189
+ 1190: 1001190
+ 1191: 1001191
+ 1192: 1001192
+ 1193: 1001193
+ 1194: 1001194
+ 1195: 1001195
+ 1196: 1001196
+ 1197: 1001197
+ 1198: 1001198
+ 1199: 1001199
+ 1200: 1001200
+ 1201: 1001201
+ 1202: 1001202
+ 1203: 1001203
+ 1204: 1001204
+ 1205: 1001205
+ 1206: 1001206
+ 1207: 1001207
+ 1208: 1001208
+ 1209: 1001209
+ 1210: 1001210
+ 1211: 1001211
+ 1212: 1001212
+ 1213: 1001213
+ 1214: 1001214
+ 1215: 1001215
+ 1216: 1001216
+ 1217: 1001217
+ 1218: 1001218
+ 1219: 1001219
+ 1220: 1001220
+ 1221: 1001221
+ 1222: 1001222
+ 1223: 1001223
+ 1224: 1001224
+ 1225: 1001225
+ 1226: 1001226
+ 1227: 1001227
+ 1228: 1001228
+ 1229: 1001229
+ 1230: 1001230
+ 1231: 1001231
+ 1232: 1001232
+ 1233: 1001233
+ 1234: 1001234
+ 1235: 1001235
+ 1236: 1001236
+ 1237: 1001237
+ 1238: 1001238
+ 1239: 1001239
+ 1240: 1001240
+ 1241: 1001241
+ 1242: 1001242
+ 1243: 1001243
+ 1244: 1001244
+ 1245: 1001245
+ 1246: 1001246
+ 1247: 1001247
+ 1248: 1001248
+ 1249: 1001249
+ 1250: 1001250
+ 1251: 1001251
+ 1252: 1001252
+ 1253: 1001253
+ 1254: 1001254
+ 1255: 1001255
+ 1256: 1001256
+ 1257: 1001257
+ 1258: 1001258
+ 1259: 1001259
+ 1260: 1001260
+ 1261: 1001261
+ 1262: 1001262
+ 1263: 1001263
+ 1264: 1001264
+ 1265: 1001265
+ 1266: 1001266
+ 1267: 1001267
+ 1268: 1001268
+ 1269: 1001269
+ 1270: 1001270
+ 1271: 1001271
+ 1272: 1001272
+ 1273: 1001273
+ 1274: 1001274
+ 1275: 1001275
+ 1276: 1001276
+ 1277: 1001277
+ 1278: 1001278
+ 1279: 1001279
+ 1280: 1001280
+ 1281: 1001281
+ 1282: 1001282
+ 1283: 1001283
+ 1284: 1001284
+ 1285: 1001285
+ 1286: 1001286
+ 1287: 1001287
+ 1288: 1001288
+ 1289: 1001289
+ 1290: 1001290
+ 1291: 1001291
+ 1292: 1001292
+ 1293: 1001293
+ 1294: 1001294
+ 1295: 1001295
+ 1296: 1001296
+ 1297: 1001297
+ 1298: 1001298
+ 1299: 1001299
+ 1300: 1001300
+ 1301: 1001301
+ 1302: 1001302
+ 1303: 1001303
+ 1304: 1001304
+ 1305: 1001305
+ 1306: 1001306
+ 1307: 1001307
+ 1308: 1001308
+ 1309: 1001309
+ 1310: 1001310
+ 1311: 1001311
+ 1312: 1001312
+ 1313: 1001313
+ 1314: 1001314
+ 1315: 1001315
+ 1316: 1001316
+ 1317: 1001317
+ 1318: 1001318
+ 1319: 1001319
+ 1320: 1001320
+ 1321: 1001321
+ 1322: 1001322
+ 1323: 1001323
+ 1324: 1001324
+ 1325: 1001325
+ 1326: 1001326
+ 1327: 1001327
+ 1328: 1001328
+ 1329: 1001329
+ 1330: 1001330
+ 1331: 1001331
+ 1332: 1001332
+ 1333: 1001333
+ 1334: 1001334
+ 1335: 1001335
+ 1336: 1001336
+ 1337: 1001337
+ 1338: 1001338
+ 1339: 1001339
+ 1340: 1001340
+ 1341: 1001341
+ 1342: 1001342
+ 1343: 1001343
+ 1344: 1001344
+ 1345: 1001345
+ 1346: 1001346
+ 1347: 1001347
+ 1348: 1001348
+ 1349: 1001349
+ 1350: 1001350
+ 1351: 1001351
+ 1352: 1001352
+ 1353: 1001353
+ 1354: 1001354
+ 1355: 1001355
+ 1356: 1001356
+ 1357: 1001357
+ 1358: 1001358
+ 1359: 1001359
+ 1360: 1001360
+ 1361: 1001361
+ 1362: 1001362
+ 1363: 1001363
+ 1364: 1001364
+ 1365: 1001365
+ 1366: 1001366
+ 1367: 1001367
+ 1368: 1001368
+ 1369: 1001369
+ 1370: 1001370
+ 1371: 1001371
+ 1372: 1001372
+ 1373: 1001373
+ 1374: 1001374
+ 1375: 1001375
+ 1376: 1001376
+ 1377: 1001377
+ 1378: 1001378
+ 1379: 1001379
+ 1380: 1001380
+ 1381: 1001381
+ 1382: 1001382
+ 1383: 1001383
+ 1384: 1001384
+ 1385: 1001385
+ 1386: 1001386
+ 1387: 1001387
+ 1388: 1001388
+ 1389: 1001389
+ 1390: 1001390
+ 1391: 1001391
+ 1392: 1001392
+ 1393: 1001393
+ 1394: 1001394
+ 1395: 1001395
+ 1396: 1001396
+ 1397: 1001397
+ 1398: 1001398
+ 1399: 1001399
+ 1400: 1001400
+ 1401: 1001401
+ 1402: 1001402
+ 1403: 1001403
+ 1404: 1001404
+ 1405: 1001405
+ 1406: 1001406
+ 1407: 1001407
+ 1408: 1001408
+ 1409: 1001409
+ 1410: 1001410
+ 1411: 1001411
+ 1412: 1001412
+ 1413: 1001413
+ 1414: 1001414
+ 1415: 1001415
+ 1416: 1001416
+ 1417: 1001417
+ 1418: 1001418
+ 1419: 1001419
+ 1420: 1001420
+ 1421: 1001421
+ 1422: 1001422
+ 1423: 1001423
+ 1424: 1001424
+ 1425: 1001425
+ 1426: 1001426
+ 1427: 1001427
+ 1428: 1001428
+ 1429: 1001429
+ 1430: 1001430
+ 1431: 1001431
+ 1432: 1001432
+ 1433: 1001433
+ 1434: 1001434
+ 1435: 1001435
+ 1436: 1001436
+ 1437: 1001437
+ 1438: 1001438
+ 1439: 1001439
+ 1440: 1001440
+ 1441: 1001441
+ 1442: 1001442
+ 1443: 1001443
+ 1444: 1001444
+ 1445: 1001445
+ 1446: 1001446
+ 1447: 1001447
+ 1448: 1001448
+ 1449: 1001449
+ 1450: 1001450
+ 1451: 1001451
+ 1452: 1001452
+ 1453: 1001453
+ 1454: 1001454
+ 1455: 1001455
+ 1456: 1001456
+ 1457: 1001457
+ 1458: 1001458
+ 1459: 1001459
+ 1460: 1001460
+ 1461: 1001461
+ 1462: 1001462
+ 1463: 1001463
+ 1464: 1001464
+ 1465: 1001465
+ 1466: 1001466
+ 1467: 1001467
+ 1468: 1001468
+ 1469: 1001469
+ 1470: 1001470
+ 1471: 1001471
+ 1472: 1001472
+ 1473: 1001473
+ 1474: 1001474
+ 1475: 1001475
+ 1476: 1001476
+ 1477: 1001477
+ 1478: 1001478
+ 1479: 1001479
+ 1480: 1001480
+ 1481: 1001481
+ 1482: 1001482
+ 1483: 1001483
+ 1484: 1001484
+ 1485: 1001485
+ 1486: 1001486
+ 1487: 1001487
+ 1488: 1001488
+ 1489: 1001489
+ 1490: 1001490
+ 1491: 1001491
+ 1492: 1001492
+ 1493: 1001493
+ 1494: 1001494
+ 1495: 1001495
+ 1496: 1001496
+ 1497: 1001497
+ 1498: 1001498
+ 1499: 1001499
+ 1500: 1001500
+ 1501: 1001501
+ 1502: 1001502
+ 1503: 1001503
+ 1504: 1001504
+ 1505: 1001505
+ 1506: 1001506
+ 1507: 1001507
+ 1508: 1001508
+ 1509: 1001509
+ 1510: 1001510
+ 1511: 1001511
+ 1512: 1001512
+ 1513: 1001513
+ 1514: 1001514
+ 1515: 1001515
+ 1516: 1001516
+ 1517: 1001517
+ 1518: 1001518
+ 1519: 1001519
+ 1520: 1001520
+ 1521: 1001521
+ 1522: 1001522
+ 1523: 1001523
+ 1524: 1001524
+ 1525: 1001525
+ 1526: 1001526
+ 1527: 1001527
+ 1528: 1001528
+ 1529: 1001529
+ 1530: 1001530
+ 1531: 1001531
+ 1532: 1001532
+ 1533: 1001533
+ 1534: 1001534
+ 1535: 1001535
+ 1536: 1001536
+ 1537: 1001537
+ 1538: 1001538
+ 1539: 1001539
+ 1540: 1001540
+ 1541: 1001541
+ 1542: 1001542
+ 1543: 1001543
+ 1544: 1001544
+ 1545: 1001545
+ 1546: 1001546
+ 1547: 1001547
+ 1548: 1001548
+ 1549: 1001549
+ 1550: 1001550
+ 1551: 1001551
+ 1552: 1001552
+ 1553: 1001553
+ 1554: 1001554
+ 1555: 1001555
+ 1556: 1001556
+ 1557: 1001557
+ 1558: 1001558
+ 1559: 1001559
+ 1560: 1001560
+ 1561: 1001561
+ 1562: 1001562
+ 1563: 1001563
+ 1564: 1001564
+ 1565: 1001565
+ 1566: 1001566
+ 1567: 1001567
+ 1568: 1001568
+ 1569: 1001569
+ 1570: 1001570
+ 1571: 1001571
+ 1572: 1001572
+ 1573: 1001573
+ 1574: 1001574
+ 1575: 1001575
+ 1576: 1001576
+ 1577: 1001577
+ 1578: 1001578
+ 1579: 1001579
+ 1580: 1001580
+ 1581: 1001581
+ 1582: 1001582
+ 1583: 1001583
+ 1584: 1001584
+ 1585: 1001585
+ 1586: 1001586
+ 1587: 1001587
+ 1588: 1001588
+ 1589: 1001589
+ 1590: 1001590
+ 1591: 1001591
+ 1592: 1001592
+ 1593: 1001593
+ 1594: 1001594
+ 1595: 1001595
+ 1596: 1001596
+ 1597: 1001597
+ 1598: 1001598
+ 1599: 1001599
+ 1600: 1001600
+ 1601: 1001601
+ 1602: 1001602
+ 1603: 1001603
+ 1604: 1001604
+ 1605: 1001605
+ 1606: 1001606
+ 1607: 1001607
+ 1608: 1001608
+ 1609: 1001609
+ 1610: 1001610
+ 1611: 1001611
+ 1612: 1001612
+ 1613: 1001613
+ 1614: 1001614
+ 1615: 1001615
+ 1616: 1001616
+ 1617: 1001617
+ 1618: 1001618
+ 1619: 1001619
+ 1620: 1001620
+ 1621: 1001621
+ 1622: 1001622
+ 1623: 1001623
+ 1624: 1001624
+ 1625: 1001625
+ 1626: 1001626
+ 1627: 1001627
+ 1628: 1001628
+ 1629: 1001629
+ 1630: 1001630
+ 1631: 1001631
+ 1632: 1001632
+ 1633: 1001633
+ 1634: 1001634
+ 1635: 1001635
+ 1636: 1001636
+ 1637: 1001637
+ 1638: 1001638
+ 1639: 1001639
+ 1640: 1001640
+ 1641: 1001641
+ 1642: 1001642
+ 1643: 1001643
+ 1644: 1001644
+ 1645: 1001645
+ 1646: 1001646
+ 1647: 1001647
+ 1648: 1001648
+ 1649: 1001649
+ 1650: 1001650
+ 1651: 1001651
+ 1652: 1001652
+ 1653: 1001653
+ 1654: 1001654
+ 1655: 1001655
+ 1656: 1001656
+ 1657: 1001657
+ 1658: 1001658
+ 1659: 1001659
+ 1660: 1001660
+ 1661: 1001661
+ 1662: 1001662
+ 1663: 1001663
+ 1664: 1001664
+ 1665: 1001665
+ 1666: 1001666
+ 1667: 1001667
+ 1668: 1001668
+ 1669: 1001669
+ 1670: 1001670
+ 1671: 1001671
+ 1672: 1001672
+ 1673: 1001673
+ 1674: 1001674
+ 1675: 1001675
+ 1676: 1001676
+ 1677: 1001677
+ 1678: 1001678
+ 1679: 1001679
+ 1680: 1001680
+ 1681: 1001681
+ 1682: 1001682
+ 1683: 1001683
+ 1684: 1001684
+ 1685: 1001685
+ 1686: 1001686
+ 1687: 1001687
+ 1688: 1001688
+ 1689: 1001689
+ 1690: 1001690
+ 1691: 1001691
+ 1692: 1001692
+ 1693: 1001693
+ 1694: 1001694
+ 1695: 1001695
+ 1696: 1001696
+ 1697: 1001697
+ 1698: 1001698
+ 1699: 1001699
+ 1700: 1001700
+ 1701: 1001701
+ 1702: 1001702
+ 1703: 1001703
+ 1704: 1001704
+ 1705: 1001705
+ 1706: 1001706
+ 1707: 1001707
+ 1708: 1001708
+ 1709: 1001709
+ 1710: 1001710
+ 1711: 1001711
+ 1712: 1001712
+ 1713: 1001713
+ 1714: 1001714
+ 1715: 1001715
+ 1716: 1001716
+ 1717: 1001717
+ 1718: 1001718
+ 1719: 1001719
+ 1720: 1001720
+ 1721: 1001721
+ 1722: 1001722
+ 1723: 1001723
+ 1724: 1001724
+ 1725: 1001725
+ 1726: 1001726
+ 1727: 1001727
+ 1728: 1001728
+ 1729: 1001729
+ 1730: 1001730
+ 1731: 1001731
+ 1732: 1001732
+ 1733: 1001733
+ 1734: 1001734
+ 1735: 1001735
+ 1736: 1001736
+ 1737: 1001737
+ 1738: 1001738
+ 1739: 1001739
+ 1740: 1001740
+ 1741: 1001741
+ 1742: 1001742
+ 1743: 1001743
+ 1744: 1001744
+ 1745: 1001745
+ 1746: 1001746
+ 1747: 1001747
+ 1748: 1001748
+ 1749: 1001749
+ 1750: 1001750
+ 1751: 1001751
+ 1752: 1001752
+ 1753: 1001753
+ 1754: 1001754
+ 1755: 1001755
+ 1756: 1001756
+ 1757: 1001757
+ 1758: 1001758
+ 1759: 1001759
+ 1760: 1001760
+ 1761: 1001761
+ 1762: 1001762
+ 1763: 1001763
+ 1764: 1001764
+ 1765: 1001765
+ 1766: 1001766
+ 1767: 1001767
+ 1768: 1001768
+ 1769: 1001769
+ 1770: 1001770
+ 1771: 1001771
+ 1772: 1001772
+ 1773: 1001773
+ 1774: 1001774
+ 1775: 1001775
+ 1776: 1001776
+ 1777: 1001777
+ 1778: 1001778
+ 1779: 1001779
+ 1780: 1001780
+ 1781: 1001781
+ 1782: 1001782
+ 1783: 1001783
+ 1784: 1001784
+ 1785: 1001785
+ 1786: 1001786
+ 1787: 1001787
+ 1788: 1001788
+ 1789: 1001789
+ 1790: 1001790
+ 1791: 1001791
+ 1792: 1001792
+ 1793: 1001793
+ 1794: 1001794
+ 1795: 1001795
+ 1796: 1001796
+ 1797: 1001797
+ 1798: 1001798
+ 1799: 1001799
+ 1800: 1001800
+ 1801: 1001801
+ 1802: 1001802
+ 1803: 1001803
+ 1804: 1001804
+ 1805: 1001805
+ 1806: 1001806
+ 1807: 1001807
+ 1808: 1001808
+ 1809: 1001809
+ 1810: 1001810
+ 1811: 1001811
+ 1812: 1001812
+ 1813: 1001813
+ 1814: 1001814
+ 1815: 1001815
+ 1816: 1001816
+ 1817: 1001817
+ 1818: 1001818
+ 1819: 1001819
+ 1820: 1001820
+ 1821: 1001821
+ 1822: 1001822
+ 1823: 1001823
+ 1824: 1001824
+ 1825: 1001825
+ 1826: 1001826
+ 1827: 1001827
+ 1828: 1001828
+ 1829: 1001829
+ 1830: 1001830
+ 1831: 1001831
+ 1832: 1001832
+ 1833: 1001833
+ 1834: 1001834
+ 1835: 1001835
+ 1836: 1001836
+ 1837: 1001837
+ 1838: 1001838
+ 1839: 1001839
+ 1840: 1001840
+ 1841: 1001841
+ 1842: 1001842
+ 1843: 1001843
+ 1844: 1001844
+ 1845: 1001845
+ 1846: 1001846
+ 1847: 1001847
+ 1848: 1001848
+ 1849: 1001849
+ 1850: 1001850
+ 1851: 1001851
+ 1852: 1001852
+ 1853: 1001853
+ 1854: 1001854
+ 1855: 1001855
+ 1856: 1001856
+ 1857: 1001857
+ 1858: 1001858
+ 1859: 1001859
+ 1860: 1001860
+ 1861: 1001861
+ 1862: 1001862
+ 1863: 1001863
+ 1864: 1001864
+ 1865: 1001865
+ 1866: 1001866
+ 1867: 1001867
+ 1868: 1001868
+ 1869: 1001869
+ 1870: 1001870
+ 1871: 1001871
+ 1872: 1001872
+ 1873: 1001873
+ 1874: 1001874
+ 1875: 1001875
+ 1876: 1001876
+ 1877: 1001877
+ 1878: 1001878
+ 1879: 1001879
+ 1880: 1001880
+ 1881: 1001881
+ 1882: 1001882
+ 1883: 1001883
+ 1884: 1001884
+ 1885: 1001885
+ 1886: 1001886
+ 1887: 1001887
+ 1888: 1001888
+ 1889: 1001889
+ 1890: 1001890
+ 1891: 1001891
+ 1892: 1001892
+ 1893: 1001893
+ 1894: 1001894
+ 1895: 1001895
+ 1896: 1001896
+ 1897: 1001897
+ 1898: 1001898
+ 1899: 1001899
+ 1900: 1001900
+ 1901: 1001901
+ 1902: 1001902
+ 1903: 1001903
+ 1904: 1001904
+ 1905: 1001905
+ 1906: 1001906
+ 1907: 1001907
+ 1908: 1001908
+ 1909: 1001909
+ 1910: 1001910
+ 1911: 1001911
+ 1912: 1001912
+ 1913: 1001913
+ 1914: 1001914
+ 1915: 1001915
+ 1916: 1001916
+ 1917: 1001917
+ 1918: 1001918
+ 1919: 1001919
+ 1920: 1001920
+ 1921: 1001921
+ 1922: 1001922
+ 1923: 1001923
+ 1924: 1001924
+ 1925: 1001925
+ 1926: 1001926
+ 1927: 1001927
+ 1928: 1001928
+ 1929: 1001929
+ 1930: 1001930
+ 1931: 1001931
+ 1932: 1001932
+ 1933: 1001933
+ 1934: 1001934
+ 1935: 1001935
+ 1936: 1001936
+ 1937: 1001937
+ 1938: 1001938
+ 1939: 1001939
+ 1940: 1001940
+ 1941: 1001941
+ 1942: 1001942
+ 1943: 1001943
+ 1944: 1001944
+ 1945: 1001945
+ 1946: 1001946
+ 1947: 1001947
+ 1948: 1001948
+ 1949: 1001949
+ 1950: 1001950
+ 1951: 1001951
+ 1952: 1001952
+ 1953: 1001953
+ 1954: 1001954
+ 1955: 1001955
+ 1956: 1001956
+ 1957: 1001957
+ 1958: 1001958
+ 1959: 1001959
+ 1960: 1001960
+ 1961: 1001961
+ 1962: 1001962
+ 1963: 1001963
+ 1964: 1001964
+ 1965: 1001965
+ 1966: 1001966
+ 1967: 1001967
+ 1968: 1001968
+ 1969: 1001969
+ 1970: 1001970
+ 1971: 1001971
+ 1972: 1001972
+ 1973: 1001973
+ 1974: 1001974
+ 1975: 1001975
+ 1976: 1001976
+ 1977: 1001977
+ 1978: 1001978
+ 1979: 1001979
+ 1980: 1001980
+ 1981: 1001981
+ 1982: 1001982
+ 1983: 1001983
+ 1984: 1001984
+ 1985: 1001985
+ 1986: 1001986
+ 1987: 1001987
+ 1988: 1001988
+ 1989: 1001989
+ 1990: 1001990
+ 1991: 1001991
+ 1992: 1001992
+ 1993: 1001993
+ 1994: 1001994
+ 1995: 1001995
+ 1996: 1001996
+ 1997: 1001997
+ 1998: 1001998
+ 1999: 1001999
+ 2000: 1002000
+ 2001: 1002001
+ 2002: 1002002
+ 2003: 1002003
+ 2004: 1002004
+ 2005: 1002005
+ 2006: 1002006
+ 2007: 1002007
+ 2008: 1002008
+ 2009: 1002009
+ 2010: 1002010
+ 2011: 1002011
+ 2012: 1002012
+ 2013: 1002013
+ 2014: 1002014
+ 2015: 1002015
+ 2016: 1002016
+ 2017: 1002017
+ 2018: 1002018
+ 2019: 1002019
+ 2020: 1002020
+ 2021: 1002021
+ 2022: 1002022
+ 2023: 1002023
+ 2024: 1002024
+ 2025: 1002025
+ 2026: 1002026
+ 2027: 1002027
+ 2028: 1002028
+ 2029: 1002029
+ 2030: 1002030
+ 2031: 1002031
+ 2032: 1002032
+ 2033: 1002033
+ 2034: 1002034
+ 2035: 1002035
+ 2036: 1002036
+ 2037: 1002037
+ 2038: 1002038
+ 2039: 1002039
+ 2040: 1002040
+ 2041: 1002041
+ 2042: 1002042
+ 2043: 1002043
+ 2044: 1002044
+ 2045: 1002045
+ 2046: 1002046
+ 2047: 1002047
+ 2048: 1002048
+ 2049: 1002049
+ 2050: 1002050
+ 2051: 1002051
+ 2052: 1002052
+ 2053: 1002053
+ 2054: 1002054
+ 2055: 1002055
+ 2056: 1002056
+ 2057: 1002057
+ 2058: 1002058
+ 2059: 1002059
+ 2060: 1002060
+ 2061: 1002061
+ 2062: 1002062
+ 2063: 1002063
+ 2064: 1002064
+ 2065: 1002065
+ 2066: 1002066
+ 2067: 1002067
+ 2068: 1002068
+ 2069: 1002069
+ 2070: 1002070
+ 2071: 1002071
+ 2072: 1002072
+ 2073: 1002073
+ 2074: 1002074
+ 2075: 1002075
+ 2076: 1002076
+ 2077: 1002077
+ 2078: 1002078
+ 2079: 1002079
+ 2080: 1002080
+ 2081: 1002081
+ 2082: 1002082
+ 2083: 1002083
+ 2084: 1002084
+ 2085: 1002085
+ 2086: 1002086
+ 2087: 1002087
+ 2088: 1002088
+ 2089: 1002089
+ 2090: 1002090
+ 2091: 1002091
+ 2092: 1002092
+ 2093: 1002093
+ 2094: 1002094
+ 2095: 1002095
+ 2096: 1002096
+ 2097: 1002097
+ 2098: 1002098
+ 2099: 1002099
+ 2100: 1002100
+ 2101: 1002101
+ 2102: 1002102
+ 2103: 1002103
+ 2104: 1002104
+ 2105: 1002105
+ 2106: 1002106
+ 2107: 1002107
+ 2108: 1002108
+ 2109: 1002109
+ 2110: 1002110
+ 2111: 1002111
+ 2112: 1002112
+ 2113: 1002113
+ 2114: 1002114
+ 2115: 1002115
+ 2116: 1002116
+ 2117: 1002117
+ 2118: 1002118
+ 2119: 1002119
+ 2120: 1002120
+ 2121: 1002121
+ 2122: 1002122
+ 2123: 1002123
+ 2124: 1002124
+ 2125: 1002125
+ 2126: 1002126
+ 2127: 1002127
+ 2128: 1002128
+ 2129: 1002129
+ 2130: 1002130
+ 2131: 1002131
+ 2132: 1002132
+ 2133: 1002133
+ 2134: 1002134
+ 2135: 1002135
+ 2136: 1002136
+ 2137: 1002137
+ 2138: 1002138
+ 2139: 1002139
+ 2140: 1002140
+ 2141: 1002141
+ 2142: 1002142
+ 2143: 1002143
+ 2144: 1002144
+ 2145: 1002145
+ 2146: 1002146
+ 2147: 1002147
+ 2148: 1002148
+ 2149: 1002149
+ 2150: 1002150
+ 2151: 1002151
+ 2152: 1002152
+ 2153: 1002153
+ 2154: 1002154
+ 2155: 1002155
+ 2156: 1002156
+ 2157: 1002157
+ 2158: 1002158
+ 2159: 1002159
+ 2160: 1002160
+ 2161: 1002161
+ 2162: 1002162
+ 2163: 1002163
+ 2164: 1002164
+ 2165: 1002165
+ 2166: 1002166
+ 2167: 1002167
+ 2168: 1002168
+ 2169: 1002169
+ 2170: 1002170
+ 2171: 1002171
+ 2172: 1002172
+ 2173: 1002173
+ 2174: 1002174
+ 2175: 1002175
+ 2176: 1002176
+ 2177: 1002177
+ 2178: 1002178
+ 2179: 1002179
+ 2180: 1002180
+ 2181: 1002181
+ 2182: 1002182
+ 2183: 1002183
+ 2184: 1002184
+ 2185: 1002185
+ 2186: 1002186
+ 2187: 1002187
+ 2188: 1002188
+ 2189: 1002189
+ 2190: 1002190
+ 2191: 1002191
+ 2192: 1002192
+ 2193: 1002193
+ 2194: 1002194
+ 2195: 1002195
+ 2196: 1002196
+ 2197: 1002197
+ 2198: 1002198
+ 2199: 1002199
+ 2200: 1002200
+ 2201: 1002201
+ 2202: 1002202
+ 2203: 1002203
+ 2204: 1002204
+ 2205: 1002205
+ 2206: 1002206
+ 2207: 1002207
+ 2208: 1002208
+ 2209: 1002209
+ 2210: 1002210
+ 2211: 1002211
+ 2212: 1002212
+ 2213: 1002213
+ 2214: 1002214
+ 2215: 1002215
+ 2216: 1002216
+ 2217: 1002217
+ 2218: 1002218
+ 2219: 1002219
+ 2220: 1002220
+ 2221: 1002221
+ 2222: 1002222
+ 2223: 1002223
+ 2224: 1002224
+ 2225: 1002225
+ 2226: 1002226
+ 2227: 1002227
+ 2228: 1002228
+ 2229: 1002229
+ 2230: 1002230
+ 2231: 1002231
+ 2232: 1002232
+ 2233: 1002233
+ 2234: 1002234
+ 2235: 1002235
+ 2236: 1002236
+ 2237: 1002237
+ 2238: 1002238
+ 2239: 1002239
+ 2240: 1002240
+ 2241: 1002241
+ 2242: 1002242
+ 2243: 1002243
+ 2244: 1002244
+ 2245: 1002245
+ 2246: 1002246
+ 2247: 1002247
+ 2248: 1002248
+ 2249: 1002249
+ 2250: 1002250
+ 2251: 1002251
+ 2252: 1002252
+ 2253: 1002253
+ 2254: 1002254
+ 2255: 1002255
+ 2256: 1002256
+ 2257: 1002257
+ 2258: 1002258
+ 2259: 1002259
+ 2260: 1002260
+ 2261: 1002261
+ 2262: 1002262
+ 2263: 1002263
+ 2264: 1002264
+ 2265: 1002265
+ 2266: 1002266
+ 2267: 1002267
+ 2268: 1002268
+ 2269: 1002269
+ 2270: 1002270
+ 2271: 1002271
+ 2272: 1002272
+ 2273: 1002273
+ 2274: 1002274
+ 2275: 1002275
+ 2276: 1002276
+ 2277: 1002277
+ 2278: 1002278
+ 2279: 1002279
+ 2280: 1002280
+ 2281: 1002281
+ 2282: 1002282
+ 2283: 1002283
+ 2284: 1002284
+ 2285: 1002285
+ 2286: 1002286
+ 2287: 1002287
+ 2288: 1002288
+ 2289: 1002289
+ 2290: 1002290
+ 2291: 1002291
+ 2292: 1002292
+ 2293: 1002293
+ 2294: 1002294
+ 2295: 1002295
+ 2296: 1002296
+ 2297: 1002297
+ 2298: 1002298
+ 2299: 1002299
+ 2300: 1002300
+ 2301: 1002301
+ 2302: 1002302
+ 2303: 1002303
+ 2304: 1002304
+ 2305: 1002305
+ 2306: 1002306
+ 2307: 1002307
+ 2308: 1002308
+ 2309: 1002309
+ 2310: 1002310
+ 2311: 1002311
+ 2312: 1002312
+ 2313: 1002313
+ 2314: 1002314
+ 2315: 1002315
+ 2316: 1002316
+ 2317: 1002317
+ 2318: 1002318
+ 2319: 1002319
+ 2320: 1002320
+ 2321: 1002321
+ 2322: 1002322
+ 2323: 1002323
+ 2324: 1002324
+ 2325: 1002325
+ 2326: 1002326
+ 2327: 1002327
+ 2328: 1002328
+ 2329: 1002329
+ 2330: 1002330
+ 2331: 1002331
+ 2332: 1002332
+ 2333: 1002333
+ 2334: 1002334
+ 2335: 1002335
+ 2336: 1002336
+ 2337: 1002337
+ 2338: 1002338
+ 2339: 1002339
+ 2340: 1002340
+ 2341: 1002341
+ 2342: 1002342
+ 2343: 1002343
+ 2344: 1002344
+ 2345: 1002345
+ 2346: 1002346
+ 2347: 1002347
+ 2348: 1002348
+ 2349: 1002349
+ 2350: 1002350
+ 2351: 1002351
+ 2352: 1002352
+ 2353: 1002353
+ 2354: 1002354
+ 2355: 1002355
+ 2356: 1002356
+ 2357: 1002357
+ 2358: 1002358
+ 2359: 1002359
+ 2360: 1002360
+ 2361: 1002361
+ 2362: 1002362
+ 2363: 1002363
+ 2364: 1002364
+ 2365: 1002365
+ 2366: 1002366
+ 2367: 1002367
+ 2368: 1002368
+ 2369: 1002369
+ 2370: 1002370
+ 2371: 1002371
+ 2372: 1002372
+ 2373: 1002373
+ 2374: 1002374
+ 2375: 1002375
+ 2376: 1002376
+ 2377: 1002377
+ 2378: 1002378
+ 2379: 1002379
+ 2380: 1002380
+ 2381: 1002381
+ 2382: 1002382
+ 2383: 1002383
+ 2384: 1002384
+ 2385: 1002385
+ 2386: 1002386
+ 2387: 1002387
+ 2388: 1002388
+ 2389: 1002389
+ 2390: 1002390
+ 2391: 1002391
+ 2392: 1002392
+ 2393: 1002393
+ 2394: 1002394
+ 2395: 1002395
+ 2396: 1002396
+ 2397: 1002397
+ 2398: 1002398
+ 2399: 1002399
+ 2400: 1002400
+ 2401: 1002401
+ 2402: 1002402
+ 2403: 1002403
+ 2404: 1002404
+ 2405: 1002405
+ 2406: 1002406
+ 2407: 1002407
+ 2408: 1002408
+ 2409: 1002409
+ 2410: 1002410
+ 2411: 1002411
+ 2412: 1002412
+ 2413: 1002413
+ 2414: 1002414
+ 2415: 1002415
+ 2416: 1002416
+ 2417: 1002417
+ 2418: 1002418
+ 2419: 1002419
+ 2420: 1002420
+ 2421: 1002421
+ 2422: 1002422
+ 2423: 1002423
+ 2424: 1002424
+ 2425: 1002425
+ 2426: 1002426
+ 2427: 1002427
+ 2428: 1002428
+ 2429: 1002429
+ 2430: 1002430
+ 2431: 1002431
+ 2432: 1002432
+ 2433: 1002433
+ 2434: 1002434
+ 2435: 1002435
+ 2436: 1002436
+ 2437: 1002437
+ 2438: 1002438
+ 2439: 1002439
+ 2440: 1002440
+ 2441: 1002441
+ 2442: 1002442
+ 2443: 1002443
+ 2444: 1002444
+ 2445: 1002445
+ 2446: 1002446
+ 2447: 1002447
+ 2448: 1002448
+ 2449: 1002449
+ 2450: 1002450
+ 2451: 1002451
+ 2452: 1002452
+ 2453: 1002453
+ 2454: 1002454
+ 2455: 1002455
+ 2456: 1002456
+ 2457: 1002457
+ 2458: 1002458
+ 2459: 1002459
+ 2460: 1002460
+ 2461: 1002461
+ 2462: 1002462
+ 2463: 1002463
+ 2464: 1002464
+ 2465: 1002465
+ 2466: 1002466
+ 2467: 1002467
+ 2468: 1002468
+ 2469: 1002469
+ 2470: 1002470
+ 2471: 1002471
+ 2472: 1002472
+ 2473: 1002473
+ 2474: 1002474
+ 2475: 1002475
+ 2476: 1002476
+ 2477: 1002477
+ 2478: 1002478
+ 2479: 1002479
+ 2480: 1002480
+ 2481: 1002481
+ 2482: 1002482
+ 2483: 1002483
+ 2484: 1002484
+ 2485: 1002485
+ 2486: 1002486
+ 2487: 1002487
+ 2488: 1002488
+ 2489: 1002489
+ 2490: 1002490
+ 2491: 1002491
+ 2492: 1002492
+ 2493: 1002493
+ 2494: 1002494
+ 2495: 1002495
+ 2496: 1002496
+ 2497: 1002497
+ 2498: 1002498
+ 2499: 1002499
+ 2500: 1002500
+ 2501: 1002501
+ 2502: 1002502
+ 2503: 1002503
+ 2504: 1002504
+ 2505: 1002505
+ 2506: 1002506
+ 2507: 1002507
+ 2508: 1002508
+ 2509: 1002509
+ 2510: 1002510
+ 2511: 1002511
+ 2512: 1002512
+ 2513: 1002513
+ 2514: 1002514
+ 2515: 1002515
+ 2516: 1002516
+ 2517: 1002517
+ 2518: 1002518
+ 2519: 1002519
+ 2520: 1002520
+ 2521: 1002521
+ 2522: 1002522
+ 2523: 1002523
+ 2524: 1002524
+ 2525: 1002525
+ 2526: 1002526
+ 2527: 1002527
+ 2528: 1002528
+ 2529: 1002529
+ 2530: 1002530
+ 2531: 1002531
+ 2532: 1002532
+ 2533: 1002533
+ 2534: 1002534
+ 2535: 1002535
+ 2536: 1002536
+ 2537: 1002537
+ 2538: 1002538
+ 2539: 1002539
+ 2540: 1002540
+ 2541: 1002541
+ 2542: 1002542
+ 2543: 1002543
+ 2544: 1002544
+ 2545: 1002545
+ 2546: 1002546
+ 2547: 1002547
+ 2548: 1002548
+ 2549: 1002549
+ 2550: 1002550
+ 2551: 1002551
+ 2552: 1002552
+ 2553: 1002553
+ 2554: 1002554
+ 2555: 1002555
+ 2556: 1002556
+ 2557: 1002557
+ 2558: 1002558
+ 2559: 1002559
+ 2560: 1002560
+ 2561: 1002561
+ 2562: 1002562
+ 2563: 1002563
+ 2564: 1002564
+ 2565: 1002565
+ 2566: 1002566
+ 2567: 1002567
+ 2568: 1002568
+ 2569: 1002569
+ 2570: 1002570
+ 2571: 1002571
+ 2572: 1002572
+ 2573: 1002573
+ 2574: 1002574
+ 2575: 1002575
+ 2576: 1002576
+ 2577: 1002577
+ 2578: 1002578
+ 2579: 1002579
+ 2580: 1002580
+ 2581: 1002581
+ 2582: 1002582
+ 2583: 1002583
+ 2584: 1002584
+ 2585: 1002585
+ 2586: 1002586
+ 2587: 1002587
+ 2588: 1002588
+ 2589: 1002589
+ 2590: 1002590
+ 2591: 1002591
+ 2592: 1002592
+ 2593: 1002593
+ 2594: 1002594
+ 2595: 1002595
+ 2596: 1002596
+ 2597: 1002597
+ 2598: 1002598
+ 2599: 1002599
+ 2600: 1002600
+ 2601: 1002601
+ 2602: 1002602
+ 2603: 1002603
+ 2604: 1002604
+ 2605: 1002605
+ 2606: 1002606
+ 2607: 1002607
+ 2608: 1002608
+ 2609: 1002609
+ 2610: 1002610
+ 2611: 1002611
+ 2612: 1002612
+ 2613: 1002613
+ 2614: 1002614
+ 2615: 1002615
+ 2616: 1002616
+ 2617: 1002617
+ 2618: 1002618
+ 2619: 1002619
+ 2620: 1002620
+ 2621: 1002621
+ 2622: 1002622
+ 2623: 1002623
+ 2624: 1002624
+ 2625: 1002625
+ 2626: 1002626
+ 2627: 1002627
+ 2628: 1002628
+ 2629: 1002629
+ 2630: 1002630
+ 2631: 1002631
+ 2632: 1002632
+ 2633: 1002633
+ 2634: 1002634
+ 2635: 1002635
+ 2636: 1002636
+ 2637: 1002637
+ 2638: 1002638
+ 2639: 1002639
+ 2640: 1002640
+ 2641: 1002641
+ 2642: 1002642
+ 2643: 1002643
+ 2644: 1002644
+ 2645: 1002645
+ 2646: 1002646
+ 2647: 1002647
+ 2648: 1002648
+ 2649: 1002649
+ 2650: 1002650
+ 2651: 1002651
+ 2652: 1002652
+ 2653: 1002653
+ 2654: 1002654
+ 2655: 1002655
+ 2656: 1002656
+ 2657: 1002657
+ 2658: 1002658
+ 2659: 1002659
+ 2660: 1002660
+ 2661: 1002661
+ 2662: 1002662
+ 2663: 1002663
+ 2664: 1002664
+ 2665: 1002665
+ 2666: 1002666
+ 2667: 1002667
+ 2668: 1002668
+ 2669: 1002669
+ 2670: 1002670
+ 2671: 1002671
+ 2672: 1002672
+ 2673: 1002673
+ 2674: 1002674
+ 2675: 1002675
+ 2676: 1002676
+ 2677: 1002677
+ 2678: 1002678
+ 2679: 1002679
+ 2680: 1002680
+ 2681: 1002681
+ 2682: 1002682
+ 2683: 1002683
+ 2684: 1002684
+ 2685: 1002685
+ 2686: 1002686
+ 2687: 1002687
+ 2688: 1002688
+ 2689: 1002689
+ 2690: 1002690
+ 2691: 1002691
+ 2692: 1002692
+ 2693: 1002693
+ 2694: 1002694
+ 2695: 1002695
+ 2696: 1002696
+ 2697: 1002697
+ 2698: 1002698
+ 2699: 1002699
+ 2700: 1002700
+ 2701: 1002701
+ 2702: 1002702
+ 2703: 1002703
+ 2704: 1002704
+ 2705: 1002705
+ 2706: 1002706
+ 2707: 1002707
+ 2708: 1002708
+ 2709: 1002709
+ 2710: 1002710
+ 2711: 1002711
+ 2712: 1002712
+ 2713: 1002713
+ 2714: 1002714
+ 2715: 1002715
+ 2716: 1002716
+ 2717: 1002717
+ 2718: 1002718
+ 2719: 1002719
+ 2720: 1002720
+ 2721: 1002721
+ 2722: 1002722
+ 2723: 1002723
+ 2724: 1002724
+ 2725: 1002725
+ 2726: 1002726
+ 2727: 1002727
+ 2728: 1002728
+ 2729: 1002729
+ 2730: 1002730
+ 2731: 1002731
+ 2732: 1002732
+ 2733: 1002733
+ 2734: 1002734
+ 2735: 1002735
+ 2736: 1002736
+ 2737: 1002737
+ 2738: 1002738
+ 2739: 1002739
+ 2740: 1002740
+ 2741: 1002741
+ 2742: 1002742
+ 2743: 1002743
+ 2744: 1002744
+ 2745: 1002745
+ 2746: 1002746
+ 2747: 1002747
+ 2748: 1002748
+ 2749: 1002749
+ 2750: 1002750
+ 2751: 1002751
+ 2752: 1002752
+ 2753: 1002753
+ 2754: 1002754
+ 2755: 1002755
+ 2756: 1002756
+ 2757: 1002757
+ 2758: 1002758
+ 2759: 1002759
+ 2760: 1002760
+ 2761: 1002761
+ 2762: 1002762
+ 2763: 1002763
+ 2764: 1002764
+ 2765: 1002765
+ 2766: 1002766
+ 2767: 1002767
+ 2768: 1002768
+ 2769: 1002769
+ 2770: 1002770
+ 2771: 1002771
+ 2772: 1002772
+ 2773: 1002773
+ 2774: 1002774
+ 2775: 1002775
+ 2776: 1002776
+ 2777: 1002777
+ 2778: 1002778
+ 2779: 1002779
+ 2780: 1002780
+ 2781: 1002781
+ 2782: 1002782
+ 2783: 1002783
+ 2784: 1002784
+ 2785: 1002785
+ 2786: 1002786
+ 2787: 1002787
+ 2788: 1002788
+ 2789: 1002789
+ 2790: 1002790
+ 2791: 1002791
+ 2792: 1002792
+ 2793: 1002793
+ 2794: 1002794
+ 2795: 1002795
+ 2796: 1002796
+ 2797: 1002797
+ 2798: 1002798
+ 2799: 1002799
+ 2800: 1002800
+ 2801: 1002801
+ 2802: 1002802
+ 2803: 1002803
+ 2804: 1002804
+ 2805: 1002805
+ 2806: 1002806
+ 2807: 1002807
+ 2808: 1002808
+ 2809: 1002809
+ 2810: 1002810
+ 2811: 1002811
+ 2812: 1002812
+ 2813: 1002813
+ 2814: 1002814
+ 2815: 1002815
+ 2816: 1002816
+ 2817: 1002817
+ 2818: 1002818
+ 2819: 1002819
+ 2820: 1002820
+ 2821: 1002821
+ 2822: 1002822
+ 2823: 1002823
+ 2824: 1002824
+ 2825: 1002825
+ 2826: 1002826
+ 2827: 1002827
+ 2828: 1002828
+ 2829: 1002829
+ 2830: 1002830
+ 2831: 1002831
+ 2832: 1002832
+ 2833: 1002833
+ 2834: 1002834
+ 2835: 1002835
+ 2836: 1002836
+ 2837: 1002837
+ 2838: 1002838
+ 2839: 1002839
+ 2840: 1002840
+ 2841: 1002841
+ 2842: 1002842
+ 2843: 1002843
+ 2844: 1002844
+ 2845: 1002845
+ 2846: 1002846
+ 2847: 1002847
+ 2848: 1002848
+ 2849: 1002849
+ 2850: 1002850
+ 2851: 1002851
+ 2852: 1002852
+ 2853: 1002853
+ 2854: 1002854
+ 2855: 1002855
+ 2856: 1002856
+ 2857: 1002857
+ 2858: 1002858
+ 2859: 1002859
+ 2860: 1002860
+ 2861: 1002861
+ 2862: 1002862
+ 2863: 1002863
+ 2864: 1002864
+ 2865: 1002865
+ 2866: 1002866
+ 2867: 1002867
+ 2868: 1002868
+ 2869: 1002869
+ 2870: 1002870
+ 2871: 1002871
+ 2872: 1002872
+ 2873: 1002873
+ 2874: 1002874
+ 2875: 1002875
+ 2876: 1002876
+ 2877: 1002877
+ 2878: 1002878
+ 2879: 1002879
+ 2880: 1002880
+ 2881: 1002881
+ 2882: 1002882
+ 2883: 1002883
+ 2884: 1002884
+ 2885: 1002885
+ 2886: 1002886
+ 2887: 1002887
+ 2888: 1002888
+ 2889: 1002889
+ 2890: 1002890
+ 2891: 1002891
+ 2892: 1002892
+ 2893: 1002893
+ 2894: 1002894
+ 2895: 1002895
+ 2896: 1002896
+ 2897: 1002897
+ 2898: 1002898
+ 2899: 1002899
+ 2900: 1002900
+ 2901: 1002901
+ 2902: 1002902
+ 2903: 1002903
+ 2904: 1002904
+ 2905: 1002905
+ 2906: 1002906
+ 2907: 1002907
+ 2908: 1002908
+ 2909: 1002909
+ 2910: 1002910
+ 2911: 1002911
+ 2912: 1002912
+ 2913: 1002913
+ 2914: 1002914
+ 2915: 1002915
+ 2916: 1002916
+ 2917: 1002917
+ 2918: 1002918
+ 2919: 1002919
+ 2920: 1002920
+ 2921: 1002921
+ 2922: 1002922
+ 2923: 1002923
+ 2924: 1002924
+ 2925: 1002925
+ 2926: 1002926
+ 2927: 1002927
+ 2928: 1002928
+ 2929: 1002929
+ 2930: 1002930
+ 2931: 1002931
+ 2932: 1002932
+ 2933: 1002933
+ 2934: 1002934
+ 2935: 1002935
+ 2936: 1002936
+ 2937: 1002937
+ 2938: 1002938
+ 2939: 1002939
+ 2940: 1002940
+ 2941: 1002941
+ 2942: 1002942
+ 2943: 1002943
+ 2944: 1002944
+ 2945: 1002945
+ 2946: 1002946
+ 2947: 1002947
+ 2948: 1002948
+ 2949: 1002949
+ 2950: 1002950
+ 2951: 1002951
+ 2952: 1002952
+ 2953: 1002953
+ 2954: 1002954
+ 2955: 1002955
+ 2956: 1002956
+ 2957: 1002957
+ 2958: 1002958
+ 2959: 1002959
+ 2960: 1002960
+ 2961: 1002961
+ 2962: 1002962
+ 2963: 1002963
+ 2964: 1002964
+ 2965: 1002965
+ 2966: 1002966
+ 2967: 1002967
+ 2968: 1002968
+ 2969: 1002969
+ 2970: 1002970
+ 2971: 1002971
+ 2972: 1002972
+ 2973: 1002973
+ 2974: 1002974
+ 2975: 1002975
+ 2976: 1002976
+ 2977: 1002977
+ 2978: 1002978
+ 2979: 1002979
+ 2980: 1002980
+ 2981: 1002981
+ 2982: 1002982
+ 2983: 1002983
+ 2984: 1002984
+ 2985: 1002985
+ 2986: 1002986
+ 2987: 1002987
+ 2988: 1002988
+ 2989: 1002989
+ 2990: 1002990
+ 2991: 1002991
+ 2992: 1002992
+ 2993: 1002993
+ 2994: 1002994
+ 2995: 1002995
+ 2996: 1002996
+ 2997: 1002997
+ 2998: 1002998
+ 2999: 1002999
+ 3000: 1003000
+ 3001: 1003001
+ 3002: 1003002
+ 3003: 1003003
+ 3004: 1003004
+ 3005: 1003005
+ 3006: 1003006
+ 3007: 1003007
+ 3008: 1003008
+ 3009: 1003009
+ 3010: 1003010
+ 3011: 1003011
+ 3012: 1003012
+ 3013: 1003013
+ 3014: 1003014
+ 3015: 1003015
+ 3016: 1003016
+ 3017: 1003017
+ 3018: 1003018
+ 3019: 1003019
+ 3020: 1003020
+ 3021: 1003021
+ 3022: 1003022
+ 3023: 1003023
+ 3024: 1003024
+ 3025: 1003025
+ 3026: 1003026
+ 3027: 1003027
+ 3028: 1003028
+ 3029: 1003029
+ 3030: 1003030
+ 3031: 1003031
+ 3032: 1003032
+ 3033: 1003033
+ 3034: 1003034
+ 3035: 1003035
+ 3036: 1003036
+ 3037: 1003037
+ 3038: 1003038
+ 3039: 1003039
+ 3040: 1003040
+ 3041: 1003041
+ 3042: 1003042
+ 3043: 1003043
+ 3044: 1003044
+ 3045: 1003045
+ 3046: 1003046
+ 3047: 1003047
+ 3048: 1003048
+ 3049: 1003049
+ 3050: 1003050
+ 3051: 1003051
+ 3052: 1003052
+ 3053: 1003053
+ 3054: 1003054
+ 3055: 1003055
+ 3056: 1003056
+ 3057: 1003057
+ 3058: 1003058
+ 3059: 1003059
+ 3060: 1003060
+ 3061: 1003061
+ 3062: 1003062
+ 3063: 1003063
+ 3064: 1003064
+ 3065: 1003065
+ 3066: 1003066
+ 3067: 1003067
+ 3068: 1003068
+ 3069: 1003069
+ 3070: 1003070
+ 3071: 1003071
+ 3072: 1003072
+ 3073: 1003073
+ 3074: 1003074
+ 3075: 1003075
+ 3076: 1003076
+ 3077: 1003077
+ 3078: 1003078
+ 3079: 1003079
+ 3080: 1003080
+ 3081: 1003081
+ 3082: 1003082
+ 3083: 1003083
+ 3084: 1003084
+ 3085: 1003085
+ 3086: 1003086
+ 3087: 1003087
+ 3088: 1003088
+ 3089: 1003089
+ 3090: 1003090
+ 3091: 1003091
+ 3092: 1003092
+ 3093: 1003093
+ 3094: 1003094
+ 3095: 1003095
+ 3096: 1003096
+ 3097: 1003097
+ 3098: 1003098
+ 3099: 1003099
+ 3100: 1003100
+ 3101: 1003101
+ 3102: 1003102
+ 3103: 1003103
+ 3104: 1003104
+ 3105: 1003105
+ 3106: 1003106
+ 3107: 1003107
+ 3108: 1003108
+ 3109: 1003109
+ 3110: 1003110
+ 3111: 1003111
+ 3112: 1003112
+ 3113: 1003113
+ 3114: 1003114
+ 3115: 1003115
+ 3116: 1003116
+ 3117: 1003117
+ 3118: 1003118
+ 3119: 1003119
+ 3120: 1003120
+ 3121: 1003121
+ 3122: 1003122
+ 3123: 1003123
+ 3124: 1003124
+ 3125: 1003125
+ 3126: 1003126
+ 3127: 1003127
+ 3128: 1003128
+ 3129: 1003129
+ 3130: 1003130
+ 3131: 1003131
+ 3132: 1003132
+ 3133: 1003133
+ 3134: 1003134
+ 3135: 1003135
+ 3136: 1003136
+ 3137: 1003137
+ 3138: 1003138
+ 3139: 1003139
+ 3140: 1003140
+ 3141: 1003141
+ 3142: 1003142
+ 3143: 1003143
+ 3144: 1003144
+ 3145: 1003145
+ 3146: 1003146
+ 3147: 1003147
+ 3148: 1003148
+ 3149: 1003149
+ 3150: 1003150
+ 3151: 1003151
+ 3152: 1003152
+ 3153: 1003153
+ 3154: 1003154
+ 3155: 1003155
+ 3156: 1003156
+ 3157: 1003157
+ 3158: 1003158
+ 3159: 1003159
+ 3160: 1003160
+ 3161: 1003161
+ 3162: 1003162
+ 3163: 1003163
+ 3164: 1003164
+ 3165: 1003165
+ 3166: 1003166
+ 3167: 1003167
+ 3168: 1003168
+ 3169: 1003169
+ 3170: 1003170
+ 3171: 1003171
+ 3172: 1003172
+ 3173: 1003173
+ 3174: 1003174
+ 3175: 1003175
+ 3176: 1003176
+ 3177: 1003177
+ 3178: 1003178
+ 3179: 1003179
+ 3180: 1003180
+ 3181: 1003181
+ 3182: 1003182
+ 3183: 1003183
+ 3184: 1003184
+ 3185: 1003185
+ 3186: 1003186
+ 3187: 1003187
+ 3188: 1003188
+ 3189: 1003189
+ 3190: 1003190
+ 3191: 1003191
+ 3192: 1003192
+ 3193: 1003193
+ 3194: 1003194
+ 3195: 1003195
+ 3196: 1003196
+ 3197: 1003197
+ 3198: 1003198
+ 3199: 1003199
+ 3200: 1003200
+ 3201: 1003201
+ 3202: 1003202
+ 3203: 1003203
+ 3204: 1003204
+ 3205: 1003205
+ 3206: 1003206
+ 3207: 1003207
+ 3208: 1003208
+ 3209: 1003209
+ 3210: 1003210
+ 3211: 1003211
+ 3212: 1003212
+ 3213: 1003213
+ 3214: 1003214
+ 3215: 1003215
+ 3216: 1003216
+ 3217: 1003217
+ 3218: 1003218
+ 3219: 1003219
+ 3220: 1003220
+ 3221: 1003221
+ 3222: 1003222
+ 3223: 1003223
+ 3224: 1003224
+ 3225: 1003225
+ 3226: 1003226
+ 3227: 1003227
+ 3228: 1003228
+ 3229: 1003229
+ 3230: 1003230
+ 3231: 1003231
+ 3232: 1003232
+ 3233: 1003233
+ 3234: 1003234
+ 3235: 1003235
+ 3236: 1003236
+ 3237: 1003237
+ 3238: 1003238
+ 3239: 1003239
+ 3240: 1003240
+ 3241: 1003241
+ 3242: 1003242
+ 3243: 1003243
+ 3244: 1003244
+ 3245: 1003245
+ 3246: 1003246
+ 3247: 1003247
+ 3248: 1003248
+ 3249: 1003249
+ 3250: 1003250
+ 3251: 1003251
+ 3252: 1003252
+ 3253: 1003253
+ 3254: 1003254
+ 3255: 1003255
+ 3256: 1003256
+ 3257: 1003257
+ 3258: 1003258
+ 3259: 1003259
+ 3260: 1003260
+ 3261: 1003261
+ 3262: 1003262
+ 3263: 1003263
+ 3264: 1003264
+ 3265: 1003265
+ 3266: 1003266
+ 3267: 1003267
+ 3268: 1003268
+ 3269: 1003269
+ 3270: 1003270
+ 3271: 1003271
+ 3272: 1003272
+ 3273: 1003273
+ 3274: 1003274
+ 3275: 1003275
+ 3276: 1003276
+ 3277: 1003277
+ 3278: 1003278
+ 3279: 1003279
+ 3280: 1003280
+ 3281: 1003281
+ 3282: 1003282
+ 3283: 1003283
+ 3284: 1003284
+ 3285: 1003285
+ 3286: 1003286
+ 3287: 1003287
+ 3288: 1003288
+ 3289: 1003289
+ 3290: 1003290
+ 3291: 1003291
+ 3292: 1003292
+ 3293: 1003293
+ 3294: 1003294
+ 3295: 1003295
+ 3296: 1003296
+ 3297: 1003297
+ 3298: 1003298
+ 3299: 1003299
+ 3300: 1003300
+ 3301: 1003301
+ 3302: 1003302
+ 3303: 1003303
+ 3304: 1003304
+ 3305: 1003305
+ 3306: 1003306
+ 3307: 1003307
+ 3308: 1003308
+ 3309: 1003309
+ 3310: 1003310
+ 3311: 1003311
+ 3312: 1003312
+ 3313: 1003313
+ 3314: 1003314
+ 3315: 1003315
+ 3316: 1003316
+ 3317: 1003317
+ 3318: 1003318
+ 3319: 1003319
+ 3320: 1003320
+ 3321: 1003321
+ 3322: 1003322
+ 3323: 1003323
+ 3324: 1003324
+ 3325: 1003325
+ 3326: 1003326
+ 3327: 1003327
+ 3328: 1003328
+ 3329: 1003329
+ 3330: 1003330
+ 3331: 1003331
+ 3332: 1003332
+ 3333: 1003333
+ 3334: 1003334
+ 3335: 1003335
+ 3336: 1003336
+ 3337: 1003337
+ 3338: 1003338
+ 3339: 1003339
+ 3340: 1003340
+ 3341: 1003341
+ 3342: 1003342
+ 3343: 1003343
+ 3344: 1003344
+ 3345: 1003345
+ 3346: 1003346
+ 3347: 1003347
+ 3348: 1003348
+ 3349: 1003349
+ 3350: 1003350
+ 3351: 1003351
+ 3352: 1003352
+ 3353: 1003353
+ 3354: 1003354
+ 3355: 1003355
+ 3356: 1003356
+ 3357: 1003357
+ 3358: 1003358
+ 3359: 1003359
+ 3360: 1003360
+ 3361: 1003361
+ 3362: 1003362
+ 3363: 1003363
+ 3364: 1003364
+ 3365: 1003365
+ 3366: 1003366
+ 3367: 1003367
+ 3368: 1003368
+ 3369: 1003369
+ 3370: 1003370
+ 3371: 1003371
+ 3372: 1003372
+ 3373: 1003373
+ 3374: 1003374
+ 3375: 1003375
+ 3376: 1003376
+ 3377: 1003377
+ 3378: 1003378
+ 3379: 1003379
+ 3380: 1003380
+ 3381: 1003381
+ 3382: 1003382
+ 3383: 1003383
+ 3384: 1003384
+ 3385: 1003385
+ 3386: 1003386
+ 3387: 1003387
+ 3388: 1003388
+ 3389: 1003389
+ 3390: 1003390
+ 3391: 1003391
+ 3392: 1003392
+ 3393: 1003393
+ 3394: 1003394
+ 3395: 1003395
+ 3396: 1003396
+ 3397: 1003397
+ 3398: 1003398
+ 3399: 1003399
+ 3400: 1003400
+ 3401: 1003401
+ 3402: 1003402
+ 3403: 1003403
+ 3404: 1003404
+ 3405: 1003405
+ 3406: 1003406
+ 3407: 1003407
+ 3408: 1003408
+ 3409: 1003409
+ 3410: 1003410
+ 3411: 1003411
+ 3412: 1003412
+ 3413: 1003413
+ 3414: 1003414
+ 3415: 1003415
+ 3416: 1003416
+ 3417: 1003417
+ 3418: 1003418
+ 3419: 1003419
+ 3420: 1003420
+ 3421: 1003421
+ 3422: 1003422
+ 3423: 1003423
+ 3424: 1003424
+ 3425: 1003425
+ 3426: 1003426
+ 3427: 1003427
+ 3428: 1003428
+ 3429: 1003429
+ 3430: 1003430
+ 3431: 1003431
+ 3432: 1003432
+ 3433: 1003433
+ 3434: 1003434
+ 3435: 1003435
+ 3436: 1003436
+ 3437: 1003437
+ 3438: 1003438
+ 3439: 1003439
+ 3440: 1003440
+ 3441: 1003441
+ 3442: 1003442
+ 3443: 1003443
+ 3444: 1003444
+ 3445: 1003445
+ 3446: 1003446
+ 3447: 1003447
+ 3448: 1003448
+ 3449: 1003449
+ 3450: 1003450
+ 3451: 1003451
+ 3452: 1003452
+ 3453: 1003453
+ 3454: 1003454
+ 3455: 1003455
+ 3456: 1003456
+ 3457: 1003457
+ 3458: 1003458
+ 3459: 1003459
+ 3460: 1003460
+ 3461: 1003461
+ 3462: 1003462
+ 3463: 1003463
+ 3464: 1003464
+ 3465: 1003465
+ 3466: 1003466
+ 3467: 1003467
+ 3468: 1003468
+ 3469: 1003469
+ 3470: 1003470
+ 3471: 1003471
+ 3472: 1003472
+ 3473: 1003473
+ 3474: 1003474
+ 3475: 1003475
+ 3476: 1003476
+ 3477: 1003477
+ 3478: 1003478
+ 3479: 1003479
+ 3480: 1003480
+ 3481: 1003481
+ 3482: 1003482
+ 3483: 1003483
+ 3484: 1003484
+ 3485: 1003485
+ 3486: 1003486
+ 3487: 1003487
+ 3488: 1003488
+ 3489: 1003489
+ 3490: 1003490
+ 3491: 1003491
+ 3492: 1003492
+ 3493: 1003493
+ 3494: 1003494
+ 3495: 1003495
+ 3496: 1003496
+ 3497: 1003497
+ 3498: 1003498
+ 3499: 1003499
+ 3500: 1003500
+ 3501: 1003501
+ 3502: 1003502
+ 3503: 1003503
+ 3504: 1003504
+ 3505: 1003505
+ 3506: 1003506
+ 3507: 1003507
+ 3508: 1003508
+ 3509: 1003509
+ 3510: 1003510
+ 3511: 1003511
+ 3512: 1003512
+ 3513: 1003513
+ 3514: 1003514
+ 3515: 1003515
+ 3516: 1003516
+ 3517: 1003517
+ 3518: 1003518
+ 3519: 1003519
+ 3520: 1003520
+ 3521: 1003521
+ 3522: 1003522
+ 3523: 1003523
+ 3524: 1003524
+ 3525: 1003525
+ 3526: 1003526
+ 3527: 1003527
+ 3528: 1003528
+ 3529: 1003529
+ 3530: 1003530
+ 3531: 1003531
+ 3532: 1003532
+ 3533: 1003533
+ 3534: 1003534
+ 3535: 1003535
+ 3536: 1003536
+ 3537: 1003537
+ 3538: 1003538
+ 3539: 1003539
+ 3540: 1003540
+ 3541: 1003541
+ 3542: 1003542
+ 3543: 1003543
+ 3544: 1003544
+ 3545: 1003545
+ 3546: 1003546
+ 3547: 1003547
+ 3548: 1003548
+ 3549: 1003549
+ 3550: 1003550
+ 3551: 1003551
+ 3552: 1003552
+ 3553: 1003553
+ 3554: 1003554
+ 3555: 1003555
+ 3556: 1003556
+ 3557: 1003557
+ 3558: 1003558
+ 3559: 1003559
+ 3560: 1003560
+ 3561: 1003561
+ 3562: 1003562
+ 3563: 1003563
+ 3564: 1003564
+ 3565: 1003565
+ 3566: 1003566
+ 3567: 1003567
+ 3568: 1003568
+ 3569: 1003569
+ 3570: 1003570
+ 3571: 1003571
+ 3572: 1003572
+ 3573: 1003573
+ 3574: 1003574
+ 3575: 1003575
+ 3576: 1003576
+ 3577: 1003577
+ 3578: 1003578
+ 3579: 1003579
+ 3580: 1003580
+ 3581: 1003581
+ 3582: 1003582
+ 3583: 1003583
+ 3584: 1003584
+ 3585: 1003585
+ 3586: 1003586
+ 3587: 1003587
+ 3588: 1003588
+ 3589: 1003589
+ 3590: 1003590
+ 3591: 1003591
+ 3592: 1003592
+ 3593: 1003593
+ 3594: 1003594
+ 3595: 1003595
+ 3596: 1003596
+ 3597: 1003597
+ 3598: 1003598
+ 3599: 1003599
+ 3600: 1003600
+ 3601: 1003601
+ 3602: 1003602
+ 3603: 1003603
+ 3604: 1003604
+ 3605: 1003605
+ 3606: 1003606
+ 3607: 1003607
+ 3608: 1003608
+ 3609: 1003609
+ 3610: 1003610
+ 3611: 1003611
+ 3612: 1003612
+ 3613: 1003613
+ 3614: 1003614
+ 3615: 1003615
+ 3616: 1003616
+ 3617: 1003617
+ 3618: 1003618
+ 3619: 1003619
+ 3620: 1003620
+ 3621: 1003621
+ 3622: 1003622
+ 3623: 1003623
+ 3624: 1003624
+ 3625: 1003625
+ 3626: 1003626
+ 3627: 1003627
+ 3628: 1003628
+ 3629: 1003629
+ 3630: 1003630
+ 3631: 1003631
+ 3632: 1003632
+ 3633: 1003633
+ 3634: 1003634
+ 3635: 1003635
+ 3636: 1003636
+ 3637: 1003637
+ 3638: 1003638
+ 3639: 1003639
+ 3640: 1003640
+ 3641: 1003641
+ 3642: 1003642
+ 3643: 1003643
+ 3644: 1003644
+ 3645: 1003645
+ 3646: 1003646
+ 3647: 1003647
+ 3648: 1003648
+ 3649: 1003649
+ 3650: 1003650
+ 3651: 1003651
+ 3652: 1003652
+ 3653: 1003653
+ 3654: 1003654
+ 3655: 1003655
+ 3656: 1003656
+ 3657: 1003657
+ 3658: 1003658
+ 3659: 1003659
+ 3660: 1003660
+ 3661: 1003661
+ 3662: 1003662
+ 3663: 1003663
+ 3664: 1003664
+ 3665: 1003665
+ 3666: 1003666
+ 3667: 1003667
+ 3668: 1003668
+ 3669: 1003669
+ 3670: 1003670
+ 3671: 1003671
+ 3672: 1003672
+ 3673: 1003673
+ 3674: 1003674
+ 3675: 1003675
+ 3676: 1003676
+ 3677: 1003677
+ 3678: 1003678
+ 3679: 1003679
+ 3680: 1003680
+ 3681: 1003681
+ 3682: 1003682
+ 3683: 1003683
+ 3684: 1003684
+ 3685: 1003685
+ 3686: 1003686
+ 3687: 1003687
+ 3688: 1003688
+ 3689: 1003689
+ 3690: 1003690
+ 3691: 1003691
+ 3692: 1003692
+ 3693: 1003693
+ 3694: 1003694
+ 3695: 1003695
+ 3696: 1003696
+ 3697: 1003697
+ 3698: 1003698
+ 3699: 1003699
+ 3700: 1003700
+ 3701: 1003701
+ 3702: 1003702
+ 3703: 1003703
+ 3704: 1003704
+ 3705: 1003705
+ 3706: 1003706
+ 3707: 1003707
+ 3708: 1003708
+ 3709: 1003709
+ 3710: 1003710
+ 3711: 1003711
+ 3712: 1003712
+ 3713: 1003713
+ 3714: 1003714
+ 3715: 1003715
+ 3716: 1003716
+ 3717: 1003717
+ 3718: 1003718
+ 3719: 1003719
+ 3720: 1003720
+ 3721: 1003721
+ 3722: 1003722
+ 3723: 1003723
+ 3724: 1003724
+ 3725: 1003725
+ 3726: 1003726
+ 3727: 1003727
+ 3728: 1003728
+ 3729: 1003729
+ 3730: 1003730
+ 3731: 1003731
+ 3732: 1003732
+ 3733: 1003733
+ 3734: 1003734
+ 3735: 1003735
+ 3736: 1003736
+ 3737: 1003737
+ 3738: 1003738
+ 3739: 1003739
+ 3740: 1003740
+ 3741: 1003741
+ 3742: 1003742
+ 3743: 1003743
+ 3744: 1003744
+ 3745: 1003745
+ 3746: 1003746
+ 3747: 1003747
+ 3748: 1003748
+ 3749: 1003749
+ 3750: 1003750
+ 3751: 1003751
+ 3752: 1003752
+ 3753: 1003753
+ 3754: 1003754
+ 3755: 1003755
+ 3756: 1003756
+ 3757: 1003757
+ 3758: 1003758
+ 3759: 1003759
+ 3760: 1003760
+ 3761: 1003761
+ 3762: 1003762
+ 3763: 1003763
+ 3764: 1003764
+ 3765: 1003765
+ 3766: 1003766
+ 3767: 1003767
+ 3768: 1003768
+ 3769: 1003769
+ 3770: 1003770
+ 3771: 1003771
+ 3772: 1003772
+ 3773: 1003773
+ 3774: 1003774
+ 3775: 1003775
+ 3776: 1003776
+ 3777: 1003777
+ 3778: 1003778
+ 3779: 1003779
+ 3780: 1003780
+ 3781: 1003781
+ 3782: 1003782
+ 3783: 1003783
+ 3784: 1003784
+ 3785: 1003785
+ 3786: 1003786
+ 3787: 1003787
+ 3788: 1003788
+ 3789: 1003789
+ 3790: 1003790
+ 3791: 1003791
+ 3792: 1003792
+ 3793: 1003793
+ 3794: 1003794
+ 3795: 1003795
+ 3796: 1003796
+ 3797: 1003797
+ 3798: 1003798
+ 3799: 1003799
+ 3800: 1003800
+ 3801: 1003801
+ 3802: 1003802
+ 3803: 1003803
+ 3804: 1003804
+ 3805: 1003805
+ 3806: 1003806
+ 3807: 1003807
+ 3808: 1003808
+ 3809: 1003809
+ 3810: 1003810
+ 3811: 1003811
+ 3812: 1003812
+ 3813: 1003813
+ 3814: 1003814
+ 3815: 1003815
+ 3816: 1003816
+ 3817: 1003817
+ 3818: 1003818
+ 3819: 1003819
+ 3820: 1003820
+ 3821: 1003821
+ 3822: 1003822
+ 3823: 1003823
+ 3824: 1003824
+ 3825: 1003825
+ 3826: 1003826
+ 3827: 1003827
+ 3828: 1003828
+ 3829: 1003829
+ 3830: 1003830
+ 3831: 1003831
+ 3832: 1003832
+ 3833: 1003833
+ 3834: 1003834
+ 3835: 1003835
+ 3836: 1003836
+ 3837: 1003837
+ 3838: 1003838
+ 3839: 1003839
+ 3840: 1003840
+ 3841: 1003841
+ 3842: 1003842
+ 3843: 1003843
+ 3844: 1003844
+ 3845: 1003845
+ 3846: 1003846
+ 3847: 1003847
+ 3848: 1003848
+ 3849: 1003849
+ 3850: 1003850
+ 3851: 1003851
+ 3852: 1003852
+ 3853: 1003853
+ 3854: 1003854
+ 3855: 1003855
+ 3856: 1003856
+ 3857: 1003857
+ 3858: 1003858
+ 3859: 1003859
+ 3860: 1003860
+ 3861: 1003861
+ 3862: 1003862
+ 3863: 1003863
+ 3864: 1003864
+ 3865: 1003865
+ 3866: 1003866
+ 3867: 1003867
+ 3868: 1003868
+ 3869: 1003869
+ 3870: 1003870
+ 3871: 1003871
+ 3872: 1003872
+ 3873: 1003873
+ 3874: 1003874
+ 3875: 1003875
+ 3876: 1003876
+ 3877: 1003877
+ 3878: 1003878
+ 3879: 1003879
+ 3880: 1003880
+ 3881: 1003881
+ 3882: 1003882
+ 3883: 1003883
+ 3884: 1003884
+ 3885: 1003885
+ 3886: 1003886
+ 3887: 1003887
+ 3888: 1003888
+ 3889: 1003889
+ 3890: 1003890
+ 3891: 1003891
+ 3892: 1003892
+ 3893: 1003893
+ 3894: 1003894
+ 3895: 1003895
+ 3896: 1003896
+ 3897: 1003897
+ 3898: 1003898
+ 3899: 1003899
+ 3900: 1003900
+ 3901: 1003901
+ 3902: 1003902
+ 3903: 1003903
+ 3904: 1003904
+ 3905: 1003905
+ 3906: 1003906
+ 3907: 1003907
+ 3908: 1003908
+ 3909: 1003909
+ 3910: 1003910
+ 3911: 1003911
+ 3912: 1003912
+ 3913: 1003913
+ 3914: 1003914
+ 3915: 1003915
+ 3916: 1003916
+ 3917: 1003917
+ 3918: 1003918
+ 3919: 1003919
+ 3920: 1003920
+ 3921: 1003921
+ 3922: 1003922
+ 3923: 1003923
+ 3924: 1003924
+ 3925: 1003925
+ 3926: 1003926
+ 3927: 1003927
+ 3928: 1003928
+ 3929: 1003929
+ 3930: 1003930
+ 3931: 1003931
+ 3932: 1003932
+ 3933: 1003933
+ 3934: 1003934
+ 3935: 1003935
+ 3936: 1003936
+ 3937: 1003937
+ 3938: 1003938
+ 3939: 1003939
+ 3940: 1003940
+ 3941: 1003941
+ 3942: 1003942
+ 3943: 1003943
+ 3944: 1003944
+ 3945: 1003945
+ 3946: 1003946
+ 3947: 1003947
+ 3948: 1003948
+ 3949: 1003949
+ 3950: 1003950
+ 3951: 1003951
+ 3952: 1003952
+ 3953: 1003953
+ 3954: 1003954
+ 3955: 1003955
+ 3956: 1003956
+ 3957: 1003957
+ 3958: 1003958
+ 3959: 1003959
+ 3960: 1003960
+ 3961: 1003961
+ 3962: 1003962
+ 3963: 1003963
+ 3964: 1003964
+ 3965: 1003965
+ 3966: 1003966
+ 3967: 1003967
+ 3968: 1003968
+ 3969: 1003969
+ 3970: 1003970
+ 3971: 1003971
+ 3972: 1003972
+ 3973: 1003973
+ 3974: 1003974
+ 3975: 1003975
+ 3976: 1003976
+ 3977: 1003977
+ 3978: 1003978
+ 3979: 1003979
+ 3980: 1003980
+ 3981: 1003981
+ 3982: 1003982
+ 3983: 1003983
+ 3984: 1003984
+ 3985: 1003985
+ 3986: 1003986
+ 3987: 1003987
+ 3988: 1003988
+ 3989: 1003989
+ 3990: 1003990
+ 3991: 1003991
+ 3992: 1003992
+ 3993: 1003993
+ 3994: 1003994
+ 3995: 1003995
+ 3996: 1003996
+ 3997: 1003997
+ 3998: 1003998
+ 3999: 1003999
+ 4000: 1004000
+ 4001: 1004001
+ 4002: 1004002
+ 4003: 1004003
+ 4004: 1004004
+ 4005: 1004005
+ 4006: 1004006
+ 4007: 1004007
+ 4008: 1004008
+ 4009: 1004009
+ 4010: 1004010
+ 4011: 1004011
+ 4012: 1004012
+ 4013: 1004013
+ 4014: 1004014
+ 4015: 1004015
+ 4016: 1004016
+ 4017: 1004017
+ 4018: 1004018
+ 4019: 1004019
+ 4020: 1004020
+ 4021: 1004021
+ 4022: 1004022
+ 4023: 1004023
+ 4024: 1004024
+ 4025: 1004025
+ 4026: 1004026
+ 4027: 1004027
+ 4028: 1004028
+ 4029: 1004029
+ 4030: 1004030
+ 4031: 1004031
+ 4032: 1004032
+ 4033: 1004033
+ 4034: 1004034
+ 4035: 1004035
+ 4036: 1004036
+ 4037: 1004037
+ 4038: 1004038
+ 4039: 1004039
+ 4040: 1004040
+ 4041: 1004041
+ 4042: 1004042
+ 4043: 1004043
+ 4044: 1004044
+ 4045: 1004045
+ 4046: 1004046
+ 4047: 1004047
+ 4048: 1004048
+ 4049: 1004049
+ 4050: 1004050
+ 4051: 1004051
+ 4052: 1004052
+ 4053: 1004053
+ 4054: 1004054
+ 4055: 1004055
+ 4056: 1004056
+ 4057: 1004057
+ 4058: 1004058
+ 4059: 1004059
+ 4060: 1004060
+ 4061: 1004061
+ 4062: 1004062
+ 4063: 1004063
+ 4064: 1004064
+ 4065: 1004065
+ 4066: 1004066
+ 4067: 1004067
+ 4068: 1004068
+ 4069: 1004069
+ 4070: 1004070
+ 4071: 1004071
+ 4072: 1004072
+ 4073: 1004073
+ 4074: 1004074
+ 4075: 1004075
+ 4076: 1004076
+ 4077: 1004077
+ 4078: 1004078
+ 4079: 1004079
+ 4080: 1004080
+ 4081: 1004081
+ 4082: 1004082
+ 4083: 1004083
+ 4084: 1004084
+ 4085: 1004085
+ 4086: 1004086
+ 4087: 1004087
+ 4088: 1004088
+ 4089: 1004089
+ 4090: 1004090
+ 4091: 1004091
+ 4092: 1004092
+ 4093: 1004093
+ 4094: 1004094
+ 4095: 1004095
+ 4096: 1004096
+ 4097: 1004097
+ 4098: 1004098
+ 4099: 1004099
+ 4100: 1004100
+ 4101: 1004101
+ 4102: 1004102
+ 4103: 1004103
+ 4104: 1004104
+ 4105: 1004105
+ 4106: 1004106
+ 4107: 1004107
+ 4108: 1004108
+ 4109: 1004109
+ 4110: 1004110
+ 4111: 1004111
+ 4112: 1004112
+ 4113: 1004113
+ 4114: 1004114
+ 4115: 1004115
+ 4116: 1004116
+ 4117: 1004117
+ 4118: 1004118
+ 4119: 1004119
+ 4120: 1004120
+ 4121: 1004121
+ 4122: 1004122
+ 4123: 1004123
+ 4124: 1004124
+ 4125: 1004125
+ 4126: 1004126
+ 4127: 1004127
+ 4128: 1004128
+ 4129: 1004129
+ 4130: 1004130
+ 4131: 1004131
+ 4132: 1004132
+ 4133: 1004133
+ 4134: 1004134
+ 4135: 1004135
+ 4136: 1004136
+ 4137: 1004137
+ 4138: 1004138
+ 4139: 1004139
+ 4140: 1004140
+ 4141: 1004141
+ 4142: 1004142
+ 4143: 1004143
+ 4144: 1004144
+ 4145: 1004145
+ 4146: 1004146
+ 4147: 1004147
+ 4148: 1004148
+ 4149: 1004149
+ 4150: 1004150
+ 4151: 1004151
+ 4152: 1004152
+ 4153: 1004153
+ 4154: 1004154
+ 4155: 1004155
+ 4156: 1004156
+ 4157: 1004157
+ 4158: 1004158
+ 4159: 1004159
+ 4160: 1004160
+ 4161: 1004161
+ 4162: 1004162
+ 4163: 1004163
+ 4164: 1004164
+ 4165: 1004165
+ 4166: 1004166
+ 4167: 1004167
+ 4168: 1004168
+ 4169: 1004169
+ 4170: 1004170
+ 4171: 1004171
+ 4172: 1004172
+ 4173: 1004173
+ 4174: 1004174
+ 4175: 1004175
+ 4176: 1004176
+ 4177: 1004177
+ 4178: 1004178
+ 4179: 1004179
+ 4180: 1004180
+ 4181: 1004181
+ 4182: 1004182
+ 4183: 1004183
+ 4184: 1004184
+ 4185: 1004185
+ 4186: 1004186
+ 4187: 1004187
+ 4188: 1004188
+ 4189: 1004189
+ 4190: 1004190
+ 4191: 1004191
+ 4192: 1004192
+ 4193: 1004193
+ 4194: 1004194
+ 4195: 1004195
+ 4196: 1004196
+ 4197: 1004197
+ 4198: 1004198
+ 4199: 1004199
+ 4200: 1004200
+ 4201: 1004201
+ 4202: 1004202
+ 4203: 1004203
+ 4204: 1004204
+ 4205: 1004205
+ 4206: 1004206
+ 4207: 1004207
+ 4208: 1004208
+ 4209: 1004209
+ 4210: 1004210
+ 4211: 1004211
+ 4212: 1004212
+ 4213: 1004213
+ 4214: 1004214
+ 4215: 1004215
+ 4216: 1004216
+ 4217: 1004217
+ 4218: 1004218
+ 4219: 1004219
+ 4220: 1004220
+ 4221: 1004221
+ 4222: 1004222
+ 4223: 1004223
+ 4224: 1004224
+ 4225: 1004225
+ 4226: 1004226
+ 4227: 1004227
+ 4228: 1004228
+ 4229: 1004229
+ 4230: 1004230
+ 4231: 1004231
+ 4232: 1004232
+ 4233: 1004233
+ 4234: 1004234
+ 4235: 1004235
+ 4236: 1004236
+ 4237: 1004237
+ 4238: 1004238
+ 4239: 1004239
+ 4240: 1004240
+ 4241: 1004241
+ 4242: 1004242
+ 4243: 1004243
+ 4244: 1004244
+ 4245: 1004245
+ 4246: 1004246
+ 4247: 1004247
+ 4248: 1004248
+ 4249: 1004249
+ 4250: 1004250
+ 4251: 1004251
+ 4252: 1004252
+ 4253: 1004253
+ 4254: 1004254
+ 4255: 1004255
+ 4256: 1004256
+ 4257: 1004257
+ 4258: 1004258
+ 4259: 1004259
+ 4260: 1004260
+ 4261: 1004261
+ 4262: 1004262
+ 4263: 1004263
+ 4264: 1004264
+ 4265: 1004265
+ 4266: 1004266
+ 4267: 1004267
+ 4268: 1004268
+ 4269: 1004269
+ 4270: 1004270
+ 4271: 1004271
+ 4272: 1004272
+ 4273: 1004273
+ 4274: 1004274
+ 4275: 1004275
+ 4276: 1004276
+ 4277: 1004277
+ 4278: 1004278
+ 4279: 1004279
+ 4280: 1004280
+ 4281: 1004281
+ 4282: 1004282
+ 4283: 1004283
+ 4284: 1004284
+ 4285: 1004285
+ 4286: 1004286
+ 4287: 1004287
+ 4288: 1004288
+ 4289: 1004289
+ 4290: 1004290
+ 4291: 1004291
+ 4292: 1004292
+ 4293: 1004293
+ 4294: 1004294
+ 4295: 1004295
+ 4296: 1004296
+ 4297: 1004297
+ 4298: 1004298
+ 4299: 1004299
+ 4300: 1004300
+ 4301: 1004301
+ 4302: 1004302
+ 4303: 1004303
+ 4304: 1004304
+ 4305: 1004305
+ 4306: 1004306
+ 4307: 1004307
+ 4308: 1004308
+ 4309: 1004309
+ 4310: 1004310
+ 4311: 1004311
+ 4312: 1004312
+ 4313: 1004313
+ 4314: 1004314
+ 4315: 1004315
+ 4316: 1004316
+ 4317: 1004317
+ 4318: 1004318
+ 4319: 1004319
+ 4320: 1004320
+ 4321: 1004321
+ 4322: 1004322
+ 4323: 1004323
+ 4324: 1004324
+ 4325: 1004325
+ 4326: 1004326
+ 4327: 1004327
+ 4328: 1004328
+ 4329: 1004329
+ 4330: 1004330
+ 4331: 1004331
+ 4332: 1004332
+ 4333: 1004333
+ 4334: 1004334
+ 4335: 1004335
+ 4336: 1004336
+ 4337: 1004337
+ 4338: 1004338
+ 4339: 1004339
+ 4340: 1004340
+ 4341: 1004341
+ 4342: 1004342
+ 4343: 1004343
+ 4344: 1004344
+ 4345: 1004345
+ 4346: 1004346
+ 4347: 1004347
+ 4348: 1004348
+ 4349: 1004349
+ 4350: 1004350
+ 4351: 1004351
+ 4352: 1004352
+ 4353: 1004353
+ 4354: 1004354
+ 4355: 1004355
+ 4356: 1004356
+ 4357: 1004357
+ 4358: 1004358
+ 4359: 1004359
+ 4360: 1004360
+ 4361: 1004361
+ 4362: 1004362
+ 4363: 1004363
+ 4364: 1004364
+ 4365: 1004365
+ 4366: 1004366
+ 4367: 1004367
+ 4368: 1004368
+ 4369: 1004369
+ 4370: 1004370
+ 4371: 1004371
+ 4372: 1004372
+ 4373: 1004373
+ 4374: 1004374
+ 4375: 1004375
+ 4376: 1004376
+ 4377: 1004377
+ 4378: 1004378
+ 4379: 1004379
+ 4380: 1004380
+ 4381: 1004381
+ 4382: 1004382
+ 4383: 1004383
+ 4384: 1004384
+ 4385: 1004385
+ 4386: 1004386
+ 4387: 1004387
+ 4388: 1004388
+ 4389: 1004389
+ 4390: 1004390
+ 4391: 1004391
+ 4392: 1004392
+ 4393: 1004393
+ 4394: 1004394
+ 4395: 1004395
+ 4396: 1004396
+ 4397: 1004397
+ 4398: 1004398
+ 4399: 1004399
+ 4400: 1004400
+ 4401: 1004401
+ 4402: 1004402
+ 4403: 1004403
+ 4404: 1004404
+ 4405: 1004405
+ 4406: 1004406
+ 4407: 1004407
+ 4408: 1004408
+ 4409: 1004409
+ 4410: 1004410
+ 4411: 1004411
+ 4412: 1004412
+ 4413: 1004413
+ 4414: 1004414
+ 4415: 1004415
+ 4416: 1004416
+ 4417: 1004417
+ 4418: 1004418
+ 4419: 1004419
+ 4420: 1004420
+ 4421: 1004421
+ 4422: 1004422
+ 4423: 1004423
+ 4424: 1004424
+ 4425: 1004425
+ 4426: 1004426
+ 4427: 1004427
+ 4428: 1004428
+ 4429: 1004429
+ 4430: 1004430
+ 4431: 1004431
+ 4432: 1004432
+ 4433: 1004433
+ 4434: 1004434
+ 4435: 1004435
+ 4436: 1004436
+ 4437: 1004437
+ 4438: 1004438
+ 4439: 1004439
+ 4440: 1004440
+ 4441: 1004441
+ 4442: 1004442
+ 4443: 1004443
+ 4444: 1004444
+ 4445: 1004445
+ 4446: 1004446
+ 4447: 1004447
+ 4448: 1004448
+ 4449: 1004449
+ 4450: 1004450
+ 4451: 1004451
+ 4452: 1004452
+ 4453: 1004453
+ 4454: 1004454
+ 4455: 1004455
+ 4456: 1004456
+ 4457: 1004457
+ 4458: 1004458
+ 4459: 1004459
+ 4460: 1004460
+ 4461: 1004461
+ 4462: 1004462
+ 4463: 1004463
+ 4464: 1004464
+ 4465: 1004465
+ 4466: 1004466
+ 4467: 1004467
+ 4468: 1004468
+ 4469: 1004469
+ 4470: 1004470
+ 4471: 1004471
+ 4472: 1004472
+ 4473: 1004473
+ 4474: 1004474
+ 4475: 1004475
+ 4476: 1004476
+ 4477: 1004477
+ 4478: 1004478
+ 4479: 1004479
+ 4480: 1004480
+ 4481: 1004481
+ 4482: 1004482
+ 4483: 1004483
+ 4484: 1004484
+ 4485: 1004485
+ 4486: 1004486
+ 4487: 1004487
+ 4488: 1004488
+ 4489: 1004489
+ 4490: 1004490
+ 4491: 1004491
+ 4492: 1004492
+ 4493: 1004493
+ 4494: 1004494
+ 4495: 1004495
+ 4496: 1004496
+ 4497: 1004497
+ 4498: 1004498
+ 4499: 1004499
+ 4500: 1004500
+ 4501: 1004501
+ 4502: 1004502
+ 4503: 1004503
+ 4504: 1004504
+ 4505: 1004505
+ 4506: 1004506
+ 4507: 1004507
+ 4508: 1004508
+ 4509: 1004509
+ 4510: 1004510
+ 4511: 1004511
+ 4512: 1004512
+ 4513: 1004513
+ 4514: 1004514
+ 4515: 1004515
+ 4516: 1004516
+ 4517: 1004517
+ 4518: 1004518
+ 4519: 1004519
+ 4520: 1004520
+ 4521: 1004521
+ 4522: 1004522
+ 4523: 1004523
+ 4524: 1004524
+ 4525: 1004525
+ 4526: 1004526
+ 4527: 1004527
+ 4528: 1004528
+ 4529: 1004529
+ 4530: 1004530
+ 4531: 1004531
+ 4532: 1004532
+ 4533: 1004533
+ 4534: 1004534
+ 4535: 1004535
+ 4536: 1004536
+ 4537: 1004537
+ 4538: 1004538
+ 4539: 1004539
+ 4540: 1004540
+ 4541: 1004541
+ 4542: 1004542
+ 4543: 1004543
+ 4544: 1004544
+ 4545: 1004545
+ 4546: 1004546
+ 4547: 1004547
+ 4548: 1004548
+ 4549: 1004549
+ 4550: 1004550
+ 4551: 1004551
+ 4552: 1004552
+ 4553: 1004553
+ 4554: 1004554
+ 4555: 1004555
+ 4556: 1004556
+ 4557: 1004557
+ 4558: 1004558
+ 4559: 1004559
+ 4560: 1004560
+ 4561: 1004561
+ 4562: 1004562
+ 4563: 1004563
+ 4564: 1004564
+ 4565: 1004565
+ 4566: 1004566
+ 4567: 1004567
+ 4568: 1004568
+ 4569: 1004569
+ 4570: 1004570
+ 4571: 1004571
+ 4572: 1004572
+ 4573: 1004573
+ 4574: 1004574
+ 4575: 1004575
+ 4576: 1004576
+ 4577: 1004577
+ 4578: 1004578
+ 4579: 1004579
+ 4580: 1004580
+ 4581: 1004581
+ 4582: 1004582
+ 4583: 1004583
+ 4584: 1004584
+ 4585: 1004585
+ 4586: 1004586
+ 4587: 1004587
+ 4588: 1004588
+ 4589: 1004589
+ 4590: 1004590
+ 4591: 1004591
+ 4592: 1004592
+ 4593: 1004593
+ 4594: 1004594
+ 4595: 1004595
+ 4596: 1004596
+ 4597: 1004597
+ 4598: 1004598
+ 4599: 1004599
+ 4600: 1004600
+ 4601: 1004601
+ 4602: 1004602
+ 4603: 1004603
+ 4604: 1004604
+ 4605: 1004605
+ 4606: 1004606
+ 4607: 1004607
+ 4608: 1004608
+ 4609: 1004609
+ 4610: 1004610
+ 4611: 1004611
+ 4612: 1004612
+ 4613: 1004613
+ 4614: 1004614
+ 4615: 1004615
+ 4616: 1004616
+ 4617: 1004617
+ 4618: 1004618
+ 4619: 1004619
+ 4620: 1004620
+ 4621: 1004621
+ 4622: 1004622
+ 4623: 1004623
+ 4624: 1004624
+ 4625: 1004625
+ 4626: 1004626
+ 4627: 1004627
+ 4628: 1004628
+ 4629: 1004629
+ 4630: 1004630
+ 4631: 1004631
+ 4632: 1004632
+ 4633: 1004633
+ 4634: 1004634
+ 4635: 1004635
+ 4636: 1004636
+ 4637: 1004637
+ 4638: 1004638
+ 4639: 1004639
+ 4640: 1004640
+ 4641: 1004641
+ 4642: 1004642
+ 4643: 1004643
+ 4644: 1004644
+ 4645: 1004645
+ 4646: 1004646
+ 4647: 1004647
+ 4648: 1004648
+ 4649: 1004649
+ 4650: 1004650
+ 4651: 1004651
+ 4652: 1004652
+ 4653: 1004653
+ 4654: 1004654
+ 4655: 1004655
+ 4656: 1004656
+ 4657: 1004657
+ 4658: 1004658
+ 4659: 1004659
+ 4660: 1004660
+ 4661: 1004661
+ 4662: 1004662
+ 4663: 1004663
+ 4664: 1004664
+ 4665: 1004665
+ 4666: 1004666
+ 4667: 1004667
+ 4668: 1004668
+ 4669: 1004669
+ 4670: 1004670
+ 4671: 1004671
+ 4672: 1004672
+ 4673: 1004673
+ 4674: 1004674
+ 4675: 1004675
+ 4676: 1004676
+ 4677: 1004677
+ 4678: 1004678
+ 4679: 1004679
+ 4680: 1004680
+ 4681: 1004681
+ 4682: 1004682
+ 4683: 1004683
+ 4684: 1004684
+ 4685: 1004685
+ 4686: 1004686
+ 4687: 1004687
+ 4688: 1004688
+ 4689: 1004689
+ 4690: 1004690
+ 4691: 1004691
+ 4692: 1004692
+ 4693: 1004693
+ 4694: 1004694
+ 4695: 1004695
+ 4696: 1004696
+ 4697: 1004697
+ 4698: 1004698
+ 4699: 1004699
+ 4700: 1004700
+ 4701: 1004701
+ 4702: 1004702
+ 4703: 1004703
+ 4704: 1004704
+ 4705: 1004705
+ 4706: 1004706
+ 4707: 1004707
+ 4708: 1004708
+ 4709: 1004709
+ 4710: 1004710
+ 4711: 1004711
+ 4712: 1004712
+ 4713: 1004713
+ 4714: 1004714
+ 4715: 1004715
+ 4716: 1004716
+ 4717: 1004717
+ 4718: 1004718
+ 4719: 1004719
+ 4720: 1004720
+ 4721: 1004721
+ 4722: 1004722
+ 4723: 1004723
+ 4724: 1004724
+ 4725: 1004725
+ 4726: 1004726
+ 4727: 1004727
+ 4728: 1004728
+ 4729: 1004729
+ 4730: 1004730
+ 4731: 1004731
+ 4732: 1004732
+ 4733: 1004733
+ 4734: 1004734
+ 4735: 1004735
+ 4736: 1004736
+ 4737: 1004737
+ 4738: 1004738
+ 4739: 1004739
+ 4740: 1004740
+ 4741: 1004741
+ 4742: 1004742
+ 4743: 1004743
+ 4744: 1004744
+ 4745: 1004745
+ 4746: 1004746
+ 4747: 1004747
+ 4748: 1004748
+ 4749: 1004749
+ 4750: 1004750
+ 4751: 1004751
+ 4752: 1004752
+ 4753: 1004753
+ 4754: 1004754
+ 4755: 1004755
+ 4756: 1004756
+ 4757: 1004757
+ 4758: 1004758
+ 4759: 1004759
+ 4760: 1004760
+ 4761: 1004761
+ 4762: 1004762
+ 4763: 1004763
+ 4764: 1004764
+ 4765: 1004765
+ 4766: 1004766
+ 4767: 1004767
+ 4768: 1004768
+ 4769: 1004769
+ 4770: 1004770
+ 4771: 1004771
+ 4772: 1004772
+ 4773: 1004773
+ 4774: 1004774
+ 4775: 1004775
+ 4776: 1004776
+ 4777: 1004777
+ 4778: 1004778
+ 4779: 1004779
+ 4780: 1004780
+ 4781: 1004781
+ 4782: 1004782
+ 4783: 1004783
+ 4784: 1004784
+ 4785: 1004785
+ 4786: 1004786
+ 4787: 1004787
+ 4788: 1004788
+ 4789: 1004789
+ 4790: 1004790
+ 4791: 1004791
+ 4792: 1004792
+ 4793: 1004793
+ 4794: 1004794
+ 4795: 1004795
+ 4796: 1004796
+ 4797: 1004797
+ 4798: 1004798
+ 4799: 1004799
+ 4800: 1004800
+ 4801: 1004801
+ 4802: 1004802
+ 4803: 1004803
+ 4804: 1004804
+ 4805: 1004805
+ 4806: 1004806
+ 4807: 1004807
+ 4808: 1004808
+ 4809: 1004809
+ 4810: 1004810
+ 4811: 1004811
+ 4812: 1004812
+ 4813: 1004813
+ 4814: 1004814
+ 4815: 1004815
+ 4816: 1004816
+ 4817: 1004817
+ 4818: 1004818
+ 4819: 1004819
+ 4820: 1004820
+ 4821: 1004821
+ 4822: 1004822
+ 4823: 1004823
+ 4824: 1004824
+ 4825: 1004825
+ 4826: 1004826
+ 4827: 1004827
+ 4828: 1004828
+ 4829: 1004829
+ 4830: 1004830
+ 4831: 1004831
+ 4832: 1004832
+ 4833: 1004833
+ 4834: 1004834
+ 4835: 1004835
+ 4836: 1004836
+ 4837: 1004837
+ 4838: 1004838
+ 4839: 1004839
+ 4840: 1004840
+ 4841: 1004841
+ 4842: 1004842
+ 4843: 1004843
+ 4844: 1004844
+ 4845: 1004845
+ 4846: 1004846
+ 4847: 1004847
+ 4848: 1004848
+ 4849: 1004849
+ 4850: 1004850
+ 4851: 1004851
+ 4852: 1004852
+ 4853: 1004853
+ 4854: 1004854
+ 4855: 1004855
+ 4856: 1004856
+ 4857: 1004857
+ 4858: 1004858
+ 4859: 1004859
+ 4860: 1004860
+ 4861: 1004861
+ 4862: 1004862
+ 4863: 1004863
+ 4864: 1004864
+ 4865: 1004865
+ 4866: 1004866
+ 4867: 1004867
+ 4868: 1004868
+ 4869: 1004869
+ 4870: 1004870
+ 4871: 1004871
+ 4872: 1004872
+ 4873: 1004873
+ 4874: 1004874
+ 4875: 1004875
+ 4876: 1004876
+ 4877: 1004877
+ 4878: 1004878
+ 4879: 1004879
+ 4880: 1004880
+ 4881: 1004881
+ 4882: 1004882
+ 4883: 1004883
+ 4884: 1004884
+ 4885: 1004885
+ 4886: 1004886
+ 4887: 1004887
+ 4888: 1004888
+ 4889: 1004889
+ 4890: 1004890
+ 4891: 1004891
+ 4892: 1004892
+ 4893: 1004893
+ 4894: 1004894
+ 4895: 1004895
+ 4896: 1004896
+ 4897: 1004897
+ 4898: 1004898
+ 4899: 1004899
+ 4900: 1004900
+ 4901: 1004901
+ 4902: 1004902
+ 4903: 1004903
+ 4904: 1004904
+ 4905: 1004905
+ 4906: 1004906
+ 4907: 1004907
+ 4908: 1004908
+ 4909: 1004909
+ 4910: 1004910
+ 4911: 1004911
+ 4912: 1004912
+ 4913: 1004913
+ 4914: 1004914
+ 4915: 1004915
+ 4916: 1004916
+ 4917: 1004917
+ 4918: 1004918
+ 4919: 1004919
+ 4920: 1004920
+ 4921: 1004921
+ 4922: 1004922
+ 4923: 1004923
+ 4924: 1004924
+ 4925: 1004925
+ 4926: 1004926
+ 4927: 1004927
+ 4928: 1004928
+ 4929: 1004929
+ 4930: 1004930
+ 4931: 1004931
+ 4932: 1004932
+ 4933: 1004933
+ 4934: 1004934
+ 4935: 1004935
+ 4936: 1004936
+ 4937: 1004937
+ 4938: 1004938
+ 4939: 1004939
+ 4940: 1004940
+ 4941: 1004941
+ 4942: 1004942
+ 4943: 1004943
+ 4944: 1004944
+ 4945: 1004945
+ 4946: 1004946
+ 4947: 1004947
+ 4948: 1004948
+ 4949: 1004949
+ 4950: 1004950
+ 4951: 1004951
+ 4952: 1004952
+ 4953: 1004953
+ 4954: 1004954
+ 4955: 1004955
+ 4956: 1004956
+ 4957: 1004957
+ 4958: 1004958
+ 4959: 1004959
+ 4960: 1004960
+ 4961: 1004961
+ 4962: 1004962
+ 4963: 1004963
+ 4964: 1004964
+ 4965: 1004965
+ 4966: 1004966
+ 4967: 1004967
+ 4968: 1004968
+ 4969: 1004969
+ 4970: 1004970
+ 4971: 1004971
+ 4972: 1004972
+ 4973: 1004973
+ 4974: 1004974
+ 4975: 1004975
+ 4976: 1004976
+ 4977: 1004977
+ 4978: 1004978
+ 4979: 1004979
+ 4980: 1004980
+ 4981: 1004981
+ 4982: 1004982
+ 4983: 1004983
+ 4984: 1004984
+ 4985: 1004985
+ 4986: 1004986
+ 4987: 1004987
+ 4988: 1004988
+ 4989: 1004989
+ 4990: 1004990
+ 4991: 1004991
+ 4992: 1004992
+ 4993: 1004993
+ 4994: 1004994
+ 4995: 1004995
+ 4996: 1004996
+ 4997: 1004997
+ 4998: 1004998
+ 4999: 1004999
+ 5000: 1005000
+ 5001: 1005001
+ 5002: 1005002
+ 5003: 1005003
+ 5004: 1005004
+ 5005: 1005005
+ 5006: 1005006
+ 5007: 1005007
+ 5008: 1005008
+ 5009: 1005009
+ 5010: 1005010
+ 5011: 1005011
+ 5012: 1005012
+ 5013: 1005013
+ 5014: 1005014
+ 5015: 1005015
+ 5016: 1005016
+ 5017: 1005017
+ 5018: 1005018
+ 5019: 1005019
+ 5020: 1005020
+ 5021: 1005021
+ 5022: 1005022
+ 5023: 1005023
+ 5024: 1005024
+ 5025: 1005025
+ 5026: 1005026
+ 5027: 1005027
+ 5028: 1005028
+ 5029: 1005029
+ 5030: 1005030
+ 5031: 1005031
+ 5032: 1005032
+ 5033: 1005033
+ 5034: 1005034
+ 5035: 1005035
+ 5036: 1005036
+ 5037: 1005037
+ 5038: 1005038
+ 5039: 1005039
+ 5040: 1005040
+ 5041: 1005041
+ 5042: 1005042
+ 5043: 1005043
+ 5044: 1005044
+ 5045: 1005045
+ 5046: 1005046
+ 5047: 1005047
+ 5048: 1005048
+ 5049: 1005049
+ 5050: 1005050
+ 5051: 1005051
+ 5052: 1005052
+ 5053: 1005053
+ 5054: 1005054
+ 5055: 1005055
+ 5056: 1005056
+ 5057: 1005057
+ 5058: 1005058
+ 5059: 1005059
+ 5060: 1005060
+ 5061: 1005061
+ 5062: 1005062
+ 5063: 1005063
+ 5064: 1005064
+ 5065: 1005065
+ 5066: 1005066
+ 5067: 1005067
+ 5068: 1005068
+ 5069: 1005069
+ 5070: 1005070
+ 5071: 1005071
+ 5072: 1005072
+ 5073: 1005073
+ 5074: 1005074
+ 5075: 1005075
+ 5076: 1005076
+ 5077: 1005077
+ 5078: 1005078
+ 5079: 1005079
+ 5080: 1005080
+ 5081: 1005081
+ 5082: 1005082
+ 5083: 1005083
+ 5084: 1005084
+ 5085: 1005085
+ 5086: 1005086
+ 5087: 1005087
+ 5088: 1005088
+ 5089: 1005089
+ 5090: 1005090
+ 5091: 1005091
+ 5092: 1005092
+ 5093: 1005093
+ 5094: 1005094
+ 5095: 1005095
+ 5096: 1005096
+ 5097: 1005097
+ 5098: 1005098
+ 5099: 1005099
+ 5100: 1005100
+ 5101: 1005101
+ 5102: 1005102
+ 5103: 1005103
+ 5104: 1005104
+ 5105: 1005105
+ 5106: 1005106
+ 5107: 1005107
+ 5108: 1005108
+ 5109: 1005109
+ 5110: 1005110
+ 5111: 1005111
+ 5112: 1005112
+ 5113: 1005113
+ 5114: 1005114
+ 5115: 1005115
+ 5116: 1005116
+ 5117: 1005117
+ 5118: 1005118
+ 5119: 1005119
+ 5120: 1005120
+ 5121: 1005121
+ 5122: 1005122
+ 5123: 1005123
+ 5124: 1005124
+ 5125: 1005125
+ 5126: 1005126
+ 5127: 1005127
+ 5128: 1005128
+ 5129: 1005129
+ 5130: 1005130
+ 5131: 1005131
+ 5132: 1005132
+ 5133: 1005133
+ 5134: 1005134
+ 5135: 1005135
+ 5136: 1005136
+ 5137: 1005137
+ 5138: 1005138
+ 5139: 1005139
+ 5140: 1005140
+ 5141: 1005141
+ 5142: 1005142
+ 5143: 1005143
+ 5144: 1005144
+ 5145: 1005145
+ 5146: 1005146
+ 5147: 1005147
+ 5148: 1005148
+ 5149: 1005149
+ 5150: 1005150
+ 5151: 1005151
+ 5152: 1005152
+ 5153: 1005153
+ 5154: 1005154
+ 5155: 1005155
+ 5156: 1005156
+ 5157: 1005157
+ 5158: 1005158
+ 5159: 1005159
+ 5160: 1005160
+ 5161: 1005161
+ 5162: 1005162
+ 5163: 1005163
+ 5164: 1005164
+ 5165: 1005165
+ 5166: 1005166
+ 5167: 1005167
+ 5168: 1005168
+ 5169: 1005169
+ 5170: 1005170
+ 5171: 1005171
+ 5172: 1005172
+ 5173: 1005173
+ 5174: 1005174
+ 5175: 1005175
+ 5176: 1005176
+ 5177: 1005177
+ 5178: 1005178
+ 5179: 1005179
+ 5180: 1005180
+ 5181: 1005181
+ 5182: 1005182
+ 5183: 1005183
+ 5184: 1005184
+ 5185: 1005185
+ 5186: 1005186
+ 5187: 1005187
+ 5188: 1005188
+ 5189: 1005189
+ 5190: 1005190
+ 5191: 1005191
+ 5192: 1005192
+ 5193: 1005193
+ 5194: 1005194
+ 5195: 1005195
+ 5196: 1005196
+ 5197: 1005197
+ 5198: 1005198
+ 5199: 1005199
+ 5200: 1005200
+ 5201: 1005201
+ 5202: 1005202
+ 5203: 1005203
+ 5204: 1005204
+ 5205: 1005205
+ 5206: 1005206
+ 5207: 1005207
+ 5208: 1005208
+ 5209: 1005209
+ 5210: 1005210
+ 5211: 1005211
+ 5212: 1005212
+ 5213: 1005213
+ 5214: 1005214
+ 5215: 1005215
+ 5216: 1005216
+ 5217: 1005217
+ 5218: 1005218
+ 5219: 1005219
+ 5220: 1005220
+ 5221: 1005221
+ 5222: 1005222
+ 5223: 1005223
+ 5224: 1005224
+ 5225: 1005225
+ 5226: 1005226
+ 5227: 1005227
+ 5228: 1005228
+ 5229: 1005229
+ 5230: 1005230
+ 5231: 1005231
+ 5232: 1005232
+ 5233: 1005233
+ 5234: 1005234
+ 5235: 1005235
+ 5236: 1005236
+ 5237: 1005237
+ 5238: 1005238
+ 5239: 1005239
+ 5240: 1005240
+ 5241: 1005241
+ 5242: 1005242
+ 5243: 1005243
+ 5244: 1005244
+ 5245: 1005245
+ 5246: 1005246
+ 5247: 1005247
+ 5248: 1005248
+ 5249: 1005249
+ 5250: 1005250
+ 5251: 1005251
+ 5252: 1005252
+ 5253: 1005253
+ 5254: 1005254
+ 5255: 1005255
+ 5256: 1005256
+ 5257: 1005257
+ 5258: 1005258
+ 5259: 1005259
+ 5260: 1005260
+ 5261: 1005261
+ 5262: 1005262
+ 5263: 1005263
+ 5264: 1005264
+ 5265: 1005265
+ 5266: 1005266
+ 5267: 1005267
+ 5268: 1005268
+ 5269: 1005269
+ 5270: 1005270
+ 5271: 1005271
+ 5272: 1005272
+ 5273: 1005273
+ 5274: 1005274
+ 5275: 1005275
+ 5276: 1005276
+ 5277: 1005277
+ 5278: 1005278
+ 5279: 1005279
+ 5280: 1005280
+ 5281: 1005281
+ 5282: 1005282
+ 5283: 1005283
+ 5284: 1005284
+ 5285: 1005285
+ 5286: 1005286
+ 5287: 1005287
+ 5288: 1005288
+ 5289: 1005289
+ 5290: 1005290
+ 5291: 1005291
+ 5292: 1005292
+ 5293: 1005293
+ 5294: 1005294
+ 5295: 1005295
+ 5296: 1005296
+ 5297: 1005297
+ 5298: 1005298
+ 5299: 1005299
+ 5300: 1005300
+ 5301: 1005301
+ 5302: 1005302
+ 5303: 1005303
+ 5304: 1005304
+ 5305: 1005305
+ 5306: 1005306
+ 5307: 1005307
+ 5308: 1005308
+ 5309: 1005309
+ 5310: 1005310
+ 5311: 1005311
+ 5312: 1005312
+ 5313: 1005313
+ 5314: 1005314
+ 5315: 1005315
+ 5316: 1005316
+ 5317: 1005317
+ 5318: 1005318
+ 5319: 1005319
+ 5320: 1005320
+ 5321: 1005321
+ 5322: 1005322
+ 5323: 1005323
+ 5324: 1005324
+ 5325: 1005325
+ 5326: 1005326
+ 5327: 1005327
+ 5328: 1005328
+ 5329: 1005329
+ 5330: 1005330
+ 5331: 1005331
+ 5332: 1005332
+ 5333: 1005333
+ 5334: 1005334
+ 5335: 1005335
+ 5336: 1005336
+ 5337: 1005337
+ 5338: 1005338
+ 5339: 1005339
+ 5340: 1005340
+ 5341: 1005341
+ 5342: 1005342
+ 5343: 1005343
+ 5344: 1005344
+ 5345: 1005345
+ 5346: 1005346
+ 5347: 1005347
+ 5348: 1005348
+ 5349: 1005349
+ 5350: 1005350
+ 5351: 1005351
+ 5352: 1005352
+ 5353: 1005353
+ 5354: 1005354
+ 5355: 1005355
+ 5356: 1005356
+ 5357: 1005357
+ 5358: 1005358
+ 5359: 1005359
+ 5360: 1005360
+ 5361: 1005361
+ 5362: 1005362
+ 5363: 1005363
+ 5364: 1005364
+ 5365: 1005365
+ 5366: 1005366
+ 5367: 1005367
+ 5368: 1005368
+ 5369: 1005369
+ 5370: 1005370
+ 5371: 1005371
+ 5372: 1005372
+ 5373: 1005373
+ 5374: 1005374
+ 5375: 1005375
+ 5376: 1005376
+ 5377: 1005377
+ 5378: 1005378
+ 5379: 1005379
+ 5380: 1005380
+ 5381: 1005381
+ 5382: 1005382
+ 5383: 1005383
+ 5384: 1005384
+ 5385: 1005385
+ 5386: 1005386
+ 5387: 1005387
+ 5388: 1005388
+ 5389: 1005389
+ 5390: 1005390
+ 5391: 1005391
+ 5392: 1005392
+ 5393: 1005393
+ 5394: 1005394
+ 5395: 1005395
+ 5396: 1005396
+ 5397: 1005397
+ 5398: 1005398
+ 5399: 1005399
+ 5400: 1005400
+ 5401: 1005401
+ 5402: 1005402
+ 5403: 1005403
+ 5404: 1005404
+ 5405: 1005405
+ 5406: 1005406
+ 5407: 1005407
+ 5408: 1005408
+ 5409: 1005409
+ 5410: 1005410
+ 5411: 1005411
+ 5412: 1005412
+ 5413: 1005413
+ 5414: 1005414
+ 5415: 1005415
+ 5416: 1005416
+ 5417: 1005417
+ 5418: 1005418
+ 5419: 1005419
+ 5420: 1005420
+ 5421: 1005421
+ 5422: 1005422
+ 5423: 1005423
+ 5424: 1005424
+ 5425: 1005425
+ 5426: 1005426
+ 5427: 1005427
+ 5428: 1005428
+ 5429: 1005429
+ 5430: 1005430
+ 5431: 1005431
+ 5432: 1005432
+ 5433: 1005433
+ 5434: 1005434
+ 5435: 1005435
+ 5436: 1005436
+ 5437: 1005437
+ 5438: 1005438
+ 5439: 1005439
+ 5440: 1005440
+ 5441: 1005441
+ 5442: 1005442
+ 5443: 1005443
+ 5444: 1005444
+ 5445: 1005445
+ 5446: 1005446
+ 5447: 1005447
+ 5448: 1005448
+ 5449: 1005449
+ 5450: 1005450
+ 5451: 1005451
+ 5452: 1005452
+ 5453: 1005453
+ 5454: 1005454
+ 5455: 1005455
+ 5456: 1005456
+ 5457: 1005457
+ 5458: 1005458
+ 5459: 1005459
+ 5460: 1005460
+ 5461: 1005461
+ 5462: 1005462
+ 5463: 1005463
+ 5464: 1005464
+ 5465: 1005465
+ 5466: 1005466
+ 5467: 1005467
+ 5468: 1005468
+ 5469: 1005469
+ 5470: 1005470
+ 5471: 1005471
+ 5472: 1005472
+ 5473: 1005473
+ 5474: 1005474
+ 5475: 1005475
+ 5476: 1005476
+ 5477: 1005477
+ 5478: 1005478
+ 5479: 1005479
+ 5480: 1005480
+ 5481: 1005481
+ 5482: 1005482
+ 5483: 1005483
+ 5484: 1005484
+ 5485: 1005485
+ 5486: 1005486
+ 5487: 1005487
+ 5488: 1005488
+ 5489: 1005489
+ 5490: 1005490
+ 5491: 1005491
+ 5492: 1005492
+ 5493: 1005493
+ 5494: 1005494
+ 5495: 1005495
+ 5496: 1005496
+ 5497: 1005497
+ 5498: 1005498
+ 5499: 1005499
+ 5500: 1005500
+ 5501: 1005501
+ 5502: 1005502
+ 5503: 1005503
+ 5504: 1005504
+ 5505: 1005505
+ 5506: 1005506
+ 5507: 1005507
+ 5508: 1005508
+ 5509: 1005509
+ 5510: 1005510
+ 5511: 1005511
+ 5512: 1005512
+ 5513: 1005513
+ 5514: 1005514
+ 5515: 1005515
+ 5516: 1005516
+ 5517: 1005517
+ 5518: 1005518
+ 5519: 1005519
+ 5520: 1005520
+ 5521: 1005521
+ 5522: 1005522
+ 5523: 1005523
+ 5524: 1005524
+ 5525: 1005525
+ 5526: 1005526
+ 5527: 1005527
+ 5528: 1005528
+ 5529: 1005529
+ 5530: 1005530
+ 5531: 1005531
+ 5532: 1005532
+ 5533: 1005533
+ 5534: 1005534
+ 5535: 1005535
+ 5536: 1005536
+ 5537: 1005537
+ 5538: 1005538
+ 5539: 1005539
+ 5540: 1005540
+ 5541: 1005541
+ 5542: 1005542
+ 5543: 1005543
+ 5544: 1005544
+ 5545: 1005545
+ 5546: 1005546
+ 5547: 1005547
+ 5548: 1005548
+ 5549: 1005549
+ 5550: 1005550
+ 5551: 1005551
+ 5552: 1005552
+ 5553: 1005553
+ 5554: 1005554
+ 5555: 1005555
+ 5556: 1005556
+ 5557: 1005557
+ 5558: 1005558
+ 5559: 1005559
+ 5560: 1005560
+ 5561: 1005561
+ 5562: 1005562
+ 5563: 1005563
+ 5564: 1005564
+ 5565: 1005565
+ 5566: 1005566
+ 5567: 1005567
+ 5568: 1005568
+ 5569: 1005569
+ 5570: 1005570
+ 5571: 1005571
+ 5572: 1005572
+ 5573: 1005573
+ 5574: 1005574
+ 5575: 1005575
+ 5576: 1005576
+ 5577: 1005577
+ 5578: 1005578
+ 5579: 1005579
+ 5580: 1005580
+ 5581: 1005581
+ 5582: 1005582
+ 5583: 1005583
+ 5584: 1005584
+ 5585: 1005585
+ 5586: 1005586
+ 5587: 1005587
+ 5588: 1005588
+ 5589: 1005589
+ 5590: 1005590
+ 5591: 1005591
+ 5592: 1005592
+ 5593: 1005593
+ 5594: 1005594
+ 5595: 1005595
+ 5596: 1005596
+ 5597: 1005597
+ 5598: 1005598
+ 5599: 1005599
+ 5600: 1005600
+ 5601: 1005601
+ 5602: 1005602
+ 5603: 1005603
+ 5604: 1005604
+ 5605: 1005605
+ 5606: 1005606
+ 5607: 1005607
+ 5608: 1005608
+ 5609: 1005609
+ 5610: 1005610
+ 5611: 1005611
+ 5612: 1005612
+ 5613: 1005613
+ 5614: 1005614
+ 5615: 1005615
+ 5616: 1005616
+ 5617: 1005617
+ 5618: 1005618
+ 5619: 1005619
+ 5620: 1005620
+ 5621: 1005621
+ 5622: 1005622
+ 5623: 1005623
+ 5624: 1005624
+ 5625: 1005625
+ 5626: 1005626
+ 5627: 1005627
+ 5628: 1005628
+ 5629: 1005629
+ 5630: 1005630
+ 5631: 1005631
+ 5632: 1005632
+ 5633: 1005633
+ 5634: 1005634
+ 5635: 1005635
+ 5636: 1005636
+ 5637: 1005637
+ 5638: 1005638
+ 5639: 1005639
+ 5640: 1005640
+ 5641: 1005641
+ 5642: 1005642
+ 5643: 1005643
+ 5644: 1005644
+ 5645: 1005645
+ 5646: 1005646
+ 5647: 1005647
+ 5648: 1005648
+ 5649: 1005649
+ 5650: 1005650
+ 5651: 1005651
+ 5652: 1005652
+ 5653: 1005653
+ 5654: 1005654
+ 5655: 1005655
+ 5656: 1005656
+ 5657: 1005657
+ 5658: 1005658
+ 5659: 1005659
+ 5660: 1005660
+ 5661: 1005661
+ 5662: 1005662
+ 5663: 1005663
+ 5664: 1005664
+ 5665: 1005665
+ 5666: 1005666
+ 5667: 1005667
+ 5668: 1005668
+ 5669: 1005669
+ 5670: 1005670
+ 5671: 1005671
+ 5672: 1005672
+ 5673: 1005673
+ 5674: 1005674
+ 5675: 1005675
+ 5676: 1005676
+ 5677: 1005677
+ 5678: 1005678
+ 5679: 1005679
+ 5680: 1005680
+ 5681: 1005681
+ 5682: 1005682
+ 5683: 1005683
+ 5684: 1005684
+ 5685: 1005685
+ 5686: 1005686
+ 5687: 1005687
+ 5688: 1005688
+ 5689: 1005689
+ 5690: 1005690
+ 5691: 1005691
+ 5692: 1005692
+ 5693: 1005693
+ 5694: 1005694
+ 5695: 1005695
+ 5696: 1005696
+ 5697: 1005697
+ 5698: 1005698
+ 5699: 1005699
+ 5700: 1005700
+ 5701: 1005701
+ 5702: 1005702
+ 5703: 1005703
+ 5704: 1005704
+ 5705: 1005705
+ 5706: 1005706
+ 5707: 1005707
+ 5708: 1005708
+ 5709: 1005709
+ 5710: 1005710
+ 5711: 1005711
+ 5712: 1005712
+ 5713: 1005713
+ 5714: 1005714
+ 5715: 1005715
+ 5716: 1005716
+ 5717: 1005717
+ 5718: 1005718
+ 5719: 1005719
+ 5720: 1005720
+ 5721: 1005721
+ 5722: 1005722
+ 5723: 1005723
+ 5724: 1005724
+ 5725: 1005725
+ 5726: 1005726
+ 5727: 1005727
+ 5728: 1005728
+ 5729: 1005729
+ 5730: 1005730
+ 5731: 1005731
+ 5732: 1005732
+ 5733: 1005733
+ 5734: 1005734
+ 5735: 1005735
+ 5736: 1005736
+ 5737: 1005737
+ 5738: 1005738
+ 5739: 1005739
+ 5740: 1005740
+ 5741: 1005741
+ 5742: 1005742
+ 5743: 1005743
+ 5744: 1005744
+ 5745: 1005745
+ 5746: 1005746
+ 5747: 1005747
+ 5748: 1005748
+ 5749: 1005749
+ 5750: 1005750
+ 5751: 1005751
+ 5752: 1005752
+ 5753: 1005753
+ 5754: 1005754
+ 5755: 1005755
+ 5756: 1005756
+ 5757: 1005757
+ 5758: 1005758
+ 5759: 1005759
+ 5760: 1005760
+ 5761: 1005761
+ 5762: 1005762
+ 5763: 1005763
+ 5764: 1005764
+ 5765: 1005765
+ 5766: 1005766
+ 5767: 1005767
+ 5768: 1005768
+ 5769: 1005769
+ 5770: 1005770
+ 5771: 1005771
+ 5772: 1005772
+ 5773: 1005773
+ 5774: 1005774
+ 5775: 1005775
+ 5776: 1005776
+ 5777: 1005777
+ 5778: 1005778
+ 5779: 1005779
+ 5780: 1005780
+ 5781: 1005781
+ 5782: 1005782
+ 5783: 1005783
+ 5784: 1005784
+ 5785: 1005785
+ 5786: 1005786
+ 5787: 1005787
+ 5788: 1005788
+ 5789: 1005789
+ 5790: 1005790
+ 5791: 1005791
+ 5792: 1005792
+ 5793: 1005793
+ 5794: 1005794
+ 5795: 1005795
+ 5796: 1005796
+ 5797: 1005797
+ 5798: 1005798
+ 5799: 1005799
+ 5800: 1005800
+ 5801: 1005801
+ 5802: 1005802
+ 5803: 1005803
+ 5804: 1005804
+ 5805: 1005805
+ 5806: 1005806
+ 5807: 1005807
+ 5808: 1005808
+ 5809: 1005809
+ 5810: 1005810
+ 5811: 1005811
+ 5812: 1005812
+ 5813: 1005813
+ 5814: 1005814
+ 5815: 1005815
+ 5816: 1005816
+ 5817: 1005817
+ 5818: 1005818
+ 5819: 1005819
+ 5820: 1005820
+ 5821: 1005821
+ 5822: 1005822
+ 5823: 1005823
+ 5824: 1005824
+ 5825: 1005825
+ 5826: 1005826
+ 5827: 1005827
+ 5828: 1005828
+ 5829: 1005829
+ 5830: 1005830
+ 5831: 1005831
+ 5832: 1005832
+ 5833: 1005833
+ 5834: 1005834
+ 5835: 1005835
+ 5836: 1005836
+ 5837: 1005837
+ 5838: 1005838
+ 5839: 1005839
+ 5840: 1005840
+ 5841: 1005841
+ 5842: 1005842
+ 5843: 1005843
+ 5844: 1005844
+ 5845: 1005845
+ 5846: 1005846
+ 5847: 1005847
+ 5848: 1005848
+ 5849: 1005849
+ 5850: 1005850
+ 5851: 1005851
+ 5852: 1005852
+ 5853: 1005853
+ 5854: 1005854
+ 5855: 1005855
+ 5856: 1005856
+ 5857: 1005857
+ 5858: 1005858
+ 5859: 1005859
+ 5860: 1005860
+ 5861: 1005861
+ 5862: 1005862
+ 5863: 1005863
+ 5864: 1005864
+ 5865: 1005865
+ 5866: 1005866
+ 5867: 1005867
+ 5868: 1005868
+ 5869: 1005869
+ 5870: 1005870
+ 5871: 1005871
+ 5872: 1005872
+ 5873: 1005873
+ 5874: 1005874
+ 5875: 1005875
+ 5876: 1005876
+ 5877: 1005877
+ 5878: 1005878
+ 5879: 1005879
+ 5880: 1005880
+ 5881: 1005881
+ 5882: 1005882
+ 5883: 1005883
+ 5884: 1005884
+ 5885: 1005885
+ 5886: 1005886
+ 5887: 1005887
+ 5888: 1005888
+ 5889: 1005889
+ 5890: 1005890
+ 5891: 1005891
+ 5892: 1005892
+ 5893: 1005893
+ 5894: 1005894
+ 5895: 1005895
+ 5896: 1005896
+ 5897: 1005897
+ 5898: 1005898
+ 5899: 1005899
+ 5900: 1005900
+ 5901: 1005901
+ 5902: 1005902
+ 5903: 1005903
+ 5904: 1005904
+ 5905: 1005905
+ 5906: 1005906
+ 5907: 1005907
+ 5908: 1005908
+ 5909: 1005909
+ 5910: 1005910
+ 5911: 1005911
+ 5912: 1005912
+ 5913: 1005913
+ 5914: 1005914
+ 5915: 1005915
+ 5916: 1005916
+ 5917: 1005917
+ 5918: 1005918
+ 5919: 1005919
+ 5920: 1005920
+ 5921: 1005921
+ 5922: 1005922
+ 5923: 1005923
+ 5924: 1005924
+ 5925: 1005925
+ 5926: 1005926
+ 5927: 1005927
+ 5928: 1005928
+ 5929: 1005929
+ 5930: 1005930
+ 5931: 1005931
+ 5932: 1005932
+ 5933: 1005933
+ 5934: 1005934
+ 5935: 1005935
+ 5936: 1005936
+ 5937: 1005937
+ 5938: 1005938
+ 5939: 1005939
+ 5940: 1005940
+ 5941: 1005941
+ 5942: 1005942
+ 5943: 1005943
+ 5944: 1005944
+ 5945: 1005945
+ 5946: 1005946
+ 5947: 1005947
+ 5948: 1005948
+ 5949: 1005949
+ 5950: 1005950
+ 5951: 1005951
+ 5952: 1005952
+ 5953: 1005953
+ 5954: 1005954
+ 5955: 1005955
+ 5956: 1005956
+ 5957: 1005957
+ 5958: 1005958
+ 5959: 1005959
+ 5960: 1005960
+ 5961: 1005961
+ 5962: 1005962
+ 5963: 1005963
+ 5964: 1005964
+ 5965: 1005965
+ 5966: 1005966
+ 5967: 1005967
+ 5968: 1005968
+ 5969: 1005969
+ 5970: 1005970
+ 5971: 1005971
+ 5972: 1005972
+ 5973: 1005973
+ 5974: 1005974
+ 5975: 1005975
+ 5976: 1005976
+ 5977: 1005977
+ 5978: 1005978
+ 5979: 1005979
+ 5980: 1005980
+ 5981: 1005981
+ 5982: 1005982
+ 5983: 1005983
+ 5984: 1005984
+ 5985: 1005985
+ 5986: 1005986
+ 5987: 1005987
+ 5988: 1005988
+ 5989: 1005989
+ 5990: 1005990
+ 5991: 1005991
+ 5992: 1005992
+ 5993: 1005993
+ 5994: 1005994
+ 5995: 1005995
+ 5996: 1005996
+ 5997: 1005997
+ 5998: 1005998
+ 5999: 1005999
+ 6000: 1006000
+ 6001: 1006001
+ 6002: 1006002
+ 6003: 1006003
+ 6004: 1006004
+ 6005: 1006005
+ 6006: 1006006
+ 6007: 1006007
+ 6008: 1006008
+ 6009: 1006009
+ 6010: 1006010
+ 6011: 1006011
+ 6012: 1006012
+ 6013: 1006013
+ 6014: 1006014
+ 6015: 1006015
+ 6016: 1006016
+ 6017: 1006017
+ 6018: 1006018
+ 6019: 1006019
+ 6020: 1006020
+ 6021: 1006021
+ 6022: 1006022
+ 6023: 1006023
+ 6024: 1006024
+ 6025: 1006025
+ 6026: 1006026
+ 6027: 1006027
+ 6028: 1006028
+ 6029: 1006029
+ 6030: 1006030
+ 6031: 1006031
+ 6032: 1006032
+ 6033: 1006033
+ 6034: 1006034
+ 6035: 1006035
+ 6036: 1006036
+ 6037: 1006037
+ 6038: 1006038
+ 6039: 1006039
+ 6040: 1006040
+ 6041: 1006041
+ 6042: 1006042
+ 6043: 1006043
+ 6044: 1006044
+ 6045: 1006045
+ 6046: 1006046
+ 6047: 1006047
+ 6048: 1006048
+ 6049: 1006049
+ 6050: 1006050
+ 6051: 1006051
+ 6052: 1006052
+ 6053: 1006053
+ 6054: 1006054
+ 6055: 1006055
+ 6056: 1006056
+ 6057: 1006057
+ 6058: 1006058
+ 6059: 1006059
+ 6060: 1006060
+ 6061: 1006061
+ 6062: 1006062
+ 6063: 1006063
+ 6064: 1006064
+ 6065: 1006065
+ 6066: 1006066
+ 6067: 1006067
+ 6068: 1006068
+ 6069: 1006069
+ 6070: 1006070
+ 6071: 1006071
+ 6072: 1006072
+ 6073: 1006073
+ 6074: 1006074
+ 6075: 1006075
+ 6076: 1006076
+ 6077: 1006077
+ 6078: 1006078
+ 6079: 1006079
+ 6080: 1006080
+ 6081: 1006081
+ 6082: 1006082
+ 6083: 1006083
+ 6084: 1006084
+ 6085: 1006085
+ 6086: 1006086
+ 6087: 1006087
+ 6088: 1006088
+ 6089: 1006089
+ 6090: 1006090
+ 6091: 1006091
+ 6092: 1006092
+ 6093: 1006093
+ 6094: 1006094
+ 6095: 1006095
+ 6096: 1006096
+ 6097: 1006097
+ 6098: 1006098
+ 6099: 1006099
+ 6100: 1006100
+ 6101: 1006101
+ 6102: 1006102
+ 6103: 1006103
+ 6104: 1006104
+ 6105: 1006105
+ 6106: 1006106
+ 6107: 1006107
+ 6108: 1006108
+ 6109: 1006109
+ 6110: 1006110
+ 6111: 1006111
+ 6112: 1006112
+ 6113: 1006113
+ 6114: 1006114
+ 6115: 1006115
+ 6116: 1006116
+ 6117: 1006117
+ 6118: 1006118
+ 6119: 1006119
+ 6120: 1006120
+ 6121: 1006121
+ 6122: 1006122
+ 6123: 1006123
+ 6124: 1006124
+ 6125: 1006125
+ 6126: 1006126
+ 6127: 1006127
+ 6128: 1006128
+ 6129: 1006129
+ 6130: 1006130
+ 6131: 1006131
+ 6132: 1006132
+ 6133: 1006133
+ 6134: 1006134
+ 6135: 1006135
+ 6136: 1006136
+ 6137: 1006137
+ 6138: 1006138
+ 6139: 1006139
+ 6140: 1006140
+ 6141: 1006141
+ 6142: 1006142
+ 6143: 1006143
+ 6144: 1006144
+ 6145: 1006145
+ 6146: 1006146
+ 6147: 1006147
+ 6148: 1006148
+ 6149: 1006149
+ 6150: 1006150
+ 6151: 1006151
+ 6152: 1006152
+ 6153: 1006153
+ 6154: 1006154
+ 6155: 1006155
+ 6156: 1006156
+ 6157: 1006157
+ 6158: 1006158
+ 6159: 1006159
+ 6160: 1006160
+ 6161: 1006161
+ 6162: 1006162
+ 6163: 1006163
+ 6164: 1006164
+ 6165: 1006165
+ 6166: 1006166
+ 6167: 1006167
+ 6168: 1006168
+ 6169: 1006169
+ 6170: 1006170
+ 6171: 1006171
+ 6172: 1006172
+ 6173: 1006173
+ 6174: 1006174
+ 6175: 1006175
+ 6176: 1006176
+ 6177: 1006177
+ 6178: 1006178
+ 6179: 1006179
+ 6180: 1006180
+ 6181: 1006181
+ 6182: 1006182
+ 6183: 1006183
+ 6184: 1006184
+ 6185: 1006185
+ 6186: 1006186
+ 6187: 1006187
+ 6188: 1006188
+ 6189: 1006189
+ 6190: 1006190
+ 6191: 1006191
+ 6192: 1006192
+ 6193: 1006193
+ 6194: 1006194
+ 6195: 1006195
+ 6196: 1006196
+ 6197: 1006197
+ 6198: 1006198
+ 6199: 1006199
+ 6200: 1006200
+ 6201: 1006201
+ 6202: 1006202
+ 6203: 1006203
+ 6204: 1006204
+ 6205: 1006205
+ 6206: 1006206
+ 6207: 1006207
+ 6208: 1006208
+ 6209: 1006209
+ 6210: 1006210
+ 6211: 1006211
+ 6212: 1006212
+ 6213: 1006213
+ 6214: 1006214
+ 6215: 1006215
+ 6216: 1006216
+ 6217: 1006217
+ 6218: 1006218
+ 6219: 1006219
+ 6220: 1006220
+ 6221: 1006221
+ 6222: 1006222
+ 6223: 1006223
+ 6224: 1006224
+ 6225: 1006225
+ 6226: 1006226
+ 6227: 1006227
+ 6228: 1006228
+ 6229: 1006229
+ 6230: 1006230
+ 6231: 1006231
+ 6232: 1006232
+ 6233: 1006233
+ 6234: 1006234
+ 6235: 1006235
+ 6236: 1006236
+ 6237: 1006237
+ 6238: 1006238
+ 6239: 1006239
+ 6240: 1006240
+ 6241: 1006241
+ 6242: 1006242
+ 6243: 1006243
+ 6244: 1006244
+ 6245: 1006245
+ 6246: 1006246
+ 6247: 1006247
+ 6248: 1006248
+ 6249: 1006249
+ 6250: 1006250
+ 6251: 1006251
+ 6252: 1006252
+ 6253: 1006253
+ 6254: 1006254
+ 6255: 1006255
+ 6256: 1006256
+ 6257: 1006257
+ 6258: 1006258
+ 6259: 1006259
+ 6260: 1006260
+ 6261: 1006261
+ 6262: 1006262
+ 6263: 1006263
+ 6264: 1006264
+ 6265: 1006265
+ 6266: 1006266
+ 6267: 1006267
+ 6268: 1006268
+ 6269: 1006269
+ 6270: 1006270
+ 6271: 1006271
+ 6272: 1006272
+ 6273: 1006273
+ 6274: 1006274
+ 6275: 1006275
+ 6276: 1006276
+ 6277: 1006277
+ 6278: 1006278
+ 6279: 1006279
+ 6280: 1006280
+ 6281: 1006281
+ 6282: 1006282
+ 6283: 1006283
+ 6284: 1006284
+ 6285: 1006285
+ 6286: 1006286
+ 6287: 1006287
+ 6288: 1006288
+ 6289: 1006289
+ 6290: 1006290
+ 6291: 1006291
+ 6292: 1006292
+ 6293: 1006293
+ 6294: 1006294
+ 6295: 1006295
+ 6296: 1006296
+ 6297: 1006297
+ 6298: 1006298
+ 6299: 1006299
+ 6300: 1006300
+ 6301: 1006301
+ 6302: 1006302
+ 6303: 1006303
+ 6304: 1006304
+ 6305: 1006305
+ 6306: 1006306
+ 6307: 1006307
+ 6308: 1006308
+ 6309: 1006309
+ 6310: 1006310
+ 6311: 1006311
+ 6312: 1006312
+ 6313: 1006313
+ 6314: 1006314
+ 6315: 1006315
+ 6316: 1006316
+ 6317: 1006317
+ 6318: 1006318
+ 6319: 1006319
+ 6320: 1006320
+ 6321: 1006321
+ 6322: 1006322
+ 6323: 1006323
+ 6324: 1006324
+ 6325: 1006325
+ 6326: 1006326
+ 6327: 1006327
+ 6328: 1006328
+ 6329: 1006329
+ 6330: 1006330
+ 6331: 1006331
+ 6332: 1006332
+ 6333: 1006333
+ 6334: 1006334
+ 6335: 1006335
+ 6336: 1006336
+ 6337: 1006337
+ 6338: 1006338
+ 6339: 1006339
+ 6340: 1006340
+ 6341: 1006341
+ 6342: 1006342
+ 6343: 1006343
+ 6344: 1006344
+ 6345: 1006345
+ 6346: 1006346
+ 6347: 1006347
+ 6348: 1006348
+ 6349: 1006349
+ 6350: 1006350
+ 6351: 1006351
+ 6352: 1006352
+ 6353: 1006353
+ 6354: 1006354
+ 6355: 1006355
+ 6356: 1006356
+ 6357: 1006357
+ 6358: 1006358
+ 6359: 1006359
+ 6360: 1006360
+ 6361: 1006361
+ 6362: 1006362
+ 6363: 1006363
+ 6364: 1006364
+ 6365: 1006365
+ 6366: 1006366
+ 6367: 1006367
+ 6368: 1006368
+ 6369: 1006369
+ 6370: 1006370
+ 6371: 1006371
+ 6372: 1006372
+ 6373: 1006373
+ 6374: 1006374
+ 6375: 1006375
+ 6376: 1006376
+ 6377: 1006377
+ 6378: 1006378
+ 6379: 1006379
+ 6380: 1006380
+ 6381: 1006381
+ 6382: 1006382
+ 6383: 1006383
+ 6384: 1006384
+ 6385: 1006385
+ 6386: 1006386
+ 6387: 1006387
+ 6388: 1006388
+ 6389: 1006389
+ 6390: 1006390
+ 6391: 1006391
+ 6392: 1006392
+ 6393: 1006393
+ 6394: 1006394
+ 6395: 1006395
+ 6396: 1006396
+ 6397: 1006397
+ 6398: 1006398
+ 6399: 1006399
+ 6400: 1006400
+ 6401: 1006401
+ 6402: 1006402
+ 6403: 1006403
+ 6404: 1006404
+ 6405: 1006405
+ 6406: 1006406
+ 6407: 1006407
+ 6408: 1006408
+ 6409: 1006409
+ 6410: 1006410
+ 6411: 1006411
+ 6412: 1006412
+ 6413: 1006413
+ 6414: 1006414
+ 6415: 1006415
+ 6416: 1006416
+ 6417: 1006417
+ 6418: 1006418
+ 6419: 1006419
+ 6420: 1006420
+ 6421: 1006421
+ 6422: 1006422
+ 6423: 1006423
+ 6424: 1006424
+ 6425: 1006425
+ 6426: 1006426
+ 6427: 1006427
+ 6428: 1006428
+ 6429: 1006429
+ 6430: 1006430
+ 6431: 1006431
+ 6432: 1006432
+ 6433: 1006433
+ 6434: 1006434
+ 6435: 1006435
+ 6436: 1006436
+ 6437: 1006437
+ 6438: 1006438
+ 6439: 1006439
+ 6440: 1006440
+ 6441: 1006441
+ 6442: 1006442
+ 6443: 1006443
+ 6444: 1006444
+ 6445: 1006445
+ 6446: 1006446
+ 6447: 1006447
+ 6448: 1006448
+ 6449: 1006449
+ 6450: 1006450
+ 6451: 1006451
+ 6452: 1006452
+ 6453: 1006453
+ 6454: 1006454
+ 6455: 1006455
+ 6456: 1006456
+ 6457: 1006457
+ 6458: 1006458
+ 6459: 1006459
+ 6460: 1006460
+ 6461: 1006461
+ 6462: 1006462
+ 6463: 1006463
+ 6464: 1006464
+ 6465: 1006465
+ 6466: 1006466
+ 6467: 1006467
+ 6468: 1006468
+ 6469: 1006469
+ 6470: 1006470
+ 6471: 1006471
+ 6472: 1006472
+ 6473: 1006473
+ 6474: 1006474
+ 6475: 1006475
+ 6476: 1006476
+ 6477: 1006477
+ 6478: 1006478
+ 6479: 1006479
+ 6480: 1006480
+ 6481: 1006481
+ 6482: 1006482
+ 6483: 1006483
+ 6484: 1006484
+ 6485: 1006485
+ 6486: 1006486
+ 6487: 1006487
+ 6488: 1006488
+ 6489: 1006489
+ 6490: 1006490
+ 6491: 1006491
+ 6492: 1006492
+ 6493: 1006493
+ 6494: 1006494
+ 6495: 1006495
+ 6496: 1006496
+ 6497: 1006497
+ 6498: 1006498
+ 6499: 1006499
+ 6500: 1006500
+ 6501: 1006501
+ 6502: 1006502
+ 6503: 1006503
+ 6504: 1006504
+ 6505: 1006505
+ 6506: 1006506
+ 6507: 1006507
+ 6508: 1006508
+ 6509: 1006509
+ 6510: 1006510
+ 6511: 1006511
+ 6512: 1006512
+ 6513: 1006513
+ 6514: 1006514
+ 6515: 1006515
+ 6516: 1006516
+ 6517: 1006517
+ 6518: 1006518
+ 6519: 1006519
+ 6520: 1006520
+ 6521: 1006521
+ 6522: 1006522
+ 6523: 1006523
+ 6524: 1006524
+ 6525: 1006525
+ 6526: 1006526
+ 6527: 1006527
+ 6528: 1006528
+ 6529: 1006529
+ 6530: 1006530
+ 6531: 1006531
+ 6532: 1006532
+ 6533: 1006533
+ 6534: 1006534
+ 6535: 1006535
+ 6536: 1006536
+ 6537: 1006537
+ 6538: 1006538
+ 6539: 1006539
+ 6540: 1006540
+ 6541: 1006541
+ 6542: 1006542
+ 6543: 1006543
+ 6544: 1006544
+ 6545: 1006545
+ 6546: 1006546
+ 6547: 1006547
+ 6548: 1006548
+ 6549: 1006549
+ 6550: 1006550
+ 6551: 1006551
+ 6552: 1006552
+ 6553: 1006553
+ 6554: 1006554
+ 6555: 1006555
+ 6556: 1006556
+ 6557: 1006557
+ 6558: 1006558
+ 6559: 1006559
+ 6560: 1006560
+ 6561: 1006561
+ 6562: 1006562
+ 6563: 1006563
+ 6564: 1006564
+ 6565: 1006565
+ 6566: 1006566
+ 6567: 1006567
+ 6568: 1006568
+ 6569: 1006569
+ 6570: 1006570
+ 6571: 1006571
+ 6572: 1006572
+ 6573: 1006573
+ 6574: 1006574
+ 6575: 1006575
+ 6576: 1006576
+ 6577: 1006577
+ 6578: 1006578
+ 6579: 1006579
+ 6580: 1006580
+ 6581: 1006581
+ 6582: 1006582
+ 6583: 1006583
+ 6584: 1006584
+ 6585: 1006585
+ 6586: 1006586
+ 6587: 1006587
+ 6588: 1006588
+ 6589: 1006589
+ 6590: 1006590
+ 6591: 1006591
+ 6592: 1006592
+ 6593: 1006593
+ 6594: 1006594
+ 6595: 1006595
+ 6596: 1006596
+ 6597: 1006597
+ 6598: 1006598
+ 6599: 1006599
+ 6600: 1006600
+ 6601: 1006601
+ 6602: 1006602
+ 6603: 1006603
+ 6604: 1006604
+ 6605: 1006605
+ 6606: 1006606
+ 6607: 1006607
+ 6608: 1006608
+ 6609: 1006609
+ 6610: 1006610
+ 6611: 1006611
+ 6612: 1006612
+ 6613: 1006613
+ 6614: 1006614
+ 6615: 1006615
+ 6616: 1006616
+ 6617: 1006617
+ 6618: 1006618
+ 6619: 1006619
+ 6620: 1006620
+ 6621: 1006621
+ 6622: 1006622
+ 6623: 1006623
+ 6624: 1006624
+ 6625: 1006625
+ 6626: 1006626
+ 6627: 1006627
+ 6628: 1006628
+ 6629: 1006629
+ 6630: 1006630
+ 6631: 1006631
+ 6632: 1006632
+ 6633: 1006633
+ 6634: 1006634
+ 6635: 1006635
+ 6636: 1006636
+ 6637: 1006637
+ 6638: 1006638
+ 6639: 1006639
+ 6640: 1006640
+ 6641: 1006641
+ 6642: 1006642
+ 6643: 1006643
+ 6644: 1006644
+ 6645: 1006645
+ 6646: 1006646
+ 6647: 1006647
+ 6648: 1006648
+ 6649: 1006649
+ 6650: 1006650
+ 6651: 1006651
+ 6652: 1006652
+ 6653: 1006653
+ 6654: 1006654
+ 6655: 1006655
+ 6656: 1006656
+ 6657: 1006657
+ 6658: 1006658
+ 6659: 1006659
+ 6660: 1006660
+ 6661: 1006661
+ 6662: 1006662
+ 6663: 1006663
+ 6664: 1006664
+ 6665: 1006665
+ 6666: 1006666
+ 6667: 1006667
+ 6668: 1006668
+ 6669: 1006669
+ 6670: 1006670
+ 6671: 1006671
+ 6672: 1006672
+ 6673: 1006673
+ 6674: 1006674
+ 6675: 1006675
+ 6676: 1006676
+ 6677: 1006677
+ 6678: 1006678
+ 6679: 1006679
+ 6680: 1006680
+ 6681: 1006681
+ 6682: 1006682
+ 6683: 1006683
+ 6684: 1006684
+ 6685: 1006685
+ 6686: 1006686
+ 6687: 1006687
+ 6688: 1006688
+ 6689: 1006689
+ 6690: 1006690
+ 6691: 1006691
+ 6692: 1006692
+ 6693: 1006693
+ 6694: 1006694
+ 6695: 1006695
+ 6696: 1006696
+ 6697: 1006697
+ 6698: 1006698
+ 6699: 1006699
+ 6700: 1006700
+ 6701: 1006701
+ 6702: 1006702
+ 6703: 1006703
+ 6704: 1006704
+ 6705: 1006705
+ 6706: 1006706
+ 6707: 1006707
+ 6708: 1006708
+ 6709: 1006709
+ 6710: 1006710
+ 6711: 1006711
+ 6712: 1006712
+ 6713: 1006713
+ 6714: 1006714
+ 6715: 1006715
+ 6716: 1006716
+ 6717: 1006717
+ 6718: 1006718
+ 6719: 1006719
+ 6720: 1006720
+ 6721: 1006721
+ 6722: 1006722
+ 6723: 1006723
+ 6724: 1006724
+ 6725: 1006725
+ 6726: 1006726
+ 6727: 1006727
+ 6728: 1006728
+ 6729: 1006729
+ 6730: 1006730
+ 6731: 1006731
+ 6732: 1006732
+ 6733: 1006733
+ 6734: 1006734
+ 6735: 1006735
+ 6736: 1006736
+ 6737: 1006737
+ 6738: 1006738
+ 6739: 1006739
+ 6740: 1006740
+ 6741: 1006741
+ 6742: 1006742
+ 6743: 1006743
+ 6744: 1006744
+ 6745: 1006745
+ 6746: 1006746
+ 6747: 1006747
+ 6748: 1006748
+ 6749: 1006749
+ 6750: 1006750
+ 6751: 1006751
+ 6752: 1006752
+ 6753: 1006753
+ 6754: 1006754
+ 6755: 1006755
+ 6756: 1006756
+ 6757: 1006757
+ 6758: 1006758
+ 6759: 1006759
+ 6760: 1006760
+ 6761: 1006761
+ 6762: 1006762
+ 6763: 1006763
+ 6764: 1006764
+ 6765: 1006765
+ 6766: 1006766
+ 6767: 1006767
+ 6768: 1006768
+ 6769: 1006769
+ 6770: 1006770
+ 6771: 1006771
+ 6772: 1006772
+ 6773: 1006773
+ 6774: 1006774
+ 6775: 1006775
+ 6776: 1006776
+ 6777: 1006777
+ 6778: 1006778
+ 6779: 1006779
+ 6780: 1006780
+ 6781: 1006781
+ 6782: 1006782
+ 6783: 1006783
+ 6784: 1006784
+ 6785: 1006785
+ 6786: 1006786
+ 6787: 1006787
+ 6788: 1006788
+ 6789: 1006789
+ 6790: 1006790
+ 6791: 1006791
+ 6792: 1006792
+ 6793: 1006793
+ 6794: 1006794
+ 6795: 1006795
+ 6796: 1006796
+ 6797: 1006797
+ 6798: 1006798
+ 6799: 1006799
+ 6800: 1006800
+ 6801: 1006801
+ 6802: 1006802
+ 6803: 1006803
+ 6804: 1006804
+ 6805: 1006805
+ 6806: 1006806
+ 6807: 1006807
+ 6808: 1006808
+ 6809: 1006809
+ 6810: 1006810
+ 6811: 1006811
+ 6812: 1006812
+ 6813: 1006813
+ 6814: 1006814
+ 6815: 1006815
+ 6816: 1006816
+ 6817: 1006817
+ 6818: 1006818
+ 6819: 1006819
+ 6820: 1006820
+ 6821: 1006821
+ 6822: 1006822
+ 6823: 1006823
+ 6824: 1006824
+ 6825: 1006825
+ 6826: 1006826
+ 6827: 1006827
+ 6828: 1006828
+ 6829: 1006829
+ 6830: 1006830
+ 6831: 1006831
+ 6832: 1006832
+ 6833: 1006833
+ 6834: 1006834
+ 6835: 1006835
+ 6836: 1006836
+ 6837: 1006837
+ 6838: 1006838
+ 6839: 1006839
+ 6840: 1006840
+ 6841: 1006841
+ 6842: 1006842
+ 6843: 1006843
+ 6844: 1006844
+ 6845: 1006845
+ 6846: 1006846
+ 6847: 1006847
+ 6848: 1006848
+ 6849: 1006849
+ 6850: 1006850
+ 6851: 1006851
+ 6852: 1006852
+ 6853: 1006853
+ 6854: 1006854
+ 6855: 1006855
+ 6856: 1006856
+ 6857: 1006857
+ 6858: 1006858
+ 6859: 1006859
+ 6860: 1006860
+ 6861: 1006861
+ 6862: 1006862
+ 6863: 1006863
+ 6864: 1006864
+ 6865: 1006865
+ 6866: 1006866
+ 6867: 1006867
+ 6868: 1006868
+ 6869: 1006869
+ 6870: 1006870
+ 6871: 1006871
+ 6872: 1006872
+ 6873: 1006873
+ 6874: 1006874
+ 6875: 1006875
+ 6876: 1006876
+ 6877: 1006877
+ 6878: 1006878
+ 6879: 1006879
+ 6880: 1006880
+ 6881: 1006881
+ 6882: 1006882
+ 6883: 1006883
+ 6884: 1006884
+ 6885: 1006885
+ 6886: 1006886
+ 6887: 1006887
+ 6888: 1006888
+ 6889: 1006889
+ 6890: 1006890
+ 6891: 1006891
+ 6892: 1006892
+ 6893: 1006893
+ 6894: 1006894
+ 6895: 1006895
+ 6896: 1006896
+ 6897: 1006897
+ 6898: 1006898
+ 6899: 1006899
+ 6900: 1006900
+ 6901: 1006901
+ 6902: 1006902
+ 6903: 1006903
+ 6904: 1006904
+ 6905: 1006905
+ 6906: 1006906
+ 6907: 1006907
+ 6908: 1006908
+ 6909: 1006909
+ 6910: 1006910
+ 6911: 1006911
+ 6912: 1006912
+ 6913: 1006913
+ 6914: 1006914
+ 6915: 1006915
+ 6916: 1006916
+ 6917: 1006917
+ 6918: 1006918
+ 6919: 1006919
+ 6920: 1006920
+ 6921: 1006921
+ 6922: 1006922
+ 6923: 1006923
+ 6924: 1006924
+ 6925: 1006925
+ 6926: 1006926
+ 6927: 1006927
+ 6928: 1006928
+ 6929: 1006929
+ 6930: 1006930
+ 6931: 1006931
+ 6932: 1006932
+ 6933: 1006933
+ 6934: 1006934
+ 6935: 1006935
+ 6936: 1006936
+ 6937: 1006937
+ 6938: 1006938
+ 6939: 1006939
+ 6940: 1006940
+ 6941: 1006941
+ 6942: 1006942
+ 6943: 1006943
+ 6944: 1006944
+ 6945: 1006945
+ 6946: 1006946
+ 6947: 1006947
+ 6948: 1006948
+ 6949: 1006949
+ 6950: 1006950
+ 6951: 1006951
+ 6952: 1006952
+ 6953: 1006953
+ 6954: 1006954
+ 6955: 1006955
+ 6956: 1006956
+ 6957: 1006957
+ 6958: 1006958
+ 6959: 1006959
+ 6960: 1006960
+ 6961: 1006961
+ 6962: 1006962
+ 6963: 1006963
+ 6964: 1006964
+ 6965: 1006965
+ 6966: 1006966
+ 6967: 1006967
+ 6968: 1006968
+ 6969: 1006969
+ 6970: 1006970
+ 6971: 1006971
+ 6972: 1006972
+ 6973: 1006973
+ 6974: 1006974
+ 6975: 1006975
+ 6976: 1006976
+ 6977: 1006977
+ 6978: 1006978
+ 6979: 1006979
+ 6980: 1006980
+ 6981: 1006981
+ 6982: 1006982
+ 6983: 1006983
+ 6984: 1006984
+ 6985: 1006985
+ 6986: 1006986
+ 6987: 1006987
+ 6988: 1006988
+ 6989: 1006989
+ 6990: 1006990
+ 6991: 1006991
+ 6992: 1006992
+ 6993: 1006993
+ 6994: 1006994
+ 6995: 1006995
+ 6996: 1006996
+ 6997: 1006997
+ 6998: 1006998
+ 6999: 1006999
+ 7000: 1007000
+ 7001: 1007001
+ 7002: 1007002
+ 7003: 1007003
+ 7004: 1007004
+ 7005: 1007005
+ 7006: 1007006
+ 7007: 1007007
+ 7008: 1007008
+ 7009: 1007009
+ 7010: 1007010
+ 7011: 1007011
+ 7012: 1007012
+ 7013: 1007013
+ 7014: 1007014
+ 7015: 1007015
+ 7016: 1007016
+ 7017: 1007017
+ 7018: 1007018
+ 7019: 1007019
+ 7020: 1007020
+ 7021: 1007021
+ 7022: 1007022
+ 7023: 1007023
+ 7024: 1007024
+ 7025: 1007025
+ 7026: 1007026
+ 7027: 1007027
+ 7028: 1007028
+ 7029: 1007029
+ 7030: 1007030
+ 7031: 1007031
+ 7032: 1007032
+ 7033: 1007033
+ 7034: 1007034
+ 7035: 1007035
+ 7036: 1007036
+ 7037: 1007037
+ 7038: 1007038
+ 7039: 1007039
+ 7040: 1007040
+ 7041: 1007041
+ 7042: 1007042
+ 7043: 1007043
+ 7044: 1007044
+ 7045: 1007045
+ 7046: 1007046
+ 7047: 1007047
+ 7048: 1007048
+ 7049: 1007049
+ 7050: 1007050
+ 7051: 1007051
+ 7052: 1007052
+ 7053: 1007053
+ 7054: 1007054
+ 7055: 1007055
+ 7056: 1007056
+ 7057: 1007057
+ 7058: 1007058
+ 7059: 1007059
+ 7060: 1007060
+ 7061: 1007061
+ 7062: 1007062
+ 7063: 1007063
+ 7064: 1007064
+ 7065: 1007065
+ 7066: 1007066
+ 7067: 1007067
+ 7068: 1007068
+ 7069: 1007069
+ 7070: 1007070
+ 7071: 1007071
+ 7072: 1007072
+ 7073: 1007073
+ 7074: 1007074
+ 7075: 1007075
+ 7076: 1007076
+ 7077: 1007077
+ 7078: 1007078
+ 7079: 1007079
+ 7080: 1007080
+ 7081: 1007081
+ 7082: 1007082
+ 7083: 1007083
+ 7084: 1007084
+ 7085: 1007085
+ 7086: 1007086
+ 7087: 1007087
+ 7088: 1007088
+ 7089: 1007089
+ 7090: 1007090
+ 7091: 1007091
+ 7092: 1007092
+ 7093: 1007093
+ 7094: 1007094
+ 7095: 1007095
+ 7096: 1007096
+ 7097: 1007097
+ 7098: 1007098
+ 7099: 1007099
+ 7100: 1007100
+ 7101: 1007101
+ 7102: 1007102
+ 7103: 1007103
+ 7104: 1007104
+ 7105: 1007105
+ 7106: 1007106
+ 7107: 1007107
+ 7108: 1007108
+ 7109: 1007109
+ 7110: 1007110
+ 7111: 1007111
+ 7112: 1007112
+ 7113: 1007113
+ 7114: 1007114
+ 7115: 1007115
+ 7116: 1007116
+ 7117: 1007117
+ 7118: 1007118
+ 7119: 1007119
+ 7120: 1007120
+ 7121: 1007121
+ 7122: 1007122
+ 7123: 1007123
+ 7124: 1007124
+ 7125: 1007125
+ 7126: 1007126
+ 7127: 1007127
+ 7128: 1007128
+ 7129: 1007129
+ 7130: 1007130
+ 7131: 1007131
+ 7132: 1007132
+ 7133: 1007133
+ 7134: 1007134
+ 7135: 1007135
+ 7136: 1007136
+ 7137: 1007137
+ 7138: 1007138
+ 7139: 1007139
+ 7140: 1007140
+ 7141: 1007141
+ 7142: 1007142
+ 7143: 1007143
+ 7144: 1007144
+ 7145: 1007145
+ 7146: 1007146
+ 7147: 1007147
+ 7148: 1007148
+ 7149: 1007149
+ 7150: 1007150
+ 7151: 1007151
+ 7152: 1007152
+ 7153: 1007153
+ 7154: 1007154
+ 7155: 1007155
+ 7156: 1007156
+ 7157: 1007157
+ 7158: 1007158
+ 7159: 1007159
+ 7160: 1007160
+ 7161: 1007161
+ 7162: 1007162
+ 7163: 1007163
+ 7164: 1007164
+ 7165: 1007165
+ 7166: 1007166
+ 7167: 1007167
+ 7168: 1007168
+ 7169: 1007169
+ 7170: 1007170
+ 7171: 1007171
+ 7172: 1007172
+ 7173: 1007173
+ 7174: 1007174
+ 7175: 1007175
+ 7176: 1007176
+ 7177: 1007177
+ 7178: 1007178
+ 7179: 1007179
+ 7180: 1007180
+ 7181: 1007181
+ 7182: 1007182
+ 7183: 1007183
+ 7184: 1007184
+ 7185: 1007185
+ 7186: 1007186
+ 7187: 1007187
+ 7188: 1007188
+ 7189: 1007189
+ 7190: 1007190
+ 7191: 1007191
+ 7192: 1007192
+ 7193: 1007193
+ 7194: 1007194
+ 7195: 1007195
+ 7196: 1007196
+ 7197: 1007197
+ 7198: 1007198
+ 7199: 1007199
+ 7200: 1007200
+ 7201: 1007201
+ 7202: 1007202
+ 7203: 1007203
+ 7204: 1007204
+ 7205: 1007205
+ 7206: 1007206
+ 7207: 1007207
+ 7208: 1007208
+ 7209: 1007209
+ 7210: 1007210
+ 7211: 1007211
+ 7212: 1007212
+ 7213: 1007213
+ 7214: 1007214
+ 7215: 1007215
+ 7216: 1007216
+ 7217: 1007217
+ 7218: 1007218
+ 7219: 1007219
+ 7220: 1007220
+ 7221: 1007221
+ 7222: 1007222
+ 7223: 1007223
+ 7224: 1007224
+ 7225: 1007225
+ 7226: 1007226
+ 7227: 1007227
+ 7228: 1007228
+ 7229: 1007229
+ 7230: 1007230
+ 7231: 1007231
+ 7232: 1007232
+ 7233: 1007233
+ 7234: 1007234
+ 7235: 1007235
+ 7236: 1007236
+ 7237: 1007237
+ 7238: 1007238
+ 7239: 1007239
+ 7240: 1007240
+ 7241: 1007241
+ 7242: 1007242
+ 7243: 1007243
+ 7244: 1007244
+ 7245: 1007245
+ 7246: 1007246
+ 7247: 1007247
+ 7248: 1007248
+ 7249: 1007249
+ 7250: 1007250
+ 7251: 1007251
+ 7252: 1007252
+ 7253: 1007253
+ 7254: 1007254
+ 7255: 1007255
+ 7256: 1007256
+ 7257: 1007257
+ 7258: 1007258
+ 7259: 1007259
+ 7260: 1007260
+ 7261: 1007261
+ 7262: 1007262
+ 7263: 1007263
+ 7264: 1007264
+ 7265: 1007265
+ 7266: 1007266
+ 7267: 1007267
+ 7268: 1007268
+ 7269: 1007269
+ 7270: 1007270
+ 7271: 1007271
+ 7272: 1007272
+ 7273: 1007273
+ 7274: 1007274
+ 7275: 1007275
+ 7276: 1007276
+ 7277: 1007277
+ 7278: 1007278
+ 7279: 1007279
+ 7280: 1007280
+ 7281: 1007281
+ 7282: 1007282
+ 7283: 1007283
+ 7284: 1007284
+ 7285: 1007285
+ 7286: 1007286
+ 7287: 1007287
+ 7288: 1007288
+ 7289: 1007289
+ 7290: 1007290
+ 7291: 1007291
+ 7292: 1007292
+ 7293: 1007293
+ 7294: 1007294
+ 7295: 1007295
+ 7296: 1007296
+ 7297: 1007297
+ 7298: 1007298
+ 7299: 1007299
+ 7300: 1007300
+ 7301: 1007301
+ 7302: 1007302
+ 7303: 1007303
+ 7304: 1007304
+ 7305: 1007305
+ 7306: 1007306
+ 7307: 1007307
+ 7308: 1007308
+ 7309: 1007309
+ 7310: 1007310
+ 7311: 1007311
+ 7312: 1007312
+ 7313: 1007313
+ 7314: 1007314
+ 7315: 1007315
+ 7316: 1007316
+ 7317: 1007317
+ 7318: 1007318
+ 7319: 1007319
+ 7320: 1007320
+ 7321: 1007321
+ 7322: 1007322
+ 7323: 1007323
+ 7324: 1007324
+ 7325: 1007325
+ 7326: 1007326
+ 7327: 1007327
+ 7328: 1007328
+ 7329: 1007329
+ 7330: 1007330
+ 7331: 1007331
+ 7332: 1007332
+ 7333: 1007333
+ 7334: 1007334
+ 7335: 1007335
+ 7336: 1007336
+ 7337: 1007337
+ 7338: 1007338
+ 7339: 1007339
+ 7340: 1007340
+ 7341: 1007341
+ 7342: 1007342
+ 7343: 1007343
+ 7344: 1007344
+ 7345: 1007345
+ 7346: 1007346
+ 7347: 1007347
+ 7348: 1007348
+ 7349: 1007349
+ 7350: 1007350
+ 7351: 1007351
+ 7352: 1007352
+ 7353: 1007353
+ 7354: 1007354
+ 7355: 1007355
+ 7356: 1007356
+ 7357: 1007357
+ 7358: 1007358
+ 7359: 1007359
+ 7360: 1007360
+ 7361: 1007361
+ 7362: 1007362
+ 7363: 1007363
+ 7364: 1007364
+ 7365: 1007365
+ 7366: 1007366
+ 7367: 1007367
+ 7368: 1007368
+ 7369: 1007369
+ 7370: 1007370
+ 7371: 1007371
+ 7372: 1007372
+ 7373: 1007373
+ 7374: 1007374
+ 7375: 1007375
+ 7376: 1007376
+ 7377: 1007377
+ 7378: 1007378
+ 7379: 1007379
+ 7380: 1007380
+ 7381: 1007381
+ 7382: 1007382
+ 7383: 1007383
+ 7384: 1007384
+ 7385: 1007385
+ 7386: 1007386
+ 7387: 1007387
+ 7388: 1007388
+ 7389: 1007389
+ 7390: 1007390
+ 7391: 1007391
+ 7392: 1007392
+ 7393: 1007393
+ 7394: 1007394
+ 7395: 1007395
+ 7396: 1007396
+ 7397: 1007397
+ 7398: 1007398
+ 7399: 1007399
+ 7400: 1007400
+ 7401: 1007401
+ 7402: 1007402
+ 7403: 1007403
+ 7404: 1007404
+ 7405: 1007405
+ 7406: 1007406
+ 7407: 1007407
+ 7408: 1007408
+ 7409: 1007409
+ 7410: 1007410
+ 7411: 1007411
+ 7412: 1007412
+ 7413: 1007413
+ 7414: 1007414
+ 7415: 1007415
+ 7416: 1007416
+ 7417: 1007417
+ 7418: 1007418
+ 7419: 1007419
+ 7420: 1007420
+ 7421: 1007421
+ 7422: 1007422
+ 7423: 1007423
+ 7424: 1007424
+ 7425: 1007425
+ 7426: 1007426
+ 7427: 1007427
+ 7428: 1007428
+ 7429: 1007429
+ 7430: 1007430
+ 7431: 1007431
+ 7432: 1007432
+ 7433: 1007433
+ 7434: 1007434
+ 7435: 1007435
+ 7436: 1007436
+ 7437: 1007437
+ 7438: 1007438
+ 7439: 1007439
+ 7440: 1007440
+ 7441: 1007441
+ 7442: 1007442
+ 7443: 1007443
+ 7444: 1007444
+ 7445: 1007445
+ 7446: 1007446
+ 7447: 1007447
+ 7448: 1007448
+ 7449: 1007449
+ 7450: 1007450
+ 7451: 1007451
+ 7452: 1007452
+ 7453: 1007453
+ 7454: 1007454
+ 7455: 1007455
+ 7456: 1007456
+ 7457: 1007457
+ 7458: 1007458
+ 7459: 1007459
+ 7460: 1007460
+ 7461: 1007461
+ 7462: 1007462
+ 7463: 1007463
+ 7464: 1007464
+ 7465: 1007465
+ 7466: 1007466
+ 7467: 1007467
+ 7468: 1007468
+ 7469: 1007469
+ 7470: 1007470
+ 7471: 1007471
+ 7472: 1007472
+ 7473: 1007473
+ 7474: 1007474
+ 7475: 1007475
+ 7476: 1007476
+ 7477: 1007477
+ 7478: 1007478
+ 7479: 1007479
+ 7480: 1007480
+ 7481: 1007481
+ 7482: 1007482
+ 7483: 1007483
+ 7484: 1007484
+ 7485: 1007485
+ 7486: 1007486
+ 7487: 1007487
+ 7488: 1007488
+ 7489: 1007489
+ 7490: 1007490
+ 7491: 1007491
+ 7492: 1007492
+ 7493: 1007493
+ 7494: 1007494
+ 7495: 1007495
+ 7496: 1007496
+ 7497: 1007497
+ 7498: 1007498
+ 7499: 1007499
+ 7500: 1007500
+ 7501: 1007501
+ 7502: 1007502
+ 7503: 1007503
+ 7504: 1007504
+ 7505: 1007505
+ 7506: 1007506
+ 7507: 1007507
+ 7508: 1007508
+ 7509: 1007509
+ 7510: 1007510
+ 7511: 1007511
+ 7512: 1007512
+ 7513: 1007513
+ 7514: 1007514
+ 7515: 1007515
+ 7516: 1007516
+ 7517: 1007517
+ 7518: 1007518
+ 7519: 1007519
+ 7520: 1007520
+ 7521: 1007521
+ 7522: 1007522
+ 7523: 1007523
+ 7524: 1007524
+ 7525: 1007525
+ 7526: 1007526
+ 7527: 1007527
+ 7528: 1007528
+ 7529: 1007529
+ 7530: 1007530
+ 7531: 1007531
+ 7532: 1007532
+ 7533: 1007533
+ 7534: 1007534
+ 7535: 1007535
+ 7536: 1007536
+ 7537: 1007537
+ 7538: 1007538
+ 7539: 1007539
+ 7540: 1007540
+ 7541: 1007541
+ 7542: 1007542
+ 7543: 1007543
+ 7544: 1007544
+ 7545: 1007545
+ 7546: 1007546
+ 7547: 1007547
+ 7548: 1007548
+ 7549: 1007549
+ 7550: 1007550
+ 7551: 1007551
+ 7552: 1007552
+ 7553: 1007553
+ 7554: 1007554
+ 7555: 1007555
+ 7556: 1007556
+ 7557: 1007557
+ 7558: 1007558
+ 7559: 1007559
+ 7560: 1007560
+ 7561: 1007561
+ 7562: 1007562
+ 7563: 1007563
+ 7564: 1007564
+ 7565: 1007565
+ 7566: 1007566
+ 7567: 1007567
+ 7568: 1007568
+ 7569: 1007569
+ 7570: 1007570
+ 7571: 1007571
+ 7572: 1007572
+ 7573: 1007573
+ 7574: 1007574
+ 7575: 1007575
+ 7576: 1007576
+ 7577: 1007577
+ 7578: 1007578
+ 7579: 1007579
+ 7580: 1007580
+ 7581: 1007581
+ 7582: 1007582
+ 7583: 1007583
+ 7584: 1007584
+ 7585: 1007585
+ 7586: 1007586
+ 7587: 1007587
+ 7588: 1007588
+ 7589: 1007589
+ 7590: 1007590
+ 7591: 1007591
+ 7592: 1007592
+ 7593: 1007593
+ 7594: 1007594
+ 7595: 1007595
+ 7596: 1007596
+ 7597: 1007597
+ 7598: 1007598
+ 7599: 1007599
+ 7600: 1007600
+ 7601: 1007601
+ 7602: 1007602
+ 7603: 1007603
+ 7604: 1007604
+ 7605: 1007605
+ 7606: 1007606
+ 7607: 1007607
+ 7608: 1007608
+ 7609: 1007609
+ 7610: 1007610
+ 7611: 1007611
+ 7612: 1007612
+ 7613: 1007613
+ 7614: 1007614
+ 7615: 1007615
+ 7616: 1007616
+ 7617: 1007617
+ 7618: 1007618
+ 7619: 1007619
+ 7620: 1007620
+ 7621: 1007621
+ 7622: 1007622
+ 7623: 1007623
+ 7624: 1007624
+ 7625: 1007625
+ 7626: 1007626
+ 7627: 1007627
+ 7628: 1007628
+ 7629: 1007629
+ 7630: 1007630
+ 7631: 1007631
+ 7632: 1007632
+ 7633: 1007633
+ 7634: 1007634
+ 7635: 1007635
+ 7636: 1007636
+ 7637: 1007637
+ 7638: 1007638
+ 7639: 1007639
+ 7640: 1007640
+ 7641: 1007641
+ 7642: 1007642
+ 7643: 1007643
+ 7644: 1007644
+ 7645: 1007645
+ 7646: 1007646
+ 7647: 1007647
+ 7648: 1007648
+ 7649: 1007649
+ 7650: 1007650
+ 7651: 1007651
+ 7652: 1007652
+ 7653: 1007653
+ 7654: 1007654
+ 7655: 1007655
+ 7656: 1007656
+ 7657: 1007657
+ 7658: 1007658
+ 7659: 1007659
+ 7660: 1007660
+ 7661: 1007661
+ 7662: 1007662
+ 7663: 1007663
+ 7664: 1007664
+ 7665: 1007665
+ 7666: 1007666
+ 7667: 1007667
+ 7668: 1007668
+ 7669: 1007669
+ 7670: 1007670
+ 7671: 1007671
+ 7672: 1007672
+ 7673: 1007673
+ 7674: 1007674
+ 7675: 1007675
+ 7676: 1007676
+ 7677: 1007677
+ 7678: 1007678
+ 7679: 1007679
+ 7680: 1007680
+ 7681: 1007681
+ 7682: 1007682
+ 7683: 1007683
+ 7684: 1007684
+ 7685: 1007685
+ 7686: 1007686
+ 7687: 1007687
+ 7688: 1007688
+ 7689: 1007689
+ 7690: 1007690
+ 7691: 1007691
+ 7692: 1007692
+ 7693: 1007693
+ 7694: 1007694
+ 7695: 1007695
+ 7696: 1007696
+ 7697: 1007697
+ 7698: 1007698
+ 7699: 1007699
+ 7700: 1007700
+ 7701: 1007701
+ 7702: 1007702
+ 7703: 1007703
+ 7704: 1007704
+ 7705: 1007705
+ 7706: 1007706
+ 7707: 1007707
+ 7708: 1007708
+ 7709: 1007709
+ 7710: 1007710
+ 7711: 1007711
+ 7712: 1007712
+ 7713: 1007713
+ 7714: 1007714
+ 7715: 1007715
+ 7716: 1007716
+ 7717: 1007717
+ 7718: 1007718
+ 7719: 1007719
+ 7720: 1007720
+ 7721: 1007721
+ 7722: 1007722
+ 7723: 1007723
+ 7724: 1007724
+ 7725: 1007725
+ 7726: 1007726
+ 7727: 1007727
+ 7728: 1007728
+ 7729: 1007729
+ 7730: 1007730
+ 7731: 1007731
+ 7732: 1007732
+ 7733: 1007733
+ 7734: 1007734
+ 7735: 1007735
+ 7736: 1007736
+ 7737: 1007737
+ 7738: 1007738
+ 7739: 1007739
+ 7740: 1007740
+ 7741: 1007741
+ 7742: 1007742
+ 7743: 1007743
+ 7744: 1007744
+ 7745: 1007745
+ 7746: 1007746
+ 7747: 1007747
+ 7748: 1007748
+ 7749: 1007749
+ 7750: 1007750
+ 7751: 1007751
+ 7752: 1007752
+ 7753: 1007753
+ 7754: 1007754
+ 7755: 1007755
+ 7756: 1007756
+ 7757: 1007757
+ 7758: 1007758
+ 7759: 1007759
+ 7760: 1007760
+ 7761: 1007761
+ 7762: 1007762
+ 7763: 1007763
+ 7764: 1007764
+ 7765: 1007765
+ 7766: 1007766
+ 7767: 1007767
+ 7768: 1007768
+ 7769: 1007769
+ 7770: 1007770
+ 7771: 1007771
+ 7772: 1007772
+ 7773: 1007773
+ 7774: 1007774
+ 7775: 1007775
+ 7776: 1007776
+ 7777: 1007777
+ 7778: 1007778
+ 7779: 1007779
+ 7780: 1007780
+ 7781: 1007781
+ 7782: 1007782
+ 7783: 1007783
+ 7784: 1007784
+ 7785: 1007785
+ 7786: 1007786
+ 7787: 1007787
+ 7788: 1007788
+ 7789: 1007789
+ 7790: 1007790
+ 7791: 1007791
+ 7792: 1007792
+ 7793: 1007793
+ 7794: 1007794
+ 7795: 1007795
+ 7796: 1007796
+ 7797: 1007797
+ 7798: 1007798
+ 7799: 1007799
+ 7800: 1007800
+ 7801: 1007801
+ 7802: 1007802
+ 7803: 1007803
+ 7804: 1007804
+ 7805: 1007805
+ 7806: 1007806
+ 7807: 1007807
+ 7808: 1007808
+ 7809: 1007809
+ 7810: 1007810
+ 7811: 1007811
+ 7812: 1007812
+ 7813: 1007813
+ 7814: 1007814
+ 7815: 1007815
+ 7816: 1007816
+ 7817: 1007817
+ 7818: 1007818
+ 7819: 1007819
+ 7820: 1007820
+ 7821: 1007821
+ 7822: 1007822
+ 7823: 1007823
+ 7824: 1007824
+ 7825: 1007825
+ 7826: 1007826
+ 7827: 1007827
+ 7828: 1007828
+ 7829: 1007829
+ 7830: 1007830
+ 7831: 1007831
+ 7832: 1007832
+ 7833: 1007833
+ 7834: 1007834
+ 7835: 1007835
+ 7836: 1007836
+ 7837: 1007837
+ 7838: 1007838
+ 7839: 1007839
+ 7840: 1007840
+ 7841: 1007841
+ 7842: 1007842
+ 7843: 1007843
+ 7844: 1007844
+ 7845: 1007845
+ 7846: 1007846
+ 7847: 1007847
+ 7848: 1007848
+ 7849: 1007849
+ 7850: 1007850
+ 7851: 1007851
+ 7852: 1007852
+ 7853: 1007853
+ 7854: 1007854
+ 7855: 1007855
+ 7856: 1007856
+ 7857: 1007857
+ 7858: 1007858
+ 7859: 1007859
+ 7860: 1007860
+ 7861: 1007861
+ 7862: 1007862
+ 7863: 1007863
+ 7864: 1007864
+ 7865: 1007865
+ 7866: 1007866
+ 7867: 1007867
+ 7868: 1007868
+ 7869: 1007869
+ 7870: 1007870
+ 7871: 1007871
+ 7872: 1007872
+ 7873: 1007873
+ 7874: 1007874
+ 7875: 1007875
+ 7876: 1007876
+ 7877: 1007877
+ 7878: 1007878
+ 7879: 1007879
+ 7880: 1007880
+ 7881: 1007881
+ 7882: 1007882
+ 7883: 1007883
+ 7884: 1007884
+ 7885: 1007885
+ 7886: 1007886
+ 7887: 1007887
+ 7888: 1007888
+ 7889: 1007889
+ 7890: 1007890
+ 7891: 1007891
+ 7892: 1007892
+ 7893: 1007893
+ 7894: 1007894
+ 7895: 1007895
+ 7896: 1007896
+ 7897: 1007897
+ 7898: 1007898
+ 7899: 1007899
+ 7900: 1007900
+ 7901: 1007901
+ 7902: 1007902
+ 7903: 1007903
+ 7904: 1007904
+ 7905: 1007905
+ 7906: 1007906
+ 7907: 1007907
+ 7908: 1007908
+ 7909: 1007909
+ 7910: 1007910
+ 7911: 1007911
+ 7912: 1007912
+ 7913: 1007913
+ 7914: 1007914
+ 7915: 1007915
+ 7916: 1007916
+ 7917: 1007917
+ 7918: 1007918
+ 7919: 1007919
+ 7920: 1007920
+ 7921: 1007921
+ 7922: 1007922
+ 7923: 1007923
+ 7924: 1007924
+ 7925: 1007925
+ 7926: 1007926
+ 7927: 1007927
+ 7928: 1007928
+ 7929: 1007929
+ 7930: 1007930
+ 7931: 1007931
+ 7932: 1007932
+ 7933: 1007933
+ 7934: 1007934
+ 7935: 1007935
+ 7936: 1007936
+ 7937: 1007937
+ 7938: 1007938
+ 7939: 1007939
+ 7940: 1007940
+ 7941: 1007941
+ 7942: 1007942
+ 7943: 1007943
+ 7944: 1007944
+ 7945: 1007945
+ 7946: 1007946
+ 7947: 1007947
+ 7948: 1007948
+ 7949: 1007949
+ 7950: 1007950
+ 7951: 1007951
+ 7952: 1007952
+ 7953: 1007953
+ 7954: 1007954
+ 7955: 1007955
+ 7956: 1007956
+ 7957: 1007957
+ 7958: 1007958
+ 7959: 1007959
+ 7960: 1007960
+ 7961: 1007961
+ 7962: 1007962
+ 7963: 1007963
+ 7964: 1007964
+ 7965: 1007965
+ 7966: 1007966
+ 7967: 1007967
+ 7968: 1007968
+ 7969: 1007969
+ 7970: 1007970
+ 7971: 1007971
+ 7972: 1007972
+ 7973: 1007973
+ 7974: 1007974
+ 7975: 1007975
+ 7976: 1007976
+ 7977: 1007977
+ 7978: 1007978
+ 7979: 1007979
+ 7980: 1007980
+ 7981: 1007981
+ 7982: 1007982
+ 7983: 1007983
+ 7984: 1007984
+ 7985: 1007985
+ 7986: 1007986
+ 7987: 1007987
+ 7988: 1007988
+ 7989: 1007989
+ 7990: 1007990
+ 7991: 1007991
+ 7992: 1007992
+ 7993: 1007993
+ 7994: 1007994
+ 7995: 1007995
+ 7996: 1007996
+ 7997: 1007997
+ 7998: 1007998
+ 7999: 1007999
+ 8000: 1008000
+ 8001: 1008001
+ 8002: 1008002
+ 8003: 1008003
+ 8004: 1008004
+ 8005: 1008005
+ 8006: 1008006
+ 8007: 1008007
+ 8008: 1008008
+ 8009: 1008009
+ 8010: 1008010
+ 8011: 1008011
+ 8012: 1008012
+ 8013: 1008013
+ 8014: 1008014
+ 8015: 1008015
+ 8016: 1008016
+ 8017: 1008017
+ 8018: 1008018
+ 8019: 1008019
+ 8020: 1008020
+ 8021: 1008021
+ 8022: 1008022
+ 8023: 1008023
+ 8024: 1008024
+ 8025: 1008025
+ 8026: 1008026
+ 8027: 1008027
+ 8028: 1008028
+ 8029: 1008029
+ 8030: 1008030
+ 8031: 1008031
+ 8032: 1008032
+ 8033: 1008033
+ 8034: 1008034
+ 8035: 1008035
+ 8036: 1008036
+ 8037: 1008037
+ 8038: 1008038
+ 8039: 1008039
+ 8040: 1008040
+ 8041: 1008041
+ 8042: 1008042
+ 8043: 1008043
+ 8044: 1008044
+ 8045: 1008045
+ 8046: 1008046
+ 8047: 1008047
+ 8048: 1008048
+ 8049: 1008049
+ 8050: 1008050
+ 8051: 1008051
+ 8052: 1008052
+ 8053: 1008053
+ 8054: 1008054
+ 8055: 1008055
+ 8056: 1008056
+ 8057: 1008057
+ 8058: 1008058
+ 8059: 1008059
+ 8060: 1008060
+ 8061: 1008061
+ 8062: 1008062
+ 8063: 1008063
+ 8064: 1008064
+ 8065: 1008065
+ 8066: 1008066
+ 8067: 1008067
+ 8068: 1008068
+ 8069: 1008069
+ 8070: 1008070
+ 8071: 1008071
+ 8072: 1008072
+ 8073: 1008073
+ 8074: 1008074
+ 8075: 1008075
+ 8076: 1008076
+ 8077: 1008077
+ 8078: 1008078
+ 8079: 1008079
+ 8080: 1008080
+ 8081: 1008081
+ 8082: 1008082
+ 8083: 1008083
+ 8084: 1008084
+ 8085: 1008085
+ 8086: 1008086
+ 8087: 1008087
+ 8088: 1008088
+ 8089: 1008089
+ 8090: 1008090
+ 8091: 1008091
+ 8092: 1008092
+ 8093: 1008093
+ 8094: 1008094
+ 8095: 1008095
+ 8096: 1008096
+ 8097: 1008097
+ 8098: 1008098
+ 8099: 1008099
+ 8100: 1008100
+ 8101: 1008101
+ 8102: 1008102
+ 8103: 1008103
+ 8104: 1008104
+ 8105: 1008105
+ 8106: 1008106
+ 8107: 1008107
+ 8108: 1008108
+ 8109: 1008109
+ 8110: 1008110
+ 8111: 1008111
+ 8112: 1008112
+ 8113: 1008113
+ 8114: 1008114
+ 8115: 1008115
+ 8116: 1008116
+ 8117: 1008117
+ 8118: 1008118
+ 8119: 1008119
+ 8120: 1008120
+ 8121: 1008121
+ 8122: 1008122
+ 8123: 1008123
+ 8124: 1008124
+ 8125: 1008125
+ 8126: 1008126
+ 8127: 1008127
+ 8128: 1008128
+ 8129: 1008129
+ 8130: 1008130
+ 8131: 1008131
+ 8132: 1008132
+ 8133: 1008133
+ 8134: 1008134
+ 8135: 1008135
+ 8136: 1008136
+ 8137: 1008137
+ 8138: 1008138
+ 8139: 1008139
+ 8140: 1008140
+ 8141: 1008141
+ 8142: 1008142
+ 8143: 1008143
+ 8144: 1008144
+ 8145: 1008145
+ 8146: 1008146
+ 8147: 1008147
+ 8148: 1008148
+ 8149: 1008149
+ 8150: 1008150
+ 8151: 1008151
+ 8152: 1008152
+ 8153: 1008153
+ 8154: 1008154
+ 8155: 1008155
+ 8156: 1008156
+ 8157: 1008157
+ 8158: 1008158
+ 8159: 1008159
+ 8160: 1008160
+ 8161: 1008161
+ 8162: 1008162
+ 8163: 1008163
+ 8164: 1008164
+ 8165: 1008165
+ 8166: 1008166
+ 8167: 1008167
+ 8168: 1008168
+ 8169: 1008169
+ 8170: 1008170
+ 8171: 1008171
+ 8172: 1008172
+ 8173: 1008173
+ 8174: 1008174
+ 8175: 1008175
+ 8176: 1008176
+ 8177: 1008177
+ 8178: 1008178
+ 8179: 1008179
+ 8180: 1008180
+ 8181: 1008181
+ 8182: 1008182
+ 8183: 1008183
+ 8184: 1008184
+ 8185: 1008185
+ 8186: 1008186
+ 8187: 1008187
+ 8188: 1008188
+ 8189: 1008189
+ 8190: 1008190
+ 8191: 1008191
+ 8192: 1008192
+ 8193: 1008193
+ 8194: 1008194
+ 8195: 1008195
+ 8196: 1008196
+ 8197: 1008197
+ 8198: 1008198
+ 8199: 1008199
+ 8200: 1008200
+ 8201: 1008201
+ 8202: 1008202
+ 8203: 1008203
+ 8204: 1008204
+ 8205: 1008205
+ 8206: 1008206
+ 8207: 1008207
+ 8208: 1008208
+ 8209: 1008209
+ 8210: 1008210
+ 8211: 1008211
+ 8212: 1008212
+ 8213: 1008213
+ 8214: 1008214
+ 8215: 1008215
+ 8216: 1008216
+ 8217: 1008217
+ 8218: 1008218
+ 8219: 1008219
+ 8220: 1008220
+ 8221: 1008221
+ 8222: 1008222
+ 8223: 1008223
+ 8224: 1008224
+ 8225: 1008225
+ 8226: 1008226
+ 8227: 1008227
+ 8228: 1008228
+ 8229: 1008229
+ 8230: 1008230
+ 8231: 1008231
+ 8232: 1008232
+ 8233: 1008233
+ 8234: 1008234
+ 8235: 1008235
+ 8236: 1008236
+ 8237: 1008237
+ 8238: 1008238
+ 8239: 1008239
+ 8240: 1008240
+ 8241: 1008241
+ 8242: 1008242
+ 8243: 1008243
+ 8244: 1008244
+ 8245: 1008245
+ 8246: 1008246
+ 8247: 1008247
+ 8248: 1008248
+ 8249: 1008249
+ 8250: 1008250
+ 8251: 1008251
+ 8252: 1008252
+ 8253: 1008253
+ 8254: 1008254
+ 8255: 1008255
+ 8256: 1008256
+ 8257: 1008257
+ 8258: 1008258
+ 8259: 1008259
+ 8260: 1008260
+ 8261: 1008261
+ 8262: 1008262
+ 8263: 1008263
+ 8264: 1008264
+ 8265: 1008265
+ 8266: 1008266
+ 8267: 1008267
+ 8268: 1008268
+ 8269: 1008269
+ 8270: 1008270
+ 8271: 1008271
+ 8272: 1008272
+ 8273: 1008273
+ 8274: 1008274
+ 8275: 1008275
+ 8276: 1008276
+ 8277: 1008277
+ 8278: 1008278
+ 8279: 1008279
+ 8280: 1008280
+ 8281: 1008281
+ 8282: 1008282
+ 8283: 1008283
+ 8284: 1008284
+ 8285: 1008285
+ 8286: 1008286
+ 8287: 1008287
+ 8288: 1008288
+ 8289: 1008289
+ 8290: 1008290
+ 8291: 1008291
+ 8292: 1008292
+ 8293: 1008293
+ 8294: 1008294
+ 8295: 1008295
+ 8296: 1008296
+ 8297: 1008297
+ 8298: 1008298
+ 8299: 1008299
+ 8300: 1008300
+ 8301: 1008301
+ 8302: 1008302
+ 8303: 1008303
+ 8304: 1008304
+ 8305: 1008305
+ 8306: 1008306
+ 8307: 1008307
+ 8308: 1008308
+ 8309: 1008309
+ 8310: 1008310
+ 8311: 1008311
+ 8312: 1008312
+ 8313: 1008313
+ 8314: 1008314
+ 8315: 1008315
+ 8316: 1008316
+ 8317: 1008317
+ 8318: 1008318
+ 8319: 1008319
+ 8320: 1008320
+ 8321: 1008321
+ 8322: 1008322
+ 8323: 1008323
+ 8324: 1008324
+ 8325: 1008325
+ 8326: 1008326
+ 8327: 1008327
+ 8328: 1008328
+ 8329: 1008329
+ 8330: 1008330
+ 8331: 1008331
+ 8332: 1008332
+ 8333: 1008333
+ 8334: 1008334
+ 8335: 1008335
+ 8336: 1008336
+ 8337: 1008337
+ 8338: 1008338
+ 8339: 1008339
+ 8340: 1008340
+ 8341: 1008341
+ 8342: 1008342
+ 8343: 1008343
+ 8344: 1008344
+ 8345: 1008345
+ 8346: 1008346
+ 8347: 1008347
+ 8348: 1008348
+ 8349: 1008349
+ 8350: 1008350
+ 8351: 1008351
+ 8352: 1008352
+ 8353: 1008353
+ 8354: 1008354
+ 8355: 1008355
+ 8356: 1008356
+ 8357: 1008357
+ 8358: 1008358
+ 8359: 1008359
+ 8360: 1008360
+ 8361: 1008361
+ 8362: 1008362
+ 8363: 1008363
+ 8364: 1008364
+ 8365: 1008365
+ 8366: 1008366
+ 8367: 1008367
+ 8368: 1008368
+ 8369: 1008369
+ 8370: 1008370
+ 8371: 1008371
+ 8372: 1008372
+ 8373: 1008373
+ 8374: 1008374
+ 8375: 1008375
+ 8376: 1008376
+ 8377: 1008377
+ 8378: 1008378
+ 8379: 1008379
+ 8380: 1008380
+ 8381: 1008381
+ 8382: 1008382
+ 8383: 1008383
+ 8384: 1008384
+ 8385: 1008385
+ 8386: 1008386
+ 8387: 1008387
+ 8388: 1008388
+ 8389: 1008389
+ 8390: 1008390
+ 8391: 1008391
+ 8392: 1008392
+ 8393: 1008393
+ 8394: 1008394
+ 8395: 1008395
+ 8396: 1008396
+ 8397: 1008397
+ 8398: 1008398
+ 8399: 1008399
+ 8400: 1008400
+ 8401: 1008401
+ 8402: 1008402
+ 8403: 1008403
+ 8404: 1008404
+ 8405: 1008405
+ 8406: 1008406
+ 8407: 1008407
+ 8408: 1008408
+ 8409: 1008409
+ 8410: 1008410
+ 8411: 1008411
+ 8412: 1008412
+ 8413: 1008413
+ 8414: 1008414
+ 8415: 1008415
+ 8416: 1008416
+ 8417: 1008417
+ 8418: 1008418
+ 8419: 1008419
+ 8420: 1008420
+ 8421: 1008421
+ 8422: 1008422
+ 8423: 1008423
+ 8424: 1008424
+ 8425: 1008425
+ 8426: 1008426
+ 8427: 1008427
+ 8428: 1008428
+ 8429: 1008429
+ 8430: 1008430
+ 8431: 1008431
+ 8432: 1008432
+ 8433: 1008433
+ 8434: 1008434
+ 8435: 1008435
+ 8436: 1008436
+ 8437: 1008437
+ 8438: 1008438
+ 8439: 1008439
+ 8440: 1008440
+ 8441: 1008441
+ 8442: 1008442
+ 8443: 1008443
+ 8444: 1008444
+ 8445: 1008445
+ 8446: 1008446
+ 8447: 1008447
+ 8448: 1008448
+ 8449: 1008449
+ 8450: 1008450
+ 8451: 1008451
+ 8452: 1008452
+ 8453: 1008453
+ 8454: 1008454
+ 8455: 1008455
+ 8456: 1008456
+ 8457: 1008457
+ 8458: 1008458
+ 8459: 1008459
+ 8460: 1008460
+ 8461: 1008461
+ 8462: 1008462
+ 8463: 1008463
+ 8464: 1008464
+ 8465: 1008465
+ 8466: 1008466
+ 8467: 1008467
+ 8468: 1008468
+ 8469: 1008469
+ 8470: 1008470
+ 8471: 1008471
+ 8472: 1008472
+ 8473: 1008473
+ 8474: 1008474
+ 8475: 1008475
+ 8476: 1008476
+ 8477: 1008477
+ 8478: 1008478
+ 8479: 1008479
+ 8480: 1008480
+ 8481: 1008481
+ 8482: 1008482
+ 8483: 1008483
+ 8484: 1008484
+ 8485: 1008485
+ 8486: 1008486
+ 8487: 1008487
+ 8488: 1008488
+ 8489: 1008489
+ 8490: 1008490
+ 8491: 1008491
+ 8492: 1008492
+ 8493: 1008493
+ 8494: 1008494
+ 8495: 1008495
+ 8496: 1008496
+ 8497: 1008497
+ 8498: 1008498
+ 8499: 1008499
+ 8500: 1008500
+ 8501: 1008501
+ 8502: 1008502
+ 8503: 1008503
+ 8504: 1008504
+ 8505: 1008505
+ 8506: 1008506
+ 8507: 1008507
+ 8508: 1008508
+ 8509: 1008509
+ 8510: 1008510
+ 8511: 1008511
+ 8512: 1008512
+ 8513: 1008513
+ 8514: 1008514
+ 8515: 1008515
+ 8516: 1008516
+ 8517: 1008517
+ 8518: 1008518
+ 8519: 1008519
+ 8520: 1008520
+ 8521: 1008521
+ 8522: 1008522
+ 8523: 1008523
+ 8524: 1008524
+ 8525: 1008525
+ 8526: 1008526
+ 8527: 1008527
+ 8528: 1008528
+ 8529: 1008529
+ 8530: 1008530
+ 8531: 1008531
+ 8532: 1008532
+ 8533: 1008533
+ 8534: 1008534
+ 8535: 1008535
+ 8536: 1008536
+ 8537: 1008537
+ 8538: 1008538
+ 8539: 1008539
+ 8540: 1008540
+ 8541: 1008541
+ 8542: 1008542
+ 8543: 1008543
+ 8544: 1008544
+ 8545: 1008545
+ 8546: 1008546
+ 8547: 1008547
+ 8548: 1008548
+ 8549: 1008549
+ 8550: 1008550
+ 8551: 1008551
+ 8552: 1008552
+ 8553: 1008553
+ 8554: 1008554
+ 8555: 1008555
+ 8556: 1008556
+ 8557: 1008557
+ 8558: 1008558
+ 8559: 1008559
+ 8560: 1008560
+ 8561: 1008561
+ 8562: 1008562
+ 8563: 1008563
+ 8564: 1008564
+ 8565: 1008565
+ 8566: 1008566
+ 8567: 1008567
+ 8568: 1008568
+ 8569: 1008569
+ 8570: 1008570
+ 8571: 1008571
+ 8572: 1008572
+ 8573: 1008573
+ 8574: 1008574
+ 8575: 1008575
+ 8576: 1008576
+ 8577: 1008577
+ 8578: 1008578
+ 8579: 1008579
+ 8580: 1008580
+ 8581: 1008581
+ 8582: 1008582
+ 8583: 1008583
+ 8584: 1008584
+ 8585: 1008585
+ 8586: 1008586
+ 8587: 1008587
+ 8588: 1008588
+ 8589: 1008589
+ 8590: 1008590
+ 8591: 1008591
+ 8592: 1008592
+ 8593: 1008593
+ 8594: 1008594
+ 8595: 1008595
+ 8596: 1008596
+ 8597: 1008597
+ 8598: 1008598
+ 8599: 1008599
+ 8600: 1008600
+ 8601: 1008601
+ 8602: 1008602
+ 8603: 1008603
+ 8604: 1008604
+ 8605: 1008605
+ 8606: 1008606
+ 8607: 1008607
+ 8608: 1008608
+ 8609: 1008609
+ 8610: 1008610
+ 8611: 1008611
+ 8612: 1008612
+ 8613: 1008613
+ 8614: 1008614
+ 8615: 1008615
+ 8616: 1008616
+ 8617: 1008617
+ 8618: 1008618
+ 8619: 1008619
+ 8620: 1008620
+ 8621: 1008621
+ 8622: 1008622
+ 8623: 1008623
+ 8624: 1008624
+ 8625: 1008625
+ 8626: 1008626
+ 8627: 1008627
+ 8628: 1008628
+ 8629: 1008629
+ 8630: 1008630
+ 8631: 1008631
+ 8632: 1008632
+ 8633: 1008633
+ 8634: 1008634
+ 8635: 1008635
+ 8636: 1008636
+ 8637: 1008637
+ 8638: 1008638
+ 8639: 1008639
+ 8640: 1008640
+ 8641: 1008641
+ 8642: 1008642
+ 8643: 1008643
+ 8644: 1008644
+ 8645: 1008645
+ 8646: 1008646
+ 8647: 1008647
+ 8648: 1008648
+ 8649: 1008649
+ 8650: 1008650
+ 8651: 1008651
+ 8652: 1008652
+ 8653: 1008653
+ 8654: 1008654
+ 8655: 1008655
+ 8656: 1008656
+ 8657: 1008657
+ 8658: 1008658
+ 8659: 1008659
+ 8660: 1008660
+ 8661: 1008661
+ 8662: 1008662
+ 8663: 1008663
+ 8664: 1008664
+ 8665: 1008665
+ 8666: 1008666
+ 8667: 1008667
+ 8668: 1008668
+ 8669: 1008669
+ 8670: 1008670
+ 8671: 1008671
+ 8672: 1008672
+ 8673: 1008673
+ 8674: 1008674
+ 8675: 1008675
+ 8676: 1008676
+ 8677: 1008677
+ 8678: 1008678
+ 8679: 1008679
+ 8680: 1008680
+ 8681: 1008681
+ 8682: 1008682
+ 8683: 1008683
+ 8684: 1008684
+ 8685: 1008685
+ 8686: 1008686
+ 8687: 1008687
+ 8688: 1008688
+ 8689: 1008689
+ 8690: 1008690
+ 8691: 1008691
+ 8692: 1008692
+ 8693: 1008693
+ 8694: 1008694
+ 8695: 1008695
+ 8696: 1008696
+ 8697: 1008697
+ 8698: 1008698
+ 8699: 1008699
+ 8700: 1008700
+ 8701: 1008701
+ 8702: 1008702
+ 8703: 1008703
+ 8704: 1008704
+ 8705: 1008705
+ 8706: 1008706
+ 8707: 1008707
+ 8708: 1008708
+ 8709: 1008709
+ 8710: 1008710
+ 8711: 1008711
+ 8712: 1008712
+ 8713: 1008713
+ 8714: 1008714
+ 8715: 1008715
+ 8716: 1008716
+ 8717: 1008717
+ 8718: 1008718
+ 8719: 1008719
+ 8720: 1008720
+ 8721: 1008721
+ 8722: 1008722
+ 8723: 1008723
+ 8724: 1008724
+ 8725: 1008725
+ 8726: 1008726
+ 8727: 1008727
+ 8728: 1008728
+ 8729: 1008729
+ 8730: 1008730
+ 8731: 1008731
+ 8732: 1008732
+ 8733: 1008733
+ 8734: 1008734
+ 8735: 1008735
+ 8736: 1008736
+ 8737: 1008737
+ 8738: 1008738
+ 8739: 1008739
+ 8740: 1008740
+ 8741: 1008741
+ 8742: 1008742
+ 8743: 1008743
+ 8744: 1008744
+ 8745: 1008745
+ 8746: 1008746
+ 8747: 1008747
+ 8748: 1008748
+ 8749: 1008749
+ 8750: 1008750
+ 8751: 1008751
+ 8752: 1008752
+ 8753: 1008753
+ 8754: 1008754
+ 8755: 1008755
+ 8756: 1008756
+ 8757: 1008757
+ 8758: 1008758
+ 8759: 1008759
+ 8760: 1008760
+ 8761: 1008761
+ 8762: 1008762
+ 8763: 1008763
+ 8764: 1008764
+ 8765: 1008765
+ 8766: 1008766
+ 8767: 1008767
+ 8768: 1008768
+ 8769: 1008769
+ 8770: 1008770
+ 8771: 1008771
+ 8772: 1008772
+ 8773: 1008773
+ 8774: 1008774
+ 8775: 1008775
+ 8776: 1008776
+ 8777: 1008777
+ 8778: 1008778
+ 8779: 1008779
+ 8780: 1008780
+ 8781: 1008781
+ 8782: 1008782
+ 8783: 1008783
+ 8784: 1008784
+ 8785: 1008785
+ 8786: 1008786
+ 8787: 1008787
+ 8788: 1008788
+ 8789: 1008789
+ 8790: 1008790
+ 8791: 1008791
+ 8792: 1008792
+ 8793: 1008793
+ 8794: 1008794
+ 8795: 1008795
+ 8796: 1008796
+ 8797: 1008797
+ 8798: 1008798
+ 8799: 1008799
+ 8800: 1008800
+ 8801: 1008801
+ 8802: 1008802
+ 8803: 1008803
+ 8804: 1008804
+ 8805: 1008805
+ 8806: 1008806
+ 8807: 1008807
+ 8808: 1008808
+ 8809: 1008809
+ 8810: 1008810
+ 8811: 1008811
+ 8812: 1008812
+ 8813: 1008813
+ 8814: 1008814
+ 8815: 1008815
+ 8816: 1008816
+ 8817: 1008817
+ 8818: 1008818
+ 8819: 1008819
+ 8820: 1008820
+ 8821: 1008821
+ 8822: 1008822
+ 8823: 1008823
+ 8824: 1008824
+ 8825: 1008825
+ 8826: 1008826
+ 8827: 1008827
+ 8828: 1008828
+ 8829: 1008829
+ 8830: 1008830
+ 8831: 1008831
+ 8832: 1008832
+ 8833: 1008833
+ 8834: 1008834
+ 8835: 1008835
+ 8836: 1008836
+ 8837: 1008837
+ 8838: 1008838
+ 8839: 1008839
+ 8840: 1008840
+ 8841: 1008841
+ 8842: 1008842
+ 8843: 1008843
+ 8844: 1008844
+ 8845: 1008845
+ 8846: 1008846
+ 8847: 1008847
+ 8848: 1008848
+ 8849: 1008849
+ 8850: 1008850
+ 8851: 1008851
+ 8852: 1008852
+ 8853: 1008853
+ 8854: 1008854
+ 8855: 1008855
+ 8856: 1008856
+ 8857: 1008857
+ 8858: 1008858
+ 8859: 1008859
+ 8860: 1008860
+ 8861: 1008861
+ 8862: 1008862
+ 8863: 1008863
+ 8864: 1008864
+ 8865: 1008865
+ 8866: 1008866
+ 8867: 1008867
+ 8868: 1008868
+ 8869: 1008869
+ 8870: 1008870
+ 8871: 1008871
+ 8872: 1008872
+ 8873: 1008873
+ 8874: 1008874
+ 8875: 1008875
+ 8876: 1008876
+ 8877: 1008877
+ 8878: 1008878
+ 8879: 1008879
+ 8880: 1008880
+ 8881: 1008881
+ 8882: 1008882
+ 8883: 1008883
+ 8884: 1008884
+ 8885: 1008885
+ 8886: 1008886
+ 8887: 1008887
+ 8888: 1008888
+ 8889: 1008889
+ 8890: 1008890
+ 8891: 1008891
+ 8892: 1008892
+ 8893: 1008893
+ 8894: 1008894
+ 8895: 1008895
+ 8896: 1008896
+ 8897: 1008897
+ 8898: 1008898
+ 8899: 1008899
+ 8900: 1008900
+ 8901: 1008901
+ 8902: 1008902
+ 8903: 1008903
+ 8904: 1008904
+ 8905: 1008905
+ 8906: 1008906
+ 8907: 1008907
+ 8908: 1008908
+ 8909: 1008909
+ 8910: 1008910
+ 8911: 1008911
+ 8912: 1008912
+ 8913: 1008913
+ 8914: 1008914
+ 8915: 1008915
+ 8916: 1008916
+ 8917: 1008917
+ 8918: 1008918
+ 8919: 1008919
+ 8920: 1008920
+ 8921: 1008921
+ 8922: 1008922
+ 8923: 1008923
+ 8924: 1008924
+ 8925: 1008925
+ 8926: 1008926
+ 8927: 1008927
+ 8928: 1008928
+ 8929: 1008929
+ 8930: 1008930
+ 8931: 1008931
+ 8932: 1008932
+ 8933: 1008933
+ 8934: 1008934
+ 8935: 1008935
+ 8936: 1008936
+ 8937: 1008937
+ 8938: 1008938
+ 8939: 1008939
+ 8940: 1008940
+ 8941: 1008941
+ 8942: 1008942
+ 8943: 1008943
+ 8944: 1008944
+ 8945: 1008945
+ 8946: 1008946
+ 8947: 1008947
+ 8948: 1008948
+ 8949: 1008949
+ 8950: 1008950
+ 8951: 1008951
+ 8952: 1008952
+ 8953: 1008953
+ 8954: 1008954
+ 8955: 1008955
+ 8956: 1008956
+ 8957: 1008957
+ 8958: 1008958
+ 8959: 1008959
+ 8960: 1008960
+ 8961: 1008961
+ 8962: 1008962
+ 8963: 1008963
+ 8964: 1008964
+ 8965: 1008965
+ 8966: 1008966
+ 8967: 1008967
+ 8968: 1008968
+ 8969: 1008969
+ 8970: 1008970
+ 8971: 1008971
+ 8972: 1008972
+ 8973: 1008973
+ 8974: 1008974
+ 8975: 1008975
+ 8976: 1008976
+ 8977: 1008977
+ 8978: 1008978
+ 8979: 1008979
+ 8980: 1008980
+ 8981: 1008981
+ 8982: 1008982
+ 8983: 1008983
+ 8984: 1008984
+ 8985: 1008985
+ 8986: 1008986
+ 8987: 1008987
+ 8988: 1008988
+ 8989: 1008989
+ 8990: 1008990
+ 8991: 1008991
+ 8992: 1008992
+ 8993: 1008993
+ 8994: 1008994
+ 8995: 1008995
+ 8996: 1008996
+ 8997: 1008997
+ 8998: 1008998
+ 8999: 1008999
diff --git a/akregator/src/mk4storage/metakit/tests/ok/l02.txt b/akregator/src/mk4storage/metakit/tests/ok/l02.txt
new file mode 100644
index 000000000..a1bd366e9
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/l02.txt
@@ -0,0 +1,2 @@
+>>> Over 64 Kb of strings
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/l02a.txt b/akregator/src/mk4storage/metakit/tests/ok/l02a.txt
new file mode 100644
index 000000000..133662334
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/l02a.txt
@@ -0,0 +1,3503 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 3500 rows = p1:S
+ 0: 'Alice in Wonderland'
+ 1: 'The wizard of Oz'
+ 2: 'I'm singin' in the rain'
+ 3: 'Alice in Wonderland'
+ 4: 'The wizard of Oz'
+ 5: 'I'm singin' in the rain'
+ 6: 'Alice in Wonderland'
+ 7: 'The wizard of Oz'
+ 8: 'I'm singin' in the rain'
+ 9: 'Alice in Wonderland'
+ 10: 'The wizard of Oz'
+ 11: 'I'm singin' in the rain'
+ 12: 'Alice in Wonderland'
+ 13: 'The wizard of Oz'
+ 14: 'I'm singin' in the rain'
+ 15: 'Alice in Wonderland'
+ 16: 'The wizard of Oz'
+ 17: 'I'm singin' in the rain'
+ 18: 'Alice in Wonderland'
+ 19: 'The wizard of Oz'
+ 20: 'I'm singin' in the rain'
+ 21: 'Alice in Wonderland'
+ 22: 'The wizard of Oz'
+ 23: 'I'm singin' in the rain'
+ 24: 'Alice in Wonderland'
+ 25: 'The wizard of Oz'
+ 26: 'I'm singin' in the rain'
+ 27: 'Alice in Wonderland'
+ 28: 'The wizard of Oz'
+ 29: 'I'm singin' in the rain'
+ 30: 'Alice in Wonderland'
+ 31: 'The wizard of Oz'
+ 32: 'I'm singin' in the rain'
+ 33: 'Alice in Wonderland'
+ 34: 'The wizard of Oz'
+ 35: 'I'm singin' in the rain'
+ 36: 'Alice in Wonderland'
+ 37: 'The wizard of Oz'
+ 38: 'I'm singin' in the rain'
+ 39: 'Alice in Wonderland'
+ 40: 'The wizard of Oz'
+ 41: 'I'm singin' in the rain'
+ 42: 'Alice in Wonderland'
+ 43: 'The wizard of Oz'
+ 44: 'I'm singin' in the rain'
+ 45: 'Alice in Wonderland'
+ 46: 'The wizard of Oz'
+ 47: 'I'm singin' in the rain'
+ 48: 'Alice in Wonderland'
+ 49: 'The wizard of Oz'
+ 50: 'I'm singin' in the rain'
+ 51: 'Alice in Wonderland'
+ 52: 'The wizard of Oz'
+ 53: 'I'm singin' in the rain'
+ 54: 'Alice in Wonderland'
+ 55: 'The wizard of Oz'
+ 56: 'I'm singin' in the rain'
+ 57: 'Alice in Wonderland'
+ 58: 'The wizard of Oz'
+ 59: 'I'm singin' in the rain'
+ 60: 'Alice in Wonderland'
+ 61: 'The wizard of Oz'
+ 62: 'I'm singin' in the rain'
+ 63: 'Alice in Wonderland'
+ 64: 'The wizard of Oz'
+ 65: 'I'm singin' in the rain'
+ 66: 'Alice in Wonderland'
+ 67: 'The wizard of Oz'
+ 68: 'I'm singin' in the rain'
+ 69: 'Alice in Wonderland'
+ 70: 'The wizard of Oz'
+ 71: 'I'm singin' in the rain'
+ 72: 'Alice in Wonderland'
+ 73: 'The wizard of Oz'
+ 74: 'I'm singin' in the rain'
+ 75: 'Alice in Wonderland'
+ 76: 'The wizard of Oz'
+ 77: 'I'm singin' in the rain'
+ 78: 'Alice in Wonderland'
+ 79: 'The wizard of Oz'
+ 80: 'I'm singin' in the rain'
+ 81: 'Alice in Wonderland'
+ 82: 'The wizard of Oz'
+ 83: 'I'm singin' in the rain'
+ 84: 'Alice in Wonderland'
+ 85: 'The wizard of Oz'
+ 86: 'I'm singin' in the rain'
+ 87: 'Alice in Wonderland'
+ 88: 'The wizard of Oz'
+ 89: 'I'm singin' in the rain'
+ 90: 'Alice in Wonderland'
+ 91: 'The wizard of Oz'
+ 92: 'I'm singin' in the rain'
+ 93: 'Alice in Wonderland'
+ 94: 'The wizard of Oz'
+ 95: 'I'm singin' in the rain'
+ 96: 'Alice in Wonderland'
+ 97: 'The wizard of Oz'
+ 98: 'I'm singin' in the rain'
+ 99: 'Alice in Wonderland'
+ 100: 'The wizard of Oz'
+ 101: 'I'm singin' in the rain'
+ 102: 'Alice in Wonderland'
+ 103: 'The wizard of Oz'
+ 104: 'I'm singin' in the rain'
+ 105: 'Alice in Wonderland'
+ 106: 'The wizard of Oz'
+ 107: 'I'm singin' in the rain'
+ 108: 'Alice in Wonderland'
+ 109: 'The wizard of Oz'
+ 110: 'I'm singin' in the rain'
+ 111: 'Alice in Wonderland'
+ 112: 'The wizard of Oz'
+ 113: 'I'm singin' in the rain'
+ 114: 'Alice in Wonderland'
+ 115: 'The wizard of Oz'
+ 116: 'I'm singin' in the rain'
+ 117: 'Alice in Wonderland'
+ 118: 'The wizard of Oz'
+ 119: 'I'm singin' in the rain'
+ 120: 'Alice in Wonderland'
+ 121: 'The wizard of Oz'
+ 122: 'I'm singin' in the rain'
+ 123: 'Alice in Wonderland'
+ 124: 'The wizard of Oz'
+ 125: 'I'm singin' in the rain'
+ 126: 'Alice in Wonderland'
+ 127: 'The wizard of Oz'
+ 128: 'I'm singin' in the rain'
+ 129: 'Alice in Wonderland'
+ 130: 'The wizard of Oz'
+ 131: 'I'm singin' in the rain'
+ 132: 'Alice in Wonderland'
+ 133: 'The wizard of Oz'
+ 134: 'I'm singin' in the rain'
+ 135: 'Alice in Wonderland'
+ 136: 'The wizard of Oz'
+ 137: 'I'm singin' in the rain'
+ 138: 'Alice in Wonderland'
+ 139: 'The wizard of Oz'
+ 140: 'I'm singin' in the rain'
+ 141: 'Alice in Wonderland'
+ 142: 'The wizard of Oz'
+ 143: 'I'm singin' in the rain'
+ 144: 'Alice in Wonderland'
+ 145: 'The wizard of Oz'
+ 146: 'I'm singin' in the rain'
+ 147: 'Alice in Wonderland'
+ 148: 'The wizard of Oz'
+ 149: 'I'm singin' in the rain'
+ 150: 'Alice in Wonderland'
+ 151: 'The wizard of Oz'
+ 152: 'I'm singin' in the rain'
+ 153: 'Alice in Wonderland'
+ 154: 'The wizard of Oz'
+ 155: 'I'm singin' in the rain'
+ 156: 'Alice in Wonderland'
+ 157: 'The wizard of Oz'
+ 158: 'I'm singin' in the rain'
+ 159: 'Alice in Wonderland'
+ 160: 'The wizard of Oz'
+ 161: 'I'm singin' in the rain'
+ 162: 'Alice in Wonderland'
+ 163: 'The wizard of Oz'
+ 164: 'I'm singin' in the rain'
+ 165: 'Alice in Wonderland'
+ 166: 'The wizard of Oz'
+ 167: 'I'm singin' in the rain'
+ 168: 'Alice in Wonderland'
+ 169: 'The wizard of Oz'
+ 170: 'I'm singin' in the rain'
+ 171: 'Alice in Wonderland'
+ 172: 'The wizard of Oz'
+ 173: 'I'm singin' in the rain'
+ 174: 'Alice in Wonderland'
+ 175: 'The wizard of Oz'
+ 176: 'I'm singin' in the rain'
+ 177: 'Alice in Wonderland'
+ 178: 'The wizard of Oz'
+ 179: 'I'm singin' in the rain'
+ 180: 'Alice in Wonderland'
+ 181: 'The wizard of Oz'
+ 182: 'I'm singin' in the rain'
+ 183: 'Alice in Wonderland'
+ 184: 'The wizard of Oz'
+ 185: 'I'm singin' in the rain'
+ 186: 'Alice in Wonderland'
+ 187: 'The wizard of Oz'
+ 188: 'I'm singin' in the rain'
+ 189: 'Alice in Wonderland'
+ 190: 'The wizard of Oz'
+ 191: 'I'm singin' in the rain'
+ 192: 'Alice in Wonderland'
+ 193: 'The wizard of Oz'
+ 194: 'I'm singin' in the rain'
+ 195: 'Alice in Wonderland'
+ 196: 'The wizard of Oz'
+ 197: 'I'm singin' in the rain'
+ 198: 'Alice in Wonderland'
+ 199: 'The wizard of Oz'
+ 200: 'I'm singin' in the rain'
+ 201: 'Alice in Wonderland'
+ 202: 'The wizard of Oz'
+ 203: 'I'm singin' in the rain'
+ 204: 'Alice in Wonderland'
+ 205: 'The wizard of Oz'
+ 206: 'I'm singin' in the rain'
+ 207: 'Alice in Wonderland'
+ 208: 'The wizard of Oz'
+ 209: 'I'm singin' in the rain'
+ 210: 'Alice in Wonderland'
+ 211: 'The wizard of Oz'
+ 212: 'I'm singin' in the rain'
+ 213: 'Alice in Wonderland'
+ 214: 'The wizard of Oz'
+ 215: 'I'm singin' in the rain'
+ 216: 'Alice in Wonderland'
+ 217: 'The wizard of Oz'
+ 218: 'I'm singin' in the rain'
+ 219: 'Alice in Wonderland'
+ 220: 'The wizard of Oz'
+ 221: 'I'm singin' in the rain'
+ 222: 'Alice in Wonderland'
+ 223: 'The wizard of Oz'
+ 224: 'I'm singin' in the rain'
+ 225: 'Alice in Wonderland'
+ 226: 'The wizard of Oz'
+ 227: 'I'm singin' in the rain'
+ 228: 'Alice in Wonderland'
+ 229: 'The wizard of Oz'
+ 230: 'I'm singin' in the rain'
+ 231: 'Alice in Wonderland'
+ 232: 'The wizard of Oz'
+ 233: 'I'm singin' in the rain'
+ 234: 'Alice in Wonderland'
+ 235: 'The wizard of Oz'
+ 236: 'I'm singin' in the rain'
+ 237: 'Alice in Wonderland'
+ 238: 'The wizard of Oz'
+ 239: 'I'm singin' in the rain'
+ 240: 'Alice in Wonderland'
+ 241: 'The wizard of Oz'
+ 242: 'I'm singin' in the rain'
+ 243: 'Alice in Wonderland'
+ 244: 'The wizard of Oz'
+ 245: 'I'm singin' in the rain'
+ 246: 'Alice in Wonderland'
+ 247: 'The wizard of Oz'
+ 248: 'I'm singin' in the rain'
+ 249: 'Alice in Wonderland'
+ 250: 'The wizard of Oz'
+ 251: 'I'm singin' in the rain'
+ 252: 'Alice in Wonderland'
+ 253: 'The wizard of Oz'
+ 254: 'I'm singin' in the rain'
+ 255: 'Alice in Wonderland'
+ 256: 'The wizard of Oz'
+ 257: 'I'm singin' in the rain'
+ 258: 'Alice in Wonderland'
+ 259: 'The wizard of Oz'
+ 260: 'I'm singin' in the rain'
+ 261: 'Alice in Wonderland'
+ 262: 'The wizard of Oz'
+ 263: 'I'm singin' in the rain'
+ 264: 'Alice in Wonderland'
+ 265: 'The wizard of Oz'
+ 266: 'I'm singin' in the rain'
+ 267: 'Alice in Wonderland'
+ 268: 'The wizard of Oz'
+ 269: 'I'm singin' in the rain'
+ 270: 'Alice in Wonderland'
+ 271: 'The wizard of Oz'
+ 272: 'I'm singin' in the rain'
+ 273: 'Alice in Wonderland'
+ 274: 'The wizard of Oz'
+ 275: 'I'm singin' in the rain'
+ 276: 'Alice in Wonderland'
+ 277: 'The wizard of Oz'
+ 278: 'I'm singin' in the rain'
+ 279: 'Alice in Wonderland'
+ 280: 'The wizard of Oz'
+ 281: 'I'm singin' in the rain'
+ 282: 'Alice in Wonderland'
+ 283: 'The wizard of Oz'
+ 284: 'I'm singin' in the rain'
+ 285: 'Alice in Wonderland'
+ 286: 'The wizard of Oz'
+ 287: 'I'm singin' in the rain'
+ 288: 'Alice in Wonderland'
+ 289: 'The wizard of Oz'
+ 290: 'I'm singin' in the rain'
+ 291: 'Alice in Wonderland'
+ 292: 'The wizard of Oz'
+ 293: 'I'm singin' in the rain'
+ 294: 'Alice in Wonderland'
+ 295: 'The wizard of Oz'
+ 296: 'I'm singin' in the rain'
+ 297: 'Alice in Wonderland'
+ 298: 'The wizard of Oz'
+ 299: 'I'm singin' in the rain'
+ 300: 'Alice in Wonderland'
+ 301: 'The wizard of Oz'
+ 302: 'I'm singin' in the rain'
+ 303: 'Alice in Wonderland'
+ 304: 'The wizard of Oz'
+ 305: 'I'm singin' in the rain'
+ 306: 'Alice in Wonderland'
+ 307: 'The wizard of Oz'
+ 308: 'I'm singin' in the rain'
+ 309: 'Alice in Wonderland'
+ 310: 'The wizard of Oz'
+ 311: 'I'm singin' in the rain'
+ 312: 'Alice in Wonderland'
+ 313: 'The wizard of Oz'
+ 314: 'I'm singin' in the rain'
+ 315: 'Alice in Wonderland'
+ 316: 'The wizard of Oz'
+ 317: 'I'm singin' in the rain'
+ 318: 'Alice in Wonderland'
+ 319: 'The wizard of Oz'
+ 320: 'I'm singin' in the rain'
+ 321: 'Alice in Wonderland'
+ 322: 'The wizard of Oz'
+ 323: 'I'm singin' in the rain'
+ 324: 'Alice in Wonderland'
+ 325: 'The wizard of Oz'
+ 326: 'I'm singin' in the rain'
+ 327: 'Alice in Wonderland'
+ 328: 'The wizard of Oz'
+ 329: 'I'm singin' in the rain'
+ 330: 'Alice in Wonderland'
+ 331: 'The wizard of Oz'
+ 332: 'I'm singin' in the rain'
+ 333: 'Alice in Wonderland'
+ 334: 'The wizard of Oz'
+ 335: 'I'm singin' in the rain'
+ 336: 'Alice in Wonderland'
+ 337: 'The wizard of Oz'
+ 338: 'I'm singin' in the rain'
+ 339: 'Alice in Wonderland'
+ 340: 'The wizard of Oz'
+ 341: 'I'm singin' in the rain'
+ 342: 'Alice in Wonderland'
+ 343: 'The wizard of Oz'
+ 344: 'I'm singin' in the rain'
+ 345: 'Alice in Wonderland'
+ 346: 'The wizard of Oz'
+ 347: 'I'm singin' in the rain'
+ 348: 'Alice in Wonderland'
+ 349: 'The wizard of Oz'
+ 350: 'I'm singin' in the rain'
+ 351: 'Alice in Wonderland'
+ 352: 'The wizard of Oz'
+ 353: 'I'm singin' in the rain'
+ 354: 'Alice in Wonderland'
+ 355: 'The wizard of Oz'
+ 356: 'I'm singin' in the rain'
+ 357: 'Alice in Wonderland'
+ 358: 'The wizard of Oz'
+ 359: 'I'm singin' in the rain'
+ 360: 'Alice in Wonderland'
+ 361: 'The wizard of Oz'
+ 362: 'I'm singin' in the rain'
+ 363: 'Alice in Wonderland'
+ 364: 'The wizard of Oz'
+ 365: 'I'm singin' in the rain'
+ 366: 'Alice in Wonderland'
+ 367: 'The wizard of Oz'
+ 368: 'I'm singin' in the rain'
+ 369: 'Alice in Wonderland'
+ 370: 'The wizard of Oz'
+ 371: 'I'm singin' in the rain'
+ 372: 'Alice in Wonderland'
+ 373: 'The wizard of Oz'
+ 374: 'I'm singin' in the rain'
+ 375: 'Alice in Wonderland'
+ 376: 'The wizard of Oz'
+ 377: 'I'm singin' in the rain'
+ 378: 'Alice in Wonderland'
+ 379: 'The wizard of Oz'
+ 380: 'I'm singin' in the rain'
+ 381: 'Alice in Wonderland'
+ 382: 'The wizard of Oz'
+ 383: 'I'm singin' in the rain'
+ 384: 'Alice in Wonderland'
+ 385: 'The wizard of Oz'
+ 386: 'I'm singin' in the rain'
+ 387: 'Alice in Wonderland'
+ 388: 'The wizard of Oz'
+ 389: 'I'm singin' in the rain'
+ 390: 'Alice in Wonderland'
+ 391: 'The wizard of Oz'
+ 392: 'I'm singin' in the rain'
+ 393: 'Alice in Wonderland'
+ 394: 'The wizard of Oz'
+ 395: 'I'm singin' in the rain'
+ 396: 'Alice in Wonderland'
+ 397: 'The wizard of Oz'
+ 398: 'I'm singin' in the rain'
+ 399: 'Alice in Wonderland'
+ 400: 'The wizard of Oz'
+ 401: 'I'm singin' in the rain'
+ 402: 'Alice in Wonderland'
+ 403: 'The wizard of Oz'
+ 404: 'I'm singin' in the rain'
+ 405: 'Alice in Wonderland'
+ 406: 'The wizard of Oz'
+ 407: 'I'm singin' in the rain'
+ 408: 'Alice in Wonderland'
+ 409: 'The wizard of Oz'
+ 410: 'I'm singin' in the rain'
+ 411: 'Alice in Wonderland'
+ 412: 'The wizard of Oz'
+ 413: 'I'm singin' in the rain'
+ 414: 'Alice in Wonderland'
+ 415: 'The wizard of Oz'
+ 416: 'I'm singin' in the rain'
+ 417: 'Alice in Wonderland'
+ 418: 'The wizard of Oz'
+ 419: 'I'm singin' in the rain'
+ 420: 'Alice in Wonderland'
+ 421: 'The wizard of Oz'
+ 422: 'I'm singin' in the rain'
+ 423: 'Alice in Wonderland'
+ 424: 'The wizard of Oz'
+ 425: 'I'm singin' in the rain'
+ 426: 'Alice in Wonderland'
+ 427: 'The wizard of Oz'
+ 428: 'I'm singin' in the rain'
+ 429: 'Alice in Wonderland'
+ 430: 'The wizard of Oz'
+ 431: 'I'm singin' in the rain'
+ 432: 'Alice in Wonderland'
+ 433: 'The wizard of Oz'
+ 434: 'I'm singin' in the rain'
+ 435: 'Alice in Wonderland'
+ 436: 'The wizard of Oz'
+ 437: 'I'm singin' in the rain'
+ 438: 'Alice in Wonderland'
+ 439: 'The wizard of Oz'
+ 440: 'I'm singin' in the rain'
+ 441: 'Alice in Wonderland'
+ 442: 'The wizard of Oz'
+ 443: 'I'm singin' in the rain'
+ 444: 'Alice in Wonderland'
+ 445: 'The wizard of Oz'
+ 446: 'I'm singin' in the rain'
+ 447: 'Alice in Wonderland'
+ 448: 'The wizard of Oz'
+ 449: 'I'm singin' in the rain'
+ 450: 'Alice in Wonderland'
+ 451: 'The wizard of Oz'
+ 452: 'I'm singin' in the rain'
+ 453: 'Alice in Wonderland'
+ 454: 'The wizard of Oz'
+ 455: 'I'm singin' in the rain'
+ 456: 'Alice in Wonderland'
+ 457: 'The wizard of Oz'
+ 458: 'I'm singin' in the rain'
+ 459: 'Alice in Wonderland'
+ 460: 'The wizard of Oz'
+ 461: 'I'm singin' in the rain'
+ 462: 'Alice in Wonderland'
+ 463: 'The wizard of Oz'
+ 464: 'I'm singin' in the rain'
+ 465: 'Alice in Wonderland'
+ 466: 'The wizard of Oz'
+ 467: 'I'm singin' in the rain'
+ 468: 'Alice in Wonderland'
+ 469: 'The wizard of Oz'
+ 470: 'I'm singin' in the rain'
+ 471: 'Alice in Wonderland'
+ 472: 'The wizard of Oz'
+ 473: 'I'm singin' in the rain'
+ 474: 'Alice in Wonderland'
+ 475: 'The wizard of Oz'
+ 476: 'I'm singin' in the rain'
+ 477: 'Alice in Wonderland'
+ 478: 'The wizard of Oz'
+ 479: 'I'm singin' in the rain'
+ 480: 'Alice in Wonderland'
+ 481: 'The wizard of Oz'
+ 482: 'I'm singin' in the rain'
+ 483: 'Alice in Wonderland'
+ 484: 'The wizard of Oz'
+ 485: 'I'm singin' in the rain'
+ 486: 'Alice in Wonderland'
+ 487: 'The wizard of Oz'
+ 488: 'I'm singin' in the rain'
+ 489: 'Alice in Wonderland'
+ 490: 'The wizard of Oz'
+ 491: 'I'm singin' in the rain'
+ 492: 'Alice in Wonderland'
+ 493: 'The wizard of Oz'
+ 494: 'I'm singin' in the rain'
+ 495: 'Alice in Wonderland'
+ 496: 'The wizard of Oz'
+ 497: 'I'm singin' in the rain'
+ 498: 'Alice in Wonderland'
+ 499: 'The wizard of Oz'
+ 500: 'I'm singin' in the rain'
+ 501: 'Alice in Wonderland'
+ 502: 'The wizard of Oz'
+ 503: 'I'm singin' in the rain'
+ 504: 'Alice in Wonderland'
+ 505: 'The wizard of Oz'
+ 506: 'I'm singin' in the rain'
+ 507: 'Alice in Wonderland'
+ 508: 'The wizard of Oz'
+ 509: 'I'm singin' in the rain'
+ 510: 'Alice in Wonderland'
+ 511: 'The wizard of Oz'
+ 512: 'I'm singin' in the rain'
+ 513: 'Alice in Wonderland'
+ 514: 'The wizard of Oz'
+ 515: 'I'm singin' in the rain'
+ 516: 'Alice in Wonderland'
+ 517: 'The wizard of Oz'
+ 518: 'I'm singin' in the rain'
+ 519: 'Alice in Wonderland'
+ 520: 'The wizard of Oz'
+ 521: 'I'm singin' in the rain'
+ 522: 'Alice in Wonderland'
+ 523: 'The wizard of Oz'
+ 524: 'I'm singin' in the rain'
+ 525: 'Alice in Wonderland'
+ 526: 'The wizard of Oz'
+ 527: 'I'm singin' in the rain'
+ 528: 'Alice in Wonderland'
+ 529: 'The wizard of Oz'
+ 530: 'I'm singin' in the rain'
+ 531: 'Alice in Wonderland'
+ 532: 'The wizard of Oz'
+ 533: 'I'm singin' in the rain'
+ 534: 'Alice in Wonderland'
+ 535: 'The wizard of Oz'
+ 536: 'I'm singin' in the rain'
+ 537: 'Alice in Wonderland'
+ 538: 'The wizard of Oz'
+ 539: 'I'm singin' in the rain'
+ 540: 'Alice in Wonderland'
+ 541: 'The wizard of Oz'
+ 542: 'I'm singin' in the rain'
+ 543: 'Alice in Wonderland'
+ 544: 'The wizard of Oz'
+ 545: 'I'm singin' in the rain'
+ 546: 'Alice in Wonderland'
+ 547: 'The wizard of Oz'
+ 548: 'I'm singin' in the rain'
+ 549: 'Alice in Wonderland'
+ 550: 'The wizard of Oz'
+ 551: 'I'm singin' in the rain'
+ 552: 'Alice in Wonderland'
+ 553: 'The wizard of Oz'
+ 554: 'I'm singin' in the rain'
+ 555: 'Alice in Wonderland'
+ 556: 'The wizard of Oz'
+ 557: 'I'm singin' in the rain'
+ 558: 'Alice in Wonderland'
+ 559: 'The wizard of Oz'
+ 560: 'I'm singin' in the rain'
+ 561: 'Alice in Wonderland'
+ 562: 'The wizard of Oz'
+ 563: 'I'm singin' in the rain'
+ 564: 'Alice in Wonderland'
+ 565: 'The wizard of Oz'
+ 566: 'I'm singin' in the rain'
+ 567: 'Alice in Wonderland'
+ 568: 'The wizard of Oz'
+ 569: 'I'm singin' in the rain'
+ 570: 'Alice in Wonderland'
+ 571: 'The wizard of Oz'
+ 572: 'I'm singin' in the rain'
+ 573: 'Alice in Wonderland'
+ 574: 'The wizard of Oz'
+ 575: 'I'm singin' in the rain'
+ 576: 'Alice in Wonderland'
+ 577: 'The wizard of Oz'
+ 578: 'I'm singin' in the rain'
+ 579: 'Alice in Wonderland'
+ 580: 'The wizard of Oz'
+ 581: 'I'm singin' in the rain'
+ 582: 'Alice in Wonderland'
+ 583: 'The wizard of Oz'
+ 584: 'I'm singin' in the rain'
+ 585: 'Alice in Wonderland'
+ 586: 'The wizard of Oz'
+ 587: 'I'm singin' in the rain'
+ 588: 'Alice in Wonderland'
+ 589: 'The wizard of Oz'
+ 590: 'I'm singin' in the rain'
+ 591: 'Alice in Wonderland'
+ 592: 'The wizard of Oz'
+ 593: 'I'm singin' in the rain'
+ 594: 'Alice in Wonderland'
+ 595: 'The wizard of Oz'
+ 596: 'I'm singin' in the rain'
+ 597: 'Alice in Wonderland'
+ 598: 'The wizard of Oz'
+ 599: 'I'm singin' in the rain'
+ 600: 'Alice in Wonderland'
+ 601: 'The wizard of Oz'
+ 602: 'I'm singin' in the rain'
+ 603: 'Alice in Wonderland'
+ 604: 'The wizard of Oz'
+ 605: 'I'm singin' in the rain'
+ 606: 'Alice in Wonderland'
+ 607: 'The wizard of Oz'
+ 608: 'I'm singin' in the rain'
+ 609: 'Alice in Wonderland'
+ 610: 'The wizard of Oz'
+ 611: 'I'm singin' in the rain'
+ 612: 'Alice in Wonderland'
+ 613: 'The wizard of Oz'
+ 614: 'I'm singin' in the rain'
+ 615: 'Alice in Wonderland'
+ 616: 'The wizard of Oz'
+ 617: 'I'm singin' in the rain'
+ 618: 'Alice in Wonderland'
+ 619: 'The wizard of Oz'
+ 620: 'I'm singin' in the rain'
+ 621: 'Alice in Wonderland'
+ 622: 'The wizard of Oz'
+ 623: 'I'm singin' in the rain'
+ 624: 'Alice in Wonderland'
+ 625: 'The wizard of Oz'
+ 626: 'I'm singin' in the rain'
+ 627: 'Alice in Wonderland'
+ 628: 'The wizard of Oz'
+ 629: 'I'm singin' in the rain'
+ 630: 'Alice in Wonderland'
+ 631: 'The wizard of Oz'
+ 632: 'I'm singin' in the rain'
+ 633: 'Alice in Wonderland'
+ 634: 'The wizard of Oz'
+ 635: 'I'm singin' in the rain'
+ 636: 'Alice in Wonderland'
+ 637: 'The wizard of Oz'
+ 638: 'I'm singin' in the rain'
+ 639: 'Alice in Wonderland'
+ 640: 'The wizard of Oz'
+ 641: 'I'm singin' in the rain'
+ 642: 'Alice in Wonderland'
+ 643: 'The wizard of Oz'
+ 644: 'I'm singin' in the rain'
+ 645: 'Alice in Wonderland'
+ 646: 'The wizard of Oz'
+ 647: 'I'm singin' in the rain'
+ 648: 'Alice in Wonderland'
+ 649: 'The wizard of Oz'
+ 650: 'I'm singin' in the rain'
+ 651: 'Alice in Wonderland'
+ 652: 'The wizard of Oz'
+ 653: 'I'm singin' in the rain'
+ 654: 'Alice in Wonderland'
+ 655: 'The wizard of Oz'
+ 656: 'I'm singin' in the rain'
+ 657: 'Alice in Wonderland'
+ 658: 'The wizard of Oz'
+ 659: 'I'm singin' in the rain'
+ 660: 'Alice in Wonderland'
+ 661: 'The wizard of Oz'
+ 662: 'I'm singin' in the rain'
+ 663: 'Alice in Wonderland'
+ 664: 'The wizard of Oz'
+ 665: 'I'm singin' in the rain'
+ 666: 'Alice in Wonderland'
+ 667: 'The wizard of Oz'
+ 668: 'I'm singin' in the rain'
+ 669: 'Alice in Wonderland'
+ 670: 'The wizard of Oz'
+ 671: 'I'm singin' in the rain'
+ 672: 'Alice in Wonderland'
+ 673: 'The wizard of Oz'
+ 674: 'I'm singin' in the rain'
+ 675: 'Alice in Wonderland'
+ 676: 'The wizard of Oz'
+ 677: 'I'm singin' in the rain'
+ 678: 'Alice in Wonderland'
+ 679: 'The wizard of Oz'
+ 680: 'I'm singin' in the rain'
+ 681: 'Alice in Wonderland'
+ 682: 'The wizard of Oz'
+ 683: 'I'm singin' in the rain'
+ 684: 'Alice in Wonderland'
+ 685: 'The wizard of Oz'
+ 686: 'I'm singin' in the rain'
+ 687: 'Alice in Wonderland'
+ 688: 'The wizard of Oz'
+ 689: 'I'm singin' in the rain'
+ 690: 'Alice in Wonderland'
+ 691: 'The wizard of Oz'
+ 692: 'I'm singin' in the rain'
+ 693: 'Alice in Wonderland'
+ 694: 'The wizard of Oz'
+ 695: 'I'm singin' in the rain'
+ 696: 'Alice in Wonderland'
+ 697: 'The wizard of Oz'
+ 698: 'I'm singin' in the rain'
+ 699: 'Alice in Wonderland'
+ 700: 'The wizard of Oz'
+ 701: 'I'm singin' in the rain'
+ 702: 'Alice in Wonderland'
+ 703: 'The wizard of Oz'
+ 704: 'I'm singin' in the rain'
+ 705: 'Alice in Wonderland'
+ 706: 'The wizard of Oz'
+ 707: 'I'm singin' in the rain'
+ 708: 'Alice in Wonderland'
+ 709: 'The wizard of Oz'
+ 710: 'I'm singin' in the rain'
+ 711: 'Alice in Wonderland'
+ 712: 'The wizard of Oz'
+ 713: 'I'm singin' in the rain'
+ 714: 'Alice in Wonderland'
+ 715: 'The wizard of Oz'
+ 716: 'I'm singin' in the rain'
+ 717: 'Alice in Wonderland'
+ 718: 'The wizard of Oz'
+ 719: 'I'm singin' in the rain'
+ 720: 'Alice in Wonderland'
+ 721: 'The wizard of Oz'
+ 722: 'I'm singin' in the rain'
+ 723: 'Alice in Wonderland'
+ 724: 'The wizard of Oz'
+ 725: 'I'm singin' in the rain'
+ 726: 'Alice in Wonderland'
+ 727: 'The wizard of Oz'
+ 728: 'I'm singin' in the rain'
+ 729: 'Alice in Wonderland'
+ 730: 'The wizard of Oz'
+ 731: 'I'm singin' in the rain'
+ 732: 'Alice in Wonderland'
+ 733: 'The wizard of Oz'
+ 734: 'I'm singin' in the rain'
+ 735: 'Alice in Wonderland'
+ 736: 'The wizard of Oz'
+ 737: 'I'm singin' in the rain'
+ 738: 'Alice in Wonderland'
+ 739: 'The wizard of Oz'
+ 740: 'I'm singin' in the rain'
+ 741: 'Alice in Wonderland'
+ 742: 'The wizard of Oz'
+ 743: 'I'm singin' in the rain'
+ 744: 'Alice in Wonderland'
+ 745: 'The wizard of Oz'
+ 746: 'I'm singin' in the rain'
+ 747: 'Alice in Wonderland'
+ 748: 'The wizard of Oz'
+ 749: 'I'm singin' in the rain'
+ 750: 'Alice in Wonderland'
+ 751: 'The wizard of Oz'
+ 752: 'I'm singin' in the rain'
+ 753: 'Alice in Wonderland'
+ 754: 'The wizard of Oz'
+ 755: 'I'm singin' in the rain'
+ 756: 'Alice in Wonderland'
+ 757: 'The wizard of Oz'
+ 758: 'I'm singin' in the rain'
+ 759: 'Alice in Wonderland'
+ 760: 'The wizard of Oz'
+ 761: 'I'm singin' in the rain'
+ 762: 'Alice in Wonderland'
+ 763: 'The wizard of Oz'
+ 764: 'I'm singin' in the rain'
+ 765: 'Alice in Wonderland'
+ 766: 'The wizard of Oz'
+ 767: 'I'm singin' in the rain'
+ 768: 'Alice in Wonderland'
+ 769: 'The wizard of Oz'
+ 770: 'I'm singin' in the rain'
+ 771: 'Alice in Wonderland'
+ 772: 'The wizard of Oz'
+ 773: 'I'm singin' in the rain'
+ 774: 'Alice in Wonderland'
+ 775: 'The wizard of Oz'
+ 776: 'I'm singin' in the rain'
+ 777: 'Alice in Wonderland'
+ 778: 'The wizard of Oz'
+ 779: 'I'm singin' in the rain'
+ 780: 'Alice in Wonderland'
+ 781: 'The wizard of Oz'
+ 782: 'I'm singin' in the rain'
+ 783: 'Alice in Wonderland'
+ 784: 'The wizard of Oz'
+ 785: 'I'm singin' in the rain'
+ 786: 'Alice in Wonderland'
+ 787: 'The wizard of Oz'
+ 788: 'I'm singin' in the rain'
+ 789: 'Alice in Wonderland'
+ 790: 'The wizard of Oz'
+ 791: 'I'm singin' in the rain'
+ 792: 'Alice in Wonderland'
+ 793: 'The wizard of Oz'
+ 794: 'I'm singin' in the rain'
+ 795: 'Alice in Wonderland'
+ 796: 'The wizard of Oz'
+ 797: 'I'm singin' in the rain'
+ 798: 'Alice in Wonderland'
+ 799: 'The wizard of Oz'
+ 800: 'I'm singin' in the rain'
+ 801: 'Alice in Wonderland'
+ 802: 'The wizard of Oz'
+ 803: 'I'm singin' in the rain'
+ 804: 'Alice in Wonderland'
+ 805: 'The wizard of Oz'
+ 806: 'I'm singin' in the rain'
+ 807: 'Alice in Wonderland'
+ 808: 'The wizard of Oz'
+ 809: 'I'm singin' in the rain'
+ 810: 'Alice in Wonderland'
+ 811: 'The wizard of Oz'
+ 812: 'I'm singin' in the rain'
+ 813: 'Alice in Wonderland'
+ 814: 'The wizard of Oz'
+ 815: 'I'm singin' in the rain'
+ 816: 'Alice in Wonderland'
+ 817: 'The wizard of Oz'
+ 818: 'I'm singin' in the rain'
+ 819: 'Alice in Wonderland'
+ 820: 'The wizard of Oz'
+ 821: 'I'm singin' in the rain'
+ 822: 'Alice in Wonderland'
+ 823: 'The wizard of Oz'
+ 824: 'I'm singin' in the rain'
+ 825: 'Alice in Wonderland'
+ 826: 'The wizard of Oz'
+ 827: 'I'm singin' in the rain'
+ 828: 'Alice in Wonderland'
+ 829: 'The wizard of Oz'
+ 830: 'I'm singin' in the rain'
+ 831: 'Alice in Wonderland'
+ 832: 'The wizard of Oz'
+ 833: 'I'm singin' in the rain'
+ 834: 'Alice in Wonderland'
+ 835: 'The wizard of Oz'
+ 836: 'I'm singin' in the rain'
+ 837: 'Alice in Wonderland'
+ 838: 'The wizard of Oz'
+ 839: 'I'm singin' in the rain'
+ 840: 'Alice in Wonderland'
+ 841: 'The wizard of Oz'
+ 842: 'I'm singin' in the rain'
+ 843: 'Alice in Wonderland'
+ 844: 'The wizard of Oz'
+ 845: 'I'm singin' in the rain'
+ 846: 'Alice in Wonderland'
+ 847: 'The wizard of Oz'
+ 848: 'I'm singin' in the rain'
+ 849: 'Alice in Wonderland'
+ 850: 'The wizard of Oz'
+ 851: 'I'm singin' in the rain'
+ 852: 'Alice in Wonderland'
+ 853: 'The wizard of Oz'
+ 854: 'I'm singin' in the rain'
+ 855: 'Alice in Wonderland'
+ 856: 'The wizard of Oz'
+ 857: 'I'm singin' in the rain'
+ 858: 'Alice in Wonderland'
+ 859: 'The wizard of Oz'
+ 860: 'I'm singin' in the rain'
+ 861: 'Alice in Wonderland'
+ 862: 'The wizard of Oz'
+ 863: 'I'm singin' in the rain'
+ 864: 'Alice in Wonderland'
+ 865: 'The wizard of Oz'
+ 866: 'I'm singin' in the rain'
+ 867: 'Alice in Wonderland'
+ 868: 'The wizard of Oz'
+ 869: 'I'm singin' in the rain'
+ 870: 'Alice in Wonderland'
+ 871: 'The wizard of Oz'
+ 872: 'I'm singin' in the rain'
+ 873: 'Alice in Wonderland'
+ 874: 'The wizard of Oz'
+ 875: 'I'm singin' in the rain'
+ 876: 'Alice in Wonderland'
+ 877: 'The wizard of Oz'
+ 878: 'I'm singin' in the rain'
+ 879: 'Alice in Wonderland'
+ 880: 'The wizard of Oz'
+ 881: 'I'm singin' in the rain'
+ 882: 'Alice in Wonderland'
+ 883: 'The wizard of Oz'
+ 884: 'I'm singin' in the rain'
+ 885: 'Alice in Wonderland'
+ 886: 'The wizard of Oz'
+ 887: 'I'm singin' in the rain'
+ 888: 'Alice in Wonderland'
+ 889: 'The wizard of Oz'
+ 890: 'I'm singin' in the rain'
+ 891: 'Alice in Wonderland'
+ 892: 'The wizard of Oz'
+ 893: 'I'm singin' in the rain'
+ 894: 'Alice in Wonderland'
+ 895: 'The wizard of Oz'
+ 896: 'I'm singin' in the rain'
+ 897: 'Alice in Wonderland'
+ 898: 'The wizard of Oz'
+ 899: 'I'm singin' in the rain'
+ 900: 'Alice in Wonderland'
+ 901: 'The wizard of Oz'
+ 902: 'I'm singin' in the rain'
+ 903: 'Alice in Wonderland'
+ 904: 'The wizard of Oz'
+ 905: 'I'm singin' in the rain'
+ 906: 'Alice in Wonderland'
+ 907: 'The wizard of Oz'
+ 908: 'I'm singin' in the rain'
+ 909: 'Alice in Wonderland'
+ 910: 'The wizard of Oz'
+ 911: 'I'm singin' in the rain'
+ 912: 'Alice in Wonderland'
+ 913: 'The wizard of Oz'
+ 914: 'I'm singin' in the rain'
+ 915: 'Alice in Wonderland'
+ 916: 'The wizard of Oz'
+ 917: 'I'm singin' in the rain'
+ 918: 'Alice in Wonderland'
+ 919: 'The wizard of Oz'
+ 920: 'I'm singin' in the rain'
+ 921: 'Alice in Wonderland'
+ 922: 'The wizard of Oz'
+ 923: 'I'm singin' in the rain'
+ 924: 'Alice in Wonderland'
+ 925: 'The wizard of Oz'
+ 926: 'I'm singin' in the rain'
+ 927: 'Alice in Wonderland'
+ 928: 'The wizard of Oz'
+ 929: 'I'm singin' in the rain'
+ 930: 'Alice in Wonderland'
+ 931: 'The wizard of Oz'
+ 932: 'I'm singin' in the rain'
+ 933: 'Alice in Wonderland'
+ 934: 'The wizard of Oz'
+ 935: 'I'm singin' in the rain'
+ 936: 'Alice in Wonderland'
+ 937: 'The wizard of Oz'
+ 938: 'I'm singin' in the rain'
+ 939: 'Alice in Wonderland'
+ 940: 'The wizard of Oz'
+ 941: 'I'm singin' in the rain'
+ 942: 'Alice in Wonderland'
+ 943: 'The wizard of Oz'
+ 944: 'I'm singin' in the rain'
+ 945: 'Alice in Wonderland'
+ 946: 'The wizard of Oz'
+ 947: 'I'm singin' in the rain'
+ 948: 'Alice in Wonderland'
+ 949: 'The wizard of Oz'
+ 950: 'I'm singin' in the rain'
+ 951: 'Alice in Wonderland'
+ 952: 'The wizard of Oz'
+ 953: 'I'm singin' in the rain'
+ 954: 'Alice in Wonderland'
+ 955: 'The wizard of Oz'
+ 956: 'I'm singin' in the rain'
+ 957: 'Alice in Wonderland'
+ 958: 'The wizard of Oz'
+ 959: 'I'm singin' in the rain'
+ 960: 'Alice in Wonderland'
+ 961: 'The wizard of Oz'
+ 962: 'I'm singin' in the rain'
+ 963: 'Alice in Wonderland'
+ 964: 'The wizard of Oz'
+ 965: 'I'm singin' in the rain'
+ 966: 'Alice in Wonderland'
+ 967: 'The wizard of Oz'
+ 968: 'I'm singin' in the rain'
+ 969: 'Alice in Wonderland'
+ 970: 'The wizard of Oz'
+ 971: 'I'm singin' in the rain'
+ 972: 'Alice in Wonderland'
+ 973: 'The wizard of Oz'
+ 974: 'I'm singin' in the rain'
+ 975: 'Alice in Wonderland'
+ 976: 'The wizard of Oz'
+ 977: 'I'm singin' in the rain'
+ 978: 'Alice in Wonderland'
+ 979: 'The wizard of Oz'
+ 980: 'I'm singin' in the rain'
+ 981: 'Alice in Wonderland'
+ 982: 'The wizard of Oz'
+ 983: 'I'm singin' in the rain'
+ 984: 'Alice in Wonderland'
+ 985: 'The wizard of Oz'
+ 986: 'I'm singin' in the rain'
+ 987: 'Alice in Wonderland'
+ 988: 'The wizard of Oz'
+ 989: 'I'm singin' in the rain'
+ 990: 'Alice in Wonderland'
+ 991: 'The wizard of Oz'
+ 992: 'I'm singin' in the rain'
+ 993: 'Alice in Wonderland'
+ 994: 'The wizard of Oz'
+ 995: 'I'm singin' in the rain'
+ 996: 'Alice in Wonderland'
+ 997: 'The wizard of Oz'
+ 998: 'I'm singin' in the rain'
+ 999: 'Alice in Wonderland'
+ 1000: 'The wizard of Oz'
+ 1001: 'I'm singin' in the rain'
+ 1002: 'Alice in Wonderland'
+ 1003: 'The wizard of Oz'
+ 1004: 'I'm singin' in the rain'
+ 1005: 'Alice in Wonderland'
+ 1006: 'The wizard of Oz'
+ 1007: 'I'm singin' in the rain'
+ 1008: 'Alice in Wonderland'
+ 1009: 'The wizard of Oz'
+ 1010: 'I'm singin' in the rain'
+ 1011: 'Alice in Wonderland'
+ 1012: 'The wizard of Oz'
+ 1013: 'I'm singin' in the rain'
+ 1014: 'Alice in Wonderland'
+ 1015: 'The wizard of Oz'
+ 1016: 'I'm singin' in the rain'
+ 1017: 'Alice in Wonderland'
+ 1018: 'The wizard of Oz'
+ 1019: 'I'm singin' in the rain'
+ 1020: 'Alice in Wonderland'
+ 1021: 'The wizard of Oz'
+ 1022: 'I'm singin' in the rain'
+ 1023: 'Alice in Wonderland'
+ 1024: 'The wizard of Oz'
+ 1025: 'I'm singin' in the rain'
+ 1026: 'Alice in Wonderland'
+ 1027: 'The wizard of Oz'
+ 1028: 'I'm singin' in the rain'
+ 1029: 'Alice in Wonderland'
+ 1030: 'The wizard of Oz'
+ 1031: 'I'm singin' in the rain'
+ 1032: 'Alice in Wonderland'
+ 1033: 'The wizard of Oz'
+ 1034: 'I'm singin' in the rain'
+ 1035: 'Alice in Wonderland'
+ 1036: 'The wizard of Oz'
+ 1037: 'I'm singin' in the rain'
+ 1038: 'Alice in Wonderland'
+ 1039: 'The wizard of Oz'
+ 1040: 'I'm singin' in the rain'
+ 1041: 'Alice in Wonderland'
+ 1042: 'The wizard of Oz'
+ 1043: 'I'm singin' in the rain'
+ 1044: 'Alice in Wonderland'
+ 1045: 'The wizard of Oz'
+ 1046: 'I'm singin' in the rain'
+ 1047: 'Alice in Wonderland'
+ 1048: 'The wizard of Oz'
+ 1049: 'I'm singin' in the rain'
+ 1050: 'Alice in Wonderland'
+ 1051: 'The wizard of Oz'
+ 1052: 'I'm singin' in the rain'
+ 1053: 'Alice in Wonderland'
+ 1054: 'The wizard of Oz'
+ 1055: 'I'm singin' in the rain'
+ 1056: 'Alice in Wonderland'
+ 1057: 'The wizard of Oz'
+ 1058: 'I'm singin' in the rain'
+ 1059: 'Alice in Wonderland'
+ 1060: 'The wizard of Oz'
+ 1061: 'I'm singin' in the rain'
+ 1062: 'Alice in Wonderland'
+ 1063: 'The wizard of Oz'
+ 1064: 'I'm singin' in the rain'
+ 1065: 'Alice in Wonderland'
+ 1066: 'The wizard of Oz'
+ 1067: 'I'm singin' in the rain'
+ 1068: 'Alice in Wonderland'
+ 1069: 'The wizard of Oz'
+ 1070: 'I'm singin' in the rain'
+ 1071: 'Alice in Wonderland'
+ 1072: 'The wizard of Oz'
+ 1073: 'I'm singin' in the rain'
+ 1074: 'Alice in Wonderland'
+ 1075: 'The wizard of Oz'
+ 1076: 'I'm singin' in the rain'
+ 1077: 'Alice in Wonderland'
+ 1078: 'The wizard of Oz'
+ 1079: 'I'm singin' in the rain'
+ 1080: 'Alice in Wonderland'
+ 1081: 'The wizard of Oz'
+ 1082: 'I'm singin' in the rain'
+ 1083: 'Alice in Wonderland'
+ 1084: 'The wizard of Oz'
+ 1085: 'I'm singin' in the rain'
+ 1086: 'Alice in Wonderland'
+ 1087: 'The wizard of Oz'
+ 1088: 'I'm singin' in the rain'
+ 1089: 'Alice in Wonderland'
+ 1090: 'The wizard of Oz'
+ 1091: 'I'm singin' in the rain'
+ 1092: 'Alice in Wonderland'
+ 1093: 'The wizard of Oz'
+ 1094: 'I'm singin' in the rain'
+ 1095: 'Alice in Wonderland'
+ 1096: 'The wizard of Oz'
+ 1097: 'I'm singin' in the rain'
+ 1098: 'Alice in Wonderland'
+ 1099: 'The wizard of Oz'
+ 1100: 'I'm singin' in the rain'
+ 1101: 'Alice in Wonderland'
+ 1102: 'The wizard of Oz'
+ 1103: 'I'm singin' in the rain'
+ 1104: 'Alice in Wonderland'
+ 1105: 'The wizard of Oz'
+ 1106: 'I'm singin' in the rain'
+ 1107: 'Alice in Wonderland'
+ 1108: 'The wizard of Oz'
+ 1109: 'I'm singin' in the rain'
+ 1110: 'Alice in Wonderland'
+ 1111: 'The wizard of Oz'
+ 1112: 'I'm singin' in the rain'
+ 1113: 'Alice in Wonderland'
+ 1114: 'The wizard of Oz'
+ 1115: 'I'm singin' in the rain'
+ 1116: 'Alice in Wonderland'
+ 1117: 'The wizard of Oz'
+ 1118: 'I'm singin' in the rain'
+ 1119: 'Alice in Wonderland'
+ 1120: 'The wizard of Oz'
+ 1121: 'I'm singin' in the rain'
+ 1122: 'Alice in Wonderland'
+ 1123: 'The wizard of Oz'
+ 1124: 'I'm singin' in the rain'
+ 1125: 'Alice in Wonderland'
+ 1126: 'The wizard of Oz'
+ 1127: 'I'm singin' in the rain'
+ 1128: 'Alice in Wonderland'
+ 1129: 'The wizard of Oz'
+ 1130: 'I'm singin' in the rain'
+ 1131: 'Alice in Wonderland'
+ 1132: 'The wizard of Oz'
+ 1133: 'I'm singin' in the rain'
+ 1134: 'Alice in Wonderland'
+ 1135: 'The wizard of Oz'
+ 1136: 'I'm singin' in the rain'
+ 1137: 'Alice in Wonderland'
+ 1138: 'The wizard of Oz'
+ 1139: 'I'm singin' in the rain'
+ 1140: 'Alice in Wonderland'
+ 1141: 'The wizard of Oz'
+ 1142: 'I'm singin' in the rain'
+ 1143: 'Alice in Wonderland'
+ 1144: 'The wizard of Oz'
+ 1145: 'I'm singin' in the rain'
+ 1146: 'Alice in Wonderland'
+ 1147: 'The wizard of Oz'
+ 1148: 'I'm singin' in the rain'
+ 1149: 'Alice in Wonderland'
+ 1150: 'The wizard of Oz'
+ 1151: 'I'm singin' in the rain'
+ 1152: 'Alice in Wonderland'
+ 1153: 'The wizard of Oz'
+ 1154: 'I'm singin' in the rain'
+ 1155: 'Alice in Wonderland'
+ 1156: 'The wizard of Oz'
+ 1157: 'I'm singin' in the rain'
+ 1158: 'Alice in Wonderland'
+ 1159: 'The wizard of Oz'
+ 1160: 'I'm singin' in the rain'
+ 1161: 'Alice in Wonderland'
+ 1162: 'The wizard of Oz'
+ 1163: 'I'm singin' in the rain'
+ 1164: 'Alice in Wonderland'
+ 1165: 'The wizard of Oz'
+ 1166: 'I'm singin' in the rain'
+ 1167: 'Alice in Wonderland'
+ 1168: 'The wizard of Oz'
+ 1169: 'I'm singin' in the rain'
+ 1170: 'Alice in Wonderland'
+ 1171: 'The wizard of Oz'
+ 1172: 'I'm singin' in the rain'
+ 1173: 'Alice in Wonderland'
+ 1174: 'The wizard of Oz'
+ 1175: 'I'm singin' in the rain'
+ 1176: 'Alice in Wonderland'
+ 1177: 'The wizard of Oz'
+ 1178: 'I'm singin' in the rain'
+ 1179: 'Alice in Wonderland'
+ 1180: 'The wizard of Oz'
+ 1181: 'I'm singin' in the rain'
+ 1182: 'Alice in Wonderland'
+ 1183: 'The wizard of Oz'
+ 1184: 'I'm singin' in the rain'
+ 1185: 'Alice in Wonderland'
+ 1186: 'The wizard of Oz'
+ 1187: 'I'm singin' in the rain'
+ 1188: 'Alice in Wonderland'
+ 1189: 'The wizard of Oz'
+ 1190: 'I'm singin' in the rain'
+ 1191: 'Alice in Wonderland'
+ 1192: 'The wizard of Oz'
+ 1193: 'I'm singin' in the rain'
+ 1194: 'Alice in Wonderland'
+ 1195: 'The wizard of Oz'
+ 1196: 'I'm singin' in the rain'
+ 1197: 'Alice in Wonderland'
+ 1198: 'The wizard of Oz'
+ 1199: 'I'm singin' in the rain'
+ 1200: 'Alice in Wonderland'
+ 1201: 'The wizard of Oz'
+ 1202: 'I'm singin' in the rain'
+ 1203: 'Alice in Wonderland'
+ 1204: 'The wizard of Oz'
+ 1205: 'I'm singin' in the rain'
+ 1206: 'Alice in Wonderland'
+ 1207: 'The wizard of Oz'
+ 1208: 'I'm singin' in the rain'
+ 1209: 'Alice in Wonderland'
+ 1210: 'The wizard of Oz'
+ 1211: 'I'm singin' in the rain'
+ 1212: 'Alice in Wonderland'
+ 1213: 'The wizard of Oz'
+ 1214: 'I'm singin' in the rain'
+ 1215: 'Alice in Wonderland'
+ 1216: 'The wizard of Oz'
+ 1217: 'I'm singin' in the rain'
+ 1218: 'Alice in Wonderland'
+ 1219: 'The wizard of Oz'
+ 1220: 'I'm singin' in the rain'
+ 1221: 'Alice in Wonderland'
+ 1222: 'The wizard of Oz'
+ 1223: 'I'm singin' in the rain'
+ 1224: 'Alice in Wonderland'
+ 1225: 'The wizard of Oz'
+ 1226: 'I'm singin' in the rain'
+ 1227: 'Alice in Wonderland'
+ 1228: 'The wizard of Oz'
+ 1229: 'I'm singin' in the rain'
+ 1230: 'Alice in Wonderland'
+ 1231: 'The wizard of Oz'
+ 1232: 'I'm singin' in the rain'
+ 1233: 'Alice in Wonderland'
+ 1234: 'The wizard of Oz'
+ 1235: 'I'm singin' in the rain'
+ 1236: 'Alice in Wonderland'
+ 1237: 'The wizard of Oz'
+ 1238: 'I'm singin' in the rain'
+ 1239: 'Alice in Wonderland'
+ 1240: 'The wizard of Oz'
+ 1241: 'I'm singin' in the rain'
+ 1242: 'Alice in Wonderland'
+ 1243: 'The wizard of Oz'
+ 1244: 'I'm singin' in the rain'
+ 1245: 'Alice in Wonderland'
+ 1246: 'The wizard of Oz'
+ 1247: 'I'm singin' in the rain'
+ 1248: 'Alice in Wonderland'
+ 1249: 'The wizard of Oz'
+ 1250: 'I'm singin' in the rain'
+ 1251: 'Alice in Wonderland'
+ 1252: 'The wizard of Oz'
+ 1253: 'I'm singin' in the rain'
+ 1254: 'Alice in Wonderland'
+ 1255: 'The wizard of Oz'
+ 1256: 'I'm singin' in the rain'
+ 1257: 'Alice in Wonderland'
+ 1258: 'The wizard of Oz'
+ 1259: 'I'm singin' in the rain'
+ 1260: 'Alice in Wonderland'
+ 1261: 'The wizard of Oz'
+ 1262: 'I'm singin' in the rain'
+ 1263: 'Alice in Wonderland'
+ 1264: 'The wizard of Oz'
+ 1265: 'I'm singin' in the rain'
+ 1266: 'Alice in Wonderland'
+ 1267: 'The wizard of Oz'
+ 1268: 'I'm singin' in the rain'
+ 1269: 'Alice in Wonderland'
+ 1270: 'The wizard of Oz'
+ 1271: 'I'm singin' in the rain'
+ 1272: 'Alice in Wonderland'
+ 1273: 'The wizard of Oz'
+ 1274: 'I'm singin' in the rain'
+ 1275: 'Alice in Wonderland'
+ 1276: 'The wizard of Oz'
+ 1277: 'I'm singin' in the rain'
+ 1278: 'Alice in Wonderland'
+ 1279: 'The wizard of Oz'
+ 1280: 'I'm singin' in the rain'
+ 1281: 'Alice in Wonderland'
+ 1282: 'The wizard of Oz'
+ 1283: 'I'm singin' in the rain'
+ 1284: 'Alice in Wonderland'
+ 1285: 'The wizard of Oz'
+ 1286: 'I'm singin' in the rain'
+ 1287: 'Alice in Wonderland'
+ 1288: 'The wizard of Oz'
+ 1289: 'I'm singin' in the rain'
+ 1290: 'Alice in Wonderland'
+ 1291: 'The wizard of Oz'
+ 1292: 'I'm singin' in the rain'
+ 1293: 'Alice in Wonderland'
+ 1294: 'The wizard of Oz'
+ 1295: 'I'm singin' in the rain'
+ 1296: 'Alice in Wonderland'
+ 1297: 'The wizard of Oz'
+ 1298: 'I'm singin' in the rain'
+ 1299: 'Alice in Wonderland'
+ 1300: 'The wizard of Oz'
+ 1301: 'I'm singin' in the rain'
+ 1302: 'Alice in Wonderland'
+ 1303: 'The wizard of Oz'
+ 1304: 'I'm singin' in the rain'
+ 1305: 'Alice in Wonderland'
+ 1306: 'The wizard of Oz'
+ 1307: 'I'm singin' in the rain'
+ 1308: 'Alice in Wonderland'
+ 1309: 'The wizard of Oz'
+ 1310: 'I'm singin' in the rain'
+ 1311: 'Alice in Wonderland'
+ 1312: 'The wizard of Oz'
+ 1313: 'I'm singin' in the rain'
+ 1314: 'Alice in Wonderland'
+ 1315: 'The wizard of Oz'
+ 1316: 'I'm singin' in the rain'
+ 1317: 'Alice in Wonderland'
+ 1318: 'The wizard of Oz'
+ 1319: 'I'm singin' in the rain'
+ 1320: 'Alice in Wonderland'
+ 1321: 'The wizard of Oz'
+ 1322: 'I'm singin' in the rain'
+ 1323: 'Alice in Wonderland'
+ 1324: 'The wizard of Oz'
+ 1325: 'I'm singin' in the rain'
+ 1326: 'Alice in Wonderland'
+ 1327: 'The wizard of Oz'
+ 1328: 'I'm singin' in the rain'
+ 1329: 'Alice in Wonderland'
+ 1330: 'The wizard of Oz'
+ 1331: 'I'm singin' in the rain'
+ 1332: 'Alice in Wonderland'
+ 1333: 'The wizard of Oz'
+ 1334: 'I'm singin' in the rain'
+ 1335: 'Alice in Wonderland'
+ 1336: 'The wizard of Oz'
+ 1337: 'I'm singin' in the rain'
+ 1338: 'Alice in Wonderland'
+ 1339: 'The wizard of Oz'
+ 1340: 'I'm singin' in the rain'
+ 1341: 'Alice in Wonderland'
+ 1342: 'The wizard of Oz'
+ 1343: 'I'm singin' in the rain'
+ 1344: 'Alice in Wonderland'
+ 1345: 'The wizard of Oz'
+ 1346: 'I'm singin' in the rain'
+ 1347: 'Alice in Wonderland'
+ 1348: 'The wizard of Oz'
+ 1349: 'I'm singin' in the rain'
+ 1350: 'Alice in Wonderland'
+ 1351: 'The wizard of Oz'
+ 1352: 'I'm singin' in the rain'
+ 1353: 'Alice in Wonderland'
+ 1354: 'The wizard of Oz'
+ 1355: 'I'm singin' in the rain'
+ 1356: 'Alice in Wonderland'
+ 1357: 'The wizard of Oz'
+ 1358: 'I'm singin' in the rain'
+ 1359: 'Alice in Wonderland'
+ 1360: 'The wizard of Oz'
+ 1361: 'I'm singin' in the rain'
+ 1362: 'Alice in Wonderland'
+ 1363: 'The wizard of Oz'
+ 1364: 'I'm singin' in the rain'
+ 1365: 'Alice in Wonderland'
+ 1366: 'The wizard of Oz'
+ 1367: 'I'm singin' in the rain'
+ 1368: 'Alice in Wonderland'
+ 1369: 'The wizard of Oz'
+ 1370: 'I'm singin' in the rain'
+ 1371: 'Alice in Wonderland'
+ 1372: 'The wizard of Oz'
+ 1373: 'I'm singin' in the rain'
+ 1374: 'Alice in Wonderland'
+ 1375: 'The wizard of Oz'
+ 1376: 'I'm singin' in the rain'
+ 1377: 'Alice in Wonderland'
+ 1378: 'The wizard of Oz'
+ 1379: 'I'm singin' in the rain'
+ 1380: 'Alice in Wonderland'
+ 1381: 'The wizard of Oz'
+ 1382: 'I'm singin' in the rain'
+ 1383: 'Alice in Wonderland'
+ 1384: 'The wizard of Oz'
+ 1385: 'I'm singin' in the rain'
+ 1386: 'Alice in Wonderland'
+ 1387: 'The wizard of Oz'
+ 1388: 'I'm singin' in the rain'
+ 1389: 'Alice in Wonderland'
+ 1390: 'The wizard of Oz'
+ 1391: 'I'm singin' in the rain'
+ 1392: 'Alice in Wonderland'
+ 1393: 'The wizard of Oz'
+ 1394: 'I'm singin' in the rain'
+ 1395: 'Alice in Wonderland'
+ 1396: 'The wizard of Oz'
+ 1397: 'I'm singin' in the rain'
+ 1398: 'Alice in Wonderland'
+ 1399: 'The wizard of Oz'
+ 1400: 'I'm singin' in the rain'
+ 1401: 'Alice in Wonderland'
+ 1402: 'The wizard of Oz'
+ 1403: 'I'm singin' in the rain'
+ 1404: 'Alice in Wonderland'
+ 1405: 'The wizard of Oz'
+ 1406: 'I'm singin' in the rain'
+ 1407: 'Alice in Wonderland'
+ 1408: 'The wizard of Oz'
+ 1409: 'I'm singin' in the rain'
+ 1410: 'Alice in Wonderland'
+ 1411: 'The wizard of Oz'
+ 1412: 'I'm singin' in the rain'
+ 1413: 'Alice in Wonderland'
+ 1414: 'The wizard of Oz'
+ 1415: 'I'm singin' in the rain'
+ 1416: 'Alice in Wonderland'
+ 1417: 'The wizard of Oz'
+ 1418: 'I'm singin' in the rain'
+ 1419: 'Alice in Wonderland'
+ 1420: 'The wizard of Oz'
+ 1421: 'I'm singin' in the rain'
+ 1422: 'Alice in Wonderland'
+ 1423: 'The wizard of Oz'
+ 1424: 'I'm singin' in the rain'
+ 1425: 'Alice in Wonderland'
+ 1426: 'The wizard of Oz'
+ 1427: 'I'm singin' in the rain'
+ 1428: 'Alice in Wonderland'
+ 1429: 'The wizard of Oz'
+ 1430: 'I'm singin' in the rain'
+ 1431: 'Alice in Wonderland'
+ 1432: 'The wizard of Oz'
+ 1433: 'I'm singin' in the rain'
+ 1434: 'Alice in Wonderland'
+ 1435: 'The wizard of Oz'
+ 1436: 'I'm singin' in the rain'
+ 1437: 'Alice in Wonderland'
+ 1438: 'The wizard of Oz'
+ 1439: 'I'm singin' in the rain'
+ 1440: 'Alice in Wonderland'
+ 1441: 'The wizard of Oz'
+ 1442: 'I'm singin' in the rain'
+ 1443: 'Alice in Wonderland'
+ 1444: 'The wizard of Oz'
+ 1445: 'I'm singin' in the rain'
+ 1446: 'Alice in Wonderland'
+ 1447: 'The wizard of Oz'
+ 1448: 'I'm singin' in the rain'
+ 1449: 'Alice in Wonderland'
+ 1450: 'The wizard of Oz'
+ 1451: 'I'm singin' in the rain'
+ 1452: 'Alice in Wonderland'
+ 1453: 'The wizard of Oz'
+ 1454: 'I'm singin' in the rain'
+ 1455: 'Alice in Wonderland'
+ 1456: 'The wizard of Oz'
+ 1457: 'I'm singin' in the rain'
+ 1458: 'Alice in Wonderland'
+ 1459: 'The wizard of Oz'
+ 1460: 'I'm singin' in the rain'
+ 1461: 'Alice in Wonderland'
+ 1462: 'The wizard of Oz'
+ 1463: 'I'm singin' in the rain'
+ 1464: 'Alice in Wonderland'
+ 1465: 'The wizard of Oz'
+ 1466: 'I'm singin' in the rain'
+ 1467: 'Alice in Wonderland'
+ 1468: 'The wizard of Oz'
+ 1469: 'I'm singin' in the rain'
+ 1470: 'Alice in Wonderland'
+ 1471: 'The wizard of Oz'
+ 1472: 'I'm singin' in the rain'
+ 1473: 'Alice in Wonderland'
+ 1474: 'The wizard of Oz'
+ 1475: 'I'm singin' in the rain'
+ 1476: 'Alice in Wonderland'
+ 1477: 'The wizard of Oz'
+ 1478: 'I'm singin' in the rain'
+ 1479: 'Alice in Wonderland'
+ 1480: 'The wizard of Oz'
+ 1481: 'I'm singin' in the rain'
+ 1482: 'Alice in Wonderland'
+ 1483: 'The wizard of Oz'
+ 1484: 'I'm singin' in the rain'
+ 1485: 'Alice in Wonderland'
+ 1486: 'The wizard of Oz'
+ 1487: 'I'm singin' in the rain'
+ 1488: 'Alice in Wonderland'
+ 1489: 'The wizard of Oz'
+ 1490: 'I'm singin' in the rain'
+ 1491: 'Alice in Wonderland'
+ 1492: 'The wizard of Oz'
+ 1493: 'I'm singin' in the rain'
+ 1494: 'Alice in Wonderland'
+ 1495: 'The wizard of Oz'
+ 1496: 'I'm singin' in the rain'
+ 1497: 'Alice in Wonderland'
+ 1498: 'The wizard of Oz'
+ 1499: 'I'm singin' in the rain'
+ 1500: 'Alice in Wonderland'
+ 1501: 'The wizard of Oz'
+ 1502: 'I'm singin' in the rain'
+ 1503: 'Alice in Wonderland'
+ 1504: 'The wizard of Oz'
+ 1505: 'I'm singin' in the rain'
+ 1506: 'Alice in Wonderland'
+ 1507: 'The wizard of Oz'
+ 1508: 'I'm singin' in the rain'
+ 1509: 'Alice in Wonderland'
+ 1510: 'The wizard of Oz'
+ 1511: 'I'm singin' in the rain'
+ 1512: 'Alice in Wonderland'
+ 1513: 'The wizard of Oz'
+ 1514: 'I'm singin' in the rain'
+ 1515: 'Alice in Wonderland'
+ 1516: 'The wizard of Oz'
+ 1517: 'I'm singin' in the rain'
+ 1518: 'Alice in Wonderland'
+ 1519: 'The wizard of Oz'
+ 1520: 'I'm singin' in the rain'
+ 1521: 'Alice in Wonderland'
+ 1522: 'The wizard of Oz'
+ 1523: 'I'm singin' in the rain'
+ 1524: 'Alice in Wonderland'
+ 1525: 'The wizard of Oz'
+ 1526: 'I'm singin' in the rain'
+ 1527: 'Alice in Wonderland'
+ 1528: 'The wizard of Oz'
+ 1529: 'I'm singin' in the rain'
+ 1530: 'Alice in Wonderland'
+ 1531: 'The wizard of Oz'
+ 1532: 'I'm singin' in the rain'
+ 1533: 'Alice in Wonderland'
+ 1534: 'The wizard of Oz'
+ 1535: 'I'm singin' in the rain'
+ 1536: 'Alice in Wonderland'
+ 1537: 'The wizard of Oz'
+ 1538: 'I'm singin' in the rain'
+ 1539: 'Alice in Wonderland'
+ 1540: 'The wizard of Oz'
+ 1541: 'I'm singin' in the rain'
+ 1542: 'Alice in Wonderland'
+ 1543: 'The wizard of Oz'
+ 1544: 'I'm singin' in the rain'
+ 1545: 'Alice in Wonderland'
+ 1546: 'The wizard of Oz'
+ 1547: 'I'm singin' in the rain'
+ 1548: 'Alice in Wonderland'
+ 1549: 'The wizard of Oz'
+ 1550: 'I'm singin' in the rain'
+ 1551: 'Alice in Wonderland'
+ 1552: 'The wizard of Oz'
+ 1553: 'I'm singin' in the rain'
+ 1554: 'Alice in Wonderland'
+ 1555: 'The wizard of Oz'
+ 1556: 'I'm singin' in the rain'
+ 1557: 'Alice in Wonderland'
+ 1558: 'The wizard of Oz'
+ 1559: 'I'm singin' in the rain'
+ 1560: 'Alice in Wonderland'
+ 1561: 'The wizard of Oz'
+ 1562: 'I'm singin' in the rain'
+ 1563: 'Alice in Wonderland'
+ 1564: 'The wizard of Oz'
+ 1565: 'I'm singin' in the rain'
+ 1566: 'Alice in Wonderland'
+ 1567: 'The wizard of Oz'
+ 1568: 'I'm singin' in the rain'
+ 1569: 'Alice in Wonderland'
+ 1570: 'The wizard of Oz'
+ 1571: 'I'm singin' in the rain'
+ 1572: 'Alice in Wonderland'
+ 1573: 'The wizard of Oz'
+ 1574: 'I'm singin' in the rain'
+ 1575: 'Alice in Wonderland'
+ 1576: 'The wizard of Oz'
+ 1577: 'I'm singin' in the rain'
+ 1578: 'Alice in Wonderland'
+ 1579: 'The wizard of Oz'
+ 1580: 'I'm singin' in the rain'
+ 1581: 'Alice in Wonderland'
+ 1582: 'The wizard of Oz'
+ 1583: 'I'm singin' in the rain'
+ 1584: 'Alice in Wonderland'
+ 1585: 'The wizard of Oz'
+ 1586: 'I'm singin' in the rain'
+ 1587: 'Alice in Wonderland'
+ 1588: 'The wizard of Oz'
+ 1589: 'I'm singin' in the rain'
+ 1590: 'Alice in Wonderland'
+ 1591: 'The wizard of Oz'
+ 1592: 'I'm singin' in the rain'
+ 1593: 'Alice in Wonderland'
+ 1594: 'The wizard of Oz'
+ 1595: 'I'm singin' in the rain'
+ 1596: 'Alice in Wonderland'
+ 1597: 'The wizard of Oz'
+ 1598: 'I'm singin' in the rain'
+ 1599: 'Alice in Wonderland'
+ 1600: 'The wizard of Oz'
+ 1601: 'I'm singin' in the rain'
+ 1602: 'Alice in Wonderland'
+ 1603: 'The wizard of Oz'
+ 1604: 'I'm singin' in the rain'
+ 1605: 'Alice in Wonderland'
+ 1606: 'The wizard of Oz'
+ 1607: 'I'm singin' in the rain'
+ 1608: 'Alice in Wonderland'
+ 1609: 'The wizard of Oz'
+ 1610: 'I'm singin' in the rain'
+ 1611: 'Alice in Wonderland'
+ 1612: 'The wizard of Oz'
+ 1613: 'I'm singin' in the rain'
+ 1614: 'Alice in Wonderland'
+ 1615: 'The wizard of Oz'
+ 1616: 'I'm singin' in the rain'
+ 1617: 'Alice in Wonderland'
+ 1618: 'The wizard of Oz'
+ 1619: 'I'm singin' in the rain'
+ 1620: 'Alice in Wonderland'
+ 1621: 'The wizard of Oz'
+ 1622: 'I'm singin' in the rain'
+ 1623: 'Alice in Wonderland'
+ 1624: 'The wizard of Oz'
+ 1625: 'I'm singin' in the rain'
+ 1626: 'Alice in Wonderland'
+ 1627: 'The wizard of Oz'
+ 1628: 'I'm singin' in the rain'
+ 1629: 'Alice in Wonderland'
+ 1630: 'The wizard of Oz'
+ 1631: 'I'm singin' in the rain'
+ 1632: 'Alice in Wonderland'
+ 1633: 'The wizard of Oz'
+ 1634: 'I'm singin' in the rain'
+ 1635: 'Alice in Wonderland'
+ 1636: 'The wizard of Oz'
+ 1637: 'I'm singin' in the rain'
+ 1638: 'Alice in Wonderland'
+ 1639: 'The wizard of Oz'
+ 1640: 'I'm singin' in the rain'
+ 1641: 'Alice in Wonderland'
+ 1642: 'The wizard of Oz'
+ 1643: 'I'm singin' in the rain'
+ 1644: 'Alice in Wonderland'
+ 1645: 'The wizard of Oz'
+ 1646: 'I'm singin' in the rain'
+ 1647: 'Alice in Wonderland'
+ 1648: 'The wizard of Oz'
+ 1649: 'I'm singin' in the rain'
+ 1650: 'Alice in Wonderland'
+ 1651: 'The wizard of Oz'
+ 1652: 'I'm singin' in the rain'
+ 1653: 'Alice in Wonderland'
+ 1654: 'The wizard of Oz'
+ 1655: 'I'm singin' in the rain'
+ 1656: 'Alice in Wonderland'
+ 1657: 'The wizard of Oz'
+ 1658: 'I'm singin' in the rain'
+ 1659: 'Alice in Wonderland'
+ 1660: 'The wizard of Oz'
+ 1661: 'I'm singin' in the rain'
+ 1662: 'Alice in Wonderland'
+ 1663: 'The wizard of Oz'
+ 1664: 'I'm singin' in the rain'
+ 1665: 'Alice in Wonderland'
+ 1666: 'The wizard of Oz'
+ 1667: 'I'm singin' in the rain'
+ 1668: 'Alice in Wonderland'
+ 1669: 'The wizard of Oz'
+ 1670: 'I'm singin' in the rain'
+ 1671: 'Alice in Wonderland'
+ 1672: 'The wizard of Oz'
+ 1673: 'I'm singin' in the rain'
+ 1674: 'Alice in Wonderland'
+ 1675: 'The wizard of Oz'
+ 1676: 'I'm singin' in the rain'
+ 1677: 'Alice in Wonderland'
+ 1678: 'The wizard of Oz'
+ 1679: 'I'm singin' in the rain'
+ 1680: 'Alice in Wonderland'
+ 1681: 'The wizard of Oz'
+ 1682: 'I'm singin' in the rain'
+ 1683: 'Alice in Wonderland'
+ 1684: 'The wizard of Oz'
+ 1685: 'I'm singin' in the rain'
+ 1686: 'Alice in Wonderland'
+ 1687: 'The wizard of Oz'
+ 1688: 'I'm singin' in the rain'
+ 1689: 'Alice in Wonderland'
+ 1690: 'The wizard of Oz'
+ 1691: 'I'm singin' in the rain'
+ 1692: 'Alice in Wonderland'
+ 1693: 'The wizard of Oz'
+ 1694: 'I'm singin' in the rain'
+ 1695: 'Alice in Wonderland'
+ 1696: 'The wizard of Oz'
+ 1697: 'I'm singin' in the rain'
+ 1698: 'Alice in Wonderland'
+ 1699: 'The wizard of Oz'
+ 1700: 'I'm singin' in the rain'
+ 1701: 'Alice in Wonderland'
+ 1702: 'The wizard of Oz'
+ 1703: 'I'm singin' in the rain'
+ 1704: 'Alice in Wonderland'
+ 1705: 'The wizard of Oz'
+ 1706: 'I'm singin' in the rain'
+ 1707: 'Alice in Wonderland'
+ 1708: 'The wizard of Oz'
+ 1709: 'I'm singin' in the rain'
+ 1710: 'Alice in Wonderland'
+ 1711: 'The wizard of Oz'
+ 1712: 'I'm singin' in the rain'
+ 1713: 'Alice in Wonderland'
+ 1714: 'The wizard of Oz'
+ 1715: 'I'm singin' in the rain'
+ 1716: 'Alice in Wonderland'
+ 1717: 'The wizard of Oz'
+ 1718: 'I'm singin' in the rain'
+ 1719: 'Alice in Wonderland'
+ 1720: 'The wizard of Oz'
+ 1721: 'I'm singin' in the rain'
+ 1722: 'Alice in Wonderland'
+ 1723: 'The wizard of Oz'
+ 1724: 'I'm singin' in the rain'
+ 1725: 'Alice in Wonderland'
+ 1726: 'The wizard of Oz'
+ 1727: 'I'm singin' in the rain'
+ 1728: 'Alice in Wonderland'
+ 1729: 'The wizard of Oz'
+ 1730: 'I'm singin' in the rain'
+ 1731: 'Alice in Wonderland'
+ 1732: 'The wizard of Oz'
+ 1733: 'I'm singin' in the rain'
+ 1734: 'Alice in Wonderland'
+ 1735: 'The wizard of Oz'
+ 1736: 'I'm singin' in the rain'
+ 1737: 'Alice in Wonderland'
+ 1738: 'The wizard of Oz'
+ 1739: 'I'm singin' in the rain'
+ 1740: 'Alice in Wonderland'
+ 1741: 'The wizard of Oz'
+ 1742: 'I'm singin' in the rain'
+ 1743: 'Alice in Wonderland'
+ 1744: 'The wizard of Oz'
+ 1745: 'I'm singin' in the rain'
+ 1746: 'Alice in Wonderland'
+ 1747: 'The wizard of Oz'
+ 1748: 'I'm singin' in the rain'
+ 1749: 'Alice in Wonderland'
+ 1750: 'The wizard of Oz'
+ 1751: 'I'm singin' in the rain'
+ 1752: 'Alice in Wonderland'
+ 1753: 'The wizard of Oz'
+ 1754: 'I'm singin' in the rain'
+ 1755: 'Alice in Wonderland'
+ 1756: 'The wizard of Oz'
+ 1757: 'I'm singin' in the rain'
+ 1758: 'Alice in Wonderland'
+ 1759: 'The wizard of Oz'
+ 1760: 'I'm singin' in the rain'
+ 1761: 'Alice in Wonderland'
+ 1762: 'The wizard of Oz'
+ 1763: 'I'm singin' in the rain'
+ 1764: 'Alice in Wonderland'
+ 1765: 'The wizard of Oz'
+ 1766: 'I'm singin' in the rain'
+ 1767: 'Alice in Wonderland'
+ 1768: 'The wizard of Oz'
+ 1769: 'I'm singin' in the rain'
+ 1770: 'Alice in Wonderland'
+ 1771: 'The wizard of Oz'
+ 1772: 'I'm singin' in the rain'
+ 1773: 'Alice in Wonderland'
+ 1774: 'The wizard of Oz'
+ 1775: 'I'm singin' in the rain'
+ 1776: 'Alice in Wonderland'
+ 1777: 'The wizard of Oz'
+ 1778: 'I'm singin' in the rain'
+ 1779: 'Alice in Wonderland'
+ 1780: 'The wizard of Oz'
+ 1781: 'I'm singin' in the rain'
+ 1782: 'Alice in Wonderland'
+ 1783: 'The wizard of Oz'
+ 1784: 'I'm singin' in the rain'
+ 1785: 'Alice in Wonderland'
+ 1786: 'The wizard of Oz'
+ 1787: 'I'm singin' in the rain'
+ 1788: 'Alice in Wonderland'
+ 1789: 'The wizard of Oz'
+ 1790: 'I'm singin' in the rain'
+ 1791: 'Alice in Wonderland'
+ 1792: 'The wizard of Oz'
+ 1793: 'I'm singin' in the rain'
+ 1794: 'Alice in Wonderland'
+ 1795: 'The wizard of Oz'
+ 1796: 'I'm singin' in the rain'
+ 1797: 'Alice in Wonderland'
+ 1798: 'The wizard of Oz'
+ 1799: 'I'm singin' in the rain'
+ 1800: 'Alice in Wonderland'
+ 1801: 'The wizard of Oz'
+ 1802: 'I'm singin' in the rain'
+ 1803: 'Alice in Wonderland'
+ 1804: 'The wizard of Oz'
+ 1805: 'I'm singin' in the rain'
+ 1806: 'Alice in Wonderland'
+ 1807: 'The wizard of Oz'
+ 1808: 'I'm singin' in the rain'
+ 1809: 'Alice in Wonderland'
+ 1810: 'The wizard of Oz'
+ 1811: 'I'm singin' in the rain'
+ 1812: 'Alice in Wonderland'
+ 1813: 'The wizard of Oz'
+ 1814: 'I'm singin' in the rain'
+ 1815: 'Alice in Wonderland'
+ 1816: 'The wizard of Oz'
+ 1817: 'I'm singin' in the rain'
+ 1818: 'Alice in Wonderland'
+ 1819: 'The wizard of Oz'
+ 1820: 'I'm singin' in the rain'
+ 1821: 'Alice in Wonderland'
+ 1822: 'The wizard of Oz'
+ 1823: 'I'm singin' in the rain'
+ 1824: 'Alice in Wonderland'
+ 1825: 'The wizard of Oz'
+ 1826: 'I'm singin' in the rain'
+ 1827: 'Alice in Wonderland'
+ 1828: 'The wizard of Oz'
+ 1829: 'I'm singin' in the rain'
+ 1830: 'Alice in Wonderland'
+ 1831: 'The wizard of Oz'
+ 1832: 'I'm singin' in the rain'
+ 1833: 'Alice in Wonderland'
+ 1834: 'The wizard of Oz'
+ 1835: 'I'm singin' in the rain'
+ 1836: 'Alice in Wonderland'
+ 1837: 'The wizard of Oz'
+ 1838: 'I'm singin' in the rain'
+ 1839: 'Alice in Wonderland'
+ 1840: 'The wizard of Oz'
+ 1841: 'I'm singin' in the rain'
+ 1842: 'Alice in Wonderland'
+ 1843: 'The wizard of Oz'
+ 1844: 'I'm singin' in the rain'
+ 1845: 'Alice in Wonderland'
+ 1846: 'The wizard of Oz'
+ 1847: 'I'm singin' in the rain'
+ 1848: 'Alice in Wonderland'
+ 1849: 'The wizard of Oz'
+ 1850: 'I'm singin' in the rain'
+ 1851: 'Alice in Wonderland'
+ 1852: 'The wizard of Oz'
+ 1853: 'I'm singin' in the rain'
+ 1854: 'Alice in Wonderland'
+ 1855: 'The wizard of Oz'
+ 1856: 'I'm singin' in the rain'
+ 1857: 'Alice in Wonderland'
+ 1858: 'The wizard of Oz'
+ 1859: 'I'm singin' in the rain'
+ 1860: 'Alice in Wonderland'
+ 1861: 'The wizard of Oz'
+ 1862: 'I'm singin' in the rain'
+ 1863: 'Alice in Wonderland'
+ 1864: 'The wizard of Oz'
+ 1865: 'I'm singin' in the rain'
+ 1866: 'Alice in Wonderland'
+ 1867: 'The wizard of Oz'
+ 1868: 'I'm singin' in the rain'
+ 1869: 'Alice in Wonderland'
+ 1870: 'The wizard of Oz'
+ 1871: 'I'm singin' in the rain'
+ 1872: 'Alice in Wonderland'
+ 1873: 'The wizard of Oz'
+ 1874: 'I'm singin' in the rain'
+ 1875: 'Alice in Wonderland'
+ 1876: 'The wizard of Oz'
+ 1877: 'I'm singin' in the rain'
+ 1878: 'Alice in Wonderland'
+ 1879: 'The wizard of Oz'
+ 1880: 'I'm singin' in the rain'
+ 1881: 'Alice in Wonderland'
+ 1882: 'The wizard of Oz'
+ 1883: 'I'm singin' in the rain'
+ 1884: 'Alice in Wonderland'
+ 1885: 'The wizard of Oz'
+ 1886: 'I'm singin' in the rain'
+ 1887: 'Alice in Wonderland'
+ 1888: 'The wizard of Oz'
+ 1889: 'I'm singin' in the rain'
+ 1890: 'Alice in Wonderland'
+ 1891: 'The wizard of Oz'
+ 1892: 'I'm singin' in the rain'
+ 1893: 'Alice in Wonderland'
+ 1894: 'The wizard of Oz'
+ 1895: 'I'm singin' in the rain'
+ 1896: 'Alice in Wonderland'
+ 1897: 'The wizard of Oz'
+ 1898: 'I'm singin' in the rain'
+ 1899: 'Alice in Wonderland'
+ 1900: 'The wizard of Oz'
+ 1901: 'I'm singin' in the rain'
+ 1902: 'Alice in Wonderland'
+ 1903: 'The wizard of Oz'
+ 1904: 'I'm singin' in the rain'
+ 1905: 'Alice in Wonderland'
+ 1906: 'The wizard of Oz'
+ 1907: 'I'm singin' in the rain'
+ 1908: 'Alice in Wonderland'
+ 1909: 'The wizard of Oz'
+ 1910: 'I'm singin' in the rain'
+ 1911: 'Alice in Wonderland'
+ 1912: 'The wizard of Oz'
+ 1913: 'I'm singin' in the rain'
+ 1914: 'Alice in Wonderland'
+ 1915: 'The wizard of Oz'
+ 1916: 'I'm singin' in the rain'
+ 1917: 'Alice in Wonderland'
+ 1918: 'The wizard of Oz'
+ 1919: 'I'm singin' in the rain'
+ 1920: 'Alice in Wonderland'
+ 1921: 'The wizard of Oz'
+ 1922: 'I'm singin' in the rain'
+ 1923: 'Alice in Wonderland'
+ 1924: 'The wizard of Oz'
+ 1925: 'I'm singin' in the rain'
+ 1926: 'Alice in Wonderland'
+ 1927: 'The wizard of Oz'
+ 1928: 'I'm singin' in the rain'
+ 1929: 'Alice in Wonderland'
+ 1930: 'The wizard of Oz'
+ 1931: 'I'm singin' in the rain'
+ 1932: 'Alice in Wonderland'
+ 1933: 'The wizard of Oz'
+ 1934: 'I'm singin' in the rain'
+ 1935: 'Alice in Wonderland'
+ 1936: 'The wizard of Oz'
+ 1937: 'I'm singin' in the rain'
+ 1938: 'Alice in Wonderland'
+ 1939: 'The wizard of Oz'
+ 1940: 'I'm singin' in the rain'
+ 1941: 'Alice in Wonderland'
+ 1942: 'The wizard of Oz'
+ 1943: 'I'm singin' in the rain'
+ 1944: 'Alice in Wonderland'
+ 1945: 'The wizard of Oz'
+ 1946: 'I'm singin' in the rain'
+ 1947: 'Alice in Wonderland'
+ 1948: 'The wizard of Oz'
+ 1949: 'I'm singin' in the rain'
+ 1950: 'Alice in Wonderland'
+ 1951: 'The wizard of Oz'
+ 1952: 'I'm singin' in the rain'
+ 1953: 'Alice in Wonderland'
+ 1954: 'The wizard of Oz'
+ 1955: 'I'm singin' in the rain'
+ 1956: 'Alice in Wonderland'
+ 1957: 'The wizard of Oz'
+ 1958: 'I'm singin' in the rain'
+ 1959: 'Alice in Wonderland'
+ 1960: 'The wizard of Oz'
+ 1961: 'I'm singin' in the rain'
+ 1962: 'Alice in Wonderland'
+ 1963: 'The wizard of Oz'
+ 1964: 'I'm singin' in the rain'
+ 1965: 'Alice in Wonderland'
+ 1966: 'The wizard of Oz'
+ 1967: 'I'm singin' in the rain'
+ 1968: 'Alice in Wonderland'
+ 1969: 'The wizard of Oz'
+ 1970: 'I'm singin' in the rain'
+ 1971: 'Alice in Wonderland'
+ 1972: 'The wizard of Oz'
+ 1973: 'I'm singin' in the rain'
+ 1974: 'Alice in Wonderland'
+ 1975: 'The wizard of Oz'
+ 1976: 'I'm singin' in the rain'
+ 1977: 'Alice in Wonderland'
+ 1978: 'The wizard of Oz'
+ 1979: 'I'm singin' in the rain'
+ 1980: 'Alice in Wonderland'
+ 1981: 'The wizard of Oz'
+ 1982: 'I'm singin' in the rain'
+ 1983: 'Alice in Wonderland'
+ 1984: 'The wizard of Oz'
+ 1985: 'I'm singin' in the rain'
+ 1986: 'Alice in Wonderland'
+ 1987: 'The wizard of Oz'
+ 1988: 'I'm singin' in the rain'
+ 1989: 'Alice in Wonderland'
+ 1990: 'The wizard of Oz'
+ 1991: 'I'm singin' in the rain'
+ 1992: 'Alice in Wonderland'
+ 1993: 'The wizard of Oz'
+ 1994: 'I'm singin' in the rain'
+ 1995: 'Alice in Wonderland'
+ 1996: 'The wizard of Oz'
+ 1997: 'I'm singin' in the rain'
+ 1998: 'Alice in Wonderland'
+ 1999: 'The wizard of Oz'
+ 2000: 'I'm singin' in the rain'
+ 2001: 'Alice in Wonderland'
+ 2002: 'The wizard of Oz'
+ 2003: 'I'm singin' in the rain'
+ 2004: 'Alice in Wonderland'
+ 2005: 'The wizard of Oz'
+ 2006: 'I'm singin' in the rain'
+ 2007: 'Alice in Wonderland'
+ 2008: 'The wizard of Oz'
+ 2009: 'I'm singin' in the rain'
+ 2010: 'Alice in Wonderland'
+ 2011: 'The wizard of Oz'
+ 2012: 'I'm singin' in the rain'
+ 2013: 'Alice in Wonderland'
+ 2014: 'The wizard of Oz'
+ 2015: 'I'm singin' in the rain'
+ 2016: 'Alice in Wonderland'
+ 2017: 'The wizard of Oz'
+ 2018: 'I'm singin' in the rain'
+ 2019: 'Alice in Wonderland'
+ 2020: 'The wizard of Oz'
+ 2021: 'I'm singin' in the rain'
+ 2022: 'Alice in Wonderland'
+ 2023: 'The wizard of Oz'
+ 2024: 'I'm singin' in the rain'
+ 2025: 'Alice in Wonderland'
+ 2026: 'The wizard of Oz'
+ 2027: 'I'm singin' in the rain'
+ 2028: 'Alice in Wonderland'
+ 2029: 'The wizard of Oz'
+ 2030: 'I'm singin' in the rain'
+ 2031: 'Alice in Wonderland'
+ 2032: 'The wizard of Oz'
+ 2033: 'I'm singin' in the rain'
+ 2034: 'Alice in Wonderland'
+ 2035: 'The wizard of Oz'
+ 2036: 'I'm singin' in the rain'
+ 2037: 'Alice in Wonderland'
+ 2038: 'The wizard of Oz'
+ 2039: 'I'm singin' in the rain'
+ 2040: 'Alice in Wonderland'
+ 2041: 'The wizard of Oz'
+ 2042: 'I'm singin' in the rain'
+ 2043: 'Alice in Wonderland'
+ 2044: 'The wizard of Oz'
+ 2045: 'I'm singin' in the rain'
+ 2046: 'Alice in Wonderland'
+ 2047: 'The wizard of Oz'
+ 2048: 'I'm singin' in the rain'
+ 2049: 'Alice in Wonderland'
+ 2050: 'The wizard of Oz'
+ 2051: 'I'm singin' in the rain'
+ 2052: 'Alice in Wonderland'
+ 2053: 'The wizard of Oz'
+ 2054: 'I'm singin' in the rain'
+ 2055: 'Alice in Wonderland'
+ 2056: 'The wizard of Oz'
+ 2057: 'I'm singin' in the rain'
+ 2058: 'Alice in Wonderland'
+ 2059: 'The wizard of Oz'
+ 2060: 'I'm singin' in the rain'
+ 2061: 'Alice in Wonderland'
+ 2062: 'The wizard of Oz'
+ 2063: 'I'm singin' in the rain'
+ 2064: 'Alice in Wonderland'
+ 2065: 'The wizard of Oz'
+ 2066: 'I'm singin' in the rain'
+ 2067: 'Alice in Wonderland'
+ 2068: 'The wizard of Oz'
+ 2069: 'I'm singin' in the rain'
+ 2070: 'Alice in Wonderland'
+ 2071: 'The wizard of Oz'
+ 2072: 'I'm singin' in the rain'
+ 2073: 'Alice in Wonderland'
+ 2074: 'The wizard of Oz'
+ 2075: 'I'm singin' in the rain'
+ 2076: 'Alice in Wonderland'
+ 2077: 'The wizard of Oz'
+ 2078: 'I'm singin' in the rain'
+ 2079: 'Alice in Wonderland'
+ 2080: 'The wizard of Oz'
+ 2081: 'I'm singin' in the rain'
+ 2082: 'Alice in Wonderland'
+ 2083: 'The wizard of Oz'
+ 2084: 'I'm singin' in the rain'
+ 2085: 'Alice in Wonderland'
+ 2086: 'The wizard of Oz'
+ 2087: 'I'm singin' in the rain'
+ 2088: 'Alice in Wonderland'
+ 2089: 'The wizard of Oz'
+ 2090: 'I'm singin' in the rain'
+ 2091: 'Alice in Wonderland'
+ 2092: 'The wizard of Oz'
+ 2093: 'I'm singin' in the rain'
+ 2094: 'Alice in Wonderland'
+ 2095: 'The wizard of Oz'
+ 2096: 'I'm singin' in the rain'
+ 2097: 'Alice in Wonderland'
+ 2098: 'The wizard of Oz'
+ 2099: 'I'm singin' in the rain'
+ 2100: 'Alice in Wonderland'
+ 2101: 'The wizard of Oz'
+ 2102: 'I'm singin' in the rain'
+ 2103: 'Alice in Wonderland'
+ 2104: 'The wizard of Oz'
+ 2105: 'I'm singin' in the rain'
+ 2106: 'Alice in Wonderland'
+ 2107: 'The wizard of Oz'
+ 2108: 'I'm singin' in the rain'
+ 2109: 'Alice in Wonderland'
+ 2110: 'The wizard of Oz'
+ 2111: 'I'm singin' in the rain'
+ 2112: 'Alice in Wonderland'
+ 2113: 'The wizard of Oz'
+ 2114: 'I'm singin' in the rain'
+ 2115: 'Alice in Wonderland'
+ 2116: 'The wizard of Oz'
+ 2117: 'I'm singin' in the rain'
+ 2118: 'Alice in Wonderland'
+ 2119: 'The wizard of Oz'
+ 2120: 'I'm singin' in the rain'
+ 2121: 'Alice in Wonderland'
+ 2122: 'The wizard of Oz'
+ 2123: 'I'm singin' in the rain'
+ 2124: 'Alice in Wonderland'
+ 2125: 'The wizard of Oz'
+ 2126: 'I'm singin' in the rain'
+ 2127: 'Alice in Wonderland'
+ 2128: 'The wizard of Oz'
+ 2129: 'I'm singin' in the rain'
+ 2130: 'Alice in Wonderland'
+ 2131: 'The wizard of Oz'
+ 2132: 'I'm singin' in the rain'
+ 2133: 'Alice in Wonderland'
+ 2134: 'The wizard of Oz'
+ 2135: 'I'm singin' in the rain'
+ 2136: 'Alice in Wonderland'
+ 2137: 'The wizard of Oz'
+ 2138: 'I'm singin' in the rain'
+ 2139: 'Alice in Wonderland'
+ 2140: 'The wizard of Oz'
+ 2141: 'I'm singin' in the rain'
+ 2142: 'Alice in Wonderland'
+ 2143: 'The wizard of Oz'
+ 2144: 'I'm singin' in the rain'
+ 2145: 'Alice in Wonderland'
+ 2146: 'The wizard of Oz'
+ 2147: 'I'm singin' in the rain'
+ 2148: 'Alice in Wonderland'
+ 2149: 'The wizard of Oz'
+ 2150: 'I'm singin' in the rain'
+ 2151: 'Alice in Wonderland'
+ 2152: 'The wizard of Oz'
+ 2153: 'I'm singin' in the rain'
+ 2154: 'Alice in Wonderland'
+ 2155: 'The wizard of Oz'
+ 2156: 'I'm singin' in the rain'
+ 2157: 'Alice in Wonderland'
+ 2158: 'The wizard of Oz'
+ 2159: 'I'm singin' in the rain'
+ 2160: 'Alice in Wonderland'
+ 2161: 'The wizard of Oz'
+ 2162: 'I'm singin' in the rain'
+ 2163: 'Alice in Wonderland'
+ 2164: 'The wizard of Oz'
+ 2165: 'I'm singin' in the rain'
+ 2166: 'Alice in Wonderland'
+ 2167: 'The wizard of Oz'
+ 2168: 'I'm singin' in the rain'
+ 2169: 'Alice in Wonderland'
+ 2170: 'The wizard of Oz'
+ 2171: 'I'm singin' in the rain'
+ 2172: 'Alice in Wonderland'
+ 2173: 'The wizard of Oz'
+ 2174: 'I'm singin' in the rain'
+ 2175: 'Alice in Wonderland'
+ 2176: 'The wizard of Oz'
+ 2177: 'I'm singin' in the rain'
+ 2178: 'Alice in Wonderland'
+ 2179: 'The wizard of Oz'
+ 2180: 'I'm singin' in the rain'
+ 2181: 'Alice in Wonderland'
+ 2182: 'The wizard of Oz'
+ 2183: 'I'm singin' in the rain'
+ 2184: 'Alice in Wonderland'
+ 2185: 'The wizard of Oz'
+ 2186: 'I'm singin' in the rain'
+ 2187: 'Alice in Wonderland'
+ 2188: 'The wizard of Oz'
+ 2189: 'I'm singin' in the rain'
+ 2190: 'Alice in Wonderland'
+ 2191: 'The wizard of Oz'
+ 2192: 'I'm singin' in the rain'
+ 2193: 'Alice in Wonderland'
+ 2194: 'The wizard of Oz'
+ 2195: 'I'm singin' in the rain'
+ 2196: 'Alice in Wonderland'
+ 2197: 'The wizard of Oz'
+ 2198: 'I'm singin' in the rain'
+ 2199: 'Alice in Wonderland'
+ 2200: 'The wizard of Oz'
+ 2201: 'I'm singin' in the rain'
+ 2202: 'Alice in Wonderland'
+ 2203: 'The wizard of Oz'
+ 2204: 'I'm singin' in the rain'
+ 2205: 'Alice in Wonderland'
+ 2206: 'The wizard of Oz'
+ 2207: 'I'm singin' in the rain'
+ 2208: 'Alice in Wonderland'
+ 2209: 'The wizard of Oz'
+ 2210: 'I'm singin' in the rain'
+ 2211: 'Alice in Wonderland'
+ 2212: 'The wizard of Oz'
+ 2213: 'I'm singin' in the rain'
+ 2214: 'Alice in Wonderland'
+ 2215: 'The wizard of Oz'
+ 2216: 'I'm singin' in the rain'
+ 2217: 'Alice in Wonderland'
+ 2218: 'The wizard of Oz'
+ 2219: 'I'm singin' in the rain'
+ 2220: 'Alice in Wonderland'
+ 2221: 'The wizard of Oz'
+ 2222: 'I'm singin' in the rain'
+ 2223: 'Alice in Wonderland'
+ 2224: 'The wizard of Oz'
+ 2225: 'I'm singin' in the rain'
+ 2226: 'Alice in Wonderland'
+ 2227: 'The wizard of Oz'
+ 2228: 'I'm singin' in the rain'
+ 2229: 'Alice in Wonderland'
+ 2230: 'The wizard of Oz'
+ 2231: 'I'm singin' in the rain'
+ 2232: 'Alice in Wonderland'
+ 2233: 'The wizard of Oz'
+ 2234: 'I'm singin' in the rain'
+ 2235: 'Alice in Wonderland'
+ 2236: 'The wizard of Oz'
+ 2237: 'I'm singin' in the rain'
+ 2238: 'Alice in Wonderland'
+ 2239: 'The wizard of Oz'
+ 2240: 'I'm singin' in the rain'
+ 2241: 'Alice in Wonderland'
+ 2242: 'The wizard of Oz'
+ 2243: 'I'm singin' in the rain'
+ 2244: 'Alice in Wonderland'
+ 2245: 'The wizard of Oz'
+ 2246: 'I'm singin' in the rain'
+ 2247: 'Alice in Wonderland'
+ 2248: 'The wizard of Oz'
+ 2249: 'I'm singin' in the rain'
+ 2250: 'Alice in Wonderland'
+ 2251: 'The wizard of Oz'
+ 2252: 'I'm singin' in the rain'
+ 2253: 'Alice in Wonderland'
+ 2254: 'The wizard of Oz'
+ 2255: 'I'm singin' in the rain'
+ 2256: 'Alice in Wonderland'
+ 2257: 'The wizard of Oz'
+ 2258: 'I'm singin' in the rain'
+ 2259: 'Alice in Wonderland'
+ 2260: 'The wizard of Oz'
+ 2261: 'I'm singin' in the rain'
+ 2262: 'Alice in Wonderland'
+ 2263: 'The wizard of Oz'
+ 2264: 'I'm singin' in the rain'
+ 2265: 'Alice in Wonderland'
+ 2266: 'The wizard of Oz'
+ 2267: 'I'm singin' in the rain'
+ 2268: 'Alice in Wonderland'
+ 2269: 'The wizard of Oz'
+ 2270: 'I'm singin' in the rain'
+ 2271: 'Alice in Wonderland'
+ 2272: 'The wizard of Oz'
+ 2273: 'I'm singin' in the rain'
+ 2274: 'Alice in Wonderland'
+ 2275: 'The wizard of Oz'
+ 2276: 'I'm singin' in the rain'
+ 2277: 'Alice in Wonderland'
+ 2278: 'The wizard of Oz'
+ 2279: 'I'm singin' in the rain'
+ 2280: 'Alice in Wonderland'
+ 2281: 'The wizard of Oz'
+ 2282: 'I'm singin' in the rain'
+ 2283: 'Alice in Wonderland'
+ 2284: 'The wizard of Oz'
+ 2285: 'I'm singin' in the rain'
+ 2286: 'Alice in Wonderland'
+ 2287: 'The wizard of Oz'
+ 2288: 'I'm singin' in the rain'
+ 2289: 'Alice in Wonderland'
+ 2290: 'The wizard of Oz'
+ 2291: 'I'm singin' in the rain'
+ 2292: 'Alice in Wonderland'
+ 2293: 'The wizard of Oz'
+ 2294: 'I'm singin' in the rain'
+ 2295: 'Alice in Wonderland'
+ 2296: 'The wizard of Oz'
+ 2297: 'I'm singin' in the rain'
+ 2298: 'Alice in Wonderland'
+ 2299: 'The wizard of Oz'
+ 2300: 'I'm singin' in the rain'
+ 2301: 'Alice in Wonderland'
+ 2302: 'The wizard of Oz'
+ 2303: 'I'm singin' in the rain'
+ 2304: 'Alice in Wonderland'
+ 2305: 'The wizard of Oz'
+ 2306: 'I'm singin' in the rain'
+ 2307: 'Alice in Wonderland'
+ 2308: 'The wizard of Oz'
+ 2309: 'I'm singin' in the rain'
+ 2310: 'Alice in Wonderland'
+ 2311: 'The wizard of Oz'
+ 2312: 'I'm singin' in the rain'
+ 2313: 'Alice in Wonderland'
+ 2314: 'The wizard of Oz'
+ 2315: 'I'm singin' in the rain'
+ 2316: 'Alice in Wonderland'
+ 2317: 'The wizard of Oz'
+ 2318: 'I'm singin' in the rain'
+ 2319: 'Alice in Wonderland'
+ 2320: 'The wizard of Oz'
+ 2321: 'I'm singin' in the rain'
+ 2322: 'Alice in Wonderland'
+ 2323: 'The wizard of Oz'
+ 2324: 'I'm singin' in the rain'
+ 2325: 'Alice in Wonderland'
+ 2326: 'The wizard of Oz'
+ 2327: 'I'm singin' in the rain'
+ 2328: 'Alice in Wonderland'
+ 2329: 'The wizard of Oz'
+ 2330: 'I'm singin' in the rain'
+ 2331: 'Alice in Wonderland'
+ 2332: 'The wizard of Oz'
+ 2333: 'I'm singin' in the rain'
+ 2334: 'Alice in Wonderland'
+ 2335: 'The wizard of Oz'
+ 2336: 'I'm singin' in the rain'
+ 2337: 'Alice in Wonderland'
+ 2338: 'The wizard of Oz'
+ 2339: 'I'm singin' in the rain'
+ 2340: 'Alice in Wonderland'
+ 2341: 'The wizard of Oz'
+ 2342: 'I'm singin' in the rain'
+ 2343: 'Alice in Wonderland'
+ 2344: 'The wizard of Oz'
+ 2345: 'I'm singin' in the rain'
+ 2346: 'Alice in Wonderland'
+ 2347: 'The wizard of Oz'
+ 2348: 'I'm singin' in the rain'
+ 2349: 'Alice in Wonderland'
+ 2350: 'The wizard of Oz'
+ 2351: 'I'm singin' in the rain'
+ 2352: 'Alice in Wonderland'
+ 2353: 'The wizard of Oz'
+ 2354: 'I'm singin' in the rain'
+ 2355: 'Alice in Wonderland'
+ 2356: 'The wizard of Oz'
+ 2357: 'I'm singin' in the rain'
+ 2358: 'Alice in Wonderland'
+ 2359: 'The wizard of Oz'
+ 2360: 'I'm singin' in the rain'
+ 2361: 'Alice in Wonderland'
+ 2362: 'The wizard of Oz'
+ 2363: 'I'm singin' in the rain'
+ 2364: 'Alice in Wonderland'
+ 2365: 'The wizard of Oz'
+ 2366: 'I'm singin' in the rain'
+ 2367: 'Alice in Wonderland'
+ 2368: 'The wizard of Oz'
+ 2369: 'I'm singin' in the rain'
+ 2370: 'Alice in Wonderland'
+ 2371: 'The wizard of Oz'
+ 2372: 'I'm singin' in the rain'
+ 2373: 'Alice in Wonderland'
+ 2374: 'The wizard of Oz'
+ 2375: 'I'm singin' in the rain'
+ 2376: 'Alice in Wonderland'
+ 2377: 'The wizard of Oz'
+ 2378: 'I'm singin' in the rain'
+ 2379: 'Alice in Wonderland'
+ 2380: 'The wizard of Oz'
+ 2381: 'I'm singin' in the rain'
+ 2382: 'Alice in Wonderland'
+ 2383: 'The wizard of Oz'
+ 2384: 'I'm singin' in the rain'
+ 2385: 'Alice in Wonderland'
+ 2386: 'The wizard of Oz'
+ 2387: 'I'm singin' in the rain'
+ 2388: 'Alice in Wonderland'
+ 2389: 'The wizard of Oz'
+ 2390: 'I'm singin' in the rain'
+ 2391: 'Alice in Wonderland'
+ 2392: 'The wizard of Oz'
+ 2393: 'I'm singin' in the rain'
+ 2394: 'Alice in Wonderland'
+ 2395: 'The wizard of Oz'
+ 2396: 'I'm singin' in the rain'
+ 2397: 'Alice in Wonderland'
+ 2398: 'The wizard of Oz'
+ 2399: 'I'm singin' in the rain'
+ 2400: 'Alice in Wonderland'
+ 2401: 'The wizard of Oz'
+ 2402: 'I'm singin' in the rain'
+ 2403: 'Alice in Wonderland'
+ 2404: 'The wizard of Oz'
+ 2405: 'I'm singin' in the rain'
+ 2406: 'Alice in Wonderland'
+ 2407: 'The wizard of Oz'
+ 2408: 'I'm singin' in the rain'
+ 2409: 'Alice in Wonderland'
+ 2410: 'The wizard of Oz'
+ 2411: 'I'm singin' in the rain'
+ 2412: 'Alice in Wonderland'
+ 2413: 'The wizard of Oz'
+ 2414: 'I'm singin' in the rain'
+ 2415: 'Alice in Wonderland'
+ 2416: 'The wizard of Oz'
+ 2417: 'I'm singin' in the rain'
+ 2418: 'Alice in Wonderland'
+ 2419: 'The wizard of Oz'
+ 2420: 'I'm singin' in the rain'
+ 2421: 'Alice in Wonderland'
+ 2422: 'The wizard of Oz'
+ 2423: 'I'm singin' in the rain'
+ 2424: 'Alice in Wonderland'
+ 2425: 'The wizard of Oz'
+ 2426: 'I'm singin' in the rain'
+ 2427: 'Alice in Wonderland'
+ 2428: 'The wizard of Oz'
+ 2429: 'I'm singin' in the rain'
+ 2430: 'Alice in Wonderland'
+ 2431: 'The wizard of Oz'
+ 2432: 'I'm singin' in the rain'
+ 2433: 'Alice in Wonderland'
+ 2434: 'The wizard of Oz'
+ 2435: 'I'm singin' in the rain'
+ 2436: 'Alice in Wonderland'
+ 2437: 'The wizard of Oz'
+ 2438: 'I'm singin' in the rain'
+ 2439: 'Alice in Wonderland'
+ 2440: 'The wizard of Oz'
+ 2441: 'I'm singin' in the rain'
+ 2442: 'Alice in Wonderland'
+ 2443: 'The wizard of Oz'
+ 2444: 'I'm singin' in the rain'
+ 2445: 'Alice in Wonderland'
+ 2446: 'The wizard of Oz'
+ 2447: 'I'm singin' in the rain'
+ 2448: 'Alice in Wonderland'
+ 2449: 'The wizard of Oz'
+ 2450: 'I'm singin' in the rain'
+ 2451: 'Alice in Wonderland'
+ 2452: 'The wizard of Oz'
+ 2453: 'I'm singin' in the rain'
+ 2454: 'Alice in Wonderland'
+ 2455: 'The wizard of Oz'
+ 2456: 'I'm singin' in the rain'
+ 2457: 'Alice in Wonderland'
+ 2458: 'The wizard of Oz'
+ 2459: 'I'm singin' in the rain'
+ 2460: 'Alice in Wonderland'
+ 2461: 'The wizard of Oz'
+ 2462: 'I'm singin' in the rain'
+ 2463: 'Alice in Wonderland'
+ 2464: 'The wizard of Oz'
+ 2465: 'I'm singin' in the rain'
+ 2466: 'Alice in Wonderland'
+ 2467: 'The wizard of Oz'
+ 2468: 'I'm singin' in the rain'
+ 2469: 'Alice in Wonderland'
+ 2470: 'The wizard of Oz'
+ 2471: 'I'm singin' in the rain'
+ 2472: 'Alice in Wonderland'
+ 2473: 'The wizard of Oz'
+ 2474: 'I'm singin' in the rain'
+ 2475: 'Alice in Wonderland'
+ 2476: 'The wizard of Oz'
+ 2477: 'I'm singin' in the rain'
+ 2478: 'Alice in Wonderland'
+ 2479: 'The wizard of Oz'
+ 2480: 'I'm singin' in the rain'
+ 2481: 'Alice in Wonderland'
+ 2482: 'The wizard of Oz'
+ 2483: 'I'm singin' in the rain'
+ 2484: 'Alice in Wonderland'
+ 2485: 'The wizard of Oz'
+ 2486: 'I'm singin' in the rain'
+ 2487: 'Alice in Wonderland'
+ 2488: 'The wizard of Oz'
+ 2489: 'I'm singin' in the rain'
+ 2490: 'Alice in Wonderland'
+ 2491: 'The wizard of Oz'
+ 2492: 'I'm singin' in the rain'
+ 2493: 'Alice in Wonderland'
+ 2494: 'The wizard of Oz'
+ 2495: 'I'm singin' in the rain'
+ 2496: 'Alice in Wonderland'
+ 2497: 'The wizard of Oz'
+ 2498: 'I'm singin' in the rain'
+ 2499: 'Alice in Wonderland'
+ 2500: 'The wizard of Oz'
+ 2501: 'I'm singin' in the rain'
+ 2502: 'Alice in Wonderland'
+ 2503: 'The wizard of Oz'
+ 2504: 'I'm singin' in the rain'
+ 2505: 'Alice in Wonderland'
+ 2506: 'The wizard of Oz'
+ 2507: 'I'm singin' in the rain'
+ 2508: 'Alice in Wonderland'
+ 2509: 'The wizard of Oz'
+ 2510: 'I'm singin' in the rain'
+ 2511: 'Alice in Wonderland'
+ 2512: 'The wizard of Oz'
+ 2513: 'I'm singin' in the rain'
+ 2514: 'Alice in Wonderland'
+ 2515: 'The wizard of Oz'
+ 2516: 'I'm singin' in the rain'
+ 2517: 'Alice in Wonderland'
+ 2518: 'The wizard of Oz'
+ 2519: 'I'm singin' in the rain'
+ 2520: 'Alice in Wonderland'
+ 2521: 'The wizard of Oz'
+ 2522: 'I'm singin' in the rain'
+ 2523: 'Alice in Wonderland'
+ 2524: 'The wizard of Oz'
+ 2525: 'I'm singin' in the rain'
+ 2526: 'Alice in Wonderland'
+ 2527: 'The wizard of Oz'
+ 2528: 'I'm singin' in the rain'
+ 2529: 'Alice in Wonderland'
+ 2530: 'The wizard of Oz'
+ 2531: 'I'm singin' in the rain'
+ 2532: 'Alice in Wonderland'
+ 2533: 'The wizard of Oz'
+ 2534: 'I'm singin' in the rain'
+ 2535: 'Alice in Wonderland'
+ 2536: 'The wizard of Oz'
+ 2537: 'I'm singin' in the rain'
+ 2538: 'Alice in Wonderland'
+ 2539: 'The wizard of Oz'
+ 2540: 'I'm singin' in the rain'
+ 2541: 'Alice in Wonderland'
+ 2542: 'The wizard of Oz'
+ 2543: 'I'm singin' in the rain'
+ 2544: 'Alice in Wonderland'
+ 2545: 'The wizard of Oz'
+ 2546: 'I'm singin' in the rain'
+ 2547: 'Alice in Wonderland'
+ 2548: 'The wizard of Oz'
+ 2549: 'I'm singin' in the rain'
+ 2550: 'Alice in Wonderland'
+ 2551: 'The wizard of Oz'
+ 2552: 'I'm singin' in the rain'
+ 2553: 'Alice in Wonderland'
+ 2554: 'The wizard of Oz'
+ 2555: 'I'm singin' in the rain'
+ 2556: 'Alice in Wonderland'
+ 2557: 'The wizard of Oz'
+ 2558: 'I'm singin' in the rain'
+ 2559: 'Alice in Wonderland'
+ 2560: 'The wizard of Oz'
+ 2561: 'I'm singin' in the rain'
+ 2562: 'Alice in Wonderland'
+ 2563: 'The wizard of Oz'
+ 2564: 'I'm singin' in the rain'
+ 2565: 'Alice in Wonderland'
+ 2566: 'The wizard of Oz'
+ 2567: 'I'm singin' in the rain'
+ 2568: 'Alice in Wonderland'
+ 2569: 'The wizard of Oz'
+ 2570: 'I'm singin' in the rain'
+ 2571: 'Alice in Wonderland'
+ 2572: 'The wizard of Oz'
+ 2573: 'I'm singin' in the rain'
+ 2574: 'Alice in Wonderland'
+ 2575: 'The wizard of Oz'
+ 2576: 'I'm singin' in the rain'
+ 2577: 'Alice in Wonderland'
+ 2578: 'The wizard of Oz'
+ 2579: 'I'm singin' in the rain'
+ 2580: 'Alice in Wonderland'
+ 2581: 'The wizard of Oz'
+ 2582: 'I'm singin' in the rain'
+ 2583: 'Alice in Wonderland'
+ 2584: 'The wizard of Oz'
+ 2585: 'I'm singin' in the rain'
+ 2586: 'Alice in Wonderland'
+ 2587: 'The wizard of Oz'
+ 2588: 'I'm singin' in the rain'
+ 2589: 'Alice in Wonderland'
+ 2590: 'The wizard of Oz'
+ 2591: 'I'm singin' in the rain'
+ 2592: 'Alice in Wonderland'
+ 2593: 'The wizard of Oz'
+ 2594: 'I'm singin' in the rain'
+ 2595: 'Alice in Wonderland'
+ 2596: 'The wizard of Oz'
+ 2597: 'I'm singin' in the rain'
+ 2598: 'Alice in Wonderland'
+ 2599: 'The wizard of Oz'
+ 2600: 'I'm singin' in the rain'
+ 2601: 'Alice in Wonderland'
+ 2602: 'The wizard of Oz'
+ 2603: 'I'm singin' in the rain'
+ 2604: 'Alice in Wonderland'
+ 2605: 'The wizard of Oz'
+ 2606: 'I'm singin' in the rain'
+ 2607: 'Alice in Wonderland'
+ 2608: 'The wizard of Oz'
+ 2609: 'I'm singin' in the rain'
+ 2610: 'Alice in Wonderland'
+ 2611: 'The wizard of Oz'
+ 2612: 'I'm singin' in the rain'
+ 2613: 'Alice in Wonderland'
+ 2614: 'The wizard of Oz'
+ 2615: 'I'm singin' in the rain'
+ 2616: 'Alice in Wonderland'
+ 2617: 'The wizard of Oz'
+ 2618: 'I'm singin' in the rain'
+ 2619: 'Alice in Wonderland'
+ 2620: 'The wizard of Oz'
+ 2621: 'I'm singin' in the rain'
+ 2622: 'Alice in Wonderland'
+ 2623: 'The wizard of Oz'
+ 2624: 'I'm singin' in the rain'
+ 2625: 'Alice in Wonderland'
+ 2626: 'The wizard of Oz'
+ 2627: 'I'm singin' in the rain'
+ 2628: 'Alice in Wonderland'
+ 2629: 'The wizard of Oz'
+ 2630: 'I'm singin' in the rain'
+ 2631: 'Alice in Wonderland'
+ 2632: 'The wizard of Oz'
+ 2633: 'I'm singin' in the rain'
+ 2634: 'Alice in Wonderland'
+ 2635: 'The wizard of Oz'
+ 2636: 'I'm singin' in the rain'
+ 2637: 'Alice in Wonderland'
+ 2638: 'The wizard of Oz'
+ 2639: 'I'm singin' in the rain'
+ 2640: 'Alice in Wonderland'
+ 2641: 'The wizard of Oz'
+ 2642: 'I'm singin' in the rain'
+ 2643: 'Alice in Wonderland'
+ 2644: 'The wizard of Oz'
+ 2645: 'I'm singin' in the rain'
+ 2646: 'Alice in Wonderland'
+ 2647: 'The wizard of Oz'
+ 2648: 'I'm singin' in the rain'
+ 2649: 'Alice in Wonderland'
+ 2650: 'The wizard of Oz'
+ 2651: 'I'm singin' in the rain'
+ 2652: 'Alice in Wonderland'
+ 2653: 'The wizard of Oz'
+ 2654: 'I'm singin' in the rain'
+ 2655: 'Alice in Wonderland'
+ 2656: 'The wizard of Oz'
+ 2657: 'I'm singin' in the rain'
+ 2658: 'Alice in Wonderland'
+ 2659: 'The wizard of Oz'
+ 2660: 'I'm singin' in the rain'
+ 2661: 'Alice in Wonderland'
+ 2662: 'The wizard of Oz'
+ 2663: 'I'm singin' in the rain'
+ 2664: 'Alice in Wonderland'
+ 2665: 'The wizard of Oz'
+ 2666: 'I'm singin' in the rain'
+ 2667: 'Alice in Wonderland'
+ 2668: 'The wizard of Oz'
+ 2669: 'I'm singin' in the rain'
+ 2670: 'Alice in Wonderland'
+ 2671: 'The wizard of Oz'
+ 2672: 'I'm singin' in the rain'
+ 2673: 'Alice in Wonderland'
+ 2674: 'The wizard of Oz'
+ 2675: 'I'm singin' in the rain'
+ 2676: 'Alice in Wonderland'
+ 2677: 'The wizard of Oz'
+ 2678: 'I'm singin' in the rain'
+ 2679: 'Alice in Wonderland'
+ 2680: 'The wizard of Oz'
+ 2681: 'I'm singin' in the rain'
+ 2682: 'Alice in Wonderland'
+ 2683: 'The wizard of Oz'
+ 2684: 'I'm singin' in the rain'
+ 2685: 'Alice in Wonderland'
+ 2686: 'The wizard of Oz'
+ 2687: 'I'm singin' in the rain'
+ 2688: 'Alice in Wonderland'
+ 2689: 'The wizard of Oz'
+ 2690: 'I'm singin' in the rain'
+ 2691: 'Alice in Wonderland'
+ 2692: 'The wizard of Oz'
+ 2693: 'I'm singin' in the rain'
+ 2694: 'Alice in Wonderland'
+ 2695: 'The wizard of Oz'
+ 2696: 'I'm singin' in the rain'
+ 2697: 'Alice in Wonderland'
+ 2698: 'The wizard of Oz'
+ 2699: 'I'm singin' in the rain'
+ 2700: 'Alice in Wonderland'
+ 2701: 'The wizard of Oz'
+ 2702: 'I'm singin' in the rain'
+ 2703: 'Alice in Wonderland'
+ 2704: 'The wizard of Oz'
+ 2705: 'I'm singin' in the rain'
+ 2706: 'Alice in Wonderland'
+ 2707: 'The wizard of Oz'
+ 2708: 'I'm singin' in the rain'
+ 2709: 'Alice in Wonderland'
+ 2710: 'The wizard of Oz'
+ 2711: 'I'm singin' in the rain'
+ 2712: 'Alice in Wonderland'
+ 2713: 'The wizard of Oz'
+ 2714: 'I'm singin' in the rain'
+ 2715: 'Alice in Wonderland'
+ 2716: 'The wizard of Oz'
+ 2717: 'I'm singin' in the rain'
+ 2718: 'Alice in Wonderland'
+ 2719: 'The wizard of Oz'
+ 2720: 'I'm singin' in the rain'
+ 2721: 'Alice in Wonderland'
+ 2722: 'The wizard of Oz'
+ 2723: 'I'm singin' in the rain'
+ 2724: 'Alice in Wonderland'
+ 2725: 'The wizard of Oz'
+ 2726: 'I'm singin' in the rain'
+ 2727: 'Alice in Wonderland'
+ 2728: 'The wizard of Oz'
+ 2729: 'I'm singin' in the rain'
+ 2730: 'Alice in Wonderland'
+ 2731: 'The wizard of Oz'
+ 2732: 'I'm singin' in the rain'
+ 2733: 'Alice in Wonderland'
+ 2734: 'The wizard of Oz'
+ 2735: 'I'm singin' in the rain'
+ 2736: 'Alice in Wonderland'
+ 2737: 'The wizard of Oz'
+ 2738: 'I'm singin' in the rain'
+ 2739: 'Alice in Wonderland'
+ 2740: 'The wizard of Oz'
+ 2741: 'I'm singin' in the rain'
+ 2742: 'Alice in Wonderland'
+ 2743: 'The wizard of Oz'
+ 2744: 'I'm singin' in the rain'
+ 2745: 'Alice in Wonderland'
+ 2746: 'The wizard of Oz'
+ 2747: 'I'm singin' in the rain'
+ 2748: 'Alice in Wonderland'
+ 2749: 'The wizard of Oz'
+ 2750: 'I'm singin' in the rain'
+ 2751: 'Alice in Wonderland'
+ 2752: 'The wizard of Oz'
+ 2753: 'I'm singin' in the rain'
+ 2754: 'Alice in Wonderland'
+ 2755: 'The wizard of Oz'
+ 2756: 'I'm singin' in the rain'
+ 2757: 'Alice in Wonderland'
+ 2758: 'The wizard of Oz'
+ 2759: 'I'm singin' in the rain'
+ 2760: 'Alice in Wonderland'
+ 2761: 'The wizard of Oz'
+ 2762: 'I'm singin' in the rain'
+ 2763: 'Alice in Wonderland'
+ 2764: 'The wizard of Oz'
+ 2765: 'I'm singin' in the rain'
+ 2766: 'Alice in Wonderland'
+ 2767: 'The wizard of Oz'
+ 2768: 'I'm singin' in the rain'
+ 2769: 'Alice in Wonderland'
+ 2770: 'The wizard of Oz'
+ 2771: 'I'm singin' in the rain'
+ 2772: 'Alice in Wonderland'
+ 2773: 'The wizard of Oz'
+ 2774: 'I'm singin' in the rain'
+ 2775: 'Alice in Wonderland'
+ 2776: 'The wizard of Oz'
+ 2777: 'I'm singin' in the rain'
+ 2778: 'Alice in Wonderland'
+ 2779: 'The wizard of Oz'
+ 2780: 'I'm singin' in the rain'
+ 2781: 'Alice in Wonderland'
+ 2782: 'The wizard of Oz'
+ 2783: 'I'm singin' in the rain'
+ 2784: 'Alice in Wonderland'
+ 2785: 'The wizard of Oz'
+ 2786: 'I'm singin' in the rain'
+ 2787: 'Alice in Wonderland'
+ 2788: 'The wizard of Oz'
+ 2789: 'I'm singin' in the rain'
+ 2790: 'Alice in Wonderland'
+ 2791: 'The wizard of Oz'
+ 2792: 'I'm singin' in the rain'
+ 2793: 'Alice in Wonderland'
+ 2794: 'The wizard of Oz'
+ 2795: 'I'm singin' in the rain'
+ 2796: 'Alice in Wonderland'
+ 2797: 'The wizard of Oz'
+ 2798: 'I'm singin' in the rain'
+ 2799: 'Alice in Wonderland'
+ 2800: 'The wizard of Oz'
+ 2801: 'I'm singin' in the rain'
+ 2802: 'Alice in Wonderland'
+ 2803: 'The wizard of Oz'
+ 2804: 'I'm singin' in the rain'
+ 2805: 'Alice in Wonderland'
+ 2806: 'The wizard of Oz'
+ 2807: 'I'm singin' in the rain'
+ 2808: 'Alice in Wonderland'
+ 2809: 'The wizard of Oz'
+ 2810: 'I'm singin' in the rain'
+ 2811: 'Alice in Wonderland'
+ 2812: 'The wizard of Oz'
+ 2813: 'I'm singin' in the rain'
+ 2814: 'Alice in Wonderland'
+ 2815: 'The wizard of Oz'
+ 2816: 'I'm singin' in the rain'
+ 2817: 'Alice in Wonderland'
+ 2818: 'The wizard of Oz'
+ 2819: 'I'm singin' in the rain'
+ 2820: 'Alice in Wonderland'
+ 2821: 'The wizard of Oz'
+ 2822: 'I'm singin' in the rain'
+ 2823: 'Alice in Wonderland'
+ 2824: 'The wizard of Oz'
+ 2825: 'I'm singin' in the rain'
+ 2826: 'Alice in Wonderland'
+ 2827: 'The wizard of Oz'
+ 2828: 'I'm singin' in the rain'
+ 2829: 'Alice in Wonderland'
+ 2830: 'The wizard of Oz'
+ 2831: 'I'm singin' in the rain'
+ 2832: 'Alice in Wonderland'
+ 2833: 'The wizard of Oz'
+ 2834: 'I'm singin' in the rain'
+ 2835: 'Alice in Wonderland'
+ 2836: 'The wizard of Oz'
+ 2837: 'I'm singin' in the rain'
+ 2838: 'Alice in Wonderland'
+ 2839: 'The wizard of Oz'
+ 2840: 'I'm singin' in the rain'
+ 2841: 'Alice in Wonderland'
+ 2842: 'The wizard of Oz'
+ 2843: 'I'm singin' in the rain'
+ 2844: 'Alice in Wonderland'
+ 2845: 'The wizard of Oz'
+ 2846: 'I'm singin' in the rain'
+ 2847: 'Alice in Wonderland'
+ 2848: 'The wizard of Oz'
+ 2849: 'I'm singin' in the rain'
+ 2850: 'Alice in Wonderland'
+ 2851: 'The wizard of Oz'
+ 2852: 'I'm singin' in the rain'
+ 2853: 'Alice in Wonderland'
+ 2854: 'The wizard of Oz'
+ 2855: 'I'm singin' in the rain'
+ 2856: 'Alice in Wonderland'
+ 2857: 'The wizard of Oz'
+ 2858: 'I'm singin' in the rain'
+ 2859: 'Alice in Wonderland'
+ 2860: 'The wizard of Oz'
+ 2861: 'I'm singin' in the rain'
+ 2862: 'Alice in Wonderland'
+ 2863: 'The wizard of Oz'
+ 2864: 'I'm singin' in the rain'
+ 2865: 'Alice in Wonderland'
+ 2866: 'The wizard of Oz'
+ 2867: 'I'm singin' in the rain'
+ 2868: 'Alice in Wonderland'
+ 2869: 'The wizard of Oz'
+ 2870: 'I'm singin' in the rain'
+ 2871: 'Alice in Wonderland'
+ 2872: 'The wizard of Oz'
+ 2873: 'I'm singin' in the rain'
+ 2874: 'Alice in Wonderland'
+ 2875: 'The wizard of Oz'
+ 2876: 'I'm singin' in the rain'
+ 2877: 'Alice in Wonderland'
+ 2878: 'The wizard of Oz'
+ 2879: 'I'm singin' in the rain'
+ 2880: 'Alice in Wonderland'
+ 2881: 'The wizard of Oz'
+ 2882: 'I'm singin' in the rain'
+ 2883: 'Alice in Wonderland'
+ 2884: 'The wizard of Oz'
+ 2885: 'I'm singin' in the rain'
+ 2886: 'Alice in Wonderland'
+ 2887: 'The wizard of Oz'
+ 2888: 'I'm singin' in the rain'
+ 2889: 'Alice in Wonderland'
+ 2890: 'The wizard of Oz'
+ 2891: 'I'm singin' in the rain'
+ 2892: 'Alice in Wonderland'
+ 2893: 'The wizard of Oz'
+ 2894: 'I'm singin' in the rain'
+ 2895: 'Alice in Wonderland'
+ 2896: 'The wizard of Oz'
+ 2897: 'I'm singin' in the rain'
+ 2898: 'Alice in Wonderland'
+ 2899: 'The wizard of Oz'
+ 2900: 'I'm singin' in the rain'
+ 2901: 'Alice in Wonderland'
+ 2902: 'The wizard of Oz'
+ 2903: 'I'm singin' in the rain'
+ 2904: 'Alice in Wonderland'
+ 2905: 'The wizard of Oz'
+ 2906: 'I'm singin' in the rain'
+ 2907: 'Alice in Wonderland'
+ 2908: 'The wizard of Oz'
+ 2909: 'I'm singin' in the rain'
+ 2910: 'Alice in Wonderland'
+ 2911: 'The wizard of Oz'
+ 2912: 'I'm singin' in the rain'
+ 2913: 'Alice in Wonderland'
+ 2914: 'The wizard of Oz'
+ 2915: 'I'm singin' in the rain'
+ 2916: 'Alice in Wonderland'
+ 2917: 'The wizard of Oz'
+ 2918: 'I'm singin' in the rain'
+ 2919: 'Alice in Wonderland'
+ 2920: 'The wizard of Oz'
+ 2921: 'I'm singin' in the rain'
+ 2922: 'Alice in Wonderland'
+ 2923: 'The wizard of Oz'
+ 2924: 'I'm singin' in the rain'
+ 2925: 'Alice in Wonderland'
+ 2926: 'The wizard of Oz'
+ 2927: 'I'm singin' in the rain'
+ 2928: 'Alice in Wonderland'
+ 2929: 'The wizard of Oz'
+ 2930: 'I'm singin' in the rain'
+ 2931: 'Alice in Wonderland'
+ 2932: 'The wizard of Oz'
+ 2933: 'I'm singin' in the rain'
+ 2934: 'Alice in Wonderland'
+ 2935: 'The wizard of Oz'
+ 2936: 'I'm singin' in the rain'
+ 2937: 'Alice in Wonderland'
+ 2938: 'The wizard of Oz'
+ 2939: 'I'm singin' in the rain'
+ 2940: 'Alice in Wonderland'
+ 2941: 'The wizard of Oz'
+ 2942: 'I'm singin' in the rain'
+ 2943: 'Alice in Wonderland'
+ 2944: 'The wizard of Oz'
+ 2945: 'I'm singin' in the rain'
+ 2946: 'Alice in Wonderland'
+ 2947: 'The wizard of Oz'
+ 2948: 'I'm singin' in the rain'
+ 2949: 'Alice in Wonderland'
+ 2950: 'The wizard of Oz'
+ 2951: 'I'm singin' in the rain'
+ 2952: 'Alice in Wonderland'
+ 2953: 'The wizard of Oz'
+ 2954: 'I'm singin' in the rain'
+ 2955: 'Alice in Wonderland'
+ 2956: 'The wizard of Oz'
+ 2957: 'I'm singin' in the rain'
+ 2958: 'Alice in Wonderland'
+ 2959: 'The wizard of Oz'
+ 2960: 'I'm singin' in the rain'
+ 2961: 'Alice in Wonderland'
+ 2962: 'The wizard of Oz'
+ 2963: 'I'm singin' in the rain'
+ 2964: 'Alice in Wonderland'
+ 2965: 'The wizard of Oz'
+ 2966: 'I'm singin' in the rain'
+ 2967: 'Alice in Wonderland'
+ 2968: 'The wizard of Oz'
+ 2969: 'I'm singin' in the rain'
+ 2970: 'Alice in Wonderland'
+ 2971: 'The wizard of Oz'
+ 2972: 'I'm singin' in the rain'
+ 2973: 'Alice in Wonderland'
+ 2974: 'The wizard of Oz'
+ 2975: 'I'm singin' in the rain'
+ 2976: 'Alice in Wonderland'
+ 2977: 'The wizard of Oz'
+ 2978: 'I'm singin' in the rain'
+ 2979: 'Alice in Wonderland'
+ 2980: 'The wizard of Oz'
+ 2981: 'I'm singin' in the rain'
+ 2982: 'Alice in Wonderland'
+ 2983: 'The wizard of Oz'
+ 2984: 'I'm singin' in the rain'
+ 2985: 'Alice in Wonderland'
+ 2986: 'The wizard of Oz'
+ 2987: 'I'm singin' in the rain'
+ 2988: 'Alice in Wonderland'
+ 2989: 'The wizard of Oz'
+ 2990: 'I'm singin' in the rain'
+ 2991: 'Alice in Wonderland'
+ 2992: 'The wizard of Oz'
+ 2993: 'I'm singin' in the rain'
+ 2994: 'Alice in Wonderland'
+ 2995: 'The wizard of Oz'
+ 2996: 'I'm singin' in the rain'
+ 2997: 'Alice in Wonderland'
+ 2998: 'The wizard of Oz'
+ 2999: 'I'm singin' in the rain'
+ 3000: 'Alice in Wonderland'
+ 3001: 'The wizard of Oz'
+ 3002: 'I'm singin' in the rain'
+ 3003: 'Alice in Wonderland'
+ 3004: 'The wizard of Oz'
+ 3005: 'I'm singin' in the rain'
+ 3006: 'Alice in Wonderland'
+ 3007: 'The wizard of Oz'
+ 3008: 'I'm singin' in the rain'
+ 3009: 'Alice in Wonderland'
+ 3010: 'The wizard of Oz'
+ 3011: 'I'm singin' in the rain'
+ 3012: 'Alice in Wonderland'
+ 3013: 'The wizard of Oz'
+ 3014: 'I'm singin' in the rain'
+ 3015: 'Alice in Wonderland'
+ 3016: 'The wizard of Oz'
+ 3017: 'I'm singin' in the rain'
+ 3018: 'Alice in Wonderland'
+ 3019: 'The wizard of Oz'
+ 3020: 'I'm singin' in the rain'
+ 3021: 'Alice in Wonderland'
+ 3022: 'The wizard of Oz'
+ 3023: 'I'm singin' in the rain'
+ 3024: 'Alice in Wonderland'
+ 3025: 'The wizard of Oz'
+ 3026: 'I'm singin' in the rain'
+ 3027: 'Alice in Wonderland'
+ 3028: 'The wizard of Oz'
+ 3029: 'I'm singin' in the rain'
+ 3030: 'Alice in Wonderland'
+ 3031: 'The wizard of Oz'
+ 3032: 'I'm singin' in the rain'
+ 3033: 'Alice in Wonderland'
+ 3034: 'The wizard of Oz'
+ 3035: 'I'm singin' in the rain'
+ 3036: 'Alice in Wonderland'
+ 3037: 'The wizard of Oz'
+ 3038: 'I'm singin' in the rain'
+ 3039: 'Alice in Wonderland'
+ 3040: 'The wizard of Oz'
+ 3041: 'I'm singin' in the rain'
+ 3042: 'Alice in Wonderland'
+ 3043: 'The wizard of Oz'
+ 3044: 'I'm singin' in the rain'
+ 3045: 'Alice in Wonderland'
+ 3046: 'The wizard of Oz'
+ 3047: 'I'm singin' in the rain'
+ 3048: 'Alice in Wonderland'
+ 3049: 'The wizard of Oz'
+ 3050: 'I'm singin' in the rain'
+ 3051: 'Alice in Wonderland'
+ 3052: 'The wizard of Oz'
+ 3053: 'I'm singin' in the rain'
+ 3054: 'Alice in Wonderland'
+ 3055: 'The wizard of Oz'
+ 3056: 'I'm singin' in the rain'
+ 3057: 'Alice in Wonderland'
+ 3058: 'The wizard of Oz'
+ 3059: 'I'm singin' in the rain'
+ 3060: 'Alice in Wonderland'
+ 3061: 'The wizard of Oz'
+ 3062: 'I'm singin' in the rain'
+ 3063: 'Alice in Wonderland'
+ 3064: 'The wizard of Oz'
+ 3065: 'I'm singin' in the rain'
+ 3066: 'Alice in Wonderland'
+ 3067: 'The wizard of Oz'
+ 3068: 'I'm singin' in the rain'
+ 3069: 'Alice in Wonderland'
+ 3070: 'The wizard of Oz'
+ 3071: 'I'm singin' in the rain'
+ 3072: 'Alice in Wonderland'
+ 3073: 'The wizard of Oz'
+ 3074: 'I'm singin' in the rain'
+ 3075: 'Alice in Wonderland'
+ 3076: 'The wizard of Oz'
+ 3077: 'I'm singin' in the rain'
+ 3078: 'Alice in Wonderland'
+ 3079: 'The wizard of Oz'
+ 3080: 'I'm singin' in the rain'
+ 3081: 'Alice in Wonderland'
+ 3082: 'The wizard of Oz'
+ 3083: 'I'm singin' in the rain'
+ 3084: 'Alice in Wonderland'
+ 3085: 'The wizard of Oz'
+ 3086: 'I'm singin' in the rain'
+ 3087: 'Alice in Wonderland'
+ 3088: 'The wizard of Oz'
+ 3089: 'I'm singin' in the rain'
+ 3090: 'Alice in Wonderland'
+ 3091: 'The wizard of Oz'
+ 3092: 'I'm singin' in the rain'
+ 3093: 'Alice in Wonderland'
+ 3094: 'The wizard of Oz'
+ 3095: 'I'm singin' in the rain'
+ 3096: 'Alice in Wonderland'
+ 3097: 'The wizard of Oz'
+ 3098: 'I'm singin' in the rain'
+ 3099: 'Alice in Wonderland'
+ 3100: 'The wizard of Oz'
+ 3101: 'I'm singin' in the rain'
+ 3102: 'Alice in Wonderland'
+ 3103: 'The wizard of Oz'
+ 3104: 'I'm singin' in the rain'
+ 3105: 'Alice in Wonderland'
+ 3106: 'The wizard of Oz'
+ 3107: 'I'm singin' in the rain'
+ 3108: 'Alice in Wonderland'
+ 3109: 'The wizard of Oz'
+ 3110: 'I'm singin' in the rain'
+ 3111: 'Alice in Wonderland'
+ 3112: 'The wizard of Oz'
+ 3113: 'I'm singin' in the rain'
+ 3114: 'Alice in Wonderland'
+ 3115: 'The wizard of Oz'
+ 3116: 'I'm singin' in the rain'
+ 3117: 'Alice in Wonderland'
+ 3118: 'The wizard of Oz'
+ 3119: 'I'm singin' in the rain'
+ 3120: 'Alice in Wonderland'
+ 3121: 'The wizard of Oz'
+ 3122: 'I'm singin' in the rain'
+ 3123: 'Alice in Wonderland'
+ 3124: 'The wizard of Oz'
+ 3125: 'I'm singin' in the rain'
+ 3126: 'Alice in Wonderland'
+ 3127: 'The wizard of Oz'
+ 3128: 'I'm singin' in the rain'
+ 3129: 'Alice in Wonderland'
+ 3130: 'The wizard of Oz'
+ 3131: 'I'm singin' in the rain'
+ 3132: 'Alice in Wonderland'
+ 3133: 'The wizard of Oz'
+ 3134: 'I'm singin' in the rain'
+ 3135: 'Alice in Wonderland'
+ 3136: 'The wizard of Oz'
+ 3137: 'I'm singin' in the rain'
+ 3138: 'Alice in Wonderland'
+ 3139: 'The wizard of Oz'
+ 3140: 'I'm singin' in the rain'
+ 3141: 'Alice in Wonderland'
+ 3142: 'The wizard of Oz'
+ 3143: 'I'm singin' in the rain'
+ 3144: 'Alice in Wonderland'
+ 3145: 'The wizard of Oz'
+ 3146: 'I'm singin' in the rain'
+ 3147: 'Alice in Wonderland'
+ 3148: 'The wizard of Oz'
+ 3149: 'I'm singin' in the rain'
+ 3150: 'Alice in Wonderland'
+ 3151: 'The wizard of Oz'
+ 3152: 'I'm singin' in the rain'
+ 3153: 'Alice in Wonderland'
+ 3154: 'The wizard of Oz'
+ 3155: 'I'm singin' in the rain'
+ 3156: 'Alice in Wonderland'
+ 3157: 'The wizard of Oz'
+ 3158: 'I'm singin' in the rain'
+ 3159: 'Alice in Wonderland'
+ 3160: 'The wizard of Oz'
+ 3161: 'I'm singin' in the rain'
+ 3162: 'Alice in Wonderland'
+ 3163: 'The wizard of Oz'
+ 3164: 'I'm singin' in the rain'
+ 3165: 'Alice in Wonderland'
+ 3166: 'The wizard of Oz'
+ 3167: 'I'm singin' in the rain'
+ 3168: 'Alice in Wonderland'
+ 3169: 'The wizard of Oz'
+ 3170: 'I'm singin' in the rain'
+ 3171: 'Alice in Wonderland'
+ 3172: 'The wizard of Oz'
+ 3173: 'I'm singin' in the rain'
+ 3174: 'Alice in Wonderland'
+ 3175: 'The wizard of Oz'
+ 3176: 'I'm singin' in the rain'
+ 3177: 'Alice in Wonderland'
+ 3178: 'The wizard of Oz'
+ 3179: 'I'm singin' in the rain'
+ 3180: 'Alice in Wonderland'
+ 3181: 'The wizard of Oz'
+ 3182: 'I'm singin' in the rain'
+ 3183: 'Alice in Wonderland'
+ 3184: 'The wizard of Oz'
+ 3185: 'I'm singin' in the rain'
+ 3186: 'Alice in Wonderland'
+ 3187: 'The wizard of Oz'
+ 3188: 'I'm singin' in the rain'
+ 3189: 'Alice in Wonderland'
+ 3190: 'The wizard of Oz'
+ 3191: 'I'm singin' in the rain'
+ 3192: 'Alice in Wonderland'
+ 3193: 'The wizard of Oz'
+ 3194: 'I'm singin' in the rain'
+ 3195: 'Alice in Wonderland'
+ 3196: 'The wizard of Oz'
+ 3197: 'I'm singin' in the rain'
+ 3198: 'Alice in Wonderland'
+ 3199: 'The wizard of Oz'
+ 3200: 'I'm singin' in the rain'
+ 3201: 'Alice in Wonderland'
+ 3202: 'The wizard of Oz'
+ 3203: 'I'm singin' in the rain'
+ 3204: 'Alice in Wonderland'
+ 3205: 'The wizard of Oz'
+ 3206: 'I'm singin' in the rain'
+ 3207: 'Alice in Wonderland'
+ 3208: 'The wizard of Oz'
+ 3209: 'I'm singin' in the rain'
+ 3210: 'Alice in Wonderland'
+ 3211: 'The wizard of Oz'
+ 3212: 'I'm singin' in the rain'
+ 3213: 'Alice in Wonderland'
+ 3214: 'The wizard of Oz'
+ 3215: 'I'm singin' in the rain'
+ 3216: 'Alice in Wonderland'
+ 3217: 'The wizard of Oz'
+ 3218: 'I'm singin' in the rain'
+ 3219: 'Alice in Wonderland'
+ 3220: 'The wizard of Oz'
+ 3221: 'I'm singin' in the rain'
+ 3222: 'Alice in Wonderland'
+ 3223: 'The wizard of Oz'
+ 3224: 'I'm singin' in the rain'
+ 3225: 'Alice in Wonderland'
+ 3226: 'The wizard of Oz'
+ 3227: 'I'm singin' in the rain'
+ 3228: 'Alice in Wonderland'
+ 3229: 'The wizard of Oz'
+ 3230: 'I'm singin' in the rain'
+ 3231: 'Alice in Wonderland'
+ 3232: 'The wizard of Oz'
+ 3233: 'I'm singin' in the rain'
+ 3234: 'Alice in Wonderland'
+ 3235: 'The wizard of Oz'
+ 3236: 'I'm singin' in the rain'
+ 3237: 'Alice in Wonderland'
+ 3238: 'The wizard of Oz'
+ 3239: 'I'm singin' in the rain'
+ 3240: 'Alice in Wonderland'
+ 3241: 'The wizard of Oz'
+ 3242: 'I'm singin' in the rain'
+ 3243: 'Alice in Wonderland'
+ 3244: 'The wizard of Oz'
+ 3245: 'I'm singin' in the rain'
+ 3246: 'Alice in Wonderland'
+ 3247: 'The wizard of Oz'
+ 3248: 'I'm singin' in the rain'
+ 3249: 'Alice in Wonderland'
+ 3250: 'The wizard of Oz'
+ 3251: 'I'm singin' in the rain'
+ 3252: 'Alice in Wonderland'
+ 3253: 'The wizard of Oz'
+ 3254: 'I'm singin' in the rain'
+ 3255: 'Alice in Wonderland'
+ 3256: 'The wizard of Oz'
+ 3257: 'I'm singin' in the rain'
+ 3258: 'Alice in Wonderland'
+ 3259: 'The wizard of Oz'
+ 3260: 'I'm singin' in the rain'
+ 3261: 'Alice in Wonderland'
+ 3262: 'The wizard of Oz'
+ 3263: 'I'm singin' in the rain'
+ 3264: 'Alice in Wonderland'
+ 3265: 'The wizard of Oz'
+ 3266: 'I'm singin' in the rain'
+ 3267: 'Alice in Wonderland'
+ 3268: 'The wizard of Oz'
+ 3269: 'I'm singin' in the rain'
+ 3270: 'Alice in Wonderland'
+ 3271: 'The wizard of Oz'
+ 3272: 'I'm singin' in the rain'
+ 3273: 'Alice in Wonderland'
+ 3274: 'The wizard of Oz'
+ 3275: 'I'm singin' in the rain'
+ 3276: 'Alice in Wonderland'
+ 3277: 'The wizard of Oz'
+ 3278: 'I'm singin' in the rain'
+ 3279: 'Alice in Wonderland'
+ 3280: 'The wizard of Oz'
+ 3281: 'I'm singin' in the rain'
+ 3282: 'Alice in Wonderland'
+ 3283: 'The wizard of Oz'
+ 3284: 'I'm singin' in the rain'
+ 3285: 'Alice in Wonderland'
+ 3286: 'The wizard of Oz'
+ 3287: 'I'm singin' in the rain'
+ 3288: 'Alice in Wonderland'
+ 3289: 'The wizard of Oz'
+ 3290: 'I'm singin' in the rain'
+ 3291: 'Alice in Wonderland'
+ 3292: 'The wizard of Oz'
+ 3293: 'I'm singin' in the rain'
+ 3294: 'Alice in Wonderland'
+ 3295: 'The wizard of Oz'
+ 3296: 'I'm singin' in the rain'
+ 3297: 'Alice in Wonderland'
+ 3298: 'The wizard of Oz'
+ 3299: 'I'm singin' in the rain'
+ 3300: 'Alice in Wonderland'
+ 3301: 'The wizard of Oz'
+ 3302: 'I'm singin' in the rain'
+ 3303: 'Alice in Wonderland'
+ 3304: 'The wizard of Oz'
+ 3305: 'I'm singin' in the rain'
+ 3306: 'Alice in Wonderland'
+ 3307: 'The wizard of Oz'
+ 3308: 'I'm singin' in the rain'
+ 3309: 'Alice in Wonderland'
+ 3310: 'The wizard of Oz'
+ 3311: 'I'm singin' in the rain'
+ 3312: 'Alice in Wonderland'
+ 3313: 'The wizard of Oz'
+ 3314: 'I'm singin' in the rain'
+ 3315: 'Alice in Wonderland'
+ 3316: 'The wizard of Oz'
+ 3317: 'I'm singin' in the rain'
+ 3318: 'Alice in Wonderland'
+ 3319: 'The wizard of Oz'
+ 3320: 'I'm singin' in the rain'
+ 3321: 'Alice in Wonderland'
+ 3322: 'The wizard of Oz'
+ 3323: 'I'm singin' in the rain'
+ 3324: 'Alice in Wonderland'
+ 3325: 'The wizard of Oz'
+ 3326: 'I'm singin' in the rain'
+ 3327: 'Alice in Wonderland'
+ 3328: 'The wizard of Oz'
+ 3329: 'I'm singin' in the rain'
+ 3330: 'Alice in Wonderland'
+ 3331: 'The wizard of Oz'
+ 3332: 'I'm singin' in the rain'
+ 3333: 'Alice in Wonderland'
+ 3334: 'The wizard of Oz'
+ 3335: 'I'm singin' in the rain'
+ 3336: 'Alice in Wonderland'
+ 3337: 'The wizard of Oz'
+ 3338: 'I'm singin' in the rain'
+ 3339: 'Alice in Wonderland'
+ 3340: 'The wizard of Oz'
+ 3341: 'I'm singin' in the rain'
+ 3342: 'Alice in Wonderland'
+ 3343: 'The wizard of Oz'
+ 3344: 'I'm singin' in the rain'
+ 3345: 'Alice in Wonderland'
+ 3346: 'The wizard of Oz'
+ 3347: 'I'm singin' in the rain'
+ 3348: 'Alice in Wonderland'
+ 3349: 'The wizard of Oz'
+ 3350: 'I'm singin' in the rain'
+ 3351: 'Alice in Wonderland'
+ 3352: 'The wizard of Oz'
+ 3353: 'I'm singin' in the rain'
+ 3354: 'Alice in Wonderland'
+ 3355: 'The wizard of Oz'
+ 3356: 'I'm singin' in the rain'
+ 3357: 'Alice in Wonderland'
+ 3358: 'The wizard of Oz'
+ 3359: 'I'm singin' in the rain'
+ 3360: 'Alice in Wonderland'
+ 3361: 'The wizard of Oz'
+ 3362: 'I'm singin' in the rain'
+ 3363: 'Alice in Wonderland'
+ 3364: 'The wizard of Oz'
+ 3365: 'I'm singin' in the rain'
+ 3366: 'Alice in Wonderland'
+ 3367: 'The wizard of Oz'
+ 3368: 'I'm singin' in the rain'
+ 3369: 'Alice in Wonderland'
+ 3370: 'The wizard of Oz'
+ 3371: 'I'm singin' in the rain'
+ 3372: 'Alice in Wonderland'
+ 3373: 'The wizard of Oz'
+ 3374: 'I'm singin' in the rain'
+ 3375: 'Alice in Wonderland'
+ 3376: 'The wizard of Oz'
+ 3377: 'I'm singin' in the rain'
+ 3378: 'Alice in Wonderland'
+ 3379: 'The wizard of Oz'
+ 3380: 'I'm singin' in the rain'
+ 3381: 'Alice in Wonderland'
+ 3382: 'The wizard of Oz'
+ 3383: 'I'm singin' in the rain'
+ 3384: 'Alice in Wonderland'
+ 3385: 'The wizard of Oz'
+ 3386: 'I'm singin' in the rain'
+ 3387: 'Alice in Wonderland'
+ 3388: 'The wizard of Oz'
+ 3389: 'I'm singin' in the rain'
+ 3390: 'Alice in Wonderland'
+ 3391: 'The wizard of Oz'
+ 3392: 'I'm singin' in the rain'
+ 3393: 'Alice in Wonderland'
+ 3394: 'The wizard of Oz'
+ 3395: 'I'm singin' in the rain'
+ 3396: 'Alice in Wonderland'
+ 3397: 'The wizard of Oz'
+ 3398: 'I'm singin' in the rain'
+ 3399: 'Alice in Wonderland'
+ 3400: 'The wizard of Oz'
+ 3401: 'I'm singin' in the rain'
+ 3402: 'Alice in Wonderland'
+ 3403: 'The wizard of Oz'
+ 3404: 'I'm singin' in the rain'
+ 3405: 'Alice in Wonderland'
+ 3406: 'The wizard of Oz'
+ 3407: 'I'm singin' in the rain'
+ 3408: 'Alice in Wonderland'
+ 3409: 'The wizard of Oz'
+ 3410: 'I'm singin' in the rain'
+ 3411: 'Alice in Wonderland'
+ 3412: 'The wizard of Oz'
+ 3413: 'I'm singin' in the rain'
+ 3414: 'Alice in Wonderland'
+ 3415: 'The wizard of Oz'
+ 3416: 'I'm singin' in the rain'
+ 3417: 'Alice in Wonderland'
+ 3418: 'The wizard of Oz'
+ 3419: 'I'm singin' in the rain'
+ 3420: 'Alice in Wonderland'
+ 3421: 'The wizard of Oz'
+ 3422: 'I'm singin' in the rain'
+ 3423: 'Alice in Wonderland'
+ 3424: 'The wizard of Oz'
+ 3425: 'I'm singin' in the rain'
+ 3426: 'Alice in Wonderland'
+ 3427: 'The wizard of Oz'
+ 3428: 'I'm singin' in the rain'
+ 3429: 'Alice in Wonderland'
+ 3430: 'The wizard of Oz'
+ 3431: 'I'm singin' in the rain'
+ 3432: 'Alice in Wonderland'
+ 3433: 'The wizard of Oz'
+ 3434: 'I'm singin' in the rain'
+ 3435: 'Alice in Wonderland'
+ 3436: 'The wizard of Oz'
+ 3437: 'I'm singin' in the rain'
+ 3438: 'Alice in Wonderland'
+ 3439: 'The wizard of Oz'
+ 3440: 'I'm singin' in the rain'
+ 3441: 'Alice in Wonderland'
+ 3442: 'The wizard of Oz'
+ 3443: 'I'm singin' in the rain'
+ 3444: 'Alice in Wonderland'
+ 3445: 'The wizard of Oz'
+ 3446: 'I'm singin' in the rain'
+ 3447: 'Alice in Wonderland'
+ 3448: 'The wizard of Oz'
+ 3449: 'I'm singin' in the rain'
+ 3450: 'Alice in Wonderland'
+ 3451: 'The wizard of Oz'
+ 3452: 'I'm singin' in the rain'
+ 3453: 'Alice in Wonderland'
+ 3454: 'The wizard of Oz'
+ 3455: 'I'm singin' in the rain'
+ 3456: 'Alice in Wonderland'
+ 3457: 'The wizard of Oz'
+ 3458: 'I'm singin' in the rain'
+ 3459: 'Alice in Wonderland'
+ 3460: 'The wizard of Oz'
+ 3461: 'I'm singin' in the rain'
+ 3462: 'Alice in Wonderland'
+ 3463: 'The wizard of Oz'
+ 3464: 'I'm singin' in the rain'
+ 3465: 'Alice in Wonderland'
+ 3466: 'The wizard of Oz'
+ 3467: 'I'm singin' in the rain'
+ 3468: 'Alice in Wonderland'
+ 3469: 'The wizard of Oz'
+ 3470: 'I'm singin' in the rain'
+ 3471: 'Alice in Wonderland'
+ 3472: 'The wizard of Oz'
+ 3473: 'I'm singin' in the rain'
+ 3474: 'Alice in Wonderland'
+ 3475: 'The wizard of Oz'
+ 3476: 'I'm singin' in the rain'
+ 3477: 'Alice in Wonderland'
+ 3478: 'The wizard of Oz'
+ 3479: 'I'm singin' in the rain'
+ 3480: 'Alice in Wonderland'
+ 3481: 'The wizard of Oz'
+ 3482: 'I'm singin' in the rain'
+ 3483: 'Alice in Wonderland'
+ 3484: 'The wizard of Oz'
+ 3485: 'I'm singin' in the rain'
+ 3486: 'Alice in Wonderland'
+ 3487: 'The wizard of Oz'
+ 3488: 'I'm singin' in the rain'
+ 3489: 'Alice in Wonderland'
+ 3490: 'The wizard of Oz'
+ 3491: 'I'm singin' in the rain'
+ 3492: 'Alice in Wonderland'
+ 3493: 'The wizard of Oz'
+ 3494: 'I'm singin' in the rain'
+ 3495: 'Alice in Wonderland'
+ 3496: 'The wizard of Oz'
+ 3497: 'I'm singin' in the rain'
+ 3498: 'Alice in Wonderland'
+ 3499: 'The wizard of Oz'
diff --git a/akregator/src/mk4storage/metakit/tests/ok/l03.txt b/akregator/src/mk4storage/metakit/tests/ok/l03.txt
new file mode 100644
index 000000000..82e31887f
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/l03.txt
@@ -0,0 +1,2 @@
+>>> Force sections in storage
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/l03a.txt b/akregator/src/mk4storage/metakit/tests/ok/l03a.txt
new file mode 100644
index 000000000..daff458fa
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/l03a.txt
@@ -0,0 +1,1503 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 500 rows = p1:V
+ 0: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9000
+ 1: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9001
+ 2: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9002
+ 3: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9003
+ 4: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9004
+ 5: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9005
+ 6: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9006
+ 7: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9007
+ 8: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9008
+ 9: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9009
+ 10: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9010
+ 11: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9011
+ 12: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9012
+ 13: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9013
+ 14: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9014
+ 15: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9015
+ 16: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9016
+ 17: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9017
+ 18: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9018
+ 19: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9019
+ 20: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9020
+ 21: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9021
+ 22: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9022
+ 23: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9023
+ 24: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9024
+ 25: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9025
+ 26: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9026
+ 27: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9027
+ 28: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9028
+ 29: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9029
+ 30: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9030
+ 31: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9031
+ 32: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9032
+ 33: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9033
+ 34: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9034
+ 35: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9035
+ 36: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9036
+ 37: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9037
+ 38: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9038
+ 39: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9039
+ 40: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9040
+ 41: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9041
+ 42: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9042
+ 43: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9043
+ 44: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9044
+ 45: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9045
+ 46: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9046
+ 47: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9047
+ 48: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9048
+ 49: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9049
+ 50: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9050
+ 51: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9051
+ 52: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9052
+ 53: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9053
+ 54: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9054
+ 55: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9055
+ 56: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9056
+ 57: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9057
+ 58: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9058
+ 59: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9059
+ 60: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9060
+ 61: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9061
+ 62: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9062
+ 63: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9063
+ 64: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9064
+ 65: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9065
+ 66: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9066
+ 67: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9067
+ 68: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9068
+ 69: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9069
+ 70: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9070
+ 71: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9071
+ 72: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9072
+ 73: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9073
+ 74: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9074
+ 75: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9075
+ 76: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9076
+ 77: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9077
+ 78: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9078
+ 79: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9079
+ 80: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9080
+ 81: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9081
+ 82: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9082
+ 83: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9083
+ 84: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9084
+ 85: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9085
+ 86: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9086
+ 87: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9087
+ 88: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9088
+ 89: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9089
+ 90: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9090
+ 91: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9091
+ 92: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9092
+ 93: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9093
+ 94: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9094
+ 95: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9095
+ 96: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9096
+ 97: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9097
+ 98: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9098
+ 99: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9099
+ 100: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9100
+ 101: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9101
+ 102: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9102
+ 103: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9103
+ 104: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9104
+ 105: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9105
+ 106: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9106
+ 107: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9107
+ 108: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9108
+ 109: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9109
+ 110: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9110
+ 111: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9111
+ 112: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9112
+ 113: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9113
+ 114: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9114
+ 115: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9115
+ 116: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9116
+ 117: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9117
+ 118: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9118
+ 119: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9119
+ 120: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9120
+ 121: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9121
+ 122: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9122
+ 123: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9123
+ 124: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9124
+ 125: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9125
+ 126: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9126
+ 127: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9127
+ 128: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9128
+ 129: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9129
+ 130: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9130
+ 131: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9131
+ 132: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9132
+ 133: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9133
+ 134: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9134
+ 135: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9135
+ 136: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9136
+ 137: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9137
+ 138: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9138
+ 139: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9139
+ 140: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9140
+ 141: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9141
+ 142: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9142
+ 143: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9143
+ 144: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9144
+ 145: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9145
+ 146: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9146
+ 147: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9147
+ 148: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9148
+ 149: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9149
+ 150: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9150
+ 151: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9151
+ 152: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9152
+ 153: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9153
+ 154: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9154
+ 155: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9155
+ 156: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9156
+ 157: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9157
+ 158: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9158
+ 159: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9159
+ 160: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9160
+ 161: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9161
+ 162: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9162
+ 163: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9163
+ 164: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9164
+ 165: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9165
+ 166: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9166
+ 167: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9167
+ 168: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9168
+ 169: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9169
+ 170: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9170
+ 171: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9171
+ 172: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9172
+ 173: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9173
+ 174: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9174
+ 175: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9175
+ 176: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9176
+ 177: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9177
+ 178: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9178
+ 179: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9179
+ 180: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9180
+ 181: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9181
+ 182: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9182
+ 183: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9183
+ 184: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9184
+ 185: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9185
+ 186: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9186
+ 187: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9187
+ 188: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9188
+ 189: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9189
+ 190: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9190
+ 191: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9191
+ 192: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9192
+ 193: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9193
+ 194: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9194
+ 195: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9195
+ 196: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9196
+ 197: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9197
+ 198: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9198
+ 199: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9199
+ 200: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9200
+ 201: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9201
+ 202: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9202
+ 203: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9203
+ 204: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9204
+ 205: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9205
+ 206: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9206
+ 207: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9207
+ 208: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9208
+ 209: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9209
+ 210: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9210
+ 211: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9211
+ 212: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9212
+ 213: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9213
+ 214: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9214
+ 215: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9215
+ 216: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9216
+ 217: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9217
+ 218: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9218
+ 219: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9219
+ 220: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9220
+ 221: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9221
+ 222: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9222
+ 223: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9223
+ 224: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9224
+ 225: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9225
+ 226: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9226
+ 227: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9227
+ 228: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9228
+ 229: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9229
+ 230: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9230
+ 231: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9231
+ 232: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9232
+ 233: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9233
+ 234: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9234
+ 235: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9235
+ 236: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9236
+ 237: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9237
+ 238: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9238
+ 239: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9239
+ 240: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9240
+ 241: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9241
+ 242: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9242
+ 243: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9243
+ 244: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9244
+ 245: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9245
+ 246: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9246
+ 247: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9247
+ 248: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9248
+ 249: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9249
+ 250: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9250
+ 251: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9251
+ 252: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9252
+ 253: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9253
+ 254: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9254
+ 255: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9255
+ 256: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9256
+ 257: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9257
+ 258: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9258
+ 259: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9259
+ 260: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9260
+ 261: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9261
+ 262: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9262
+ 263: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9263
+ 264: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9264
+ 265: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9265
+ 266: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9266
+ 267: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9267
+ 268: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9268
+ 269: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9269
+ 270: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9270
+ 271: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9271
+ 272: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9272
+ 273: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9273
+ 274: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9274
+ 275: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9275
+ 276: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9276
+ 277: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9277
+ 278: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9278
+ 279: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9279
+ 280: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9280
+ 281: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9281
+ 282: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9282
+ 283: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9283
+ 284: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9284
+ 285: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9285
+ 286: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9286
+ 287: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9287
+ 288: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9288
+ 289: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9289
+ 290: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9290
+ 291: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9291
+ 292: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9292
+ 293: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9293
+ 294: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9294
+ 295: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9295
+ 296: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9296
+ 297: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9297
+ 298: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9298
+ 299: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9299
+ 300: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9300
+ 301: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9301
+ 302: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9302
+ 303: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9303
+ 304: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9304
+ 305: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9305
+ 306: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9306
+ 307: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9307
+ 308: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9308
+ 309: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9309
+ 310: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9310
+ 311: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9311
+ 312: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9312
+ 313: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9313
+ 314: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9314
+ 315: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9315
+ 316: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9316
+ 317: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9317
+ 318: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9318
+ 319: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9319
+ 320: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9320
+ 321: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9321
+ 322: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9322
+ 323: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9323
+ 324: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9324
+ 325: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9325
+ 326: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9326
+ 327: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9327
+ 328: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9328
+ 329: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9329
+ 330: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9330
+ 331: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9331
+ 332: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9332
+ 333: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9333
+ 334: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9334
+ 335: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9335
+ 336: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9336
+ 337: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9337
+ 338: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9338
+ 339: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9339
+ 340: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9340
+ 341: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9341
+ 342: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9342
+ 343: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9343
+ 344: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9344
+ 345: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9345
+ 346: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9346
+ 347: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9347
+ 348: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9348
+ 349: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9349
+ 350: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9350
+ 351: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9351
+ 352: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9352
+ 353: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9353
+ 354: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9354
+ 355: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9355
+ 356: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9356
+ 357: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9357
+ 358: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9358
+ 359: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9359
+ 360: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9360
+ 361: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9361
+ 362: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9362
+ 363: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9363
+ 364: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9364
+ 365: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9365
+ 366: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9366
+ 367: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9367
+ 368: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9368
+ 369: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9369
+ 370: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9370
+ 371: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9371
+ 372: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9372
+ 373: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9373
+ 374: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9374
+ 375: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9375
+ 376: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9376
+ 377: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9377
+ 378: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9378
+ 379: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9379
+ 380: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9380
+ 381: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9381
+ 382: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9382
+ 383: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9383
+ 384: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9384
+ 385: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9385
+ 386: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9386
+ 387: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9387
+ 388: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9388
+ 389: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9389
+ 390: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9390
+ 391: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9391
+ 392: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9392
+ 393: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9393
+ 394: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9394
+ 395: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9395
+ 396: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9396
+ 397: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9397
+ 398: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9398
+ 399: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9399
+ 400: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9400
+ 401: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9401
+ 402: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9402
+ 403: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9403
+ 404: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9404
+ 405: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9405
+ 406: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9406
+ 407: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9407
+ 408: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9408
+ 409: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9409
+ 410: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9410
+ 411: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9411
+ 412: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9412
+ 413: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9413
+ 414: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9414
+ 415: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9415
+ 416: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9416
+ 417: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9417
+ 418: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9418
+ 419: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9419
+ 420: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9420
+ 421: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9421
+ 422: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9422
+ 423: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9423
+ 424: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9424
+ 425: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9425
+ 426: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9426
+ 427: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9427
+ 428: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9428
+ 429: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9429
+ 430: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9430
+ 431: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9431
+ 432: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9432
+ 433: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9433
+ 434: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9434
+ 435: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9435
+ 436: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9436
+ 437: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9437
+ 438: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9438
+ 439: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9439
+ 440: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9440
+ 441: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9441
+ 442: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9442
+ 443: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9443
+ 444: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9444
+ 445: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9445
+ 446: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9446
+ 447: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9447
+ 448: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9448
+ 449: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9449
+ 450: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9450
+ 451: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9451
+ 452: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9452
+ 453: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9453
+ 454: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9454
+ 455: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9455
+ 456: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9456
+ 457: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9457
+ 458: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9458
+ 459: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9459
+ 460: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9460
+ 461: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9461
+ 462: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9462
+ 463: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9463
+ 464: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9464
+ 465: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9465
+ 466: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9466
+ 467: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9467
+ 468: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9468
+ 469: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9469
+ 470: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9470
+ 471: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9471
+ 472: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9472
+ 473: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9473
+ 474: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9474
+ 475: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9475
+ 476: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9476
+ 477: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9477
+ 478: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9478
+ 479: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9479
+ 480: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9480
+ 481: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9481
+ 482: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9482
+ 483: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9483
+ 484: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9484
+ 485: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9485
+ 486: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9486
+ 487: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9487
+ 488: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9488
+ 489: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9489
+ 490: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9490
+ 491: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9491
+ 492: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9492
+ 493: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9493
+ 494: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9494
+ 495: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9495
+ 496: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9496
+ 497: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9497
+ 498: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9498
+ 499: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9499
diff --git a/akregator/src/mk4storage/metakit/tests/ok/l03b.txt b/akregator/src/mk4storage/metakit/tests/ok/l03b.txt
new file mode 100644
index 000000000..daff458fa
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/l03b.txt
@@ -0,0 +1,1503 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 500 rows = p1:V
+ 0: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9000
+ 1: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9001
+ 2: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9002
+ 3: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9003
+ 4: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9004
+ 5: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9005
+ 6: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9006
+ 7: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9007
+ 8: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9008
+ 9: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9009
+ 10: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9010
+ 11: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9011
+ 12: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9012
+ 13: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9013
+ 14: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9014
+ 15: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9015
+ 16: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9016
+ 17: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9017
+ 18: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9018
+ 19: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9019
+ 20: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9020
+ 21: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9021
+ 22: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9022
+ 23: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9023
+ 24: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9024
+ 25: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9025
+ 26: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9026
+ 27: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9027
+ 28: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9028
+ 29: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9029
+ 30: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9030
+ 31: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9031
+ 32: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9032
+ 33: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9033
+ 34: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9034
+ 35: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9035
+ 36: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9036
+ 37: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9037
+ 38: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9038
+ 39: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9039
+ 40: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9040
+ 41: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9041
+ 42: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9042
+ 43: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9043
+ 44: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9044
+ 45: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9045
+ 46: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9046
+ 47: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9047
+ 48: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9048
+ 49: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9049
+ 50: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9050
+ 51: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9051
+ 52: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9052
+ 53: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9053
+ 54: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9054
+ 55: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9055
+ 56: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9056
+ 57: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9057
+ 58: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9058
+ 59: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9059
+ 60: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9060
+ 61: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9061
+ 62: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9062
+ 63: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9063
+ 64: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9064
+ 65: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9065
+ 66: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9066
+ 67: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9067
+ 68: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9068
+ 69: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9069
+ 70: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9070
+ 71: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9071
+ 72: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9072
+ 73: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9073
+ 74: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9074
+ 75: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9075
+ 76: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9076
+ 77: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9077
+ 78: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9078
+ 79: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9079
+ 80: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9080
+ 81: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9081
+ 82: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9082
+ 83: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9083
+ 84: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9084
+ 85: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9085
+ 86: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9086
+ 87: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9087
+ 88: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9088
+ 89: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9089
+ 90: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9090
+ 91: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9091
+ 92: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9092
+ 93: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9093
+ 94: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9094
+ 95: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9095
+ 96: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9096
+ 97: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9097
+ 98: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9098
+ 99: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9099
+ 100: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9100
+ 101: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9101
+ 102: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9102
+ 103: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9103
+ 104: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9104
+ 105: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9105
+ 106: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9106
+ 107: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9107
+ 108: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9108
+ 109: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9109
+ 110: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9110
+ 111: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9111
+ 112: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9112
+ 113: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9113
+ 114: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9114
+ 115: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9115
+ 116: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9116
+ 117: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9117
+ 118: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9118
+ 119: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9119
+ 120: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9120
+ 121: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9121
+ 122: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9122
+ 123: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9123
+ 124: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9124
+ 125: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9125
+ 126: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9126
+ 127: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9127
+ 128: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9128
+ 129: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9129
+ 130: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9130
+ 131: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9131
+ 132: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9132
+ 133: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9133
+ 134: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9134
+ 135: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9135
+ 136: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9136
+ 137: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9137
+ 138: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9138
+ 139: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9139
+ 140: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9140
+ 141: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9141
+ 142: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9142
+ 143: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9143
+ 144: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9144
+ 145: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9145
+ 146: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9146
+ 147: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9147
+ 148: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9148
+ 149: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9149
+ 150: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9150
+ 151: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9151
+ 152: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9152
+ 153: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9153
+ 154: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9154
+ 155: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9155
+ 156: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9156
+ 157: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9157
+ 158: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9158
+ 159: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9159
+ 160: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9160
+ 161: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9161
+ 162: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9162
+ 163: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9163
+ 164: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9164
+ 165: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9165
+ 166: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9166
+ 167: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9167
+ 168: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9168
+ 169: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9169
+ 170: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9170
+ 171: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9171
+ 172: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9172
+ 173: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9173
+ 174: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9174
+ 175: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9175
+ 176: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9176
+ 177: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9177
+ 178: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9178
+ 179: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9179
+ 180: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9180
+ 181: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9181
+ 182: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9182
+ 183: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9183
+ 184: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9184
+ 185: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9185
+ 186: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9186
+ 187: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9187
+ 188: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9188
+ 189: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9189
+ 190: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9190
+ 191: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9191
+ 192: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9192
+ 193: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9193
+ 194: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9194
+ 195: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9195
+ 196: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9196
+ 197: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9197
+ 198: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9198
+ 199: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9199
+ 200: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9200
+ 201: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9201
+ 202: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9202
+ 203: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9203
+ 204: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9204
+ 205: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9205
+ 206: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9206
+ 207: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9207
+ 208: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9208
+ 209: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9209
+ 210: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9210
+ 211: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9211
+ 212: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9212
+ 213: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9213
+ 214: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9214
+ 215: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9215
+ 216: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9216
+ 217: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9217
+ 218: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9218
+ 219: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9219
+ 220: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9220
+ 221: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9221
+ 222: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9222
+ 223: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9223
+ 224: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9224
+ 225: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9225
+ 226: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9226
+ 227: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9227
+ 228: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9228
+ 229: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9229
+ 230: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9230
+ 231: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9231
+ 232: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9232
+ 233: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9233
+ 234: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9234
+ 235: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9235
+ 236: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9236
+ 237: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9237
+ 238: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9238
+ 239: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9239
+ 240: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9240
+ 241: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9241
+ 242: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9242
+ 243: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9243
+ 244: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9244
+ 245: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9245
+ 246: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9246
+ 247: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9247
+ 248: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9248
+ 249: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9249
+ 250: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9250
+ 251: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9251
+ 252: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9252
+ 253: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9253
+ 254: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9254
+ 255: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9255
+ 256: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9256
+ 257: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9257
+ 258: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9258
+ 259: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9259
+ 260: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9260
+ 261: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9261
+ 262: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9262
+ 263: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9263
+ 264: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9264
+ 265: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9265
+ 266: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9266
+ 267: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9267
+ 268: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9268
+ 269: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9269
+ 270: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9270
+ 271: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9271
+ 272: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9272
+ 273: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9273
+ 274: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9274
+ 275: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9275
+ 276: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9276
+ 277: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9277
+ 278: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9278
+ 279: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9279
+ 280: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9280
+ 281: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9281
+ 282: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9282
+ 283: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9283
+ 284: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9284
+ 285: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9285
+ 286: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9286
+ 287: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9287
+ 288: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9288
+ 289: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9289
+ 290: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9290
+ 291: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9291
+ 292: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9292
+ 293: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9293
+ 294: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9294
+ 295: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9295
+ 296: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9296
+ 297: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9297
+ 298: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9298
+ 299: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9299
+ 300: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9300
+ 301: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9301
+ 302: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9302
+ 303: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9303
+ 304: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9304
+ 305: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9305
+ 306: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9306
+ 307: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9307
+ 308: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9308
+ 309: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9309
+ 310: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9310
+ 311: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9311
+ 312: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9312
+ 313: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9313
+ 314: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9314
+ 315: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9315
+ 316: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9316
+ 317: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9317
+ 318: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9318
+ 319: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9319
+ 320: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9320
+ 321: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9321
+ 322: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9322
+ 323: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9323
+ 324: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9324
+ 325: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9325
+ 326: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9326
+ 327: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9327
+ 328: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9328
+ 329: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9329
+ 330: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9330
+ 331: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9331
+ 332: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9332
+ 333: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9333
+ 334: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9334
+ 335: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9335
+ 336: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9336
+ 337: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9337
+ 338: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9338
+ 339: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9339
+ 340: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9340
+ 341: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9341
+ 342: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9342
+ 343: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9343
+ 344: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9344
+ 345: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9345
+ 346: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9346
+ 347: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9347
+ 348: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9348
+ 349: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9349
+ 350: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9350
+ 351: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9351
+ 352: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9352
+ 353: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9353
+ 354: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9354
+ 355: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9355
+ 356: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9356
+ 357: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9357
+ 358: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9358
+ 359: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9359
+ 360: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9360
+ 361: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9361
+ 362: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9362
+ 363: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9363
+ 364: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9364
+ 365: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9365
+ 366: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9366
+ 367: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9367
+ 368: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9368
+ 369: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9369
+ 370: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9370
+ 371: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9371
+ 372: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9372
+ 373: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9373
+ 374: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9374
+ 375: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9375
+ 376: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9376
+ 377: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9377
+ 378: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9378
+ 379: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9379
+ 380: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9380
+ 381: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9381
+ 382: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9382
+ 383: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9383
+ 384: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9384
+ 385: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9385
+ 386: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9386
+ 387: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9387
+ 388: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9388
+ 389: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9389
+ 390: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9390
+ 391: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9391
+ 392: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9392
+ 393: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9393
+ 394: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9394
+ 395: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9395
+ 396: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9396
+ 397: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9397
+ 398: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9398
+ 399: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9399
+ 400: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9400
+ 401: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9401
+ 402: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9402
+ 403: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9403
+ 404: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9404
+ 405: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9405
+ 406: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9406
+ 407: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9407
+ 408: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9408
+ 409: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9409
+ 410: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9410
+ 411: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9411
+ 412: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9412
+ 413: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9413
+ 414: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9414
+ 415: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9415
+ 416: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9416
+ 417: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9417
+ 418: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9418
+ 419: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9419
+ 420: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9420
+ 421: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9421
+ 422: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9422
+ 423: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9423
+ 424: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9424
+ 425: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9425
+ 426: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9426
+ 427: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9427
+ 428: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9428
+ 429: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9429
+ 430: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9430
+ 431: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9431
+ 432: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9432
+ 433: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9433
+ 434: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9434
+ 435: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9435
+ 436: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9436
+ 437: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9437
+ 438: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9438
+ 439: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9439
+ 440: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9440
+ 441: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9441
+ 442: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9442
+ 443: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9443
+ 444: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9444
+ 445: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9445
+ 446: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9446
+ 447: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9447
+ 448: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9448
+ 449: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9449
+ 450: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9450
+ 451: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9451
+ 452: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9452
+ 453: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9453
+ 454: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9454
+ 455: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9455
+ 456: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9456
+ 457: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9457
+ 458: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9458
+ 459: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9459
+ 460: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9460
+ 461: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9461
+ 462: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9462
+ 463: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9463
+ 464: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9464
+ 465: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9465
+ 466: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9466
+ 467: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9467
+ 468: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9468
+ 469: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9469
+ 470: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9470
+ 471: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9471
+ 472: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9472
+ 473: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9473
+ 474: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9474
+ 475: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9475
+ 476: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9476
+ 477: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9477
+ 478: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9478
+ 479: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9479
+ 480: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9480
+ 481: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9481
+ 482: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9482
+ 483: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9483
+ 484: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9484
+ 485: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9485
+ 486: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9486
+ 487: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9487
+ 488: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9488
+ 489: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9489
+ 490: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9490
+ 491: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9491
+ 492: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9492
+ 493: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9493
+ 494: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9494
+ 495: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9495
+ 496: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9496
+ 497: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9497
+ 498: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9498
+ 499: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9499
diff --git a/akregator/src/mk4storage/metakit/tests/ok/l04.txt b/akregator/src/mk4storage/metakit/tests/ok/l04.txt
new file mode 100644
index 000000000..23920007e
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/l04.txt
@@ -0,0 +1,2 @@
+>>> Modify sections in storage
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/l04a.txt b/akregator/src/mk4storage/metakit/tests/ok/l04a.txt
new file mode 100644
index 000000000..2eed1fc28
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/l04a.txt
@@ -0,0 +1,1503 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 500 rows = p1:V
+ 0: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 1
+ 1: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9001
+ 2: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9002
+ 3: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9003
+ 4: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9004
+ 5: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9005
+ 6: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9006
+ 7: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9007
+ 8: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9008
+ 9: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9009
+ 10: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9010
+ 11: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9011
+ 12: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9012
+ 13: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9013
+ 14: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9014
+ 15: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9015
+ 16: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9016
+ 17: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9017
+ 18: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9018
+ 19: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9019
+ 20: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9020
+ 21: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9021
+ 22: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9022
+ 23: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9023
+ 24: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9024
+ 25: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9025
+ 26: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9026
+ 27: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9027
+ 28: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9028
+ 29: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9029
+ 30: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9030
+ 31: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9031
+ 32: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9032
+ 33: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9033
+ 34: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9034
+ 35: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9035
+ 36: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9036
+ 37: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9037
+ 38: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9038
+ 39: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9039
+ 40: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9040
+ 41: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9041
+ 42: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9042
+ 43: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9043
+ 44: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9044
+ 45: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9045
+ 46: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9046
+ 47: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9047
+ 48: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9048
+ 49: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9049
+ 50: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9050
+ 51: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9051
+ 52: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9052
+ 53: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9053
+ 54: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9054
+ 55: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9055
+ 56: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9056
+ 57: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9057
+ 58: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9058
+ 59: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9059
+ 60: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9060
+ 61: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9061
+ 62: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9062
+ 63: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9063
+ 64: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9064
+ 65: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9065
+ 66: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9066
+ 67: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9067
+ 68: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9068
+ 69: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9069
+ 70: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9070
+ 71: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9071
+ 72: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9072
+ 73: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9073
+ 74: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9074
+ 75: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9075
+ 76: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9076
+ 77: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9077
+ 78: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9078
+ 79: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9079
+ 80: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9080
+ 81: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9081
+ 82: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9082
+ 83: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9083
+ 84: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9084
+ 85: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9085
+ 86: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9086
+ 87: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9087
+ 88: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9088
+ 89: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9089
+ 90: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9090
+ 91: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9091
+ 92: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9092
+ 93: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9093
+ 94: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9094
+ 95: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9095
+ 96: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9096
+ 97: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9097
+ 98: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9098
+ 99: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9099
+ 100: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9100
+ 101: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9101
+ 102: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9102
+ 103: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9103
+ 104: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9104
+ 105: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9105
+ 106: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9106
+ 107: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9107
+ 108: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9108
+ 109: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9109
+ 110: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9110
+ 111: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9111
+ 112: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9112
+ 113: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9113
+ 114: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9114
+ 115: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9115
+ 116: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9116
+ 117: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9117
+ 118: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9118
+ 119: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9119
+ 120: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9120
+ 121: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9121
+ 122: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9122
+ 123: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9123
+ 124: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9124
+ 125: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9125
+ 126: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9126
+ 127: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9127
+ 128: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9128
+ 129: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9129
+ 130: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9130
+ 131: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9131
+ 132: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9132
+ 133: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9133
+ 134: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9134
+ 135: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9135
+ 136: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9136
+ 137: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9137
+ 138: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9138
+ 139: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9139
+ 140: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9140
+ 141: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9141
+ 142: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9142
+ 143: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9143
+ 144: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9144
+ 145: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9145
+ 146: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9146
+ 147: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9147
+ 148: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9148
+ 149: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9149
+ 150: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9150
+ 151: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9151
+ 152: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9152
+ 153: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9153
+ 154: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9154
+ 155: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9155
+ 156: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9156
+ 157: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9157
+ 158: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9158
+ 159: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9159
+ 160: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9160
+ 161: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9161
+ 162: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9162
+ 163: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9163
+ 164: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9164
+ 165: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9165
+ 166: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9166
+ 167: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9167
+ 168: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9168
+ 169: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9169
+ 170: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9170
+ 171: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9171
+ 172: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9172
+ 173: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9173
+ 174: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9174
+ 175: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9175
+ 176: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9176
+ 177: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9177
+ 178: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9178
+ 179: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9179
+ 180: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9180
+ 181: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9181
+ 182: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9182
+ 183: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9183
+ 184: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9184
+ 185: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9185
+ 186: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9186
+ 187: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9187
+ 188: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9188
+ 189: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9189
+ 190: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9190
+ 191: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9191
+ 192: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9192
+ 193: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9193
+ 194: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9194
+ 195: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9195
+ 196: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9196
+ 197: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9197
+ 198: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9198
+ 199: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9199
+ 200: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9200
+ 201: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9201
+ 202: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9202
+ 203: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9203
+ 204: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9204
+ 205: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9205
+ 206: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9206
+ 207: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9207
+ 208: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9208
+ 209: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9209
+ 210: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9210
+ 211: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9211
+ 212: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9212
+ 213: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9213
+ 214: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9214
+ 215: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9215
+ 216: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9216
+ 217: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9217
+ 218: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9218
+ 219: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9219
+ 220: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9220
+ 221: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9221
+ 222: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9222
+ 223: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9223
+ 224: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9224
+ 225: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9225
+ 226: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9226
+ 227: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9227
+ 228: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9228
+ 229: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9229
+ 230: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9230
+ 231: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9231
+ 232: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9232
+ 233: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9233
+ 234: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9234
+ 235: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9235
+ 236: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9236
+ 237: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9237
+ 238: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9238
+ 239: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9239
+ 240: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9240
+ 241: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9241
+ 242: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9242
+ 243: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9243
+ 244: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9244
+ 245: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9245
+ 246: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9246
+ 247: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9247
+ 248: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9248
+ 249: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9249
+ 250: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9250
+ 251: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9251
+ 252: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9252
+ 253: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9253
+ 254: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9254
+ 255: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9255
+ 256: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9256
+ 257: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9257
+ 258: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9258
+ 259: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9259
+ 260: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9260
+ 261: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9261
+ 262: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9262
+ 263: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9263
+ 264: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9264
+ 265: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9265
+ 266: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9266
+ 267: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9267
+ 268: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9268
+ 269: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9269
+ 270: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9270
+ 271: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9271
+ 272: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9272
+ 273: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9273
+ 274: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9274
+ 275: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9275
+ 276: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9276
+ 277: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9277
+ 278: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9278
+ 279: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9279
+ 280: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9280
+ 281: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9281
+ 282: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9282
+ 283: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9283
+ 284: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9284
+ 285: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9285
+ 286: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9286
+ 287: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9287
+ 288: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9288
+ 289: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9289
+ 290: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9290
+ 291: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9291
+ 292: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9292
+ 293: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9293
+ 294: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9294
+ 295: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9295
+ 296: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9296
+ 297: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9297
+ 298: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9298
+ 299: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9299
+ 300: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9300
+ 301: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9301
+ 302: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9302
+ 303: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9303
+ 304: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9304
+ 305: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9305
+ 306: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9306
+ 307: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9307
+ 308: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9308
+ 309: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9309
+ 310: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9310
+ 311: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9311
+ 312: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9312
+ 313: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9313
+ 314: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9314
+ 315: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9315
+ 316: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9316
+ 317: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9317
+ 318: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9318
+ 319: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9319
+ 320: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9320
+ 321: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9321
+ 322: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9322
+ 323: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9323
+ 324: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9324
+ 325: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9325
+ 326: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9326
+ 327: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9327
+ 328: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9328
+ 329: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9329
+ 330: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9330
+ 331: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9331
+ 332: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9332
+ 333: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9333
+ 334: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9334
+ 335: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9335
+ 336: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9336
+ 337: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9337
+ 338: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9338
+ 339: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9339
+ 340: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9340
+ 341: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9341
+ 342: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9342
+ 343: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9343
+ 344: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9344
+ 345: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9345
+ 346: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9346
+ 347: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9347
+ 348: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9348
+ 349: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9349
+ 350: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9350
+ 351: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9351
+ 352: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9352
+ 353: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9353
+ 354: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9354
+ 355: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9355
+ 356: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9356
+ 357: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9357
+ 358: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9358
+ 359: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9359
+ 360: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9360
+ 361: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9361
+ 362: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9362
+ 363: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9363
+ 364: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9364
+ 365: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9365
+ 366: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9366
+ 367: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9367
+ 368: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9368
+ 369: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9369
+ 370: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9370
+ 371: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9371
+ 372: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9372
+ 373: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9373
+ 374: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9374
+ 375: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9375
+ 376: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9376
+ 377: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9377
+ 378: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9378
+ 379: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9379
+ 380: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9380
+ 381: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9381
+ 382: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9382
+ 383: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9383
+ 384: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9384
+ 385: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9385
+ 386: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9386
+ 387: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9387
+ 388: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9388
+ 389: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9389
+ 390: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9390
+ 391: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9391
+ 392: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9392
+ 393: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9393
+ 394: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9394
+ 395: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9395
+ 396: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9396
+ 397: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9397
+ 398: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9398
+ 399: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9399
+ 400: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9400
+ 401: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9401
+ 402: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9402
+ 403: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9403
+ 404: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9404
+ 405: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9405
+ 406: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9406
+ 407: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9407
+ 408: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9408
+ 409: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9409
+ 410: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9410
+ 411: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9411
+ 412: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9412
+ 413: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9413
+ 414: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9414
+ 415: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9415
+ 416: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9416
+ 417: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9417
+ 418: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9418
+ 419: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9419
+ 420: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9420
+ 421: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9421
+ 422: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9422
+ 423: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9423
+ 424: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9424
+ 425: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9425
+ 426: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9426
+ 427: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9427
+ 428: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9428
+ 429: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9429
+ 430: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9430
+ 431: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9431
+ 432: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9432
+ 433: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9433
+ 434: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9434
+ 435: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9435
+ 436: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9436
+ 437: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9437
+ 438: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9438
+ 439: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9439
+ 440: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9440
+ 441: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9441
+ 442: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9442
+ 443: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9443
+ 444: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9444
+ 445: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9445
+ 446: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9446
+ 447: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9447
+ 448: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9448
+ 449: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9449
+ 450: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9450
+ 451: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9451
+ 452: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9452
+ 453: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9453
+ 454: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9454
+ 455: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9455
+ 456: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9456
+ 457: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9457
+ 458: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9458
+ 459: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9459
+ 460: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9460
+ 461: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9461
+ 462: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9462
+ 463: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9463
+ 464: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9464
+ 465: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9465
+ 466: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9466
+ 467: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9467
+ 468: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9468
+ 469: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9469
+ 470: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9470
+ 471: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9471
+ 472: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9472
+ 473: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9473
+ 474: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9474
+ 475: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9475
+ 476: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9476
+ 477: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9477
+ 478: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9478
+ 479: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9479
+ 480: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9480
+ 481: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9481
+ 482: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9482
+ 483: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9483
+ 484: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9484
+ 485: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9485
+ 486: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9486
+ 487: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9487
+ 488: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9488
+ 489: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9489
+ 490: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9490
+ 491: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9491
+ 492: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9492
+ 493: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9493
+ 494: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9494
+ 495: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9495
+ 496: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9496
+ 497: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9497
+ 498: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9498
+ 499: subview 'p1'
+ VIEW 1 rows = p2:I
+ 0: 9499
diff --git a/akregator/src/mk4storage/metakit/tests/ok/l05.txt b/akregator/src/mk4storage/metakit/tests/ok/l05.txt
new file mode 100644
index 000000000..64d8af7ad
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/l05.txt
@@ -0,0 +1,2 @@
+>>> Delete from 32 Kb of strings
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/l05a.txt b/akregator/src/mk4storage/metakit/tests/ok/l05a.txt
new file mode 100644
index 000000000..d01cb2dc6
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/l05a.txt
@@ -0,0 +1,4 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 1 rows = p1:I p2:S p3:S
+ 0: 1747 'The wizard of Oz' 'The wizard of Oz'
diff --git a/akregator/src/mk4storage/metakit/tests/ok/l06.txt b/akregator/src/mk4storage/metakit/tests/ok/l06.txt
new file mode 100644
index 000000000..d5e421d0d
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/l06.txt
@@ -0,0 +1,2 @@
+>>> Bit field manipulations
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/l06a.txt b/akregator/src/mk4storage/metakit/tests/ok/l06a.txt
new file mode 100644
index 000000000..05757a48e
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/l06a.txt
@@ -0,0 +1,1371 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 1368 rows = p1:I
+ 0: 0
+ 1: 1
+ 2: 2
+ 3: 3
+ 4: 4
+ 5: 5
+ 6: 6
+ 7: 7
+ 8: 8
+ 9: 9
+ 10: 10
+ 11: 11
+ 12: 12
+ 13: 13
+ 14: 14
+ 15: 15
+ 16: 16
+ 17: 17
+ 18: 17
+ 19: 17
+ 20: 17
+ 21: 17
+ 22: 17
+ 23: 17
+ 24: 17
+ 25: 17
+ 26: 17
+ 27: 17
+ 28: 17
+ 29: 17
+ 30: 17
+ 31: 17
+ 32: 17
+ 33: 17
+ 34: 17
+ 35: 16
+ 36: 16
+ 37: 16
+ 38: 16
+ 39: 16
+ 40: 16
+ 41: 16
+ 42: 16
+ 43: 16
+ 44: 16
+ 45: 16
+ 46: 16
+ 47: 16
+ 48: 16
+ 49: 16
+ 50: 16
+ 51: 15
+ 52: 15
+ 53: 15
+ 54: 15
+ 55: 15
+ 56: 15
+ 57: 15
+ 58: 15
+ 59: 15
+ 60: 15
+ 61: 15
+ 62: 15
+ 63: 15
+ 64: 15
+ 65: 15
+ 66: 14
+ 67: 14
+ 68: 14
+ 69: 14
+ 70: 14
+ 71: 14
+ 72: 14
+ 73: 14
+ 74: 14
+ 75: 14
+ 76: 14
+ 77: 14
+ 78: 14
+ 79: 14
+ 80: 13
+ 81: 13
+ 82: 13
+ 83: 13
+ 84: 13
+ 85: 13
+ 86: 13
+ 87: 13
+ 88: 13
+ 89: 13
+ 90: 13
+ 91: 13
+ 92: 13
+ 93: 12
+ 94: 12
+ 95: 12
+ 96: 12
+ 97: 12
+ 98: 12
+ 99: 12
+ 100: 12
+ 101: 12
+ 102: 12
+ 103: 12
+ 104: 12
+ 105: 11
+ 106: 11
+ 107: 11
+ 108: 11
+ 109: 11
+ 110: 11
+ 111: 11
+ 112: 11
+ 113: 11
+ 114: 11
+ 115: 11
+ 116: 10
+ 117: 10
+ 118: 10
+ 119: 10
+ 120: 10
+ 121: 10
+ 122: 10
+ 123: 10
+ 124: 10
+ 125: 10
+ 126: 9
+ 127: 9
+ 128: 9
+ 129: 9
+ 130: 9
+ 131: 9
+ 132: 9
+ 133: 9
+ 134: 9
+ 135: 8
+ 136: 8
+ 137: 8
+ 138: 8
+ 139: 8
+ 140: 8
+ 141: 8
+ 142: 8
+ 143: 7
+ 144: 7
+ 145: 7
+ 146: 7
+ 147: 7
+ 148: 7
+ 149: 7
+ 150: 6
+ 151: 6
+ 152: 6
+ 153: 6
+ 154: 6
+ 155: 6
+ 156: 5
+ 157: 5
+ 158: 5
+ 159: 5
+ 160: 5
+ 161: 4
+ 162: 4
+ 163: 4
+ 164: 4
+ 165: 3
+ 166: 3
+ 167: 3
+ 168: 2
+ 169: 2
+ 170: 1
+ 171: 0
+ 172: 1
+ 173: 2
+ 174: 3
+ 175: 4
+ 176: 5
+ 177: 6
+ 178: 7
+ 179: 8
+ 180: 9
+ 181: 10
+ 182: 11
+ 183: 12
+ 184: 13
+ 185: 14
+ 186: 15
+ 187: 16
+ 188: 17
+ 189: 17
+ 190: 17
+ 191: 17
+ 192: 17
+ 193: 17
+ 194: 17
+ 195: 17
+ 196: 17
+ 197: 17
+ 198: 17
+ 199: 17
+ 200: 17
+ 201: 17
+ 202: 17
+ 203: 17
+ 204: 17
+ 205: 17
+ 206: 16
+ 207: 16
+ 208: 16
+ 209: 16
+ 210: 16
+ 211: 16
+ 212: 16
+ 213: 16
+ 214: 16
+ 215: 16
+ 216: 16
+ 217: 16
+ 218: 16
+ 219: 16
+ 220: 16
+ 221: 16
+ 222: 15
+ 223: 15
+ 224: 15
+ 225: 15
+ 226: 15
+ 227: 15
+ 228: 15
+ 229: 15
+ 230: 15
+ 231: 15
+ 232: 15
+ 233: 15
+ 234: 15
+ 235: 15
+ 236: 15
+ 237: 14
+ 238: 14
+ 239: 14
+ 240: 14
+ 241: 14
+ 242: 14
+ 243: 14
+ 244: 14
+ 245: 14
+ 246: 14
+ 247: 14
+ 248: 14
+ 249: 14
+ 250: 14
+ 251: 13
+ 252: 13
+ 253: 13
+ 254: 13
+ 255: 13
+ 256: 13
+ 257: 13
+ 258: 13
+ 259: 13
+ 260: 13
+ 261: 13
+ 262: 13
+ 263: 13
+ 264: 12
+ 265: 12
+ 266: 12
+ 267: 12
+ 268: 12
+ 269: 12
+ 270: 12
+ 271: 12
+ 272: 12
+ 273: 12
+ 274: 12
+ 275: 12
+ 276: 11
+ 277: 11
+ 278: 11
+ 279: 11
+ 280: 11
+ 281: 11
+ 282: 11
+ 283: 11
+ 284: 11
+ 285: 11
+ 286: 11
+ 287: 10
+ 288: 10
+ 289: 10
+ 290: 10
+ 291: 10
+ 292: 10
+ 293: 10
+ 294: 10
+ 295: 10
+ 296: 10
+ 297: 9
+ 298: 9
+ 299: 9
+ 300: 9
+ 301: 9
+ 302: 9
+ 303: 9
+ 304: 9
+ 305: 9
+ 306: 8
+ 307: 8
+ 308: 8
+ 309: 8
+ 310: 8
+ 311: 8
+ 312: 8
+ 313: 8
+ 314: 7
+ 315: 7
+ 316: 7
+ 317: 7
+ 318: 7
+ 319: 7
+ 320: 7
+ 321: 6
+ 322: 6
+ 323: 6
+ 324: 6
+ 325: 6
+ 326: 6
+ 327: 5
+ 328: 5
+ 329: 5
+ 330: 5
+ 331: 5
+ 332: 4
+ 333: 4
+ 334: 4
+ 335: 4
+ 336: 3
+ 337: 3
+ 338: 3
+ 339: 2
+ 340: 2
+ 341: 1
+ 342: 0
+ 343: 1
+ 344: 2
+ 345: 3
+ 346: 4
+ 347: 5
+ 348: 6
+ 349: 7
+ 350: 8
+ 351: 9
+ 352: 10
+ 353: 11
+ 354: 12
+ 355: 13
+ 356: 14
+ 357: 15
+ 358: 16
+ 359: 17
+ 360: 17
+ 361: 17
+ 362: 17
+ 363: 17
+ 364: 17
+ 365: 17
+ 366: 17
+ 367: 17
+ 368: 17
+ 369: 17
+ 370: 17
+ 371: 17
+ 372: 17
+ 373: 17
+ 374: 17
+ 375: 17
+ 376: 17
+ 377: 16
+ 378: 16
+ 379: 16
+ 380: 16
+ 381: 16
+ 382: 16
+ 383: 16
+ 384: 16
+ 385: 16
+ 386: 16
+ 387: 16
+ 388: 16
+ 389: 16
+ 390: 16
+ 391: 16
+ 392: 16
+ 393: 15
+ 394: 15
+ 395: 15
+ 396: 15
+ 397: 15
+ 398: 15
+ 399: 15
+ 400: 15
+ 401: 15
+ 402: 15
+ 403: 15
+ 404: 15
+ 405: 15
+ 406: 15
+ 407: 15
+ 408: 14
+ 409: 14
+ 410: 14
+ 411: 14
+ 412: 14
+ 413: 14
+ 414: 14
+ 415: 14
+ 416: 14
+ 417: 14
+ 418: 14
+ 419: 14
+ 420: 14
+ 421: 14
+ 422: 13
+ 423: 13
+ 424: 13
+ 425: 13
+ 426: 13
+ 427: 13
+ 428: 13
+ 429: 13
+ 430: 13
+ 431: 13
+ 432: 13
+ 433: 13
+ 434: 13
+ 435: 12
+ 436: 12
+ 437: 12
+ 438: 12
+ 439: 12
+ 440: 12
+ 441: 12
+ 442: 12
+ 443: 12
+ 444: 12
+ 445: 12
+ 446: 12
+ 447: 11
+ 448: 11
+ 449: 11
+ 450: 11
+ 451: 11
+ 452: 11
+ 453: 11
+ 454: 11
+ 455: 11
+ 456: 11
+ 457: 11
+ 458: 10
+ 459: 10
+ 460: 10
+ 461: 10
+ 462: 10
+ 463: 10
+ 464: 10
+ 465: 10
+ 466: 10
+ 467: 10
+ 468: 9
+ 469: 9
+ 470: 9
+ 471: 9
+ 472: 9
+ 473: 9
+ 474: 9
+ 475: 9
+ 476: 9
+ 477: 8
+ 478: 8
+ 479: 8
+ 480: 8
+ 481: 8
+ 482: 8
+ 483: 8
+ 484: 8
+ 485: 7
+ 486: 7
+ 487: 7
+ 488: 7
+ 489: 7
+ 490: 7
+ 491: 7
+ 492: 6
+ 493: 6
+ 494: 6
+ 495: 6
+ 496: 6
+ 497: 6
+ 498: 5
+ 499: 5
+ 500: 5
+ 501: 5
+ 502: 5
+ 503: 4
+ 504: 4
+ 505: 4
+ 506: 4
+ 507: 3
+ 508: 3
+ 509: 3
+ 510: 2
+ 511: 2
+ 512: 1
+ 513: 0
+ 514: 1
+ 515: 2
+ 516: 3
+ 517: 4
+ 518: 5
+ 519: 6
+ 520: 7
+ 521: 8
+ 522: 9
+ 523: 10
+ 524: 11
+ 525: 12
+ 526: 13
+ 527: 14
+ 528: 15
+ 529: 16
+ 530: 17
+ 531: 17
+ 532: 17
+ 533: 17
+ 534: 17
+ 535: 17
+ 536: 17
+ 537: 17
+ 538: 17
+ 539: 17
+ 540: 17
+ 541: 17
+ 542: 17
+ 543: 17
+ 544: 17
+ 545: 17
+ 546: 17
+ 547: 17
+ 548: 16
+ 549: 16
+ 550: 16
+ 551: 16
+ 552: 16
+ 553: 16
+ 554: 16
+ 555: 16
+ 556: 16
+ 557: 16
+ 558: 16
+ 559: 16
+ 560: 16
+ 561: 16
+ 562: 16
+ 563: 16
+ 564: 15
+ 565: 15
+ 566: 15
+ 567: 15
+ 568: 15
+ 569: 15
+ 570: 15
+ 571: 15
+ 572: 15
+ 573: 15
+ 574: 15
+ 575: 15
+ 576: 15
+ 577: 15
+ 578: 15
+ 579: 14
+ 580: 14
+ 581: 14
+ 582: 14
+ 583: 14
+ 584: 14
+ 585: 14
+ 586: 14
+ 587: 14
+ 588: 14
+ 589: 14
+ 590: 14
+ 591: 14
+ 592: 14
+ 593: 13
+ 594: 13
+ 595: 13
+ 596: 13
+ 597: 13
+ 598: 13
+ 599: 13
+ 600: 13
+ 601: 13
+ 602: 13
+ 603: 13
+ 604: 13
+ 605: 13
+ 606: 12
+ 607: 12
+ 608: 12
+ 609: 12
+ 610: 12
+ 611: 12
+ 612: 12
+ 613: 12
+ 614: 12
+ 615: 12
+ 616: 12
+ 617: 12
+ 618: 11
+ 619: 11
+ 620: 11
+ 621: 11
+ 622: 11
+ 623: 11
+ 624: 11
+ 625: 11
+ 626: 11
+ 627: 11
+ 628: 11
+ 629: 10
+ 630: 10
+ 631: 10
+ 632: 10
+ 633: 10
+ 634: 10
+ 635: 10
+ 636: 10
+ 637: 10
+ 638: 10
+ 639: 9
+ 640: 9
+ 641: 9
+ 642: 9
+ 643: 9
+ 644: 9
+ 645: 9
+ 646: 9
+ 647: 9
+ 648: 8
+ 649: 8
+ 650: 8
+ 651: 8
+ 652: 8
+ 653: 8
+ 654: 8
+ 655: 8
+ 656: 7
+ 657: 7
+ 658: 7
+ 659: 7
+ 660: 7
+ 661: 7
+ 662: 7
+ 663: 6
+ 664: 6
+ 665: 6
+ 666: 6
+ 667: 6
+ 668: 6
+ 669: 5
+ 670: 5
+ 671: 5
+ 672: 5
+ 673: 5
+ 674: 4
+ 675: 4
+ 676: 4
+ 677: 4
+ 678: 3
+ 679: 3
+ 680: 3
+ 681: 2
+ 682: 2
+ 683: 1
+ 684: 0
+ 685: 1
+ 686: 2
+ 687: 3
+ 688: 4
+ 689: 5
+ 690: 6
+ 691: 7
+ 692: 8
+ 693: 9
+ 694: 10
+ 695: 11
+ 696: 12
+ 697: 13
+ 698: 14
+ 699: 15
+ 700: 0
+ 701: 1
+ 702: 1
+ 703: 1
+ 704: 1
+ 705: 1
+ 706: 1
+ 707: 1
+ 708: 1
+ 709: 1
+ 710: 1
+ 711: 1
+ 712: 1
+ 713: 1
+ 714: 1
+ 715: 1
+ 716: 1
+ 717: 1
+ 718: 1
+ 719: 0
+ 720: 0
+ 721: 0
+ 722: 0
+ 723: 0
+ 724: 0
+ 725: 0
+ 726: 0
+ 727: 0
+ 728: 0
+ 729: 0
+ 730: 0
+ 731: 0
+ 732: 0
+ 733: 0
+ 734: 0
+ 735: 15
+ 736: 15
+ 737: 15
+ 738: 15
+ 739: 15
+ 740: 15
+ 741: 15
+ 742: 15
+ 743: 15
+ 744: 15
+ 745: 15
+ 746: 15
+ 747: 15
+ 748: 15
+ 749: 15
+ 750: 14
+ 751: 14
+ 752: 14
+ 753: 14
+ 754: 14
+ 755: 14
+ 756: 14
+ 757: 14
+ 758: 14
+ 759: 14
+ 760: 14
+ 761: 14
+ 762: 14
+ 763: 14
+ 764: 13
+ 765: 13
+ 766: 13
+ 767: 13
+ 768: 13
+ 769: 13
+ 770: 13
+ 771: 13
+ 772: 13
+ 773: 13
+ 774: 13
+ 775: 13
+ 776: 13
+ 777: 12
+ 778: 12
+ 779: 12
+ 780: 12
+ 781: 12
+ 782: 12
+ 783: 12
+ 784: 12
+ 785: 12
+ 786: 12
+ 787: 12
+ 788: 12
+ 789: 11
+ 790: 11
+ 791: 11
+ 792: 11
+ 793: 11
+ 794: 11
+ 795: 11
+ 796: 11
+ 797: 11
+ 798: 11
+ 799: 11
+ 800: 10
+ 801: 10
+ 802: 10
+ 803: 10
+ 804: 10
+ 805: 10
+ 806: 10
+ 807: 10
+ 808: 10
+ 809: 10
+ 810: 9
+ 811: 9
+ 812: 9
+ 813: 9
+ 814: 9
+ 815: 9
+ 816: 9
+ 817: 9
+ 818: 9
+ 819: 8
+ 820: 8
+ 821: 8
+ 822: 8
+ 823: 8
+ 824: 8
+ 825: 8
+ 826: 8
+ 827: 7
+ 828: 7
+ 829: 7
+ 830: 7
+ 831: 7
+ 832: 7
+ 833: 7
+ 834: 6
+ 835: 6
+ 836: 6
+ 837: 6
+ 838: 6
+ 839: 6
+ 840: 5
+ 841: 5
+ 842: 5
+ 843: 5
+ 844: 5
+ 845: 4
+ 846: 4
+ 847: 4
+ 848: 4
+ 849: 3
+ 850: 3
+ 851: 3
+ 852: 2
+ 853: 2
+ 854: 1
+ 855: 0
+ 856: 1
+ 857: 2
+ 858: 3
+ 859: 4
+ 860: 5
+ 861: 6
+ 862: 7
+ 863: 0
+ 864: 1
+ 865: 2
+ 866: 3
+ 867: 4
+ 868: 5
+ 869: 6
+ 870: 7
+ 871: 0
+ 872: 1
+ 873: 1
+ 874: 1
+ 875: 1
+ 876: 1
+ 877: 1
+ 878: 1
+ 879: 1
+ 880: 1
+ 881: 1
+ 882: 1
+ 883: 1
+ 884: 1
+ 885: 1
+ 886: 1
+ 887: 1
+ 888: 1
+ 889: 1
+ 890: 0
+ 891: 0
+ 892: 0
+ 893: 0
+ 894: 0
+ 895: 0
+ 896: 0
+ 897: 0
+ 898: 0
+ 899: 0
+ 900: 0
+ 901: 0
+ 902: 0
+ 903: 0
+ 904: 0
+ 905: 0
+ 906: 7
+ 907: 7
+ 908: 7
+ 909: 7
+ 910: 7
+ 911: 7
+ 912: 7
+ 913: 7
+ 914: 7
+ 915: 7
+ 916: 7
+ 917: 7
+ 918: 7
+ 919: 7
+ 920: 7
+ 921: 6
+ 922: 6
+ 923: 6
+ 924: 6
+ 925: 6
+ 926: 6
+ 927: 6
+ 928: 6
+ 929: 6
+ 930: 6
+ 931: 6
+ 932: 6
+ 933: 6
+ 934: 6
+ 935: 5
+ 936: 5
+ 937: 5
+ 938: 5
+ 939: 5
+ 940: 5
+ 941: 5
+ 942: 5
+ 943: 5
+ 944: 5
+ 945: 5
+ 946: 5
+ 947: 5
+ 948: 4
+ 949: 4
+ 950: 4
+ 951: 4
+ 952: 4
+ 953: 4
+ 954: 4
+ 955: 4
+ 956: 4
+ 957: 4
+ 958: 4
+ 959: 4
+ 960: 3
+ 961: 3
+ 962: 3
+ 963: 3
+ 964: 3
+ 965: 3
+ 966: 3
+ 967: 3
+ 968: 3
+ 969: 3
+ 970: 3
+ 971: 2
+ 972: 2
+ 973: 2
+ 974: 2
+ 975: 2
+ 976: 2
+ 977: 2
+ 978: 2
+ 979: 2
+ 980: 2
+ 981: 1
+ 982: 1
+ 983: 1
+ 984: 1
+ 985: 1
+ 986: 1
+ 987: 1
+ 988: 1
+ 989: 1
+ 990: 0
+ 991: 0
+ 992: 0
+ 993: 0
+ 994: 0
+ 995: 0
+ 996: 0
+ 997: 0
+ 998: 7
+ 999: 7
+ 1000: 7
+ 1001: 7
+ 1002: 7
+ 1003: 7
+ 1004: 7
+ 1005: 6
+ 1006: 6
+ 1007: 6
+ 1008: 6
+ 1009: 6
+ 1010: 6
+ 1011: 5
+ 1012: 5
+ 1013: 5
+ 1014: 5
+ 1015: 5
+ 1016: 4
+ 1017: 4
+ 1018: 4
+ 1019: 4
+ 1020: 3
+ 1021: 3
+ 1022: 3
+ 1023: 2
+ 1024: 2
+ 1025: 1
+ 1026: 0
+ 1027: 1
+ 1028: 2
+ 1029: 3
+ 1030: 0
+ 1031: 1
+ 1032: 2
+ 1033: 3
+ 1034: 0
+ 1035: 1
+ 1036: 2
+ 1037: 3
+ 1038: 0
+ 1039: 1
+ 1040: 2
+ 1041: 3
+ 1042: 0
+ 1043: 1
+ 1044: 1
+ 1045: 1
+ 1046: 1
+ 1047: 1
+ 1048: 1
+ 1049: 1
+ 1050: 1
+ 1051: 1
+ 1052: 1
+ 1053: 1
+ 1054: 1
+ 1055: 1
+ 1056: 1
+ 1057: 1
+ 1058: 1
+ 1059: 1
+ 1060: 1
+ 1061: 0
+ 1062: 0
+ 1063: 0
+ 1064: 0
+ 1065: 0
+ 1066: 0
+ 1067: 0
+ 1068: 0
+ 1069: 0
+ 1070: 0
+ 1071: 0
+ 1072: 0
+ 1073: 0
+ 1074: 0
+ 1075: 0
+ 1076: 0
+ 1077: 3
+ 1078: 3
+ 1079: 3
+ 1080: 3
+ 1081: 3
+ 1082: 3
+ 1083: 3
+ 1084: 3
+ 1085: 3
+ 1086: 3
+ 1087: 3
+ 1088: 3
+ 1089: 3
+ 1090: 3
+ 1091: 3
+ 1092: 2
+ 1093: 2
+ 1094: 2
+ 1095: 2
+ 1096: 2
+ 1097: 2
+ 1098: 2
+ 1099: 2
+ 1100: 2
+ 1101: 2
+ 1102: 2
+ 1103: 2
+ 1104: 2
+ 1105: 2
+ 1106: 1
+ 1107: 1
+ 1108: 1
+ 1109: 1
+ 1110: 1
+ 1111: 1
+ 1112: 1
+ 1113: 1
+ 1114: 1
+ 1115: 1
+ 1116: 1
+ 1117: 1
+ 1118: 1
+ 1119: 0
+ 1120: 0
+ 1121: 0
+ 1122: 0
+ 1123: 0
+ 1124: 0
+ 1125: 0
+ 1126: 0
+ 1127: 0
+ 1128: 0
+ 1129: 0
+ 1130: 0
+ 1131: 3
+ 1132: 3
+ 1133: 3
+ 1134: 3
+ 1135: 3
+ 1136: 3
+ 1137: 3
+ 1138: 3
+ 1139: 3
+ 1140: 3
+ 1141: 3
+ 1142: 2
+ 1143: 2
+ 1144: 2
+ 1145: 2
+ 1146: 2
+ 1147: 2
+ 1148: 2
+ 1149: 2
+ 1150: 2
+ 1151: 2
+ 1152: 1
+ 1153: 1
+ 1154: 1
+ 1155: 1
+ 1156: 1
+ 1157: 1
+ 1158: 1
+ 1159: 1
+ 1160: 1
+ 1161: 0
+ 1162: 0
+ 1163: 0
+ 1164: 0
+ 1165: 0
+ 1166: 0
+ 1167: 0
+ 1168: 0
+ 1169: 3
+ 1170: 3
+ 1171: 3
+ 1172: 3
+ 1173: 3
+ 1174: 3
+ 1175: 3
+ 1176: 2
+ 1177: 2
+ 1178: 2
+ 1179: 2
+ 1180: 2
+ 1181: 2
+ 1182: 1
+ 1183: 1
+ 1184: 1
+ 1185: 1
+ 1186: 1
+ 1187: 0
+ 1188: 0
+ 1189: 0
+ 1190: 0
+ 1191: 3
+ 1192: 3
+ 1193: 3
+ 1194: 2
+ 1195: 2
+ 1196: 1
+ 1197: 0
+ 1198: 1
+ 1199: 0
+ 1200: 1
+ 1201: 0
+ 1202: 1
+ 1203: 0
+ 1204: 1
+ 1205: 0
+ 1206: 1
+ 1207: 0
+ 1208: 1
+ 1209: 0
+ 1210: 1
+ 1211: 0
+ 1212: 1
+ 1213: 0
+ 1214: 1
+ 1215: 1
+ 1216: 1
+ 1217: 1
+ 1218: 1
+ 1219: 1
+ 1220: 1
+ 1221: 1
+ 1222: 1
+ 1223: 1
+ 1224: 1
+ 1225: 1
+ 1226: 1
+ 1227: 1
+ 1228: 1
+ 1229: 1
+ 1230: 1
+ 1231: 1
+ 1232: 0
+ 1233: 0
+ 1234: 0
+ 1235: 0
+ 1236: 0
+ 1237: 0
+ 1238: 0
+ 1239: 0
+ 1240: 0
+ 1241: 0
+ 1242: 0
+ 1243: 0
+ 1244: 0
+ 1245: 0
+ 1246: 0
+ 1247: 0
+ 1248: 1
+ 1249: 1
+ 1250: 1
+ 1251: 1
+ 1252: 1
+ 1253: 1
+ 1254: 1
+ 1255: 1
+ 1256: 1
+ 1257: 1
+ 1258: 1
+ 1259: 1
+ 1260: 1
+ 1261: 1
+ 1262: 1
+ 1263: 0
+ 1264: 0
+ 1265: 0
+ 1266: 0
+ 1267: 0
+ 1268: 0
+ 1269: 0
+ 1270: 0
+ 1271: 0
+ 1272: 0
+ 1273: 0
+ 1274: 0
+ 1275: 0
+ 1276: 0
+ 1277: 1
+ 1278: 1
+ 1279: 1
+ 1280: 1
+ 1281: 1
+ 1282: 1
+ 1283: 1
+ 1284: 1
+ 1285: 1
+ 1286: 1
+ 1287: 1
+ 1288: 1
+ 1289: 1
+ 1290: 0
+ 1291: 0
+ 1292: 0
+ 1293: 0
+ 1294: 0
+ 1295: 0
+ 1296: 0
+ 1297: 0
+ 1298: 0
+ 1299: 0
+ 1300: 0
+ 1301: 0
+ 1302: 1
+ 1303: 1
+ 1304: 1
+ 1305: 1
+ 1306: 1
+ 1307: 1
+ 1308: 1
+ 1309: 1
+ 1310: 1
+ 1311: 1
+ 1312: 1
+ 1313: 0
+ 1314: 0
+ 1315: 0
+ 1316: 0
+ 1317: 0
+ 1318: 0
+ 1319: 0
+ 1320: 0
+ 1321: 0
+ 1322: 0
+ 1323: 1
+ 1324: 1
+ 1325: 1
+ 1326: 1
+ 1327: 1
+ 1328: 1
+ 1329: 1
+ 1330: 1
+ 1331: 1
+ 1332: 0
+ 1333: 0
+ 1334: 0
+ 1335: 0
+ 1336: 0
+ 1337: 0
+ 1338: 0
+ 1339: 0
+ 1340: 1
+ 1341: 1
+ 1342: 1
+ 1343: 1
+ 1344: 1
+ 1345: 1
+ 1346: 1
+ 1347: 0
+ 1348: 0
+ 1349: 0
+ 1350: 0
+ 1351: 0
+ 1352: 0
+ 1353: 1
+ 1354: 1
+ 1355: 1
+ 1356: 1
+ 1357: 1
+ 1358: 0
+ 1359: 0
+ 1360: 0
+ 1361: 0
+ 1362: 1
+ 1363: 1
+ 1364: 1
+ 1365: 0
+ 1366: 0
+ 1367: 1
diff --git a/akregator/src/mk4storage/metakit/tests/ok/l07.txt b/akregator/src/mk4storage/metakit/tests/ok/l07.txt
new file mode 100644
index 000000000..fa6b10cfc
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/l07.txt
@@ -0,0 +1,2 @@
+>>> Huge description
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/l07a.txt b/akregator/src/mk4storage/metakit/tests/ok/l07a.txt
new file mode 100644
index 000000000..11c013725
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/l07a.txt
@@ -0,0 +1,4 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 1 rows = a123456789a123456789a123456789p1:I a123456789a123456789a123456789p2:I a123456789a123456789a123456789p3:I a123456789a123456789a123456789p4:I a123456789a123456789a123456789p5:I a123456789a123456789a123456789p6:I a123456789a123456789a123456789p7:I a123456789a123456789a123456789p8:I a123456789a123456789a123456789p9:I a123456789a123456789a123456789p10:I a123456789a123456789a123456789p11:I a123456789a123456789a123456789p12:I a123456789a123456789a123456789p13:I a123456789a123456789a123456789p14:I a123456789a123456789a123456789p15:I a123456789a123456789a123456789p16:I a123456789a123456789a123456789p17:I a123456789a123456789a123456789p18:I a123456789a123456789a123456789p19:I a123456789a123456789a123456789p20:I a123456789a123456789a123456789p21:I a123456789a123456789a123456789p22:I a123456789a123456789a123456789p23:I a123456789a123456789a123456789p24:I a123456789a123456789a123456789p25:I a123456789a123456789a123456789p26:I a123456789a123456789a123456789p27:I a123456789a123456789a123456789p28:I a123456789a123456789a123456789p29:I a123456789a123456789a123456789p30:I a123456789a123456789a123456789p31:I a123456789a123456789a123456789p32:I a123456789a123456789a123456789p33:I a123456789a123456789a123456789p34:I a123456789a123456789a123456789p35:I a123456789a123456789a123456789p36:I a123456789a123456789a123456789p37:I a123456789a123456789a123456789p38:I a123456789a123456789a123456789p39:I a123456789a123456789a123456789p40:I a123456789a123456789a123456789p41:I a123456789a123456789a123456789p42:I a123456789a123456789a123456789p43:I a123456789a123456789a123456789p44:I a123456789a123456789a123456789p45:I a123456789a123456789a123456789p46:I a123456789a123456789a123456789p47:I a123456789a123456789a123456789p48:I a123456789a123456789a123456789p49:I a123456789a123456789a123456789p50:I a123456789a123456789a123456789p51:I a123456789a123456789a123456789p52:I a123456789a123456789a123456789p53:I a123456789a123456789a123456789p54:I a123456789a123456789a123456789p55:I a123456789a123456789a123456789p56:I a123456789a123456789a123456789p57:I a123456789a123456789a123456789p58:I a123456789a123456789a123456789p59:I a123456789a123456789a123456789p60:I a123456789a123456789a123456789p61:I a123456789a123456789a123456789p62:I a123456789a123456789a123456789p63:I a123456789a123456789a123456789p64:I a123456789a123456789a123456789p65:I a123456789a123456789a123456789p66:I a123456789a123456789a123456789p67:I a123456789a123456789a123456789p68:I a123456789a123456789a123456789p69:I a123456789a123456789a123456789p70:I a123456789a123456789a123456789p71:I a123456789a123456789a123456789p72:I a123456789a123456789a123456789p73:I a123456789a123456789a123456789p74:I a123456789a123456789a123456789p75:I a123456789a123456789a123456789p76:I a123456789a123456789a123456789p77:I a123456789a123456789a123456789p78:I a123456789a123456789a123456789p79:I a123456789a123456789a123456789p80:I a123456789a123456789a123456789p81:I a123456789a123456789a123456789p82:I a123456789a123456789a123456789p83:I a123456789a123456789a123456789p84:I a123456789a123456789a123456789p85:I a123456789a123456789a123456789p86:I a123456789a123456789a123456789p87:I a123456789a123456789a123456789p88:I a123456789a123456789a123456789p89:I a123456789a123456789a123456789p90:I a123456789a123456789a123456789p91:I a123456789a123456789a123456789p92:I a123456789a123456789a123456789p93:I a123456789a123456789a123456789p94:I a123456789a123456789a123456789p95:I a123456789a123456789a123456789p96:I a123456789a123456789a123456789p97:I a123456789a123456789a123456789p98:I a123456789a123456789a123456789p99:I a123456789a123456789a123456789p100:I a123456789a123456789a123456789p101:I a123456789a123456789a123456789p102:I a123456789a123456789a123456789p103:I a123456789a123456789a123456789p104:I a123456789a123456789a123456789p105:I a123456789a123456789a123456789p106:I a123456789a123456789a123456789p107:I a123456789a123456789a123456789p108:I a123456789a123456789a123456789p109:I a123456789a123456789a123456789p110:I a123456789a123456789a123456789p111:I a123456789a123456789a123456789p112:I a123456789a123456789a123456789p113:I a123456789a123456789a123456789p114:I a123456789a123456789a123456789p115:I a123456789a123456789a123456789p116:I a123456789a123456789a123456789p117:I a123456789a123456789a123456789p118:I a123456789a123456789a123456789p119:I a123456789a123456789a123456789p120:I a123456789a123456789a123456789p121:I a123456789a123456789a123456789p122:I a123456789a123456789a123456789p123:I a123456789a123456789a123456789p124:I a123456789a123456789a123456789p125:I a123456789a123456789a123456789p126:I a123456789a123456789a123456789p127:I a123456789a123456789a123456789p128:I a123456789a123456789a123456789p129:I a123456789a123456789a123456789p130:I a123456789a123456789a123456789p131:I a123456789a123456789a123456789p132:I a123456789a123456789a123456789p133:I a123456789a123456789a123456789p134:I a123456789a123456789a123456789p135:I a123456789a123456789a123456789p136:I a123456789a123456789a123456789p137:I a123456789a123456789a123456789p138:I a123456789a123456789a123456789p139:I a123456789a123456789a123456789p140:I a123456789a123456789a123456789p141:I a123456789a123456789a123456789p142:I a123456789a123456789a123456789p143:I a123456789a123456789a123456789p144:I a123456789a123456789a123456789p145:I a123456789a123456789a123456789p146:I a123456789a123456789a123456789p147:I a123456789a123456789a123456789p148:I a123456789a123456789a123456789p149:I
+ 0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
diff --git a/akregator/src/mk4storage/metakit/tests/ok/m01.txt b/akregator/src/mk4storage/metakit/tests/ok/m01.txt
new file mode 100644
index 000000000..0c3bb84be
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/m01.txt
@@ -0,0 +1,2 @@
+>>> Hash mapping
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/m02.txt b/akregator/src/mk4storage/metakit/tests/ok/m02.txt
new file mode 100644
index 000000000..703e30b2d
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/m02.txt
@@ -0,0 +1,2 @@
+>>> Blocked view bug
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/m02a.txt b/akregator/src/mk4storage/metakit/tests/ok/m02a.txt
new file mode 100644
index 000000000..c51c6f2a6
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/m02a.txt
@@ -0,0 +1,22 @@
+ VIEW 1 rows = v1:V
+ 0: subview 'v1'
+ VIEW 2 rows = _B:V
+ 0: subview '_B'
+ VIEW 15 rows = p1:B
+ 0: (3490b)
+ 1: (3491b)
+ 2: (3492b)
+ 3: (3493b)
+ 4: (3494b)
+ 5: (3495b)
+ 6: (3496b)
+ 7: (3497b)
+ 8: (3498b)
+ 9: (3499b)
+ 10: (3500b)
+ 11: (3501b)
+ 12: (3502b)
+ 13: (3503b)
+ 14: (3504b)
+ 1: subview '_B'
+ VIEW 0 rows = p1:B
diff --git a/akregator/src/mk4storage/metakit/tests/ok/m03.txt b/akregator/src/mk4storage/metakit/tests/ok/m03.txt
new file mode 100644
index 000000000..f80527b3c
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/m03.txt
@@ -0,0 +1,2 @@
+>>> Hash adds
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/m03a.txt b/akregator/src/mk4storage/metakit/tests/ok/m03a.txt
new file mode 100644
index 000000000..dc96ffa34
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/m03a.txt
@@ -0,0 +1,55 @@
+ VIEW 1 rows = d1:V m1:V d2:V m2:V d3:V m3:V d4:V m4:V
+ 0: subview 'd1'
+ VIEW 4 rows = p1:S
+ 0: 'one'
+ 1: 'two'
+ 2: 'three'
+ 3: 'four'
+ 0: subview 'm1'
+ VIEW 9 rows = _H:I _R:I
+ 0: 0 -1
+ 1: -1413211378 1
+ 2: -153687682 2
+ 3: 0 -1
+ 4: 0 -1
+ 5: 0 -1
+ 6: -1614533319 3
+ 7: -245760992 0
+ 8: 11 0
+ 0: subview 'd2'
+ VIEW 3 rows = p1:S
+ 0: 'two'
+ 1: 'three'
+ 2: 'four'
+ 0: subview 'm2'
+ VIEW 9 rows = _H:I _R:I
+ 0: 0 -1
+ 1: -1413211378 0
+ 2: -153687682 1
+ 3: 0 -1
+ 4: 0 -1
+ 5: 0 -1
+ 6: -1614533319 2
+ 7: 0 -1
+ 8: 11 0
+ 0: subview 'd3'
+ VIEW 2 rows = p1:S
+ 0: 'three'
+ 1: 'four'
+ 0: subview 'm3'
+ VIEW 5 rows = _H:I _R:I
+ 0: 0 -1
+ 1: -153687682 0
+ 2: -1614533319 1
+ 3: 0 -1
+ 4: 7 0
+ 0: subview 'd4'
+ VIEW 1 rows = p1:S
+ 0: 'four'
+ 0: subview 'm4'
+ VIEW 5 rows = _H:I _R:I
+ 0: 0 -1
+ 1: 0 -1
+ 2: -1614533319 0
+ 3: 0 -1
+ 4: 7 0
diff --git a/akregator/src/mk4storage/metakit/tests/ok/m04.txt b/akregator/src/mk4storage/metakit/tests/ok/m04.txt
new file mode 100644
index 000000000..036ca9951
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/m04.txt
@@ -0,0 +1,2 @@
+>>> Locate bug
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/m04a.txt b/akregator/src/mk4storage/metakit/tests/ok/m04a.txt
new file mode 100644
index 000000000..fb38c3971
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/m04a.txt
@@ -0,0 +1,9 @@
+ VIEW 1 rows = v1:V
+ 0: subview 'v1'
+ VIEW 6 rows = p1:I p2:S
+ 0: 1 'one'
+ 1: 2 'two'
+ 2: 3 'three'
+ 3: 4 'four'
+ 4: 5 'five'
+ 5: 6 'six'
diff --git a/akregator/src/mk4storage/metakit/tests/ok/m05.txt b/akregator/src/mk4storage/metakit/tests/ok/m05.txt
new file mode 100644
index 000000000..7b4e60c7d
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/m05.txt
@@ -0,0 +1,2 @@
+>>> Blocked view with subviews
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/m05a.txt b/akregator/src/mk4storage/metakit/tests/ok/m05a.txt
new file mode 100644
index 000000000..a9f34115d
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/m05a.txt
@@ -0,0 +1,4012 @@
+ VIEW 1 rows = v1:V
+ 0: subview 'v1'
+ VIEW 3 rows = _B:V
+ 0: subview '_B'
+ VIEW 500 rows = p1:S sv:V
+ 0: 'id-0'
+ 0: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 0
+ 1: 'id-1'
+ 1: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 1
+ 2: 'id-2'
+ 2: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 2
+ 3: 'id-3'
+ 3: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 3
+ 4: 'id-4'
+ 4: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 4
+ 5: 'id-5'
+ 5: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 5
+ 6: 'id-6'
+ 6: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 6
+ 7: 'id-7'
+ 7: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 7
+ 8: 'id-8'
+ 8: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 8
+ 9: 'id-9'
+ 9: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 9
+ 10: 'id-10'
+ 10: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 10
+ 11: 'id-11'
+ 11: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 11
+ 12: 'id-12'
+ 12: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 12
+ 13: 'id-13'
+ 13: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 13
+ 14: 'id-14'
+ 14: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 14
+ 15: 'id-15'
+ 15: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 15
+ 16: 'id-16'
+ 16: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 16
+ 17: 'id-17'
+ 17: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 17
+ 18: 'id-18'
+ 18: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 18
+ 19: 'id-19'
+ 19: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 19
+ 20: 'id-20'
+ 20: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 20
+ 21: 'id-21'
+ 21: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 21
+ 22: 'id-22'
+ 22: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 22
+ 23: 'id-23'
+ 23: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 23
+ 24: 'id-24'
+ 24: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 24
+ 25: 'id-25'
+ 25: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 25
+ 26: 'id-26'
+ 26: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 26
+ 27: 'id-27'
+ 27: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 27
+ 28: 'id-28'
+ 28: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 28
+ 29: 'id-29'
+ 29: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 29
+ 30: 'id-30'
+ 30: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 30
+ 31: 'id-31'
+ 31: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 31
+ 32: 'id-32'
+ 32: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 32
+ 33: 'id-33'
+ 33: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 33
+ 34: 'id-34'
+ 34: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 34
+ 35: 'id-35'
+ 35: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 35
+ 36: 'id-36'
+ 36: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 36
+ 37: 'id-37'
+ 37: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 37
+ 38: 'id-38'
+ 38: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 38
+ 39: 'id-39'
+ 39: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 39
+ 40: 'id-40'
+ 40: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 40
+ 41: 'id-41'
+ 41: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 41
+ 42: 'id-42'
+ 42: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 42
+ 43: 'id-43'
+ 43: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 43
+ 44: 'id-44'
+ 44: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 44
+ 45: 'id-45'
+ 45: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 45
+ 46: 'id-46'
+ 46: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 46
+ 47: 'id-47'
+ 47: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 47
+ 48: 'id-48'
+ 48: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 48
+ 49: 'id-49'
+ 49: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 49
+ 50: 'id-50'
+ 50: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 50
+ 51: 'id-51'
+ 51: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 51
+ 52: 'id-52'
+ 52: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 52
+ 53: 'id-53'
+ 53: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 53
+ 54: 'id-54'
+ 54: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 54
+ 55: 'id-55'
+ 55: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 55
+ 56: 'id-56'
+ 56: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 56
+ 57: 'id-57'
+ 57: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 57
+ 58: 'id-58'
+ 58: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 58
+ 59: 'id-59'
+ 59: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 59
+ 60: 'id-60'
+ 60: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 60
+ 61: 'id-61'
+ 61: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 61
+ 62: 'id-62'
+ 62: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 62
+ 63: 'id-63'
+ 63: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 63
+ 64: 'id-64'
+ 64: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 64
+ 65: 'id-65'
+ 65: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 65
+ 66: 'id-66'
+ 66: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 66
+ 67: 'id-67'
+ 67: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 67
+ 68: 'id-68'
+ 68: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 68
+ 69: 'id-69'
+ 69: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 69
+ 70: 'id-70'
+ 70: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 70
+ 71: 'id-71'
+ 71: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 71
+ 72: 'id-72'
+ 72: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 72
+ 73: 'id-73'
+ 73: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 73
+ 74: 'id-74'
+ 74: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 74
+ 75: 'id-75'
+ 75: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 75
+ 76: 'id-76'
+ 76: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 76
+ 77: 'id-77'
+ 77: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 77
+ 78: 'id-78'
+ 78: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 78
+ 79: 'id-79'
+ 79: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 79
+ 80: 'id-80'
+ 80: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 80
+ 81: 'id-81'
+ 81: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 81
+ 82: 'id-82'
+ 82: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 82
+ 83: 'id-83'
+ 83: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 83
+ 84: 'id-84'
+ 84: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 84
+ 85: 'id-85'
+ 85: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 85
+ 86: 'id-86'
+ 86: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 86
+ 87: 'id-87'
+ 87: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 87
+ 88: 'id-88'
+ 88: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 88
+ 89: 'id-89'
+ 89: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 89
+ 90: 'id-90'
+ 90: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 90
+ 91: 'id-91'
+ 91: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 91
+ 92: 'id-92'
+ 92: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 92
+ 93: 'id-93'
+ 93: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 93
+ 94: 'id-94'
+ 94: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 94
+ 95: 'id-95'
+ 95: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 95
+ 96: 'id-96'
+ 96: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 96
+ 97: 'id-97'
+ 97: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 97
+ 98: 'id-98'
+ 98: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 98
+ 99: 'id-99'
+ 99: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 99
+ 100: 'id-100'
+ 100: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 100
+ 101: 'id-101'
+ 101: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 101
+ 102: 'id-102'
+ 102: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 102
+ 103: 'id-103'
+ 103: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 103
+ 104: 'id-104'
+ 104: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 104
+ 105: 'id-105'
+ 105: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 105
+ 106: 'id-106'
+ 106: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 106
+ 107: 'id-107'
+ 107: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 107
+ 108: 'id-108'
+ 108: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 108
+ 109: 'id-109'
+ 109: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 109
+ 110: 'id-110'
+ 110: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 110
+ 111: 'id-111'
+ 111: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 111
+ 112: 'id-112'
+ 112: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 112
+ 113: 'id-113'
+ 113: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 113
+ 114: 'id-114'
+ 114: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 114
+ 115: 'id-115'
+ 115: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 115
+ 116: 'id-116'
+ 116: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 116
+ 117: 'id-117'
+ 117: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 117
+ 118: 'id-118'
+ 118: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 118
+ 119: 'id-119'
+ 119: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 119
+ 120: 'id-120'
+ 120: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 120
+ 121: 'id-121'
+ 121: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 121
+ 122: 'id-122'
+ 122: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 122
+ 123: 'id-123'
+ 123: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 123
+ 124: 'id-124'
+ 124: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 124
+ 125: 'id-125'
+ 125: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 125
+ 126: 'id-126'
+ 126: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 126
+ 127: 'id-127'
+ 127: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 127
+ 128: 'id-128'
+ 128: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 128
+ 129: 'id-129'
+ 129: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 129
+ 130: 'id-130'
+ 130: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 130
+ 131: 'id-131'
+ 131: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 131
+ 132: 'id-132'
+ 132: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 132
+ 133: 'id-133'
+ 133: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 133
+ 134: 'id-134'
+ 134: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 134
+ 135: 'id-135'
+ 135: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 135
+ 136: 'id-136'
+ 136: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 136
+ 137: 'id-137'
+ 137: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 137
+ 138: 'id-138'
+ 138: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 138
+ 139: 'id-139'
+ 139: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 139
+ 140: 'id-140'
+ 140: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 140
+ 141: 'id-141'
+ 141: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 141
+ 142: 'id-142'
+ 142: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 142
+ 143: 'id-143'
+ 143: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 143
+ 144: 'id-144'
+ 144: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 144
+ 145: 'id-145'
+ 145: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 145
+ 146: 'id-146'
+ 146: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 146
+ 147: 'id-147'
+ 147: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 147
+ 148: 'id-148'
+ 148: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 148
+ 149: 'id-149'
+ 149: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 149
+ 150: 'id-150'
+ 150: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 150
+ 151: 'id-151'
+ 151: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 151
+ 152: 'id-152'
+ 152: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 152
+ 153: 'id-153'
+ 153: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 153
+ 154: 'id-154'
+ 154: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 154
+ 155: 'id-155'
+ 155: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 155
+ 156: 'id-156'
+ 156: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 156
+ 157: 'id-157'
+ 157: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 157
+ 158: 'id-158'
+ 158: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 158
+ 159: 'id-159'
+ 159: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 159
+ 160: 'id-160'
+ 160: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 160
+ 161: 'id-161'
+ 161: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 161
+ 162: 'id-162'
+ 162: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 162
+ 163: 'id-163'
+ 163: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 163
+ 164: 'id-164'
+ 164: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 164
+ 165: 'id-165'
+ 165: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 165
+ 166: 'id-166'
+ 166: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 166
+ 167: 'id-167'
+ 167: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 167
+ 168: 'id-168'
+ 168: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 168
+ 169: 'id-169'
+ 169: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 169
+ 170: 'id-170'
+ 170: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 170
+ 171: 'id-171'
+ 171: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 171
+ 172: 'id-172'
+ 172: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 172
+ 173: 'id-173'
+ 173: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 173
+ 174: 'id-174'
+ 174: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 174
+ 175: 'id-175'
+ 175: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 175
+ 176: 'id-176'
+ 176: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 176
+ 177: 'id-177'
+ 177: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 177
+ 178: 'id-178'
+ 178: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 178
+ 179: 'id-179'
+ 179: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 179
+ 180: 'id-180'
+ 180: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 180
+ 181: 'id-181'
+ 181: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 181
+ 182: 'id-182'
+ 182: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 182
+ 183: 'id-183'
+ 183: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 183
+ 184: 'id-184'
+ 184: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 184
+ 185: 'id-185'
+ 185: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 185
+ 186: 'id-186'
+ 186: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 186
+ 187: 'id-187'
+ 187: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 187
+ 188: 'id-188'
+ 188: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 188
+ 189: 'id-189'
+ 189: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 189
+ 190: 'id-190'
+ 190: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 190
+ 191: 'id-191'
+ 191: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 191
+ 192: 'id-192'
+ 192: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 192
+ 193: 'id-193'
+ 193: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 193
+ 194: 'id-194'
+ 194: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 194
+ 195: 'id-195'
+ 195: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 195
+ 196: 'id-196'
+ 196: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 196
+ 197: 'id-197'
+ 197: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 197
+ 198: 'id-198'
+ 198: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 198
+ 199: 'id-199'
+ 199: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 199
+ 200: 'id-200'
+ 200: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 200
+ 201: 'id-201'
+ 201: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 201
+ 202: 'id-202'
+ 202: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 202
+ 203: 'id-203'
+ 203: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 203
+ 204: 'id-204'
+ 204: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 204
+ 205: 'id-205'
+ 205: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 205
+ 206: 'id-206'
+ 206: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 206
+ 207: 'id-207'
+ 207: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 207
+ 208: 'id-208'
+ 208: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 208
+ 209: 'id-209'
+ 209: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 209
+ 210: 'id-210'
+ 210: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 210
+ 211: 'id-211'
+ 211: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 211
+ 212: 'id-212'
+ 212: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 212
+ 213: 'id-213'
+ 213: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 213
+ 214: 'id-214'
+ 214: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 214
+ 215: 'id-215'
+ 215: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 215
+ 216: 'id-216'
+ 216: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 216
+ 217: 'id-217'
+ 217: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 217
+ 218: 'id-218'
+ 218: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 218
+ 219: 'id-219'
+ 219: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 219
+ 220: 'id-220'
+ 220: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 220
+ 221: 'id-221'
+ 221: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 221
+ 222: 'id-222'
+ 222: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 222
+ 223: 'id-223'
+ 223: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 223
+ 224: 'id-224'
+ 224: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 224
+ 225: 'id-225'
+ 225: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 225
+ 226: 'id-226'
+ 226: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 226
+ 227: 'id-227'
+ 227: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 227
+ 228: 'id-228'
+ 228: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 228
+ 229: 'id-229'
+ 229: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 229
+ 230: 'id-230'
+ 230: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 230
+ 231: 'id-231'
+ 231: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 231
+ 232: 'id-232'
+ 232: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 232
+ 233: 'id-233'
+ 233: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 233
+ 234: 'id-234'
+ 234: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 234
+ 235: 'id-235'
+ 235: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 235
+ 236: 'id-236'
+ 236: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 236
+ 237: 'id-237'
+ 237: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 237
+ 238: 'id-238'
+ 238: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 238
+ 239: 'id-239'
+ 239: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 239
+ 240: 'id-240'
+ 240: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 240
+ 241: 'id-241'
+ 241: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 241
+ 242: 'id-242'
+ 242: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 242
+ 243: 'id-243'
+ 243: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 243
+ 244: 'id-244'
+ 244: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 244
+ 245: 'id-245'
+ 245: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 245
+ 246: 'id-246'
+ 246: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 246
+ 247: 'id-247'
+ 247: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 247
+ 248: 'id-248'
+ 248: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 248
+ 249: 'id-249'
+ 249: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 249
+ 250: 'id-250'
+ 250: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 250
+ 251: 'id-251'
+ 251: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 251
+ 252: 'id-252'
+ 252: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 252
+ 253: 'id-253'
+ 253: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 253
+ 254: 'id-254'
+ 254: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 254
+ 255: 'id-255'
+ 255: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 255
+ 256: 'id-256'
+ 256: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 256
+ 257: 'id-257'
+ 257: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 257
+ 258: 'id-258'
+ 258: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 258
+ 259: 'id-259'
+ 259: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 259
+ 260: 'id-260'
+ 260: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 260
+ 261: 'id-261'
+ 261: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 261
+ 262: 'id-262'
+ 262: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 262
+ 263: 'id-263'
+ 263: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 263
+ 264: 'id-264'
+ 264: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 264
+ 265: 'id-265'
+ 265: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 265
+ 266: 'id-266'
+ 266: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 266
+ 267: 'id-267'
+ 267: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 267
+ 268: 'id-268'
+ 268: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 268
+ 269: 'id-269'
+ 269: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 269
+ 270: 'id-270'
+ 270: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 270
+ 271: 'id-271'
+ 271: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 271
+ 272: 'id-272'
+ 272: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 272
+ 273: 'id-273'
+ 273: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 273
+ 274: 'id-274'
+ 274: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 274
+ 275: 'id-275'
+ 275: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 275
+ 276: 'id-276'
+ 276: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 276
+ 277: 'id-277'
+ 277: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 277
+ 278: 'id-278'
+ 278: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 278
+ 279: 'id-279'
+ 279: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 279
+ 280: 'id-280'
+ 280: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 280
+ 281: 'id-281'
+ 281: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 281
+ 282: 'id-282'
+ 282: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 282
+ 283: 'id-283'
+ 283: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 283
+ 284: 'id-284'
+ 284: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 284
+ 285: 'id-285'
+ 285: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 285
+ 286: 'id-286'
+ 286: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 286
+ 287: 'id-287'
+ 287: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 287
+ 288: 'id-288'
+ 288: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 288
+ 289: 'id-289'
+ 289: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 289
+ 290: 'id-290'
+ 290: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 290
+ 291: 'id-291'
+ 291: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 291
+ 292: 'id-292'
+ 292: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 292
+ 293: 'id-293'
+ 293: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 293
+ 294: 'id-294'
+ 294: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 294
+ 295: 'id-295'
+ 295: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 295
+ 296: 'id-296'
+ 296: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 296
+ 297: 'id-297'
+ 297: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 297
+ 298: 'id-298'
+ 298: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 298
+ 299: 'id-299'
+ 299: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 299
+ 300: 'id-300'
+ 300: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 300
+ 301: 'id-301'
+ 301: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 301
+ 302: 'id-302'
+ 302: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 302
+ 303: 'id-303'
+ 303: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 303
+ 304: 'id-304'
+ 304: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 304
+ 305: 'id-305'
+ 305: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 305
+ 306: 'id-306'
+ 306: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 306
+ 307: 'id-307'
+ 307: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 307
+ 308: 'id-308'
+ 308: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 308
+ 309: 'id-309'
+ 309: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 309
+ 310: 'id-310'
+ 310: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 310
+ 311: 'id-311'
+ 311: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 311
+ 312: 'id-312'
+ 312: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 312
+ 313: 'id-313'
+ 313: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 313
+ 314: 'id-314'
+ 314: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 314
+ 315: 'id-315'
+ 315: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 315
+ 316: 'id-316'
+ 316: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 316
+ 317: 'id-317'
+ 317: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 317
+ 318: 'id-318'
+ 318: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 318
+ 319: 'id-319'
+ 319: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 319
+ 320: 'id-320'
+ 320: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 320
+ 321: 'id-321'
+ 321: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 321
+ 322: 'id-322'
+ 322: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 322
+ 323: 'id-323'
+ 323: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 323
+ 324: 'id-324'
+ 324: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 324
+ 325: 'id-325'
+ 325: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 325
+ 326: 'id-326'
+ 326: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 326
+ 327: 'id-327'
+ 327: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 327
+ 328: 'id-328'
+ 328: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 328
+ 329: 'id-329'
+ 329: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 329
+ 330: 'id-330'
+ 330: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 330
+ 331: 'id-331'
+ 331: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 331
+ 332: 'id-332'
+ 332: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 332
+ 333: 'id-333'
+ 333: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 333
+ 334: 'id-334'
+ 334: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 334
+ 335: 'id-335'
+ 335: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 335
+ 336: 'id-336'
+ 336: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 336
+ 337: 'id-337'
+ 337: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 337
+ 338: 'id-338'
+ 338: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 338
+ 339: 'id-339'
+ 339: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 339
+ 340: 'id-340'
+ 340: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 340
+ 341: 'id-341'
+ 341: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 341
+ 342: 'id-342'
+ 342: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 342
+ 343: 'id-343'
+ 343: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 343
+ 344: 'id-344'
+ 344: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 344
+ 345: 'id-345'
+ 345: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 345
+ 346: 'id-346'
+ 346: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 346
+ 347: 'id-347'
+ 347: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 347
+ 348: 'id-348'
+ 348: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 348
+ 349: 'id-349'
+ 349: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 349
+ 350: 'id-350'
+ 350: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 350
+ 351: 'id-351'
+ 351: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 351
+ 352: 'id-352'
+ 352: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 352
+ 353: 'id-353'
+ 353: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 353
+ 354: 'id-354'
+ 354: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 354
+ 355: 'id-355'
+ 355: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 355
+ 356: 'id-356'
+ 356: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 356
+ 357: 'id-357'
+ 357: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 357
+ 358: 'id-358'
+ 358: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 358
+ 359: 'id-359'
+ 359: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 359
+ 360: 'id-360'
+ 360: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 360
+ 361: 'id-361'
+ 361: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 361
+ 362: 'id-362'
+ 362: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 362
+ 363: 'id-363'
+ 363: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 363
+ 364: 'id-364'
+ 364: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 364
+ 365: 'id-365'
+ 365: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 365
+ 366: 'id-366'
+ 366: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 366
+ 367: 'id-367'
+ 367: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 367
+ 368: 'id-368'
+ 368: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 368
+ 369: 'id-369'
+ 369: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 369
+ 370: 'id-370'
+ 370: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 370
+ 371: 'id-371'
+ 371: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 371
+ 372: 'id-372'
+ 372: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 372
+ 373: 'id-373'
+ 373: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 373
+ 374: 'id-374'
+ 374: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 374
+ 375: 'id-375'
+ 375: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 375
+ 376: 'id-376'
+ 376: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 376
+ 377: 'id-377'
+ 377: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 377
+ 378: 'id-378'
+ 378: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 378
+ 379: 'id-379'
+ 379: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 379
+ 380: 'id-380'
+ 380: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 380
+ 381: 'id-381'
+ 381: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 381
+ 382: 'id-382'
+ 382: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 382
+ 383: 'id-383'
+ 383: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 383
+ 384: 'id-384'
+ 384: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 384
+ 385: 'id-385'
+ 385: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 385
+ 386: 'id-386'
+ 386: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 386
+ 387: 'id-387'
+ 387: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 387
+ 388: 'id-388'
+ 388: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 388
+ 389: 'id-389'
+ 389: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 389
+ 390: 'id-390'
+ 390: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 390
+ 391: 'id-391'
+ 391: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 391
+ 392: 'id-392'
+ 392: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 392
+ 393: 'id-393'
+ 393: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 393
+ 394: 'id-394'
+ 394: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 394
+ 395: 'id-395'
+ 395: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 395
+ 396: 'id-396'
+ 396: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 396
+ 397: 'id-397'
+ 397: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 397
+ 398: 'id-398'
+ 398: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 398
+ 399: 'id-399'
+ 399: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 399
+ 400: 'id-400'
+ 400: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 400
+ 401: 'id-401'
+ 401: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 401
+ 402: 'id-402'
+ 402: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 402
+ 403: 'id-403'
+ 403: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 403
+ 404: 'id-404'
+ 404: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 404
+ 405: 'id-405'
+ 405: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 405
+ 406: 'id-406'
+ 406: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 406
+ 407: 'id-407'
+ 407: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 407
+ 408: 'id-408'
+ 408: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 408
+ 409: 'id-409'
+ 409: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 409
+ 410: 'id-410'
+ 410: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 410
+ 411: 'id-411'
+ 411: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 411
+ 412: 'id-412'
+ 412: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 412
+ 413: 'id-413'
+ 413: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 413
+ 414: 'id-414'
+ 414: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 414
+ 415: 'id-415'
+ 415: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 415
+ 416: 'id-416'
+ 416: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 416
+ 417: 'id-417'
+ 417: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 417
+ 418: 'id-418'
+ 418: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 418
+ 419: 'id-419'
+ 419: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 419
+ 420: 'id-420'
+ 420: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 420
+ 421: 'id-421'
+ 421: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 421
+ 422: 'id-422'
+ 422: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 422
+ 423: 'id-423'
+ 423: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 423
+ 424: 'id-424'
+ 424: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 424
+ 425: 'id-425'
+ 425: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 425
+ 426: 'id-426'
+ 426: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 426
+ 427: 'id-427'
+ 427: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 427
+ 428: 'id-428'
+ 428: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 428
+ 429: 'id-429'
+ 429: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 429
+ 430: 'id-430'
+ 430: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 430
+ 431: 'id-431'
+ 431: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 431
+ 432: 'id-432'
+ 432: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 432
+ 433: 'id-433'
+ 433: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 433
+ 434: 'id-434'
+ 434: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 434
+ 435: 'id-435'
+ 435: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 435
+ 436: 'id-436'
+ 436: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 436
+ 437: 'id-437'
+ 437: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 437
+ 438: 'id-438'
+ 438: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 438
+ 439: 'id-439'
+ 439: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 439
+ 440: 'id-440'
+ 440: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 440
+ 441: 'id-441'
+ 441: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 441
+ 442: 'id-442'
+ 442: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 442
+ 443: 'id-443'
+ 443: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 443
+ 444: 'id-444'
+ 444: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 444
+ 445: 'id-445'
+ 445: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 445
+ 446: 'id-446'
+ 446: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 446
+ 447: 'id-447'
+ 447: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 447
+ 448: 'id-448'
+ 448: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 448
+ 449: 'id-449'
+ 449: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 449
+ 450: 'id-450'
+ 450: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 450
+ 451: 'id-451'
+ 451: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 451
+ 452: 'id-452'
+ 452: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 452
+ 453: 'id-453'
+ 453: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 453
+ 454: 'id-454'
+ 454: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 454
+ 455: 'id-455'
+ 455: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 455
+ 456: 'id-456'
+ 456: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 456
+ 457: 'id-457'
+ 457: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 457
+ 458: 'id-458'
+ 458: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 458
+ 459: 'id-459'
+ 459: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 459
+ 460: 'id-460'
+ 460: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 460
+ 461: 'id-461'
+ 461: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 461
+ 462: 'id-462'
+ 462: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 462
+ 463: 'id-463'
+ 463: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 463
+ 464: 'id-464'
+ 464: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 464
+ 465: 'id-465'
+ 465: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 465
+ 466: 'id-466'
+ 466: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 466
+ 467: 'id-467'
+ 467: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 467
+ 468: 'id-468'
+ 468: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 468
+ 469: 'id-469'
+ 469: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 469
+ 470: 'id-470'
+ 470: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 470
+ 471: 'id-471'
+ 471: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 471
+ 472: 'id-472'
+ 472: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 472
+ 473: 'id-473'
+ 473: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 473
+ 474: 'id-474'
+ 474: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 474
+ 475: 'id-475'
+ 475: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 475
+ 476: 'id-476'
+ 476: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 476
+ 477: 'id-477'
+ 477: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 477
+ 478: 'id-478'
+ 478: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 478
+ 479: 'id-479'
+ 479: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 479
+ 480: 'id-480'
+ 480: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 480
+ 481: 'id-481'
+ 481: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 481
+ 482: 'id-482'
+ 482: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 482
+ 483: 'id-483'
+ 483: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 483
+ 484: 'id-484'
+ 484: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 484
+ 485: 'id-485'
+ 485: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 485
+ 486: 'id-486'
+ 486: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 486
+ 487: 'id-487'
+ 487: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 487
+ 488: 'id-488'
+ 488: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 488
+ 489: 'id-489'
+ 489: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 489
+ 490: 'id-490'
+ 490: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 490
+ 491: 'id-491'
+ 491: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 491
+ 492: 'id-492'
+ 492: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 492
+ 493: 'id-493'
+ 493: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 493
+ 494: 'id-494'
+ 494: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 494
+ 495: 'id-495'
+ 495: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 495
+ 496: 'id-496'
+ 496: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 496
+ 497: 'id-497'
+ 497: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 497
+ 498: 'id-498'
+ 498: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 498
+ 499: 'id-499'
+ 499: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 499
+ 1: subview '_B'
+ VIEW 500 rows = p1:S sv:V
+ 0: 'id-500'
+ 0: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 500
+ 1: 'id-501'
+ 1: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 501
+ 2: 'id-502'
+ 2: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 502
+ 3: 'id-503'
+ 3: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 503
+ 4: 'id-504'
+ 4: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 504
+ 5: 'id-505'
+ 5: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 505
+ 6: 'id-506'
+ 6: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 506
+ 7: 'id-507'
+ 7: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 507
+ 8: 'id-508'
+ 8: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 508
+ 9: 'id-509'
+ 9: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 509
+ 10: 'id-510'
+ 10: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 510
+ 11: 'id-511'
+ 11: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 511
+ 12: 'id-512'
+ 12: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 512
+ 13: 'id-513'
+ 13: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 513
+ 14: 'id-514'
+ 14: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 514
+ 15: 'id-515'
+ 15: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 515
+ 16: 'id-516'
+ 16: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 516
+ 17: 'id-517'
+ 17: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 517
+ 18: 'id-518'
+ 18: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 518
+ 19: 'id-519'
+ 19: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 519
+ 20: 'id-520'
+ 20: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 520
+ 21: 'id-521'
+ 21: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 521
+ 22: 'id-522'
+ 22: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 522
+ 23: 'id-523'
+ 23: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 523
+ 24: 'id-524'
+ 24: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 524
+ 25: 'id-525'
+ 25: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 525
+ 26: 'id-526'
+ 26: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 526
+ 27: 'id-527'
+ 27: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 527
+ 28: 'id-528'
+ 28: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 528
+ 29: 'id-529'
+ 29: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 529
+ 30: 'id-530'
+ 30: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 530
+ 31: 'id-531'
+ 31: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 531
+ 32: 'id-532'
+ 32: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 532
+ 33: 'id-533'
+ 33: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 533
+ 34: 'id-534'
+ 34: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 534
+ 35: 'id-535'
+ 35: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 535
+ 36: 'id-536'
+ 36: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 536
+ 37: 'id-537'
+ 37: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 537
+ 38: 'id-538'
+ 38: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 538
+ 39: 'id-539'
+ 39: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 539
+ 40: 'id-540'
+ 40: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 540
+ 41: 'id-541'
+ 41: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 541
+ 42: 'id-542'
+ 42: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 542
+ 43: 'id-543'
+ 43: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 543
+ 44: 'id-544'
+ 44: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 544
+ 45: 'id-545'
+ 45: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 545
+ 46: 'id-546'
+ 46: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 546
+ 47: 'id-547'
+ 47: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 547
+ 48: 'id-548'
+ 48: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 548
+ 49: 'id-549'
+ 49: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 549
+ 50: 'id-550'
+ 50: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 550
+ 51: 'id-551'
+ 51: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 551
+ 52: 'id-552'
+ 52: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 552
+ 53: 'id-553'
+ 53: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 553
+ 54: 'id-554'
+ 54: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 554
+ 55: 'id-555'
+ 55: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 555
+ 56: 'id-556'
+ 56: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 556
+ 57: 'id-557'
+ 57: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 557
+ 58: 'id-558'
+ 58: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 558
+ 59: 'id-559'
+ 59: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 559
+ 60: 'id-560'
+ 60: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 560
+ 61: 'id-561'
+ 61: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 561
+ 62: 'id-562'
+ 62: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 562
+ 63: 'id-563'
+ 63: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 563
+ 64: 'id-564'
+ 64: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 564
+ 65: 'id-565'
+ 65: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 565
+ 66: 'id-566'
+ 66: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 566
+ 67: 'id-567'
+ 67: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 567
+ 68: 'id-568'
+ 68: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 568
+ 69: 'id-569'
+ 69: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 569
+ 70: 'id-570'
+ 70: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 570
+ 71: 'id-571'
+ 71: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 571
+ 72: 'id-572'
+ 72: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 572
+ 73: 'id-573'
+ 73: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 573
+ 74: 'id-574'
+ 74: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 574
+ 75: 'id-575'
+ 75: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 575
+ 76: 'id-576'
+ 76: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 576
+ 77: 'id-577'
+ 77: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 577
+ 78: 'id-578'
+ 78: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 578
+ 79: 'id-579'
+ 79: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 579
+ 80: 'id-580'
+ 80: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 580
+ 81: 'id-581'
+ 81: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 581
+ 82: 'id-582'
+ 82: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 582
+ 83: 'id-583'
+ 83: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 583
+ 84: 'id-584'
+ 84: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 584
+ 85: 'id-585'
+ 85: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 585
+ 86: 'id-586'
+ 86: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 586
+ 87: 'id-587'
+ 87: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 587
+ 88: 'id-588'
+ 88: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 588
+ 89: 'id-589'
+ 89: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 589
+ 90: 'id-590'
+ 90: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 590
+ 91: 'id-591'
+ 91: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 591
+ 92: 'id-592'
+ 92: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 592
+ 93: 'id-593'
+ 93: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 593
+ 94: 'id-594'
+ 94: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 594
+ 95: 'id-595'
+ 95: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 595
+ 96: 'id-596'
+ 96: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 596
+ 97: 'id-597'
+ 97: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 597
+ 98: 'id-598'
+ 98: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 598
+ 99: 'id-599'
+ 99: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 599
+ 100: 'id-600'
+ 100: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 600
+ 101: 'id-601'
+ 101: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 601
+ 102: 'id-602'
+ 102: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 602
+ 103: 'id-603'
+ 103: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 603
+ 104: 'id-604'
+ 104: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 604
+ 105: 'id-605'
+ 105: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 605
+ 106: 'id-606'
+ 106: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 606
+ 107: 'id-607'
+ 107: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 607
+ 108: 'id-608'
+ 108: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 608
+ 109: 'id-609'
+ 109: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 609
+ 110: 'id-610'
+ 110: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 610
+ 111: 'id-611'
+ 111: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 611
+ 112: 'id-612'
+ 112: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 612
+ 113: 'id-613'
+ 113: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 613
+ 114: 'id-614'
+ 114: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 614
+ 115: 'id-615'
+ 115: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 615
+ 116: 'id-616'
+ 116: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 616
+ 117: 'id-617'
+ 117: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 617
+ 118: 'id-618'
+ 118: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 618
+ 119: 'id-619'
+ 119: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 619
+ 120: 'id-620'
+ 120: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 620
+ 121: 'id-621'
+ 121: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 621
+ 122: 'id-622'
+ 122: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 622
+ 123: 'id-623'
+ 123: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 623
+ 124: 'id-624'
+ 124: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 624
+ 125: 'id-625'
+ 125: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 625
+ 126: 'id-626'
+ 126: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 626
+ 127: 'id-627'
+ 127: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 627
+ 128: 'id-628'
+ 128: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 628
+ 129: 'id-629'
+ 129: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 629
+ 130: 'id-630'
+ 130: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 630
+ 131: 'id-631'
+ 131: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 631
+ 132: 'id-632'
+ 132: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 632
+ 133: 'id-633'
+ 133: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 633
+ 134: 'id-634'
+ 134: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 634
+ 135: 'id-635'
+ 135: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 635
+ 136: 'id-636'
+ 136: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 636
+ 137: 'id-637'
+ 137: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 637
+ 138: 'id-638'
+ 138: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 638
+ 139: 'id-639'
+ 139: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 639
+ 140: 'id-640'
+ 140: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 640
+ 141: 'id-641'
+ 141: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 641
+ 142: 'id-642'
+ 142: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 642
+ 143: 'id-643'
+ 143: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 643
+ 144: 'id-644'
+ 144: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 644
+ 145: 'id-645'
+ 145: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 645
+ 146: 'id-646'
+ 146: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 646
+ 147: 'id-647'
+ 147: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 647
+ 148: 'id-648'
+ 148: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 648
+ 149: 'id-649'
+ 149: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 649
+ 150: 'id-650'
+ 150: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 650
+ 151: 'id-651'
+ 151: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 651
+ 152: 'id-652'
+ 152: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 652
+ 153: 'id-653'
+ 153: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 653
+ 154: 'id-654'
+ 154: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 654
+ 155: 'id-655'
+ 155: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 655
+ 156: 'id-656'
+ 156: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 656
+ 157: 'id-657'
+ 157: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 657
+ 158: 'id-658'
+ 158: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 658
+ 159: 'id-659'
+ 159: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 659
+ 160: 'id-660'
+ 160: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 660
+ 161: 'id-661'
+ 161: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 661
+ 162: 'id-662'
+ 162: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 662
+ 163: 'id-663'
+ 163: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 663
+ 164: 'id-664'
+ 164: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 664
+ 165: 'id-665'
+ 165: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 665
+ 166: 'id-666'
+ 166: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 666
+ 167: 'id-667'
+ 167: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 667
+ 168: 'id-668'
+ 168: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 668
+ 169: 'id-669'
+ 169: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 669
+ 170: 'id-670'
+ 170: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 670
+ 171: 'id-671'
+ 171: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 671
+ 172: 'id-672'
+ 172: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 672
+ 173: 'id-673'
+ 173: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 673
+ 174: 'id-674'
+ 174: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 674
+ 175: 'id-675'
+ 175: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 675
+ 176: 'id-676'
+ 176: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 676
+ 177: 'id-677'
+ 177: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 677
+ 178: 'id-678'
+ 178: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 678
+ 179: 'id-679'
+ 179: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 679
+ 180: 'id-680'
+ 180: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 680
+ 181: 'id-681'
+ 181: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 681
+ 182: 'id-682'
+ 182: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 682
+ 183: 'id-683'
+ 183: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 683
+ 184: 'id-684'
+ 184: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 684
+ 185: 'id-685'
+ 185: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 685
+ 186: 'id-686'
+ 186: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 686
+ 187: 'id-687'
+ 187: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 687
+ 188: 'id-688'
+ 188: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 688
+ 189: 'id-689'
+ 189: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 689
+ 190: 'id-690'
+ 190: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 690
+ 191: 'id-691'
+ 191: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 691
+ 192: 'id-692'
+ 192: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 692
+ 193: 'id-693'
+ 193: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 693
+ 194: 'id-694'
+ 194: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 694
+ 195: 'id-695'
+ 195: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 695
+ 196: 'id-696'
+ 196: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 696
+ 197: 'id-697'
+ 197: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 697
+ 198: 'id-698'
+ 198: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 698
+ 199: 'id-699'
+ 199: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 699
+ 200: 'id-700'
+ 200: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 700
+ 201: 'id-701'
+ 201: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 701
+ 202: 'id-702'
+ 202: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 702
+ 203: 'id-703'
+ 203: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 703
+ 204: 'id-704'
+ 204: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 704
+ 205: 'id-705'
+ 205: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 705
+ 206: 'id-706'
+ 206: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 706
+ 207: 'id-707'
+ 207: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 707
+ 208: 'id-708'
+ 208: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 708
+ 209: 'id-709'
+ 209: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 709
+ 210: 'id-710'
+ 210: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 710
+ 211: 'id-711'
+ 211: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 711
+ 212: 'id-712'
+ 212: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 712
+ 213: 'id-713'
+ 213: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 713
+ 214: 'id-714'
+ 214: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 714
+ 215: 'id-715'
+ 215: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 715
+ 216: 'id-716'
+ 216: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 716
+ 217: 'id-717'
+ 217: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 717
+ 218: 'id-718'
+ 218: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 718
+ 219: 'id-719'
+ 219: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 719
+ 220: 'id-720'
+ 220: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 720
+ 221: 'id-721'
+ 221: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 721
+ 222: 'id-722'
+ 222: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 722
+ 223: 'id-723'
+ 223: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 723
+ 224: 'id-724'
+ 224: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 724
+ 225: 'id-725'
+ 225: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 725
+ 226: 'id-726'
+ 226: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 726
+ 227: 'id-727'
+ 227: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 727
+ 228: 'id-728'
+ 228: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 728
+ 229: 'id-729'
+ 229: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 729
+ 230: 'id-730'
+ 230: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 730
+ 231: 'id-731'
+ 231: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 731
+ 232: 'id-732'
+ 232: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 732
+ 233: 'id-733'
+ 233: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 733
+ 234: 'id-734'
+ 234: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 734
+ 235: 'id-735'
+ 235: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 735
+ 236: 'id-736'
+ 236: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 736
+ 237: 'id-737'
+ 237: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 737
+ 238: 'id-738'
+ 238: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 738
+ 239: 'id-739'
+ 239: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 739
+ 240: 'id-740'
+ 240: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 740
+ 241: 'id-741'
+ 241: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 741
+ 242: 'id-742'
+ 242: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 742
+ 243: 'id-743'
+ 243: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 743
+ 244: 'id-744'
+ 244: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 744
+ 245: 'id-745'
+ 245: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 745
+ 246: 'id-746'
+ 246: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 746
+ 247: 'id-747'
+ 247: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 747
+ 248: 'id-748'
+ 248: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 748
+ 249: 'id-749'
+ 249: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 749
+ 250: 'id-750'
+ 250: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 750
+ 251: 'id-751'
+ 251: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 751
+ 252: 'id-752'
+ 252: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 752
+ 253: 'id-753'
+ 253: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 753
+ 254: 'id-754'
+ 254: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 754
+ 255: 'id-755'
+ 255: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 755
+ 256: 'id-756'
+ 256: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 756
+ 257: 'id-757'
+ 257: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 757
+ 258: 'id-758'
+ 258: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 758
+ 259: 'id-759'
+ 259: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 759
+ 260: 'id-760'
+ 260: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 760
+ 261: 'id-761'
+ 261: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 761
+ 262: 'id-762'
+ 262: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 762
+ 263: 'id-763'
+ 263: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 763
+ 264: 'id-764'
+ 264: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 764
+ 265: 'id-765'
+ 265: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 765
+ 266: 'id-766'
+ 266: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 766
+ 267: 'id-767'
+ 267: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 767
+ 268: 'id-768'
+ 268: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 768
+ 269: 'id-769'
+ 269: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 769
+ 270: 'id-770'
+ 270: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 770
+ 271: 'id-771'
+ 271: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 771
+ 272: 'id-772'
+ 272: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 772
+ 273: 'id-773'
+ 273: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 773
+ 274: 'id-774'
+ 274: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 774
+ 275: 'id-775'
+ 275: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 775
+ 276: 'id-776'
+ 276: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 776
+ 277: 'id-777'
+ 277: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 777
+ 278: 'id-778'
+ 278: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 778
+ 279: 'id-779'
+ 279: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 779
+ 280: 'id-780'
+ 280: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 780
+ 281: 'id-781'
+ 281: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 781
+ 282: 'id-782'
+ 282: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 782
+ 283: 'id-783'
+ 283: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 783
+ 284: 'id-784'
+ 284: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 784
+ 285: 'id-785'
+ 285: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 785
+ 286: 'id-786'
+ 286: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 786
+ 287: 'id-787'
+ 287: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 787
+ 288: 'id-788'
+ 288: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 788
+ 289: 'id-789'
+ 289: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 789
+ 290: 'id-790'
+ 290: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 790
+ 291: 'id-791'
+ 291: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 791
+ 292: 'id-792'
+ 292: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 792
+ 293: 'id-793'
+ 293: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 793
+ 294: 'id-794'
+ 294: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 794
+ 295: 'id-795'
+ 295: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 795
+ 296: 'id-796'
+ 296: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 796
+ 297: 'id-797'
+ 297: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 797
+ 298: 'id-798'
+ 298: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 798
+ 299: 'id-799'
+ 299: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 799
+ 300: 'id-800'
+ 300: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 800
+ 301: 'id-801'
+ 301: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 801
+ 302: 'id-802'
+ 302: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 802
+ 303: 'id-803'
+ 303: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 803
+ 304: 'id-804'
+ 304: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 804
+ 305: 'id-805'
+ 305: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 805
+ 306: 'id-806'
+ 306: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 806
+ 307: 'id-807'
+ 307: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 807
+ 308: 'id-808'
+ 308: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 808
+ 309: 'id-809'
+ 309: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 809
+ 310: 'id-810'
+ 310: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 810
+ 311: 'id-811'
+ 311: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 811
+ 312: 'id-812'
+ 312: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 812
+ 313: 'id-813'
+ 313: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 813
+ 314: 'id-814'
+ 314: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 814
+ 315: 'id-815'
+ 315: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 815
+ 316: 'id-816'
+ 316: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 816
+ 317: 'id-817'
+ 317: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 817
+ 318: 'id-818'
+ 318: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 818
+ 319: 'id-819'
+ 319: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 819
+ 320: 'id-820'
+ 320: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 820
+ 321: 'id-821'
+ 321: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 821
+ 322: 'id-822'
+ 322: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 822
+ 323: 'id-823'
+ 323: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 823
+ 324: 'id-824'
+ 324: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 824
+ 325: 'id-825'
+ 325: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 825
+ 326: 'id-826'
+ 326: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 826
+ 327: 'id-827'
+ 327: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 827
+ 328: 'id-828'
+ 328: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 828
+ 329: 'id-829'
+ 329: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 829
+ 330: 'id-830'
+ 330: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 830
+ 331: 'id-831'
+ 331: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 831
+ 332: 'id-832'
+ 332: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 832
+ 333: 'id-833'
+ 333: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 833
+ 334: 'id-834'
+ 334: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 834
+ 335: 'id-835'
+ 335: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 835
+ 336: 'id-836'
+ 336: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 836
+ 337: 'id-837'
+ 337: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 837
+ 338: 'id-838'
+ 338: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 838
+ 339: 'id-839'
+ 339: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 839
+ 340: 'id-840'
+ 340: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 840
+ 341: 'id-841'
+ 341: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 841
+ 342: 'id-842'
+ 342: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 842
+ 343: 'id-843'
+ 343: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 843
+ 344: 'id-844'
+ 344: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 844
+ 345: 'id-845'
+ 345: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 845
+ 346: 'id-846'
+ 346: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 846
+ 347: 'id-847'
+ 347: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 847
+ 348: 'id-848'
+ 348: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 848
+ 349: 'id-849'
+ 349: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 849
+ 350: 'id-850'
+ 350: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 850
+ 351: 'id-851'
+ 351: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 851
+ 352: 'id-852'
+ 352: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 852
+ 353: 'id-853'
+ 353: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 853
+ 354: 'id-854'
+ 354: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 854
+ 355: 'id-855'
+ 355: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 855
+ 356: 'id-856'
+ 356: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 856
+ 357: 'id-857'
+ 357: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 857
+ 358: 'id-858'
+ 358: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 858
+ 359: 'id-859'
+ 359: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 859
+ 360: 'id-860'
+ 360: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 860
+ 361: 'id-861'
+ 361: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 861
+ 362: 'id-862'
+ 362: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 862
+ 363: 'id-863'
+ 363: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 863
+ 364: 'id-864'
+ 364: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 864
+ 365: 'id-865'
+ 365: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 865
+ 366: 'id-866'
+ 366: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 866
+ 367: 'id-867'
+ 367: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 867
+ 368: 'id-868'
+ 368: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 868
+ 369: 'id-869'
+ 369: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 869
+ 370: 'id-870'
+ 370: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 870
+ 371: 'id-871'
+ 371: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 871
+ 372: 'id-872'
+ 372: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 872
+ 373: 'id-873'
+ 373: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 873
+ 374: 'id-874'
+ 374: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 874
+ 375: 'id-875'
+ 375: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 875
+ 376: 'id-876'
+ 376: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 876
+ 377: 'id-877'
+ 377: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 877
+ 378: 'id-878'
+ 378: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 878
+ 379: 'id-879'
+ 379: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 879
+ 380: 'id-880'
+ 380: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 880
+ 381: 'id-881'
+ 381: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 881
+ 382: 'id-882'
+ 382: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 882
+ 383: 'id-883'
+ 383: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 883
+ 384: 'id-884'
+ 384: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 884
+ 385: 'id-885'
+ 385: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 885
+ 386: 'id-886'
+ 386: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 886
+ 387: 'id-887'
+ 387: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 887
+ 388: 'id-888'
+ 388: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 888
+ 389: 'id-889'
+ 389: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 889
+ 390: 'id-890'
+ 390: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 890
+ 391: 'id-891'
+ 391: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 891
+ 392: 'id-892'
+ 392: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 892
+ 393: 'id-893'
+ 393: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 893
+ 394: 'id-894'
+ 394: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 894
+ 395: 'id-895'
+ 395: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 895
+ 396: 'id-896'
+ 396: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 896
+ 397: 'id-897'
+ 397: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 897
+ 398: 'id-898'
+ 398: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 898
+ 399: 'id-899'
+ 399: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 899
+ 400: 'id-900'
+ 400: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 900
+ 401: 'id-901'
+ 401: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 901
+ 402: 'id-902'
+ 402: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 902
+ 403: 'id-903'
+ 403: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 903
+ 404: 'id-904'
+ 404: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 904
+ 405: 'id-905'
+ 405: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 905
+ 406: 'id-906'
+ 406: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 906
+ 407: 'id-907'
+ 407: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 907
+ 408: 'id-908'
+ 408: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 908
+ 409: 'id-909'
+ 409: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 909
+ 410: 'id-910'
+ 410: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 910
+ 411: 'id-911'
+ 411: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 911
+ 412: 'id-912'
+ 412: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 912
+ 413: 'id-913'
+ 413: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 913
+ 414: 'id-914'
+ 414: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 914
+ 415: 'id-915'
+ 415: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 915
+ 416: 'id-916'
+ 416: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 916
+ 417: 'id-917'
+ 417: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 917
+ 418: 'id-918'
+ 418: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 918
+ 419: 'id-919'
+ 419: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 919
+ 420: 'id-920'
+ 420: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 920
+ 421: 'id-921'
+ 421: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 921
+ 422: 'id-922'
+ 422: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 922
+ 423: 'id-923'
+ 423: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 923
+ 424: 'id-924'
+ 424: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 924
+ 425: 'id-925'
+ 425: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 925
+ 426: 'id-926'
+ 426: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 926
+ 427: 'id-927'
+ 427: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 927
+ 428: 'id-928'
+ 428: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 928
+ 429: 'id-929'
+ 429: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 929
+ 430: 'id-930'
+ 430: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 930
+ 431: 'id-931'
+ 431: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 931
+ 432: 'id-932'
+ 432: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 932
+ 433: 'id-933'
+ 433: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 933
+ 434: 'id-934'
+ 434: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 934
+ 435: 'id-935'
+ 435: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 935
+ 436: 'id-936'
+ 436: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 936
+ 437: 'id-937'
+ 437: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 937
+ 438: 'id-938'
+ 438: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 938
+ 439: 'id-939'
+ 439: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 939
+ 440: 'id-940'
+ 440: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 940
+ 441: 'id-941'
+ 441: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 941
+ 442: 'id-942'
+ 442: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 942
+ 443: 'id-943'
+ 443: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 943
+ 444: 'id-944'
+ 444: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 944
+ 445: 'id-945'
+ 445: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 945
+ 446: 'id-946'
+ 446: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 946
+ 447: 'id-947'
+ 447: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 947
+ 448: 'id-948'
+ 448: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 948
+ 449: 'id-949'
+ 449: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 949
+ 450: 'id-950'
+ 450: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 950
+ 451: 'id-951'
+ 451: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 951
+ 452: 'id-952'
+ 452: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 952
+ 453: 'id-953'
+ 453: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 953
+ 454: 'id-954'
+ 454: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 954
+ 455: 'id-955'
+ 455: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 955
+ 456: 'id-956'
+ 456: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 956
+ 457: 'id-957'
+ 457: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 957
+ 458: 'id-958'
+ 458: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 958
+ 459: 'id-959'
+ 459: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 959
+ 460: 'id-960'
+ 460: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 960
+ 461: 'id-961'
+ 461: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 961
+ 462: 'id-962'
+ 462: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 962
+ 463: 'id-963'
+ 463: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 963
+ 464: 'id-964'
+ 464: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 964
+ 465: 'id-965'
+ 465: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 965
+ 466: 'id-966'
+ 466: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 966
+ 467: 'id-967'
+ 467: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 967
+ 468: 'id-968'
+ 468: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 968
+ 469: 'id-969'
+ 469: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 969
+ 470: 'id-970'
+ 470: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 970
+ 471: 'id-971'
+ 471: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 971
+ 472: 'id-972'
+ 472: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 972
+ 473: 'id-973'
+ 473: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 973
+ 474: 'id-974'
+ 474: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 974
+ 475: 'id-975'
+ 475: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 975
+ 476: 'id-976'
+ 476: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 976
+ 477: 'id-977'
+ 477: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 977
+ 478: 'id-978'
+ 478: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 978
+ 479: 'id-979'
+ 479: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 979
+ 480: 'id-980'
+ 480: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 980
+ 481: 'id-981'
+ 481: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 981
+ 482: 'id-982'
+ 482: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 982
+ 483: 'id-983'
+ 483: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 983
+ 484: 'id-984'
+ 484: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 984
+ 485: 'id-985'
+ 485: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 985
+ 486: 'id-986'
+ 486: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 986
+ 487: 'id-987'
+ 487: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 987
+ 488: 'id-988'
+ 488: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 988
+ 489: 'id-989'
+ 489: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 989
+ 490: 'id-990'
+ 490: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 990
+ 491: 'id-991'
+ 491: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 991
+ 492: 'id-992'
+ 492: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 992
+ 493: 'id-993'
+ 493: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 993
+ 494: 'id-994'
+ 494: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 994
+ 495: 'id-995'
+ 495: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 995
+ 496: 'id-996'
+ 496: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 996
+ 497: 'id-997'
+ 497: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 997
+ 498: 'id-998'
+ 498: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 998
+ 499: 'id-999'
+ 499: subview 'sv'
+ VIEW 1 rows = p2:I
+ 0: 999
+ 2: subview '_B'
+ VIEW 1 rows = p1:S sv:V
+ 0: 'insert-0'
+ 0: subview 'sv'
+ VIEW 0 rows = p2:I
diff --git a/akregator/src/mk4storage/metakit/tests/ok/m06.txt b/akregator/src/mk4storage/metakit/tests/ok/m06.txt
new file mode 100644
index 000000000..ef0cb4640
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/m06.txt
@@ -0,0 +1,2 @@
+>>> Blocked view multi-row deletion
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/m06a.txt b/akregator/src/mk4storage/metakit/tests/ok/m06a.txt
new file mode 100644
index 000000000..d72b2e671
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/m06a.txt
@@ -0,0 +1,2963 @@
+ VIEW 1 rows = v1:V v2:V
+ 0: subview 'v1'
+ VIEW 901 rows = p1:I
+ 0: 1
+ 1: 100
+ 2: 101
+ 3: 102
+ 4: 103
+ 5: 104
+ 6: 105
+ 7: 106
+ 8: 107
+ 9: 108
+ 10: 109
+ 11: 110
+ 12: 111
+ 13: 112
+ 14: 113
+ 15: 114
+ 16: 115
+ 17: 116
+ 18: 117
+ 19: 118
+ 20: 119
+ 21: 120
+ 22: 121
+ 23: 122
+ 24: 123
+ 25: 124
+ 26: 125
+ 27: 126
+ 28: 127
+ 29: 128
+ 30: 129
+ 31: 130
+ 32: 131
+ 33: 132
+ 34: 133
+ 35: 134
+ 36: 135
+ 37: 136
+ 38: 137
+ 39: 138
+ 40: 139
+ 41: 140
+ 42: 141
+ 43: 142
+ 44: 143
+ 45: 144
+ 46: 145
+ 47: 146
+ 48: 147
+ 49: 148
+ 50: 149
+ 51: 150
+ 52: 151
+ 53: 152
+ 54: 153
+ 55: 154
+ 56: 155
+ 57: 156
+ 58: 157
+ 59: 158
+ 60: 159
+ 61: 160
+ 62: 161
+ 63: 162
+ 64: 163
+ 65: 164
+ 66: 165
+ 67: 166
+ 68: 167
+ 69: 168
+ 70: 169
+ 71: 170
+ 72: 171
+ 73: 172
+ 74: 173
+ 75: 174
+ 76: 175
+ 77: 176
+ 78: 177
+ 79: 178
+ 80: 179
+ 81: 180
+ 82: 181
+ 83: 182
+ 84: 183
+ 85: 184
+ 86: 185
+ 87: 186
+ 88: 187
+ 89: 188
+ 90: 189
+ 91: 190
+ 92: 191
+ 93: 192
+ 94: 193
+ 95: 194
+ 96: 195
+ 97: 196
+ 98: 197
+ 99: 198
+ 100: 199
+ 101: 200
+ 102: 201
+ 103: 202
+ 104: 203
+ 105: 204
+ 106: 205
+ 107: 206
+ 108: 207
+ 109: 208
+ 110: 209
+ 111: 210
+ 112: 211
+ 113: 212
+ 114: 213
+ 115: 214
+ 116: 215
+ 117: 216
+ 118: 217
+ 119: 218
+ 120: 219
+ 121: 220
+ 122: 221
+ 123: 222
+ 124: 223
+ 125: 224
+ 126: 225
+ 127: 226
+ 128: 227
+ 129: 228
+ 130: 229
+ 131: 230
+ 132: 231
+ 133: 232
+ 134: 233
+ 135: 234
+ 136: 235
+ 137: 236
+ 138: 237
+ 139: 238
+ 140: 239
+ 141: 240
+ 142: 241
+ 143: 242
+ 144: 243
+ 145: 244
+ 146: 245
+ 147: 246
+ 148: 247
+ 149: 248
+ 150: 249
+ 151: 250
+ 152: 251
+ 153: 252
+ 154: 253
+ 155: 254
+ 156: 255
+ 157: 256
+ 158: 257
+ 159: 258
+ 160: 259
+ 161: 260
+ 162: 261
+ 163: 262
+ 164: 263
+ 165: 264
+ 166: 265
+ 167: 266
+ 168: 267
+ 169: 268
+ 170: 269
+ 171: 270
+ 172: 271
+ 173: 272
+ 174: 273
+ 175: 274
+ 176: 275
+ 177: 276
+ 178: 277
+ 179: 278
+ 180: 279
+ 181: 280
+ 182: 281
+ 183: 282
+ 184: 283
+ 185: 284
+ 186: 285
+ 187: 286
+ 188: 287
+ 189: 288
+ 190: 289
+ 191: 290
+ 192: 291
+ 193: 292
+ 194: 293
+ 195: 294
+ 196: 295
+ 197: 296
+ 198: 297
+ 199: 298
+ 200: 299
+ 201: 300
+ 202: 301
+ 203: 302
+ 204: 303
+ 205: 304
+ 206: 305
+ 207: 306
+ 208: 307
+ 209: 308
+ 210: 309
+ 211: 310
+ 212: 311
+ 213: 312
+ 214: 313
+ 215: 314
+ 216: 315
+ 217: 316
+ 218: 317
+ 219: 318
+ 220: 319
+ 221: 320
+ 222: 321
+ 223: 322
+ 224: 323
+ 225: 324
+ 226: 325
+ 227: 326
+ 228: 327
+ 229: 328
+ 230: 329
+ 231: 330
+ 232: 331
+ 233: 332
+ 234: 333
+ 235: 334
+ 236: 335
+ 237: 336
+ 238: 337
+ 239: 338
+ 240: 339
+ 241: 340
+ 242: 341
+ 243: 342
+ 244: 343
+ 245: 344
+ 246: 345
+ 247: 346
+ 248: 347
+ 249: 348
+ 250: 349
+ 251: 350
+ 252: 351
+ 253: 352
+ 254: 353
+ 255: 354
+ 256: 355
+ 257: 356
+ 258: 357
+ 259: 358
+ 260: 359
+ 261: 360
+ 262: 361
+ 263: 362
+ 264: 363
+ 265: 364
+ 266: 365
+ 267: 366
+ 268: 367
+ 269: 368
+ 270: 369
+ 271: 370
+ 272: 371
+ 273: 372
+ 274: 373
+ 275: 374
+ 276: 375
+ 277: 376
+ 278: 377
+ 279: 378
+ 280: 379
+ 281: 380
+ 282: 381
+ 283: 382
+ 284: 383
+ 285: 384
+ 286: 385
+ 287: 386
+ 288: 387
+ 289: 388
+ 290: 389
+ 291: 390
+ 292: 391
+ 293: 392
+ 294: 393
+ 295: 394
+ 296: 395
+ 297: 396
+ 298: 397
+ 299: 398
+ 300: 399
+ 301: 400
+ 302: 401
+ 303: 402
+ 304: 403
+ 305: 404
+ 306: 405
+ 307: 406
+ 308: 407
+ 309: 408
+ 310: 409
+ 311: 410
+ 312: 411
+ 313: 412
+ 314: 413
+ 315: 414
+ 316: 415
+ 317: 416
+ 318: 417
+ 319: 418
+ 320: 419
+ 321: 420
+ 322: 421
+ 323: 422
+ 324: 423
+ 325: 424
+ 326: 425
+ 327: 426
+ 328: 427
+ 329: 428
+ 330: 429
+ 331: 430
+ 332: 431
+ 333: 432
+ 334: 433
+ 335: 434
+ 336: 435
+ 337: 436
+ 338: 437
+ 339: 438
+ 340: 439
+ 341: 440
+ 342: 441
+ 343: 442
+ 344: 443
+ 345: 444
+ 346: 445
+ 347: 446
+ 348: 447
+ 349: 448
+ 350: 449
+ 351: 450
+ 352: 451
+ 353: 452
+ 354: 453
+ 355: 454
+ 356: 455
+ 357: 456
+ 358: 457
+ 359: 458
+ 360: 459
+ 361: 460
+ 362: 461
+ 363: 462
+ 364: 463
+ 365: 464
+ 366: 465
+ 367: 466
+ 368: 467
+ 369: 468
+ 370: 469
+ 371: 470
+ 372: 471
+ 373: 472
+ 374: 473
+ 375: 474
+ 376: 475
+ 377: 476
+ 378: 477
+ 379: 478
+ 380: 479
+ 381: 480
+ 382: 481
+ 383: 482
+ 384: 483
+ 385: 484
+ 386: 485
+ 387: 486
+ 388: 487
+ 389: 488
+ 390: 489
+ 391: 490
+ 392: 491
+ 393: 492
+ 394: 493
+ 395: 494
+ 396: 495
+ 397: 496
+ 398: 497
+ 399: 498
+ 400: 499
+ 401: 500
+ 402: 501
+ 403: 502
+ 404: 503
+ 405: 504
+ 406: 505
+ 407: 506
+ 408: 507
+ 409: 508
+ 410: 509
+ 411: 510
+ 412: 511
+ 413: 512
+ 414: 513
+ 415: 514
+ 416: 515
+ 417: 516
+ 418: 517
+ 419: 518
+ 420: 519
+ 421: 520
+ 422: 521
+ 423: 522
+ 424: 523
+ 425: 524
+ 426: 525
+ 427: 526
+ 428: 527
+ 429: 528
+ 430: 529
+ 431: 530
+ 432: 531
+ 433: 532
+ 434: 533
+ 435: 534
+ 436: 535
+ 437: 536
+ 438: 537
+ 439: 538
+ 440: 539
+ 441: 540
+ 442: 541
+ 443: 542
+ 444: 543
+ 445: 544
+ 446: 545
+ 447: 546
+ 448: 547
+ 449: 548
+ 450: 549
+ 451: 550
+ 452: 551
+ 453: 552
+ 454: 553
+ 455: 554
+ 456: 555
+ 457: 556
+ 458: 557
+ 459: 558
+ 460: 559
+ 461: 560
+ 462: 561
+ 463: 562
+ 464: 563
+ 465: 564
+ 466: 565
+ 467: 566
+ 468: 567
+ 469: 568
+ 470: 569
+ 471: 570
+ 472: 571
+ 473: 572
+ 474: 573
+ 475: 574
+ 476: 575
+ 477: 576
+ 478: 577
+ 479: 578
+ 480: 579
+ 481: 580
+ 482: 581
+ 483: 582
+ 484: 583
+ 485: 584
+ 486: 585
+ 487: 586
+ 488: 587
+ 489: 588
+ 490: 589
+ 491: 590
+ 492: 591
+ 493: 592
+ 494: 593
+ 495: 594
+ 496: 595
+ 497: 596
+ 498: 597
+ 499: 598
+ 500: 599
+ 501: 600
+ 502: 601
+ 503: 602
+ 504: 603
+ 505: 604
+ 506: 605
+ 507: 606
+ 508: 607
+ 509: 608
+ 510: 609
+ 511: 610
+ 512: 611
+ 513: 612
+ 514: 613
+ 515: 614
+ 516: 615
+ 517: 616
+ 518: 617
+ 519: 618
+ 520: 619
+ 521: 620
+ 522: 621
+ 523: 622
+ 524: 623
+ 525: 624
+ 526: 625
+ 527: 626
+ 528: 627
+ 529: 628
+ 530: 629
+ 531: 630
+ 532: 631
+ 533: 632
+ 534: 633
+ 535: 634
+ 536: 635
+ 537: 636
+ 538: 637
+ 539: 638
+ 540: 639
+ 541: 640
+ 542: 641
+ 543: 642
+ 544: 643
+ 545: 644
+ 546: 645
+ 547: 646
+ 548: 647
+ 549: 648
+ 550: 649
+ 551: 650
+ 552: 651
+ 553: 652
+ 554: 653
+ 555: 654
+ 556: 655
+ 557: 656
+ 558: 657
+ 559: 658
+ 560: 659
+ 561: 660
+ 562: 661
+ 563: 662
+ 564: 663
+ 565: 664
+ 566: 665
+ 567: 666
+ 568: 667
+ 569: 668
+ 570: 669
+ 571: 670
+ 572: 671
+ 573: 672
+ 574: 673
+ 575: 674
+ 576: 675
+ 577: 676
+ 578: 677
+ 579: 678
+ 580: 679
+ 581: 680
+ 582: 681
+ 583: 682
+ 584: 683
+ 585: 684
+ 586: 685
+ 587: 686
+ 588: 687
+ 589: 688
+ 590: 689
+ 591: 690
+ 592: 691
+ 593: 692
+ 594: 693
+ 595: 694
+ 596: 695
+ 597: 696
+ 598: 697
+ 599: 698
+ 600: 699
+ 601: 700
+ 602: 701
+ 603: 702
+ 604: 703
+ 605: 704
+ 606: 705
+ 607: 706
+ 608: 707
+ 609: 708
+ 610: 709
+ 611: 710
+ 612: 711
+ 613: 712
+ 614: 713
+ 615: 714
+ 616: 715
+ 617: 716
+ 618: 717
+ 619: 718
+ 620: 719
+ 621: 720
+ 622: 721
+ 623: 722
+ 624: 723
+ 625: 724
+ 626: 725
+ 627: 726
+ 628: 727
+ 629: 728
+ 630: 729
+ 631: 730
+ 632: 731
+ 633: 732
+ 634: 733
+ 635: 734
+ 636: 735
+ 637: 736
+ 638: 737
+ 639: 738
+ 640: 739
+ 641: 740
+ 642: 741
+ 643: 742
+ 644: 743
+ 645: 744
+ 646: 745
+ 647: 746
+ 648: 747
+ 649: 748
+ 650: 749
+ 651: 750
+ 652: 751
+ 653: 752
+ 654: 753
+ 655: 754
+ 656: 755
+ 657: 756
+ 658: 757
+ 659: 758
+ 660: 759
+ 661: 760
+ 662: 761
+ 663: 762
+ 664: 763
+ 665: 764
+ 666: 765
+ 667: 766
+ 668: 767
+ 669: 768
+ 670: 769
+ 671: 770
+ 672: 771
+ 673: 772
+ 674: 773
+ 675: 774
+ 676: 775
+ 677: 776
+ 678: 777
+ 679: 778
+ 680: 779
+ 681: 780
+ 682: 781
+ 683: 782
+ 684: 783
+ 685: 784
+ 686: 785
+ 687: 786
+ 688: 787
+ 689: 788
+ 690: 789
+ 691: 790
+ 692: 791
+ 693: 792
+ 694: 793
+ 695: 794
+ 696: 795
+ 697: 796
+ 698: 797
+ 699: 798
+ 700: 799
+ 701: 800
+ 702: 801
+ 703: 802
+ 704: 803
+ 705: 804
+ 706: 805
+ 707: 806
+ 708: 807
+ 709: 808
+ 710: 809
+ 711: 810
+ 712: 811
+ 713: 812
+ 714: 813
+ 715: 814
+ 716: 815
+ 717: 816
+ 718: 817
+ 719: 818
+ 720: 819
+ 721: 820
+ 722: 821
+ 723: 822
+ 724: 823
+ 725: 824
+ 726: 825
+ 727: 826
+ 728: 827
+ 729: 828
+ 730: 829
+ 731: 830
+ 732: 831
+ 733: 832
+ 734: 833
+ 735: 834
+ 736: 835
+ 737: 836
+ 738: 837
+ 739: 838
+ 740: 839
+ 741: 840
+ 742: 841
+ 743: 842
+ 744: 843
+ 745: 844
+ 746: 845
+ 747: 846
+ 748: 847
+ 749: 848
+ 750: 849
+ 751: 850
+ 752: 851
+ 753: 852
+ 754: 853
+ 755: 854
+ 756: 855
+ 757: 856
+ 758: 857
+ 759: 858
+ 760: 859
+ 761: 860
+ 762: 861
+ 763: 862
+ 764: 863
+ 765: 864
+ 766: 865
+ 767: 866
+ 768: 867
+ 769: 868
+ 770: 869
+ 771: 870
+ 772: 871
+ 773: 872
+ 774: 873
+ 775: 874
+ 776: 875
+ 777: 876
+ 778: 877
+ 779: 878
+ 780: 879
+ 781: 880
+ 782: 881
+ 783: 882
+ 784: 883
+ 785: 884
+ 786: 885
+ 787: 886
+ 788: 887
+ 789: 888
+ 790: 889
+ 791: 890
+ 792: 891
+ 793: 892
+ 794: 893
+ 795: 894
+ 796: 895
+ 797: 896
+ 798: 897
+ 799: 898
+ 800: 899
+ 801: 900
+ 802: 901
+ 803: 902
+ 804: 903
+ 805: 904
+ 806: 905
+ 807: 906
+ 808: 907
+ 809: 908
+ 810: 909
+ 811: 910
+ 812: 911
+ 813: 912
+ 814: 913
+ 815: 914
+ 816: 915
+ 817: 916
+ 818: 917
+ 819: 918
+ 820: 919
+ 821: 920
+ 822: 921
+ 823: 922
+ 824: 923
+ 825: 924
+ 826: 925
+ 827: 926
+ 828: 927
+ 829: 928
+ 830: 929
+ 831: 930
+ 832: 931
+ 833: 932
+ 834: 933
+ 835: 934
+ 836: 935
+ 837: 936
+ 838: 937
+ 839: 938
+ 840: 939
+ 841: 940
+ 842: 941
+ 843: 942
+ 844: 943
+ 845: 944
+ 846: 945
+ 847: 946
+ 848: 947
+ 849: 948
+ 850: 949
+ 851: 950
+ 852: 951
+ 853: 952
+ 854: 953
+ 855: 954
+ 856: 955
+ 857: 956
+ 858: 957
+ 859: 958
+ 860: 959
+ 861: 960
+ 862: 961
+ 863: 962
+ 864: 963
+ 865: 964
+ 866: 965
+ 867: 966
+ 868: 967
+ 869: 968
+ 870: 969
+ 871: 970
+ 872: 971
+ 873: 972
+ 874: 973
+ 875: 974
+ 876: 975
+ 877: 976
+ 878: 977
+ 879: 978
+ 880: 979
+ 881: 980
+ 882: 981
+ 883: 982
+ 884: 983
+ 885: 984
+ 886: 985
+ 887: 986
+ 888: 987
+ 889: 988
+ 890: 989
+ 891: 990
+ 892: 991
+ 893: 992
+ 894: 993
+ 895: 994
+ 896: 995
+ 897: 996
+ 898: 997
+ 899: 998
+ 900: 999
+ 0: subview 'v2'
+ VIEW 4 rows = _B:V
+ 0: subview '_B'
+ VIEW 999 rows = _H:I _R:I
+ 0: 0 -1
+ 1: 0 -1
+ 2: -1461104643 430
+ 3: 0 -1
+ 4: 0 -1
+ 5: 1034993658 780
+ 6: 777013241 36
+ 7: 608274424 551
+ 8: 0 -1
+ 9: -1460496394 19
+ 10: 0 -1
+ 11: 0 -1
+ 12: 1035601907 881
+ 13: 0 -1
+ 14: 0 -1
+ 15: 1799477232 164
+ 16: 0 -1
+ 17: 0 -1
+ 18: 0 -1
+ 19: -696012820 427
+ 20: -683483157 154
+ 21: 0 -1
+ 22: 1800085481 265
+ 23: 0 -1
+ 24: -268685337 757
+ 25: 0 -1
+ 26: -695404571 16
+ 27: -953384988 296
+ 28: 0 -1
+ 29: 338980834 282
+ 30: 81000417 562
+ 31: 1373974496 137
+ 32: -1987770401 30
+ 33: -694796322 629
+ 34: 0 -1
+ 35: 0 -1
+ 36: 339589083 383
+ 37: 0 -1
+ 38: 0 -1
+ 39: 1103464408 690
+ 40: 0 -1
+ 41: -965306410 158
+ 42: 0 -1
+ 43: 69687252 13
+ 44: 1530791891 508
+ 45: 0 -1
+ 46: 1104072657 791
+ 47: 0 -1
+ 48: -964698161 259
+ 49: 0 -1
+ 50: 0 -1
+ 51: -1649397812 822
+ 52: 0 -1
+ 53: 0 -1
+ 54: 846700489 148
+ 55: 677961672 663
+ 56: -1222070329 640
+ 57: -1390809146 131
+ 58: 0 -1
+ 59: 0 -1
+ 60: 0 -1
+ 61: -1999083582 505
+ 62: 0 -1
+ 63: 1869164480 276
+ 64: 0 -1
+ 65: -199606338 768
+ 66: 0 -1
+ 67: -626325572 539
+ 68: 834779067 10
+ 69: 576798650 290
+ 70: 1869772729 377
+ 71: 0 -1
+ 72: -198998089 869
+ 73: 0 -1
+ 74: 0 -1
+ 75: -883697740 408
+ 76: 0 -1
+ 77: 0 -1
+ 78: 1599262641 418
+ 79: 0 -1
+ 80: -1918083153 142
+ 81: 0 -1
+ 82: 565485485 253
+ 83: 0 -1
+ 84: 0 -1
+ 85: 1599870890 7
+ 86: 0 -1
+ 87: 0 -1
+ 88: 0 -1
+ 89: -895619162 270
+ 90: -1153599579 550
+ 91: 139374500 125
+ 92: 0 -1
+ 93: 1342498722 900
+ 94: 0 -1
+ 95: -1930612832 415
+ 96: -895010913 371
+ 97: 0 -1
+ 98: 0 -1
+ 99: -131135588 678
+ 100: -1503285349 745
+ 101: 0 -1
+ 102: -1930004583 4
+ 103: 0 -1
+ 104: 296191895 496
+ 105: 0 -1
+ 106: -130527339 779
+ 107: 0 -1
+ 108: 0 -1
+ 109: -1929396334 617
+ 110: 0 -1
+ 111: 0 -1
+ 112: 0 -1
+ 113: 0 -1
+ 114: -387899507 136
+ 115: -556638324 651
+ 116: 0 -1
+ 117: 646485898 402
+ 118: 0 -1
+ 119: -1164912760 1
+ 120: 0 -1
+ 121: 1061283718 493
+ 122: 0 -1
+ 123: 634564484 264
+ 124: 2095669123 247
+ 125: 0 -1
+ 126: 1668949889 530
+ 127: 1410969472 810
+ 128: 0 -1
+ 129: 0 -1
+ 130: 635172733 365
+ 131: 0 -1
+ 132: 1838296955 628
+ 133: 1669558138 119
+ 134: 0 -1
+ 135: 0 -1
+ 136: 0 -1
+ 137: 0 -1
+ 138: -1083912331 662
+ 139: 0 -1
+ 140: 0 -1
+ 141: -1434206350 756
+ 142: 0 -1
+ 143: -1860925584 527
+ 144: 0 -1
+ 145: 0 -1
+ 146: 0 -1
+ 147: -61448340 790
+ 148: -1433598101 857
+ 149: 0 -1
+ 150: 0 -1
+ 151: -2118297752 396
+ 152: 0 -1
+ 153: 107898726 888
+ 154: -60840091 891
+ 155: 0 -1
+ 156: 1142284131 130
+ 157: 0 -1
+ 158: -669114527 241
+ 159: 0 -1
+ 160: 1557081951 733
+ 161: 0 -1
+ 162: 0 -1
+ 163: 0 -1
+ 164: 0 -1
+ 165: -2130219174 258
+ 166: 0 -1
+ 167: -1095225512 113
+ 168: 0 -1
+ 169: 1130970966 605
+ 170: 0 -1
+ 171: 0 -1
+ 172: -2129610925 359
+ 173: 0 -1
+ 174: 0 -1
+ 175: 0 -1
+ 176: 0 -1
+ 177: -588114098 390
+ 178: 0 -1
+ 179: 0 -1
+ 180: -938408117 484
+ 181: 0 -1
+ 182: -1365127351 767
+ 183: 0 -1
+ 184: 861069127 235
+ 185: 0 -1
+ 186: 434349893 518
+ 187: 176369476 798
+ 188: 0 -1
+ 189: 0 -1
+ 190: -1622499519 124
+ 191: -1791238336 639
+ 192: 603696959 616
+ 193: 434958142 107
+ 194: 0 -1
+ 195: 0 -1
+ 196: 0 -1
+ 197: -173316294 481
+ 198: 0 -1
+ 199: -600035528 252
+ 200: 0 -1
+ 201: 1626160950 744
+ 202: 0 -1
+ 203: 1199441716 515
+ 204: 0 -1
+ 205: 0 -1
+ 206: -599427279 353
+ 207: 0 -1
+ 208: 1626769199 845
+ 209: 0 -1
+ 210: 0 -1
+ 211: 942069548 384
+ 212: 0 -1
+ 213: 0 -1
+ 214: 1976454953 650
+ 215: 0 -1
+ 216: -92315865 118
+ 217: 0 -1
+ 218: -1903714523 229
+ 219: 0 -1
+ 220: 0 -1
+ 221: 0 -1
+ 222: 0 -1
+ 223: -1296048352 778
+ 224: 0 -1
+ 225: 930148126 246
+ 226: 0 -1
+ 227: 1965141788 101
+ 228: 0 -1
+ 229: -1126701286 876
+ 230: -1295440103 879
+ 231: 0 -1
+ 232: 930756375 347
+ 233: 0 -1
+ 234: 0 -1
+ 235: 0 -1
+ 236: 322481939 721
+ 237: 0 -1
+ 238: 0 -1
+ 239: 0 -1
+ 240: 2121959183 472
+ 241: 0 -1
+ 242: 1695239949 755
+ 243: 0 -1
+ 244: 0 -1
+ 245: -103629046 593
+ 246: 0 -1
+ 247: 0 -1
+ 248: 0 -1
+ 249: 0 -1
+ 250: 1437867781 112
+ 251: 1269128964 627
+ 252: 0 -1
+ 253: -1822714110 378
+ 254: 0 -1
+ 255: 0 -1
+ 256: 0 -1
+ 257: -1407916290 469
+ 258: 0 -1
+ 259: -1834635524 240
+ 260: -373530885 223
+ 261: 0 -1
+ 262: -800250119 506
+ 263: 0 -1
+ 264: 0 -1
+ 265: 0 -1
+ 266: -1834027275 341
+ 267: 0 -1
+ 268: -630903053 604
+ 269: -799641870 95
+ 270: 0 -1
+ 271: 0 -1
+ 272: 0 -1
+ 273: 0 -1
+ 274: 741854957 638
+ 275: 0 -1
+ 276: 0 -1
+ 277: 391560938 732
+ 278: 0 -1
+ 279: -35158296 503
+ 280: 0 -1
+ 281: 0 -1
+ 282: 0 -1
+ 283: 1764318948 766
+ 284: 392169187 833
+ 285: 0 -1
+ 286: 0 -1
+ 287: -292530464 372
+ 288: 0 -1
+ 289: 1933666014 864
+ 290: 1764927197 867
+ 291: 0 -1
+ 292: -1326915877 106
+ 293: 0 -1
+ 294: 1156652761 217
+ 295: 0 -1
+ 296: -912118057 709
+ 297: 0 -1
+ 298: 0 -1
+ 299: 0 -1
+ 300: 0 -1
+ 301: -304451886 234
+ 302: 0 -1
+ 303: 730541776 89
+ 304: 0 -1
+ 305: -1338229042 581
+ 306: 0 -1
+ 307: 0 -1
+ 308: -303843637 335
+ 309: 0 -1
+ 310: 0 -1
+ 311: -988543288 898
+ 312: 0 -1
+ 313: 1237653190 366
+ 314: 0 -1
+ 315: 0 -1
+ 316: 887359171 460
+ 317: 0 -1
+ 318: 460639937 743
+ 319: 0 -1
+ 320: -1608130881 211
+ 321: 0 -1
+ 322: -2034850115 494
+ 323: 0 -1
+ 324: 0 -1
+ 325: 0 -1
+ 326: 203267769 100
+ 327: 34528952 615
+ 328: -1865503049 592
+ 329: -2034241866 83
+ 330: 0 -1
+ 331: 0 -1
+ 332: 0 -1
+ 333: 1652450994 457
+ 334: 0 -1
+ 335: 1225731760 228
+ 336: 0 -1
+ 337: -843039058 720
+ 338: 0 -1
+ 339: -1269758292 491
+ 340: 0 -1
+ 341: 0 -1
+ 342: 1226340009 329
+ 343: 0 -1
+ 344: -842430809 821
+ 345: 0 -1
+ 346: 0 -1
+ 347: -1527130460 360
+ 348: 0 -1
+ 349: 0 -1
+ 350: -492745055 626
+ 351: 0 -1
+ 352: 1733451423 94
+ 353: 0 -1
+ 354: -77947235 205
+ 355: 0 -1
+ 356: 0 -1
+ 357: 0 -1
+ 358: 0 -1
+ 359: 529718936 754
+ 360: 0 -1
+ 361: -1539051882 222
+ 362: 0 -1
+ 363: -504058220 77
+ 364: 0 -1
+ 365: 699066002 852
+ 366: 530327185 855
+ 367: 0 -1
+ 368: -1538443633 323
+ 369: 0 -1
+ 370: 0 -1
+ 371: 2071824012 886
+ 372: -2146718069 697
+ 373: 0 -1
+ 374: 0 -1
+ 375: 0 -1
+ 376: -347240825 448
+ 377: 0 -1
+ 378: -773960059 731
+ 379: 0 -1
+ 380: 0 -1
+ 381: 1722138242 569
+ 382: 0 -1
+ 383: 0 -1
+ 384: 0 -1
+ 385: 0 -1
+ 386: -1031332227 88
+ 387: -1200071044 603
+ 388: 0 -1
+ 389: 3053178 354
+ 390: 0 -1
+ 391: 0 -1
+ 392: 0 -1
+ 393: 417850998 445
+ 394: 0 -1
+ 395: -8868236 216
+ 396: 1452236403 199
+ 397: 0 -1
+ 398: 1025517169 482
+ 399: 0 -1
+ 400: 0 -1
+ 401: 0 -1
+ 402: -8259987 317
+ 403: 0 -1
+ 404: 1194864235 580
+ 405: 1026125418 71
+ 406: 0 -1
+ 407: 0 -1
+ 408: 0 -1
+ 409: 0 -1
+ 410: -1727345051 614
+ 411: 0 -1
+ 412: 0 -1
+ 413: -2077639070 708
+ 414: 0 -1
+ 415: 1790608992 479
+ 416: 0 -1
+ 417: 0 -1
+ 418: 0 -1
+ 419: -704881060 742
+ 420: -2077030821 809
+ 421: 0 -1
+ 422: 0 -1
+ 423: 1533236824 348
+ 424: 0 -1
+ 425: -535533994 840
+ 426: -704272811 843
+ 427: 0 -1
+ 428: 498851411 82
+ 429: 0 -1
+ 430: -1312547247 193
+ 431: 0 -1
+ 432: 913649231 685
+ 433: 0 -1
+ 434: 0 -1
+ 435: 0 -1
+ 436: 0 -1
+ 437: 1521315402 210
+ 438: 0 -1
+ 439: -1738658232 65
+ 440: 0 -1
+ 441: 487538246 557
+ 442: 0 -1
+ 443: 0 -1
+ 444: 1521923651 311
+ 445: 0 -1
+ 446: 0 -1
+ 447: 837224000 874
+ 448: 0 -1
+ 449: -1231546818 342
+ 450: 0 -1
+ 451: 0 -1
+ 452: -1581840837 436
+ 453: 0 -1
+ 454: -2008560071 719
+ 455: 0 -1
+ 456: 217636407 187
+ 457: 0 -1
+ 458: -209082827 470
+ 459: 0 -1
+ 460: 0 -1
+ 461: 0 -1
+ 462: 2029035057 76
+ 463: 1860296240 591
+ 464: -39735761 568
+ 465: -208474578 59
+ 466: 0 -1
+ 467: 0 -1
+ 468: 0 -1
+ 469: -816749014 433
+ 470: 0 -1
+ 471: -1243468248 204
+ 472: 0 -1
+ 473: 982728230 696
+ 474: 0 -1
+ 475: 556008996 467
+ 476: 0 -1
+ 477: 0 -1
+ 478: -1242859999 305
+ 479: 0 -1
+ 480: 983336479 797
+ 481: 0 -1
+ 482: 0 -1
+ 483: 298636828 336
+ 484: 0 -1
+ 485: 0 -1
+ 486: 1333022233 602
+ 487: 0 -1
+ 488: -735748585 70
+ 489: 0 -1
+ 490: 1747820053 181
+ 491: 0 -1
+ 492: 0 -1
+ 493: 0 -1
+ 494: 0 -1
+ 495: -1939481072 730
+ 496: 0 -1
+ 497: 286715406 198
+ 498: 0 -1
+ 499: 1321709068 53
+ 500: 0 -1
+ 501: -1770134006 828
+ 502: -1938872823 831
+ 503: 0 -1
+ 504: 287323655 299
+ 505: 0 -1
+ 506: 0 -1
+ 507: -397375996 862
+ 508: -320950781 673
+ 509: 0 -1
+ 510: 0 -1
+ 511: 0 -1
+ 512: 1478526463 424
+ 513: 0 -1
+ 514: 1051807229 707
+ 515: 0 -1
+ 516: 0 -1
+ 517: -747061766 545
+ 518: 0 -1
+ 519: 0 -1
+ 520: 0 -1
+ 521: 0 -1
+ 522: 794435061 64
+ 523: 625696244 579
+ 524: 0 -1
+ 525: 1828820466 330
+ 526: 0 -1
+ 527: 0 -1
+ 528: 0 -1
+ 529: -2051349010 421
+ 530: 0 -1
+ 531: 1816899052 192
+ 532: -1016963605 175
+ 533: 0 -1
+ 534: -1443682839 458
+ 535: 0 -1
+ 536: 0 -1
+ 537: 0 -1
+ 538: 1817507301 293
+ 539: 0 -1
+ 540: -1274335773 556
+ 541: -1443074590 47
+ 542: 0 -1
+ 543: 0 -1
+ 544: 0 -1
+ 545: 0 -1
+ 546: 98422237 590
+ 547: 0 -1
+ 548: 0 -1
+ 549: -251871782 684
+ 550: 0 -1
+ 551: -678591016 455
+ 552: 357010903 411
+ 553: 0 -1
+ 554: 0 -1
+ 555: 1120886228 718
+ 556: -251263533 785
+ 557: 0 -1
+ 558: 0 -1
+ 559: -935963184 324
+ 560: 1548213711 536
+ 561: 1290233294 816
+ 562: 1121494477 819
+ 563: 0 -1
+ 564: -1970348597 58
+ 565: -677374518 657
+ 566: 513220041 169
+ 567: 0 -1
+ 568: 0 -1
+ 569: 0 -1
+ 570: 0 -1
+ 571: 0 -1
+ 572: 0 -1
+ 573: -947884606 186
+ 574: 0 -1
+ 575: 87109056 41
+ 576: 0 -1
+ 577: -1981661762 533
+ 578: 0 -1
+ 579: 0 -1
+ 580: -947276357 287
+ 581: 0 -1
+ 582: 0 -1
+ 583: -1631976008 850
+ 584: 0 -1
+ 585: 594220470 318
+ 586: 1887194549 405
+ 587: 0 -1
+ 588: -1204648525 668
+ 589: 0 -1
+ 590: -182792783 695
+ 591: 0 -1
+ 592: 2043403695 163
+ 593: 0 -1
+ 594: 1616684461 446
+ 595: 0 -1
+ 596: 0 -1
+ 597: -182184534 796
+ 598: -440164951 52
+ 599: -608903768 567
+ 600: 1786031527 544
+ 601: 1617292710 35
+ 602: 0 -1
+ 603: 0 -1
+ 604: -181576285 897
+ 605: 0 -1
+ 606: 0 -1
+ 607: 582299040 180
+ 608: 0 -1
+ 609: -1486471778 672
+ 610: 0 -1
+ 611: -1913191012 443
+ 612: 0 -1
+ 613: 0 -1
+ 614: 582907289 281
+ 615: 0 -1
+ 616: -1485863529 773
+ 617: 0 -1
+ 618: 0 -1
+ 619: 2124404116 312
+ 620: 0 -1
+ 621: 0 -1
+ 622: -1136177775 578
+ 623: 156796304 153
+ 624: 1090018703 46
+ 625: -1911974514 645
+ 626: -721379955 157
+ 627: 0 -1
+ 628: -877589109 399
+ 629: 0 -1
+ 630: 0 -1
+ 631: -113713784 706
+ 632: 0 -1
+ 633: 2112482694 174
+ 634: 0 -1
+ 635: -1147490940 29
+ 636: 313613699 524
+ 637: 55633282 804
+ 638: -113105535 807
+ 639: 0 -1
+ 640: 2113090943 275
+ 641: 0 -1
+ 642: 0 -1
+ 643: 1428391292 838
+ 644: 0 -1
+ 645: 0 -1
+ 646: 0 -1
+ 647: 0 -1
+ 648: 1855718775 656
+ 649: 1686979958 147
+ 650: -1417392779 683
+ 651: 0 -1
+ 652: 0 -1
+ 653: 1078705522 521
+ 654: 0 -1
+ 655: 0 -1
+ 656: 0 -1
+ 657: -1416784530 784
+ 658: -1674764947 40
+ 659: -1843503764 555
+ 660: -382399125 26
+ 661: -640379542 306
+ 662: 652594537 393
+ 663: 0 -1
+ 664: -1416176281 885
+ 665: 0 -1
+ 666: 0 -1
+ 667: -652300956 168
+ 668: 0 -1
+ 669: 0 -1
+ 670: 382084449 434
+ 671: 0 -1
+ 672: -1686686369 0
+ 673: 0 -1
+ 674: -651692707 269
+ 675: 0 -1
+ 676: 0 -1
+ 677: 382692698 23
+ 678: 0 -1
+ 679: 0 -1
+ 680: 0 -1
+ 681: 0 -1
+ 682: 1924189525 566
+ 683: -1077803692 141
+ 684: 0 -1
+ 685: 0 -1
+ 686: 0 -1
+ 687: 1147176272 431
+ 688: -2112189105 387
+ 689: 0 -1
+ 690: 0 -1
+ 691: -1348313780 694
+ 692: 1574503755 761
+ 693: 0 -1
+ 694: 1147784521 20
+ 695: 889804104 300
+ 696: -920986297 512
+ 697: 0 -1
+ 698: -1347705531 795
+ 699: 0 -1
+ 700: -144581309 34
+ 701: 1148392770 633
+ 702: 0 -1
+ 703: 0 -1
+ 704: 0 -1
+ 705: 0 -1
+ 706: -1605077699 152
+ 707: -1773816516 667
+ 708: 0 -1
+ 709: 877882682 162
+ 710: 0 -1
+ 711: 1912876344 17
+ 712: 0 -1
+ 713: -155894474 509
+ 714: 0 -1
+ 715: -582613708 280
+ 716: 878490931 263
+ 717: 0 -1
+ 718: 0 -1
+ 719: 193791280 826
+ 720: -1616999121 14
+ 721: -1874979538 294
+ 722: -582005459 381
+ 723: 0 -1
+ 724: 621118763 644
+ 725: 452379946 135
+ 726: 1642974505 671
+ 727: 0 -1
+ 728: 0 -1
+ 729: 0 -1
+ 730: -852515547 422
+ 731: 0 -1
+ 732: 0 -1
+ 733: 1643582754 772
+ 734: 0 -1
+ 735: 1216863520 543
+ 736: 0 -1
+ 737: -851907298 11
+ 738: 0 -1
+ 739: 0 -1
+ 740: 1644191003 873
+ 741: 0 -1
+ 742: 0 -1
+ 743: 959491352 412
+ 744: 0 -1
+ 745: 0 -1
+ 746: 0 -1
+ 747: -87423724 419
+ 748: -74894061 146
+ 749: 0 -1
+ 750: -1886292719 257
+ 751: 0 -1
+ 752: 339903759 749
+ 753: 0 -1
+ 754: -86815475 8
+ 755: -344795892 288
+ 756: 0 -1
+ 757: 947569930 274
+ 758: 689589513 554
+ 759: 1982563592 129
+ 760: 0 -1
+ 761: -86207226 621
+ 762: 0 -1
+ 763: 0 -1
+ 764: 948178179 375
+ 765: 0 -1
+ 766: 0 -1
+ 767: 1712053504 682
+ 768: 0 -1
+ 769: -1805292290 406
+ 770: 0 -1
+ 771: 678276348 5
+ 772: 2139380987 500
+ 773: 0 -1
+ 774: 1712661753 783
+ 775: 0 -1
+ 776: -356109065 251
+ 777: 0 -1
+ 778: -782828299 534
+ 779: -1040808716 814
+ 780: 0 -1
+ 781: 0 -1
+ 782: 1455289585 140
+ 783: 1286550768 655
+ 784: -613481233 632
+ 785: -782220050 123
+ 786: 0 -1
+ 787: 0 -1
+ 788: 0 -1
+ 789: -1390494486 497
+ 790: 0 -1
+ 791: -1817213720 268
+ 792: 0 -1
+ 793: 408982758 760
+ 794: 0 -1
+ 795: -17736476 531
+ 796: 1443368163 2
+ 797: 0 -1
+ 798: -1816605471 369
+ 799: 0 -1
+ 800: 409591007 861
+ 801: 0 -1
+ 802: 0 -1
+ 803: -275108644 400
+ 804: 0 -1
+ 805: 0 -1
+ 806: 759276761 666
+ 807: 0 -1
+ 808: -1309494057 134
+ 809: 0 -1
+ 810: 1174074581 245
+ 811: 0 -1
+ 812: 0 -1
+ 813: 0 -1
+ 814: 0 -1
+ 815: 1781740752 794
+ 816: 0 -1
+ 817: -287030066 262
+ 818: -545010483 542
+ 819: 747963596 117
+ 820: 0 -1
+ 821: 1951087818 892
+ 822: 1782349001 895
+ 823: 0 -1
+ 824: -286421817 363
+ 825: 0 -1
+ 826: 0 -1
+ 827: 477453508 670
+ 828: -894696253 737
+ 829: 0 -1
+ 830: 0 -1
+ 831: 0 -1
+ 832: 904780991 488
+ 833: 0 -1
+ 834: 478061757 771
+ 835: 0 -1
+ 836: 0 -1
+ 837: -1320807238 609
+ 838: 0 -1
+ 839: 0 -1
+ 840: 0 -1
+ 841: 0 -1
+ 842: 220689589 128
+ 843: 51950772 643
+ 844: 0 -1
+ 845: 1255074994 394
+ 846: 0 -1
+ 847: 0 -1
+ 848: 0 -1
+ 849: 1669872814 485
+ 850: 0 -1
+ 851: 1243153580 256
+ 852: -1590709077 239
+ 853: 0 -1
+ 854: -2017428311 522
+ 855: 2019558568 802
+ 856: 0 -1
+ 857: 0 -1
+ 858: 1243761829 357
+ 859: 0 -1
+ 860: -1848081245 620
+ 861: -2016820062 111
+ 862: 0 -1
+ 863: 0 -1
+ 864: 0 -1
+ 865: 0 -1
+ 866: -475323235 654
+ 867: 0 -1
+ 868: 0 -1
+ 869: -825617254 748
+ 870: 0 -1
+ 871: -1252336488 519
+ 872: 0 -1
+ 873: 0 -1
+ 874: 0 -1
+ 875: 547140756 782
+ 876: -825009005 849
+ 877: 0 -1
+ 878: 0 -1
+ 879: -1509708656 388
+ 880: 0 -1
+ 881: 716487822 880
+ 882: 547749005 883
+ 883: 0 -1
+ 884: 1750873227 122
+ 885: 0 -1
+ 886: -60525431 233
+ 887: 0 -1
+ 888: -2129296249 725
+ 889: 0 -1
+ 890: 0 -1
+ 891: 0 -1
+ 892: 0 -1
+ 893: -1521630078 250
+ 894: 0 -1
+ 895: -486636416 105
+ 896: 0 -1
+ 897: 1739560062 597
+ 898: 0 -1
+ 899: 0 -1
+ 900: -1521021829 351
+ 901: 0 -1
+ 902: 0 -1
+ 903: 0 -1
+ 904: 0 -1
+ 905: 20474998 382
+ 906: 0 -1
+ 907: 0 -1
+ 908: -329819021 476
+ 909: 0 -1
+ 910: -756538255 759
+ 911: 0 -1
+ 912: 1469658223 227
+ 913: 0 -1
+ 914: 1042938989 510
+ 915: 0 -1
+ 916: 0 -1
+ 917: 0 -1
+ 918: -1013910423 116
+ 919: -1182649240 631
+ 920: 1212286055 608
+ 921: 1043547238 99
+ 922: 0 -1
+ 923: 0 -1
+ 924: 0 -1
+ 925: 435272802 473
+ 926: 0 -1
+ 927: 8553568 244
+ 928: 0 -1
+ 929: -2060217250 736
+ 930: 0 -1
+ 931: 1808030812 507
+ 932: 0 -1
+ 933: 0 -1
+ 934: 9161817 345
+ 935: 0 -1
+ 936: -2059609001 837
+ 937: 0 -1
+ 938: 0 -1
+ 939: 1550658644 376
+ 940: 0 -1
+ 941: 0 -1
+ 942: -1709923247 642
+ 943: 0 -1
+ 944: 516273231 110
+ 945: 0 -1
+ 946: -1295125427 221
+ 947: 0 -1
+ 948: 0 -1
+ 949: 0 -1
+ 950: 0 -1
+ 951: -687459256 770
+ 952: 0 -1
+ 953: 1538737222 238
+ 954: 0 -1
+ 955: -1721236412 93
+ 956: 0 -1
+ 957: -518112190 868
+ 958: -686851007 871
+ 959: 0 -1
+ 960: 1539345471 339
+ 961: 0 -1
+ 962: 0 -1
+ 963: 0 -1
+ 964: 931071035 713
+ 965: 0 -1
+ 966: 0 -1
+ 967: 0 -1
+ 968: -1564419017 464
+ 969: 0 -1
+ 970: -1991138251 747
+ 971: 0 -1
+ 972: 0 -1
+ 973: 504960050 585
+ 974: 0 -1
+ 975: 0 -1
+ 976: 0 -1
+ 977: 0 -1
+ 978: 2046456877 104
+ 979: 1877718060 619
+ 980: 0 -1
+ 981: -1214125014 370
+ 982: 0 -1
+ 983: 0 -1
+ 984: 0 -1
+ 985: -799327194 461
+ 986: 0 -1
+ 987: -1226046428 232
+ 988: 235058211 215
+ 989: 0 -1
+ 990: -191661023 498
+ 991: 0 -1
+ 992: 0 -1
+ 993: 0 -1
+ 994: -1225438179 333
+ 995: 0 -1
+ 996: -22313957 596
+ 997: -191052774 87
+ 998: 0 -1
+ 1: subview '_B'
+ VIEW 47 rows = _H:I _R:I
+ 0: 0 -1
+ 1: 0 -1
+ 2: 1350444053 630
+ 3: 0 -1
+ 4: 0 -1
+ 5: 1000150034 724
+ 6: 0 -1
+ 7: 573430800 495
+ 8: 0 -1
+ 9: 0 -1
+ 10: 0 -1
+ 11: -1922059252 758
+ 12: 1000758283 825
+ 13: 0 -1
+ 14: 0 -1
+ 15: 316058632 364
+ 16: 0 -1
+ 17: -1752712186 856
+ 18: -1921451003 859
+ 19: 0 -1
+ 20: -718326781 98
+ 21: 0 -1
+ 22: 1765241857 209
+ 23: 0 -1
+ 24: -303528961 701
+ 25: 0 -1
+ 26: 0 -1
+ 27: 0 -1
+ 28: 0 -1
+ 29: 304137210 226
+ 30: 0 -1
+ 31: 1339130872 81
+ 32: 0 -1
+ 33: -729639946 573
+ 34: 0 -1
+ 35: 0 -1
+ 36: 304745459 327
+ 37: 0 -1
+ 38: 0 -1
+ 39: -379954192 890
+ 40: 0 -1
+ 41: 1846242286 358
+ 42: 0 -1
+ 43: 0 -1
+ 44: 1495948267 452
+ 45: 0 -1
+ 46: 1069229033 735
+ 2: subview '_B'
+ VIEW 1001 rows = _H:I _R:I
+ 0: -999541785 203
+ 1: 0 -1
+ 2: -1426261019 486
+ 3: 0 -1
+ 4: 0 -1
+ 5: 0 -1
+ 6: 811856865 92
+ 7: 643118048 607
+ 8: -1256913953 584
+ 9: -1425652770 75
+ 10: 0 -1
+ 11: 0 -1
+ 12: 0 -1
+ 13: -2033927206 449
+ 14: 0 -1
+ 15: 1834320856 220
+ 16: 0 -1
+ 17: -234449962 712
+ 18: 0 -1
+ 19: -661169196 483
+ 20: 0 -1
+ 21: 0 -1
+ 22: 1834929105 321
+ 23: 0 -1
+ 24: -233841713 813
+ 25: 0 -1
+ 26: 0 -1
+ 27: -918541364 352
+ 28: 0 -1
+ 29: 0 -1
+ 30: 115844041 618
+ 31: 0 -1
+ 32: -1952926777 86
+ 33: 0 -1
+ 34: 530641861 197
+ 35: 0 -1
+ 36: 0 -1
+ 37: 0 -1
+ 38: 0 -1
+ 39: 1138308032 746
+ 40: 0 -1
+ 41: -930462786 214
+ 42: 0 -1
+ 43: 104530876 69
+ 44: 0 -1
+ 45: 1307655098 844
+ 46: 1138916281 847
+ 47: 0 -1
+ 48: -929854537 315
+ 49: 0 -1
+ 50: 0 -1
+ 51: -1614554188 878
+ 52: -1538128973 689
+ 53: 0 -1
+ 54: 0 -1
+ 55: 0 -1
+ 56: 261348271 440
+ 57: 0 -1
+ 58: -165370963 723
+ 59: 0 -1
+ 60: 0 -1
+ 61: -1964239958 561
+ 62: 0 -1
+ 63: 0 -1
+ 64: 0 -1
+ 65: 0 -1
+ 66: -422743131 80
+ 67: -591481948 595
+ 68: 0 -1
+ 69: 611642274 346
+ 70: 0 -1
+ 71: 0 -1
+ 72: 0 -1
+ 73: 1026440094 437
+ 74: 0 -1
+ 75: 599720860 208
+ 76: 2060825499 191
+ 77: 0 -1
+ 78: 1634106265 474
+ 79: 0 -1
+ 80: 0 -1
+ 81: 0 -1
+ 82: 600329109 309
+ 83: 0 -1
+ 84: 1803453331 572
+ 85: 1634714514 63
+ 86: 0 -1
+ 87: 0 -1
+ 88: 0 -1
+ 89: 0 -1
+ 90: -1118755955 606
+ 91: 0 -1
+ 92: 0 -1
+ 93: -1469049974 700
+ 94: 0 -1
+ 95: -1895769208 471
+ 96: 0 -1
+ 97: 0 -1
+ 98: 0 -1
+ 99: -96291964 734
+ 100: -1468441725 801
+ 101: 0 -1
+ 102: 0 -1
+ 103: 2141825920 340
+ 104: 0 -1
+ 105: 73055102 832
+ 106: -95683715 835
+ 107: 0 -1
+ 108: 1107440507 74
+ 109: 0 -1
+ 110: -703958151 185
+ 111: 0 -1
+ 112: 1522238327 677
+ 113: 0 -1
+ 114: 0 -1
+ 115: 0 -1
+ 116: 0 -1
+ 117: 2129904498 202
+ 118: 0 -1
+ 119: -1130069136 57
+ 120: 0 -1
+ 121: 1096127342 549
+ 122: 0 -1
+ 123: 0 -1
+ 124: 2130512747 303
+ 125: 0 -1
+ 126: 0 -1
+ 127: 1445813096 866
+ 128: 0 -1
+ 129: -622957722 334
+ 130: 0 -1
+ 131: 0 -1
+ 132: -973251741 428
+ 133: 0 -1
+ 134: -1399970975 711
+ 135: 0 -1
+ 136: 826225503 179
+ 137: 0 -1
+ 138: 399506269 462
+ 139: 0 -1
+ 140: 0 -1
+ 141: 0 -1
+ 142: -1657343143 68
+ 143: -1826081960 583
+ 144: 568853335 560
+ 145: 400114518 51
+ 146: 0 -1
+ 147: 0 -1
+ 148: 0 -1
+ 149: -208159918 425
+ 150: 0 -1
+ 151: -634879152 196
+ 152: 0 -1
+ 153: 1591317326 688
+ 154: 0 -1
+ 155: 1164598092 459
+ 156: 0 -1
+ 157: 0 -1
+ 158: -634270903 297
+ 159: 0 -1
+ 160: 1591925575 789
+ 161: 0 -1
+ 162: 0 -1
+ 163: 907225924 328
+ 164: 0 -1
+ 165: 0 -1
+ 166: 1941611329 594
+ 167: 0 -1
+ 168: -127159489 62
+ 169: 1165814590 661
+ 170: -1938558147 173
+ 171: 0 -1
+ 172: 0 -1
+ 173: 0 -1
+ 174: 0 -1
+ 175: -1330891976 722
+ 176: 0 -1
+ 177: 895304502 190
+ 178: 0 -1
+ 179: 1930298164 45
+ 180: -903564493 540
+ 181: -1161544910 820
+ 182: -1330283727 823
+ 183: 0 -1
+ 184: 895912751 291
+ 185: 0 -1
+ 186: 0 -1
+ 187: 211213100 854
+ 188: 0 -1
+ 189: 0 -1
+ 190: 0 -1
+ 191: 0 -1
+ 192: 2087115559 416
+ 193: 0 -1
+ 194: 1660396325 699
+ 195: 0 -1
+ 196: 0 -1
+ 197: -138472670 537
+ 198: 0 -1
+ 199: 0 -1
+ 200: 0 -1
+ 201: 0 -1
+ 202: 1403024157 56
+ 203: 1234285340 571
+ 204: 0 -1
+ 205: -1857557734 322
+ 206: -564583655 409
+ 207: 0 -1
+ 208: 0 -1
+ 209: -1442759914 413
+ 210: 0 -1
+ 211: -1869479148 184
+ 212: -408374509 167
+ 213: 0 -1
+ 214: -835093743 450
+ 215: 0 -1
+ 216: 0 -1
+ 217: 0 -1
+ 218: -1868870899 285
+ 219: 0 -1
+ 220: -665746677 548
+ 221: -834485494 39
+ 222: 0 -1
+ 223: 0 -1
+ 224: 0 -1
+ 225: 0 -1
+ 226: 707011333 582
+ 227: 0 -1
+ 228: 0 -1
+ 229: 356717314 676
+ 230: 0 -1
+ 231: -70001920 447
+ 232: 965599999 403
+ 233: 0 -1
+ 234: 0 -1
+ 235: 1729475324 710
+ 236: 357325563 777
+ 237: 0 -1
+ 238: 0 -1
+ 239: -327374088 316
+ 240: -2138164489 528
+ 241: 1898822390 808
+ 242: 1730083573 811
+ 243: 0 -1
+ 244: -1361759501 50
+ 245: -68785422 649
+ 246: 1121809137 161
+ 247: 0 -1
+ 248: 0 -1
+ 249: 0 -1
+ 250: 0 -1
+ 251: 0 -1
+ 252: 0 -1
+ 253: -339295510 178
+ 254: 0 -1
+ 255: 695698152 33
+ 256: 0 -1
+ 257: -1373072666 525
+ 258: 0 -1
+ 259: 0 -1
+ 260: -338687261 279
+ 261: 0 -1
+ 262: 0 -1
+ 263: -1023386912 842
+ 264: 0 -1
+ 265: 1202809566 310
+ 266: -1799183651 397
+ 267: 0 -1
+ 268: -596059429 660
+ 269: -764798246 151
+ 270: 425796313 687
+ 271: 0 -1
+ 272: 0 -1
+ 273: 0 -1
+ 274: -2069693739 438
+ 275: 0 -1
+ 276: 0 -1
+ 277: 426404562 788
+ 278: 168424145 44
+ 279: -314672 559
+ 280: 0 -1
+ 281: -2069085490 27
+ 282: 0 -1
+ 283: 0 -1
+ 284: 427012811 889
+ 285: 0 -1
+ 286: 0 -1
+ 287: 1190888136 172
+ 288: 0 -1
+ 289: 0 -1
+ 290: 0 -1
+ 291: -1304601916 435
+ 292: 0 -1
+ 293: 0 -1
+ 294: 1191496385 273
+ 295: 0 -1
+ 296: -877274433 765
+ 297: 0 -1
+ 298: -1303993667 24
+ 299: -1561974084 304
+ 300: 0 -1
+ 301: 0 -1
+ 302: -527588679 570
+ 303: 765385400 145
+ 304: 1698607799 38
+ 305: -1303385418 637
+ 306: 0 -1
+ 307: 0 -1
+ 308: -269000013 391
+ 309: 0 -1
+ 310: 0 -1
+ 311: 494875312 698
+ 312: 0 -1
+ 313: -1573895506 166
+ 314: 0 -1
+ 315: -538901844 21
+ 316: 922202795 516
+ 317: 0 -1
+ 318: 495483561 799
+ 319: 0 -1
+ 320: -1573287257 267
+ 321: 0 -1
+ 322: 0 -1
+ 323: 2036980388 830
+ 324: 0 -1
+ 325: 0 -1
+ 326: 238111393 156
+ 327: 0 -1
+ 328: -1830659425 648
+ 329: -1999398242 139
+ 330: -808803683 675
+ 331: 0 -1
+ 332: 0 -1
+ 333: 1687294618 513
+ 334: 0 -1
+ 335: 1260575384 284
+ 336: 0 -1
+ 337: -808195434 776
+ 338: -1066175851 32
+ 339: -1234914668 547
+ 340: 226189971 18
+ 341: -31790446 298
+ 342: 1261183633 385
+ 343: 0 -1
+ 344: -807587185 877
+ 345: 0 -1
+ 346: 0 -1
+ 347: -43711860 160
+ 348: 0 -1
+ 349: 0 -1
+ 350: 990673545 426
+ 351: 0 -1
+ 352: 1768295047 150
+ 353: 0 -1
+ 354: -43103611 261
+ 355: 0 -1
+ 356: 0 -1
+ 357: 991281794 15
+ 358: 0 -1
+ 359: 0 -1
+ 360: 0 -1
+ 361: -1504208258 278
+ 362: -1762188675 558
+ 363: -469214596 133
+ 364: 0 -1
+ 365: 0 -1
+ 366: 0 -1
+ 367: 1755765368 423
+ 368: -1503600009 379
+ 369: 0 -1
+ 370: 0 -1
+ 371: -739724684 686
+ 372: -2111874445 753
+ 373: 0 -1
+ 374: 1756373617 12
+ 375: 1498393200 292
+ 376: -312397201 504
+ 377: 0 -1
+ 378: -739116435 787
+ 379: 0 -1
+ 380: 0 -1
+ 381: 1756981866 625
+ 382: 0 -1
+ 383: 0 -1
+ 384: 0 -1
+ 385: 0 -1
+ 386: -996488603 144
+ 387: -1165227420 659
+ 388: 0 -1
+ 389: 37896802 410
+ 390: 0 -1
+ 391: -1773501856 9
+ 392: 0 -1
+ 393: 452694622 501
+ 394: 0 -1
+ 395: 25975388 272
+ 396: 1487080027 255
+ 397: 0 -1
+ 398: 1060360793 538
+ 399: 802380376 818
+ 400: -1008410025 6
+ 401: -1266390442 286
+ 402: 26583637 373
+ 403: 0 -1
+ 404: 1229707859 636
+ 405: 1060969042 127
+ 406: 0 -1
+ 407: 0 -1
+ 408: 0 -1
+ 409: 0 -1
+ 410: -243926451 414
+ 411: 0 -1
+ 412: 0 -1
+ 413: -2042795446 764
+ 414: 0 -1
+ 415: 1825452616 535
+ 416: 0 -1
+ 417: -243318202 3
+ 418: 0 -1
+ 419: 0 -1
+ 420: -2042187197 865
+ 421: 0 -1
+ 422: 0 -1
+ 423: 1568080448 404
+ 424: 0 -1
+ 425: -500690370 896
+ 426: -669429187 899
+ 427: 0 -1
+ 428: 533695035 138
+ 429: 0 -1
+ 430: -1277703623 249
+ 431: 0 -1
+ 432: 948492855 741
+ 433: 0 -1
+ 434: 0 -1
+ 435: 0 -1
+ 436: 0 -1
+ 437: 1556159026 266
+ 438: 1298178609 546
+ 439: -1703814608 121
+ 440: 0 -1
+ 441: 522381870 613
+ 442: 0 -1
+ 443: 0 -1
+ 444: 1556767275 367
+ 445: 0 -1
+ 446: 0 -1
+ 447: -1974324696 674
+ 448: 0 -1
+ 449: -1196703194 398
+ 450: 0 -1
+ 451: 0 -1
+ 452: -1546997213 492
+ 453: 0 -1
+ 454: -1973716447 775
+ 455: 0 -1
+ 456: 252480031 243
+ 457: 0 -1
+ 458: -174239203 526
+ 459: -432219620 806
+ 460: 0 -1
+ 461: 0 -1
+ 462: 2063878681 132
+ 463: 1895139864 647
+ 464: -4892137 624
+ 465: -173630954 115
+ 466: 0 -1
+ 467: 0 -1
+ 468: 0 -1
+ 469: -781905390 489
+ 470: 0 -1
+ 471: -1208624624 260
+ 472: 0 -1
+ 473: 1017571854 752
+ 474: 0 -1
+ 475: 590852620 523
+ 476: 0 -1
+ 477: 0 -1
+ 478: -1208016375 361
+ 479: 0 -1
+ 480: 1018180103 853
+ 481: 0 -1
+ 482: 0 -1
+ 483: 333480452 392
+ 484: 0 -1
+ 485: 0 -1
+ 486: 1367865857 658
+ 487: 0 -1
+ 488: -700904961 126
+ 489: 0 -1
+ 490: 1782663677 237
+ 491: 0 -1
+ 492: 0 -1
+ 493: 0 -1
+ 494: 0 -1
+ 495: -1904637448 786
+ 496: 0 -1
+ 497: 321559030 254
+ 498: 0 -1
+ 499: 1356552692 109
+ 500: 0 -1
+ 501: -1735290382 884
+ 502: -1904029199 887
+ 503: 0 -1
+ 504: 322167279 355
+ 505: 0 -1
+ 506: 0 -1
+ 507: 0 -1
+ 508: -286107157 729
+ 509: 0 -1
+ 510: 0 -1
+ 511: 0 -1
+ 512: 1513370087 480
+ 513: 0 -1
+ 514: 1086650853 763
+ 515: 0 -1
+ 516: 0 -1
+ 517: -712218142 601
+ 518: 0 -1
+ 519: 0 -1
+ 520: 0 -1
+ 521: 0 -1
+ 522: 829278685 120
+ 523: 660539868 635
+ 524: 0 -1
+ 525: 1863664090 386
+ 526: 0 -1
+ 527: 0 -1
+ 528: 0 -1
+ 529: -2016505386 477
+ 530: 0 -1
+ 531: 1851742676 248
+ 532: -982119981 231
+ 533: 0 -1
+ 534: -1408839215 514
+ 535: 0 -1
+ 536: 0 -1
+ 537: 0 -1
+ 538: 1852350925 349
+ 539: 0 -1
+ 540: -1239492149 612
+ 541: -1408230966 103
+ 542: 0 -1
+ 543: 0 -1
+ 544: 0 -1
+ 545: 0 -1
+ 546: 133265861 646
+ 547: 0 -1
+ 548: 0 -1
+ 549: -217028158 740
+ 550: 0 -1
+ 551: -643747392 511
+ 552: 0 -1
+ 553: 0 -1
+ 554: 0 -1
+ 555: 1155729852 774
+ 556: -216419909 841
+ 557: 0 -1
+ 558: 0 -1
+ 559: -901119560 380
+ 560: 0 -1
+ 561: 1325076918 872
+ 562: 1156338101 875
+ 563: 0 -1
+ 564: -1935504973 114
+ 565: 0 -1
+ 566: 548063665 225
+ 567: 0 -1
+ 568: -1520707153 717
+ 569: 0 -1
+ 570: 0 -1
+ 571: 0 -1
+ 572: 0 -1
+ 573: -913040982 242
+ 574: 0 -1
+ 575: 121952680 97
+ 576: 0 -1
+ 577: -1946818138 589
+ 578: 0 -1
+ 579: 0 -1
+ 580: -912432733 343
+ 581: 0 -1
+ 582: 0 -1
+ 583: 0 -1
+ 584: 0 -1
+ 585: 629064094 374
+ 586: 0 -1
+ 587: 0 -1
+ 588: 278770075 468
+ 589: 0 -1
+ 590: -147949159 751
+ 591: 0 -1
+ 592: 2078247319 219
+ 593: 0 -1
+ 594: 1651528085 502
+ 595: 0 -1
+ 596: 0 -1
+ 597: 0 -1
+ 598: -405321327 108
+ 599: -574060144 623
+ 600: 1820875151 600
+ 601: 1652136334 91
+ 602: 0 -1
+ 603: 0 -1
+ 604: 0 -1
+ 605: 1043861898 465
+ 606: 0 -1
+ 607: 617142664 236
+ 608: 0 -1
+ 609: -1451628154 728
+ 610: 0 -1
+ 611: -1878347388 499
+ 612: 0 -1
+ 613: 0 -1
+ 614: 617750913 337
+ 615: 0 -1
+ 616: -1451019905 829
+ 617: 0 -1
+ 618: 0 -1
+ 619: -2135719556 368
+ 620: 0 -1
+ 621: 0 -1
+ 622: -1101334151 634
+ 623: 0 -1
+ 624: 1124862327 102
+ 625: 0 -1
+ 626: -686536331 213
+ 627: 0 -1
+ 628: 0 -1
+ 629: 0 -1
+ 630: 0 -1
+ 631: -78870160 762
+ 632: 0 -1
+ 633: 2147326318 230
+ 634: 0 -1
+ 635: -1112647316 85
+ 636: 0 -1
+ 637: 90476906 860
+ 638: -78261911 863
+ 639: 0 -1
+ 640: -2147032729 331
+ 641: 0 -1
+ 642: 0 -1
+ 643: 1463234916 894
+ 644: 1539660131 705
+ 645: 0 -1
+ 646: 0 -1
+ 647: 0 -1
+ 648: -955829921 456
+ 649: 0 -1
+ 650: -1382549155 739
+ 651: 0 -1
+ 652: 0 -1
+ 653: 1113549146 577
+ 654: 0 -1
+ 655: 0 -1
+ 656: 0 -1
+ 657: 0 -1
+ 658: -1639921323 96
+ 659: -1808660140 611
+ 660: 0 -1
+ 661: -605535918 362
+ 662: 0 -1
+ 663: 0 -1
+ 664: 0 -1
+ 665: -190738098 453
+ 666: 0 -1
+ 667: -617457332 224
+ 668: 843647307 207
+ 669: 0 -1
+ 670: 416928073 490
+ 671: 0 -1
+ 672: 0 -1
+ 673: 0 -1
+ 674: -616849083 325
+ 675: 0 -1
+ 676: 586275139 588
+ 677: 417536322 79
+ 678: 0 -1
+ 679: 0 -1
+ 680: 0 -1
+ 681: 0 -1
+ 682: 1959033149 622
+ 683: 0 -1
+ 684: 0 -1
+ 685: 1608739130 716
+ 686: 0 -1
+ 687: 1182019896 487
+ 688: 0 -1
+ 689: 0 -1
+ 690: 0 -1
+ 691: -1313470156 750
+ 692: 1609347379 817
+ 693: 0 -1
+ 694: 0 -1
+ 695: 924647728 356
+ 696: 0 -1
+ 697: -1144123090 848
+ 698: -1312861907 851
+ 699: 0 -1
+ 700: -109737685 90
+ 701: 0 -1
+ 702: -1921136343 201
+ 703: 0 -1
+ 704: 305060135 693
+ 705: 0 -1
+ 706: 0 -1
+ 707: 0 -1
+ 708: 0 -1
+ 709: 912726306 218
+ 710: 0 -1
+ 711: 1947719968 73
+ 712: 0 -1
+ 713: -121050850 565
+ 714: 0 -1
+ 715: 0 -1
+ 716: 913334555 319
+ 717: 0 -1
+ 718: 0 -1
+ 719: 228634904 882
+ 720: 0 -1
+ 721: -1840135914 350
+ 722: 0 -1
+ 723: 0 -1
+ 724: 2104537363 444
+ 725: 0 -1
+ 726: 1677818129 727
+ 727: 0 -1
+ 728: -390952689 195
+ 729: 0 -1
+ 730: -817671923 478
+ 731: 0 -1
+ 732: 0 -1
+ 733: 0 -1
+ 734: 1420445961 84
+ 735: 1251707144 599
+ 736: -648324857 576
+ 737: -817063674 67
+ 738: 0 -1
+ 739: 0 -1
+ 740: 0 -1
+ 741: -1425338110 441
+ 742: 0 -1
+ 743: -1852057344 212
+ 744: 0 -1
+ 745: 374139134 704
+ 746: 0 -1
+ 747: -52580100 475
+ 748: 0 -1
+ 749: 0 -1
+ 750: -1851449095 313
+ 751: 0 -1
+ 752: 374747383 805
+ 753: 0 -1
+ 754: 0 -1
+ 755: -309952268 344
+ 756: 0 -1
+ 757: 0 -1
+ 758: 724433137 610
+ 759: 0 -1
+ 760: -1344337681 78
+ 761: 0 -1
+ 762: 1139230957 189
+ 763: 0 -1
+ 764: 0 -1
+ 765: 0 -1
+ 766: 0 -1
+ 767: 1746897128 738
+ 768: 0 -1
+ 769: -321873690 206
+ 770: 0 -1
+ 771: 713119972 61
+ 772: 0 -1
+ 773: 1916244194 836
+ 774: 1747505377 839
+ 775: 0 -1
+ 776: -321265441 307
+ 777: 0 -1
+ 778: 0 -1
+ 779: -1005965092 870
+ 780: -929539877 681
+ 781: 0 -1
+ 782: 0 -1
+ 783: 0 -1
+ 784: 869937367 432
+ 785: 0 -1
+ 786: 443218133 715
+ 787: 0 -1
+ 788: 0 -1
+ 789: -1355650862 553
+ 790: 0 -1
+ 791: 0 -1
+ 792: 0 -1
+ 793: 0 -1
+ 794: 185845965 72
+ 795: 17107148 587
+ 796: 0 -1
+ 797: 1220231370 338
+ 798: 0 -1
+ 799: 0 -1
+ 800: 0 -1
+ 801: 1635029190 429
+ 802: 0 -1
+ 803: 1208309956 200
+ 804: -1625552701 183
+ 805: 0 -1
+ 806: -2052271935 466
+ 807: 0 -1
+ 808: 0 -1
+ 809: 0 -1
+ 810: 1208918205 301
+ 811: 0 -1
+ 812: -1882924869 564
+ 813: -2051663686 55
+ 814: 0 -1
+ 815: 0 -1
+ 816: 0 -1
+ 817: 0 -1
+ 818: -510166859 598
+ 819: 0 -1
+ 820: 0 -1
+ 821: -860460878 692
+ 822: 0 -1
+ 823: -1287180112 463
+ 824: 0 -1
+ 825: 0 -1
+ 826: 0 -1
+ 827: 512297132 726
+ 828: -859852629 793
+ 829: 0 -1
+ 830: 0 -1
+ 831: -1544552280 332
+ 832: 0 -1
+ 833: 681644198 824
+ 834: 512905381 827
+ 835: 0 -1
+ 836: 1716029603 66
+ 837: -1285963614 665
+ 838: -95369055 177
+ 839: 0 -1
+ 840: 2130827423 669
+ 841: 0 -1
+ 842: 0 -1
+ 843: 0 -1
+ 844: 0 -1
+ 845: -1556473702 194
+ 846: 0 -1
+ 847: -521480040 49
+ 848: 0 -1
+ 849: 1704716438 541
+ 850: 0 -1
+ 851: 0 -1
+ 852: -1555865453 295
+ 853: 0 -1
+ 854: 0 -1
+ 855: 2054402192 858
+ 856: 0 -1
+ 857: -14368626 326
+ 858: 0 -1
+ 859: 0 -1
+ 860: -364662645 420
+ 861: 0 -1
+ 862: -791381879 703
+ 863: 0 -1
+ 864: 1434814599 171
+ 865: 0 -1
+ 866: 1008095365 454
+ 867: 0 -1
+ 868: 0 -1
+ 869: 0 -1
+ 870: -1048754047 60
+ 871: -1217492864 575
+ 872: 1177442431 552
+ 873: 1008703614 43
+ 874: 0 -1
+ 875: 0 -1
+ 876: 0 -1
+ 877: 400429178 417
+ 878: 0 -1
+ 879: -26290056 188
+ 880: 0 -1
+ 881: -2095060874 680
+ 882: 0 -1
+ 883: 1773187188 451
+ 884: 0 -1
+ 885: 0 -1
+ 886: -25681807 289
+ 887: 0 -1
+ 888: -2094452625 781
+ 889: 0 -1
+ 890: 0 -1
+ 891: 1515815020 320
+ 892: 0 -1
+ 893: 0 -1
+ 894: -1744766871 586
+ 895: 0 -1
+ 896: 481429607 54
+ 897: 1774403686 653
+ 898: -1329969051 165
+ 899: 0 -1
+ 900: -1486178205 407
+ 901: 0 -1
+ 902: 0 -1
+ 903: -722302880 714
+ 904: 0 -1
+ 905: 1503893598 182
+ 906: 0 -1
+ 907: -1756080036 37
+ 908: -294975397 532
+ 909: -552955814 812
+ 910: -721694631 815
+ 911: 0 -1
+ 912: 1504501847 283
+ 913: 0 -1
+ 914: 0 -1
+ 915: 819802196 846
+ 916: 0 -1
+ 917: 0 -1
+ 918: 0 -1
+ 919: 0 -1
+ 920: 1247129679 664
+ 921: 1078390862 155
+ 922: -2025981875 691
+ 923: 0 -1
+ 924: 0 -1
+ 925: 470116426 529
+ 926: 0 -1
+ 927: 0 -1
+ 928: 0 -1
+ 929: -2025373626 792
+ 930: 2011613253 48
+ 931: 1842874436 563
+ 932: 0 -1
+ 933: -1248968638 314
+ 934: 44005441 401
+ 935: 0 -1
+ 936: -2024765377 893
+ 937: 0 -1
+ 938: 0 -1
+ 939: -1260890052 176
+ 940: 200214587 159
+ 941: 0 -1
+ 942: -226504647 442
+ 943: 0 -1
+ 944: 0 -1
+ 945: 0 -1
+ 946: -1260281803 277
+ 947: 0 -1
+ 948: 0 -1
+ 949: -225896398 31
+ 950: 0 -1
+ 951: 0 -1
+ 952: 0 -1
+ 953: 0 -1
+ 954: 1315600429 574
+ 955: -1686392788 149
+ 956: 0 -1
+ 957: 0 -1
+ 958: 0 -1
+ 959: 538587176 439
+ 960: 1574189095 395
+ 961: 0 -1
+ 962: 0 -1
+ 963: -1956902876 702
+ 964: 965914659 769
+ 965: 0 -1
+ 966: 539195425 28
+ 967: 281215008 308
+ 968: -1529575393 520
+ 969: -1787555810 800
+ 970: -1956294627 803
+ 971: 0 -1
+ 972: -753170405 42
+ 973: 539803674 641
+ 974: 0 -1
+ 975: 0 -1
+ 976: 0 -1
+ 977: 0 -1
+ 978: 0 -1
+ 979: 0 -1
+ 980: 0 -1
+ 981: 269293586 170
+ 982: 0 -1
+ 983: 1304287248 25
+ 984: 0 -1
+ 985: -764483570 517
+ 986: 0 -1
+ 987: 0 -1
+ 988: 269901835 271
+ 989: 0 -1
+ 990: 0 -1
+ 991: -414797816 834
+ 992: 2069379079 22
+ 993: 1811398662 302
+ 994: -1190594555 389
+ 995: 0 -1
+ 996: 12529667 652
+ 997: -156209150 143
+ 998: 1034385409 679
+ 999: 0 -1
+ 1000: 2053 0
+ 3: subview '_B'
+ VIEW 2 rows = _H:I _R:I
+ 0: 0 -1
+ 1: 0 -1
diff --git a/akregator/src/mk4storage/metakit/tests/ok/m07.txt b/akregator/src/mk4storage/metakit/tests/ok/m07.txt
new file mode 100644
index 000000000..aac9208cf
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/m07.txt
@@ -0,0 +1,63 @@
+>>> All blocked view multi-deletion cases
+blockdel pos 0 len 1
+blockdel pos 0 len 2
+blockdel pos 0 len 3
+blockdel pos 0 len 998
+blockdel pos 0 len 999
+blockdel pos 0 len 1000
+blockdel pos 0 len 1001
+blockdel pos 0 len 1998
+blockdel pos 0 len 1999
+blockdel pos 0 len 2000
+blockdel pos 0 len 2001
+blockdel pos 1 len 1
+blockdel pos 1 len 2
+blockdel pos 1 len 3
+blockdel pos 1 len 998
+blockdel pos 1 len 999
+blockdel pos 1 len 1000
+blockdel pos 1 len 1001
+blockdel pos 1 len 1998
+blockdel pos 1 len 1999
+blockdel pos 1 len 2000
+blockdel pos 1 len 2001
+blockdel pos 998 len 1
+blockdel pos 998 len 2
+blockdel pos 998 len 3
+blockdel pos 998 len 998
+blockdel pos 998 len 999
+blockdel pos 998 len 1000
+blockdel pos 998 len 1001
+blockdel pos 999 len 1
+blockdel pos 999 len 2
+blockdel pos 999 len 3
+blockdel pos 999 len 998
+blockdel pos 999 len 999
+blockdel pos 999 len 1000
+blockdel pos 999 len 1001
+blockdel pos 1000 len 1
+blockdel pos 1000 len 2
+blockdel pos 1000 len 3
+blockdel pos 1000 len 998
+blockdel pos 1000 len 999
+blockdel pos 1000 len 1000
+blockdel pos 1000 len 1001
+blockdel pos 1001 len 1
+blockdel pos 1001 len 2
+blockdel pos 1001 len 3
+blockdel pos 1001 len 998
+blockdel pos 1001 len 999
+blockdel pos 1001 len 1000
+blockdel pos 1001 len 1001
+blockdel pos 2998 len 1
+blockdel pos 2997 len 2
+blockdel pos 2996 len 3
+blockdel pos 2001 len 998
+blockdel pos 2000 len 999
+blockdel pos 1999 len 1000
+blockdel pos 1998 len 1001
+blockdel pos 1001 len 1998
+blockdel pos 1000 len 1999
+blockdel pos 999 len 2000
+blockdel pos 998 len 2001
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/n01.txt b/akregator/src/mk4storage/metakit/tests/ok/n01.txt
new file mode 100644
index 000000000..28b19811f
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/n01.txt
@@ -0,0 +1,2 @@
+>>> Add to selection
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/n02.txt b/akregator/src/mk4storage/metakit/tests/ok/n02.txt
new file mode 100644
index 000000000..a912aae04
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/n02.txt
@@ -0,0 +1,2 @@
+>>> Remove from selection
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/n03.txt b/akregator/src/mk4storage/metakit/tests/ok/n03.txt
new file mode 100644
index 000000000..5934324cc
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/n03.txt
@@ -0,0 +1,2 @@
+>>> Modify into selection
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/n04.txt b/akregator/src/mk4storage/metakit/tests/ok/n04.txt
new file mode 100644
index 000000000..efb96017d
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/n04.txt
@@ -0,0 +1,2 @@
+>>> Modify out of selection
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/n05.txt b/akregator/src/mk4storage/metakit/tests/ok/n05.txt
new file mode 100644
index 000000000..bc40bea33
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/n05.txt
@@ -0,0 +1,2 @@
+>>> Add to sorted
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/n06.txt b/akregator/src/mk4storage/metakit/tests/ok/n06.txt
new file mode 100644
index 000000000..f8c499a53
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/n06.txt
@@ -0,0 +1,2 @@
+>>> Remove from sorted
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/n07.txt b/akregator/src/mk4storage/metakit/tests/ok/n07.txt
new file mode 100644
index 000000000..87ff41217
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/n07.txt
@@ -0,0 +1,2 @@
+>>> New property through sort
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/n08.txt b/akregator/src/mk4storage/metakit/tests/ok/n08.txt
new file mode 100644
index 000000000..0939301c6
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/n08.txt
@@ -0,0 +1,2 @@
+>>> Nested project and select
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/n09.txt b/akregator/src/mk4storage/metakit/tests/ok/n09.txt
new file mode 100644
index 000000000..0732f4208
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/n09.txt
@@ -0,0 +1,2 @@
+>>> Multiple dependencies
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/n10.txt b/akregator/src/mk4storage/metakit/tests/ok/n10.txt
new file mode 100644
index 000000000..8c1f92ded
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/n10.txt
@@ -0,0 +1,2 @@
+>>> Modify sorted duplicates
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/n11.txt b/akregator/src/mk4storage/metakit/tests/ok/n11.txt
new file mode 100644
index 000000000..07d6ebddf
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/n11.txt
@@ -0,0 +1,2 @@
+>>> Resize compound derived view
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/n12.txt b/akregator/src/mk4storage/metakit/tests/ok/n12.txt
new file mode 100644
index 000000000..fa194393d
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/n12.txt
@@ -0,0 +1,2 @@
+>>> Alter multiply derived view
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/n13.txt b/akregator/src/mk4storage/metakit/tests/ok/n13.txt
new file mode 100644
index 000000000..e9ba290d1
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/n13.txt
@@ -0,0 +1,2 @@
+>>> Project without
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/n14.txt b/akregator/src/mk4storage/metakit/tests/ok/n14.txt
new file mode 100644
index 000000000..2522115e5
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/n14.txt
@@ -0,0 +1,2 @@
+>>> Insert in non-mapped position
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/n14a.txt b/akregator/src/mk4storage/metakit/tests/ok/n14a.txt
new file mode 100644
index 000000000..ef5e47ac5
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/n14a.txt
@@ -0,0 +1,15 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 12 rows = p1:I
+ 0: 0
+ 1: 1
+ 2: 2
+ 3: 6
+ 4: 0
+ 5: 1
+ 6: 2
+ 7: 1
+ 8: 0
+ 9: 1
+ 10: 2
+ 11: 0
diff --git a/akregator/src/mk4storage/metakit/tests/ok/r00.txt b/akregator/src/mk4storage/metakit/tests/ok/r00.txt
new file mode 100644
index 000000000..c2dd0e8c5
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/r00.txt
@@ -0,0 +1,2 @@
+>>> Simple insert
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/r00a.txt b/akregator/src/mk4storage/metakit/tests/ok/r00a.txt
new file mode 100644
index 000000000..16475db59
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/r00a.txt
@@ -0,0 +1,253 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 250 rows = p1:I
+ 0: 1
+ 1: 2
+ 2: 3
+ 3: 4
+ 4: 5
+ 5: 6
+ 6: 7
+ 7: 8
+ 8: 9
+ 9: 10
+ 10: 11
+ 11: 12
+ 12: 13
+ 13: 14
+ 14: 15
+ 15: 16
+ 16: 17
+ 17: 18
+ 18: 19
+ 19: 20
+ 20: 21
+ 21: 22
+ 22: 23
+ 23: 24
+ 24: 25
+ 25: 26
+ 26: 27
+ 27: 28
+ 28: 29
+ 29: 30
+ 30: 31
+ 31: 32
+ 32: 33
+ 33: 34
+ 34: 35
+ 35: 36
+ 36: 37
+ 37: 38
+ 38: 39
+ 39: 40
+ 40: 41
+ 41: 42
+ 42: 43
+ 43: 44
+ 44: 45
+ 45: 46
+ 46: 47
+ 47: 48
+ 48: 49
+ 49: 50
+ 50: 51
+ 51: 52
+ 52: 53
+ 53: 54
+ 54: 55
+ 55: 56
+ 56: 57
+ 57: 58
+ 58: 59
+ 59: 60
+ 60: 61
+ 61: 62
+ 62: 63
+ 63: 64
+ 64: 65
+ 65: 66
+ 66: 67
+ 67: 68
+ 68: 69
+ 69: 70
+ 70: 71
+ 71: 72
+ 72: 73
+ 73: 74
+ 74: 75
+ 75: 76
+ 76: 77
+ 77: 78
+ 78: 79
+ 79: 80
+ 80: 81
+ 81: 82
+ 82: 83
+ 83: 84
+ 84: 85
+ 85: 86
+ 86: 87
+ 87: 88
+ 88: 89
+ 89: 90
+ 90: 91
+ 91: 92
+ 92: 93
+ 93: 94
+ 94: 95
+ 95: 96
+ 96: 97
+ 97: 98
+ 98: 99
+ 99: 100
+ 100: 101
+ 101: 102
+ 102: 103
+ 103: 104
+ 104: 105
+ 105: 106
+ 106: 107
+ 107: 108
+ 108: 109
+ 109: 110
+ 110: 111
+ 111: 112
+ 112: 113
+ 113: 114
+ 114: 115
+ 115: 116
+ 116: 117
+ 117: 118
+ 118: 119
+ 119: 120
+ 120: 121
+ 121: 122
+ 122: 123
+ 123: 1
+ 124: 2
+ 125: 3
+ 126: 4
+ 127: 5
+ 128: 6
+ 129: 7
+ 130: 8
+ 131: 9
+ 132: 10
+ 133: 11
+ 134: 12
+ 135: 13
+ 136: 14
+ 137: 15
+ 138: 16
+ 139: 17
+ 140: 18
+ 141: 19
+ 142: 20
+ 143: 21
+ 144: 22
+ 145: 23
+ 146: 24
+ 147: 25
+ 148: 26
+ 149: 27
+ 150: 28
+ 151: 29
+ 152: 30
+ 153: 31
+ 154: 32
+ 155: 33
+ 156: 34
+ 157: 35
+ 158: 36
+ 159: 37
+ 160: 38
+ 161: 39
+ 162: 40
+ 163: 41
+ 164: 42
+ 165: 43
+ 166: 44
+ 167: 45
+ 168: 46
+ 169: 47
+ 170: 48
+ 171: 49
+ 172: 50
+ 173: 51
+ 174: 52
+ 175: 53
+ 176: 54
+ 177: 55
+ 178: 56
+ 179: 57
+ 180: 58
+ 181: 59
+ 182: 60
+ 183: 61
+ 184: 62
+ 185: 63
+ 186: 64
+ 187: 65
+ 188: 66
+ 189: 67
+ 190: 68
+ 191: 69
+ 192: 70
+ 193: 71
+ 194: 72
+ 195: 73
+ 196: 74
+ 197: 75
+ 198: 76
+ 199: 77
+ 200: 78
+ 201: 79
+ 202: 80
+ 203: 81
+ 204: 82
+ 205: 83
+ 206: 84
+ 207: 85
+ 208: 86
+ 209: 87
+ 210: 88
+ 211: 89
+ 212: 90
+ 213: 91
+ 214: 92
+ 215: 93
+ 216: 94
+ 217: 95
+ 218: 96
+ 219: 97
+ 220: 98
+ 221: 99
+ 222: 100
+ 223: 101
+ 224: 102
+ 225: 103
+ 226: 104
+ 227: 105
+ 228: 106
+ 229: 107
+ 230: 108
+ 231: 109
+ 232: 110
+ 233: 111
+ 234: 112
+ 235: 113
+ 236: 114
+ 237: 115
+ 238: 116
+ 239: 117
+ 240: 118
+ 241: 119
+ 242: 120
+ 243: 121
+ 244: 122
+ 245: 123
+ 246: 1
+ 247: 2
+ 248: 3
+ 249: 4
diff --git a/akregator/src/mk4storage/metakit/tests/ok/r01.txt b/akregator/src/mk4storage/metakit/tests/ok/r01.txt
new file mode 100644
index 000000000..092f02ca2
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/r01.txt
@@ -0,0 +1,2 @@
+>>> Simple removes
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/r01a.txt b/akregator/src/mk4storage/metakit/tests/ok/r01a.txt
new file mode 100644
index 000000000..65a6851c8
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/r01a.txt
@@ -0,0 +1,18 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 15 rows = p1:I
+ 0: 9
+ 1: 10
+ 2: 11
+ 3: 12
+ 4: 13
+ 5: 14
+ 6: 15
+ 7: 16
+ 8: 17
+ 9: 18
+ 10: 19
+ 11: 20
+ 12: 21
+ 13: 22
+ 14: 23
diff --git a/akregator/src/mk4storage/metakit/tests/ok/r02.txt b/akregator/src/mk4storage/metakit/tests/ok/r02.txt
new file mode 100644
index 000000000..9f5b549a9
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/r02.txt
@@ -0,0 +1,2 @@
+>>> Large inserts and removes
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/r02a.txt b/akregator/src/mk4storage/metakit/tests/ok/r02a.txt
new file mode 100644
index 000000000..c86766a9c
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/r02a.txt
@@ -0,0 +1,8 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 5 rows = p1:I
+ 0: 37
+ 1: 38
+ 2: 39
+ 3: 95
+ 4: 96
diff --git a/akregator/src/mk4storage/metakit/tests/ok/r03.txt b/akregator/src/mk4storage/metakit/tests/ok/r03.txt
new file mode 100644
index 000000000..34f35e910
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/r03.txt
@@ -0,0 +1,2 @@
+>>> Binary property insertions
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/r03a.txt b/akregator/src/mk4storage/metakit/tests/ok/r03a.txt
new file mode 100644
index 000000000..a99e46af8
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/r03a.txt
@@ -0,0 +1,8 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 5 rows = p1:B
+ 0: (1024b)
+ 1: (256b)
+ 2: (1024b)
+ 3: (1024b)
+ 4: (341b)
diff --git a/akregator/src/mk4storage/metakit/tests/ok/r04.txt b/akregator/src/mk4storage/metakit/tests/ok/r04.txt
new file mode 100644
index 000000000..60404b776
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/r04.txt
@@ -0,0 +1,2 @@
+>>> Scripted string property tests
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/r04a.txt b/akregator/src/mk4storage/metakit/tests/ok/r04a.txt
new file mode 100644
index 000000000..88ad82637
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/r04a.txt
@@ -0,0 +1,3 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 0 rows = p1:S
diff --git a/akregator/src/mk4storage/metakit/tests/ok/reversed.txt b/akregator/src/mk4storage/metakit/tests/ok/reversed.txt
new file mode 100644
index 000000000..59ba292d4
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/reversed.txt
@@ -0,0 +1,14 @@
+ VIEW 1 rows = address:V info:V
+ 0: subview 'address'
+ VIEW 8 rows = name:S country:S age:I
+ 0: 'John Williams' 'UK' 0
+ 1: 'Paco Pena' 'Spain' 44
+ 2: 'Julian Bream' '' 50
+ 3: 'Julian Bream' '' 0
+ 4: 'Julien Coco' 'Netherlands' 0
+ 5: 'John Williams' 'UK' 0
+ 6: 'Paco Pena' 'Spain' 0
+ 7: 'Julien Coco' 'Netherlands' 0
+ 0: subview 'info'
+ VIEW 1 rows = version:I
+ 0: 100
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s00.txt b/akregator/src/mk4storage/metakit/tests/ok/s00.txt
new file mode 100644
index 000000000..24df9e24a
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s00.txt
@@ -0,0 +1,2 @@
+>>> Simple storage
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s00a.txt b/akregator/src/mk4storage/metakit/tests/ok/s00a.txt
new file mode 100644
index 000000000..0872f9361
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s00a.txt
@@ -0,0 +1,3 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 0 rows = p1:I
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s01.txt b/akregator/src/mk4storage/metakit/tests/ok/s01.txt
new file mode 100644
index 000000000..b5d474170
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s01.txt
@@ -0,0 +1,2 @@
+>>> Integer storage
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s01a.txt b/akregator/src/mk4storage/metakit/tests/ok/s01a.txt
new file mode 100644
index 000000000..b393bf251
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s01a.txt
@@ -0,0 +1,6 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 3 rows = p1:I
+ 0: 123
+ 1: 789
+ 2: 456
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s02.txt b/akregator/src/mk4storage/metakit/tests/ok/s02.txt
new file mode 100644
index 000000000..7ec87fa82
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s02.txt
@@ -0,0 +1,2 @@
+>>> Float storage
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s02a.txt b/akregator/src/mk4storage/metakit/tests/ok/s02a.txt
new file mode 100644
index 000000000..6a561a53e
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s02a.txt
@@ -0,0 +1,6 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 3 rows = p1:F
+ 0: 12.3
+ 1: 78.9
+ 2: 45.6
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s03.txt b/akregator/src/mk4storage/metakit/tests/ok/s03.txt
new file mode 100644
index 000000000..307fb2a61
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s03.txt
@@ -0,0 +1,2 @@
+>>> String storage
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s03a.txt b/akregator/src/mk4storage/metakit/tests/ok/s03a.txt
new file mode 100644
index 000000000..83b694645
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s03a.txt
@@ -0,0 +1,6 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 3 rows = p1:S
+ 0: 'one'
+ 1: 'three'
+ 2: 'two'
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s04.txt b/akregator/src/mk4storage/metakit/tests/ok/s04.txt
new file mode 100644
index 000000000..2a6472b6f
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s04.txt
@@ -0,0 +1,2 @@
+>>> View storage
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s04a.txt b/akregator/src/mk4storage/metakit/tests/ok/s04a.txt
new file mode 100644
index 000000000..2b6800f31
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s04a.txt
@@ -0,0 +1,18 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 3 rows = p1:S p2:V
+ 0: 'one'
+ 0: subview 'p2'
+ VIEW 1 rows = p3:I
+ 0: 1
+ 1: 'three'
+ 1: subview 'p2'
+ VIEW 3 rows = p3:I
+ 0: 111
+ 1: 222
+ 2: 333
+ 2: 'two'
+ 2: subview 'p2'
+ VIEW 2 rows = p3:I
+ 0: 11
+ 1: 22
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s05.txt b/akregator/src/mk4storage/metakit/tests/ok/s05.txt
new file mode 100644
index 000000000..625769c15
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s05.txt
@@ -0,0 +1,2 @@
+>>> Store and reload
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s05a.txt b/akregator/src/mk4storage/metakit/tests/ok/s05a.txt
new file mode 100644
index 000000000..fb8a3f195
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s05a.txt
@@ -0,0 +1,4 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 1 rows = p1:I
+ 0: 123
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s06.txt b/akregator/src/mk4storage/metakit/tests/ok/s06.txt
new file mode 100644
index 000000000..6246a4721
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s06.txt
@@ -0,0 +1,2 @@
+>>> Commit twice
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s06a.txt b/akregator/src/mk4storage/metakit/tests/ok/s06a.txt
new file mode 100644
index 000000000..5688100e0
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s06a.txt
@@ -0,0 +1,5 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 2 rows = p1:I
+ 0: 123
+ 1: 234
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s07.txt b/akregator/src/mk4storage/metakit/tests/ok/s07.txt
new file mode 100644
index 000000000..93559f6fe
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s07.txt
@@ -0,0 +1,2 @@
+>>> Commit modified
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s07a.txt b/akregator/src/mk4storage/metakit/tests/ok/s07a.txt
new file mode 100644
index 000000000..80140cf7f
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s07a.txt
@@ -0,0 +1,4 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 1 rows = p1:I
+ 0: 234
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s08.txt b/akregator/src/mk4storage/metakit/tests/ok/s08.txt
new file mode 100644
index 000000000..cd8f89711
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s08.txt
@@ -0,0 +1,2 @@
+>>> View after storage
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s08a.txt b/akregator/src/mk4storage/metakit/tests/ok/s08a.txt
new file mode 100644
index 000000000..fb8a3f195
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s08a.txt
@@ -0,0 +1,4 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 1 rows = p1:I
+ 0: 123
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s09.txt b/akregator/src/mk4storage/metakit/tests/ok/s09.txt
new file mode 100644
index 000000000..9599ae19e
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s09.txt
@@ -0,0 +1,2 @@
+>>> Copy storage
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s09a.txt b/akregator/src/mk4storage/metakit/tests/ok/s09a.txt
new file mode 100644
index 000000000..fb8a3f195
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s09a.txt
@@ -0,0 +1,4 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 1 rows = p1:I
+ 0: 123
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s09b.txt b/akregator/src/mk4storage/metakit/tests/ok/s09b.txt
new file mode 100644
index 000000000..fb8a3f195
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s09b.txt
@@ -0,0 +1,4 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 1 rows = p1:I
+ 0: 123
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s10.txt b/akregator/src/mk4storage/metakit/tests/ok/s10.txt
new file mode 100644
index 000000000..03f9bed9b
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s10.txt
@@ -0,0 +1,2 @@
+>>> Stream storage
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s10a.txt b/akregator/src/mk4storage/metakit/tests/ok/s10a.txt
new file mode 100644
index 000000000..2b6800f31
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s10a.txt
@@ -0,0 +1,18 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 3 rows = p1:S p2:V
+ 0: 'one'
+ 0: subview 'p2'
+ VIEW 1 rows = p3:I
+ 0: 1
+ 1: 'three'
+ 1: subview 'p2'
+ VIEW 3 rows = p3:I
+ 0: 111
+ 1: 222
+ 2: 333
+ 2: 'two'
+ 2: subview 'p2'
+ VIEW 2 rows = p3:I
+ 0: 11
+ 1: 22
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s10b.txt b/akregator/src/mk4storage/metakit/tests/ok/s10b.txt
new file mode 100644
index 000000000..2b6800f31
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s10b.txt
@@ -0,0 +1,18 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 3 rows = p1:S p2:V
+ 0: 'one'
+ 0: subview 'p2'
+ VIEW 1 rows = p3:I
+ 0: 1
+ 1: 'three'
+ 1: subview 'p2'
+ VIEW 3 rows = p3:I
+ 0: 111
+ 1: 222
+ 2: 333
+ 2: 'two'
+ 2: subview 'p2'
+ VIEW 2 rows = p3:I
+ 0: 11
+ 1: 22
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s10c.txt b/akregator/src/mk4storage/metakit/tests/ok/s10c.txt
new file mode 100644
index 000000000..bb34ca011
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s10c.txt
@@ -0,0 +1,21 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 4 rows = p1:S p2:V
+ 0: 'one'
+ 0: subview 'p2'
+ VIEW 1 rows = p3:I
+ 0: 1
+ 1: 'three'
+ 1: subview 'p2'
+ VIEW 3 rows = p3:I
+ 0: 111
+ 1: 222
+ 2: 333
+ 2: 'two'
+ 2: subview 'p2'
+ VIEW 2 rows = p3:I
+ 0: 11
+ 1: 22
+ 3: 'four'
+ 3: subview 'p2'
+ VIEW 0 rows = p3:I
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s11.txt b/akregator/src/mk4storage/metakit/tests/ok/s11.txt
new file mode 100644
index 000000000..fd82a1603
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s11.txt
@@ -0,0 +1,2 @@
+>>> Commit and rollback
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s11a.txt b/akregator/src/mk4storage/metakit/tests/ok/s11a.txt
new file mode 100644
index 000000000..fb8a3f195
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s11a.txt
@@ -0,0 +1,4 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 1 rows = p1:I
+ 0: 123
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s12.txt b/akregator/src/mk4storage/metakit/tests/ok/s12.txt
new file mode 100644
index 000000000..be9ca7a36
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s12.txt
@@ -0,0 +1,2 @@
+>>> Remove subview
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s12a.txt b/akregator/src/mk4storage/metakit/tests/ok/s12a.txt
new file mode 100644
index 000000000..9b6e95f0a
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s12a.txt
@@ -0,0 +1,3 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 0 rows = p1:I p2:V
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s13.txt b/akregator/src/mk4storage/metakit/tests/ok/s13.txt
new file mode 100644
index 000000000..112c33c70
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s13.txt
@@ -0,0 +1,2 @@
+>>> Remove middle subview
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s13a.txt b/akregator/src/mk4storage/metakit/tests/ok/s13a.txt
new file mode 100644
index 000000000..2189bb0a0
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s13a.txt
@@ -0,0 +1,13 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 2 rows = p1:I p2:V
+ 0: 123
+ 0: subview 'p2'
+ VIEW 1 rows = p3:I
+ 0: 234
+ 1: 125
+ 1: subview 'p2'
+ VIEW 3 rows = p3:I
+ 0: 456
+ 1: 457
+ 2: 458
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s14.txt b/akregator/src/mk4storage/metakit/tests/ok/s14.txt
new file mode 100644
index 000000000..0e9348b04
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s14.txt
@@ -0,0 +1,2 @@
+>>> Replace attached subview
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s14a.txt b/akregator/src/mk4storage/metakit/tests/ok/s14a.txt
new file mode 100644
index 000000000..e87913c05
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s14a.txt
@@ -0,0 +1,6 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 1 rows = p1:I p2:V
+ 0: 0
+ 0: subview 'p2'
+ VIEW 0 rows = p3:I
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s15.txt b/akregator/src/mk4storage/metakit/tests/ok/s15.txt
new file mode 100644
index 000000000..305baef1a
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s15.txt
@@ -0,0 +1,2 @@
+>>> Add after removed subviews
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s15a.txt b/akregator/src/mk4storage/metakit/tests/ok/s15a.txt
new file mode 100644
index 000000000..9e07c88fe
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s15a.txt
@@ -0,0 +1,7 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 1 rows = p1:I p2:V
+ 0: 111
+ 0: subview 'p2'
+ VIEW 1 rows = p3:I
+ 0: 234
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s16.txt b/akregator/src/mk4storage/metakit/tests/ok/s16.txt
new file mode 100644
index 000000000..27c69ca10
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s16.txt
@@ -0,0 +1,2 @@
+>>> Add after removed ints
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s16a.txt b/akregator/src/mk4storage/metakit/tests/ok/s16a.txt
new file mode 100644
index 000000000..fd274ae0d
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s16a.txt
@@ -0,0 +1,6 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 1 rows = p1:I p2:V
+ 0: 4
+ 0: subview 'p2'
+ VIEW 0 rows = p3:I
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s17.txt b/akregator/src/mk4storage/metakit/tests/ok/s17.txt
new file mode 100644
index 000000000..979139531
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s17.txt
@@ -0,0 +1,2 @@
+>>> Add after removed strings
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s17a.txt b/akregator/src/mk4storage/metakit/tests/ok/s17a.txt
new file mode 100644
index 000000000..40720e9d5
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s17a.txt
@@ -0,0 +1,6 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 1 rows = p1:S p2:V
+ 0: 'four'
+ 0: subview 'p2'
+ VIEW 0 rows = p3:I
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s18.txt b/akregator/src/mk4storage/metakit/tests/ok/s18.txt
new file mode 100644
index 000000000..5ff2d8e73
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s18.txt
@@ -0,0 +1,2 @@
+>>> Empty storage
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s18a.txt b/akregator/src/mk4storage/metakit/tests/ok/s18a.txt
new file mode 100644
index 000000000..a28a7cae2
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s18a.txt
@@ -0,0 +1 @@
+ VIEW 1 rows =
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s19.txt b/akregator/src/mk4storage/metakit/tests/ok/s19.txt
new file mode 100644
index 000000000..0a9ff3a17
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s19.txt
@@ -0,0 +1,2 @@
+>>> Empty view outlives storage
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s19a.txt b/akregator/src/mk4storage/metakit/tests/ok/s19a.txt
new file mode 100644
index 000000000..a28a7cae2
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s19a.txt
@@ -0,0 +1 @@
+ VIEW 1 rows =
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s20.txt b/akregator/src/mk4storage/metakit/tests/ok/s20.txt
new file mode 100644
index 000000000..5124a59e3
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s20.txt
@@ -0,0 +1,2 @@
+>>> View outlives storage
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s20a.txt b/akregator/src/mk4storage/metakit/tests/ok/s20a.txt
new file mode 100644
index 000000000..a28a7cae2
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s20a.txt
@@ -0,0 +1 @@
+ VIEW 1 rows =
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s21.txt b/akregator/src/mk4storage/metakit/tests/ok/s21.txt
new file mode 100644
index 000000000..4b944bf03
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s21.txt
@@ -0,0 +1,2 @@
+>>> Test demo scenario
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s21a.txt b/akregator/src/mk4storage/metakit/tests/ok/s21a.txt
new file mode 100644
index 000000000..2da5bab8b
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s21a.txt
@@ -0,0 +1,10 @@
+ VIEW 1 rows = a:V b:V
+ 0: subview 'a'
+ VIEW 4 rows = p1:S p2:S p3:I
+ 0: 'One' 'Un' 0
+ 1: 'Two' 'Deux' 123
+ 2: 'Four' '' 0
+ 3: 'Three' 'Trois' 0
+ 0: subview 'b'
+ VIEW 1 rows = p4:I
+ 0: 234
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s22.txt b/akregator/src/mk4storage/metakit/tests/ok/s22.txt
new file mode 100644
index 000000000..8d5c2bc75
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s22.txt
@@ -0,0 +1,2 @@
+>>> Double storage
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s22a.txt b/akregator/src/mk4storage/metakit/tests/ok/s22a.txt
new file mode 100644
index 000000000..03d83cf6f
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s22a.txt
@@ -0,0 +1,6 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 3 rows = p1:D
+ 0: 1234.5678
+ 1: 3456.789
+ 2: 2345.6789
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s23.txt b/akregator/src/mk4storage/metakit/tests/ok/s23.txt
new file mode 100644
index 000000000..7f921bcf3
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s23.txt
@@ -0,0 +1,2 @@
+>>> Find absent record
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s23a.txt b/akregator/src/mk4storage/metakit/tests/ok/s23a.txt
new file mode 100644
index 000000000..a28a7cae2
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s23a.txt
@@ -0,0 +1 @@
+ VIEW 1 rows =
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s24.txt b/akregator/src/mk4storage/metakit/tests/ok/s24.txt
new file mode 100644
index 000000000..91ef101b2
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s24.txt
@@ -0,0 +1,2 @@
+>>> Bitwise storage
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s24a.txt b/akregator/src/mk4storage/metakit/tests/ok/s24a.txt
new file mode 100644
index 000000000..37fc08320
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s24a.txt
@@ -0,0 +1,45 @@
+ VIEW 1 rows = a1:V a2:V a3:V a4:V
+ 0: subview 'a1'
+ VIEW 9 rows = p1:I
+ 0: 1
+ 1: 0
+ 2: 1
+ 3: 0
+ 4: 1
+ 5: 0
+ 6: 1
+ 7: 0
+ 8: 1
+ 0: subview 'a2'
+ VIEW 9 rows = p1:I
+ 0: 3
+ 1: 0
+ 2: 1
+ 3: 2
+ 4: 3
+ 5: 0
+ 6: 1
+ 7: 2
+ 8: 3
+ 0: subview 'a3'
+ VIEW 9 rows = p1:I
+ 0: 7
+ 1: 8
+ 2: 9
+ 3: 10
+ 4: 11
+ 5: 12
+ 6: 13
+ 7: 14
+ 8: 15
+ 0: subview 'a4'
+ VIEW 9 rows = p1:I
+ 0: 119
+ 1: 120
+ 2: 121
+ 3: 122
+ 4: 123
+ 5: 124
+ 6: 125
+ 7: 126
+ 8: 127
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s25.txt b/akregator/src/mk4storage/metakit/tests/ok/s25.txt
new file mode 100644
index 000000000..a9f5a3686
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s25.txt
@@ -0,0 +1,2 @@
+>>> Bytes storage
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s25a.txt b/akregator/src/mk4storage/metakit/tests/ok/s25a.txt
new file mode 100644
index 000000000..ced17ab22
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s25a.txt
@@ -0,0 +1,6 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 3 rows = p1:B
+ 0: (2b)
+ 1: (4b)
+ 2: (5b)
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s26.txt b/akregator/src/mk4storage/metakit/tests/ok/s26.txt
new file mode 100644
index 000000000..4496d6ee5
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s26.txt
@@ -0,0 +1,2 @@
+>>> Bitwise autosizing
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s26a.txt b/akregator/src/mk4storage/metakit/tests/ok/s26a.txt
new file mode 100644
index 000000000..2b644a8e8
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s26a.txt
@@ -0,0 +1,4 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 1 rows = p1:I p2:I p3:I p4:I
+ 0: 100000 100000 100000 100000
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s27.txt b/akregator/src/mk4storage/metakit/tests/ok/s27.txt
new file mode 100644
index 000000000..d35484ead
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s27.txt
@@ -0,0 +1,2 @@
+>>> Bytes restructuring
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s27a.txt b/akregator/src/mk4storage/metakit/tests/ok/s27a.txt
new file mode 100644
index 000000000..c39554b1e
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s27a.txt
@@ -0,0 +1,4 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 1 rows = p1:B
+ 0: (4b)
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s28.txt b/akregator/src/mk4storage/metakit/tests/ok/s28.txt
new file mode 100644
index 000000000..4e7e1a167
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s28.txt
@@ -0,0 +1,2 @@
+>>> Doubles added later
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s28a.txt b/akregator/src/mk4storage/metakit/tests/ok/s28a.txt
new file mode 100644
index 000000000..a731a6a3c
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s28a.txt
@@ -0,0 +1,7 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 1 rows = p1:F p2:D p3:V
+ 0: 123 123
+ 0: subview 'p3'
+ VIEW 1 rows = p1:F p2:D
+ 0: 234 234
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s29.txt b/akregator/src/mk4storage/metakit/tests/ok/s29.txt
new file mode 100644
index 000000000..982807abc
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s29.txt
@@ -0,0 +1,2 @@
+>>> Delete bytes property
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s29a.txt b/akregator/src/mk4storage/metakit/tests/ok/s29a.txt
new file mode 100644
index 000000000..36e2113bd
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s29a.txt
@@ -0,0 +1,3 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 0 rows = p1:B
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s30.txt b/akregator/src/mk4storage/metakit/tests/ok/s30.txt
new file mode 100644
index 000000000..e86ceee7c
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s30.txt
@@ -0,0 +1,2 @@
+>>> Memo storage
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s30a.txt b/akregator/src/mk4storage/metakit/tests/ok/s30a.txt
new file mode 100644
index 000000000..ced17ab22
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s30a.txt
@@ -0,0 +1,6 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 3 rows = p1:B
+ 0: (2b)
+ 1: (4b)
+ 2: (5b)
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s31.txt b/akregator/src/mk4storage/metakit/tests/ok/s31.txt
new file mode 100644
index 000000000..661077237
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s31.txt
@@ -0,0 +1,2 @@
+>>> Check sort buffer use
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s31a.txt b/akregator/src/mk4storage/metakit/tests/ok/s31a.txt
new file mode 100644
index 000000000..bb0beb13e
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s31a.txt
@@ -0,0 +1,6 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 3 rows = p1:I
+ 0: 3
+ 1: 1
+ 2: 2
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s32.txt b/akregator/src/mk4storage/metakit/tests/ok/s32.txt
new file mode 100644
index 000000000..342f61ddb
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s32.txt
@@ -0,0 +1,2 @@
+>>> Set memo empty or same size
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s32a.txt b/akregator/src/mk4storage/metakit/tests/ok/s32a.txt
new file mode 100644
index 000000000..c39554b1e
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s32a.txt
@@ -0,0 +1,4 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 1 rows = p1:B
+ 0: (4b)
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s33.txt b/akregator/src/mk4storage/metakit/tests/ok/s33.txt
new file mode 100644
index 000000000..749e7d37c
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s33.txt
@@ -0,0 +1,2 @@
+>>> Serialize memo fields
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s33a.txt b/akregator/src/mk4storage/metakit/tests/ok/s33a.txt
new file mode 100644
index 000000000..ced17ab22
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s33a.txt
@@ -0,0 +1,6 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 3 rows = p1:B
+ 0: (2b)
+ 1: (4b)
+ 2: (5b)
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s33b.txt b/akregator/src/mk4storage/metakit/tests/ok/s33b.txt
new file mode 100644
index 000000000..ced17ab22
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s33b.txt
@@ -0,0 +1,6 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 3 rows = p1:B
+ 0: (2b)
+ 1: (4b)
+ 2: (5b)
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s33c.txt b/akregator/src/mk4storage/metakit/tests/ok/s33c.txt
new file mode 100644
index 000000000..ced17ab22
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s33c.txt
@@ -0,0 +1,6 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 3 rows = p1:B
+ 0: (2b)
+ 1: (4b)
+ 2: (5b)
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s34.txt b/akregator/src/mk4storage/metakit/tests/ok/s34.txt
new file mode 100644
index 000000000..63a225ef2
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s34.txt
@@ -0,0 +1,2 @@
+>>> Smart and failed commits
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s34a.txt b/akregator/src/mk4storage/metakit/tests/ok/s34a.txt
new file mode 100644
index 000000000..81e1847d2
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s34a.txt
@@ -0,0 +1,4 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 1 rows = p1:I
+ 0: 111
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s35.txt b/akregator/src/mk4storage/metakit/tests/ok/s35.txt
new file mode 100644
index 000000000..18835d389
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s35.txt
@@ -0,0 +1,2 @@
+>>> Datafile with preamble
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s35a.txt b/akregator/src/mk4storage/metakit/tests/ok/s35a.txt
new file mode 100644
index 000000000..81e1847d2
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s35a.txt
@@ -0,0 +1,4 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 1 rows = p1:I
+ 0: 111
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s36.txt b/akregator/src/mk4storage/metakit/tests/ok/s36.txt
new file mode 100644
index 000000000..63d15af21
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s36.txt
@@ -0,0 +1,2 @@
+>>> Commit after load
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s36a.txt b/akregator/src/mk4storage/metakit/tests/ok/s36a.txt
new file mode 100644
index 000000000..81e1847d2
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s36a.txt
@@ -0,0 +1,4 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 1 rows = p1:I
+ 0: 111
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s36b.txt b/akregator/src/mk4storage/metakit/tests/ok/s36b.txt
new file mode 100644
index 000000000..81e1847d2
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s36b.txt
@@ -0,0 +1,4 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 1 rows = p1:I
+ 0: 111
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s37.txt b/akregator/src/mk4storage/metakit/tests/ok/s37.txt
new file mode 100644
index 000000000..8bf5f8b73
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s37.txt
@@ -0,0 +1,2 @@
+>>> Change short partial fields
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s37a.txt b/akregator/src/mk4storage/metakit/tests/ok/s37a.txt
new file mode 100644
index 000000000..21eab9c9d
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s37a.txt
@@ -0,0 +1,4 @@
+ VIEW 1 rows = v1:V
+ 0: subview 'v1'
+ VIEW 1 rows = key:I p1:B
+ 0: 0 (6b)
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s38.txt b/akregator/src/mk4storage/metakit/tests/ok/s38.txt
new file mode 100644
index 000000000..acd0b2019
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s38.txt
@@ -0,0 +1,2 @@
+>>> Lots of empty subviews
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s38a.txt b/akregator/src/mk4storage/metakit/tests/ok/s38a.txt
new file mode 100644
index 000000000..8ee8c3471
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s38a.txt
@@ -0,0 +1,7 @@
+ VIEW 1 rows = v:V
+ 0: subview 'v'
+ VIEW 2 rows = v1:V
+ 0: subview 'v1'
+ VIEW 0 rows = p1:S
+ 1: subview 'v1'
+ VIEW 0 rows = p1:S
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s39.txt b/akregator/src/mk4storage/metakit/tests/ok/s39.txt
new file mode 100644
index 000000000..a907f11e6
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s39.txt
@@ -0,0 +1,2 @@
+>>> Do not detach empty top-level views
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s39a.txt b/akregator/src/mk4storage/metakit/tests/ok/s39a.txt
new file mode 100644
index 000000000..7799a2713
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s39a.txt
@@ -0,0 +1,4 @@
+ VIEW 1 rows = v1:V
+ 0: subview 'v1'
+ VIEW 1 rows = p1:I
+ 0: 123
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s40.txt b/akregator/src/mk4storage/metakit/tests/ok/s40.txt
new file mode 100644
index 000000000..b799ff95c
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s40.txt
@@ -0,0 +1,2 @@
+>>> LoadFrom after commit
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s40a.txt b/akregator/src/mk4storage/metakit/tests/ok/s40a.txt
new file mode 100644
index 000000000..d256fc735
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s40a.txt
@@ -0,0 +1,4 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 1 rows = p1:I
+ 0: 456
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s41.txt b/akregator/src/mk4storage/metakit/tests/ok/s41.txt
new file mode 100644
index 000000000..419edbad8
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s41.txt
@@ -0,0 +1,2 @@
+>>> Partial modify blocked
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s41a.txt b/akregator/src/mk4storage/metakit/tests/ok/s41a.txt
new file mode 100644
index 000000000..51bc32d70
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s41a.txt
@@ -0,0 +1,8 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 2 rows = _B:V
+ 0: subview '_B'
+ VIEW 1 rows = p1:B
+ 0: (8b)
+ 1: subview '_B'
+ VIEW 0 rows = p1:B
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s42.txt b/akregator/src/mk4storage/metakit/tests/ok/s42.txt
new file mode 100644
index 000000000..61c83f2aa
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s42.txt
@@ -0,0 +1,2 @@
+>>> Get descriptions
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s43.txt b/akregator/src/mk4storage/metakit/tests/ok/s43.txt
new file mode 100644
index 000000000..af2b07123
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s43.txt
@@ -0,0 +1,2 @@
+>>> View reuse after sub-byte ints
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s43a.txt b/akregator/src/mk4storage/metakit/tests/ok/s43a.txt
new file mode 100644
index 000000000..df0a22ecb
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s43a.txt
@@ -0,0 +1,5 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 2 rows = p1:I
+ 0: 0
+ 1: 12345
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s44.txt b/akregator/src/mk4storage/metakit/tests/ok/s44.txt
new file mode 100644
index 000000000..640461805
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s44.txt
@@ -0,0 +1,2 @@
+>>> Bad memo free space
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s44a.txt b/akregator/src/mk4storage/metakit/tests/ok/s44a.txt
new file mode 100644
index 000000000..02b49b500
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s44a.txt
@@ -0,0 +1,4 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 1 rows = p1:I p2:B
+ 0: 0 (12345b)
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s45.txt b/akregator/src/mk4storage/metakit/tests/ok/s45.txt
new file mode 100644
index 000000000..066826a49
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s45.txt
@@ -0,0 +1,2 @@
+>>> Bad subview memo free space
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s45a.txt b/akregator/src/mk4storage/metakit/tests/ok/s45a.txt
new file mode 100644
index 000000000..920e28eed
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s45a.txt
@@ -0,0 +1,7 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 1 rows = p1:I p2:V
+ 0: 0
+ 0: subview 'p2'
+ VIEW 1 rows = p3:B
+ 0: (12345b)
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s46.txt b/akregator/src/mk4storage/metakit/tests/ok/s46.txt
new file mode 100644
index 000000000..b799ff95c
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s46.txt
@@ -0,0 +1,2 @@
+>>> LoadFrom after commit
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s46a.txt b/akregator/src/mk4storage/metakit/tests/ok/s46a.txt
new file mode 100644
index 000000000..9fa04509b
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s46a.txt
@@ -0,0 +1,15 @@
+ VIEW 1 rows = a:V
+ 0: subview 'a'
+ VIEW 12 rows = p1:I
+ 0: 11
+ 1: 22
+ 2: 33
+ 3: 44
+ 4: 0
+ 5: 55
+ 6: 66
+ 7: 77
+ 8: 0
+ 9: 88
+ 10: 99
+ 11: 1000
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s47.txt b/akregator/src/mk4storage/metakit/tests/ok/s47.txt
new file mode 100644
index 000000000..55827d04d
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s47.txt
@@ -0,0 +1,2 @@
+>>> Defining bad property type
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s48.txt b/akregator/src/mk4storage/metakit/tests/ok/s48.txt
new file mode 100644
index 000000000..28fdd3a5c
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s48.txt
@@ -0,0 +1,2 @@
+>>> Resize subview to zero and back
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s48a.txt b/akregator/src/mk4storage/metakit/tests/ok/s48a.txt
new file mode 100644
index 000000000..5e398789c
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s48a.txt
@@ -0,0 +1,5 @@
+ VIEW 1 rows = v1:V
+ 0: subview 'v1'
+ VIEW 1 rows = v2:V
+ 0: subview 'v2'
+ VIEW 0 rows = p1:I
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s48b.txt b/akregator/src/mk4storage/metakit/tests/ok/s48b.txt
new file mode 100644
index 000000000..5e398789c
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s48b.txt
@@ -0,0 +1,5 @@
+ VIEW 1 rows = v1:V
+ 0: subview 'v1'
+ VIEW 1 rows = v2:V
+ 0: subview 'v2'
+ VIEW 0 rows = p1:I
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s49.txt b/akregator/src/mk4storage/metakit/tests/ok/s49.txt
new file mode 100644
index 000000000..b32d7ff00
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s49.txt
@@ -0,0 +1,2 @@
+>>> Specify conflicting properties
+<<< done.
diff --git a/akregator/src/mk4storage/metakit/tests/ok/s49a.txt b/akregator/src/mk4storage/metakit/tests/ok/s49a.txt
new file mode 100644
index 000000000..992724c50
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/ok/s49a.txt
@@ -0,0 +1,7 @@
+ VIEW 1 rows = v1:V v2:V v3:V
+ 0: subview 'v1'
+ VIEW 0 rows = p1:I
+ 0: subview 'v2'
+ VIEW 0 rows = p1:I
+ 0: subview 'v3'
+ VIEW 0 rows = v3:V
diff --git a/akregator/src/mk4storage/metakit/tests/regress.cpp b/akregator/src/mk4storage/metakit/tests/regress.cpp
new file mode 100644
index 000000000..0725f57f5
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/regress.cpp
@@ -0,0 +1,269 @@
+// regress.cpp -- Regression test program, main code
+// $Id$
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit/
+
+#include "regress.h"
+
+#if defined (macintosh)
+ #include <SIOUX.h>
+ #ifdef DEBUG_NEW
+ #include <DebugNew.cp>
+ //#include "ZoneRanger.c"
+ #if DEBUG_NEW >= 2 && !defined (q4_MAC_LEAK_CHECK)
+ #define q4_MAC_LEAK_CHECK 1
+ #endif
+ #endif
+#endif
+
+#if __profile__
+ #define q4_MWCW_PROFILER 1
+ #include <profiler.h>
+#endif
+
+#if q4_NOTHROW
+ const char* msg;
+#endif
+
+#if _WIN32_WCE
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+int remove(const char* fn_)
+{
+ c4_Bytes buffer;
+ int n = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, fn_, -1, NULL, 0);
+ wchar_t* w = (wchar_t*) buffer.SetBufferClear((n+1) * sizeof (wchar_t));
+ MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, fn_, -1, w, n);
+ return DeleteFile((wchar_t*) buffer.Contents()) ? 0 : -1;
+}
+
+#endif
+
+int
+#if _WIN32_WCE
+_cdecl
+#endif
+main()
+{
+// afxMemDF |= allocMemDF | checkAlwaysMemDF;
+
+ // The M4STRING package sometimes keeps a spare empty string around.
+ // By allocating it here, we avoid a few bogus memory leak reports.
+ c4_String empty;
+
+ #if q4_MAC_LEAK_CHECK
+ DebugNewForgetLeaks();
+ #endif
+
+#if q4_MWCW_PROFILER
+ if (!ProfilerInit(collectDetailed, bestTimeBase, 20, 5))
+ {
+#endif
+ TestBasics1();
+ TestBasics2();
+ TestNotify();
+ TestCustom1();
+ TestCustom2();
+ TestResize();
+ TestStores1();
+ TestStores2();
+ TestStores3();
+ TestStores4();
+ TestStores5();
+ TestDiffer();
+ TestExtend();
+ TestFormat();
+ TestMapped();
+ TestLimits();
+
+#if q4_MWCW_PROFILER
+ ProfilerDump("\pRegress.prof");
+ ProfilerTerm();
+ }
+#endif
+
+ #if defined (_DEBUG)
+ fputs("\nPress return... ", stderr);
+ getchar();
+ #endif
+ #if q4_MAC_LEAK_CHECK
+ if (DebugNewReportLeaks())
+ fputs(" *** Memory leaks found ***\n", stderr);
+ #endif
+ #if defined (macintosh)
+ SIOUXSettings.asktosaveonclose = false;
+ #endif
+
+ fputs("Done.\n", stderr);
+ return 0;
+}
+
+// Recursively display the entire view contents. The results shown do not
+// depend on file layout (free space, file positions, flat vs. on-demand).
+
+static void ViewDisplay(const c4_View& v_, FILE* fp, int l_ =0)
+{
+ c4_String types;
+ bool hasData = false, hasSubs = false;
+
+ // display header info and collect all data types
+ fprintf(fp, "%*s VIEW %5d rows =", l_, "", v_.GetSize());
+ for (int n = 0; n < v_.NumProperties(); ++n)
+ {
+ c4_Property prop = v_.NthProperty(n);
+ char t = prop.Type();
+
+ fprintf(fp, " %s:%c", (const char*) prop.Name(), t);
+
+ types += t;
+
+ if (t == 'V')
+ hasSubs = true;
+ else
+ hasData = true;
+ }
+ fprintf(fp, "\n");
+
+ for (int j = 0; j < v_.GetSize(); ++j)
+ {
+ if (hasData) // data properties are all shown on the same line
+ {
+ fprintf(fp, "%*s %4d:", l_, "", j);
+ c4_RowRef r = v_[j];
+
+ for (int k = 0; k < types.GetLength(); ++k)
+ {
+ c4_Property p = v_.NthProperty(k);
+
+ switch (types[k])
+ {
+ case 'I':
+ fprintf(fp, " %ld", (long) ((c4_IntProp&) p) (r));
+ break;
+
+#if !q4_TINY
+ case 'F':
+ fprintf(fp, " %g", (double) ((c4_FloatProp&) p) (r));
+ break;
+
+ case 'D':
+ fprintf(fp, " %.12g", (double) ((c4_DoubleProp&) p) (r));
+ break;
+#endif
+
+ case 'S':
+ fprintf(fp, " '%s'", (const char*) ((c4_StringProp&) p) (r));
+ break;
+
+ case 'M': // backward compatibility
+ case 'B':
+ fprintf(fp, " (%db)", (p (r)).GetSize());
+ break;
+
+ default:
+ if (types[k] != 'V')
+ fprintf(fp, " (%c?)", types[k]);
+ }
+ }
+
+ fprintf(fp, "\n");
+ }
+
+ if (hasSubs) // subviews are then shown, each as a separate block
+ {
+ for (int k = 0; k < types.GetLength(); ++k)
+ {
+ if (types[k] == 'V')
+ {
+ c4_Property prop = v_.NthProperty(k);
+
+ fprintf(fp, "%*s %4d: subview '%s'\n", l_, "", j,
+ (const char*) prop.Name());
+
+ c4_ViewProp& vp = (c4_ViewProp&) prop;
+
+ ViewDisplay(vp (v_[j]), fp, l_ + 2);
+ }
+ }
+ }
+ }
+}
+
+void DumpFile(const char* in_, const char* out_)
+{
+ FILE* fp = fopen(out_, TEXTOUT);
+ A(fp);
+
+ c4_Storage store (in_, 0);
+
+ ViewDisplay(store, fp);
+
+ fclose(fp);
+}
+
+void Fail(const char* msg)
+{
+ #if q4_NOTHROW
+ fprintf(stderr, "\t%s\n", msg);
+ printf("*** %s ***\n", msg);
+ #else
+ throw msg;
+ #endif
+}
+
+void FailExpr(const char* expr)
+{
+ char buffer [100];
+ sprintf(buffer, "Failed: A(%s)", expr);
+ Fail(buffer);
+}
+
+int StartTest(int mask_, const char* name_, const char* desc_)
+{
+ if (mask_)
+ {
+ #if q4_MFC && defined(_DEBUG)
+ TRACE("%s - %-40s *** DISABLED ***\n", name_, desc_);
+ #endif
+ #if !q4_MWCW_PROFILER
+ fprintf(stderr, "%s - %-40s *** DISABLED ***\n", name_, desc_);
+ #endif
+ return false;
+ }
+
+ #if q4_MFC && defined(_DEBUG)
+ TRACE("%s - %s\n", name_, desc_);
+ #endif
+ #if !q4_MWCW_PROFILER
+ fprintf(stderr, "%s - %s\n", name_, desc_);
+ #endif
+
+ char buffer [50];
+ sprintf(buffer, "%s%s.txt", TESTDIR, name_);
+ #if _WIN32_WCE
+ fclose(stdout);
+ fopen(buffer, TEXTOUT);
+ #else
+ freopen(buffer, TEXTOUT, stdout);
+ #endif
+ printf(">>> %s\n", desc_);
+
+ return true;
+}
+
+void CatchMsg(const char* msg)
+{
+ #if !q4_MWCW_PROFILER
+ fprintf(stderr, "\t%s\n", msg);
+ #endif
+ printf("*** %s ***\n", msg);
+}
+
+void CatchOther()
+{
+ #if !q4_MWCW_PROFILER
+ fputs("\tException!\n", stderr);
+ #endif
+ printf("*** Exception ***\n");
+}
diff --git a/akregator/src/mk4storage/metakit/tests/regress.h b/akregator/src/mk4storage/metakit/tests/regress.h
new file mode 100644
index 000000000..f317bcb26
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/regress.h
@@ -0,0 +1,145 @@
+// regress.h -- Regression test program, header file
+// $Id$
+// This is part of Metakit, see http://www.equi4.com/metakit/
+
+#include "mk4.h"
+#include "mk4io.h"
+#include "mk4str.h"
+
+#define TraceAll false
+
+ // default for dos and unix is to assume they don't support exceptions
+#if defined (_DOS) || defined (unix) || defined (__unix__) || \
+ defined (__GNUC__) || defined (_WIN32_WCE)
+#if !defined (q4_NOTHROW)
+#define q4_NOTHROW 1
+#endif
+#endif
+
+#ifdef _WIN32_WCE
+int remove(const char*);
+#endif
+
+#if _MSC_VER == 800
+#pragma warning (disable: 4703) // function too large for global optimizations
+
+// also no exceptions in MSVC 1.52 when used with a QuickWin target
+#if defined (_QWINVER) && !defined (q4_NOTHROW)
+#define q4_NOTHROW 1
+#endif
+#endif
+
+#if q4_NOTHROW
+#define try
+#define catch(x) if (0)
+
+extern const char* msg;
+#endif
+
+#if defined (macintosh)
+#define TESTDIR ":tests:"
+#define TEXTOUT "wt"
+#define LINESEP "\r"
+#elif defined (__VMS)
+#define TESTDIR "[.tests]"
+#define TEXTOUT "w"
+#define LINESEP "\r\n" // is this correct?
+#elif defined (unix) || defined (__unix__) || defined (__GNUC__)
+#define TESTDIR "tests/"
+#define TEXTOUT "w"
+#define LINESEP "\n"
+#else
+#define TESTDIR "tests\\"
+#define TEXTOUT "wt"
+#define LINESEP "\r\n"
+#endif
+
+#include <stdio.h>
+
+#if q4_MFC && defined(_DEBUG)
+#define B(n_,d_,c_) \
+ if (StartTest(c_, #n_, #d_)) \
+ { \
+ CMemoryState oldState, newState, diffState; \
+ oldState.Checkpoint(); \
+ afxTraceEnabled = TraceAll; \
+ try \
+ { \
+ {
+#define E \
+ } \
+ puts("<<< done."); \
+ } \
+ catch (const char* msg) { CatchMsg(msg); } \
+ catch (...) { CatchOther(); } \
+ afxTraceEnabled = true; \
+ fflush(stdout); \
+ newState.Checkpoint(); \
+ if (diffState.Difference(oldState, newState)) \
+ { \
+ fputs("\tMemory leaked!\n", stderr); \
+ puts("*** Memory leaked ***"); \
+ TRACE(" *** Memory leaked, "); \
+ diffState.DumpAllObjectsSince(); \
+ } \
+ fflush(stdout); \
+ }
+#else
+#define B(n_,d_,c_) \
+ if (StartTest(c_, #n_, #d_)) \
+ { \
+ try \
+ { \
+ {
+#define E \
+ } \
+ puts("<<< done."); \
+ } \
+ catch (const char* msg) { CatchMsg(msg); } \
+ catch (...) { CatchOther(); } \
+ fflush(stdout); \
+ }
+#endif
+
+#define A(e_) if (e_) ; else FailExpr(#e_)
+
+#define W(f_) remove(#f_)
+#define R(f_) A(remove(#f_) == 0)
+#define D(f_) DumpFile(#f_, TESTDIR #f_ ".txt")
+
+typedef c4_BytesProp c4_MemoProp;
+
+extern void DumpFile(const char* in_, const char* out_);
+extern void Fail(const char* msg);
+extern void FailExpr(const char* expr);
+extern int StartTest(int, const char*, const char*);
+extern void CatchMsg(const char* msg);
+extern void CatchOther();
+
+extern void TestBasics1();
+extern void TestBasics2();
+extern void TestCustom1();
+extern void TestCustom2();
+extern void TestDiffer();
+extern void TestExtend();
+extern void TestFormat();
+extern void TestLimits();
+extern void TestMapped();
+extern void TestNotify();
+extern void TestResize();
+extern void TestStores1();
+extern void TestStores2();
+extern void TestStores3();
+extern void TestStores4();
+extern void TestStores5();
+
+ // The Borland C++ RTL does not want file handle objects to cross
+ // DLL boundaries, so we use special fopen/fclose hooks in the DLL.
+
+#if defined (__BORLANDC__) // this assumes Metakit is in a DLL!
+extern FILE* f4_FileOpenInDLL(const char*, const char*);
+extern int f4_FileCloseInDLL(FILE*);
+
+#define fopen f4_FileOpenInDLL
+#define fclose f4_FileCloseInDLL
+#endif
diff --git a/akregator/src/mk4storage/metakit/tests/tbasic1.cpp b/akregator/src/mk4storage/metakit/tests/tbasic1.cpp
new file mode 100644
index 000000000..0c5742a25
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/tbasic1.cpp
@@ -0,0 +1,268 @@
+// tbasic1.cpp -- Regression test program, basic tests part 1
+// $Id$
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit/
+
+#include "regress.h"
+
+void TestBasics1()
+{
+ B(b00, Should fail, 0)
+ {
+ A(false);
+ } E;
+
+ B(b01, Should succeed, 0)
+ {
+ A(sizeof (t4_byte) == 1);
+ A(sizeof (short) == 2);
+ A(sizeof (t4_i32) == 4);
+ A(sizeof (float) == 4);
+ A(sizeof (double) == 8);
+ } E;
+
+ B(b02, Int property, 0)
+ {
+ c4_Row r1;
+ c4_IntProp p1 ("p1");
+ p1 (r1) = 1234567890L;
+ long x1 = p1 (r1);
+ A(x1 == 1234567890L);
+ } E;
+
+#if !q4_TINY
+ B(b03, Float property, 0)
+ {
+ c4_Row r1;
+ c4_FloatProp p1 ("p1");
+ p1 (r1) = 123.456;
+ double x1 = p1 (r1);
+ A((float) x1 == (float) 123.456);
+ } E;
+#endif
+
+ B(b04, String property, 0)
+ {
+ c4_Row r1;
+ c4_StringProp p1 ("p1");
+ p1 (r1) = "abc";
+ const char* x1 = p1 (r1);
+ A((c4_String) x1 == "abc");
+ } E;
+
+ B(b05, View property, 0)
+ {
+ c4_View v1;
+ c4_Row r1;
+ c4_ViewProp p1 ("p1");
+ p1 (r1) = v1;
+ c4_View x1 = p1 (r1);
+ // compare cursors to make sure this is the same sequence
+ A(x1[0] == v1[0]);
+ } E;
+
+ B(b06, View construction, 0)
+ {
+ c4_IntProp p1 ("p1"), p2 ("p2"), p3 ("p3");
+ c4_View v1 = (p1, p3, p2);
+ A(v1.FindProperty(p1.GetId()) == 0);
+ A(v1.FindProperty(p2.GetId()) == 2);
+ A(v1.FindProperty(p3.GetId()) == 1);
+ } E;
+
+ B(b07, Row manipulation, 0)
+ {
+ c4_StringProp p1 ("p1"), p2 ("p2");
+ c4_IntProp p3 ("p3");
+ c4_Row r1;
+ p1 (r1) = "look at this" ;
+ const char* x1 = p1 (r1);
+ A(x1 == (c4_String) "look at this");
+ r1 = p1 [ "what's in a" ] + p2 [ "name..." ];
+ c4_String t = (const char*) p2 (r1);
+ p1 (r1) = t + (const char*) (p1 (r1));
+ p2 (r1) = p1 (r1);
+ c4_String x2 = (const char*) p1 (r1); // 2000-03-16, store as c4_String
+ A(x2 == "name...what's in a");
+ // the above change avoids an evaluation order issue in assert below
+ A(x2 == p2 (r1));
+ p3 (r1) = 12345;
+ p3 (r1) = p3 (r1) + 123;
+ int x3 = p3 (r1);
+ A(x3 == 12345 + 123);
+ } E;
+
+ B(b08, Row expressions, 0)
+ {
+ c4_StringProp p1 ("p1"), p2 ("p2");
+ c4_IntProp p3 ("p3");
+ c4_Row r1;
+ c4_View v1 = (p1, p2, p3);
+ v1.SetSize(5);
+ r1 = v1[1];
+ v1[2] = v1[1];
+ v1[3] = r1;
+ v1[4] = v1[4];
+ r1 = r1;
+ } E;
+
+ B(b09, View manipulation, 0)
+ {
+ c4_StringProp p1 ("p1"), p2 ("p2");
+ c4_Row r1 = p1 ["One"] + p2 ["Two"];
+ c4_Row r2;
+ c4_View v1;
+ v1.Add(r1);
+ v1.Add(r2);
+ v1.Add(r1);
+ A(v1.GetSize() == 3);
+ A(v1[0] == r1);
+ A(v1[1] == r2);
+ A(v1[2] == r1);
+ v1.RemoveAt(1, 1);
+ A(v1.GetSize() == 2);
+ A(v1[0] == r1);
+ A(v1[0] == v1[1]);
+ } E;
+
+ B(b10, View sorting, 0)
+ {
+ c4_IntProp p1 ("p1");
+ c4_View v1;
+ v1.Add(p1 [111]);
+ v1.Add(p1 [222]);
+ v1.Add(p1 [333]);
+ v1.Add(p1 [345]);
+ v1.Add(p1 [234]);
+ v1.Add(p1 [123]);
+ c4_View v2 = v1.Sort();
+ A(v2.GetSize() == 6);
+ A(p1 (v2[0]) == 111);
+ A(p1 (v2[1]) == 123);
+ A(p1 (v2[2]) == 222);
+ A(p1 (v2[3]) == 234);
+ A(p1 (v2[4]) == 333);
+ A(p1 (v2[5]) == 345);
+ } E;
+
+ B(b11, View selection, 0)
+ {
+ c4_IntProp p1 ("p1");
+ c4_View v1;
+ v1.Add(p1 [111]);
+ v1.Add(p1 [222]);
+ v1.Add(p1 [333]);
+ v1.Add(p1 [345]);
+ v1.Add(p1 [234]);
+ v1.Add(p1 [123]);
+ c4_View v2 = v1.SelectRange(p1 [200], p1 [333]);
+ A(v2.GetSize() == 3);
+ A(p1 (v2[0]) == 222);
+ A(p1 (v2[1]) == 333);
+ A(p1 (v2[2]) == 234);
+ } E;
+
+ B(b12, Add after remove, 0)
+ {
+ c4_StringProp p1 ("p1");
+ c4_View v1;
+ v1.Add(p1 ["abc"]);
+ A(v1.GetSize() == 1);
+ v1.RemoveAt(0);
+ A(v1.GetSize() == 0);
+ v1.Add(p1 ["def"]);
+ A(v1.GetSize() == 1);
+ } E;
+
+ B(b13, Clear view entry, 0)
+ {
+ c4_IntProp p1 ("p1");
+ c4_View v1;
+
+ v1.Add(p1 [123]);
+ A(v1.GetSize() == 1);
+ A(p1 (v1[0]) == 123);
+
+ v1[0] = c4_Row ();
+ A(v1.GetSize() == 1);
+ A(p1 (v1[0]) == 0);
+ } E;
+
+ B(b14, Empty view outlives temp storage, 0)
+ {
+ c4_View v1;
+ c4_Storage s1;
+ v1 = s1.GetAs("a[p1:I,p2:S]");
+ } E;
+
+ B(b15, View outlives temp storage, 0)
+ {
+ c4_IntProp p1 ("p1");
+ c4_View v1;
+
+ {
+ c4_Storage s1;
+ v1 = s1.GetAs("a[p1:I,p2:S]");
+ v1.Add(p1 [123]);
+ }
+
+ // 19990916 - semantics changed, view now 1 row, but 0 props
+ A(v1.GetSize() == 1);
+ A(v1.NumProperties() == 0);
+ //A(p1 (v1[0]) == 123);
+ } E;
+
+ B(b16, View outlives cleared temp storage, 0)
+ {
+ c4_IntProp p1 ("p1");
+ c4_View v1;
+
+ {
+ c4_Storage s1;
+ v1 = s1.GetAs("a[p1:I,p2:S]");
+ v1.Add(p1 [123]);
+ v1.RemoveAll();
+ }
+
+ A(v1.GetSize() == 0);
+ v1.Add(p1 [123]);
+ A(v1.GetSize() == 1);
+ A(p1 (v1[0]) == 123);
+ } E;
+
+#if !q4_TINY
+ B(b17, Double property, 0)
+ {
+ c4_Row r1;
+ c4_DoubleProp p1 ("p1");
+ p1 (r1) = 1234.5678;
+ double x1 = p1 (r1);
+ A(x1 == (double) 1234.5678);
+ } E;
+#endif
+
+ B(b18, SetAtGrow usage, 0)
+ {
+ c4_IntProp p1 ("p1");
+ c4_View v1;
+
+ v1.SetAtGrow(3, p1 [333]);
+ v1.SetAtGrow(1, p1 [111]);
+ v1.SetAtGrow(5, p1 [555]);
+
+ A(v1.GetSize() == 6);
+ A(p1 (v1[1]) == 111);
+ A(p1 (v1[3]) == 333);
+ A(p1 (v1[5]) == 555);
+ } E;
+
+ B(b19, Bytes property, 0)
+ {
+ c4_Row r1;
+ c4_BytesProp p1 ("p1");
+ c4_Bytes x1 ("hi!", 3);
+
+ p1 (r1) = x1;
+ c4_Bytes x2 = p1 (r1);
+ A(x1 == x2);
+ } E;
+}
diff --git a/akregator/src/mk4storage/metakit/tests/tbasic2.cpp b/akregator/src/mk4storage/metakit/tests/tbasic2.cpp
new file mode 100644
index 000000000..53c6b307f
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/tbasic2.cpp
@@ -0,0 +1,218 @@
+// tbasic2.cpp -- Regression test program, basic tests part 2
+// $Id$
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit/
+
+#include "regress.h"
+
+ static int ViewSize(c4_View v)
+ {
+ return v.GetSize();
+ }
+
+void TestBasics2()
+{
+ B(b20, Search sorted view, 0)
+ {
+ c4_IntProp p1 ("p1");
+ c4_StringProp p2 ("p2");
+ c4_View v1;
+ v1.Add(p1 [111] + p2 ["one"]);
+ v1.Add(p1 [222] + p2 ["two"]);
+ v1.Add(p1 [333] + p2 ["three"]);
+ v1.Add(p1 [345] + p2 ["four"]);
+ v1.Add(p1 [234] + p2 ["five"]);
+ v1.Add(p1 [123] + p2 ["six"]);
+ c4_View v2 = v1.Sort();
+ A(v2.GetSize() == 6);
+ A(p1 (v2[0]) == 111);
+ A(p1 (v2[1]) == 123);
+ A(p1 (v2[2]) == 222);
+ A(p1 (v2[3]) == 234);
+ A(p1 (v2[4]) == 333);
+ A(p1 (v2[5]) == 345);
+ A(v2.Search(p1 [123]) == 1);
+ A(v2.Search(p1 [100]) == 0);
+ A(v2.Search(p1 [200]) == 2);
+ A(v2.Search(p1 [400]) == 6);
+ c4_View v3 = v1.SortOn(p2);
+ A(v3.GetSize() == 6);
+ A(p1 (v3[0]) == 234);
+ A(p1 (v3[1]) == 345);
+ A(p1 (v3[2]) == 111);
+ A(p1 (v3[3]) == 123);
+ A(p1 (v3[4]) == 333);
+ A(p1 (v3[5]) == 222);
+ A(v3.Search(p2 ["six"]) == 3);
+ A(v3.Search(p2 ["aha"]) == 0);
+ A(v3.Search(p2 ["gee"]) == 2);
+ A(v3.Search(p2 ["wow"]) == 6);
+ c4_View v4 = v1.SortOnReverse(p2, p2);
+ A(v4.GetSize() == 6);
+ A(p1 (v4[0]) == 222);
+ A(p1 (v4[1]) == 333);
+ A(p1 (v4[2]) == 123);
+ A(p1 (v4[3]) == 111);
+ A(p1 (v4[4]) == 345);
+ A(p1 (v4[5]) == 234);
+ A(v4.Search(p2 ["six"]) == 2);
+ A(v4.Search(p2 ["aha"]) == 6);
+ A(v4.Search(p2 ["gee"]) == 4);
+ A(v4.Search(p2 ["wow"]) == 0);
+ } E;
+
+ B(b21, Memo property, 0)
+ {
+ c4_Row r1;
+ c4_MemoProp p1 ("p1");
+ c4_Bytes x1 ("hi!", 3);
+
+ p1 (r1) = x1;
+ c4_Bytes x2 = p1 (r1);
+ A(x1 == x2);
+ } E;
+
+ B(b22, Stored view references, 0)
+ {
+ c4_ViewProp p1 ("p1");
+ c4_View v1;
+
+ {
+ v1.Add(p1 [c4_View ()]);
+ }
+
+ // this works
+ int n = ViewSize(p1.Get(v1[0]));
+ A(n == 0);
+
+ // this fails in 1.8b2 using MSVC 1.52 (tq_wvus)
+ //
+ // The compiler destructs temp c4_View once too often, or
+ // what's more likely, fails to call the constructor once.
+ //
+ // So for MSVC 1.52: use prop.Get(rowref) for subviews,
+ // or immediately assign the result to a c4_View object,
+ // do not pass a "prop (rowref)" expression as argument.
+
+#if _MSC_VER != 800
+ int m = ViewSize(p1 (v1[0]));
+ A(m == 0);
+#endif
+ } E;
+
+ B(b23, Sort comparison fix, 0) // 1.9e: compare buffering problem
+ {
+ c4_DoubleProp p1 ("p1");
+ c4_View v1;
+ for (int i = 0; i < 100; ++i)
+ v1.Add(p1 [99-i]);
+ c4_View v2 = v1.Sort();
+ A(v2.GetSize() == 100);
+ for (int j = 0; j < 100; ++j)
+ {
+ A(p1 (v1[j]) == (double) 99-j);
+ A(p1 (v2[j]) == (double) j);
+ }
+ } E;
+
+ B(b24, Custom view comparisons, 0) // 1.9f: more compare cache problems
+ {
+ c4_IntProp p1 ("p1");
+ c4_FloatProp p2 ("p2");
+ c4_DoubleProp p3 ("p3");
+ c4_IntProp p4 ("p4");
+ c4_View v1;
+ v1.Add(p1 [2] + p2 [2] + p3 [2]);
+ v1.Add(p1 [1] + p2 [1] + p3 [1]);
+ v1.Add(p1 [3] + p2 [3] + p3 [3]);
+ A(v1.GetSize() == 3);
+ A((int) p1 (v1[0]) > (int) p1 (v1[1]));
+ A((float) p2 (v1[0]) > (float) p2 (v1[1]));
+ A((double) p3 (v1[0]) > (double) p3 (v1[1]));
+ A((int) p1 (v1[0]) < (int) p1 (v1[2]));
+ A((float) p2 (v1[0]) < (float) p2 (v1[2]));
+ A((double) p3 (v1[0]) < (double) p3 (v1[2]));
+ c4_View v2 = v1.Unique();
+ A(v2.GetSize() == 3);
+ A((int) p1 (v2[0]) != (int) p1 (v2[1]));
+ A((float) p2 (v2[0]) != (float) p2 (v2[1]));
+ A((double) p3 (v2[0]) != (double) p3 (v2[1]));
+ A((int) p1 (v2[0]) != (int) p1 (v2[2]));
+ A((float) p2 (v2[0]) != (float) p2 (v2[2]));
+ A((double) p3 (v2[0]) != (double) p3 (v2[2]));
+ v1.Add(p1 [2] + p2 [2] + p3 [2]);
+ v1.Add(p1 [1] + p2 [1] + p3 [1]);
+ v1.Add(p1 [3] + p2 [3] + p3 [3]);
+ c4_View v3 = v1.Unique();
+ A(v3.GetSize() == 3);
+ A((int) p1 (v3[0]) != (int) p1 (v3[1]));
+ A((float) p2 (v3[0]) != (float) p2 (v3[1]));
+ A((double) p3 (v3[0]) != (double) p3 (v3[1]));
+ A((int) p1 (v3[0]) != (int) p1 (v3[2]));
+ A((float) p2 (v3[0]) != (float) p2 (v3[2]));
+ A((double) p3 (v3[0]) != (double) p3 (v3[2]));
+ c4_View v4 = v1.Counts(p1, p4);
+ A(v4.GetSize() == 3);
+ c4_View v5 = v1.Counts(p2, p4);
+ A(v5.GetSize() == 3); // this failed in 1.9f
+ c4_View v6 = v1.Counts(p3, p4);
+ A(v6.GetSize() == 3); // this failed in 1.9f
+ } E;
+
+ B(b25, Copy row from derived, 0)
+ {
+ c4_IntProp p1 ("p1");
+ c4_View v1;
+ v1.Add(p1 [111]);
+ v1.Add(p1 [222]);
+ v1.Add(p1 [333]);
+ c4_View v2 = v1.Select(p1 [222]);
+ A(v2.GetSize() == 1);
+ A(p1 (v2[0]) == 222);
+ c4_Row r = v2[0];
+ A(p1 (r) == 222); // 1.9g: failed because SetAt did not remap
+ } E;
+
+ B(b26, Partial memo field access, 0)
+ {
+ c4_BytesProp p1 ("p1");
+ c4_View v1;
+ v1.Add(p1 [c4_Bytes ("12345", 5)]);
+ A(v1.GetSize() == 1);
+ c4_Bytes buf = p1 (v1[0]);
+ A(buf.Size() == 5);
+ A(buf == c4_Bytes ("12345", 5));
+ buf = p1(v1[0]).Access(1,3);
+ A(buf == c4_Bytes ("234", 3));
+ p1 (v1[0]).Modify(c4_Bytes ("ab", 2), 2, 0);
+ buf = p1 (v1[0]);
+ A(buf == c4_Bytes ("12ab5", 5));
+ p1 (v1[0]).Modify(c4_Bytes ("ABC", 3), 1, 2);
+ buf = p1 (v1[0]);
+ A(buf == c4_Bytes ("1ABCab5", 7));
+ p1 (v1[0]).Modify(c4_Bytes ("xyz", 3), 2, -2);
+ buf = p1 (v1[0]);
+ A(buf == c4_Bytes ("1Axyz", 5));
+ p1 (v1[0]).Modify(c4_Bytes ("3456", 4), 4, 0);
+ buf = p1 (v1[0]);
+ A(buf == c4_Bytes ("1Axy3456", 8));
+ } E;
+
+ B(b27, Copy value to another row, 0)
+ {
+ c4_StringProp p1 ("p1");
+ c4_View v1;
+ v1.SetSize(2);
+ p1 (v1[1]) = "abc";
+ // next assert fails in MacOS X 10.2.1 "Jaguar" with 2.4.7
+ // seems bug in gcc 3.1, -O i.s.o. -O2 works [jcw 21oct02]
+ A((const char*) (p1 (v1[0])) == (c4_String) "");
+ A((const char*) (p1 (v1[1])) == (c4_String) "abc");
+
+ // fails in 2.4.0, reported by Jerry McRae, August 2001
+ p1 (v1[0]) = (const char*) p1 (v1[1]);
+ // MacOS 10.2.3 gcc 3.1 dec 2002 is still weird, inserting the
+ // following code (which should be a noop) *fixes* the assert!
+ //const char* q = p1 (v1[1]);
+ A((c4_String)(const char*) (p1 (v1[0])) == (c4_String) "abc");
+ } E;
+}
diff --git a/akregator/src/mk4storage/metakit/tests/tcusto1.cpp b/akregator/src/mk4storage/metakit/tests/tcusto1.cpp
new file mode 100644
index 000000000..38161d5fc
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/tcusto1.cpp
@@ -0,0 +1,277 @@
+// tcusto1.cpp -- Regression test program, custom view tests
+// $Id$
+// This is part of Metakit, see http://www.equi4.com/metakit/
+
+#include "regress.h"
+
+void TestCustom1()
+{
+ B(c01, Slice forward, 0)
+ {
+ c4_IntProp p1 ("p1");
+
+ c4_View v1;
+ v1.Add(p1 [123]);
+ v1.Add(p1 [234]);
+ v1.Add(p1 [345]);
+ v1.Add(p1 [456]);
+ v1.Add(p1 [567]);
+
+ c4_View v2 = v1.Slice(1, -1, 2);
+ A(v2.GetSize() == 2);
+ A(p1 (v2[0]) == 234);
+ A(p1 (v2[1]) == 456);
+
+ v1.Add(p1 [678]);
+ A(v1.GetSize() == 6);
+ A(v2.GetSize() == 3);
+ A(p1 (v2[2]) == 678);
+ } E;
+
+ B(c02, Slice backward, 0)
+ {
+ c4_IntProp p1 ("p1");
+
+ c4_View v1;
+ v1.Add(p1 [123]);
+ v1.Add(p1 [234]);
+ v1.Add(p1 [345]);
+ v1.Add(p1 [456]);
+ v1.Add(p1 [567]);
+
+ c4_View v2 = v1.Slice(1, -1, -2);
+ A(v2.GetSize() == 2);
+ A(p1 (v2[0]) == 456);
+ A(p1 (v2[1]) == 234);
+
+ v1.Add(p1 [678]);
+ A(v1.GetSize() == 6);
+ A(v2.GetSize() == 3);
+ A(p1 (v2[0]) == 678);
+ A(p1 (v2[1]) == 456);
+ A(p1 (v2[2]) == 234);
+ } E;
+
+ B(c03, Slice reverse, 0)
+ {
+ c4_IntProp p1 ("p1");
+
+ c4_View v1;
+ v1.Add(p1 [123]);
+ v1.Add(p1 [234]);
+ v1.Add(p1 [345]);
+ v1.Add(p1 [456]);
+ v1.Add(p1 [567]);
+
+ c4_View v2 = v1.Slice(1, 5, -1);
+ A(v2.GetSize() == 4);
+ A(p1 (v2[0]) == 567);
+ A(p1 (v2[1]) == 456);
+ A(p1 (v2[2]) == 345);
+ A(p1 (v2[3]) == 234);
+
+ v1.Add(p1 [678]);
+ A(v1.GetSize() == 6);
+ A(v2.GetSize() == 4);
+ } E;
+
+ B(c04, Cartesian product, 0)
+ {
+ c4_IntProp p1 ("p1");
+ c4_IntProp p2 ("p2");
+
+ c4_View v1;
+ v1.Add(p1 [123]);
+ v1.Add(p1 [234]);
+ v1.Add(p1 [345]);
+
+ c4_View v2;
+ v2.Add(p2 [111]);
+ v2.Add(p2 [222]);
+
+ c4_View v3 = v1.Product(v2);
+ A(v3.GetSize() == 6);
+ A(p1 (v3[0]) == 123);
+ A(p2 (v3[0]) == 111);
+ A(p1 (v3[1]) == 123);
+ A(p2 (v3[1]) == 222);
+ A(p1 (v3[2]) == 234);
+ A(p2 (v3[2]) == 111);
+ A(p1 (v3[3]) == 234);
+ A(p2 (v3[3]) == 222);
+ A(p1 (v3[4]) == 345);
+ A(p2 (v3[4]) == 111);
+ A(p1 (v3[5]) == 345);
+ A(p2 (v3[5]) == 222);
+
+ v1.Add(p1 [456]);
+ A(v3.GetSize() == 8);
+ v2.Add(p2 [333]);
+ A(v3.GetSize() == 12);
+ } E;
+
+ B(c05, Remapping, 0)
+ {
+ c4_IntProp p1 ("p1");
+
+ c4_View v1;
+ v1.Add(p1 [123]);
+ v1.Add(p1 [234]);
+ v1.Add(p1 [345]);
+
+ c4_View v2;
+ v2.Add(p1 [2]);
+ v2.Add(p1 [0]);
+ v2.Add(p1 [1]);
+ v2.Add(p1 [0]);
+
+ c4_View v3 = v1.RemapWith(v2);
+ A(v3.GetSize() == 4);
+ A(p1 (v3[0]) == 345);
+ A(p1 (v3[1]) == 123);
+ A(p1 (v3[2]) == 234);
+ A(p1 (v3[3]) == 123);
+ } E;
+
+ B(c06, Pairwise combination, 0)
+ {
+ c4_IntProp p1 ("p1");
+ c4_IntProp p2 ("p2");
+
+ c4_View v1;
+ v1.Add(p1 [123]);
+ v1.Add(p1 [234]);
+ v1.Add(p1 [345]);
+
+ c4_View v2;
+ v2.Add(p2 [111]);
+ v2.Add(p2 [222]);
+ v2.Add(p2 [333]);
+
+ c4_View v3 = v1.Pair(v2);
+ A(v3.GetSize() == 3);
+ A(p1 (v3[0]) == 123);
+ A(p2 (v3[0]) == 111);
+ A(p1 (v3[1]) == 234);
+ A(p2 (v3[1]) == 222);
+ A(p1 (v3[2]) == 345);
+ A(p2 (v3[2]) == 333);
+ } E;
+
+ B(c07, Concatenate views, 0)
+ {
+ c4_IntProp p1 ("p1");
+
+ c4_View v1;
+ v1.Add(p1 [123]);
+ v1.Add(p1 [234]);
+ v1.Add(p1 [345]);
+
+ c4_View v2;
+ v2.Add(p1 [111]);
+ v2.Add(p1 [222]);
+
+ c4_View v3 = v1.Concat(v2);
+ A(v3.GetSize() == 5);
+ A(p1 (v3[0]) == 123);
+ A(p1 (v3[1]) == 234);
+ A(p1 (v3[2]) == 345);
+ A(p1 (v3[3]) == 111);
+ A(p1 (v3[4]) == 222);
+ } E;
+
+ B(c08, Rename property, 0)
+ {
+ c4_IntProp p1 ("p1");
+ c4_IntProp p2 ("p2");
+
+ c4_View v1;
+ v1.Add(p1 [123]);
+ v1.Add(p1 [234]);
+ v1.Add(p1 [345]);
+
+ c4_View v2 = v1.Rename(p1, p2);
+ A(v2.GetSize() == 3);
+ A(p2 (v2[0]) == 123);
+ A(p2 (v2[1]) == 234);
+ A(p2 (v2[2]) == 345);
+ A(p1 (v2[0]) == 0);
+ A(p1 (v2[1]) == 0);
+ A(p1 (v2[2]) == 0);
+ } E;
+
+ B(c09, GroupBy operation, 0)
+ {
+ c4_StringProp p1 ("p1");
+ c4_IntProp p2 ("p2");
+ c4_ViewProp p3 ("p3");
+
+ c4_View v1, v2, v3;
+
+ v1.Add(p1 [""]);
+ v1.Add(p1 ["1"] + p2 [1]);
+ v1.Add(p1 ["12"] + p2 [1]);
+ v1.Add(p1 ["12"] + p2 [2]);
+ v1.Add(p1 ["123"] + p2 [1]);
+ v1.Add(p1 ["123"] + p2 [2]);
+ v1.Add(p1 ["123"] + p2 [3]);
+
+ v2 = v1.GroupBy(p1, p3);
+ A(v2.GetSize() == 4);
+ A(p1 (v2[0]) == (c4_String) "");
+ A(p1 (v2[1]) == (c4_String) "1");
+ A(p1 (v2[2]) == (c4_String) "12");
+ A(p1 (v2[3]) == (c4_String) "123");
+
+ v3 = p3 (v2[0]);
+ A(v3.GetSize() == 1);
+ A(p2 (v3[0]) == 0);
+ v3 = p3 (v2[1]);
+ A(v3.GetSize() == 1);
+ A(p2 (v3[0]) == 1);
+ v3 = p3 (v2[2]);
+ A(v3.GetSize() == 2);
+ A(p2 (v3[0]) == 1);
+ A(p2 (v3[1]) == 2);
+ v3 = p3 (v2[3]);
+ A(v3.GetSize() == 3);
+ A(p2 (v3[0]) == 1);
+ A(p2 (v3[1]) == 2);
+ A(p2 (v3[2]) == 3);
+
+ } E;
+
+ B(c10, Counts operation, 0)
+ {
+ c4_StringProp p1 ("p1");
+ c4_IntProp p2 ("p2"), p3 ("p3");
+
+ c4_View v1, v2, v3;
+
+ v1.Add(p1 [""]);
+ v1.Add(p1 ["1"] + p2 [1]);
+ v1.Add(p1 ["12"] + p2 [1]);
+ v1.Add(p1 ["12"] + p2 [2]);
+ v1.Add(p1 ["123"] + p2 [1]);
+ v1.Add(p1 ["123"] + p2 [2]);
+ v1.Add(p1 ["123"] + p2 [3]);
+
+ v2 = v1.Counts(p1, p3);
+ A(v2.GetSize() == 4);
+ A(p1 (v2[0]) == (c4_String) "");
+ A(p1 (v2[1]) == (c4_String) "1");
+ A(p1 (v2[2]) == (c4_String) "12");
+ A(p1 (v2[3]) == (c4_String) "123");
+
+ A(p2 (v2[0]) == 0);
+ A(p2 (v2[1]) == 0);
+ A(p2 (v2[2]) == 0);
+ A(p2 (v2[3]) == 0);
+
+ A(p3 (v2[0]) == 1);
+ A(p3 (v2[1]) == 1);
+ A(p3 (v2[2]) == 2);
+ A(p3 (v2[3]) == 3);
+
+ } E;
+}
diff --git a/akregator/src/mk4storage/metakit/tests/tcusto2.cpp b/akregator/src/mk4storage/metakit/tests/tcusto2.cpp
new file mode 100644
index 000000000..53949592d
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/tcusto2.cpp
@@ -0,0 +1,441 @@
+// tcusto2.cpp -- Regression test program, custom view tests
+// $Id$
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit/
+
+#include "regress.h"
+
+void TestCustom2()
+{
+ B(c11, Unique operation, 0);
+ {
+ c4_IntProp p1 ("p1"), p2 ("p2");
+
+ c4_View v1, v2, v3;
+
+ v1.Add(p1 [1] + p2 [11]);
+ v1.Add(p1 [1] + p2 [22]);
+ v1.Add(p1 [2] + p2 [33]);
+ v1.Add(p1 [2] + p2 [33]);
+ v1.Add(p1 [3] + p2 [44]);
+ v1.Add(p1 [4] + p2 [55]);
+ v1.Add(p1 [4] + p2 [55]);
+ v1.Add(p1 [4] + p2 [55]);
+
+ v2 = v1.Unique();
+ A(v2.GetSize() == 5);
+ A(p1 (v2[0]) == 1);
+ A(p1 (v2[1]) == 1);
+ A(p1 (v2[2]) == 2);
+ A(p1 (v2[3]) == 3);
+ A(p1 (v2[4]) == 4);
+
+ A(p2 (v2[0]) == 11);
+ A(p2 (v2[1]) == 22);
+ A(p2 (v2[2]) == 33);
+ A(p2 (v2[3]) == 44);
+ A(p2 (v2[4]) == 55);
+
+ } E;
+
+ B(c12, Union operation, 0)
+ {
+ c4_IntProp p1 ("p1");
+
+ c4_View v1, v2, v3;
+
+ v1.Add(p1 [1]);
+ v1.Add(p1 [2]);
+ v1.Add(p1 [3]);
+
+ v2.Add(p1 [2]);
+ v2.Add(p1 [3]);
+ v2.Add(p1 [4]);
+ v2.Add(p1 [5]);
+
+ v3 = v1.Union(v2);
+ A(v3.GetSize() == 5);
+ A(p1 (v3[0]) == 1);
+ A(p1 (v3[1]) == 2);
+ A(p1 (v3[2]) == 3);
+ A(p1 (v3[3]) == 4);
+ A(p1 (v3[4]) == 5);
+ } E;
+
+ B(c13, Intersect operation, 0)
+ {
+ c4_IntProp p1 ("p1");
+
+ c4_View v1, v2, v3;
+
+ v1.Add(p1 [1]);
+ v1.Add(p1 [2]);
+ v1.Add(p1 [3]);
+
+ v2.Add(p1 [2]);
+ v2.Add(p1 [3]);
+ v2.Add(p1 [4]);
+ v2.Add(p1 [5]);
+
+ v3 = v1.Intersect(v2);
+ A(v3.GetSize() == 2);
+ A(p1 (v3[0]) == 2);
+ A(p1 (v3[1]) == 3);
+ } E;
+
+ B(c14, Different operation, 0)
+ {
+ c4_IntProp p1 ("p1");
+
+ c4_View v1, v2, v3;
+
+ v1.Add(p1 [1]);
+ v1.Add(p1 [2]);
+ v1.Add(p1 [3]);
+
+ v2.Add(p1 [2]);
+ v2.Add(p1 [3]);
+ v2.Add(p1 [4]);
+ v2.Add(p1 [5]);
+
+ v3 = v1.Different(v2);
+ A(v3.GetSize() == 3);
+ A(p1 (v3[0]) == 1);
+ A(p1 (v3[1]) == 4);
+ A(p1 (v3[2]) == 5);
+ } E;
+
+ B(c15, Minus operation, 0)
+ {
+ c4_IntProp p1 ("p1");
+
+ c4_View v1, v2, v3;
+
+ v1.Add(p1 [1]);
+ v1.Add(p1 [2]);
+ v1.Add(p1 [3]);
+
+ v2.Add(p1 [2]);
+ v2.Add(p1 [3]);
+ v2.Add(p1 [4]);
+ v2.Add(p1 [5]);
+
+ v3 = v1.Minus(v2);
+ A(v3.GetSize() == 1);
+ A(p1 (v3[0]) == 1);
+ } E;
+
+ B(c16, View comparisons, 0)
+ {
+ c4_IntProp p1 ("p1");
+
+ c4_View v1;
+ v1.Add(p1 [1]);
+ v1.Add(p1 [2]);
+ v1.Add(p1 [3]);
+ v1.Add(p1 [4]);
+ v1.Add(p1 [5]);
+
+ A(v1 == v1);
+ A(v1 == v1.Slice(0));
+ A(v1.Slice(0,2) < v1.Slice(0,3));
+ A(v1.Slice(0,3) == v1.Slice(0,3));
+ A(v1.Slice(0,4) > v1.Slice(0,3));
+ A(v1.Slice(0,3) < v1.Slice(1,3));
+ A(v1.Slice(0,3) < v1.Slice(1,4));
+ A(v1.Slice(1,3) > v1.Slice(0,3));
+ A(v1.Slice(1,4) > v1.Slice(0,3));
+ } E;
+
+ B(c17, Join operation, 0)
+ {
+ c4_StringProp p1 ("p1"), p2 ("p2");
+ c4_IntProp p3 ("p3");
+
+ c4_View v1, v2, v3;
+
+ v1.Add(p1 [""]);
+ v1.Add(p1 ["1"] + p2 ["a"]);
+ v1.Add(p1 ["12"] + p2 ["ab"]);
+ v1.Add(p1 ["123"] + p2 ["abc"]);
+
+ v2.Add(p1 ["1"] + p3 [1]);
+ v2.Add(p1 ["12"] + p3 [1]);
+ v2.Add(p1 ["12"] + p3 [2]);
+ v2.Add(p1 ["123"] + p3 [1]);
+ v2.Add(p1 ["123"] + p3 [2]);
+ v2.Add(p1 ["123"] + p3 [3]);
+
+ v3 = v1.Join(p1, v2); // inner join
+ A(v3.GetSize() == 6);
+
+ A(p1 (v3[0]) == (c4_String) "1");
+ A(p1 (v3[1]) == (c4_String) "12");
+ A(p1 (v3[2]) == (c4_String) "12");
+ A(p1 (v3[3]) == (c4_String) "123");
+ A(p1 (v3[4]) == (c4_String) "123");
+ A(p1 (v3[5]) == (c4_String) "123");
+
+ A(p2 (v3[0]) == (c4_String) "a");
+ A(p2 (v3[1]) == (c4_String) "ab");
+ A(p2 (v3[2]) == (c4_String) "ab");
+ A(p2 (v3[3]) == (c4_String) "abc");
+ A(p2 (v3[4]) == (c4_String) "abc");
+ A(p2 (v3[5]) == (c4_String) "abc");
+
+ A(p3 (v3[0]) == 1);
+ A(p3 (v3[1]) == 1);
+ A(p3 (v3[2]) == 2);
+ A(p3 (v3[3]) == 1);
+ A(p3 (v3[4]) == 2);
+ A(p3 (v3[5]) == 3);
+
+ v3 = v1.Join(p1, v2, true); // outer join
+ A(v3.GetSize() == 7);
+
+ A(p1 (v3[0]) == (c4_String) "");
+ A(p1 (v3[1]) == (c4_String) "1");
+ A(p1 (v3[2]) == (c4_String) "12");
+ A(p1 (v3[3]) == (c4_String) "12");
+ A(p1 (v3[4]) == (c4_String) "123");
+ A(p1 (v3[5]) == (c4_String) "123");
+ A(p1 (v3[6]) == (c4_String) "123");
+
+ A(p2 (v3[0]) == (c4_String) "");
+ A(p2 (v3[1]) == (c4_String) "a");
+ A(p2 (v3[2]) == (c4_String) "ab");
+ A(p2 (v3[3]) == (c4_String) "ab");
+ A(p2 (v3[4]) == (c4_String) "abc");
+ A(p2 (v3[5]) == (c4_String) "abc");
+ A(p2 (v3[6]) == (c4_String) "abc");
+
+ A(p3 (v3[0]) == 0);
+ A(p3 (v3[1]) == 1);
+ A(p3 (v3[2]) == 1);
+ A(p3 (v3[3]) == 2);
+ A(p3 (v3[4]) == 1);
+ A(p3 (v3[5]) == 2);
+ A(p3 (v3[6]) == 3);
+ } E;
+
+ B(c18, Groupby sort fix, 0) // fails in 1.8.4 (from P. Ritter, 14-10-1998)
+ {
+ c4_StringProp p1 ("Country");
+ c4_StringProp p2 ("City");
+ c4_ViewProp p3 ("SubList");
+
+ c4_View v1, v2, v3;
+
+ v1.Add(p1 ["US"] + p2 ["Philadelphia"]);
+ v1.Add(p1 ["France"] + p2 ["Bordeaux"]);
+ v1.Add(p1 ["US"] + p2 ["Miami"]);
+ v1.Add(p1 ["France"] + p2 ["Paris"]);
+ v1.Add(p1 ["US"] + p2 ["Boston"]);
+ v1.Add(p1 ["France"] + p2 ["Nice"]);
+ v1.Add(p1 ["US"] + p2 ["NY"]);
+ v1.Add(p1 ["US"] + p2 ["Miami"]);
+
+ v2 = v1.GroupBy(p1, p3);
+ A(v2.GetSize() == 2);
+ A(p1 (v2[0]) == (c4_String) "France");
+ A(p1 (v2[1]) == (c4_String) "US");
+
+ v3 = p3 (v2[0]);
+ A(v3.GetSize() == 3);
+ A(p2 (v3[0]) == (c4_String) "Bordeaux");
+ A(p2 (v3[1]) == (c4_String) "Nice");
+ A(p2 (v3[2]) == (c4_String) "Paris");
+ v3 = p3 (v2[1]);
+ A(v3.GetSize() == 5);
+ A(p2 (v3[0]) == (c4_String) "Boston");
+ A(p2 (v3[1]) == (c4_String) "Miami");
+ A(p2 (v3[2]) == (c4_String) "Miami");
+ A(p2 (v3[3]) == (c4_String) "NY");
+ A(p2 (v3[4]) == (c4_String) "Philadelphia");
+ } E;
+
+ B(c19, JoinProp operation, 0) // moved, used to also be called c15
+ {
+ c4_StringProp p1 ("p1");
+ c4_ViewProp p2 ("p2");
+ c4_IntProp p3 ("p3");
+
+ c4_View v1, v2a, v2b, v2c, v3;
+
+ v2a.Add(p3 [1]);
+ v2a.Add(p3 [2]);
+ v2a.Add(p3 [3]);
+ v1.Add(p1 ["123"] + p2 [v2a]);
+
+ v2b.Add(p3 [1]);
+ v2b.Add(p3 [2]);
+ v1.Add(p1 ["12"] + p2 [v2b]);
+
+ v2c.Add(p3 [1]);
+ v1.Add(p1 ["1"] + p2 [v2c]);
+
+ v1.Add(p1 [""]);
+
+ v3 = v1.JoinProp(p2); // inner join
+ A(v3.GetSize() == 6);
+
+ A(p1 (v3[0]) == (c4_String) "123");
+ A(p1 (v3[1]) == (c4_String) "123");
+ A(p1 (v3[2]) == (c4_String) "123");
+ A(p1 (v3[3]) == (c4_String) "12");
+ A(p1 (v3[4]) == (c4_String) "12");
+ A(p1 (v3[5]) == (c4_String) "1");
+
+ A(p3 (v3[0]) == 1);
+ A(p3 (v3[1]) == 2);
+ A(p3 (v3[2]) == 3);
+ A(p3 (v3[3]) == 1);
+ A(p3 (v3[4]) == 2);
+ A(p3 (v3[5]) == 1);
+
+ v3 = v1.JoinProp(p2, true); // outer join
+ A(v3.GetSize() == 7);
+
+ A(p1 (v3[0]) == (c4_String) "123");
+ A(p1 (v3[1]) == (c4_String) "123");
+ A(p1 (v3[2]) == (c4_String) "123");
+ A(p1 (v3[3]) == (c4_String) "12");
+ A(p1 (v3[4]) == (c4_String) "12");
+ A(p1 (v3[5]) == (c4_String) "1");
+ A(p1 (v3[6]) == (c4_String) "");
+
+ A(p3 (v3[0]) == 1);
+ A(p3 (v3[1]) == 2);
+ A(p3 (v3[2]) == 3);
+ A(p3 (v3[3]) == 1);
+ A(p3 (v3[4]) == 2);
+ A(p3 (v3[5]) == 1);
+ A(p3 (v3[6]) == 0);
+ } E;
+
+ B(c20, Wide cartesian product, 0)
+ {
+ // added 2nd prop's to do a better test - 1999-12-23
+ c4_IntProp p1 ("p1");
+ c4_IntProp p2 ("p2");
+ c4_IntProp p3 ("p3");
+ c4_IntProp p4 ("p4");
+
+ c4_View v1;
+ v1.Add(p1 [123] + p2 [321]);
+ v1.Add(p1 [234] + p2 [432]);
+ v1.Add(p1 [345] + p2 [543]);
+
+ c4_View v2;
+ v2.Add(p3 [111] + p4 [11]);
+ v2.Add(p3 [222] + p4 [22]);
+
+ c4_View v3 = v1.Product(v2);
+ A(v3.GetSize() == 6);
+ A(p1 (v3[0]) == 123);
+ A(p2 (v3[0]) == 321);
+ A(p3 (v3[0]) == 111);
+ A(p4 (v3[0]) == 11);
+ A(p1 (v3[1]) == 123);
+ A(p2 (v3[1]) == 321);
+ A(p3 (v3[1]) == 222);
+ A(p4 (v3[1]) == 22);
+ A(p1 (v3[2]) == 234);
+ A(p2 (v3[2]) == 432);
+ A(p3 (v3[2]) == 111);
+ A(p4 (v3[2]) == 11);
+ A(p1 (v3[3]) == 234);
+ A(p2 (v3[3]) == 432);
+ A(p3 (v3[3]) == 222);
+ A(p4 (v3[3]) == 22);
+ A(p1 (v3[4]) == 345);
+ A(p2 (v3[4]) == 543);
+ A(p3 (v3[4]) == 111);
+ A(p4 (v3[4]) == 11);
+ A(p1 (v3[5]) == 345);
+ A(p2 (v3[5]) == 543);
+ A(p3 (v3[5]) == 222);
+ A(p4 (v3[5]) == 22);
+
+ v1.Add(p1 [456]);
+ A(v3.GetSize() == 8);
+ v2.Add(p2 [333]);
+ A(v3.GetSize() == 12);
+ } E;
+
+ B(c21, Join on compound key, 0)
+ {
+ c4_IntProp p1 ("p1"), p2 ("p2"), p3 ("p3"), p4 ("p4");
+
+ c4_View v1, v2, v3;
+
+ v1.Add(p1 [1] + p2 [11] + p3 [111]);
+ v1.Add(p1 [2] + p2 [22] + p3 [222]);
+ v1.Add(p1 [3] + p2 [22] + p3 [111]);
+
+ v2.Add(p2 [11] + p3 [111] + p4 [1111]);
+ v2.Add(p2 [22] + p3 [222] + p4 [2222]);
+ v2.Add(p2 [22] + p3 [222] + p4 [3333]);
+ v2.Add(p2 [22] + p3 [333] + p4 [4444]);
+
+ // this works here, but it fails in Python, i.e. Mk4py 2.4.0
+ v3 = v1.Join((p2, p3), v2);
+
+ A(v3.GetSize() == 3);
+
+ A(p1 (v3[0]) == 1);
+ A(p1 (v3[1]) == 2);
+ A(p1 (v3[2]) == 2);
+
+ A(p2 (v3[0]) == 11);
+ A(p2 (v3[1]) == 22);
+ A(p2 (v3[2]) == 22);
+
+ A(p3 (v3[0]) == 111);
+ A(p3 (v3[1]) == 222);
+ A(p3 (v3[2]) == 222);
+
+ A(p4 (v3[0]) == 1111);
+ A(p4 (v3[1]) == 2222);
+ A(p4 (v3[2]) == 3333);
+ } E;
+
+ B(c22, Groupby with selection, 0)
+ {
+ c4_Storage s1;
+ c4_View v1 = s1.GetAs("v1[p1:I,p2:I,p3:I]");
+ c4_IntProp p1 ("p1"), p2 ("p2"), p3 ("p3");
+ c4_ViewProp p4 ("p4");
+
+ v1.Add(p1[0] + p2[1] + p3[10]);
+ v1.Add(p1[1] + p2[1] + p3[20]);
+ v1.Add(p1[2] + p2[2] + p3[30]);
+ v1.Add(p1[3] + p2[3] + p3[40]);
+ v1.Add(p1[4] + p2[3] + p3[50]);
+
+ s1.Commit();
+ A(v1.GetSize() == 5);
+
+ c4_View v2 = v1.GroupBy(p2,p4);
+ A(v2.GetSize() == 3);
+
+ c4_View v3 = p4 (v2[0]);
+ A(v3.GetSize() == 2);
+ A(p3 (v3[0]) == 10);
+ A(p3 (v3[1]) == 20);
+
+ c4_View v4 = p4 (v2[1]);
+ A(v4.GetSize() == 1);
+ A(p3 (v4[0]) == 30);
+
+ c4_View v5 = p4 (v2[2]);
+ A(v5.GetSize() == 2);
+ A(p3 (v5[0]) == 40);
+ A(p3 (v5[1]) == 50);
+
+ c4_View v6 = v4.Sort();
+ A(v6.GetSize() == 1);
+ A(p1 (v6[0]) == 2);
+ A(p3 (v6[0]) == 30);
+
+ } E;
+}
diff --git a/akregator/src/mk4storage/metakit/tests/tdiffer.cpp b/akregator/src/mk4storage/metakit/tests/tdiffer.cpp
new file mode 100644
index 000000000..16dc97c34
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/tdiffer.cpp
@@ -0,0 +1,52 @@
+// tdiffer.cpp -- Regression test program, differential commit tests
+// $Id$
+// This is part of Metakit, see http://www.equi4.com/metakit/
+
+#include "regress.h"
+
+void TestDiffer()
+{
+ B(d01, Commit aside, 0) W(d01a); W(d01b);
+ {
+ c4_IntProp p1 ("p1");
+ {
+ c4_Storage s1 ("d01a", 1);
+ A(s1.Strategy().FileSize() == 0);
+ c4_View v1 = s1.GetAs("a[p1:I]");
+ v1.Add(p1 [123]);
+ s1.Commit();
+ }
+ {
+ c4_Storage s1 ("d01a", 0);
+ c4_Storage s2 ("d01b", 1);
+ s1.SetAside(s2);
+ c4_View v1 = s1.View("a");
+ A(v1.GetSize() == 1);
+ A(p1 (v1[0]) == 123);
+ v1.Add(p1 [456]);
+ A(v1.GetSize() == 2);
+ A(p1 (v1[0]) == 123);
+ A(p1 (v1[1]) == 456);
+ s1.Commit();
+ A(v1.GetSize() == 2);
+ A(p1 (v1[0]) == 123);
+ A(p1 (v1[1]) == 456);
+ s2.Commit();
+ A(v1.GetSize() == 2);
+ A(p1 (v1[0]) == 123);
+ A(p1 (v1[1]) == 456);
+ }
+ {
+ c4_Storage s1 ("d01a", 0);
+ c4_View v1 = s1.View("a");
+ A(v1.GetSize() == 1);
+ A(p1 (v1[0]) == 123);
+ c4_Storage s2 ("d01b", 0);
+ s1.SetAside(s2);
+ c4_View v2 = s1.View("a");
+ A(v2.GetSize() == 2);
+ A(p1 (v2[0]) == 123);
+ A(p1 (v2[1]) == 456);
+ }
+ } D(d01a); D(d01b); R(d01a); R(d01b); E;
+}
diff --git a/akregator/src/mk4storage/metakit/tests/textend.cpp b/akregator/src/mk4storage/metakit/tests/textend.cpp
new file mode 100644
index 000000000..98331f1af
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/textend.cpp
@@ -0,0 +1,195 @@
+// textend.cpp -- Regression test program, commit extend tests
+// $Id$
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit/
+
+#include "regress.h"
+
+const int kSize1 = 41;
+const int kSize2 = 85;
+
+void TestExtend()
+{
+ B(e01, Extend new file, 0) W(e01a);
+ {
+ c4_IntProp p1 ("p1");
+ c4_Storage s1 ("e01a", 2);
+ A(s1.Strategy().FileSize() == 0);
+ c4_View v1 = s1.GetAs("a[p1:I]");
+ v1.Add(p1 [123]);
+ s1.Commit();
+ A(s1.Strategy().FileSize() == kSize1);
+ v1.Add(p1 [456]);
+ s1.Commit();
+ A(s1.Strategy().FileSize() == kSize2);
+ } D(e01a); R(e01a); E;
+
+ B(e02, Extend committing twice, 0) W(e02a);
+ {
+ c4_IntProp p1 ("p1");
+ c4_Storage s1 ("e02a", 2);
+ A(s1.Strategy().FileSize() == 0);
+ c4_View v1 = s1.GetAs("a[p1:I]");
+ v1.Add(p1 [123]);
+ s1.Commit();
+ A(s1.Strategy().FileSize() == kSize1);
+ s1.Commit();
+ A(s1.Strategy().FileSize() == kSize1);
+ v1.Add(p1 [456]);
+ s1.Commit();
+ A(s1.Strategy().FileSize() == kSize2);
+ } D(e02a); R(e02a); E;
+
+ B(e03, Read during extend, 0) W(e03a);
+ {
+ c4_IntProp p1 ("p1");
+ c4_Storage s1 ("e03a", 2);
+ A(s1.Strategy().FileSize() == 0);
+ c4_View v1 = s1.GetAs("a[p1:I]");
+ v1.Add(p1 [123]);
+ s1.Commit();
+ A(s1.Strategy().FileSize() == kSize1);
+
+ {
+ c4_Storage s2 ("e03a", 0);
+ c4_View v2 = s2.View("a");
+ A(v2.GetSize() == 1);
+ A(p1 (v2[0]) == 123);
+ }
+
+ v1.Add(p1 [456]);
+ s1.Commit();
+ A(s1.Strategy().FileSize() == kSize2);
+
+ {
+ c4_Storage s3 ("e03a", 0);
+ c4_View v3 = s3.View("a");
+ A(v3.GetSize() == 2);
+ A(p1 (v3[0]) == 123);
+ A(p1 (v3[1]) == 456);
+ }
+ } D(e03a); R(e03a); E;
+
+ B(e04, Extend during read, 0) W(e04a);
+ {
+ c4_IntProp p1 ("p1");
+
+ {
+ c4_Storage s1 ("e04a", 2);
+ A(s1.Strategy().FileSize() == 0);
+ c4_View v1 = s1.GetAs("a[p1:I]");
+ v1.Add(p1 [123]);
+ s1.Commit();
+ A(s1.Strategy().FileSize() == kSize1);
+ }
+
+ c4_Storage s2 ("e04a", 0);
+ c4_View v2 = s2.View("a");
+ A(v2.GetSize() == 1);
+ A(p1 (v2[0]) == 123);
+
+ c4_Storage s3 ("e04a", 0); // open, don't load
+
+ {
+ c4_Storage s4 ("e04a", 2);
+ A(s4.Strategy().FileSize() == kSize1);
+ c4_View v4 = s4.View("a");
+ v4.Add(p1 [123]);
+ s4.Commit();
+ A(s4.Strategy().FileSize() > kSize1); // == kSize2);
+ }
+
+ c4_View v2a = s2.View("a");
+ A(v2a.GetSize() == 1);
+ A(p1 (v2a[0]) == 123);
+
+ c4_View v3 = s3.View("a");
+ A(v3.GetSize() == 1);
+ A(p1 (v3[0]) == 123);
+
+ } D(e04a); R(e04a); E;
+
+ B(e05, Test memory mapping, 0) W(e05a);
+ {
+ // this is not a test of MK, but of the underlying system code
+
+ {
+ c4_FileStrategy fs;
+ bool f1 = fs.DataOpen("e05a", 1);
+ A(!f1);
+ fs.DataWrite(0, "hi!", 3);
+ A(fs._failure == 0);
+ A(fs.FileSize() == 3);
+ fs.DataCommit(0);
+ A(fs.FileSize() == 3);
+ fs.ResetFileMapping();
+ if (fs._mapStart != 0)
+ {
+ A(fs._dataSize == 3);
+ c4_String s ((char*) fs._mapStart, 3);
+ A(s == "hi!");
+ }
+ fs.DataWrite(3, "hello", 5);
+ A(fs._failure == 0);
+ A(fs.FileSize() == 8);
+ fs.DataCommit(0);
+ A(fs.FileSize() == 8);
+ if (fs._mapStart != 0)
+ {
+ A(fs._dataSize == 3);
+ c4_String s ((char*) fs._mapStart, 8);
+ A(s == "hi!hello");
+ }
+ fs.DataWrite(100, "wow!", 4);
+ A(fs._failure == 0);
+ A(fs.FileSize() == 104);
+ fs.DataCommit(0);
+ A(fs.FileSize() == 104);
+ fs.ResetFileMapping();
+ if (fs._mapStart != 0)
+ {
+ A(fs._dataSize == 104);
+ c4_String s ((char*) fs._mapStart + 100, 4);
+ A(s == "wow!");
+ }
+ }
+
+ // clear the file, so dump doesn't choke on it
+ FILE* fp = fopen("e05a", "w");
+ A(fp != 0);
+ fclose(fp);
+
+ } D(e05a); R(e05a); E;
+
+ B(e06, Rollback during extend, 0) W(e06a);
+ {
+ c4_IntProp p1 ("p1");
+ c4_Storage s1 ("e06a", 2);
+ A(s1.Strategy().FileSize() == 0);
+ c4_View v1 = s1.GetAs("a[p1:I]");
+ v1.Add(p1 [123]);
+ s1.Commit();
+ A(s1.Strategy().FileSize() == kSize1);
+
+ c4_Storage s2 ("e06a", 0);
+ c4_View v2 = s2.View("a");
+ A(v2.GetSize() == 1);
+ A(p1 (v2[0]) == 123);
+
+ v1.Add(p1 [456]);
+ s1.Commit();
+ A(s1.Strategy().FileSize() == kSize2);
+#if 0
+/* fails on NT + Samba, though it works fine with mmap'ing disabled */
+ s2.Rollback();
+
+ c4_View v2a = s2.View("a");
+ A(v2a.GetSize() == 2);
+ A(p1 (v2a[0]) == 123);
+ A(p1 (v2a[1]) == 456);
+#else
+ c4_View v2a = s2.View("a");
+ A(v2a.GetSize() == 1);
+ A(p1 (v2a[0]) == 123);
+#endif
+ } D(e06a); R(e06a); E;
+}
diff --git a/akregator/src/mk4storage/metakit/tests/tformat.cpp b/akregator/src/mk4storage/metakit/tests/tformat.cpp
new file mode 100644
index 000000000..ba6e92549
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/tformat.cpp
@@ -0,0 +1,306 @@
+// tformat.cpp -- Regression test program, (re-)format tests
+// $Id$
+// This is part of Metakit, see http://www.equi4.com/metakit/
+
+#include "regress.h"
+
+void TestFormat()
+{
+ B(f01, Add view to format, 0) W(f01a);
+ {
+ c4_IntProp p1 ("p1");
+ c4_IntProp p2 ("p2");
+ {
+ c4_Storage s1 ("f01a", 1);
+ s1.SetStructure("a[p1:I]");
+
+ c4_View v1 = s1.View("a");
+ v1.Add(p1 [123]);
+ s1.Commit();
+
+ c4_View v2 = s1.GetAs("b[p2:I]");
+
+ v2.Add(p2 [345]);
+ v2.Add(p2 [567]);
+
+ s1.Commit();
+ }
+ {
+ c4_Storage s1 ("f01a", 0);
+
+ c4_View v1 = s1.View("a");
+ A(v1.GetSize() == 1);
+ A(p1 (v1[0]) == 123);
+
+ c4_View v2 = s1.View("b");
+ A(v2.GetSize() == 2);
+ A(p2 (v2[0]) == 345);
+ A(p2 (v2[1]) == 567);
+ }
+ } D(f01a); R(f01a); E;
+
+ B(f02, Remove view from format, 0) W(f02a);
+ {
+ c4_IntProp p1 ("p1");
+ c4_IntProp p2 ("p2");
+ {
+ c4_Storage s1 ("f02a", 1);
+ s1.SetStructure("a[p1:I],b[p2:I]");
+
+ c4_View v1 = s1.View("a");
+ v1.Add(p1 [123]);
+
+ c4_View v2 = s1.View("b");
+ v2.Add(p2 [345]);
+ v2.Add(p2 [567]);
+
+ s1.Commit();
+ }
+ {
+ c4_Storage s1 ("f02a", 1);
+ s1.SetStructure("b[p2:I]");
+
+ c4_View v1 = s1.View("a");
+ A(v1.GetSize() == 1); // 19990916 new semantics, still as temp view
+ A(p1 (v1[0]) == 123);
+
+ c4_View v2 = s1.View("b");
+ A(v2.GetSize() == 2);
+ A(p2 (v2[0]) == 345);
+ A(p2 (v2[1]) == 567);
+
+ s1.Commit();
+ }
+ {
+ c4_Storage s1 ("f02a", 0);
+
+ c4_View v1 = s1.View("a");
+ A(v1.GetSize() == 0);
+
+ c4_View v2 = s1.View("b");
+ A(v2.GetSize() == 2);
+ A(p2 (v2[0]) == 345);
+ A(p2 (v2[1]) == 567);
+ }
+ } D(f02a); R(f02a); E;
+
+ B(f03, Rollback format change, 0) W(f03a);
+ {
+ c4_IntProp p1 ("p1");
+ {
+ c4_Storage s1 ("f03a", 1);
+ s1.SetStructure("a[p1:I]");
+
+ c4_View v1 = s1.View("a");
+ v1.Add(p1 [123]);
+
+ s1.Commit();
+
+ v1 = s1.GetAs("a");
+ A(v1.GetSize() == 0);
+
+ s1.Rollback();
+
+ v1 = s1.View("a");
+ A(v1.GetSize() == 1);
+ A(p1 (v1[0]) == 123);
+ }
+ } D(f03a); R(f03a); E;
+
+ B(f04, Rearrange format, 0) W(f04a);
+ {
+ c4_IntProp p1 ("p1");
+ c4_IntProp p2 ("p2");
+ {
+ c4_Storage s1 ("f04a", 1);
+ s1.SetStructure("a[p1:I],b[p2:I]");
+
+ c4_View v1 = s1.View("a");
+ v1.Add(p1 [123]);
+
+ c4_View v2 = s1.View("b");
+ v2.Add(p2 [345]);
+ v2.Add(p2 [567]);
+
+ s1.Commit();
+ }
+ {
+ c4_Storage s1 ("f04a", 1);
+ s1.SetStructure("b[p2:I],a[p1:I]");
+
+ c4_View v1 = s1.View("a");
+ A(v1.GetSize() == 1);
+ A(p1 (v1[0]) == 123);
+
+ c4_View v2 = s1.View("b");
+ A(v2.GetSize() == 2);
+ A(p2 (v2[0]) == 345);
+ A(p2 (v2[1]) == 567);
+
+ s1.Commit();
+ }
+ } D(f04a); R(f04a); E;
+
+ B(f05, Nested reformat, 0) W(f05a);
+ {
+ c4_IntProp p1 ("p1");
+ c4_IntProp p2 ("p2");
+ {
+ c4_Storage s1 ("f05a", 1);
+ s1.SetStructure("a[p1:I],b[p2:I]");
+
+ c4_View v1 = s1.View("a");
+ v1.Add(p1 [123]);
+
+ c4_View v2 = s1.View("b");
+ v2.Add(p2 [345]);
+ v2.Add(p2 [567]);
+
+ s1.Commit();
+ }
+ {
+ c4_Storage s1 ("f05a", 1);
+ s1.SetStructure("a[p1:I],b[p1:I,p2:I]");
+
+ c4_View v2 = s1.View("b");
+ p1 (v2[0]) = 543;
+ p1 (v2[1]) = 765;
+
+ s1.Commit();
+ }
+ {
+ c4_Storage s1 ("f05a", 0);
+
+ c4_View v1 = s1.View("a");
+ A(v1.GetSize() == 1);
+ A(p1 (v1[0]) == 123);
+
+ c4_View v2 = s1.View("b");
+ A(v2.GetSize() == 2);
+ A(p1 (v2[0]) == 543);
+ A(p1 (v2[1]) == 765);
+ A(p2 (v2[0]) == 345);
+ A(p2 (v2[1]) == 567);
+ }
+ } D(f05a); R(f05a); E;
+
+ B(f06, Flip foreign data, 0)
+ {
+ D(reversed); // not created here, only dump existing file
+ } E;
+
+ B(f07, Automatic structure info (obsolete), 0) W(f07a);
+ {
+/* Structure() and Store() are no longer supported
+ c4_StringProp p1 ("p1"), p2 ("p2");
+ c4_Row r1 = p1 ["One"] + p2 ["Two"];
+ c4_Row r2;
+ c4_View v1;
+ v1.Add(r1);
+ v1.Add(r2);
+ v1.Add(r1);
+
+ c4_View v2 = v1.Structure();
+ A(v2.GetSize() == 1);
+
+ c4_ViewProp pView ("view");
+ c4_View v3 = pView (v2[0]);
+ A(v3.GetSize() == 2);
+*/
+ #define FORMAT07 "dict[parent:I,index:I,view[name:S,type:S,child:I]]"
+ c4_Storage s1 ("f07a", 1);
+ s1.SetStructure(FORMAT07);
+
+ //s1.View("dict") = v1.Structure();
+
+ s1.Commit();
+
+ } D(f07a); R(f07a); E;
+
+ B(f08, Automatic storage format, 0) W(f08a);
+ {
+ c4_StringProp p1 ("p1"), p2 ("p2");
+ c4_Row r1 = p1 ["One"] + p2 ["Two"];
+ c4_Row r2;
+ c4_View v1;
+ v1.Add(r1);
+ v1.Add(r2);
+ v1.Add(r1);
+
+ c4_Storage s1 ("f08a", 1);
+
+ // changed 2000-03-15: Store is gone
+ //s1.Store("dict", v1);
+ c4_View v2 = s1.GetAs("dict[p1:S,p2:S]");
+ v2.InsertAt(0, v1);
+
+ s1.Commit();
+
+ } D(f08a); R(f08a); E;
+
+ B(f09, Partial restructuring, 0) W(f09a);
+ {
+ c4_IntProp p1 ("p1"), p2 ("p2"), p3 ("p3");
+ c4_Storage s1 ("f09a", 1);
+
+ c4_View v1 = s1.GetAs("a[p1:I]");
+ v1.SetSize(10);
+
+ for (int i = 0; i < v1.GetSize(); ++i)
+ p1 (v1[i]) = 1000 + i;
+
+ c4_View v2 = s1.GetAs("a[p1:I,p2:I]");
+
+ for (int j = 0; j < v2.GetSize(); j += 2)
+ p2 (v2[j]) = 2000 + j;
+
+ c4_View v3 = s1.GetAs("a[p1:I,p2:I,p3:I]");
+
+ for (int k = 0; k < v3.GetSize(); k += 3)
+ p3 (v3[k]) = 3000 + k;
+
+ s1.Commit();
+
+ } D(f09a); R(f09a); E;
+
+ B(f10, Committed restructuring, 0) W(f10a);
+ {
+ c4_IntProp p1 ("p1"), p2 ("p2"), p3 ("p3");
+ c4_Storage s1 ("f10a", 1);
+
+ c4_View v1 = s1.GetAs("a[p1:I]");
+ v1.SetSize(10);
+
+ for (int i = 0; i < v1.GetSize(); ++i)
+ p1 (v1[i]) = 1000 + i;
+
+ s1.Commit();
+
+ c4_View v2 = s1.GetAs("a[p1:I,p2:I]");
+
+ for (int j = 0; j < v2.GetSize(); j += 2)
+ p2 (v2[j]) = 2000 + j;
+
+ s1.Commit();
+
+ c4_View v3 = s1.GetAs("a[p1:I,p2:I,p3:I]");
+
+ for (int k = 0; k < v3.GetSize(); k += 3)
+ p3 (v3[k]) = 3000 + k;
+
+ s1.Commit();
+
+ } D(f10a); R(f10a); E;
+
+ // 19990824: don't crash on GetAs with an inexistent view
+ B(f11, Delete missing view, 0) W(f11a);
+ {
+ c4_Storage s1 ("f11a", 1);
+
+ c4_View v1 = s1.GetAs("a");
+ v1.SetSize(10);
+
+ s1.Commit();
+
+ } D(f11a); R(f11a); E;
+}
diff --git a/akregator/src/mk4storage/metakit/tests/tlimits.cpp b/akregator/src/mk4storage/metakit/tests/tlimits.cpp
new file mode 100644
index 000000000..a66ccbf05
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/tlimits.cpp
@@ -0,0 +1,282 @@
+// tlimits.cpp -- Regression test program, limit tests
+// $Id$
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit/
+
+#include "regress.h"
+
+void TestLimits()
+{
+ B(l00, Lots of properties, 0) W(l00a);
+ {
+ c4_String desc;
+
+ for (int i = 1; i < 150; ++i)
+ {
+ char buf [20];
+ sprintf(buf, ",p%d:I", i);
+
+ desc += buf;
+ }
+
+ desc = "a[" + desc.Mid(1) + "]";
+
+ c4_Storage s1 ("l00a", 1);
+ s1.SetStructure(desc);
+ c4_View v1 = s1.View("a");
+ c4_IntProp p123 ("p123");
+ v1.Add(p123 [123]);
+ s1.Commit();
+
+ } D(l00a); R(l00a); E;
+
+ B(l01, Over 32 Kb of integers, 0) W(l01a);
+ {
+ c4_Storage s1 ("l01a", 1);
+ s1.SetStructure("a[p1:I]");
+ c4_View v1 = s1.View("a");
+ c4_IntProp p1 ("p1");
+ v1.SetSize(9000);
+
+ for (int i = 0; i < v1.GetSize(); ++i)
+ {
+ p1 (v1[i]) = 1000000L + i;
+
+ A(p1 (v1[i]) - 1000000L == i);
+ }
+
+ for (int j = 0; j < v1.GetSize(); ++j)
+ {
+ A(p1 (v1[j]) - 1000000L == j);
+ }
+
+ s1.Commit();
+
+ for (int k = 0; k < v1.GetSize(); ++k)
+ {
+ A(p1 (v1[k]) - 1000000L == k);
+ }
+
+ } D(l01a); R(l01a); E;
+
+ B(l02, Over 64 Kb of strings, 0) W(l02a);
+ {
+ static char* texts[3] = { "Alice in Wonderland",
+ "The wizard of Oz",
+ "I'm singin' in the rain" };
+
+ c4_Storage s1 ("l02a", 1);
+ s1.SetStructure("a[p1:S]");
+ c4_View v1 = s1.View("a");
+ c4_StringProp p1 ("p1");
+ c4_Row r1;
+
+ for (int i = 0; i < 3500; ++i)
+ {
+ p1 (r1) = texts [i % 3];
+ v1.Add(r1);
+
+ A(p1 (v1[i]) == (c4_String) texts [i % 3]);
+ }
+
+ for (int j = 0; j < v1.GetSize(); ++j)
+ {
+ A(p1 (v1[j]) == (c4_String) texts [j % 3]);
+ }
+
+ s1.Commit();
+
+ for (int k = 0; k < v1.GetSize(); ++k)
+ {
+ A(p1 (v1[k]) == (c4_String) texts [k % 3]);
+ }
+
+ } D(l02a); R(l02a); E;
+
+ B(l03, Force sections in storage, 0) W(l03a); W(l03b);
+ {
+ c4_ViewProp p1 ("p1");
+ c4_IntProp p2 ("p2");
+
+ {
+ c4_Storage s1 ("l03a", 1);
+ s1.SetStructure("a[p1[p2:I]]");
+ c4_View v1 = s1.View("a");
+
+ c4_View v2;
+ v2.SetSize(1);
+
+ for (int i = 0; i < 500; ++i)
+ {
+ p2 (v2[0]) = 9000 + i;
+ v1.Add(p1 [v2]);
+ }
+
+ s1.Commit();
+ }
+ {
+ c4_Storage s1 ("l03a", 0);
+ c4_View v1 = s1.View("a");
+
+ for (int i = 0; i < 500; ++i)
+ {
+ c4_View v2 = p1 (v1[i]);
+ A(p2 (v2[0]) == 9000 + i);
+ }
+
+ c4_FileStream fs1 (fopen("l03b", "wb"), true);
+ s1.SaveTo(fs1);
+ }
+ {
+ c4_Storage s1;
+
+ c4_FileStream fs1 (fopen("l03b", "rb"), true);
+ s1.LoadFrom(fs1);
+
+ c4_View v1 = s1.View("a");
+
+ for (int i = 0; i < 500; ++i)
+ {
+ c4_View v2 = p1 (v1[i]);
+ A(p2 (v2[0]) == 9000 + i);
+ }
+ }
+ } D(l03a); D(l03b); R(l03a); R(l03b); E;
+
+ B(l04, Modify sections in storage, 0) W(l04a);
+ {
+ c4_ViewProp p1 ("p1");
+ c4_IntProp p2 ("p2");
+
+ {
+ c4_Storage s1 ("l04a", 1);
+ s1.SetStructure("a[p1[p2:I]]");
+ c4_View v1 = s1.View("a");
+
+ c4_View v2;
+ v2.SetSize(1);
+
+ for (int i = 0; i < 500; ++i)
+ {
+ p2 (v2[0]) = 9000 + i;
+ v1.Add(p1 [v2]);
+ }
+
+ s1.Commit();
+ }
+ {
+ c4_Storage s1 ("l04a", 1);
+ c4_View v1 = s1.View("a");
+ c4_View v2 = p1 (v1[0]);
+
+ p2 (v2[0]) = 1;
+ // this corrupted file in 1.5: free space was bad after load
+ s1.Commit();
+ }
+ {
+ c4_Storage s1 ("l04a", 0);
+ }
+ } D(l04a); R(l04a); E;
+
+ B(l05, Delete from 32 Kb of strings, 0) W(l05a);
+ {
+ static char* texts[3] = { "Alice in Wonderland",
+ "The wizard of Oz",
+ "I'm singin' in the rain" };
+
+ c4_Storage s1 ("l05a", 1);
+ s1.SetStructure("a[p1:I,p2:S,p3:S]");
+ c4_View v1 = s1.View("a");
+ c4_IntProp p1 ("p1");
+ c4_StringProp p2 ("p2"), p3 ("p3");
+ c4_Row r1;
+
+ for (int i = 0; i < 1750; ++i)
+ {
+ p1 (r1) = i;
+ p2 (r1) = texts [i % 3];
+ p3 (r1) = texts [i % 3];
+ v1.Add(r1);
+
+ A(p2 (v1[i]) == (c4_String) texts [i % 3]);
+ }
+
+ for (int j = 0; j < v1.GetSize(); ++j)
+ {
+ A(p1 (v1[j]) == j);
+ A(p2 (v1[j]) == (c4_String) texts [j % 3]);
+ A(p3 (v1[j]) == (c4_String) texts [j % 3]);
+ }
+
+ s1.Commit();
+
+ while (v1.GetSize() > 1) // randomly remove entries
+ v1.RemoveAt((unsigned short) (211 * v1.GetSize()) % v1.GetSize());
+
+ s1.Commit();
+
+ } D(l05a); R(l05a); E;
+
+ B(l06, Bit field manipulations, 0) W(l06a);
+ {
+ c4_IntProp p1 ("p1");
+ c4_View v2;
+
+ {
+ c4_Storage s1 ("l06a", 1);
+ s1.SetStructure("a[p1:I]");
+ c4_View v1 = s1.View("a");
+ c4_Row r1;
+
+ for (int i = 2; i <= 256; i <<= 1)
+ {
+ for (int j = 0; j < 18; ++j)
+ {
+ p1 (r1) = j & (i - 1);
+
+ v1.InsertAt(j, r1, j + 1);
+ v2.InsertAt(j, r1, j + 1);
+ }
+
+ s1.Commit();
+ }
+ }
+ {
+ c4_Storage s1 ("l06a", 0);
+ c4_View v1 = s1.View("a");
+
+ int n = v2.GetSize();
+ A(n == v1.GetSize());
+
+ for (int i = 0; i < n; ++i)
+ {
+ long v = p1 (v2[i]);
+ A(p1 (v1[i]) == v);
+ }
+ }
+
+ } D(l06a); R(l06a); E;
+
+ B(l07, Huge description, 0) W(l07a);
+ {
+ c4_String desc;
+
+ for (int i = 1; i < 150; ++i)
+ {
+ char buf [50];
+ // 1999-07-25: longer size to force over 4 Kb of description
+ sprintf(buf, ",a123456789a123456789a123456789p%d:I", i);
+
+ desc += buf;
+ }
+
+ desc = "a[" + desc.Mid(1) + "]";
+
+ c4_Storage s1 ("l07a", 1);
+ s1.SetStructure(desc);
+ c4_View v1 = s1.View("a");
+ c4_IntProp p123 ("p123");
+ v1.Add(p123 [123]);
+ s1.Commit();
+
+ } D(l07a); R(l07a); E;
+}
diff --git a/akregator/src/mk4storage/metakit/tests/tmapped.cpp b/akregator/src/mk4storage/metakit/tests/tmapped.cpp
new file mode 100644
index 000000000..20f8de5f2
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/tmapped.cpp
@@ -0,0 +1,244 @@
+// tmapped.cpp -- Regression test program, mapped view tests
+// $Id$
+// This is part of Metakit, see http://www.equi4.com/metakit/
+
+#include "regress.h"
+
+void TestBlockDel(int pos_, int len_)
+{
+ printf("blockdel pos %d len %d\n", pos_, len_);
+
+ c4_ViewProp p1 ("_B");
+ c4_IntProp p2 ("p2");
+
+ c4_Storage s1;
+ c4_View v1 = s1.GetAs("v1[_B[p2:I]]");
+
+ int n = 0;
+ static int sizes[] = {999, 999, 999, 2, 0};
+
+ for (int i = 0; sizes[i]; ++i) {
+ c4_View v;
+ v.SetSize(sizes[i]);
+ for (int j = 0; j < sizes[i]; ++j)
+ p2 (v[j]) = ++n;
+ v1.Add(p1 [v]);
+ }
+
+ c4_View v2 = v1.Blocked();
+ A(v2.GetSize() == 2999);
+
+ v2.RemoveAt(pos_, len_);
+ A(v2.GetSize() == 2999 - len_);
+}
+
+void TestMapped()
+{
+ B(m01, Hash mapping, 0);
+ {
+ c4_StringProp p1 ("p1");
+
+ c4_Storage s1;
+ c4_View v1 = s1.GetAs("v1[p1:S]");
+ c4_View v2 = s1.GetAs("v2[_H:I,_R:I]");
+ c4_View v3 = v1.Hash(v2, 1);
+
+ v3.Add(p1 ["b93655249726e5ef4c68e45033c2e0850570e1e07"]);
+ v3.Add(p1 ["2ab03fba463d214f854a71ab5c951cea096887adf"]);
+ v3.Add(p1 ["2e196eecb91b02c16c23360d8e1b205f0b3e3fa3d"]);
+ A(v3.GetSize() == 3);
+
+ // infinite loop in 2.4.0, reported by Nathan Rogers, July 2001
+ // happens when looking for missing key after a hash collision
+ int f = v3.Find(p1 ["7c0734c9187133f34588517fb5b39294076f22ba3"]);
+ A(f == -1);
+ } E;
+
+ // example from Steve Baxter, Nov 2001, after block perf bugfix
+ // assertion failure on row 1001, due to commit data mismatch
+ B(m02, Blocked view bug, 0) W(m02a);
+ {
+ c4_BytesProp p1 ("p1");
+ c4_Bytes h;
+
+ c4_Storage s1 ("m02a", true);
+ c4_View v1 = s1.GetAs("v1[_B[p1:B]]");
+ c4_View v2 = v1.Blocked();
+
+ for (int i = 0; i < 1005; ++i) {
+ h.SetBuffer(2500 + i);
+ v2.Add(p1 [h]);
+
+ if (i >= 999) // will crash a few rounds later, at row 1001
+ s1.Commit();
+ }
+
+ // reduce size to shorten the dump output
+ v2.RemoveAt(0, 990);
+ s1.Commit();
+
+ } D(m02a); R(m02a); E;
+
+ B(m03, Hash adds, 0) W(m03a);
+ {
+ c4_StringProp p1 ("p1");
+
+ c4_Storage s1 ("m03a", true);
+
+ c4_View d1 = s1.GetAs("d1[p1:S]");
+ c4_View m1 = s1.GetAs("m1[_H:I,_R:I]");
+ c4_View h1 = d1.Hash(m1);
+
+ h1.Add(p1 ["one"]);
+ s1.Commit();
+
+ c4_View d2 = s1.GetAs("d2[p1:S]");
+ c4_View m2 = s1.GetAs("m2[_H:I,_R:I]");
+ c4_View h2 = d2.Hash(m2);
+
+ h1.Add(p1 ["two"]);
+ h2.Add(p1 ["two"]);
+ s1.Commit();
+
+ c4_View d3 = s1.GetAs("d3[p1:S]");
+ c4_View m3 = s1.GetAs("m3[_H:I,_R:I]");
+ c4_View h3 = d3.Hash(m3);
+
+ h1.Add(p1 ["three"]);
+ h2.Add(p1 ["three"]);
+ h3.Add(p1 ["three"]);
+ s1.Commit();
+
+ c4_View d4 = s1.GetAs("d4[p1:S]");
+ c4_View m4 = s1.GetAs("m4[_H:I,_R:I]");
+ c4_View h4 = d4.Hash(m4);
+
+ h1.Add(p1 ["four"]);
+ h2.Add(p1 ["four"]);
+ h3.Add(p1 ["four"]);
+ h4.Add(p1 ["four"]);
+ s1.Commit();
+
+ } D(m03a); R(m03a); E;
+
+ B(m04, Locate bug, 0) W(m04a);
+ {
+ c4_IntProp p1 ("p1");
+ c4_StringProp p2 ("p2");
+
+ c4_Storage s1 ("m04a", true);
+ s1.AutoCommit();
+
+ c4_View v1 = s1.GetAs("v1[p1:I,p2:S]");
+
+ v1.Add(p1 [1] + p2 ["one"]);
+ v1.Add(p1 [2] + p2 ["two"]);
+ v1.Add(p1 [3] + p2 ["three"]);
+ s1.Commit();
+
+ c4_View v2 = v1.Ordered();
+ A(v2.GetSize() == 3);
+ v2.Add(p1 [6] + p2 ["six"]);
+ v2.Add(p1 [5] + p2 ["five"]);
+ v2.Add(p1 [4] + p2 ["four"]);
+ A(v2.GetSize() == 6);
+ A(v1.GetSize() == 6);
+
+ A(p1 (v1[0]) == 1);
+ A(p1 (v1[1]) == 2);
+ A(p1 (v1[2]) == 3);
+ A(p1 (v1[3]) == 4);
+ A(p1 (v1[4]) == 5);
+ A(p1 (v1[5]) == 6);
+
+ A(v2.Find(p1 [4]) == 3);
+ A(v2.Search(p1 [4]) == 3);
+
+ int i1 = -1;
+ A(v1.Locate(p1 [4], &i1) == 1);
+ A(i1 == 3);
+
+ int i2 = -1;
+ A(v2.Locate(p1 [4], &i2) == 1);
+ A(i2 == 3);
+
+ } D(m04a); R(m04a); E;
+
+ // subviews are not relocated properly with blocked views in 2.4.7
+ B(m05, Blocked view with subviews, 0) W(m05a);
+ {
+ char buf[10];
+ c4_StringProp p1 ("p1");
+ c4_IntProp p2 ("p2");
+ c4_ViewProp pSv ("sv");
+
+ c4_Storage s1 ("m05a", true);
+ c4_View v1 = s1.GetAs("v1[_B[p1:S,sv[p2:I]]]");
+ c4_View v2 = v1.Blocked();
+
+ for (int i = 0; i < 1000; ++i) {
+ sprintf(buf, "id-%d", i);
+ v2.Add(p1 [buf]);
+
+ c4_View v3 = pSv (v2[i]);
+ v3.Add(p2 [i]);
+ }
+
+ for (int j = 0; j < 1; ++j) {
+ sprintf(buf, "insert-%d", j);
+ v2.InsertAt(500, p1 [buf]);
+ }
+
+ s1.Commit();
+
+ } D(m05a); R(m05a); E;
+
+ // 2003/02/14 - assert fails for 2.4.8 in c4_Column::RemoveData
+ B(m06, Blocked view multi-row deletion, 0) W(m06a);
+ {
+ c4_IntProp p1 ("p1");
+
+ c4_Storage s1 ("m06a", true);
+ c4_View v1 = s1.GetAs("v1[p1:I]");
+ c4_View v2 = s1.GetAs("v2[_B[_H:I,_R:I]]");
+ c4_View v3 = v2.Blocked();
+ c4_View v4 = v1.Hash(v3, 1);
+
+ v4.Add(p1 [1]);
+ v4.Add(p1 [2]);
+ v4.RemoveAt(1);
+
+ for (int i = 100; i < 1000; ++i) {
+ v4.Add(p1 [i]);
+ }
+
+ s1.Commit();
+
+ } D(m06a); R(m06a); E;
+
+ // 2003/03/07 - still not correct on blocked veiw deletions
+ B(m07, All blocked view multi-deletion cases, 0);
+ {
+ int i, j;
+ for (i = 0; i < 2; ++i) {
+ for (j = 1; j < 4; ++j)
+ TestBlockDel(i, j);
+ for (j = 998; j < 1002; ++j)
+ TestBlockDel(i, j);
+ for (j = 1998; j < 2002; ++j)
+ TestBlockDel(i, j);
+ }
+ for (i = 998; i < 1002; ++i) {
+ for (j = 1; j < 4; ++j)
+ TestBlockDel(i, j);
+ for (j = 998; j < 1002; ++j)
+ TestBlockDel(i, j);
+ }
+ for (i = 1; i < 4; ++i)
+ TestBlockDel(2999 - i, i);
+ for (i = 998; i < 1002; ++i)
+ TestBlockDel(2999 - i, i);
+ for (i = 1998; i < 2002; ++i)
+ TestBlockDel(2999 - i, i);
+ } E;
+}
diff --git a/akregator/src/mk4storage/metakit/tests/tnotify.cpp b/akregator/src/mk4storage/metakit/tests/tnotify.cpp
new file mode 100644
index 000000000..e630db951
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/tnotify.cpp
@@ -0,0 +1,444 @@
+// tnotify.cpp -- Regression test program, notification tests
+// $Id$
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit/
+
+#include "regress.h"
+
+void TestNotify()
+{
+ B(n01, Add to selection, 0)
+ {
+ c4_IntProp p1 ("p1");
+ c4_View v1;
+ v1.Add(p1 [111]);
+ v1.Add(p1 [222]);
+ v1.Add(p1 [333]);
+ v1.Add(p1 [345]);
+ v1.Add(p1 [234]);
+ v1.Add(p1 [123]);
+ A(v1.GetSize() == 6);
+ c4_View v2 = v1.SelectRange(p1 [200], p1 [333]);
+ A(v2.GetSize() == 3);
+ A(p1 (v2[0]) == 222);
+ A(p1 (v2[1]) == 333);
+ A(p1 (v2[2]) == 234);
+ v1.Add(p1 [300]);
+ A(v1.GetSize() == 7);
+ A(v2.GetSize() == 4);
+ A(p1 (v2[0]) == 222);
+ A(p1 (v2[1]) == 333);
+ A(p1 (v2[2]) == 234);
+ A(p1 (v2[3]) == 300);
+ v1.Add(p1 [199]);
+ A(v1.GetSize() == 8);
+ A(v2.GetSize() == 4);
+ A(p1 (v2[0]) == 222);
+ A(p1 (v2[1]) == 333);
+ A(p1 (v2[2]) == 234);
+ A(p1 (v2[3]) == 300);
+ } E;
+
+ B(n02, Remove from selection, 0)
+ {
+ c4_IntProp p1 ("p1");
+ c4_View v1;
+ v1.Add(p1 [111]);
+ v1.Add(p1 [222]);
+ v1.Add(p1 [333]);
+ v1.Add(p1 [345]);
+ v1.Add(p1 [234]);
+ v1.Add(p1 [123]);
+ A(v1.GetSize() == 6);
+ c4_View v2 = v1.SelectRange(p1 [200], p1 [333]);
+ A(v2.GetSize() == 3);
+ A(p1 (v2[0]) == 222);
+ A(p1 (v2[1]) == 333);
+ A(p1 (v2[2]) == 234);
+ v1.RemoveAt(2);
+ A(v1.GetSize() == 5);
+ A(v2.GetSize() == 2);
+ A(p1 (v2[0]) == 222);
+ A(p1 (v2[1]) == 234);
+ v1.RemoveAt(2);
+ A(v1.GetSize() == 4);
+ A(v2.GetSize() == 2);
+ A(p1 (v2[0]) == 222);
+ A(p1 (v2[1]) == 234);
+ } E;
+
+ B(n03, Modify into selection, 0)
+ {
+ c4_IntProp p1 ("p1");
+ c4_View v1;
+ v1.Add(p1 [111]);
+ v1.Add(p1 [222]);
+ v1.Add(p1 [333]);
+ v1.Add(p1 [345]);
+ v1.Add(p1 [234]);
+ v1.Add(p1 [123]);
+ A(v1.GetSize() == 6);
+ c4_View v2 = v1.SelectRange(p1 [200], p1 [333]);
+ A(v2.GetSize() == 3);
+ A(p1 (v2[0]) == 222);
+ A(p1 (v2[1]) == 333);
+ A(p1 (v2[2]) == 234);
+ p1 (v1[5]) = 300;
+ A(v2.GetSize() == 4);
+ A(p1 (v2[0]) == 222);
+ A(p1 (v2[1]) == 333);
+ A(p1 (v2[2]) == 234);
+ A(p1 (v2[3]) == 300);
+ } E;
+
+ B(n04, Modify out of selection, 0)
+ {
+ c4_IntProp p1 ("p1");
+ c4_View v1;
+ v1.Add(p1 [111]);
+ v1.Add(p1 [222]);
+ v1.Add(p1 [333]);
+ v1.Add(p1 [345]);
+ v1.Add(p1 [234]);
+ v1.Add(p1 [123]);
+ A(v1.GetSize() == 6);
+ c4_View v2 = v1.SelectRange(p1 [200], p1 [333]);
+ A(v2.GetSize() == 3);
+ A(p1 (v2[0]) == 222);
+ A(p1 (v2[1]) == 333);
+ A(p1 (v2[2]) == 234);
+ p1 (v1[2]) = 100;
+ A(v2.GetSize() == 2);
+ A(p1 (v2[0]) == 222);
+ A(p1 (v2[1]) == 234);
+ } E;
+
+ B(n05, Add to sorted, 0)
+ {
+ c4_IntProp p1 ("p1");
+ c4_View v1;
+ v1.Add(p1 [111]);
+ v1.Add(p1 [222]);
+ v1.Add(p1 [333]);
+ v1.Add(p1 [345]);
+ v1.Add(p1 [234]);
+ v1.Add(p1 [123]);
+ A(v1.GetSize() == 6);
+ c4_View v2 = v1.Sort();
+ A(v2.GetSize() == 6);
+ A(p1 (v2[0]) == 111);
+ A(p1 (v2[1]) == 123);
+ A(p1 (v2[2]) == 222);
+ A(p1 (v2[3]) == 234);
+ A(p1 (v2[4]) == 333);
+ A(p1 (v2[5]) == 345);
+ v1.Add(p1 [300]);
+ A(v2.GetSize() == 7);
+ A(p1 (v2[0]) == 111);
+ A(p1 (v2[1]) == 123);
+ A(p1 (v2[2]) == 222);
+ A(p1 (v2[3]) == 234);
+ A(p1 (v2[4]) == 300);
+ A(p1 (v2[5]) == 333);
+ A(p1 (v2[6]) == 345);
+ } E;
+
+ B(n06, Remove from sorted, 0)
+ {
+ c4_IntProp p1 ("p1");
+ c4_View v1;
+ v1.Add(p1 [111]);
+ v1.Add(p1 [222]);
+ v1.Add(p1 [333]);
+ v1.Add(p1 [345]);
+ v1.Add(p1 [234]);
+ v1.Add(p1 [123]);
+ A(v1.GetSize() == 6);
+ c4_View v2 = v1.Sort();
+ A(v2.GetSize() == 6);
+ A(p1 (v2[0]) == 111);
+ A(p1 (v2[1]) == 123);
+ A(p1 (v2[2]) == 222);
+ A(p1 (v2[3]) == 234);
+ A(p1 (v2[4]) == 333);
+ A(p1 (v2[5]) == 345);
+ v1.RemoveAt(2);
+ A(v2.GetSize() == 5);
+ A(p1 (v2[0]) == 111);
+ A(p1 (v2[1]) == 123);
+ A(p1 (v2[2]) == 222);
+ A(p1 (v2[3]) == 234);
+ A(p1 (v2[4]) == 345);
+ } E;
+
+ B(n07, New property through sort, 0)
+ {
+ c4_IntProp p1 ("p1"), p2 ("p2");
+ c4_View v1;
+ v1.Add(p1 [11]);
+ v1.Add(p1 [1]);
+ v1.Add(p1 [111]);
+ A(v1.FindProperty(p2.GetId()) < 0);
+
+ c4_View v2 = v1.SortOn(p1);
+ A(v2.FindProperty(p2.GetId()) < 0);
+
+ A(v2.GetSize() == 3);
+ A(p1 (v2[0]) == 1);
+ A(p1 (v2[1]) == 11);
+ A(p1 (v2[2]) == 111);
+
+ p2 (v1[0]) = 22;
+ A(v1.FindProperty(p2.GetId()) == 1);
+ A(v2.FindProperty(p2.GetId()) == 1);
+
+ A(p2 (v2[1]) == 22);
+ } E;
+
+ B(n08, Nested project and select, 0)
+ {
+ c4_IntProp p1 ("p1"), p2 ("p2");
+ c4_View v1;
+ v1.Add(p1 [10] + p2 [1]);
+ v1.Add(p1 [11]);
+ v1.Add(p1 [12] + p2 [1]);
+ v1.Add(p1 [13]);
+ v1.Add(p1 [14] + p2 [1]);
+ v1.Add(p1 [15]);
+ v1.Add(p1 [16] + p2 [1]);
+ A(v1.GetSize() == 7);
+
+ c4_View v2 = v1.Select(p2 [1]);
+ A(v2.GetSize() == 4);
+ A(p1 (v2[0]) == 10);
+ A(p1 (v2[1]) == 12);
+ A(p1 (v2[2]) == 14);
+ A(p1 (v2[3]) == 16);
+
+ c4_View v3 = v2.Project(p1);
+ A(v3.GetSize() == 4);
+ A(p1 (v3[0]) == 10);
+ A(p1 (v3[1]) == 12);
+ A(p1 (v3[2]) == 14);
+ A(p1 (v3[3]) == 16);
+
+ A(p2 (v3[0]) == 0);
+ A(p2 (v3[1]) == 0);
+ A(p2 (v3[2]) == 0);
+ A(p2 (v3[3]) == 0);
+
+/* not yet implemented: setting result of selection
+ p1 (v3[1]) = 123;
+ A(p1 (v3[1]) == 123);
+ A(p1 (v2[1]) == 123);
+ A(p1 (v1[2]) == 123);
+*/
+ } E;
+
+ B(n09, Multiple dependencies, 0)
+ {
+ c4_IntProp p1 ("p1"), p2 ("p2");
+ c4_View v1;
+ v1.Add(p1 [111] + p2[1111]);
+ v1.Add(p1 [222]);
+ v1.Add(p1 [333]);
+ v1.Add(p1 [345]);
+ v1.Add(p1 [234]);
+ v1.Add(p1 [123]);
+ A(v1.GetSize() == 6);
+
+ c4_View v2 = v1.SelectRange(p1 [200], p1 [333]);
+ A(v2.GetSize() == 3);
+ A(p1 (v2[0]) == 222);
+ A(p1 (v2[1]) == 333);
+ A(p1 (v2[2]) == 234);
+
+ c4_View v3 = v1.SelectRange(p1 [340], p1 [350]);
+ A(v3.GetSize() == 1);
+ A(p1 (v3[0]) == 345);
+
+ c4_View v4 = v2.SortOn(p1);
+ A(v4.GetSize() == 3);
+ A(p1 (v4[0]) == 222);
+ A(p1 (v4[1]) == 234);
+ A(p1 (v4[2]) == 333);
+
+ c4_View v5 = v3.SortOn(p1);
+ A(v5.GetSize() == 1);
+ A(p1 (v5[0]) == 345);
+
+ p1 (v1[2]) = 346;
+
+ A(v2.GetSize() == 2);
+ A(p1 (v2[0]) == 222);
+ A(p1 (v2[1]) == 234);
+
+ A(v3.GetSize() == 2);
+ A(p1 (v3[0]) == 346);
+ A(p1 (v3[1]) == 345);
+
+ A(v4.GetSize() == 2);
+ A(p1 (v4[0]) == 222);
+ A(p1 (v4[1]) == 234);
+
+ A(v5.GetSize() == 2);
+ A(p1 (v5[0]) == 345);
+ A(p1 (v5[1]) == 346);
+ } E;
+
+ B(n10, Modify sorted duplicates, 0)
+ {
+ c4_IntProp p1 ("p1");
+ c4_View v1;
+ v1.SetSize(3);
+ p1 (v1[0]) = 0;
+ c4_View v2 = v1.Sort();
+ p1 (v1[0]) = 1;
+ p1 (v1[1]) = 1; // crashed in 1.5, fix in: c4_SortSeq::PosInMap
+ } E;
+
+ B(n11, Resize compound derived view, 0)
+ {
+ c4_IntProp p1 ("p1"), p2 ("p2");
+ c4_View v1 = (p1, p2);
+ c4_View v2 = v1.SelectRange(p2 [200], p2 [333]);
+ c4_View v3 = v2.SortOn(p1);
+ A(v2.GetSize() == 0);
+ A(v3.GetSize() == 0);
+ v1.SetSize(1); // crashed in 1.5, fix in: c4_FilterSeq::Match
+ A(v1.GetSize() == 1);
+ A(v2.GetSize() == 0);
+ A(v3.GetSize() == 0);
+ v1[0] = p2 [300];
+ A(v1.GetSize() == 1);
+ A(v2.GetSize() == 1);
+ A(v3.GetSize() == 1);
+ A(p2 (v2[0]) == 300);
+ v1.Add(p1 [199]);
+ A(v1.GetSize() == 2);
+ A(v2.GetSize() == 1);
+ A(p2 (v2[0]) == 300);
+ } E;
+
+ B(n12, Alter multiply derived view, 0)
+ {
+ c4_IntProp p1 ("p1");
+ c4_StringProp p2 ("p2"), p3 ("p3");
+ c4_View v1 = (p1, p2);
+ c4_View v2 = v1.Select(p1 [1]);
+ c4_View v3 = v2.SortOn(p2);
+ c4_View v4 = v1.Select(p1 [2]);
+ c4_View v5 = v4.SortOn(p2);
+
+ v1.Add(p1[1] + p2 ["een"] + p3 ["1"]);
+ v1.Add(p1[1] + p2 ["elf"] + p3 ["11"]);
+ v1.Add(p1[2] + p2 ["twee"] + p3 ["2"]);
+ v1.Add(p1[2] + p2 ["twaalf"] + p3 ["12"]);
+ v1.Add(p1[2] + p2 ["twintig"] + p3 ["20"]);
+ v1.Add(p1[2] + p2 ["tachtig"] + p3 ["80"]);
+
+ A(v1.GetSize() == 6);
+ A(v2.GetSize() == 2);
+ A(v3.GetSize() == 2);
+ A(v4.GetSize() == 4);
+ A(v5.GetSize() == 4);
+
+ A(p3 (v1[2]) == (c4_String) "2");
+ A(p3 (v4[0]) == (c4_String) "2");
+
+ A(p3 (v3[0]) == (c4_String) "1");
+ A(p3 (v3[1]) == (c4_String) "11");
+
+ A(p3 (v5[0]) == (c4_String) "80");
+ A(p3 (v5[1]) == (c4_String) "12");
+ A(p3 (v5[2]) == (c4_String) "2");
+ A(p3 (v5[3]) == (c4_String) "20");
+
+ v1[3] = p1[2] + p2 ["twaalf"] + p3 ["12+"];
+
+ A(p3 (v3[0]) == (c4_String) "1");
+ A(p3 (v3[1]) == (c4_String) "11");
+
+ A(p3 (v1[3]) == (c4_String) "12+");
+ A(p3 (v4[1]) == (c4_String) "12+");
+
+ A(p3 (v5[0]) == (c4_String) "80");
+ A(p3 (v5[1]) == (c4_String) "12+");
+ A(p3 (v5[2]) == (c4_String) "2");
+ A(p3 (v5[3]) == (c4_String) "20");
+ } E;
+
+ B(n13, Project without, 0) // failed in 1.8.4
+ {
+ c4_IntProp p1 ("p1"), p2 ("p2");
+ c4_View v1;
+
+ v1.Add(p1 [1] + p2 [2]);
+ int n1 = v1.NumProperties();
+ A(n1 == 2);
+
+ c4_View v2 = v1.ProjectWithout(p2);
+ int n2 = v2.NumProperties();
+ A(n2 == 1);
+ } E;
+
+/*
+ B(n14, Add to reverse sorted, 0)
+ {
+ c4_IntProp p1 ("p1"), p2 ("p2");
+ c4_View v1;
+ v1.Add(p1 [333] + p2 [1]);
+ v1.Add(p1 [345] + p2 [1]);
+ v1.Add(p1 [234] + p2 [1]);
+ v1.Add(p1 [123] + p2 [0]);
+ A(v1.GetSize() == 4);
+ c4_View v1a = v1.Select(p2 [1]);
+ A(v1a.GetSize() == 3);
+ c4_View v1b = v1a.SelectRange(p1 [100], p1 [999]);
+ A(v1b.GetSize() == 3);
+ c4_View v2 = v1b.SortOnReverse(p1, p1);
+ A(v2.GetSize() == 3);
+ A(p1 (v2[0]) == 345);
+ A(p1 (v2[1]) == 333);
+ A(p1 (v2[2]) == 234);
+ v1.Add(p1 [300] + p2 [1]);
+ A(v2.GetSize() == 4);
+ A(p1 (v2[0]) == 345);
+ A(p1 (v2[1]) == 333);
+ A(p1 (v2[2]) == 300);
+ A(p1 (v2[3]) == 234);
+ v1.Add(p1 [299] + p2 [1]);
+ A(v2.GetSize() == 5);
+ A(p1 (v2[0]) == 345);
+ A(p1 (v2[1]) == 333);
+ A(p1 (v2[2]) == 300);
+ A(p1 (v2[3]) == 299);
+ A(p1 (v2[4]) == 234);
+ } E;
+*/
+ // this failed in 2.4.8, reported by S. Selznick, 2002-11-22
+ B(n14, Insert in non-mapped position, 0) W(n14a);
+ {
+ c4_IntProp p1 ("p1");
+ c4_Storage s1 ("n14a", 1);
+ s1.SetStructure("a[p1:I]");
+ c4_View v1 = s1.View("a");
+
+ static int intlist[] = { 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, -1 };
+ for (int c = 0; -1 != intlist[c]; c++)
+ v1.Add(p1 [intlist[c]]);
+
+ A(v1.GetSize() == 10);
+ c4_View v2 = v1.Select(p1 [1]);
+ A(v2.GetSize() == 3);
+
+ v1.InsertAt(3, p1 [6]);
+ A(v1.GetSize() == 11);
+ A(v2.GetSize() == 3);
+
+ v1.InsertAt(7, p1 [1]);
+ A(v1.GetSize() == 12);
+ A(v2.GetSize() == 4);
+
+ s1.Commit();
+ } D(n14a); R(n14a); E;
+}
diff --git a/akregator/src/mk4storage/metakit/tests/tresize.cpp b/akregator/src/mk4storage/metakit/tests/tresize.cpp
new file mode 100644
index 000000000..e6011090d
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/tresize.cpp
@@ -0,0 +1,289 @@
+// trseize.cpp -- Regression test program, resizing tests
+// $Id$
+// This is part of Metakit, see http://www.equi4.com/metakit/
+
+#include "regress.h"
+
+#include <stdlib.h> // strtol
+#include <string.h> // memory functions
+
+class CResizer : public c4_Storage
+{
+public:
+ CResizer (const char* file);
+ ~CResizer ();
+
+ void Verify();
+
+ int Ins(int, int);
+ int Del(int, int);
+
+private:
+ enum { kMaxData = 15000 };
+ char* _refData;
+ int _refSize;
+
+ c4_View _attached;
+ c4_View _unattached;
+ c4_IntProp _prop;
+
+ char _seed;
+
+ CResizer (const CResizer&); // not implemented
+ void operator= (const CResizer&); // not implemented
+};
+
+CResizer::CResizer (const char* file)
+ : c4_Storage (file, 1), _refSize (0), _prop ("p1"), _seed (0)
+{
+ SetStructure("a[p1:I]");
+
+ _refData = new char [kMaxData];
+
+ _attached = View("a");
+
+ Verify();
+}
+
+CResizer::~CResizer ()
+{
+ Verify();
+
+ Commit();
+
+ Verify();
+
+ delete [] _refData;
+}
+
+void CResizer::Verify()
+{
+ int i;
+
+ A(_refSize == _unattached.GetSize());
+ A(_refSize == _attached.GetSize());
+
+ for (i = 0; i < _refSize; ++i)
+ {
+ A(_refData[i] == _prop (_unattached[i]));
+ A(_refData[i] == _prop (_attached[i]));
+ }
+}
+
+int CResizer::Ins(int pos_, int cnt_)
+{
+ A(pos_ <= _refSize);
+ A(_refSize + cnt_ < kMaxData);
+
+ memmove(_refData + pos_ + cnt_, _refData + pos_, _refSize - pos_);
+ _refSize += cnt_;
+
+ c4_Row row;
+ _unattached.InsertAt(pos_, row, cnt_);
+ _attached.InsertAt(pos_, row, cnt_);
+
+ for (int i = pos_; i < pos_ + cnt_; ++i)
+ {
+ _refData[i] = ++_seed;
+ _prop (_unattached[i]) = _seed;
+ _prop (_attached[i]) = _seed;
+
+ if (_seed >= 123)
+ _seed = 0;
+ }
+
+ Verify();
+
+ return _refSize;
+}
+
+int CResizer::Del(int pos_, int cnt_)
+{
+ A(pos_ + cnt_ <= _refSize);
+
+ _refSize -= cnt_;
+ memmove(_refData + pos_, _refData + pos_ + cnt_, _refSize - pos_);
+
+ _unattached.RemoveAt(pos_, cnt_);
+ _attached.RemoveAt(pos_, cnt_);
+
+ Verify();
+
+ return _refSize;
+}
+
+void TestResize()
+{
+ B(r00, Simple insert, 0) W(r00a);
+ {
+ CResizer r1 ("r00a");
+
+ int n = r1.Ins(0, 250);
+ A(n == 250);
+
+ } D(r00a); R(r00a); E;
+
+ B(r01, Simple removes, 0) W(r01a);
+ {
+ CResizer r1 ("r01a");
+ int n;
+
+ n = r1.Ins( 0, 500); A(n == 500);
+
+ n = r1.Del( 0, 50); A(n == 450);
+ n = r1.Del( 350, 100); A(n == 350);
+ n = r1.Del( 25, 150); A(n == 200);
+ n = r1.Del( 0, 200); A(n == 0);
+
+ n = r1.Ins( 0, 15); A(n == 15);
+
+ } D(r01a); R(r01a); E;
+
+ B(r02, Large inserts and removes, 0) W(r02a);
+ {
+ int big = sizeof (int) == sizeof (short) ? 1000 : 4000;
+
+ CResizer r1 ("r02a");
+ int n;
+
+ n = r1.Ins( 0, 2000); A(n == 2000);
+ n = r1.Ins( 0, 3000); A(n == 5000);
+ n = r1.Ins(5000, 1000 + big); A(n == 6000 + big);
+ n = r1.Ins( 100, 10); A(n == 6010 + big);
+ n = r1.Ins(4000, 100); A(n == 6110 + big);
+ n = r1.Ins( 0, 1001); A(n == 7111 + big);
+
+ n = r1.Del(7111, big); A(n == 7111);
+ n = r1.Del( 0, 4111); A(n == 3000);
+ n = r1.Del( 10, 10); A(n == 2990);
+ n = r1.Del( 10, 10); A(n == 2980);
+ n = r1.Del( 5, 10); A(n == 2970);
+ n = r1.Del( 0, 990); A(n == 1980);
+ n = r1.Del( 3, 1975); A(n == 5);
+
+ } D(r02a); R(r02a); E;
+
+ B(r03, Binary property insertions, 0) W(r03a);
+ {
+ c4_BytesProp p1 ("p1");
+ c4_Storage s1 ("r03a", 1);
+ s1.SetStructure("a[p1:B]");
+ c4_View v1 = s1.View("a");
+
+ char buf [1024];
+
+ memset(buf, 0x11, sizeof buf);
+ v1.Add(p1 [c4_Bytes (buf, sizeof buf)]);
+
+ memset(buf, 0x22, sizeof buf);
+ v1.Add(p1 [c4_Bytes (buf, sizeof buf / 2)]);
+
+ s1.Commit();
+
+ memset(buf, 0x33, sizeof buf);
+ p1 (v1[1]) = c4_Bytes (buf, sizeof buf); // fix c4_Column::CopyData
+
+ memset(buf, 0x44, sizeof buf);
+ v1.Add(p1 [c4_Bytes (buf, sizeof buf / 3)]);
+
+ s1.Commit();
+
+ memset(buf, 0x55, sizeof buf);
+ v1.InsertAt(1, p1 [c4_Bytes (buf, sizeof buf)]);
+
+ memset(buf, 0x66, sizeof buf);
+ v1.InsertAt(1, p1 [c4_Bytes (buf, sizeof buf / 4)]);
+
+ s1.Commit();
+
+ } D(r03a); R(r03a); E;
+
+ B(r04, Scripted string property tests, 0) W(r04a);
+ {
+ c4_StringProp p1 ("p1");
+ c4_Storage s1 ("r04a", 1);
+ s1.SetStructure("a[p1:S]");
+
+ // This code implements a tiny language to specify tests in:
+ //
+ // "<X>,<Y>A" add X partial buffers of size Y
+ // "<X>a" add X full buffers at end
+ // "<X>,<Y>C" change entry X to a partial buffer of size Y
+ // "<X>c" change entry at position X to a full buffer
+ // "<X>,<Y>I" insert partial buffer of size Y at position X
+ // "<X>i" insert a full buffer at position X
+ // "<X>,<Y>R" remove Y entries at position X
+ // "<X>r" remove one entry at position X
+ //
+ // ">" commit changes
+ // "<" rollback changes
+ //
+ // " " ignore spaces
+ // "<X>," for additional args
+ // "<X>=" verify number of rows is X
+
+ const char* scripts [] =
+ {
+ // A B C D E F G H I J
+ "5a 5a 5a 1r 5r 10r 6r 2r > 10=",
+ "5a 5a 5a 1,200C 5,200C 10,200C 6,200C 2,200C > 15=",
+ "5a 5a 5a 1,300C 5,300C 10,300C 6,300C 2,300C > 15=",
+
+ // A B C D E F G H I J
+ "50a 50a 50a 10r 50r 100r 60r 20r > 145=",
+ "50a 50a 50a 10,200C 50,200C 100,200C 60,200C 20,200C > 150=",
+ "50a 50a 50a 10,300C 50,300C 100,300C 60,300C 20,300C > 150=",
+
+ // A B C D E F G H I J
+ "50,0A 50,0A 50,0A 10c 50c 100c 60c 20c > 150=", // asserts in 1.7b1
+
+ // A B C D E
+ "3,3A 1,10C 1,1C > 3=", // asserts in 1.7 - June 6 build
+
+ "",
+ 0
+ };
+
+ for (int i = 0; scripts[i]; ++i)
+ {
+ c4_View v1 = s1.View("a");
+ v1.RemoveAll();
+ s1.Commit();
+ A(v1.GetSize() == 0); // start with a clean slate each time
+
+ const char* p = scripts[i];
+
+ char fill = '@';
+ int save = 0;
+ c4_Row row;
+
+ while (*p)
+ {
+ // default is a string of 255 chars (with additional null byte)
+ p1 (row) = c4_String (++fill, 255);
+
+ int arg = (int) strtol(p, (char**) &p, 10); // loses const
+
+ switch (*p++)
+ {
+ case 'A': p1 (row) = c4_String (fill, arg); arg = save;
+ case 'a': while (--arg >= 0) v1.Add(row); break;
+ case 'C': p1 (row) = c4_String (fill, arg); arg = save;
+ case 'c': v1.SetAt(arg, row); break;
+ case 'I': p1 (row) = c4_String (fill, arg); arg = save;
+ case 'i': v1.InsertAt(arg, row); break;
+ case 'R': v1.RemoveAt(save, arg); break;
+ case 'r': v1.RemoveAt(arg); break;
+ case '>': s1.Commit(); break;
+ case '<': s1.Rollback(); v1 = s1.View("a"); break;
+ case ' ': break;
+ case ',': save = arg; break;
+ case '=': A(v1.GetSize() == arg); break;
+ }
+ }
+ }
+
+ s1.Commit();
+
+ } D(r04a); R(r04a); E;
+}
diff --git a/akregator/src/mk4storage/metakit/tests/tstore1.cpp b/akregator/src/mk4storage/metakit/tests/tstore1.cpp
new file mode 100644
index 000000000..c071648a6
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/tstore1.cpp
@@ -0,0 +1,180 @@
+// tstore1.cpp -- Regression test program, storage tests, part 1
+// $Id$
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit/
+
+#include "regress.h"
+
+void TestStores1()
+{
+ B(s00, Simple storage, 0) W(s00a);
+ {
+ c4_Storage s1 ("s00a", 1);
+ s1.SetStructure("a[p1:I]");
+ s1.Commit();
+ } D(s00a); R(s00a); E;
+
+ B(s01, Integer storage, 0) W(s01a);
+ {
+ c4_IntProp p1 ("p1");
+ c4_Storage s1 ("s01a", 1);
+ s1.SetStructure("a[p1:I]");
+ c4_View v1 = s1.View("a");
+ v1.Add(p1 [123]);
+ v1.Add(p1 [456]);
+ v1.InsertAt(1, p1 [789]);
+ A(v1.GetSize() == 3);
+ s1.Commit();
+ A(v1.GetSize() == 3);
+ } D(s01a); R(s01a); E;
+
+#if !q4_TINY
+ B(s02, Float storage, 0) W(s02a);
+ {
+ c4_FloatProp p1 ("p1");
+ c4_Storage s1 ("s02a", 1);
+ s1.SetStructure("a[p1:F]");
+ c4_View v1 = s1.View("a");
+ v1.Add(p1 [12.3]);
+ v1.Add(p1 [45.6]);
+ v1.InsertAt(1, p1 [78.9]);
+ s1.Commit();
+ } D(s02a); R(s02a); E;
+#endif
+
+ B(s03, String storage, 0) W(s03a);
+ {
+ c4_StringProp p1 ("p1");
+ c4_Storage s1 ("s03a", 1);
+ s1.SetStructure("a[p1:S]");
+ c4_View v1 = s1.View("a");
+ v1.Add(p1 ["one"]);
+ v1.Add(p1 ["two"]);
+ v1.InsertAt(1, p1 ["three"]);
+ s1.Commit();
+ } D(s03a); R(s03a); E;
+
+ B(s04, View storage, 0) W(s04a);
+ {
+ c4_StringProp p1 ("p1");
+ c4_ViewProp p2 ("p2");
+ c4_IntProp p3 ("p3");
+ c4_Storage s1 ("s04a", 1);
+ s1.SetStructure("a[p1:S,p2[p3:I]]");
+ c4_View v1 = s1.View("a");
+ v1.Add(p1 ["one"]);
+ v1.Add(p1 ["two"]);
+ c4_View v2 = p2 (v1[0]);
+ v2.Add(p3 [1]);
+ v2 = p2 (v1[1]);
+ v2.Add(p3 [11]);
+ v2.Add(p3 [22]);
+ v1.InsertAt(1, p1 ["three"]);
+ v2 = p2 (v1[1]);
+ v2.Add(p3 [111]);
+ v2.Add(p3 [222]);
+ v2.Add(p3 [333]);
+ s1.Commit();
+ } D(s04a); R(s04a); E;
+
+ B(s05, Store and reload, 0) W(s05a);
+ {
+ c4_IntProp p1 ("p1");
+ {
+ c4_Storage s1 ("s05a", 1);
+ s1.SetStructure("a[p1:I]");
+ c4_View v1 = s1.View("a");
+ v1.Add(p1 [123]);
+ s1.Commit();
+ }
+ {
+ c4_Storage s1 ("s05a", 0);
+ c4_View v1 = s1.View("a");
+ A(v1.GetSize() == 1);
+ A(p1 (v1[0]) == 123);
+ }
+ } D(s05a); R(s05a); E;
+
+ B(s06, Commit twice, 0) W(s06a);
+ {
+ c4_IntProp p1 ("p1");
+ {
+ c4_Storage s1 ("s06a", 1);
+ s1.SetStructure("a[p1:I]");
+ c4_View v1 = s1.View("a");
+ v1.Add(p1 [123]);
+ s1.Commit();
+ v1.Add(p1 [234]);
+ s1.Commit();
+ }
+ {
+ c4_Storage s1 ("s06a", 0);
+ c4_View v1 = s1.View("a");
+ A(v1.GetSize() == 2);
+ A(p1 (v1[0]) == 123);
+ A(p1 (v1[1]) == 234);
+ }
+ } D(s06a); R(s06a); E;
+
+ B(s07, Commit modified, 0) W(s07a);
+ {
+ c4_IntProp p1 ("p1");
+ {
+ c4_Storage s1 ("s07a", 1);
+ s1.SetStructure("a[p1:I]");
+ c4_View v1 = s1.View("a");
+ v1.Add(p1 [123]);
+ s1.Commit();
+ p1 (v1[0]) = 234;
+ s1.Commit();
+ }
+ {
+ c4_Storage s1 ("s07a", 0);
+ c4_View v1 = s1.View("a");
+ A(v1.GetSize() == 1);
+ A(p1 (v1[0]) == 234);
+ }
+ } D(s07a); R(s07a); E;
+
+ B(s08, View after storage, 0) W(s08a);
+ {
+ c4_IntProp p1 ("p1");
+ {
+ c4_Storage s1 ("s08a", 1);
+ s1.SetStructure("a[p1:I]");
+ c4_View v1 = s1.View("a");
+ v1.Add(p1 [123]);
+ s1.Commit();
+ }
+ c4_View v1;
+ {
+ c4_Storage s1 ("s08a", 0);
+ v1 = s1.View("a");
+ }
+ // 19990916 - semantics changed, view now 1 row, but 0 props
+ A(v1.GetSize() == 1);
+ A(v1.NumProperties() == 0);
+ v1.InsertAt(0, p1 [234]);
+ A(v1.GetSize() == 2);
+ A(p1 (v1[0]) == 234);
+ A(p1 (v1[1]) == 0); // the original value is gone
+ } D(s08a); R(s08a); E;
+
+ B(s09, Copy storage, 0) W(s09a); W(s09b);
+ {
+ c4_IntProp p1 ("p1");
+ {
+ c4_Storage s1 ("s09a", 1);
+ s1.SetStructure("a[p1:I]");
+ c4_View v1 = s1.View("a");
+ v1.Add(p1 [123]);
+ s1.Commit();
+ }
+ {
+ c4_Storage s1 ("s09a", 0);
+ c4_Storage s2 ("s09b", 1);
+ s2.SetStructure("a[p1:I]");
+ s2.View("a") = s1.View("a");
+ s2.Commit();
+ }
+ } D(s09a); D(s09b); R(s09a); R(s09b); E;
+}
diff --git a/akregator/src/mk4storage/metakit/tests/tstore2.cpp b/akregator/src/mk4storage/metakit/tests/tstore2.cpp
new file mode 100644
index 000000000..371ffcca5
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/tstore2.cpp
@@ -0,0 +1,326 @@
+// tstore2.cpp -- Regression test program, storage tests, part 2
+// $Id$
+// This is part of Metakit, see http://www.equi4.com/metakit/
+
+#include "regress.h"
+
+void TestStores2()
+{
+ B(s10, Stream storage, 0) W(s10a); W(s10b); W(s10c);
+ {
+ // s10a is original
+ // s10b is a copy, random access
+ // s10c is a serialized copy
+ c4_StringProp p1 ("p1");
+ c4_ViewProp p2 ("p2");
+ c4_IntProp p3 ("p3");
+ {
+ c4_Storage s1 ("s10a", 1);
+ s1.SetStructure("a[p1:S,p2[p3:I]]");
+ c4_View v1 = s1.View("a");
+ v1.Add(p1 ["one"]);
+ v1.Add(p1 ["two"]);
+ c4_View v2 = p2 (v1[0]);
+ v2.Add(p3 [1]);
+ v2 = p2 (v1[1]);
+ v2.Add(p3 [11]);
+ v2.Add(p3 [22]);
+ v1.InsertAt(1, p1 ["three"]);
+ v2 = p2 (v1[1]);
+ v2.Add(p3 [111]);
+ v2.Add(p3 [222]);
+ v2.Add(p3 [333]);
+ s1.Commit();
+ }
+ {
+ c4_Storage s1 ("s10a", 0);
+ c4_Storage s2 ("s10b", 1);
+ s2.SetStructure("a[p1:S,p2[p3:I]]");
+ s2.View("a") = s1.View("a");
+ s2.Commit();
+ }
+ {
+ c4_Storage s3 ("s10b", 0);
+
+ c4_FileStream fs1 (fopen("s10c", "wb"), true);
+ s3.SaveTo(fs1);
+ }
+ {
+ c4_Storage s1 ("s10c", 0); // new after 2.01: serialized is no longer special
+
+ c4_View v1 = s1.View("a");
+ A(v1.GetSize() == 3);
+ c4_View v2 = p2 (v1[0]);
+ A(v2.GetSize() == 1);
+ c4_View v3 = p2 (v1[1]);
+ A(v3.GetSize() == 3);
+ c4_View v4 = p2 (v1[2]);
+ A(v4.GetSize() == 2);
+ }
+ {
+ c4_Storage s1;
+
+ c4_FileStream fs1 (fopen("s10c", "rb"), true);
+ s1.LoadFrom(fs1);
+
+ c4_View v1 = s1.View("a");
+ A(v1.GetSize() == 3);
+ c4_View v2 = p2 (v1[0]);
+ A(v2.GetSize() == 1);
+ c4_View v3 = p2 (v1[1]);
+ A(v3.GetSize() == 3);
+ c4_View v4 = p2 (v1[2]);
+ A(v4.GetSize() == 2);
+ }
+ {
+ c4_Storage s1 ("s10c", 1);
+
+ c4_View v1 = s1.View("a");
+ A(v1.GetSize() == 3);
+ c4_View v2 = p2 (v1[0]);
+ A(v2.GetSize() == 1);
+ c4_View v3 = p2 (v1[1]);
+ A(v3.GetSize() == 3);
+ c4_View v4 = p2 (v1[2]);
+ A(v4.GetSize() == 2);
+ v1.Add(p1 ["four"]);
+ s1.Commit();
+ }
+ {
+ c4_Storage s1 ("s10c", 0);
+ c4_View v1 = s1.View("a");
+ A(v1.GetSize() == 4);
+ c4_View v2 = p2 (v1[0]);
+ A(v2.GetSize() == 1);
+ c4_View v3 = p2 (v1[1]);
+ A(v3.GetSize() == 3);
+ c4_View v4 = p2 (v1[2]);
+ A(v4.GetSize() == 2);
+ c4_View v5 = p2 (v1[3]);
+ A(v5.GetSize() == 0);
+ }
+ } D(s10a); D(s10b); D(s10c); R(s10a); R(s10b); R(s10c); E;
+
+ B(s11, Commit and rollback, 0) W(s11a);
+ {
+ c4_IntProp p1 ("p1");
+ {
+ c4_Storage s1 ("s11a", 1);
+ s1.SetStructure("a[p1:I]");
+ c4_View v1 = s1.View("a");
+ v1.Add(p1 [123]);
+ s1.Commit();
+ }
+ {
+ c4_Storage s1 ("s11a", 0);
+ c4_View v1 = s1.View("a");
+ A(v1.GetSize() == 1);
+ A(p1 (v1[0]) == 123);
+ v1.InsertAt(0, p1 [234]);
+ A(v1.GetSize() == 2);
+ A(p1 (v1[0]) == 234);
+ A(p1 (v1[1]) == 123);
+ s1.Rollback();
+ // 19990916 - semantics changed, still 2 rows, but 0 props
+ A(v1.GetSize() == 2);
+ A(v1.NumProperties() == 0);
+ v1 = s1.View("a");
+ A(v1.GetSize() == 1);
+ A(p1 (v1[0]) == 123);
+ }
+ } D(s11a); R(s11a); E;
+
+ B(s12, Remove subview, 0) W(s12a);
+ {
+ c4_IntProp p1 ("p1"), p3 ("p3");
+ c4_ViewProp p2 ("p2");
+ {
+ c4_Storage s1 ("s12a", 1);
+ s1.SetStructure("a[p1:I,p2[p3:I]]");
+ c4_View v1 = s1.View("a");
+ c4_View v2;
+ v2.Add(p3 [234]);
+ v1.Add(p1 [123] + p2 [v2]);
+ s1.Commit();
+ }
+ {
+ c4_Storage s1 ("s12a", 1);
+ c4_View v1 = s1.View("a");
+ A(v1.GetSize() == 1);
+ A(p1 (v1[0]) == 123);
+ c4_View v2 = p2 (v1[0]);
+ A(v2.GetSize() == 1);
+ A(p3 (v2[0]) == 234);
+ v1.RemoveAt(0);
+ A(v1.GetSize() == 0);
+ s1.Commit();
+ A(v1.GetSize() == 0);
+ }
+ } D(s12a); R(s12a); E;
+
+ B(s13, Remove middle subview, 0) W(s13a);
+ {
+ c4_IntProp p1 ("p1"), p3 ("p3");
+ c4_ViewProp p2 ("p2");
+ {
+ c4_Storage s1 ("s13a", 1);
+ s1.SetStructure("a[p1:I,p2[p3:I]]");
+ c4_View v1 = s1.View("a");
+
+ c4_View v2a;
+ v2a.Add(p3 [234]);
+ v1.Add(p1 [123] + p2 [v2a]);
+
+ c4_View v2b;
+ v2b.Add(p3 [345]);
+ v2b.Add(p3 [346]);
+ v1.Add(p1 [124] + p2 [v2b]);
+
+ c4_View v2c;
+ v2c.Add(p3 [456]);
+ v2c.Add(p3 [457]);
+ v2c.Add(p3 [458]);
+ v1.Add(p1 [125] + p2 [v2c]);
+
+ s1.Commit();
+ }
+ {
+ c4_Storage s1 ("s13a", 1);
+ c4_View v1 = s1.View("a");
+ A(v1.GetSize() == 3);
+ A(p1 (v1[0]) == 123);
+ A(p1 (v1[1]) == 124);
+ A(p1 (v1[2]) == 125);
+ c4_View v2a = p2 (v1[0]);
+ A(v2a.GetSize() == 1);
+ A(p3 (v2a[0]) == 234);
+ c4_View v2b = p2 (v1[1]);
+ A(v2b.GetSize() == 2);
+ A(p3 (v2b[0]) == 345);
+ c4_View v2c = p2 (v1[2]);
+ A(v2c.GetSize() == 3);
+ A(p3 (v2c[0]) == 456);
+ v1.RemoveAt(1);
+ A(v1.GetSize() == 2);
+ v2a = p2 (v1[0]);
+ A(v2a.GetSize() == 1);
+ A(p3 (v2a[0]) == 234);
+ v2b = p2 (v1[1]);
+ A(v2b.GetSize() == 3);
+ A(p3 (v2b[0]) == 456);
+ s1.Commit();
+ A(v1.GetSize() == 2);
+ A(p1 (v1[0]) == 123);
+ A(p1 (v1[1]) == 125);
+ }
+ } D(s13a); R(s13a); E;
+
+ B(s14, Replace attached subview, 0) W(s14a);
+ {
+ c4_IntProp p1 ("p1");
+ c4_ViewProp p2 ("p2");
+ {
+ c4_Storage s1 ("s14a", 1);
+ s1.SetStructure("a[p1:I,p2[p3:I]]");
+ c4_View v1 = s1.View("a");
+
+ v1.Add(p1 [123] + p2 [c4_View ()]);
+ A(v1.GetSize() == 1);
+
+ v1[0] = p2 [c4_View ()];
+ A(v1.GetSize() == 1);
+ A(p1 (v1[0]) == 0);
+
+ s1.Commit();
+ }
+ } D(s14a); R(s14a); E;
+
+ B(s15, Add after removed subviews, 0) W(s15a);
+ {
+ c4_IntProp p1 ("p1"), p3 ("p3");
+ c4_ViewProp p2 ("p2");
+ {
+ c4_Storage s1 ("s15a", 1);
+ s1.SetStructure("a[p1:I,p2[p3:I]]");
+ c4_View v1 = s1.View("a");
+
+ c4_View v2;
+ v2.Add(p3 [234]);
+
+ v1.Add(p1 [123] + p2 [v2]);
+ v1.Add(p1 [456] + p2 [v2]);
+ v1.Add(p1 [789] + p2 [v2]);
+ A(v1.GetSize() == 3);
+
+ v1[0] = v1[2];
+ v1.RemoveAt(2);
+
+ v1[0] = v1[1];
+ v1.RemoveAt(1);
+
+ v1.RemoveAt(0);
+
+ v1.Add(p1 [111] + p2 [v2]);
+
+ s1.Commit();
+ }
+ } D(s15a); R(s15a); E;
+
+ B(s16, Add after removed ints, 0) W(s16a);
+ {
+ c4_IntProp p1 ("p1");
+
+ c4_Storage s1 ("s16a", 1);
+ s1.SetStructure("a[p1:I,p2[p3:I]]");
+ c4_View v1 = s1.View("a");
+
+ v1.Add(p1 [1]);
+ v1.Add(p1 [2]);
+ v1.Add(p1 [3]);
+
+ v1.RemoveAt(2);
+ v1.RemoveAt(1);
+ v1.RemoveAt(0);
+
+ v1.Add(p1 [4]);
+
+ s1.Commit();
+
+ } D(s16a); R(s16a); E;
+
+ B(s17, Add after removed strings, 0) W(s17a);
+ {
+ c4_StringProp p1 ("p1");
+
+ c4_Storage s1 ("s17a", 1);
+ s1.SetStructure("a[p1:S,p2[p3:I]]");
+ c4_View v1 = s1.View("a");
+
+ v1.Add(p1 ["one"]);
+ v1.Add(p1 ["two"]);
+ v1.Add(p1 ["three"]);
+
+ v1.RemoveAt(2);
+ v1.RemoveAt(1);
+ v1.RemoveAt(0);
+
+ v1.Add(p1 ["four"]);
+
+ s1.Commit();
+
+ } D(s17a); R(s17a); E;
+
+ B(s18, Empty storage, 0) W(s18a);
+ {
+ c4_Storage s1 ("s18a", 1);
+
+ } D(s18a); R(s18a); E;
+
+ B(s19, Empty view outlives storage, 0) W(s19a);
+ {
+ c4_View v1;
+ c4_Storage s1 ("s19a", 1);
+ v1 = s1.GetAs("a[p1:I,p2:S]");
+
+ } D(s19a); R(s19a); E;
+}
diff --git a/akregator/src/mk4storage/metakit/tests/tstore3.cpp b/akregator/src/mk4storage/metakit/tests/tstore3.cpp
new file mode 100644
index 000000000..21418151c
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/tstore3.cpp
@@ -0,0 +1,366 @@
+// tstore3.cpp -- Regression test program, storage tests, part 3
+// $Id$
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit/
+
+#include "regress.h"
+
+void TestStores3()
+{
+ B(s20, View outlives storage, 0) W(s20a);
+ {
+ c4_IntProp p1 ("p1");
+ c4_View v1;
+
+ {
+ c4_Storage s1 ("s20a", 1);
+ v1 = s1.GetAs("a[p1:I,p2:S]");
+ v1.Add(p1 [123]);
+ }
+
+ // 19990916 - semantics changed, rows kept but no properties
+ //A(p1 (v1[0]) == 123);
+ A(v1.GetSize() == 1);
+ A(v1.NumProperties() == 0);
+
+ } D(s20a); R(s20a); E;
+
+ B(s21, Test demo scenario, 0) W(s21a);
+ {
+ c4_StringProp p1 ("p1"), p2 ("p2");
+ {
+ c4_Storage storage ("s21a", 1);
+ storage.SetStructure("a[p1:S,p2:S]");
+ c4_View v1;
+ c4_Row r1;
+
+ p1 (r1) = "One";
+ p2 (r1) = "Un";
+ v1.Add(r1);
+ A(v1.GetSize() == 1);
+
+ p1 (r1) = "Two";
+ p2 (r1) = "Deux";
+ v1.Add(r1);
+ A(v1.GetSize() == 2);
+
+ // changed 2000-03-15: Store is gone
+ //v1 = storage.Store("a", v1);
+ v1 = storage.View("a") = v1;
+
+ A(v1.GetSize() == 2);
+ A(p1 (v1[1]) == (c4_String) "Two");
+ A(p2 (v1[1]) == (c4_String) "Deux");
+ A(p1 (v1[0]) == (c4_String) "One");
+ A(p2 (v1[0]) == (c4_String) "Un");
+
+ storage.Commit();
+ A(v1.GetSize() == 2);
+ A(p1 (v1[1]) == (c4_String) "Two");
+ A(p2 (v1[1]) == (c4_String) "Deux");
+ A(p1 (v1[0]) == (c4_String) "One");
+ A(p2 (v1[0]) == (c4_String) "Un");
+
+ c4_String s1 (p1 (v1[1]));
+ c4_String s2 (p2 (v1[1]));
+ A(s1 == "Two");
+ A(s2 == "Deux");
+
+ storage.Commit();
+
+ v1.Add(p1 ["Three"] + p2 ["Trois"]);
+
+ storage.Commit();
+ A(v1.GetSize() == 3);
+ A(p2 (v1[2]) == (c4_String) "Trois");
+
+ v1 = storage.GetAs("a[p1:S,p2:S,p3:I]");
+ A(v1.GetSize() == 3);
+ A(p2 (v1[2]) == (c4_String) "Trois");
+
+ c4_IntProp p3 ("p3");
+ p3 (v1[1]) = 123;
+
+ storage.Commit();
+ A(v1.GetSize() == 3);
+ A(p2 (v1[2]) == (c4_String) "Trois");
+
+ c4_View v2 = storage.GetAs("b[p4:I]");
+
+ c4_IntProp p4 ("p4");
+ v2.Add(p4 [234]);
+
+ storage.Commit();
+ A(v1.GetSize() == 3);
+ A(p2 (v1[2]) == (c4_String) "Trois");
+
+ c4_IntProp p4a ("p4");
+ v1.InsertAt(2, p1 ["Four"] + p4a [345]);
+
+ storage.Commit();
+ A(v1.GetSize() == 4);
+ A(p1 (v1[0]) == (c4_String) "One");
+ A(p1 (v1[1]) == (c4_String) "Two");
+ A(p1 (v1[2]) == (c4_String) "Four");
+ A(p1 (v1[3]) == (c4_String) "Three");
+ A(p2 (v1[3]) == (c4_String) "Trois");
+ A(v2.GetSize() == 1);
+ A(p4 (v2[0]) == 234);
+ }
+ {
+ c4_Storage storage ("s21a", 0);
+ c4_View v1 = storage.View("a");
+ A(v1.GetSize() == 4);
+ A(p1 (v1[0]) == (c4_String) "One");
+ A(p1 (v1[1]) == (c4_String) "Two");
+ A(p1 (v1[2]) == (c4_String) "Four");
+ A(p1 (v1[3]) == (c4_String) "Three");
+ c4_View v2 = storage.View("b");
+ c4_IntProp p4 ("p4");
+ A(v2.GetSize() == 1);
+ A(p4 (v2[0]) == 234);
+ }
+ } D(s21a); R(s21a); E;
+
+#if !q4_TINY
+ B(s22, Double storage, 0) W(s22a);
+ {
+ c4_DoubleProp p1 ("p1");
+ c4_Storage s1 ("s22a", 1);
+ s1.SetStructure("a[p1:D]");
+ c4_View v1 = s1.View("a");
+ v1.Add(p1 [1234.5678]);
+ v1.Add(p1 [2345.6789]);
+ v1.InsertAt(1, p1 [3456.7890]);
+ s1.Commit();
+ } D(s22a); R(s22a); E;
+#endif
+
+ B(s23, Find absent record, 0) W(s23a);
+ {
+ c4_Storage s1 ("s23a", 1);
+ s1.SetStructure("v[h:S,p:I,a:I,b:I,c:I,d:I,e:I,f:I,g:I,x:I]");
+ c4_View view = s1.View("v");
+
+ c4_StringProp H("h");
+ c4_IntProp P("p");
+
+ c4_Row row;
+ H(row) = "someString";
+ P(row) = 99;
+
+ int x = view.Find(row);
+ A(x == -1);
+
+ } D(s23a); R(s23a); E;
+
+ B(s24, Bitwise storage, 0) W(s24a);
+ {
+ c4_IntProp p1 ("p1");
+
+ int m = 9;
+
+ // insert values in front, but check fractional sizes at each step
+ for (int n = 0; n < m; ++n)
+ {
+ {
+ c4_Storage s1 ("s24a", 1);
+ s1.SetStructure("a1[p1:I],a2[p1:I],a3[p1:I],a4[p1:I]");
+ s1.AutoCommit(); // new feature in 1.6
+
+ c4_View v1 = s1.View("a1");
+ c4_View v2 = s1.View("a2");
+ c4_View v3 = s1.View("a3");
+ c4_View v4 = s1.View("a4");
+
+ c4_Row row;
+ int k = ~ n;
+
+ p1 (row) = k & 0x01;
+ v1.InsertAt(0, row);
+
+ p1 (row) = k & 0x03;
+ v2.InsertAt(0, row);
+
+ p1 (row) = k & 0x0F;
+ v3.InsertAt(0, row);
+
+ p1 (row) = k & 0x7F;
+ v4.InsertAt(0, row);
+ }
+ // the following checks that all tiny size combinations work
+ {
+ c4_Storage s1 ("s24a", 0);
+
+ c4_View v1 = s1.View("a1");
+ c4_View v2 = s1.View("a2");
+ c4_View v3 = s1.View("a3");
+ c4_View v4 = s1.View("a4");
+
+ A(v1.GetSize() == n + 1);
+ A(v2.GetSize() == n + 1);
+ A(v3.GetSize() == n + 1);
+ A(v4.GetSize() == n + 1);
+ }
+ }
+
+ c4_Storage s1 ("s24a", 0);
+
+ c4_View v1 = s1.View("a1");
+ c4_View v2 = s1.View("a2");
+ c4_View v3 = s1.View("a3");
+ c4_View v4 = s1.View("a4");
+
+ A(v1.GetSize() == m);
+ A(v2.GetSize() == m);
+ A(v3.GetSize() == m);
+ A(v4.GetSize() == m);
+
+ // now check that the inserted values are correct
+ for (int i = 0; i < m; ++i)
+ {
+ int j = m - i - 1;
+ int k = ~ i;
+
+ A(p1 (v1[j]) == (k & 0x01));
+ A(p1 (v2[j]) == (k & 0x03));
+ A(p1 (v3[j]) == (k & 0x0F));
+ A(p1 (v4[j]) == (k & 0x7F));
+ }
+
+ } D(s24a); R(s24a); E;
+
+ B(s25, Bytes storage, 0) W(s25a);
+ {
+ c4_Bytes hi ("hi", 2);
+ c4_Bytes gday ("gday", 4);
+ c4_Bytes hello ("hello", 5);
+
+ c4_BytesProp p1 ("p1");
+ c4_Storage s1 ("s25a", 1);
+ s1.SetStructure("a[p1:B]");
+ c4_View v1 = s1.View("a");
+
+ v1.Add(p1 [hi]);
+ A(p1 (v1[0]) == hi);
+ v1.Add(p1 [hello]);
+ A(p1 (v1[0]) == hi);
+ A(p1 (v1[1]) == hello);
+ v1.InsertAt(1, p1 [gday]);
+ A(p1 (v1[0]) == hi);
+ A(p1 (v1[1]) == gday);
+ A(p1 (v1[2]) == hello);
+ s1.Commit();
+ A(p1 (v1[0]) == hi);
+ A(p1 (v1[1]) == gday);
+ A(p1 (v1[2]) == hello);
+
+ } D(s25a); R(s25a); E;
+
+ B(s26, Bitwise autosizing, 0) W(s26a);
+ {
+ c4_IntProp p1 ("p1"), p2 ("p2"), p3 ("p3"), p4 ("p4");
+ c4_Storage s1 ("s26a", 1);
+ s1.SetStructure("a[p1:I,p2:I,p3:I,p4:I]");
+ c4_View v1 = s1.View("a");
+
+ v1.Add(p1 [1] + p2 [3] + p3 [15] + p4 [127]);
+ A(p1 (v1[0]) == 1);
+ A(p2 (v1[0]) == 3);
+ A(p3 (v1[0]) == 15);
+ A(p4 (v1[0]) == 127);
+
+ p1 (v1[0]) = 100000L;
+ p2 (v1[0]) = 100000L;
+ p3 (v1[0]) = 100000L;
+ p4 (v1[0]) = 100000L;
+
+ // these failed in 1.61
+ A(p1 (v1[0]) == 100000L);
+ A(p2 (v1[0]) == 100000L);
+ A(p3 (v1[0]) == 100000L);
+ A(p4 (v1[0]) == 100000L);
+
+ s1.Commit();
+
+ } D(s26a); R(s26a); E;
+
+ B(s27, Bytes restructuring, 0) W(s27a);
+ {
+ c4_Bytes test ("test", 4);
+
+ c4_BytesProp p1 ("p1");
+ c4_Storage s1 ("s27a", 1);
+
+ c4_Row row;
+ p1 (row) = test;
+
+ c4_View v1;
+ v1.Add(row);
+
+ // changed 2000-03-15: Store is gone
+ //s1.Store("a", v1); // asserts in 1.61
+ c4_View v2 = s1.GetAs("a[p1:B]");
+ v2.InsertAt(0, v1);
+
+ s1.Commit();
+
+ } D(s27a); R(s27a); E;
+
+#if !q4_TINY
+ B(s28, Doubles added later, 0) W(s28a);
+ {
+ c4_FloatProp p1 ("p1");
+ c4_DoubleProp p2 ("p2");
+ c4_ViewProp p3 ("p3");
+
+ c4_Storage s1 ("s28a", 1);
+ s1.SetStructure("a[p1:F,p2:D,p3[p1:F,p2:D]]");
+ c4_View v1 = s1.View("a");
+
+ c4_Row r1;
+
+ p1 (r1) = 123;
+ p2 (r1) = 123;
+
+ c4_View v2;
+ v2.Add (p1 [234] + p2 [234]);
+ p3 (r1) = v2;
+
+ v1.Add(r1);
+ double x1 = p1 (v1[0]);
+ A(x1 == p2 (v1[0]));
+
+ v2 = p3 (v1[0]);
+ double x2 = p1 (v2[0]);
+ A(x2 == p2 (v2[0])); // fails in 1.6
+
+ s1.Commit();
+
+ } D(s28a); R(s28a); E;
+#endif
+
+ B(s29, Delete bytes property, 0) W(s29a);
+ {
+ {
+ c4_BytesProp p1 ("p1");
+
+ c4_Storage s1 ("s29a", 1);
+ s1.SetStructure("a[p1:B]");
+ c4_View v1 = s1.View("a");
+
+ int data = 99;
+ v1.Add(p1 [c4_Bytes (&data, sizeof data)]);
+
+ s1.Commit();
+ }
+ {
+ c4_Storage s1 ("s29a", 1);
+ c4_View v1 = s1.View("a");
+
+ v1.RemoveAt(0); // asserts in 1.7
+
+ s1.Commit();
+ }
+
+ } D(s29a); R(s29a); E;
+}
diff --git a/akregator/src/mk4storage/metakit/tests/tstore4.cpp b/akregator/src/mk4storage/metakit/tests/tstore4.cpp
new file mode 100644
index 000000000..930c074c3
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/tstore4.cpp
@@ -0,0 +1,323 @@
+// tstore4.cpp -- Regression test program, storage tests, part 4
+// $Id$
+// This is part of Metakit, see http://www.equi4.com/metakit/
+
+#include "regress.h"
+
+void TestStores4()
+{
+ B(s30, Memo storage, 0) W(s30a);
+ {
+ c4_Bytes hi ("hi", 2);
+ c4_Bytes gday ("gday", 4);
+ c4_Bytes hello ("hello", 5);
+
+ c4_MemoProp p1 ("p1");
+ c4_Storage s1 ("s30a", 1);
+ s1.SetStructure("a[p1:B]");
+ c4_View v1 = s1.View("a");
+
+ v1.Add(p1 [hi]);
+ A(p1 (v1[0]) == hi);
+ v1.Add(p1 [hello]);
+ A(p1 (v1[0]) == hi);
+ A(p1 (v1[1]) == hello);
+ v1.InsertAt(1, p1 [gday]);
+ A(p1 (v1[0]) == hi);
+ A(p1 (v1[1]) == gday);
+ A(p1 (v1[2]) == hello);
+ s1.Commit();
+ A(p1 (v1[0]) == hi);
+ A(p1 (v1[1]) == gday);
+ A(p1 (v1[2]) == hello);
+
+ } D(s30a); R(s30a); E;
+
+ // this failed in the unbuffered 1.8.5a interim release in Mk4tcl 1.0.5
+ B(s31, Check sort buffer use, 0) W(s31a);
+ {
+ c4_IntProp p1 ("p1");
+ c4_Storage s1 ("s31a", 1);
+ s1.SetStructure("a[p1:I]");
+ c4_View v1 = s1.View("a");
+ v1.Add(p1 [3]);
+ v1.Add(p1 [1]);
+ v1.Add(p1 [2]);
+ s1.Commit();
+
+ c4_View v2 = v1.SortOn(p1);
+ A(v2.GetSize() == 3);
+ A(p1 (v2[0]) == 1);
+ A(p1 (v2[1]) == 2);
+ A(p1 (v2[2]) == 3);
+
+ } D(s31a); R(s31a); E;
+
+ // this failed in 1.8.6, fixed 19990828
+ B(s32, Set memo empty or same size, 0) W(s32a);
+ {
+ c4_Bytes empty;
+ c4_Bytes full ("full", 4);
+ c4_Bytes more ("more", 4);
+
+ c4_MemoProp p1 ("p1");
+ c4_Storage s1 ("s32a", 1);
+ s1.SetStructure("a[p1:B]");
+ c4_View v1 = s1.View("a");
+
+ v1.Add(p1 [full]);
+ A(p1 (v1[0]) == full);
+ s1.Commit();
+ A(p1 (v1[0]) == full);
+
+ p1 (v1[0]) = empty;
+ A(p1 (v1[0]) == empty);
+ s1.Commit();
+ A(p1 (v1[0]) == empty);
+
+ p1 (v1[0]) = more;
+ A(p1 (v1[0]) == more);
+ s1.Commit();
+ A(p1 (v1[0]) == more);
+
+ p1 (v1[0]) = full;
+ A(p1 (v1[0]) == full);
+ s1.Commit();
+ A(p1 (v1[0]) == full);
+
+ } D(s32a); R(s32a); E;
+
+ // this failed in 1.8.6, fixed 19990828
+ B(s33, Serialize memo fields, 0) W(s33a); W(s33b); W(s33c);
+ {
+ c4_Bytes hi ("hi", 2);
+ c4_Bytes gday ("gday", 4);
+ c4_Bytes hello ("hello", 5);
+
+ c4_MemoProp p1 ("p1");
+
+ c4_Storage s1 ("s33a", 1);
+ s1.SetStructure("a[p1:B]");
+ c4_View v1 = s1.View("a");
+
+ v1.Add(p1 [hi]);
+ v1.Add(p1 [gday]);
+ v1.Add(p1 [hello]);
+ A(p1 (v1[0]) == hi);
+ A(p1 (v1[1]) == gday);
+ A(p1 (v1[2]) == hello);
+ s1.Commit();
+ A(p1 (v1[0]) == hi);
+ A(p1 (v1[1]) == gday);
+ A(p1 (v1[2]) == hello);
+
+ {
+ c4_FileStream fs1 (fopen("s33b", "wb"), true);
+ s1.SaveTo(fs1);
+ }
+
+ c4_Storage s2 ("s33c", 1);
+
+ c4_FileStream fs2 (fopen("s33b", "rb"), true);
+ s2.LoadFrom(fs2);
+
+ c4_View v2 = s2.View("a");
+ A(p1 (v2[0]) == hi);
+ A(p1 (v2[1]) == gday);
+ A(p1 (v2[2]) == hello);
+ s2.Commit();
+ A(p1 (v2[0]) == hi);
+ A(p1 (v2[1]) == gday);
+ A(p1 (v2[2]) == hello);
+ s2.Commit();
+ A(p1 (v2[0]) == hi);
+ A(p1 (v2[1]) == gday);
+ A(p1 (v2[2]) == hello);
+
+ } D(s33a); D(s33b); D(s33c); R(s33a); R(s33b); R(s33c); E;
+
+ // check smarter commit and commit failure on r/o
+ B(s34, Smart and failed commits, 0) W(s34a);
+ {
+ c4_IntProp p1 ("p1");
+ {
+ c4_Storage s1 ("s34a", 1);
+ s1.SetStructure("a[p1:I]");
+ c4_View v1 = s1.View("a");
+ v1.Add(p1 [111]);
+ A(v1.GetSize() == 1);
+ A(p1 (v1[0]) == 111);
+ bool f1 = s1.Commit();
+ A(f1);
+ A(v1.GetSize() == 1);
+ A(p1 (v1[0]) == 111);
+ bool f2 = s1.Commit();
+ A(f2); // succeeds, but should not write anything
+ A(v1.GetSize() == 1);
+ A(p1 (v1[0]) == 111);
+ }
+ {
+ c4_Storage s1 ("s34a", 0);
+ c4_View v1 = s1.View("a");
+ v1.Add(p1 [222]);
+ A(v1.GetSize() == 2);
+ A(p1 (v1[0]) == 111);
+ A(p1 (v1[1]) == 222);
+ bool f1 = s1.Commit();
+ A(!f1);
+ A(v1.GetSize() == 2);
+ A(p1 (v1[0]) == 111);
+ A(p1 (v1[1]) == 222);
+ }
+ } D(s34a); R(s34a); E;
+
+ B(s35, Datafile with preamble, 0) W(s35a);
+ {
+ {
+ c4_FileStream fs1 (fopen("s35a", "wb"), true);
+ fs1.Write("abc", 3);
+ }
+ c4_IntProp p1 ("p1");
+ {
+ c4_Storage s1 ("s35a", 1);
+ s1.SetStructure("a[p1:I]");
+ c4_View v1 = s1.View("a");
+ v1.Add(p1 [111]);
+ A(v1.GetSize() == 1);
+ A(p1 (v1[0]) == 111);
+ bool f1 = s1.Commit();
+ A(f1);
+ A(v1.GetSize() == 1);
+ A(p1 (v1[0]) == 111);
+ bool f2 = s1.Commit();
+ A(f2); // succeeds, but should not write anything
+ A(v1.GetSize() == 1);
+ A(p1 (v1[0]) == 111);
+ }
+ {
+ c4_FileStream fs1 (fopen("s35a", "rb"), true);
+ char buffer [10];
+ int n1 = fs1.Read(buffer, 3);
+ A(n1 == 3);
+ A(c4_String (buffer, 3) == "abc");
+ }
+ {
+ c4_Storage s1 ("s35a", 0);
+ c4_View v1 = s1.View("a");
+ A(v1.GetSize() == 1);
+ A(p1 (v1[0]) == 111);
+ v1.Add(p1 [222]);
+ A(v1.GetSize() == 2);
+ A(p1 (v1[0]) == 111);
+ A(p1 (v1[1]) == 222);
+ bool f1 = s1.Commit();
+ A(!f1);
+ A(v1.GetSize() == 2);
+ A(p1 (v1[0]) == 111);
+ A(p1 (v1[1]) == 222);
+ }
+ } D(s35a); R(s35a); E;
+
+ B(s36, Commit after load, 0) W(s36a); W(s36b);
+ {
+ c4_IntProp p1 ("p1");
+
+ c4_Storage s1 ("s36a", 1);
+ s1.SetStructure("a[p1:I]");
+ c4_View v1 = s1.View("a");
+ v1.Add(p1 [111]);
+ A(v1.GetSize() == 1);
+ A(p1 (v1[0]) == 111);
+
+ {
+ c4_FileStream fs1 (fopen("s36b", "wb"), true);
+ s1.SaveTo(fs1);
+ }
+
+ p1 (v1[0]) = 222;
+ v1.Add(p1 [333]);
+ bool f1 = s1.Commit();
+ A(f1);
+ A(v1.GetSize() == 2);
+ A(p1 (v1[0]) == 222);
+ A(p1 (v1[1]) == 333);
+
+ c4_FileStream fs2 (fopen("s36b", "rb"), true);
+ s1.LoadFrom(fs2);
+ //A(v1.GetSize() == 0); // should be detached, but it's still 2
+
+ c4_View v2 = s1.View("a");
+ A(v2.GetSize() == 1);
+ A(p1 (v2[0]) == 111);
+
+ // this fails in 2.4.0, reported by James Lupo, August 2001
+ bool f2 = s1.Commit();
+ A(f2);
+ } D(s36a); D(s36b); R(s36a); R(s36b); E;
+
+ // fails in 2.4.1, reported Oct 31. 2001 by Steve Baxter
+ B(s37, Change short partial fields, 0) W(s37a);
+ {
+ c4_BytesProp p1 ("p1");
+ c4_Storage s1( "s37a", true );
+ c4_View v1 = s1.GetAs("v1[key:I,p1:B]");
+
+ v1.Add(p1 [c4_Bytes ("12345", 6)]);
+ A(v1.GetSize() == 1);
+ s1.Commit();
+
+ c4_Bytes buf = p1 (v1[0]);
+ A(buf.Size() == 6);
+ A(buf == c4_Bytes ("12345", 6));
+ buf = p1(v1[0]).Access(1,3);
+ A(buf == c4_Bytes ("234", 3));
+ p1 (v1[0]).Modify(c4_Bytes ("ab", 2), 2, 0);
+ s1.Commit();
+
+ buf = p1 (v1[0]);
+ A(buf == c4_Bytes ("12ab5", 6));
+ } D(s37a); R(s37a); E;
+
+ // Gross memory use (but no leaks), January 2002, Murat Berk
+ B(s38, Lots of empty subviews, 0) W(s38a);
+ {
+ c4_BytesProp p1 ("p1");
+ {
+ c4_Storage s1( "s38a", true );
+ c4_View v = s1.GetAs("v[v1[p1:S]]");
+
+ v.SetSize(100000);
+ s1.Commit();
+ }
+ {
+ c4_Storage s2( "s38a", true );
+ c4_View v2 = s2.View("v");
+ // this should not materialize all the empty subviews
+ v2.SetSize(v2.GetSize() + 1);
+ // nor should this
+ s2.Commit();
+ }
+ {
+ c4_Storage s3( "s38a", true );
+ c4_View v3 = s3.View("v");
+ v3.RemoveAt(1, v3.GetSize() - 2);
+ A(v3.GetSize() == 2);
+ s3.Commit();
+ }
+ } D(s38a); R(s38a); E;
+
+ // Fix bug introduced on 7-2-2002, as reported by M. Berk
+ B(s39, Do not detach empty top-level views, 0) W(s39a);
+ {
+ c4_IntProp p1 ("p1");
+ c4_Storage s1( "s39a", true );
+ c4_View v1 = s1.GetAs("v1[p1:I]");
+ s1.Commit();
+ A(v1.GetSize() == 0);
+ v1.Add(p1 [123]);
+ A(v1.GetSize() == 1);
+ s1.Commit();
+ c4_View v2 = s1.View("v1");
+ A(v2.GetSize() == 1); // fails with 0 due to recent bug
+ } D(s39a); R(s39a); E;
+}
diff --git a/akregator/src/mk4storage/metakit/tests/tstore5.cpp b/akregator/src/mk4storage/metakit/tests/tstore5.cpp
new file mode 100644
index 000000000..1e50b91f3
--- /dev/null
+++ b/akregator/src/mk4storage/metakit/tests/tstore5.cpp
@@ -0,0 +1,286 @@
+// tstore5.cpp -- Regression test program, storage tests, part 5
+// $Id$
+// This is part of Metakit, see http://www.equi4.com/metakit/
+
+#include "regress.h"
+
+void TestStores5()
+{
+ B(s40, LoadFrom after commit, 0) W(s40a);
+ {
+ c4_IntProp p1 ("p1");
+
+ { // create datafile by streaming out
+ c4_Storage s1;
+ s1.SetStructure("a[p1:I]");
+
+ c4_View v1 = s1.View("a");
+ v1.Add(p1 [123]);
+ A(p1 (v1[0]) == 123);
+ A(v1.GetSize() == 1);
+
+ c4_FileStream fs1 (fopen("s40a", "wb"), true);
+ s1.SaveTo(fs1);
+ }
+ { // it should load just fine
+ c4_Storage s2;
+ c4_FileStream fs1 (fopen("s40a", "rb"), true);
+ bool ok = s2.LoadFrom(fs1);
+ A(ok);
+
+ c4_View v1 = s2.View("a");
+ A(p1 (v1[0]) == 123);
+ A(v1.GetSize() == 1);
+ }
+ { // open the datafile and commit a change
+ c4_Storage s3 ("s40a", true);
+
+ c4_View v1 = s3.View("a");
+ A(p1 (v1[0]) == 123);
+ A(v1.GetSize() == 1);
+ p1 (v1[0]) = 456;
+ s3.Commit();
+ A(p1 (v1[0]) == 456);
+ A(v1.GetSize() == 1);
+ }
+ { // it should load fine and show the last changes
+ c4_Storage s4;
+ c4_FileStream fs1 (fopen("s40a", "rb"), true);
+ bool ok = s4.LoadFrom(fs1);
+ A(ok);
+
+ c4_View v1 = s4.View("a");
+ A(p1 (v1[0]) == 456);
+ A(v1.GetSize() == 1);
+ }
+ { // it should open just fine in the normal way as well
+ c4_Storage s5 ("s40a", false);
+ c4_View v1 = s5.View("a");
+ A(p1 (v1[0]) == 456);
+ A(v1.GetSize() == 1);
+ }
+ } D(s40a); R(s40a); E;
+
+ // 2002-03-13: failure on Win32, Modify calls base class GetNthMemoCol
+ B(s41, Partial modify blocked, 0) W(s41a);
+ {
+ c4_BytesProp p1 ("p1");
+ c4_Storage s1 ("s41a", true);
+ c4_View v1 = s1.GetAs("a[_B[p1:B]]");
+
+ // custom viewers did not support partial access in 2.4.3
+ c4_View v2 = v1.Blocked();
+ s1.Commit();
+
+ v2.SetSize(1);
+
+ c4_BytesRef m = p1 (v2[0]);
+ m.Modify(c4_Bytes ("abcdefgh", 8), 0);
+
+ s1.Commit();
+
+ } D(s41a); R(s41a); E;
+
+ B(s42, Get descriptions, 0)
+ {
+ c4_Storage s1;
+ s1.SetStructure("a[p1:I],b[p2:S]");
+
+ c4_String x1 = s1.Description();
+ A(x1 == "a[p1:I],b[p2:S]");
+
+ c4_String x2 = s1.Description("b");
+ A(x2 == "p2:S");
+
+ const char* cp = s1.Description("c");
+ A(cp == 0);
+ } E;
+
+ // 2002-04-24: VPI subview ints clobbered
+ B(s43, View reuse after sub-byte ints, 0) W(s43a);
+ {
+ c4_IntProp p1 ("p1");
+ c4_Storage s1 ("s43a", true);
+ c4_View v1 = s1.GetAs("a[p1:I]");
+
+ v1.Add(p1 [0]);
+ v1.Add(p1 [1]);
+ s1.Commit();
+
+ v1.SetSize(1); // 1 is an even trickier bug than 0
+ s1.Commit();
+
+ // adding the following two lines works around the 2.4.4 bug
+ //s1.Rollback();
+ //v1 = s1.GetAs("a[p1:I]");
+
+ v1.Add(p1 [12345]);
+ s1.Commit();
+
+ //int n = p1 (v1[1]);
+ A(p1 (v1[1]) == 12345);
+
+ } D(s43a); R(s43a); E;
+
+ B(s44, Bad memo free space, 0) W(s44a);
+ {
+ c4_IntProp p1 ("p1");
+ c4_BytesProp p2 ("p2");
+ c4_Storage s1 ("s44a", true);
+ c4_View v1 = s1.GetAs("a[p1:I,p2:B]");
+
+ c4_Bytes data;
+ t4_byte* p = data.SetBuffer(12345);
+ for (int i = 0; i < data.Size(); ++i)
+ p[i] = (t4_byte) i;
+
+ v1.Add(p2 [data]);
+ s1.Commit();
+
+ p1 (v1[0]) = 1;
+ s1.Commit();
+
+ p1 (v1[0]) = 0;
+ s1.Commit();
+
+ c4_Bytes temp = p2 (v1[0]);
+ A(temp == data); // this failed in 2.4.5
+
+ } D(s44a); R(s44a); E;
+
+ B(s45, Bad subview memo free space, 0) W(s45a);
+ {
+ c4_IntProp p1 ("p1");
+ c4_ViewProp p2 ("p2");
+ c4_BytesProp p3 ("p3");
+ c4_Storage s1 ("s45a", true);
+ c4_View v1 = s1.GetAs("a[p1:I,p2[p3:B]]");
+
+ c4_Bytes data;
+ t4_byte* p = data.SetBuffer(12345);
+ for (int i = 0; i < data.Size(); ++i)
+ p[i] = (t4_byte) i;
+
+ v1.SetSize(1);
+ c4_View v2 = p2 (v1[0]);
+ v2.Add(p3 [data]);
+ s1.Commit();
+
+ p1 (v1[0]) = 1;
+ s1.Commit();
+
+ p1 (v1[0]) = 0;
+ s1.Commit();
+
+ c4_View v3 = p2 (v1[0]);
+ c4_Bytes temp = p3 (v3[0]);
+ A(temp == data); // this failed in 2.4.5
+
+ } D(s45a); R(s45a); E;
+
+ B(s46, LoadFrom after commit, 0) W(s46a);
+ {
+ c4_IntProp p1 ("p1");
+
+ {
+ c4_Storage s1 ("s46a", true);
+ s1.SetStructure("a[p1:I]");
+ c4_View v1 = s1.View("a");
+
+ v1.Add(p1 [11]);
+ v1.Add(p1 [22]);
+ v1.Add(p1 [33]);
+ v1.Add(p1 [44]);
+ v1.Add(p1 [55]);
+ v1.Add(p1 [66]);
+ v1.Add(p1 [77]);
+ v1.Add(p1 [88]);
+ v1.Add(p1 [99]);
+
+ s1.Commit();
+ }
+ {
+ c4_Storage s2 ("s46a", true);
+ c4_View v2 = s2.View("a");
+
+ v2.Add(p1 [1000]); // force 1->2 byte ints
+ v2.InsertAt(7, c4_Row ());
+ v2.InsertAt(4, c4_Row ());
+
+ //for (int i = 6; i <= 9; ++i) printf("%d\n", (int) p1 (v2[i]));
+
+ A(p1 (v2[6]) == 66);
+ A(p1 (v2[8]) == 0);
+ A(p1 (v2[9]) == 88);
+ A(p1 (v2[7]) == 77); // this failed in 2.4.6
+
+ s2.Commit();
+ }
+ } D(s46a); R(s46a); E;
+
+ // 2004-01-16 bad property type crashes MK 2.4.9.2 and before
+ // this hits an assertion in debug mode, so then it has to be disabled
+ B(s47, Defining bad property type, 0)
+ {
+ c4_IntProp p1 ("p2");
+
+ c4_Storage s1;
+#if defined(NDEBUG)
+ c4_View v1 = s1.GetAs("v1[p1:A]");
+#else
+ // assertions are enabled, turn this into a dummy test instead
+ c4_View v1 = s1.GetAs("v1[p1:I]");
+#endif
+ v1.Add(p1 [123]);
+
+ A(v1.GetSize() == 1);
+ A(p1 (v1 [0]) == 123);
+ } E;
+
+ // 2004-01-18 file damaging bug, when resizing a comitted subview
+ // to empty, committing, and then resizing back to containing data.
+ // Fortunately this usage pattern never happened in blocked views!
+ B(s48, Resize subview to zero and back, 0) W(s48a); W(s48b);
+ {
+ {
+ c4_Storage s1 ("s48a", true);
+ c4_View v1 = s1.GetAs("v1[v2[p1:I]]");
+ v1.SetSize(1);
+ s1.Commit();
+ }
+ {
+ c4_Storage s1 ("s48a", true);
+ c4_View v1 = s1.View("v1");
+ v1.SetSize(0);
+ s1.Commit();
+ // the problem is that the in-memory copy has forgotten that it
+ // has nothing left on disk, and a comparison is done later on to
+ // avoid saving unmodified data - the bad decision is that data has
+ // not changed, but actually it has and must be reallocated!
+ // (fixes are in c4_FormatV::Insert and c4_FormatV::Remove)
+ v1.SetSize(1);
+ s1.Commit();
+ // at this point, the 2.4.9.2 file is corrupt!
+ c4_FileStream fs1 (fopen("s48b", "wb"), true);
+ s1.SaveTo(fs1);
+ }
+ {
+ // using this damaged datafile will then crash
+ c4_Storage s1 ("s48a", false);
+ c4_View v1 = s1.View("v1");
+ v1.SetSize(2);
+ }
+ } D(s48a); D(s48b); R(s48a); R(s48b); E;
+
+ // 2004-01-20 better handling of bad input: ignore repeated props
+ B(s49, Specify conflicting properties, 0) W(s49a);
+ {
+ c4_Storage s1 ("s49a", true);
+ c4_View v1 = s1.GetAs("v1[p1:I,p1:S]");
+ c4_View v2 = s1.GetAs("v2[p1:I,P1:S]");
+ c4_View v3 = s1.GetAs("v3[v3[^]]");
+ c4_String x1 = s1.Description();
+ A(x1 == "v1[p1:I],v2[p1:I],v3[v3[^]]");
+ s1.Commit();
+ } D(s49a); E;
+}
diff --git a/akregator/src/mk4storage/mk4config.kcfg b/akregator/src/mk4storage/mk4config.kcfg
new file mode 100644
index 000000000..2067756cf
--- /dev/null
+++ b/akregator/src/mk4storage/mk4config.kcfg
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
+ http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
+ <kcfgfile name="akregatorrc" />
+ <group name="StorageMK4" >
+ <entry key="Commit Interval" type="Int" >
+ <label>Commit Interval</label>
+ <whatsthis>Commit interval in seconds for writing back changes</whatsthis>
+ <default>3</default>
+ </entry>
+ <entry key="Archive Path" type="String" >
+ <whatsthis>Path to archive</whatsthis>
+ <default></default>
+ </entry>
+ </group>
+</kcfg>
diff --git a/akregator/src/mk4storage/mk4config.kcfgc b/akregator/src/mk4storage/mk4config.kcfgc
new file mode 100644
index 000000000..d7285cd60
--- /dev/null
+++ b/akregator/src/mk4storage/mk4config.kcfgc
@@ -0,0 +1,6 @@
+File=mk4config.kcfg
+ClassName=MK4Config
+Singleton=true
+NameSpace=Akregator
+Mutators=true
+MemberVariables=private
diff --git a/akregator/src/mk4storage/mk4confwidget.cpp b/akregator/src/mk4storage/mk4confwidget.cpp
new file mode 100644
index 000000000..fb95e1602
--- /dev/null
+++ b/akregator/src/mk4storage/mk4confwidget.cpp
@@ -0,0 +1,92 @@
+/*
+ This file is part of Akregator.
+
+ Copyright (C) 2005 Frank Osterfeld <frank.osterfeld@kdemail.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ As a special exception, permission is given to link this program
+ with any edition of Qt, and distribute the resulting executable,
+ without including the source code for Qt in the source distribution.
+*/
+
+#include "mk4config.h"
+#include "mk4confwidget.h"
+#include "storagemk4impl.h"
+
+#include <qcheckbox.h>
+#include <qlabel.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kurlrequester.h>
+
+namespace Akregator {
+namespace Backend {
+
+MK4ConfWidget::MK4ConfWidget() : MK4ConfWidgetBase()
+{
+ if (MK4Config::archivePath() == StorageMK4Impl::defaultArchivePath() || MK4Config::archivePath().isEmpty())
+ {
+ filereq->setURL(StorageMK4Impl::defaultArchivePath());
+ MK4Config::setArchivePath(StorageMK4Impl::defaultArchivePath());
+ cbUseDefault->setChecked(true);
+ filereq->setEnabled(false);
+ label->setEnabled(false);
+ }
+ else
+ {
+ cbUseDefault->setChecked(false);
+ filereq->setEnabled(true);
+ label->setEnabled(true);
+ }
+ filereq->setURL(MK4Config::archivePath());
+ connect(cbUseDefault, SIGNAL(toggled(bool)), this, SLOT(slotChkBoxUseDefault(bool)));
+
+}
+
+void MK4ConfWidget::accept()
+{
+
+ QString path = cbUseDefault->isChecked() ? StorageMK4Impl::defaultArchivePath() : filereq->url();
+ if (path != MK4Config::archivePath())
+ {
+ // TODO: if the user changed the archive location, inform him that
+ // the archive is not migrated automatically, but that he has to
+ // close Akregator and copy the files over/use some fancy CLI tool not
+ // yet written
+ }
+ MK4Config::setArchivePath(path);
+ MK4Config::writeConfig();
+ MK4ConfWidgetBase::accept();
+}
+
+void MK4ConfWidget::slotChkBoxUseDefault(bool checked)
+{
+ if (checked)
+ {
+ filereq->setURL(StorageMK4Impl::defaultArchivePath());
+ filereq->setEnabled(false);
+ }
+ else
+ {
+ filereq->setEnabled(true);
+ }
+}
+
+
+}
+}
+
+#include "mk4confwidget.moc"
diff --git a/akregator/src/mk4storage/mk4confwidget.h b/akregator/src/mk4storage/mk4confwidget.h
new file mode 100644
index 000000000..e697c21bc
--- /dev/null
+++ b/akregator/src/mk4storage/mk4confwidget.h
@@ -0,0 +1,48 @@
+/*
+ This file is part of Akregator.
+
+ Copyright (C) 2005 Frank Osterfeld <frank.osterfeld@kdemail.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ As a special exception, permission is given to link this program
+ with any edition of Qt, and distribute the resulting executable,
+ without including the source code for Qt in the source distribution.
+*/
+
+#ifndef AKREGATOR_BACKEND_MK4CONFWIDGET_H
+#define AKREGATOR_BACKEND_MK4CONFWIDGET_H
+
+#include "mk4confwidgetbase.h"
+
+namespace Akregator {
+namespace Backend {
+
+class MK4ConfWidget : public MK4ConfWidgetBase
+{
+ Q_OBJECT
+ public:
+
+ MK4ConfWidget();
+
+ public slots:
+ virtual void accept();
+ void slotChkBoxUseDefault(bool checked);
+};
+
+}
+}
+
+#endif // AKREGATOR_BACKEND_MK4CONFWIDGET_H
diff --git a/akregator/src/mk4storage/mk4confwidgetbase.ui b/akregator/src/mk4storage/mk4confwidgetbase.ui
new file mode 100644
index 000000000..cc91559af
--- /dev/null
+++ b/akregator/src/mk4storage/mk4confwidgetbase.ui
@@ -0,0 +1,178 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>Akregator::Backend::MK4ConfWidgetBase</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>MK4ConfWidgetBase</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>377</width>
+ <height>115</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Metakit Settings</string>
+ </property>
+ <property name="sizeGripEnabled">
+ <bool>true</bool>
+ </property>
+ <property name="modal">
+ <bool>true</bool>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget" row="0" column="0">
+ <property name="name">
+ <cstring>layout4</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>cbUseDefault</cstring>
+ </property>
+ <property name="text">
+ <string>Use default location</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout3</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>label</cstring>
+ </property>
+ <property name="text">
+ <string>Archive location:</string>
+ </property>
+ </widget>
+ <widget class="KURLRequester">
+ <property name="name">
+ <cstring>filereq</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QLayoutWidget" row="1" column="0">
+ <property name="name">
+ <cstring>layout4</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>Horizontal Spacing2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>140</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>buttonOk</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;OK</string>
+ </property>
+ <property name="accel">
+ <string></string>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>buttonApply</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Apply</string>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>buttonCancel</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Cancel</string>
+ </property>
+ <property name="accel">
+ <string></string>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>buttonOk</sender>
+ <signal>clicked()</signal>
+ <receiver>MK4ConfWidgetBase</receiver>
+ <slot>accept()</slot>
+ </connection>
+ <connection>
+ <sender>buttonCancel</sender>
+ <signal>clicked()</signal>
+ <receiver>MK4ConfWidgetBase</receiver>
+ <slot>reject()</slot>
+ </connection>
+ <connection>
+ <sender>cbUseDefault</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>label</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cbUseDefault</sender>
+ <signal>&lt;No Signal&gt;</signal>
+ <receiver>cbUseDefault</receiver>
+ <slot>&lt;No)</slot>
+ </connection>
+</connections>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kurlrequester.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+</includehints>
+</UI>
diff --git a/akregator/src/mk4storage/mk4plugin.cpp b/akregator/src/mk4storage/mk4plugin.cpp
new file mode 100644
index 000000000..a475a226a
--- /dev/null
+++ b/akregator/src/mk4storage/mk4plugin.cpp
@@ -0,0 +1,50 @@
+/*
+ This file is part of Akregator.
+
+ Copyright (C) 2005 Frank Osterfeld <frank.osterfeld@kdemail.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ As a special exception, permission is given to link this program
+ with any edition of Qt, and distribute the resulting executable,
+ without including the source code for Qt in the source distribution.
+*/
+
+#include "mk4plugin.h"
+
+#include <klocale.h>
+
+#include "storagefactorymk4impl.h"
+#include "storagefactoryregistry.h"
+
+AKREGATOR_EXPORT_PLUGIN( Akregator::Backend::MK4Plugin )
+
+namespace Akregator {
+namespace Backend {
+
+bool MK4Plugin::init()
+{
+ m_factory = new StorageFactoryMK4Impl();
+ return StorageFactoryRegistry::self()->registerFactory(m_factory, "metakit");
+}
+
+MK4Plugin::~MK4Plugin()
+{
+ StorageFactoryRegistry::self()->unregisterFactory("metakit");
+ delete m_factory;
+}
+
+}
+}
diff --git a/akregator/src/mk4storage/mk4plugin.h b/akregator/src/mk4storage/mk4plugin.h
new file mode 100644
index 000000000..0c46e4fb5
--- /dev/null
+++ b/akregator/src/mk4storage/mk4plugin.h
@@ -0,0 +1,49 @@
+/*
+ This file is part of Akregator.
+
+ Copyright (C) 2005 Frank Osterfeld <frank.osterfeld@kdemail.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ As a special exception, permission is given to link this program
+ with any edition of Qt, and distribute the resulting executable,
+ without including the source code for Qt in the source distribution.
+*/
+
+#ifndef AKREGATOR_BACKEND_MK4PLUGIN_H
+#define AKREGATOR_BACKEND_MK4PLUGIN_H
+
+#include "../plugin.h"
+
+class QString;
+
+namespace Akregator {
+namespace Backend {
+
+class StorageFactory;
+
+class MK4Plugin : public Akregator::Plugin
+{
+ public:
+ virtual ~MK4Plugin();
+ virtual bool init();
+
+ private:
+ StorageFactory* m_factory;
+};
+
+}
+}
+#endif // AKREGATOR_BACKEND_MK4PLUGIN_H
diff --git a/akregator/src/mk4storage/storagefactorymk4impl.cpp b/akregator/src/mk4storage/storagefactorymk4impl.cpp
new file mode 100644
index 000000000..9303bb965
--- /dev/null
+++ b/akregator/src/mk4storage/storagefactorymk4impl.cpp
@@ -0,0 +1,71 @@
+/*
+ This file is part of Akregator.
+
+ Copyright (C) 2005 Frank Osterfeld <frank.osterfeld@kdemail.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ As a special exception, permission is given to link this program
+ with any edition of Qt, and distribute the resulting executable,
+ without including the source code for Qt in the source distribution.
+*/
+#include "storagefactorymk4impl.h"
+#include "storagemk4impl.h"
+//#include "mk4confwidget.h"
+//#include "mk4config.h"
+
+#include <klocale.h>
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qwidget.h>
+
+namespace Akregator {
+namespace Backend {
+
+Storage* StorageFactoryMK4Impl::createStorage(const QStringList& params) const
+{
+ Storage* storage = new StorageMK4Impl;
+ storage->initialize(params);
+ return storage;
+}
+
+QString StorageFactoryMK4Impl::key() const
+{
+ return "metakit";
+}
+
+QString StorageFactoryMK4Impl::name() const
+{
+ return i18n("Metakit");
+}
+
+
+void StorageFactoryMK4Impl::configure()
+{ /*
+ MK4ConfWidgetBase* confWidget = new MK4ConfWidget();
+ // fill with Settings
+
+
+ if (confWidget->exec() == QDialog::Accepted)
+ {
+ // store and apply settings
+ }
+
+ delete confWidget;
+ */
+}
+
+}
+}
diff --git a/akregator/src/mk4storage/storagefactorymk4impl.h b/akregator/src/mk4storage/storagefactorymk4impl.h
new file mode 100644
index 000000000..b5e51db9d
--- /dev/null
+++ b/akregator/src/mk4storage/storagefactorymk4impl.h
@@ -0,0 +1,53 @@
+/*
+ This file is part of Akregator.
+
+ Copyright (C) 2005 Frank Osterfeld <frank.osterfeld@kdemail.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ As a special exception, permission is given to link this program
+ with any edition of Qt, and distribute the resulting executable,
+ without including the source code for Qt in the source distribution.
+*/
+
+#ifndef STORAGEFACTORYMK4IMPL_H
+#define STORAGEFACTORYMK4IMPL_H
+
+#include "storagefactory.h"
+
+class QString;
+class QStringList;
+
+namespace Akregator {
+namespace Backend {
+
+class Storage;
+
+class StorageFactoryMK4Impl : public StorageFactory
+{
+ public:
+ virtual QString key() const;
+ virtual QString name() const;
+ virtual void configure();
+ virtual Storage* createStorage(const QStringList& params) const;
+ virtual bool isConfigurable() const { return false; }
+ virtual bool allowsMultipleWriteAccess() const { return false; }
+
+};
+
+}
+}
+
+#endif
diff --git a/akregator/src/mk4storage/storagemk4impl.cpp b/akregator/src/mk4storage/storagemk4impl.cpp
new file mode 100644
index 000000000..8a3af0e02
--- /dev/null
+++ b/akregator/src/mk4storage/storagemk4impl.cpp
@@ -0,0 +1,402 @@
+/*
+ This file is part of Akregator.
+
+ Copyright (C) 2005 Stanislav Karchebny <Stanislav.Karchebny@kdemail.net>
+ 2005 Frank Osterfeld <frank.osterfeld@kdemail.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ As a special exception, permission is given to link this program
+ with any edition of Qt, and distribute the resulting executable,
+ without including the source code for Qt in the source distribution.
+*/
+#include "storagemk4impl.h"
+#include "feedstoragemk4impl.h"
+
+#include <mk4.h>
+
+#include <qmap.h>
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qtimer.h>
+
+#include <kdebug.h>
+#include <kstandarddirs.h>
+
+namespace Akregator {
+namespace Backend {
+
+class StorageMK4Impl::StorageMK4ImplPrivate
+{
+ public:
+ StorageMK4ImplPrivate() : modified(false),
+ purl("url"),
+ pFeedList("feedList"),
+ pTagSet("tagSet"),
+ punread("unread"),
+ ptotalCount("totalCount"),
+ plastFetch("lastFetch") {}
+
+ c4_Storage* storage;
+ c4_View archiveView;
+ bool autoCommit;
+ bool modified;
+ QMap<QString, FeedStorage*> feeds;
+ QStringList feedURLs;
+ c4_StringProp purl, pFeedList, pTagSet;
+ c4_IntProp punread, ptotalCount, plastFetch;
+ QString archivePath;
+
+ bool taggingEnabled;
+
+ c4_Storage* feedListStorage;
+ c4_View feedListView;
+};
+
+bool StorageMK4Impl::taggingEnabled() const
+{
+ return d->taggingEnabled;
+}
+
+void StorageMK4Impl::setArchivePath(const QString& archivePath)
+{
+ if (archivePath.isNull()) // if isNull, reset to default
+ d->archivePath = defaultArchivePath();
+ else
+ d->archivePath = archivePath;
+}
+
+QString StorageMK4Impl::archivePath() const
+{
+ return d->archivePath;
+}
+
+StorageMK4Impl::StorageMK4Impl() : d(new StorageMK4ImplPrivate)
+{
+ setArchivePath(QString::null); // set path to default
+}
+
+QString StorageMK4Impl::defaultArchivePath()
+{
+ return KGlobal::dirs()->saveLocation("data", "akregator")+"Archive";
+}
+
+StorageMK4Impl::~StorageMK4Impl()
+{
+ close();
+ delete d;
+ d = 0;
+}
+void StorageMK4Impl::initialize(const QStringList& params)
+{
+ d->taggingEnabled = false;
+
+ QStringList::ConstIterator it = params.begin();
+ QStringList::ConstIterator end = params.end();
+
+ for ( ; it != end; ++it)
+ {
+ QStringList tokens = QStringList::split("=", *it);
+ if (tokens.count() == 2 && *(tokens.at(0)) == "taggingEnabled"
+ && *(tokens.at(1)) == "true")
+ {
+ d->taggingEnabled = true;
+ }
+
+ }
+}
+
+bool StorageMK4Impl::open(bool autoCommit)
+{
+ QString filePath = d->archivePath +"/archiveindex.mk4";
+ d->storage = new c4_Storage(filePath.local8Bit(), true);
+ d->archiveView = d->storage->GetAs("archive[url:S,unread:I,totalCount:I,lastFetch:I]");
+ c4_View hash = d->storage->GetAs("archiveHash[_H:I,_R:I]");
+ d->archiveView = d->archiveView.Hash(hash, 1); // hash on url
+ d->autoCommit = autoCommit;
+
+ filePath = d->archivePath +"/feedlistbackup.mk4";
+ d->feedListStorage = new c4_Storage(filePath.local8Bit(), true);
+ d->feedListView = d->feedListStorage->GetAs("archive[feedList:S,tagSet:S]");
+ return true;
+}
+
+bool StorageMK4Impl::autoCommit() const
+{
+ return d->autoCommit;
+}
+
+bool StorageMK4Impl::close()
+{
+ QMap<QString, FeedStorage*>::Iterator it;
+ QMap<QString, FeedStorage*>::Iterator end(d->feeds.end() ) ;
+ for (it = d->feeds.begin(); it != end; ++it)
+ {
+ it.data()->close();
+ delete it.data();
+ }
+ if(d->autoCommit)
+ d->storage->Commit();
+
+ delete d->storage;
+ d->storage = 0;
+
+ d->feedListStorage->Commit();
+ delete d->feedListStorage;
+ d->feedListStorage = 0;
+
+ return true;
+}
+
+bool StorageMK4Impl::commit()
+{
+ QMap<QString, FeedStorage*>::Iterator it;
+ QMap<QString, FeedStorage*>::Iterator end(d->feeds.end() ) ;
+ for ( it = d->feeds.begin(); it != end; ++it )
+ it.data()->commit();
+
+ if(d->storage)
+ {
+ d->storage->Commit();
+ return true;
+ }
+
+ return false;
+}
+
+bool StorageMK4Impl::rollback()
+{
+ QMap<QString, FeedStorage*>::Iterator it;
+ QMap<QString, FeedStorage*>::Iterator end(d->feeds.end() ) ;
+ for ( it = d->feeds.begin(); it != end; ++it )
+ it.data()->rollback();
+
+ if(d->storage)
+ {
+ d->storage->Rollback();
+ return true;
+ }
+ return false;
+}
+
+int StorageMK4Impl::unreadFor(const QString &url)
+{
+ c4_Row findrow;
+ d->purl(findrow) = url.ascii();
+ int findidx = d->archiveView.Find(findrow);
+
+ return findidx != -1 ? d->punread(d->archiveView.GetAt(findidx)) : 0;
+}
+
+void StorageMK4Impl::setUnreadFor(const QString &url, int unread)
+{
+ c4_Row findrow;
+ d->purl(findrow) = url.ascii();
+ int findidx = d->archiveView.Find(findrow);
+ if (findidx == -1)
+ return;
+ findrow = d->archiveView.GetAt(findidx);
+ d->punread(findrow) = unread;
+ d->archiveView.SetAt(findidx, findrow);
+ markDirty();
+}
+
+int StorageMK4Impl::totalCountFor(const QString &url)
+{
+ c4_Row findrow;
+ d->purl(findrow) = url.ascii();
+ int findidx = d->archiveView.Find(findrow);
+
+ return findidx != -1 ? d->ptotalCount(d->archiveView.GetAt(findidx)) : 0;
+}
+
+void StorageMK4Impl::setTotalCountFor(const QString &url, int total)
+{
+ c4_Row findrow;
+ d->purl(findrow) = url.ascii();
+ int findidx = d->archiveView.Find(findrow);
+ if (findidx == -1)
+ return;
+ findrow = d->archiveView.GetAt(findidx);
+ d->ptotalCount(findrow) = total;
+ d->archiveView.SetAt(findidx, findrow);
+ markDirty();
+}
+
+int StorageMK4Impl::lastFetchFor(const QString& url)
+{
+ c4_Row findrow;
+ d->purl(findrow) = url.ascii();
+ int findidx = d->archiveView.Find(findrow);
+
+ return (findidx != -1 ? d->plastFetch(d->archiveView.GetAt(findidx)) : 0);
+}
+
+void StorageMK4Impl::setLastFetchFor(const QString& url, int lastFetch)
+{
+ c4_Row findrow;
+ d->purl(findrow) = url.ascii();
+ int findidx = d->archiveView.Find(findrow);
+ if (findidx == -1)
+ return;
+ findrow = d->archiveView.GetAt(findidx);
+ d->plastFetch(findrow) = lastFetch;
+ d->archiveView.SetAt(findidx, findrow);
+ markDirty();
+}
+
+void StorageMK4Impl::markDirty()
+{
+ if (!d->modified)
+ {
+ d->modified = true;
+ // commit changes after 3 seconds
+ QTimer::singleShot(3000, this, SLOT(slotCommit()));
+ }
+}
+
+void StorageMK4Impl::slotCommit()
+{
+ if (d->modified)
+ commit();
+ d->modified = false;
+}
+
+FeedStorage* StorageMK4Impl::archiveFor(const QString& url)
+{
+ if (!d->feeds.contains(url))
+ {
+ FeedStorage* fs = new FeedStorageMK4Impl(url, this);
+ d->feeds[url] = fs;
+ c4_Row findrow;
+ d->purl(findrow) = url.ascii();
+ int findidx = d->archiveView.Find(findrow);
+ if (findidx == -1)
+ {
+ d->punread(findrow) = 0;
+ d->ptotalCount(findrow) = 0;
+ d->plastFetch(findrow) = 0;
+ d->archiveView.Add(findrow);
+ markDirty();
+ }
+ fs->convertOldArchive();
+ }
+ return d->feeds[url];
+}
+
+QStringList StorageMK4Impl::feeds() const
+{
+ // TODO: cache list
+ QStringList list;
+ int size = d->archiveView.GetSize();
+ for (int i = 0; i < size; i++)
+ list += QString(d->purl(d->archiveView.GetAt(i)));
+ // fill with urls
+ return list;
+
+}
+
+void StorageMK4Impl::add(Storage* source)
+{
+ QStringList feeds = source->feeds();
+ QStringList::ConstIterator end(feeds.end() ) ;
+
+ for (QStringList::ConstIterator it = feeds.begin(); it != end; ++it)
+ {
+ FeedStorage* fa = archiveFor(*it);
+ fa->add(source->archiveFor(*it));
+ }
+}
+
+
+void StorageMK4Impl::clear()
+{
+ QStringList feeds;
+ int size = d->archiveView.GetSize();
+ for (int i = 0; i < size; i++)
+ feeds += QString(d->purl(d->archiveView.GetAt(i)));
+ QStringList::ConstIterator end(feeds.end() ) ;
+
+ for (QStringList::ConstIterator it = feeds.begin(); it != end; ++it)
+ {
+ FeedStorage* fa = archiveFor(*it);
+ fa->clear();
+ fa->commit();
+ // FIXME: delete file (should be 0 in size now)
+ }
+ d->storage->RemoveAll();
+
+}
+
+void StorageMK4Impl::storeFeedList(const QString& opmlStr)
+{
+
+ if (d->feedListView.GetSize() == 0)
+ {
+ c4_Row row;
+ d->pFeedList(row) = !opmlStr.isEmpty() ? opmlStr.utf8().data() : "";
+ d->pTagSet(row) = "";
+ d->feedListView.Add(row);
+ }
+ else
+ {
+ c4_Row row = d->feedListView.GetAt(0);
+ d->pFeedList(row) = !opmlStr.isEmpty() ? opmlStr.utf8().data() : "";
+ d->feedListView.SetAt(0, row);
+ }
+ markDirty();
+}
+
+QString StorageMK4Impl::restoreFeedList() const
+{
+ if (d->feedListView.GetSize() == 0)
+ return "";
+
+ c4_Row row = d->feedListView.GetAt(0);
+ return QString::fromUtf8(d->pFeedList(row));
+}
+
+void StorageMK4Impl::storeTagSet(const QString& xmlStr)
+{
+
+ if (d->feedListView.GetSize() == 0)
+ {
+ c4_Row row;
+ d->pTagSet(row) = !xmlStr.isEmpty() ? xmlStr.utf8().data() : "";
+ d->pFeedList(row) = "";
+ d->feedListView.Add(row);
+ }
+ else
+ {
+ c4_Row row = d->feedListView.GetAt(0);
+ d->pTagSet(row) = !xmlStr.isEmpty() ? xmlStr.utf8().data() : "";
+ d->feedListView.SetAt(0, row);
+ }
+ markDirty();
+}
+
+QString StorageMK4Impl::restoreTagSet() const
+{
+ if (d->feedListView.GetSize() == 0)
+ return "";
+
+ c4_Row row = d->feedListView.GetAt(0);
+ return QString::fromUtf8(d->pTagSet(row));
+}
+
+} // namespace Backend
+} // namespace Akregator
+
+#include "storagemk4impl.moc"
diff --git a/akregator/src/mk4storage/storagemk4impl.h b/akregator/src/mk4storage/storagemk4impl.h
new file mode 100644
index 000000000..7b3a43783
--- /dev/null
+++ b/akregator/src/mk4storage/storagemk4impl.h
@@ -0,0 +1,130 @@
+/*
+ This file is part of Akregator.
+
+ Copyright (C) 2005 Stanislav Karchebny <Stanislav.Karchebny@kdemail.net>
+ 2005 Frank Osterfeld <frank.osterfeld@kdemail.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ As a special exception, permission is given to link this program
+ with any edition of Qt, and distribute the resulting executable,
+ without including the source code for Qt in the source distribution.
+*/
+
+#ifndef STORAGEMK4IMPL_H
+#define STORAGEMK4IMPL_H
+
+#include "storage.h"
+
+namespace Akregator {
+namespace Backend {
+
+/**
+ * Metakit implementation of Storage interface
+ */
+class StorageMK4Impl : public Storage
+{
+ Q_OBJECT
+ public:
+
+ StorageMK4Impl();
+ StorageMK4Impl(const StorageMK4Impl&);
+ StorageMK4Impl &operator =(const StorageMK4Impl&);
+ virtual ~StorageMK4Impl();
+
+
+ /** KGlobal::dirs()->saveLocation("data", "akregator")+"/Archive" */
+ static QString defaultArchivePath();
+
+ /** sets the directory where the metakit files will be stored.
+
+ @param archivePath the path to the archive, or QString::null to reset it to the default.
+ */
+ void setArchivePath(const QString& archivePath);
+
+ /** returns the path to the metakit archives */
+ QString archivePath() const;
+
+
+
+ virtual void initialize(const QStringList& params);
+ /**
+ * Open storage and prepare it for work.
+ * @return true on success.
+ */
+ virtual bool open(bool autoCommit = false);
+
+ /**
+ * Commit changes made in feeds and articles, making them persistent.
+ * @return true on success.
+ */
+ virtual bool commit();
+
+ /**
+ * Rollback changes made in feeds and articles, reverting to last committed values.
+ * @returns true on success.
+ */
+ virtual bool rollback();
+
+ /**
+ * Closes storage, freeing all allocated resources. Called from destructor, so you don't need to call it directly.
+ * @return true on success.
+ */
+ virtual bool close();
+
+ /**
+ * @return Article archive for feed at given url.
+ */
+ virtual FeedStorage* archiveFor(const QString &url);
+ virtual bool autoCommit() const;
+ virtual int unreadFor(const QString &url);
+ virtual void setUnreadFor(const QString &url, int unread);
+ virtual int totalCountFor(const QString &url);
+ virtual void setTotalCountFor(const QString &url, int total);
+ virtual int lastFetchFor(const QString& url);
+ virtual void setLastFetchFor(const QString& url, int lastFetch);
+
+ virtual QStringList feeds() const;
+
+ virtual void storeFeedList(const QString& opmlStr);
+ virtual QString restoreFeedList() const;
+
+ virtual void storeTagSet(const QString& xmlStr);
+ virtual QString restoreTagSet() const;
+
+ /** adds all feed storages from a source to this storage
+ existing articles are replaced
+ */
+ virtual void add(Storage* source);
+
+ /** deletes all feed storages in this archive */
+ virtual void clear();
+
+ virtual bool taggingEnabled() const;
+
+ void markDirty();
+
+ protected slots:
+ virtual void slotCommit();
+
+ private:
+ class StorageMK4ImplPrivate;
+ StorageMK4ImplPrivate *d;
+};
+
+}
+}
+
+#endif // STORAGEMK4IMPL_H