/** EOGlobalID.m EOGlobalID Copyright (C) 2000-2003 Free Software Foundation, Inc. Author: Mirko Viviani Date: February 2000 $Revision$ $Date$ This file is part of the GNUstep Database Library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. **/ #include "config.h" RCS_ID("$Id$") #ifdef GNUSTEP #include #include #include #include #include #else #include #endif #ifndef GNUSTEP #include #endif #include #include #include NSString *EOGlobalIDChangedNotification = @"EOGlobalIDChangedNotification"; @implementation EOGlobalID + (void)initialize { if (self == [EOGlobalID class]) { Class cls = NSClassFromString(@"EODatabaseContext"); if (cls != Nil) [cls class]; // Insure correct initialization. } } - (BOOL)isEqual: (id)other { return NO; } - (unsigned)hash { return 0; } - (BOOL)isTemporary { return NO; } - (id)copyWithZone: (NSZone *)zone { EOGlobalID *gid = [[[self class] alloc] init]; return gid; } @end @implementation EOTemporaryGlobalID static unsigned short sequence = (unsigned short)-1; + (EOTemporaryGlobalID *)temporaryGlobalID { return [[[self alloc] init] autorelease]; } /** * Fills the supplied buffer with 12 bytes that are unique to the * subnet. The first two bytes encode a sequence of the process. * Then two bytes encode the process ID followed by four bytes which * encode a time stamp. The last four bytes encode the IP address. * The caller must insure that the buffer pointed to is large enough * to hold the twelve bytes. */ + (void)assignGloballyUniqueBytes: (unsigned char *)buffer { static int pid = 0; static unsigned char ipComp[4]; unsigned char *bPtr; unsigned short seq; unsigned int i; union { NSTimeInterval interval; unsigned long stamp; } time; EOFLOGObjectFnStart(); if (pid == 0) { NSString *ipString; NSArray *ipComps; pid = [[NSProcessInfo processInfo] processIdentifier]; pid %= 0xFFFF; ipString = [[NSHost currentHost] address]; ipComps = [ipString componentsSeparatedByString: @"."]; for (i=0; i<4; i++) { NSString *comp = [ipComps objectAtIndex: i]; ipComp[i] = (unsigned char)[comp intValue]; } } memset (buffer, 0, 12); seq = sequence-- % 0xFFFF; bPtr = (unsigned char *)&seq; buffer[0] = bPtr[0]; buffer[1] = bPtr[1]; bPtr = (unsigned char *)&pid; buffer[2] = bPtr[0]; buffer[3] = bPtr[1]; time.interval = [NSDate timeIntervalSinceReferenceDate]; time.stamp %= 0xFFFFFFFF; bPtr = (unsigned char *)&time.stamp; buffer[4] = bPtr[0]; buffer[5] = bPtr[1]; buffer[6] = bPtr[2]; buffer[7] = bPtr[3]; buffer[8] = ipComp[0]; buffer[9] = ipComp[1]; buffer[10] = ipComp[2]; buffer[11] = ipComp[3]; if (sequence == 0) { sequence = (unsigned short)-1; } EOFLOGObjectFnStop(); } - (id)init { EOFLOGObjectFnStart(); if ((self = [super init])) { [EOTemporaryGlobalID assignGloballyUniqueBytes:_bytes]; } EOFLOGObjectFnStop(); return self; } - (BOOL)isTemporary { return YES; } - (BOOL)isEqual: (id)other { if (self == other) return YES; if ([other isKindOfClass: [EOTemporaryGlobalID class]] == NO) return NO; if (!memcmp(_bytes, ((EOTemporaryGlobalID *)other)->_bytes, sizeof(_bytes))) return YES; return NO; } - (void)encodeWithCoder: (NSCoder *)coder { [coder encodeValueOfObjCType: @encode(unsigned) at: &_refCount]; [coder encodeValueOfObjCType: @encode(unsigned char[12]) at: _bytes]; } - (id)initWithCoder: (NSCoder *)coder { self = [super init]; [coder decodeValueOfObjCType: @encode(unsigned) at: &_refCount]; [coder decodeValueOfObjCType: @encode(unsigned char[12]) at: _bytes]; return self; } - (id)copyWithZone: (NSZone *)zone { EOTemporaryGlobalID *gid = [super copyWithZone:zone]; gid->_refCount = _refCount; memcpy(gid->_bytes, _bytes, sizeof(_bytes)); return gid; } @end