xref: /haiku/src/kits/tracker/Utilities.h (revision b55a57da7173b9af0432bd3e148d03f06161d036)
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 		union {
200 			char*	ascii;
201 				// Type = 0
202 			int32	num;
203 				// Type = 1
204 		};
205 	};
206 
207 	Chunk a;
208 	Chunk b;
209 
210 	size_t len1 = strlen(s1);
211 	size_t len2 = strlen(s2);
212 
213 	char bufferA[len1 + 1];
214 	char bufferB[len2 + 1];
215 
216 	uint32 i = 0;
217 	uint32 j = 0;
218 
219 	while (true) {
220 		// determine type of next chunks in each string based on first char
221 		if (i == len1)
222 			a.type = -1;
223 		else if (IsDigit(s1[i]))
224 			a.type = 1;
225 		else
226 			a.type = 0;
227 
228 		if (j == len2)
229 			b.type = -1;
230 		else if (IsDigit(s2[j]))
231 			b.type = 1;
232 		else
233 			b.type = 0;
234 
235 		// check if we reached the end of either string
236 		if (a.type == b.type && a.type == -1)
237 			return 0;
238 		if (a.type == -1)
239 			return -1;
240 		if (b.type == -1)
241 			return 1;
242 
243 		if (a.type != b.type) {
244 			// different chunk types, just compare the remaining strings
245 			return strcasecmp(&s1[i], &s2[j]);
246 		}
247 
248 		// fetch the next chunk for a
249 		if (a.type == 0) {
250 			// string chunk
251 			int32 k = i;
252 			while (!IsDigit(s1[k]) && s1[k] != 0) {
253 				bufferA[k - i] = s1[k];
254 				k++;
255 			}
256 			bufferA[k - i] = 0;
257 			a.ascii = bufferA;
258 			i += k - i;
259 		} else {
260 			// number chunk
261 			int32 k = i;
262 			while (IsDigit(s1[k]) && s1[k] != 0) {
263 				bufferA[k - i] = s1[k];
264 				k++;
265 			}
266 			bufferA[k - i] = 0;
267 			a.ascii = bufferA;
268 			a.num = atoi(bufferA);
269 			i += k - i;
270 		}
271 
272 		// fetch the next chunk for b
273 		if (b.type == 0) {
274 			// string chunk
275 			int32 k = j;
276 			while (!IsDigit(s2[k]) && s2[k] != 0) {
277 				bufferB[k - j] = s2[k];
278 				k++;
279 			}
280 			bufferB[k - j] = 0;
281 			b.ascii = bufferB;
282 			j += k - j;
283 		} else {
284 			// number chunk
285 			int32 k = j;
286 			while (IsDigit(s2[k]) && s2[k] != 0) {
287 				bufferB[k - j] = s2[k];
288 				k++;
289 			}
290 			bufferB[k - j] = 0;
291 			b.ascii = bufferB;
292 			b.num = atoi(bufferB);
293 			j += k - j;
294 		}
295 
296 		// compare the two chunks based on their type
297 		if (a.type == 0) {
298 			// string chunks
299 			int stringCompareResult = strcasecmp(a.ascii, b.ascii);
300 			// if the chunk strings are the same, keep using natural
301 			// sorting for the next chunks
302 			if (stringCompareResult != 0)
303 				return stringCompareResult;
304 		} else {
305 			// number chunks
306 			if (a.num != b.num) {
307 				if (a.num < b.num)
308 					return -1;
309 				if (a.num > b.num)
310 					return 1;
311 			}
312 		}
313 	}
314 
315 	return 0;
316 }
317 
318 
319 bool ValidateStream(BMallocIO *, uint32, int32 version);
320 
321 
322 uint32 HashString(const char *string, uint32 seed);
323 uint32 AttrHashString(const char *string, uint32 type);
324 
325 
326 class OffscreenBitmap {
327 	// a utility class for setting up offscreen bitmaps
328 	public:
329 		OffscreenBitmap(BRect bounds);
330 		OffscreenBitmap();
331 		~OffscreenBitmap();
332 
333 		BView *BeginUsing(BRect bounds);
334 		void DoneUsing();
335 		BBitmap *Bitmap() const;
336 			// blit this to your view when you are done rendering
337 		BView *View() const;
338 			// use this to render your image
339 
340 	private:
341 		void NewBitmap(BRect frame);
342 		BBitmap *fBitmap;
343 };
344 
345 
346 // bitmap functions
347 extern void FadeRGBA32Horizontal(uint32 *bits, int32 width, int32 height, int32 from, int32 to);
348 extern void FadeRGBA32Vertical(uint32 *bits, int32 width, int32 height, int32 from, int32 to);
349 
350 
351 class FlickerFreeStringView : public BStringView {
352 	// Adds support for offscreen bitmap drawing for string views that update often
353 	// this would be better implemented as an option of BStringView
354 	public:
355 		FlickerFreeStringView(BRect bounds, const char *name,
356 			const char *text, uint32 resizeFlags = B_FOLLOW_LEFT | B_FOLLOW_TOP,
357 			uint32 flags = B_WILL_DRAW);
358 		FlickerFreeStringView(BRect bounds, const char *name,
359 			const char *text, BBitmap *existingOffscreen,
360 			uint32 resizeFlags = B_FOLLOW_LEFT | B_FOLLOW_TOP,
361 			uint32 flags = B_WILL_DRAW);
362 		virtual ~FlickerFreeStringView();
363 		virtual void Draw(BRect);
364 		virtual void AttachedToWindow();
365 		virtual void SetViewColor(rgb_color);
366 		virtual void SetLowColor(rgb_color);
367 
368 	private:
369 		OffscreenBitmap *fBitmap;
370 		rgb_color fViewColor;
371 		rgb_color fLowColor;
372 		BBitmap *fOrigBitmap;
373 
374 		typedef BStringView _inherited;
375 };
376 
377 
378 class DraggableIcon : public BView {
379 	// used to determine a save location for a file
380 	public:
381 		DraggableIcon(BRect, const char *, const char *mimeType, icon_size,
382 			const BMessage *, BMessenger,
383 			uint32 resizeFlags = B_FOLLOW_LEFT | B_FOLLOW_TOP,
384 			uint32 flags = B_WILL_DRAW);
385 		virtual ~DraggableIcon();
386 
387 		static BRect PreferredRect(BPoint offset, icon_size);
388 		void SetTarget(BMessenger);
389 
390 	protected:
391 		virtual void AttachedToWindow();
392 		virtual void MouseDown(BPoint);
393 		virtual void Draw(BRect);
394 
395 		virtual bool DragStarted(BMessage *dragMessage);
396 
397 	protected:
398 		BBitmap *fBitmap;
399 		BMessage fMessage;
400 		BMessenger fTarget;
401 };
402 
403 
404 class PositionPassingMenuItem : public BMenuItem {
405 	public:
406 		PositionPassingMenuItem(const char *title, BMessage *, char shortcut = 0,
407 			uint32 modifiers = 0);
408 
409 		PositionPassingMenuItem(BMenu *, BMessage *);
410 
411 	protected:
412 		virtual status_t Invoke(BMessage * = 0);
413 			// appends the invoke location for NewFolder, etc. to use
414 
415 	private:
416 		typedef BMenuItem _inherited;
417 };
418 
419 
420 class Benaphore {
421 	// aka benaphore
422 	public:
423 		Benaphore(const char *name = "Light Lock")
424 		:	fSemaphore(create_sem(0, name)),
425 			fCount(1)
426 		{
427 		}
428 
429 		~Benaphore()
430 		{
431 			delete_sem(fSemaphore);
432 		}
433 
434 		bool Lock()
435 		{
436 			if (atomic_add(&fCount, -1) <= 0)
437 				return acquire_sem(fSemaphore) == B_OK;
438 
439 			return true;
440 		}
441 
442 		void Unlock()
443 		{
444 			if (atomic_add(&fCount, 1) < 0)
445 				release_sem(fSemaphore);
446 		}
447 
448 		bool IsLocked() const
449 		{
450 			return fCount <= 0;
451 		}
452 
453 	private:
454 		sem_id fSemaphore;
455 		int32 fCount;
456 };
457 
458 
459 class SeparatorLine : public BView {
460 	public:
461 		SeparatorLine(BPoint , float , bool vertical, const char *name = "");
462 		virtual	void Draw(BRect bounds);
463 };
464 
465 
466 class TitledSeparatorItem : public BMenuItem {
467 	public:
468 		TitledSeparatorItem(const char *);
469 		virtual ~TitledSeparatorItem();
470 
471 		virtual void SetEnabled(bool state);
472 
473 	protected:
474 		virtual	void GetContentSize(float *width, float *height);
475 		virtual	void Draw();
476 
477 	private:
478 		typedef BMenuItem _inherited;
479 };
480 
481 
482 class LooperAutoLocker {
483 	public:
484 		LooperAutoLocker(BHandler *handler)
485 		:	fHandler(handler),
486 			fHasLock(handler->LockLooper())
487 		{
488 		}
489 
490 		~LooperAutoLocker()
491 		{
492 			if (fHasLock)
493 				fHandler->UnlockLooper();
494 		}
495 
496 		bool operator!() const
497 		{
498 			return !fHasLock;
499 		}
500 
501 		bool IsLocked() const
502 		{
503 			return fHasLock;
504 		}
505 
506 	private:
507 		BHandler *fHandler;
508 		bool fHasLock;
509 };
510 
511 
512 class MessengerAutoLocker {
513 	// move this into AutoLock.h
514 	public:
515 		MessengerAutoLocker(BMessenger *messenger)
516 			:	fMessenger(messenger),
517 				fHasLock(messenger->LockTarget())
518 		{ }
519 
520 		~MessengerAutoLocker()
521 		{
522 			Unlock();
523 		}
524 
525 		bool operator!() const
526 		{
527 			return !fHasLock;
528 		}
529 
530 		bool IsLocked() const
531 		{
532 			return fHasLock;
533 		}
534 
535 		void Unlock()
536 		{
537 			if (fHasLock) {
538 				BLooper *looper;
539 				fMessenger->Target(&looper);
540 				if (looper)
541 					looper->Unlock();
542 				fHasLock = false;
543 			}
544 		}
545 
546 	private:
547 		BMessenger *fMessenger;
548 		bool fHasLock;
549 };
550 
551 
552 class ShortcutFilter : public BMessageFilter {
553 	public:
554 		ShortcutFilter(uint32 shortcutKey, uint32 shortcutModifier,
555 			uint32 shortcutWhat, BHandler *target);
556 
557 	protected:
558 		filter_result Filter(BMessage *, BHandler **);
559 
560 	private:
561 		uint32 fShortcutKey;
562 		uint32 fShortcutModifier;
563 		uint32 fShortcutWhat;
564 		BHandler *fTarget;
565 };
566 
567 // iterates over all the refs in a message
568 entry_ref *EachEntryRef(BMessage *, entry_ref *(*)(entry_ref *, void *),
569 	void *passThru = 0);
570 const entry_ref *EachEntryRef(const BMessage *,
571 	const entry_ref *(*)(const entry_ref *, void *), void *passThru = 0);
572 
573 entry_ref *EachEntryRef(BMessage *, entry_ref *(*)(entry_ref *, void *),
574 	void *passThru, int32 maxCount);
575 const entry_ref *EachEntryRef(const BMessage *,
576 	const entry_ref *(*)(const entry_ref *, void *), void *passThru, int32 maxCount);
577 
578 
579 bool ContainsEntryRef(const BMessage *, const entry_ref *);
580 int32 CountRefs(const BMessage *);
581 
582 BMenuItem *EachMenuItem(BMenu *menu, bool recursive, BMenuItem *(*func)(BMenuItem *));
583 const BMenuItem *EachMenuItem(const BMenu *menu, bool recursive,
584 	BMenuItem *(*func)(const BMenuItem *));
585 
586 int64 StringToScalar(const char *text);
587 	// string to num, understands kB, MB, etc.
588 
589 // misc calls
590 void EmbedUniqueVolumeInfo(BMessage *, const BVolume *);
591 status_t MatchArchivedVolume(BVolume *, const BMessage *, int32 index = 0);
592 void TruncateLeaf(BString *string);
593 
594 void StringFromStream(BString *, BMallocIO *, bool endianSwap = false);
595 void StringToStream(const BString *, BMallocIO *);
596 int32 ArchiveSize(const BString *);
597 
598 extern void EnableNamedMenuItem(BMenu *menu, const char *itemName, bool on);
599 extern void MarkNamedMenuItem(BMenu *menu, const char *itemName, bool on);
600 extern void EnableNamedMenuItem(BMenu *menu, uint32 commandName, bool on);
601 extern void MarkNamedMenuItem(BMenu *menu, uint32 commandName, bool on);
602 extern void DeleteSubmenu(BMenuItem *submenuItem);
603 
604 extern bool BootedInSafeMode();
605 
606 // Now is in kits
607 #if B_BEOS_VERSION <= B_BEOS_VERSION_MAUI && !defined(__HAIKU__)
608 
609 // Should be in kits
610 bool operator==(const rgb_color &, const rgb_color &);
611 bool operator!=(const rgb_color &, const rgb_color &);
612 
613 #endif
614 
615 inline rgb_color
616 Color(int32 r, int32 g, int32 b, int32 alpha = 255)
617 {
618 	rgb_color result;
619 	result.red = (uchar)r;
620 	result.green = (uchar)g;
621 	result.blue = (uchar)b;
622 	result.alpha = (uchar)alpha;
623 
624 	return result;
625 }
626 
627 void PrintToStream(rgb_color color);
628 
629 template <class InitCheckable>
630 void
631 ThrowOnInitCheckError(InitCheckable *item)
632 {
633 	if (!item)
634 		throw B_ERROR;
635 	status_t error = item->InitCheck();
636 	if (error != B_OK)
637 		throw error;
638 }
639 
640 #if DEBUG
641 #define ThrowOnError(error) _ThrowOnError(error, __FILE__, __LINE__)
642 #define ThrowIfNotSize(error) _ThrowIfNotSize(error, __FILE__, __LINE__)
643 #define ThrowOnErrorWithMessage(error, debugStr) _ThrowOnError(error, debugStr, __FILE__, __LINE__)
644 #else
645 #define ThrowOnError(x) _ThrowOnError(x, 0, 0)
646 #define ThrowIfNotSize(x) _ThrowIfNotSize(x, 0, 0)
647 #define ThrowOnErrorWithMessage(error, debugStr) _ThrowOnError(error, debugStr, __FILE__, __LINE__)
648 #endif
649 
650 void _ThrowOnError(status_t, const char *, int32);
651 void _ThrowIfNotSize(ssize_t, const char *, int32);
652 void _ThrowOnError(status_t, const char *debugStr, const char *, int32);
653 
654 // stub calls that work around BAppFile info inefficiency
655 status_t GetAppSignatureFromAttr(BFile *, char *);
656 status_t GetAppIconFromAttr(BFile *, BBitmap *, icon_size);
657 status_t GetFileIconFromAttr(BNode *, BBitmap *, icon_size);
658 
659 
660 // debugging
661 void HexDump(const void *buffer, int32 length);
662 
663 #if xDEBUG
664 
665 inline void
666 PrintRefToStream(const entry_ref *ref, const char *trailer = "\n")
667 {
668 	if (!ref) {
669 		PRINT(("NULL entry_ref%s", trailer));
670 		return;
671 	}
672 	BPath path;
673 	BEntry entry(ref);
674 	entry.GetPath(&path);
675 	PRINT(("%s%s", path.Path(), trailer));
676 }
677 
678 inline void
679 PrintEntryToStream(const BEntry *entry, const char *trailer = "\n")
680 {
681 	if (!entry) {
682 		PRINT(("NULL entry%s", trailer));
683 		return;
684 	}
685 	BPath path;
686 	entry->GetPath(&path);
687 	PRINT(("%s%s", path.Path(), trailer));
688 }
689 
690 inline void
691 PrintDirToStream(const BDirectory *dir, const char *trailer = "\n")
692 {
693 	if (!dir) {
694 		PRINT(("NULL entry_ref%s", trailer));
695 		return;
696 	}
697 	BPath path;
698 	BEntry entry;
699 	dir->GetEntry(&entry);
700 	entry.GetPath(&path);
701 	PRINT(("%s%s", path.Path(), trailer));
702 }
703 
704 #else
705 
706 inline void PrintRefToStream(const entry_ref *, const char * = 0) {}
707 inline void PrintEntryToStream(const BEntry *, const char * = 0) {}
708 inline void PrintDirToStream(const BDirectory *, const char * = 0) {}
709 
710 #endif
711 
712 #ifdef xDEBUG
713 
714 	extern FILE *logFile;
715 
716 	inline void PrintToLogFile(const char *fmt, ...)
717 	{
718     	va_list ap;
719         va_start(ap, fmt);
720 		vfprintf(logFile, fmt, ap);
721 		va_end(ap);
722 	}
723 
724 	#define WRITELOG(_ARGS_)													\
725 		if (logFile == 0) 														\
726 			logFile = fopen("/var/log/tracker.log", "a+"); 						\
727 		if (logFile != 0) {														\
728 			thread_info info;													\
729 			get_thread_info(find_thread(NULL), &info);							\
730 			PrintToLogFile("[t %Ld] \"%s\" (%s:%i) ", system_time(),			\
731 				info.name, __FILE__, __LINE__);									\
732 			PrintToLogFile _ARGS_;												\
733 			PrintToLogFile("\n");												\
734 			fflush(logFile);													\
735 		}
736 
737 #else
738 
739 	#define WRITELOG(_ARGS_)
740 
741 #endif
742 
743 // fancy casting macros
744 
745 template <typename NewType, typename OldType>
746 inline NewType assert_cast(OldType castedPointer) {
747 	ASSERT(dynamic_cast<NewType>(castedPointer) != NULL);
748 	return static_cast<NewType>(castedPointer);
749 }
750 
751 // B_SWAP_INT32 have broken signedness, simple cover calls to fix that
752 // should fix up in ByteOrder.h
753 
754 inline int32 SwapInt32(int32 value) { return (int32)B_SWAP_INT32((uint32)value); }
755 inline uint32 SwapUInt32(uint32 value) { return B_SWAP_INT32(value); }
756 inline int64 SwapInt64(int64 value) { return (int64)B_SWAP_INT64((uint64)value); }
757 inline uint64 SwapUInt64(uint64 value) { return B_SWAP_INT64(value); }
758 
759 
760 extern const float kExactMatchScore;
761 float ComputeTypeAheadScore(const char *text, const char *match,
762 	size_t matchLength, bool wordMode = false);
763 
764 } // namespace BPrivate
765 
766 #endif	// _UTILITIES_H
767