vfs: check userland buffers before reading them.
[haiku.git] / src / apps / webpositive / support / SettingsMessage.cpp
blob15dc12394ce9f8c9ffba6d1c3a2a9513c5a1ae89
1 /*
2 * Copyright 2008-2010, Stephan Aßmus <superstippi@gmx.de>.
3 * Copyright 1998, Eric Shepherd.
4 * All rights reserved. Distributed under the terms of the Be Sample Code
5 * license.
6 */
8 //! Be Newsletter Volume II, Issue 35; September 2, 1998 (Eric Shepherd)
10 #include "SettingsMessage.h"
12 #include <new>
14 #include <Autolock.h>
15 #include <Entry.h>
16 #include <File.h>
17 #include <Messenger.h>
18 #include <String.h>
21 SettingsMessage::SettingsMessage(directory_which directory,
22 const char* filename)
24 BMessage('pref'),
25 fListeners(4)
27 fStatus = find_directory(directory, &fPath);
29 if (fStatus == B_OK)
30 fStatus = fPath.Append(filename);
32 if (fStatus == B_OK)
33 fStatus = Load();
37 SettingsMessage::~SettingsMessage()
39 Save();
41 for (int32 i = fListeners.CountItems() - 1; i >= 0; i--)
42 delete reinterpret_cast<BMessenger*>(fListeners.ItemAtFast(i));
46 status_t
47 SettingsMessage::InitCheck() const
49 return fStatus;
53 status_t
54 SettingsMessage::Load()
56 BAutolock _(this);
58 BFile file(fPath.Path(), B_READ_ONLY);
59 status_t status = file.InitCheck();
61 if (status == B_OK)
62 status = Unflatten(&file);
64 return status;
68 status_t
69 SettingsMessage::Save() const
71 BAutolock _(const_cast<SettingsMessage*>(this));
73 BFile file(fPath.Path(), B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
74 status_t status = file.InitCheck();
76 if (status == B_OK)
77 status = Flatten(&file);
79 return status;
83 bool
84 SettingsMessage::AddListener(const BMessenger& listener)
86 BAutolock _(this);
88 BMessenger* listenerCopy = new(std::nothrow) BMessenger(listener);
89 if (listenerCopy && fListeners.AddItem(listenerCopy))
90 return true;
91 delete listenerCopy;
92 return false;
96 void
97 SettingsMessage::RemoveListener(const BMessenger& listener)
99 BAutolock _(this);
101 for (int32 i = fListeners.CountItems() - 1; i >= 0; i--) {
102 BMessenger* listenerItem = reinterpret_cast<BMessenger*>(
103 fListeners.ItemAtFast(i));
104 if (*listenerItem == listener) {
105 fListeners.RemoveItem(i);
106 delete listenerItem;
107 return;
113 // #pragma mark -
116 status_t
117 SettingsMessage::SetValue(const char* name, bool value)
119 status_t ret = ReplaceBool(name, value);
120 if (ret != B_OK)
121 ret = AddBool(name, value);
122 if (ret == B_OK)
123 _NotifyValueChanged(name);
124 return ret;
128 status_t
129 SettingsMessage::SetValue(const char* name, int8 value)
131 status_t ret = ReplaceInt8(name, value);
132 if (ret != B_OK)
133 ret = AddInt8(name, value);
134 if (ret == B_OK)
135 _NotifyValueChanged(name);
136 return ret;
140 status_t
141 SettingsMessage::SetValue(const char* name, int16 value)
143 status_t ret = ReplaceInt16(name, value);
144 if (ret != B_OK)
145 ret = AddInt16(name, value);
146 if (ret == B_OK)
147 _NotifyValueChanged(name);
148 return ret;
152 status_t
153 SettingsMessage::SetValue(const char* name, int32 value)
155 status_t ret = ReplaceInt32(name, value);
156 if (ret != B_OK)
157 ret = AddInt32(name, value);
158 if (ret == B_OK)
159 _NotifyValueChanged(name);
160 return ret;
164 status_t
165 SettingsMessage::SetValue(const char* name, uint32 value)
167 status_t ret = ReplaceUInt32(name, value);
168 if (ret != B_OK)
169 ret = AddUInt32(name, value);
170 if (ret == B_OK)
171 _NotifyValueChanged(name);
172 return ret;
176 status_t
177 SettingsMessage::SetValue(const char* name, int64 value)
179 status_t ret = ReplaceInt64(name, value);
180 if (ret != B_OK)
181 ret = AddInt64(name, value);
182 if (ret == B_OK)
183 _NotifyValueChanged(name);
184 return ret;
188 status_t
189 SettingsMessage::SetValue(const char* name, float value)
191 status_t ret = ReplaceFloat(name, value);
192 if (ret != B_OK)
193 ret = AddFloat(name, value);
194 if (ret == B_OK)
195 _NotifyValueChanged(name);
196 return ret;
200 status_t
201 SettingsMessage::SetValue(const char* name, double value)
203 status_t ret = ReplaceDouble(name, value);
204 if (ret != B_OK)
205 ret = AddDouble(name, value);
206 if (ret == B_OK)
207 _NotifyValueChanged(name);
208 return ret;
212 status_t
213 SettingsMessage::SetValue(const char* name, const char* value)
215 status_t ret = ReplaceString(name, value);
216 if (ret != B_OK)
217 ret = AddString(name, value);
218 if (ret == B_OK)
219 _NotifyValueChanged(name);
220 return ret;
224 status_t
225 SettingsMessage::SetValue(const char* name, const BString& value)
227 status_t ret = ReplaceString(name, value);
228 if (ret != B_OK)
229 ret = AddString(name, value);
230 if (ret == B_OK)
231 _NotifyValueChanged(name);
232 return ret;
236 status_t
237 SettingsMessage::SetValue(const char* name, const BPoint& value)
239 status_t ret = ReplacePoint(name, value);
240 if (ret != B_OK)
241 ret = AddPoint(name, value);
242 if (ret == B_OK)
243 _NotifyValueChanged(name);
244 return ret;
248 status_t
249 SettingsMessage::SetValue(const char* name, const BRect& value)
251 status_t ret = ReplaceRect(name, value);
252 if (ret != B_OK)
253 ret = AddRect(name, value);
254 if (ret == B_OK)
255 _NotifyValueChanged(name);
256 return ret;
260 status_t
261 SettingsMessage::SetValue(const char* name, const entry_ref& value)
263 status_t ret = ReplaceRef(name, &value);
264 if (ret != B_OK)
265 ret = AddRef(name, &value);
266 if (ret == B_OK)
267 _NotifyValueChanged(name);
268 return ret;
272 status_t
273 SettingsMessage::SetValue(const char* name, const BMessage& value)
275 status_t ret = ReplaceMessage(name, &value);
276 if (ret != B_OK)
277 ret = AddMessage(name, &value);
278 if (ret == B_OK)
279 _NotifyValueChanged(name);
280 return ret;
284 status_t
285 SettingsMessage::SetValue(const char* name, const BFlattenable* value)
287 status_t ret = ReplaceFlat(name, const_cast<BFlattenable*>(value));
288 if (ret != B_OK)
289 ret = AddFlat(name, const_cast<BFlattenable*>(value));
290 if (ret == B_OK)
291 _NotifyValueChanged(name);
292 return ret;
296 status_t
297 SettingsMessage::SetValue(const char* name, const BFont& value)
299 font_family family;
300 font_style style;
301 value.GetFamilyAndStyle(&family, &style);
303 BMessage fontMessage;
304 status_t ret = fontMessage.AddString("family", family);
305 if (ret == B_OK)
306 ret = fontMessage.AddString("style", style);
307 if (ret == B_OK)
308 ret = fontMessage.AddFloat("size", value.Size());
310 if (ret == B_OK) {
311 if (ReplaceMessage(name, &fontMessage) != B_OK)
312 ret = AddMessage(name, &fontMessage);
314 if (ret == B_OK)
315 _NotifyValueChanged(name);
316 return ret;
320 // #pragma mark -
323 bool
324 SettingsMessage::GetValue(const char* name, bool defaultValue) const
326 bool value;
327 if (FindBool(name, &value) != B_OK)
328 return defaultValue;
329 return value;
333 int8
334 SettingsMessage::GetValue(const char* name, int8 defaultValue) const
336 int8 value;
337 if (FindInt8(name, &value) != B_OK)
338 return defaultValue;
339 return value;
343 int16
344 SettingsMessage::GetValue(const char* name, int16 defaultValue) const
346 int16 value;
347 if (FindInt16(name, &value) != B_OK)
348 return defaultValue;
349 return value;
353 int32
354 SettingsMessage::GetValue(const char* name, int32 defaultValue) const
356 int32 value;
357 if (FindInt32(name, &value) != B_OK)
358 return defaultValue;
359 return value;
363 uint32
364 SettingsMessage::GetValue(const char* name, uint32 defaultValue) const
366 uint32 value;
367 if (FindUInt32(name, &value) != B_OK)
368 return defaultValue;
369 return value;
373 int64
374 SettingsMessage::GetValue(const char* name, int64 defaultValue) const
376 int64 value;
377 if (FindInt64(name, &value) != B_OK)
378 return defaultValue;
379 return value;
383 float
384 SettingsMessage::GetValue(const char* name, float defaultValue) const
386 float value;
387 if (FindFloat(name, &value) != B_OK)
388 return defaultValue;
389 return value;
393 double
394 SettingsMessage::GetValue(const char* name, double defaultValue) const
396 double value;
397 if (FindDouble(name, &value) != B_OK)
398 return defaultValue;
399 return value;
403 BString
404 SettingsMessage::GetValue(const char* name, const BString& defaultValue) const
406 BString value;
407 if (FindString(name, &value) != B_OK)
408 return defaultValue;
409 return value;
413 const char*
414 SettingsMessage::GetValue(const char* name, const char* defaultValue) const
416 const char* value;
417 if (FindString(name, &value) != B_OK)
418 return defaultValue;
419 return value;
423 BPoint
424 SettingsMessage::GetValue(const char *name, BPoint defaultValue) const
426 BPoint value;
427 if (FindPoint(name, &value) != B_OK)
428 return defaultValue;
429 return value;
433 BRect
434 SettingsMessage::GetValue(const char* name, BRect defaultValue) const
436 BRect value;
437 if (FindRect(name, &value) != B_OK)
438 return defaultValue;
439 return value;
443 entry_ref
444 SettingsMessage::GetValue(const char* name, const entry_ref& defaultValue) const
446 entry_ref value;
447 if (FindRef(name, &value) != B_OK)
448 return defaultValue;
449 return value;
453 BMessage
454 SettingsMessage::GetValue(const char* name, const BMessage& defaultValue) const
456 BMessage value;
457 if (FindMessage(name, &value) != B_OK)
458 return defaultValue;
459 return value;
463 BFont
464 SettingsMessage::GetValue(const char* name, const BFont& defaultValue) const
466 BMessage fontMessage;
467 if (FindMessage(name, &fontMessage) != B_OK)
468 return defaultValue;
470 const char* family;
471 const char* style;
472 float size;
473 if (fontMessage.FindString("family", &family) != B_OK
474 || fontMessage.FindString("style", &style) != B_OK
475 || fontMessage.FindFloat("size", &size) != B_OK) {
476 return defaultValue;
479 BFont value;
480 if (value.SetFamilyAndStyle(family, style) != B_OK)
481 return defaultValue;
483 value.SetSize(size);
485 return value;
489 // #pragma mark - private
492 void
493 SettingsMessage::_NotifyValueChanged(const char* name) const
495 BMessage message(SETTINGS_VALUE_CHANGED);
496 message.AddString("name", name);
498 // Add the value of that name to the notification.
499 type_code type;
500 if (GetInfo(name, &type) == B_OK) {
501 const void* data;
502 ssize_t numBytes;
503 if (FindData(name, type, &data, &numBytes) == B_OK)
504 message.AddData("value", type, data, numBytes);
507 int32 count = fListeners.CountItems();
508 for (int32 i = 0; i < count; i++) {
509 BMessenger* listener = reinterpret_cast<BMessenger*>(
510 fListeners.ItemAtFast(i));
511 listener->SendMessage(&message);