diff options
Diffstat (limited to 'src/sitespec.c')
-rw-r--r-- | src/sitespec.c | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/src/sitespec.c b/src/sitespec.c new file mode 100644 index 00000000..4df62a9f --- /dev/null +++ b/src/sitespec.c | |||
@@ -0,0 +1,158 @@ | |||
1 | /* Copyright 2021 Jaakko Keränen <jaakko.keranen@iki.fi> | ||
2 | |||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions are met: | ||
5 | |||
6 | 1. Redistributions of source code must retain the above copyright notice, this | ||
7 | list of conditions and the following disclaimer. | ||
8 | 2. Redistributions in binary form must reproduce the above copyright notice, | ||
9 | this list of conditions and the following disclaimer in the documentation | ||
10 | and/or other materials provided with the distribution. | ||
11 | |||
12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | ||
13 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
14 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
15 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR | ||
16 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
17 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
18 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
19 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
20 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
21 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | ||
22 | |||
23 | #include "sitespec.h" | ||
24 | |||
25 | #include <the_Foundation/file.h> | ||
26 | #include <the_Foundation/path.h> | ||
27 | #include <the_Foundation/stringhash.h> | ||
28 | |||
29 | iDeclareClass(SiteParams) | ||
30 | iDeclareObjectConstruction(SiteParams) | ||
31 | |||
32 | struct Impl_SiteParams { | ||
33 | iObject object; | ||
34 | uint16_t titanPort; | ||
35 | /* TODO: theme seed, style settings */ | ||
36 | }; | ||
37 | |||
38 | void init_SiteParams(iSiteParams *d) { | ||
39 | d->titanPort = 0; /* undefined */ | ||
40 | } | ||
41 | |||
42 | void deinit_SiteParams(iSiteParams *d) { | ||
43 | iUnused(d); | ||
44 | } | ||
45 | |||
46 | iDefineClass(SiteParams) | ||
47 | iDefineObjectConstruction(SiteParams) | ||
48 | |||
49 | /*----------------------------------------------------------------------------------------------*/ | ||
50 | |||
51 | struct Impl_SiteSpec { | ||
52 | iString savePath; | ||
53 | iStringHash sites; | ||
54 | }; | ||
55 | |||
56 | static iSiteSpec siteSpec_; | ||
57 | |||
58 | static void load_SiteSpec_(iSiteSpec *d) { | ||
59 | iFile *f = iClob(new_File(&d->savePath)); | ||
60 | if (open_File(f, readOnly_FileMode | text_FileMode)) { | ||
61 | iString *src = collect_String(readString_File(f)); | ||
62 | iRangecc split = iNullRange; | ||
63 | iString *key = collectNew_String(); | ||
64 | iSiteParams *params = NULL; | ||
65 | while (nextSplit_Rangecc(range_String(src), "\n", &split)) { | ||
66 | iRangecc line = split; | ||
67 | trim_Rangecc(&line); | ||
68 | if (isEmpty_Range(&line)) { | ||
69 | continue; | ||
70 | } | ||
71 | if (startsWith_Rangecc(line, "# ")) { | ||
72 | if (params && !isEmpty_String(key)) { | ||
73 | insert_StringHash(&d->sites, key, params); | ||
74 | iReleasePtr(¶ms); | ||
75 | } | ||
76 | line.start += 2; | ||
77 | setRange_String(key, line); | ||
78 | params = new_SiteParams(); | ||
79 | continue; | ||
80 | } | ||
81 | if (startsWith_Rangecc(line, "titanPort: ")) { | ||
82 | line.start += 11; | ||
83 | if (params) { | ||
84 | params->titanPort = atoi(cstr_Rangecc(line)); | ||
85 | } | ||
86 | continue; | ||
87 | } | ||
88 | } | ||
89 | if (params && !isEmpty_String(key)) { | ||
90 | insert_StringHash(&d->sites, key, params); | ||
91 | iReleasePtr(¶ms); | ||
92 | } | ||
93 | } | ||
94 | } | ||
95 | |||
96 | static void save_SiteSpec_(iSiteSpec *d) { | ||
97 | iFile *f = new_File(&d->savePath); | ||
98 | if (open_File(f, writeOnly_FileMode | text_FileMode)) { | ||
99 | iString *buf = new_String(); | ||
100 | iConstForEach(StringHash, i, &d->sites) { | ||
101 | const iBlock * key = &i.value->keyBlock; | ||
102 | const iSiteParams *params = i.value->object; | ||
103 | format_String(buf, "# %s\n", cstr_Block(key)); | ||
104 | appendFormat_String(buf, "titanPort: %u\n", params->titanPort); | ||
105 | write_File(f, utf8_String(buf)); | ||
106 | } | ||
107 | delete_String(buf); | ||
108 | } | ||
109 | iRelease(f); | ||
110 | } | ||
111 | |||
112 | void init_SiteSpec(const char *saveDir) { | ||
113 | iSiteSpec *d = &siteSpec_; | ||
114 | initCStr_String(&d->savePath, concatPath_CStr(saveDir, "sitespec.txt")); | ||
115 | init_StringHash(&d->sites); | ||
116 | load_SiteSpec_(d); | ||
117 | } | ||
118 | |||
119 | void deinit_SiteSpec(void) { | ||
120 | iSiteSpec *d = &siteSpec_; | ||
121 | deinit_StringHash(&d->sites); | ||
122 | deinit_String(&d->savePath); | ||
123 | } | ||
124 | |||
125 | void setValue_SiteSpec(const iString *site, enum iSiteSpecKey key, int value) { | ||
126 | iSiteSpec *d = &siteSpec_; | ||
127 | const iString *hashKey = collect_String(lower_String(site)); | ||
128 | iSiteParams *params = value_StringHash(&d->sites, hashKey); | ||
129 | if (!params) { | ||
130 | params = new_SiteParams(); | ||
131 | insert_StringHash(&d->sites, hashKey, params); | ||
132 | } | ||
133 | iBool needSave = iFalse; | ||
134 | switch (key) { | ||
135 | case titanPort_SiteSpecKey: | ||
136 | params->titanPort = iClamp(value, 0, 0xffff); | ||
137 | needSave = iTrue; | ||
138 | default: | ||
139 | break; | ||
140 | } | ||
141 | if (needSave) { | ||
142 | save_SiteSpec_(d); | ||
143 | } | ||
144 | } | ||
145 | |||
146 | int value_SiteSpec(const iString *site, enum iSiteSpecKey key) { | ||
147 | iSiteSpec *d = &siteSpec_; | ||
148 | const iSiteParams *params = constValue_StringHash(&d->sites, collect_String(lower_String(site))); | ||
149 | if (!params) { | ||
150 | return 0; | ||
151 | } | ||
152 | switch (key) { | ||
153 | case titanPort_SiteSpecKey: | ||
154 | return params->titanPort; | ||
155 | default: | ||
156 | return 0; | ||
157 | } | ||
158 | } | ||