|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24:
25: /*
26: File: HFSUtilities.c
27:
28: Contains: xxx put contents here xxx
29:
30: Version: HFS Plus 1.0
31:
32: Copyright: � 1997 by Apple Computer, Inc., all rights reserved.
33:
34: File Ownership:
35:
36: DRI: Don Brady
37:
38: Other Contacts: Mark Day, Deric Horn
39:
40: Technology: xxx put technology here xxx
41:
42: Writers:
43:
44: (DSH) Deric Horn
45: (msd) Mark Day
46: (djb) Don Brady
47:
48: Change History (most recent first):
49:
50: <Rhap> 3/31/98 djb Sync up with final HFSVolumes.h header file.
51: <CS13> 9/9/97 msd Make PascalBinaryCompare and UnicodeBinaryCompare faster.
52: <CS12> 9/7/97 djb Conditionalize DebugStrs to DEBUG_BUILD.
53: <CS11> 9/4/97 msd Add U64SetU routine.
54: <CS10> 8/18/97 DSH Conditionalizedout Math64 routines already compiled for DFA.
55: <CS9> 7/22/97 msd LocalToUTC and UTCToLocal are now functions (not macros) so that
56: they can pin their outputs.
57: <CS8> 7/21/97 djb Add U64Add and U64Subtract (used by instrumentation).
58: <CS7> 7/18/97 msd Include LowMemPriv.h.
59: <CS6> 7/16/97 DSH FilesInternal.i renamed FileMgrInternal.i to avoid name
60: collision
61: <CS5> 7/8/97 DSH Loading PrecompiledHeaders from define passed in on C line
62: <CS4> 6/9/97 msd Add GetTimeUTC and GetTimeLocal.
63: <CS3> 5/23/97 djb Fixing ClearMemory bug - it was clearing an extra byte!
64: <CS2> 5/16/97 msd Include FilesInternal.h
65: <CS1> 4/24/97 djb first checked in
66: <HFS1> 3/31/97 djb first checked in
67: */
68:
69: #if ( PRAGMA_LOAD_SUPPORTED )
70: #pragma load PrecompiledHeaders
71: #else
72: #if TARGET_OS_MAC
73: #include <Types.h>
74: #include <LowMemPriv.h>
75: #else
76: #include "../headers/system/MacOSStubs.h"
77: #endif /* TARGET_OS_MAC */
78: #endif /* PRAGMA_LOAD_SUPPORTED */
79:
80:
81: #include "../headers/HFSVolumes.h"
82: #include "../headers/FileMgrInternal.h"
83:
84:
85: /*-------------------------------------------------------------------------------
86: Routine: ClearMemory - clear a block of memory
87:
88: -------------------------------------------------------------------------------*/
89:
90: void ClearMemory( void* start, UInt32 length )
91: {
92: UInt32 zero = 0;
93: UInt32* dataPtr;
94: UInt8* bytePtr;
95: UInt32 fragCount; // serves as both a length and quadlong count
96: // for the beginning and main fragment
97:
98: if ( length == 0 )
99: return;
100:
101: // is request less than 4 bytes?
102: if ( length < 4 ) // length = 1,2 or 3
103: {
104: bytePtr = (UInt8 *) start;
105:
106: do
107: {
108: *bytePtr++ = zero; // clear one byte at a time
109: }
110: while ( --length );
111:
112: return;
113: }
114:
115: // are we aligned on an odd boundry?
116: fragCount = (UInt32) start & 3;
117:
118: if ( fragCount ) // fragCount = 1,2 or 3
119: {
120: bytePtr = (UInt8 *) start;
121:
122: do
123: {
124: *bytePtr++ = zero; // clear one byte at a time
125: ++fragCount;
126: --length;
127: }
128: while ( (fragCount < 4) && (length > 0) );
129:
130: if ( length == 0 )
131: return;
132:
133: dataPtr = (UInt32*) (((UInt32) start & 0xFFFFFFFC) + 4); // make it long word aligned
134: }
135: else
136: {
137: dataPtr = (UInt32*) ((UInt32) start & 0xFFFFFFFC); // make it long word aligned
138: }
139:
140: // At this point dataPtr is long aligned
141:
142: // are there odd bytes to copy?
143: fragCount = length & 3;
144:
145: if ( fragCount )
146: {
147: bytePtr = (UInt8 *) ((UInt32) dataPtr + (UInt32) length - 1); // point to last byte
148:
149: length -= fragCount; // adjust remaining length
150:
151: do
152: {
153: *bytePtr-- = zero; // clear one byte at a time
154: }
155: while ( --fragCount );
156:
157: if ( length == 0 )
158: return;
159: }
160:
161: // At this point length is a multiple of 4
162:
163: #if DEBUG_BUILD
164: if ( length < 4 )
165: DebugStr("\p ClearMemory: length < 4");
166: #endif
167:
168: // fix up beginning to get us on a 64 byte boundary
169: fragCount = length & (64-1);
170:
171: #if DEBUG_BUILD
172: if ( fragCount < 4 && fragCount > 0 )
173: DebugStr("\p ClearMemory: fragCount < 4");
174: #endif
175:
176: if ( fragCount )
177: {
178: length -= fragCount; // subtract fragment from length now
179: fragCount >>= 2; // divide by 4 to get a count, for DBRA loop
180: do
181: {
182: // clear 4 bytes at a time...
183: *dataPtr++ = zero;
184: }
185: while (--fragCount);
186: }
187:
188: // Are we finished yet?
189: if ( length == 0 )
190: return;
191:
192: // Time to turn on the fire hose
193: length >>= 6; // divide by 64 to get count
194: do
195: {
196: // spray 64 bytes at a time...
197: *dataPtr++ = zero; *dataPtr++ = zero; *dataPtr++ = zero; *dataPtr++ = zero;
198: *dataPtr++ = zero; *dataPtr++ = zero; *dataPtr++ = zero; *dataPtr++ = zero;
199: *dataPtr++ = zero; *dataPtr++ = zero; *dataPtr++ = zero; *dataPtr++ = zero;
200: *dataPtr++ = zero; *dataPtr++ = zero; *dataPtr++ = zero; *dataPtr++ = zero;
201: }
202: while (--length);
203: }
204:
205:
206: //_______________________________________________________________________
207:
208: Boolean UnicodeBinaryCompare( ConstHFSUniStr255Param ustr1, ConstHFSUniStr255Param ustr2 )
209: {
210: UInt16 len;
211: const UniChar *u1;
212: const UniChar *u2;
213:
214: len = ustr1->length;
215:
216: if ( len != ustr2->length )
217: return false;
218:
219: u1 = ustr1->unicode;
220: u2 = ustr2->unicode;
221:
222: ++len; // adjust for pre-decrement in loop
223:
224: // Keep going until we run out of characters, or find one that differs
225: while (--len && *(u1++) == *(u2++))
226: ;
227:
228: // Return true iff we ran out of characters
229: return len==0;
230: }
231:
232: //_______________________________________________________________________
233:
234: Boolean PascalBinaryCompare( ConstStr31Param pstr1, ConstStr31Param pstr2 )
235: {
236: unsigned length;
237:
238: length = *pstr1;
239: if (*(pstr1++) != *(pstr2++)) // lengths must match
240: return false;
241:
242: ++length; // adjust for pre-decrement in loop
243:
244: // Keep going until we run out of characters, or find one that differs
245: while (--length && *(pstr1++) == *(pstr2++))
246: ;
247:
248: // Return true iff we ran out of characters
249: return length==0;
250: }
251:
252: #if TARGET_OS_MAC
253:
254: #if (FORDISKFIRSTAID)
255:
256: UInt32 LocalToUTC(UInt32 localTime)
257: {
258: return localTime;
259: }
260: UInt32 UTCToLocal(UInt32 utcTime)
261: {
262: return utcTime;
263: }
264:
265: #else /* not for Disk First Aid */
266:
267: UInt32 LocalToUTC(register UInt32 localTime)
268: {
269: register UInt32 utc;
270:
271: //
272: // An input of zero means "never". In that case, don't adjust it.
273: //
274: if (localTime == 0)
275: return 0;
276:
277: //
278: // Compute Universal Time
279: //
280: utc = localTime - ((FSVarsRec*) LMGetFSMVars())->offsetToUTC;
281:
282: //
283: // If we wrapped around, then use the most extreme
284: // value closest to the localTime input.
285: //
286: if ((utc ^ localTime) & 0xFF000000 == 0xFF000000) {
287: if (localTime & 0xFF000000)
288: utc = 0xFFFFFFFF; // pin to maximum value
289: else
290: utc = 0; // pin to minimum value
291: }
292:
293: return utc;
294: }
295:
296:
297: UInt32 UTCToLocal(register UInt32 utcTime)
298: {
299: register UInt32 local;
300:
301: //
302: // An input of zero means "never". In that case, don't adjust it.
303: //
304: if (utcTime == 0)
305: return 0;
306:
307: //
308: // Compute Universal Time
309: //
310: local = utcTime + ((FSVarsRec *) LMGetFSMVars())->offsetToUTC;
311:
312: //
313: // If we wrapped around, then use the most extreme
314: // value closest to the utcTime input.
315: //
316: if ((local ^ utcTime) & 0xFF000000 == 0xFF000000) {
317: if (utcTime & 0xFF000000)
318: local = 0xFFFFFFFF; // pin to maximum value
319: else
320: local = 0; // pin to minimum value
321: }
322:
323: return local;
324: }
325: #endif
326: #endif /* TARGE_OS_MAC */
327:
328:
329: #if TARGET_OS_MAC
330: UInt32 GetTimeUTC(void)
331: {
332: UInt32 localTime;
333:
334: GetDateTime(&localTime);
335: return LocalToUTC(localTime);
336: }
337:
338:
339: UInt32 GetTimeLocal(void)
340: {
341: UInt32 localTime;
342:
343: GetDateTime(&localTime);
344: return localTime;
345: }
346: #endif /* TARGET_OS_MAC */
347:
348:
349: #ifndef __MATH64__
350:
351: UInt64 U64Add (UInt64 x, UInt64 y)
352: {
353: UInt64 result;
354:
355: result.lo = x.lo + y.lo;
356: result.hi = x.hi + y.hi;
357:
358: // Now see if there was a carry out of the low half. If there was a carry
359: // out, then the unsigned interpretation of the result will be less than
360: // the unsigned interpretation of both addends.
361:
362: if (((UInt32) result.lo) < ((UInt32) x.lo))
363: ++result.hi; // was carry; add it to upper half
364:
365: return(result); // pass the answer back
366: }
367:
368:
369: UInt64 U64Subtract (UInt64 left, UInt64 right)
370: {
371: UInt64 result;
372:
373: result.lo = left.lo - right.lo;
374: result.hi = left.hi - right.hi;
375:
376: // Now see if there was a borrow from the low half. There will be one if
377: // the unsigned interpretation of right.lo is greater than the unsigned
378: // interpretation of left.lo.
379:
380: if (((UInt32) right.lo) > ((UInt32) left.lo))
381: --result.hi; // was borrow; subtract from upper half
382:
383: return(result); // pass the answer back
384: }
385:
386: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.