xref: /haiku/src/kits/tracker/Utilities.h (revision 1b80286772b529a3d6de3bbeb0720c62e6a32fed)
1 /*
2 Open Tracker License
3 
4 Terms and Conditions
5 
6 Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
7 
8 Permission is hereby granted, free of charge, to any person obtaining a copy of
9 this software and associated documentation files (the "Software"), to deal in
10 the Software without restriction, including without limitation the rights to
11 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12 of the Software, and to permit persons to whom the Software is furnished to do
13 so, subject to the following conditions:
14 
15 The above copyright notice and this permission notice applies to all licensees
16 and shall be included in all copies or substantial portions of the Software.
17 
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION
23 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 
25 Except as contained in this notice, the name of Be Incorporated shall not be
26 used in advertising or otherwise to promote the sale, use or other dealings in
27 this Software without prior written authorization from Be Incorporated.
28 
29 Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks
30 of Be Incorporated in the United States and other countries. Other brand product
31 names are registered trademarks or trademarks of their respective holders.
32 All rights reserved.
33 */
34 
35 #ifndef	_UTILITIES_H
36 #define _UTILITIES_H
37 
38 #include <stdarg.h>
39 #include <stdlib.h>
40 
41 #include <ByteOrder.h>
42 #include <Bitmap.h>
43 #include <DataIO.h>
44 #include <Directory.h>
45 #include <Entry.h>
46 #include <Font.h>
47 #include <GraphicsDefs.h>
48 #include <Looper.h>
49 #include <MenuItem.h>
50 #include <MessageFilter.h>
51 #include <Mime.h>
52 #include <ObjectList.h>
53 #include <Point.h>
54 #include <Path.h>
55 #include <String.h>
56 #include <StringView.h>
57 
58 
59 class BMessage;
60 class BVolume;
61 class BBitmap;
62 class BTextView;
63 class BView;
64 
65 namespace BPrivate {
66 
67 class Benaphore;
68 class BPose;
69 class BPoseView;
70 
71 // global variables
72 extern const rgb_color kBlack;
73 extern const rgb_color kWhite;
74 
75 const int64 kHalfKBSize = 512;
76 const int64 kKBSize = 1024;
77 const int64 kMBSize = 1048576;
78 const int64 kGBSize = 1073741824;
79 const int64 kTBSize = kGBSize * kKBSize;
80 
81 const int32 kMiniIconSeparator = 3;
82 
83 #ifdef __HAIKU__
84 const color_space kDefaultIconDepth = B_RGBA32;
85 #else
86 const color_space kDefaultIconDepth = B_CMAP8;
87 #endif
88 
89 // misc typedefs, constants and structs
90 
91 // Periodically updated poses (ones with a volume space bar) register
92 // themselfs in this global list. This way they can be iterated over instead
93 // of sending around update messages.
94 
95 class PeriodicUpdatePoses {
96 	public:
97 		PeriodicUpdatePoses();
98 		~PeriodicUpdatePoses();
99 
100 		typedef bool (*PeriodicUpdateCallback)(BPose *pose, void *cookie);
101 
102 		void AddPose(BPose *pose, BPoseView *poseView,
103 			PeriodicUpdateCallback callback, void *cookie);
104 		bool RemovePose(BPose *pose, void **cookie);
105 
106 		void DoPeriodicUpdate(bool forceRedraw);
107 
108 	private:
109 		struct periodic_pose {
110 			BPose					*pose;
111 			BPoseView				*pose_view;
112 			PeriodicUpdateCallback	callback;
113 			void					*cookie;
114 		};
115 
116 		Benaphore *fLock;
117 		BObjectList<periodic_pose> fPoseList;
118 };
119 
120 extern PeriodicUpdatePoses gPeriodicUpdatePoses;
121 
122 
123 // PoseInfo is the structure that gets saved as attributes for every node on
124 // disk, defining the node's position and visibility
125 class PoseInfo {
126 	public:
127 		static void EndianSwap(void *castToThis);
128 		void PrintToStream();
129 
130 		bool fInvisible;
131 		ino_t fInitedDirectory;
132 			// for a location to be valid, fInitedDirectory has to contain the inode
133 			// of the items parent directory
134 			// This makes it impossible to for instance zip up files and extract
135 			// them in the same location. This should probably be reworked -- Tracker
136 			// could say strip the file location attributes when dropping files into
137 			// a closed folder
138 		BPoint fLocation;
139 };
140 
141 
142 // extends PoseInfo adding workspace support; used for desktop
143 // poses only
144 class ExtendedPoseInfo {
145 	public:
146 		size_t Size() const;
147 		static size_t Size(int32);
148 		size_t SizeWithHeadroom() const;
149 		static size_t SizeWithHeadroom(size_t);
150 		bool HasLocationForFrame(BRect) const;
151 		BPoint LocationForFrame(BRect) const;
152 		bool SetLocationForFrame(BPoint, BRect);
153 
154 		static void EndianSwap(void *castToThis);
155 		void PrintToStream();
156 
157 		uint32 fWorkspaces;
158 		bool fInvisible;
159 		bool fShowFromBootOnly;
160 		bool fReservedBool1;
161 		bool fReservedBool2;
162 		int32 fReservedInt1;
163 		int32 fReservedInt2;
164 		int32 fReservedInt3;
165 		int32 fReservedInt4;
166 		int32 fReservedInt5;
167 
168 		int32 fNumFrames;
169 		struct FrameLocation {
170 			BPoint fLocation;
171 			BRect fFrame;
172 			uint32 fWorkspaces;
173 		};
174 
175 		FrameLocation fLocations[0];
176 };
177 
178 // misc functions
179 void DisallowMetaKeys(BTextView *);
180 void DisallowFilenameKeys(BTextView *);
181 
182 
183 inline bool
184 IsDigit(const char c)
185 {
186 	if ((c >= 48 && c <= 57) || c == 32)
187 		return true;
188 	else
189 		return false;
190 }
191 
192 
193 //! Compares two strings naturally, as opposed to lexicographically
194 inline int
195 NaturalCompare(const char *s1, const char *s2)
196 {
197 	struct Chunk {
198 		int32	type;
199 		char*	ascii;
200 			// Type = 0
201 		int32	num;
202 			// Type = 1
203 	};
204 
205 	Chunk a;
206 	Chunk b;
207 
208 	size_t len1 = strlen(s1);
209 	size_t len2 = strlen(s2);
210 
211 	char bufferA[len1 + 1];
212 	char bufferB[len2 + 1];
213 
214 	uint32 i = 0;
215 	uint32 j = 0;
216 
217 	while (true) {
218 		// determine type of next chunks in each string based on first char
219 		if (i == len1)
220 			a.type = -1;
221 		else if (IsDigit(s1[i]))
222 			a.type = 1;
223 		else
224 			a.type = 0;
225 
226 		if (j == len2)
227 			b.type = -1;
228 		else if (IsDigit(s2[j]))
229 			b.type = 1;
230 		else
231 			b.type = 0;
232 
233 		// check if we reached the end of either string
234 		if (a.type == b.type && a.type == -1)
235 			return 0;
236 		if (a.type == -1)
237 			return -1;
238 		if (b.type == -1)
239 			return 1;
240 
241 		if (a.type != b.type) {
242 			// different chunk types, just compare the remaining strings
243 			return strcasecmp(&s1[i], &s2[j]);
244 		}
245 
246 		// fetch the next chunk for a
247 		if (a.type == 0) {
248 			// string chunk
249 			int32 k = i;
250 			while (!IsDigit(s1[k]) && s1[k] != 0) {
251 				bufferA[k - i] = s1[k];
252 				k++;
253 			}
254 			bufferA[k - i] = 0;
255 			a.ascii = bufferA;
256 			i += k - i;
257 		} else {
258 			// number chunk
259 			int32 k = i;
260 			while (IsDigit(s1[k]) && s1[k] != 0) {
261 				bufferA[k - i] = s1[k];
262 				k++;
263 			}
264 			bufferA[k - i] = 0;
265 			a.ascii = bufferA;
266 			a.num = atoi(bufferA);
267 			i += k - i;
268 		}
269 
270 		// fetch the next chunk for b
271 		if (b.type == 0) {
272 			// string chunk
273 			int32 k = j;
274 			while (!IsDigit(s2[k]) && s2[k] != 0) {
275 				bufferB[k - j] = s2[k];
276 				k++;
277 			}
278 			bufferB[k - j] = 0;
279 			b.ascii = bufferB;
280 			j += k - j;
281 		} else {
282 			// number chunk
283 			int32 k = j;
284 			while (IsDigit(s2[k]) && s2[k] != 0) {
285 				bufferB[k - j] = s2[k];
286 				k++;
287 			}
288 			bufferB[k - j] = 0;
289 			b.ascii = bufferB;
290 			b.num = atoi(bufferB);
291 			j += k - j;
292 		}
293 
294 		// compare the two chunks based on their type
295 		if (a.type == 0) {
296 			// string chunks
297 			int stringCompareResult = strcasecmp(a.ascii, b.ascii);
298 			// if the chunk strings are the same, keep using natural
299 			// sorting for the next chunks
300 			if (stringCompareResult != 0)
301 				return stringCompareResult;
302 		} else {
303 			// number chunks
304 			if (a.num != b.num) {
305 				if (a.num < b.num)
306 					return -1;
307 				if (a.num > b.num)
308 					return 1;
309 			}
310 		}
311 	}
312 
313 	return 0;
314 }
315 
316 
317 bool ValidateStream(BMallocIO *, uint32, int32 version);
318 
319 
320 uint32 HashString(const char *string, uint32 seed);
321 uint32 AttrHashString(const char *string, uint32 type);
322 
323 
324 class OffscreenBitmap {
325 	// a utility class for setting up offscreen bitmaps
326 	public:
327 		OffscreenBitmap(BRect bounds);
328 		OffscreenBitmap();
329 		~OffscreenBitmap();
330 
331 		BView *BeginUsing(BRect bounds);
332 		void DoneUsing();
333 		BBitmap *Bitmap() const;
334 			// blit this to your view when you are done rendering
335 		BView *View() const;
336 			// use this to render your image
337 
338 	private:
339 		void NewBitmap(BRect frame);
340 		BBitmap *fBitmap;
341 };
342 
343 
344 // bitmap functions
345 extern void FadeRGBA32Horizontal(uint32 *bits, int32 width, int32 height, int32 from, int32 to);
346 extern void FadeRGBA32Vertical(uint32 *bits, int32 width, int32 height, int32 from, int32 to);
347 
348 
349 class FlickerFreeStringView : public BStringView {
350 	// Adds support for offscreen bitmap drawing for string views that update often
351 	// this would be better implemented as an option of BStringView
352 	public:
353 		FlickerFreeStringView(BRect bounds, const char *name,
354 			const char *text, uint32 resizeFlags = B_FOLLOW_LEFT | B_FOLLOW_TOP,
355 			uint32 flags = B_WILL_DRAW);
356 		FlickerFreeStringView(BRect bounds, const char *name,
357 			const char *text, BBitmap *existingOffscreen,
358 			uint32 resizeFlags = B_FOLLOW_LEFT | B_FOLLOW_TOP,
359 			uint32 flags = B_WILL_DRAW);
360 		virtual ~FlickerFreeStringView();
361 		virtual void Draw(BRect);
362 		virtual void AttachedToWindow();
363 		virtual void SetViewColor(rgb_color);
364 		virtual void SetLowColor(rgb_color);
365 
366 	private:
367 		OffscreenBitmap *fBitmap;
368 		rgb_color fViewColor;
369 		rgb_color fLowColor;
370 		BBitmap *fOrigBitmap;
371 
372 		typedef BStringView _inherited;
373 };
374 
375 
376 class DraggableIcon : public BView {
377 	// used to determine a save location for a file
378 	public:
379 		DraggableIcon(BRect, const char *, const char *mimeType, icon_size,
380 			const BMessage *, BMessenger,
381 			uint32 resizeFlags = B_FOLLOW_LEFT | B_FOLLOW_TOP,
382 			uint32 flags = B_WILL_DRAW);
383 		virtual ~DraggableIcon();
384 
385 		static BRect PreferredRect(BPoint offset, icon_size);
386 		void SetTarget(BMessenger);
387 
388 	protected:
389 		virtual void AttachedToWindow();
390 		virtual void MouseDown(BPoint);
391 		virtual void Draw(BRect);
392 
393 		virtual bool DragStarted(BMessage *dragMessage);
394 
395 	protected:
396 		BBitmap *fBitmap;
397 		BMessage fMessage;
398 		BMessenger fTarget;
399 };
400 
401 
402 class PositionPassingMenuItem : public BMenuItem {
403 	public:
404 		PositionPassingMenuItem(const char *title, BMessage *, char shortcut = 0,
405 			uint32 modifiers = 0);
406 
407 		PositionPassingMenuItem(BMenu *, BMessage *);
408 
409 	protected:
410 		virtual status_t Invoke(BMessage * = 0);
411 			// appends the invoke location for NewFolder, etc. to use
412 
413 	private:
414 		typedef BMenuItem _inherited;
415 };
416 
417 
418 class Benaphore {
419 	// aka benaphore
420 	public:
421 		Benaphore(const char *name = "Light Lock")
422 		:	fSemaphore(create_sem(0, name)),
423 			fCount(1)
424 		{
425 		}
426 
427 		~Benaphore()
428 		{
429 			delete_sem(fSemaphore);
430 		}
431 
432 		bool Lock()
433 		{
434 			if (atomic_add(&fCount, -1) <= 0)
435 				return acquire_sem(fSemaphore) == B_OK;
436 
437 			return true;
438 		}
439 
440 		void Unlock()
441 		{
442 			if (atomic_add(&fCount, 1) < 0)
443 				release_sem(fSemaphore);
444 		}
445 
446 		bool IsLocked() const
447 		{
448 			return fCount <= 0;
449 		}
450 
451 	private:
452 		sem_id fSemaphore;
453 		int32 fCount;
454 };
455 
456 
457 class SeparatorLine : public BView {
458 	public:
459 		SeparatorLine(BPoint , float , bool vertical, const char *name = "");
460 		virtual	void Draw(BRect bounds);
461 };
462 
463 
464 class TitledSeparatorItem : public BMenuItem {
465 	public:
466 		TitledSeparatorItem(const char *);
467 		virtual ~TitledSeparatorItem();
468 
469 		virtual void SetEnabled(bool state);
470 
471 	protected:
472 		virtual	void GetContentSize(float *width, float *height);
473 		virtual	void Draw();
474 
475 	private:
476 		typedef BMenuItem _inherited;
477 };
478 
479 
480 class LooperAutoLocker {
481 	public:
482 		LooperAutoLocker(BHandler *handler)
483 		:	fHandler(handler),
484 			fHasLock(handler->LockLooper())
485 		{
486 		}
487 
488 		~LooperAutoLocker()
489 		{
490 			if (fHasLock)
491 				fHandler->UnlockLooper();
492 		}
493 
494 		bool operator!() const
495 		{
496 			return !fHasLock;
497 		}
498 
499 		bool IsLocked() const
500 		{
501 			return fHasLock;
502 		}
503 
504 	private:
505 		BHandler *fHandler;
506 		bool fHasLock;
507 };
508 
509 
510 class MessengerAutoLocker {
511 	// move this into AutoLock.h
512 	public:
513 		MessengerAutoLocker(BMessenger *messenger)
514 			:	fMessenger(messenger),
515 				fHasLock(messenger->LockTarget())
516 		{ }
517 
518 		~MessengerAutoLocker()
519 		{
520 			Unlock();
521 		}
522 
523 		bool operator!() const
524 		{
525 			return !fHasLock;
526 		}
527 
528 		bool IsLocked() const
529 		{
530 			return fHasLock;
531 		}
532 
533 		void Unlock()
534 		{
535 			if (fHasLock) {
536 				BLooper *looper;
537 				fMessenger->Target(&looper);
538 				if (looper)
539 					looper->Unlock();
540 				fHasLock = false;
541 			}
542 		}
543 
544 	private:
545 		BMessenger *fMessenger;
546 		bool fHasLock;
547 };
548 
549 
550 class ShortcutFilter : public BMessageFilter {
551 	public:
552 		ShortcutFilter(uint32 shortcutKey, uint32 shortcutModifier,
553 			uint32 shortcutWhat, BHandler *target);
554 
555 	protected:
556 		filter_result Filter(BMessage *, BHandler **);
557 
558 	private:
559 		uint32 fShortcutKey;
560 		uint32 fShortcutModifier;
561 		uint32 fShortcutWhat;
562 		BHandler *fTarget;
563 };
564 
565 // iterates over all the refs in a message
566 entry_ref *EachEntryRef(BMessage *, entry_ref *(*)(entry_ref *, void *),
567 	void *passThru = 0);
568 const entry_ref *EachEntryRef(const BMessage *,
569 	const entry_ref *(*)(const entry_ref *, void *), void *passThru = 0);
570 
571 entry_ref *EachEntryRef(BMessage *, entry_ref *(*)(entry_ref *, void *),
572 	void *passThru, int32 maxCount);
573 const entry_ref *EachEntryRef(const BMessage *,
574 	const entry_ref *(*)(const entry_ref *, void *), void *passThru, int32 maxCount);
575 
576 
577 bool ContainsEntryRef(const BMessage *, const entry_ref *);
578 int32 CountRefs(const BMessage *);
579 
580 BMenuItem *EachMenuItem(BMenu *menu, bool recursive, BMenuItem *(*func)(BMenuItem *));
581 const BMenuItem *EachMenuItem(const BMenu *menu, bool recursive,
582 	BMenuItem *(*func)(const BMenuItem *));
583 
584 int64 StringToScalar(const char *text);
585 	// string to num, understands kB, MB, etc.
586 
587 // misc calls
588 void EmbedUniqueVolumeInfo(BMessage *, const BVolume *);
589 status_t MatchArchivedVolume(BVolume *, const BMessage *, int32 index = 0);
590 void TruncateLeaf(BString *string);
591 
592 void StringFromStream(BString *, BMallocIO *, bool endianSwap = false);
593 void StringToStream(const BString *, BMallocIO *);
594 int32 ArchiveSize(const BString *);
595 
596 extern void EnableNamedMenuItem(BMenu *menu, const char *itemName, bool on);
597 extern void MarkNamedMenuItem(BMenu *menu, const char *itemName, bool on);
598 extern void EnableNamedMenuItem(BMenu *menu, uint32 commandName, bool on);
599 extern void MarkNamedMenuItem(BMenu *menu, uint32 commandName, bool on);
600 extern void DeleteSubmenu(BMenuItem *submenuItem);
601 
602 extern bool BootedInSafeMode();
603 
604 // Now is in kits
605 #if B_BEOS_VERSION <= B_BEOS_VERSION_MAUI && !defined(__HAIKU__)
606 
607 // Should be in kits
608 bool operator==(const rgb_color &, const rgb_color &);
609 bool operator!=(const rgb_color &, const rgb_color &);
610 
611 #endif
612 
613 inline rgb_color
614 Color(int32 r, int32 g, int32 b, int32 alpha = 255)
615 {
616 	rgb_color result;
617 	result.red = (uchar)r;
618 	result.green = (uchar)g;
619 	result.blue = (uchar)b;
620 	result.alpha = (uchar)alpha;
621 
622 	return result;
623 }
624 
625 void PrintToStream(rgb_color color);
626 
627 template <class InitCheckable>
628 void
629 ThrowOnInitCheckError(InitCheckable *item)
630 {
631 	if (!item)
632 		throw B_ERROR;
633 	status_t error = item->InitCheck();
634 	if (error != B_OK)
635 		throw error;
636 }
637 
638 #if DEBUG
639 #define ThrowOnError(error) _ThrowOnError(error, __FILE__, __LINE__)
640 #define ThrowIfNotSize(error) _ThrowIfNotSize(error, __FILE__, __LINE__)
641 #define ThrowOnErrorWithMessage(error, debugStr) _ThrowOnError(error, debugStr, __FILE__, __LINE__)
642 #else
643 #define ThrowOnError(x) _ThrowOnError(x, 0, 0)
644 #define ThrowIfNotSize(x) _ThrowIfNotSize(x, 0, 0)
645 #define ThrowOnErrorWithMessage(error, debugStr) _ThrowOnError(error, debugStr, __FILE__, __LINE__)
646 #endif
647 
648 void _ThrowOnError(status_t, const char *, int32);
649 void _ThrowIfNotSize(ssize_t, const char *, int32);
650 void _ThrowOnError(status_t, const char *debugStr, const char *, int32);
651 
652 // stub calls that work around BAppFile info inefficiency
653 status_t GetAppSignatureFromAttr(BFile *, char *);
654 status_t GetAppIconFromAttr(BFile *, BBitmap *, icon_size);
655 status_t GetFileIconFromAttr(BNode *, BBitmap *, icon_size);
656 
657 
658 // debugging
659 void HexDump(const void *buffer, int32 length);
660 
661 #if xDEBUG
662 
663 inline void
664 PrintRefToStream(const entry_ref *ref, const char *trailer = "\n")
665 {
666 	if (!ref) {
667 		PRINT(("NULL entry_ref%s", trailer));
668 		return;
669 	}
670 	BPath path;
671 	BEntry entry(ref);
672 	entry.GetPath(&path);
673 	PRINT(("%s%s", path.Path(), trailer));
674 }
675 
676 inline void
677 PrintEntryToStream(const BEntry *entry, const char *trailer = "\n")
678 {
679 	if (!entry) {
680 		PRINT(("NULL entry%s", trailer));
681 		return;
682 	}
683 	BPath path;
684 	entry->GetPath(&path);
685 	PRINT(("%s%s", path.Path(), trailer));
686 }
687 
688 inline void
689 PrintDirToStream(const BDirectory *dir, const char *trailer = "\n")
690 {
691 	if (!dir) {
692 		PRINT(("NULL entry_ref%s", trailer));
693 		return;
694 	}
695 	BPath path;
696 	BEntry entry;
697 	dir->GetEntry(&entry);
698 	entry.GetPath(&path);
699 	PRINT(("%s%s", path.Path(), trailer));
700 }
701 
702 #else
703 
704 inline void PrintRefToStream(const entry_ref *, const char * = 0) {}
705 inline void PrintEntryToStream(const BEntry *, const char * = 0) {}
706 inline void PrintDirToStream(const BDirectory *, const char * = 0) {}
707 
708 #endif
709 
710 #ifdef xDEBUG
711 
712 	extern FILE *logFile;
713 
714 	inline void PrintToLogFile(const char *fmt, ...)
715 	{
716     	va_list ap;
717         va_start(ap, fmt);
718 		vfprintf(logFile, fmt, ap);
719 		va_end(ap);
720 	}
721 
722 	#define WRITELOG(_ARGS_)													\
723 		if (logFile == 0) 														\
724 			logFile = fopen("/var/log/tracker.log", "a+"); 						\
725 		if (logFile != 0) {														\
726 			thread_info info;													\
727 			get_thread_info(find_thread(NULL), &info);							\
728 			PrintToLogFile("[t %Ld] \"%s\" (%s:%i) ", system_time(),			\
729 				info.name, __FILE__, __LINE__);									\
730 			PrintToLogFile _ARGS_;												\
731 			PrintToLogFile("\n");												\
732 			fflush(logFile);													\
733 		}
734 
735 #else
736 
737 	#define WRITELOG(_ARGS_)
738 
739 #endif
740 
741 // fancy casting macros
742 
743 template <typename NewType, typename OldType>
744 inline NewType assert_cast(OldType castedPointer) {
745 	ASSERT(dynamic_cast<NewType>(castedPointer) != NULL);
746 	return static_cast<NewType>(castedPointer);
747 }
748 
749 // B_SWAP_INT32 have broken signedness, simple cover calls to fix that
750 // should fix up in ByteOrder.h
751 
752 inline int32 SwapInt32(int32 value) { return (int32)B_SWAP_INT32((uint32)value); }
753 inline uint32 SwapUInt32(uint32 value) { return B_SWAP_INT32(value); }
754 inline int64 SwapInt64(int64 value) { return (int64)B_SWAP_INT64((uint64)value); }
755 inline uint64 SwapUInt64(uint64 value) { return B_SWAP_INT64(value); }
756 
757 
758 extern const float kExactMatchScore;
759 float ComputeTypeAheadScore(const char *text, const char *match,
760 	size_t matchLength, bool wordMode = false);
761 
762 } // namespace BPrivate
763 
764 #endif	// _UTILITIES_H
765