diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/bookmarks.c | 109 | ||||
-rw-r--r-- | src/bookmarks.h | 39 |
2 files changed, 148 insertions, 0 deletions
diff --git a/src/bookmarks.c b/src/bookmarks.c new file mode 100644 index 00000000..babfc323 --- /dev/null +++ b/src/bookmarks.c | |||
@@ -0,0 +1,109 @@ | |||
1 | #include "bookmarks.h" | ||
2 | |||
3 | #include <the_Foundation/file.h> | ||
4 | #include <the_Foundation/path.h> | ||
5 | |||
6 | void init_Bookmark(iBookmark *d) { | ||
7 | init_String(&d->url); | ||
8 | init_String(&d->title); | ||
9 | init_String(&d->tags); | ||
10 | iZap(d->when); | ||
11 | } | ||
12 | |||
13 | void deinit_Bookmark(iBookmark *d) { | ||
14 | deinit_String(&d->tags); | ||
15 | deinit_String(&d->title); | ||
16 | deinit_String(&d->url); | ||
17 | } | ||
18 | |||
19 | iDefineTypeConstruction(Bookmark) | ||
20 | |||
21 | static int cmpTimeDescending_Bookmark_(const iBookmark **a, const iBookmark **b) { | ||
22 | return iCmp(seconds_Time(&(*b)->when), seconds_Time(&(*a)->when)); | ||
23 | } | ||
24 | |||
25 | /*----------------------------------------------------------------------------------------------*/ | ||
26 | |||
27 | static const char *fileName_Bookmarks_ = "bookmarks.txt"; | ||
28 | |||
29 | struct Impl_Bookmarks { | ||
30 | iArray bookmarks; | ||
31 | }; | ||
32 | |||
33 | iDefineTypeConstruction(Bookmarks) | ||
34 | |||
35 | void init_Bookmarks(iBookmarks *d) { | ||
36 | init_Array(&d->bookmarks, sizeof(iBookmark)); | ||
37 | } | ||
38 | |||
39 | void deinit_Bookmarks(iBookmarks *d) { | ||
40 | clear_Bookmarks(d); | ||
41 | deinit_Array(&d->bookmarks); | ||
42 | } | ||
43 | |||
44 | void clear_Bookmarks(iBookmarks *d) { | ||
45 | iForEach(Array, i, &d->bookmarks) { | ||
46 | deinit_Bookmark(i.value); | ||
47 | } | ||
48 | clear_Array(&d->bookmarks); | ||
49 | } | ||
50 | |||
51 | void load_Bookmarks(iBookmarks *d, const char *dirPath) { | ||
52 | clear_Bookmarks(d); | ||
53 | iFile *f = newCStr_File(concatPath_CStr(dirPath, fileName_Bookmarks_)); | ||
54 | if (open_File(f, readOnly_FileMode | text_FileMode)) { | ||
55 | const iRangecc src = range_Block(collect_Block(readAll_File(f))); | ||
56 | iRangecc line = iNullRange; | ||
57 | while (nextSplit_Rangecc(&src, "\n", &line)) { | ||
58 | iBookmark bm; | ||
59 | init_Bookmark(&bm); | ||
60 | char *endPos; | ||
61 | initSeconds_Time(&bm.when, strtod(line.start, &endPos)); | ||
62 | line.start = skipSpace_CStr(endPos); | ||
63 | setRange_String(&bm.url, line); | ||
64 | nextSplit_Rangecc(&src, "\n", &line); | ||
65 | setRange_String(&bm.title, line); | ||
66 | nextSplit_Rangecc(&src, "\n", &line); | ||
67 | setRange_String(&bm.tags, line); | ||
68 | pushBack_Array(&d->bookmarks, &bm); | ||
69 | } | ||
70 | } | ||
71 | iRelease(f); | ||
72 | } | ||
73 | |||
74 | void save_Bookmarks(const iBookmarks *d, const char *dirPath) { | ||
75 | iFile *f = newCStr_File(concatPath_CStr(dirPath, fileName_Bookmarks_)); | ||
76 | if (open_File(f, writeOnly_FileMode | text_FileMode)) { | ||
77 | iString *str = collectNew_String(); | ||
78 | iConstForEach(Array, i, &d->bookmarks) { | ||
79 | const iBookmark *bm = i.value; | ||
80 | format_String(str, "%lf %s\%s\n%s\n", seconds_Time(&bm->when), cstr_String(&bm->url), | ||
81 | cstr_String(&bm->title), cstr_String(&bm->tags)); | ||
82 | writeData_File(f, cstr_String(str), size_String(str)); | ||
83 | } | ||
84 | } | ||
85 | iRelease(f); | ||
86 | } | ||
87 | |||
88 | void add_Bookmarks(iBookmarks *d, const iString *url, const iString *title, const iString *tags) { | ||
89 | iBookmark bm; | ||
90 | init_Bookmark(&bm); | ||
91 | set_String(&bm.url, url); | ||
92 | set_String(&bm.title, title); | ||
93 | set_String(&bm.tags, tags); | ||
94 | initCurrent_Time(&bm.when); | ||
95 | pushBack_Array(&d->bookmarks, &bm); | ||
96 | } | ||
97 | |||
98 | const iPtrArray *list_Bookmarks(const iBookmarks *d, iBookmarksFilterFunc filter, | ||
99 | iBookmarksCompareFunc cmp) { | ||
100 | iPtrArray *list = collectNew_PtrArray(); | ||
101 | iConstForEach(Array, i, &d->bookmarks) { | ||
102 | if (!filter || filter(i.value)) { | ||
103 | pushBack_PtrArray(list, i.value); | ||
104 | } | ||
105 | } | ||
106 | if (!cmp) cmp = cmpTimeDescending_Bookmark_; | ||
107 | sort_Array(list, (int (*)(const void *, const void *)) cmp); | ||
108 | return list; | ||
109 | } | ||
diff --git a/src/bookmarks.h b/src/bookmarks.h new file mode 100644 index 00000000..e32f6bef --- /dev/null +++ b/src/bookmarks.h | |||
@@ -0,0 +1,39 @@ | |||
1 | #pragma once | ||
2 | |||
3 | #include <the_Foundation/ptrarray.h> | ||
4 | #include <the_Foundation/string.h> | ||
5 | #include <the_Foundation/time.h> | ||
6 | |||
7 | iDeclareType(Bookmark) | ||
8 | iDeclareTypeConstruction(Bookmark) | ||
9 | |||
10 | struct Impl_Bookmark { | ||
11 | iString url; | ||
12 | iString title; | ||
13 | iString tags; | ||
14 | iTime when; | ||
15 | }; | ||
16 | |||
17 | iDeclareType(Bookmarks) | ||
18 | iDeclareTypeConstruction(Bookmarks) | ||
19 | |||
20 | void clear_Bookmarks (iBookmarks *); | ||
21 | void load_Bookmarks (iBookmarks *, const char *dirPath); | ||
22 | void save_Bookmarks (const iBookmarks *, const char *dirPath); | ||
23 | |||
24 | typedef iBool (*iBookmarksFilterFunc) (const iBookmark *); | ||
25 | typedef int (*iBookmarksCompareFunc)(const iBookmark **, const iBookmark **); | ||
26 | |||
27 | /** | ||
28 | * Lists all or a subset of the bookmarks in a sorted array of Bookmark pointers. | ||
29 | * | ||
30 | * @param filter Filter function to determine which bookmarks should be returned. | ||
31 | * If NULL, all bookmarks are listed. | ||
32 | * @param cmp Sort function that compares Bookmark pointers. If NULL, the | ||
33 | * returned list is sorted by descending creation time. | ||
34 | * | ||
35 | * @return Collected array of bookmarks. Caller does not get ownership of the | ||
36 | * list or the bookmarks. | ||
37 | */ | ||
38 | const iPtrArray *list_Bookmarks(const iBookmarks *, iBookmarksFilterFunc filter, | ||
39 | iBookmarksCompareFunc cmp); | ||