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