/*
* Copyright (c) 2008, 2009, 2010, 2011
* Jonathan Schleifer <js@webkeks.org>
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
* the packaging of this file.
*
* Alternatively, it may be distributed under the terms of the GNU General
* Public License, either version 2 or 3, which can be found in the file
* LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
* file.
*/
#include "config.h"
#include <stdlib.h>
#include <string.h>
#import "OFConstantString.h"
#import "OFInvalidEncodingException.h"
#import "OFNotImplementedException.h"
#import "OFOutOfMemoryException.h"
#ifdef OF_APPLE_RUNTIME
# import <objc/runtime.h>
void *_OFConstantStringClassReference;
#endif
@implementation OFConstantString
#ifdef OF_APPLE_RUNTIME
+ (void)load
{
objc_setFutureClass((Class)&_OFConstantStringClassReference,
"OFConstantString");
}
#endif
- (void)finishInitialization
{
struct of_string_ivars *ivars;
if (initialized == SIZE_MAX)
return;
if ((ivars = malloc(sizeof(*ivars))) == NULL)
@throw [OFOutOfMemoryException
exceptionWithClass: isa
requestedSize: sizeof(*ivars)];
memset(ivars, 0, sizeof(*ivars));
ivars->cString = (char*)s;
ivars->cStringLength = initialized;
switch (of_string_check_utf8(ivars->cString, ivars->cStringLength,
&ivars->length)) {
case 1:
ivars->UTF8 = YES;
break;
case -1:
free(ivars);
@throw [OFInvalidEncodingException exceptionWithClass: isa];
}
s = ivars;
initialized = SIZE_MAX;
}
/*
* The following methods are not available since it's a constant string, which
* can't be allocated or initialized at runtime.
*/
+ alloc
{
@throw [OFNotImplementedException exceptionWithClass: self
selector: _cmd];
}
- init
{
Class c = isa;
[self release];
@throw [OFNotImplementedException exceptionWithClass: c
selector: _cmd];
}
- initWithUTF8String: (const char*)UTF8String
{
Class c = isa;
[self release];
@throw [OFNotImplementedException exceptionWithClass: c
selector: _cmd];
}
- initWithUTF8String: (const char*)UTF8String
length: (size_t)UTF8StringLength
{
Class c = isa;
[self release];
@throw [OFNotImplementedException exceptionWithClass: c
selector: _cmd];
}
- initWithCString: (const char*)cString
encoding: (of_string_encoding_t)encoding
{
Class c = isa;
[self release];
@throw [OFNotImplementedException exceptionWithClass: c
selector: _cmd];
}
- initWithCString: (const char*)cString
encoding: (of_string_encoding_t)encoding
length: (size_t)cStringLength
{
Class c = isa;
[self release];
@throw [OFNotImplementedException exceptionWithClass: c
selector: _cmd];
}
- initWithString: (OFString*)string
{
Class c = isa;
[self release];
@throw [OFNotImplementedException exceptionWithClass: c
selector: _cmd];
}
- initWithUnicodeString: (of_unichar_t*)string
{
Class c = isa;
[self release];
@throw [OFNotImplementedException exceptionWithClass: c
selector: _cmd];
}
- initWithUnicodeString: (of_unichar_t*)string
byteOrder: (of_endianess_t)byteOrder
{
Class c = isa;
[self release];
@throw [OFNotImplementedException exceptionWithClass: c
selector: _cmd];
}
- initWithUnicodeString: (of_unichar_t*)string
length: (size_t)length
{
Class c = isa;
[self release];
@throw [OFNotImplementedException exceptionWithClass: c
selector: _cmd];
}
- initWithUnicodeString: (of_unichar_t*)string
byteOrder: (of_endianess_t)byteOrder
length: (size_t)length
{
Class c = isa;
[self release];
@throw [OFNotImplementedException exceptionWithClass: c
selector: _cmd];
}
- initWithUTF16String: (uint16_t*)string
byteOrder: (of_endianess_t)byteOrder
{
Class c = isa;
[self release];
@throw [OFNotImplementedException exceptionWithClass: c
selector: _cmd];
}
- initWithUTF16String: (uint16_t*)string
length: (size_t)length
{
Class c = isa;
[self release];
@throw [OFNotImplementedException exceptionWithClass: c
selector: _cmd];
}
- initWithUTF16String: (uint16_t*)string
byteOrder: (of_endianess_t)byteOrder
length: (size_t)length
{
Class c = isa;
[self release];
@throw [OFNotImplementedException exceptionWithClass: c
selector: _cmd];
}
- initWithFormat: (OFConstantString*)format, ...
{
Class c = isa;
[self release];
@throw [OFNotImplementedException exceptionWithClass: c
selector: _cmd];
}
- initWithFormat: (OFConstantString*)format
arguments: (va_list)args
{
Class c = isa;
[self release];
@throw [OFNotImplementedException exceptionWithClass: c
selector: _cmd];
}
- initWithPath: (OFString*)firstComponent, ...
{
Class c = isa;
[self release];
@throw [OFNotImplementedException exceptionWithClass: c
selector: _cmd];
}
- initWithPath: (OFString*)firstComponent
arguments: (va_list)arguments
{
Class c = isa;
[self release];
@throw [OFNotImplementedException exceptionWithClass: c
selector: _cmd];
}
- initWithContentsOfFile: (OFString*)path
{
Class c = isa;
[self release];
@throw [OFNotImplementedException exceptionWithClass: c
selector: _cmd];
}
- initWithContentsOfFile: (OFString*)path
encoding: (of_string_encoding_t)encoding
{
Class c = isa;
[self release];
@throw [OFNotImplementedException exceptionWithClass: c
selector: _cmd];
}
- initWithContentsOfURL: (OFURL*)URL
{
Class c = isa;
[self release];
@throw [OFNotImplementedException exceptionWithClass: c
selector: _cmd];
}
- initWithContentsOfURL: (OFURL*)URL
encoding: (of_string_encoding_t)encoding
{
Class c = isa;
[self release];
@throw [OFNotImplementedException exceptionWithClass: c
selector: _cmd];
}
/* From protocol OFSerializing */
- initWithSerialization: (OFXMLElement*)element
{
Class c = isa;
[self release];
@throw [OFNotImplementedException exceptionWithClass: c
selector: _cmd];
}
/*
* The following methods are not available because constant strings are
* preallocated by the compiler and thus don't have a memory pool.
*/
- (void)addMemoryToPool: (void*)ptr
{
@throw [OFNotImplementedException exceptionWithClass: isa
selector: _cmd];
}
- (void*)allocMemoryWithSize: (size_t)size
{
@throw [OFNotImplementedException exceptionWithClass: isa
selector: _cmd];
}
- (void*)allocMemoryForNItems: (size_t)nitems
withSize: (size_t)size
{
@throw [OFNotImplementedException exceptionWithClass: isa
selector: _cmd];
}
- (void*)resizeMemory: (void*)ptr
toSize: (size_t)size
{
@throw [OFNotImplementedException exceptionWithClass: isa
selector: _cmd];
}
- (void*)resizeMemory: (void*)ptr
toNItems: (size_t)nitems
withSize: (size_t)size
{
@throw [OFNotImplementedException exceptionWithClass: isa
selector: _cmd];
}
- (void)freeMemory: (void*)ptr
{
@throw [OFNotImplementedException exceptionWithClass: isa
selector: _cmd];
}
/*
* The following methods are unnecessary because constant strings are
* singletons.
*/
- retain
{
return self;
}
- autorelease
{
return self;
}
- (unsigned int)retainCount
{
return OF_RETAIN_COUNT_MAX;
}
- (void)release
{
}
- (void)dealloc
{
@throw [OFNotImplementedException exceptionWithClass: isa
selector: _cmd];
[super dealloc]; /* Get rid of a stupid warning */
}
/*
* In all following methods, it is checked whether the constant string has been
* initialized. If not, it will be initialized. Finally, the implementation of
* the superclass will be called.
*/
/* From protocol OFCopying */
- copy
{
if (initialized != SIZE_MAX)
[self finishInitialization];
return [super copy];
}
/* From protocol OFMutableCopying */
- mutableCopy
{
if (initialized != SIZE_MAX)
[self finishInitialization];
return [super mutableCopy];
}
/* From protocol OFComparing */
- (of_comparison_result_t)compare: (id)object
{
if (initialized != SIZE_MAX)
[self finishInitialization];
return [super compare: object];
}
/* From OFObject, but reimplemented in OFString */
- (BOOL)isEqual: (id)object
{
if (initialized != SIZE_MAX)
[self finishInitialization];
return [super isEqual: object];
}
- (uint32_t)hash
{
if (initialized != SIZE_MAX)
[self finishInitialization];
return [super hash];
}
- (OFString*)description
{
if (initialized != SIZE_MAX)
[self finishInitialization];
return [super description];
}
/* From OFString */
- (const char*)UTF8String
{
if (initialized != SIZE_MAX)
[self finishInitialization];
return [super UTF8String];
}
- (const char*)cStringWithEncoding: (of_string_encoding_t)encoding
{
if (initialized != SIZE_MAX)
[self finishInitialization];
return [super cStringWithEncoding: encoding];
}
- (size_t)length
{
if (initialized != SIZE_MAX)
[self finishInitialization];
return [super length];
}
- (size_t)UTF8StringLength
{
if (initialized != SIZE_MAX)
[self finishInitialization];
return [super UTF8StringLength];
}
- (size_t)cStringLengthWithEncoding: (of_string_encoding_t)encoding
{
if (initialized != SIZE_MAX)
[self finishInitialization];
return [super cStringLengthWithEncoding: encoding];
}
- (of_comparison_result_t)caseInsensitiveCompare: (OFString*)otherString
{
if (initialized != SIZE_MAX)
[self finishInitialization];
return [super caseInsensitiveCompare: otherString];
}
- (of_unichar_t)characterAtIndex: (size_t)index
{
if (initialized != SIZE_MAX)
[self finishInitialization];
return [super characterAtIndex: index];
}
- (size_t)indexOfFirstOccurrenceOfString: (OFString*)string
{
if (initialized != SIZE_MAX)
[self finishInitialization];
return [super indexOfFirstOccurrenceOfString: string];
}
- (size_t)indexOfLastOccurrenceOfString: (OFString*)string
{
if (initialized != SIZE_MAX)
[self finishInitialization];
return [super indexOfLastOccurrenceOfString: string];
}
- (BOOL)containsString: (OFString*)string
{
if (initialized != SIZE_MAX)
[self finishInitialization];
return [super containsString: string];
}
- (OFString*)substringWithRange: (of_range_t)range
{
if (initialized != SIZE_MAX)
[self finishInitialization];
return [super substringWithRange: range];
}
- (OFString*)stringByAppendingString: (OFString*)string
{
if (initialized != SIZE_MAX)
[self finishInitialization];
return [super stringByAppendingString: string];
}
- (OFString*)stringByPrependingString: (OFString*)string
{
if (initialized != SIZE_MAX)
[self finishInitialization];
return [super stringByPrependingString: string];
}
- (OFString*)uppercaseString
{
if (initialized != SIZE_MAX)
[self finishInitialization];
return [super uppercaseString];
}
- (OFString*)lowercaseString
{
if (initialized != SIZE_MAX)
[self finishInitialization];
return [super lowercaseString];
}
- (OFString*)stringByDeletingLeadingWhitespaces
{
if (initialized != SIZE_MAX)
[self finishInitialization];
return [super stringByDeletingLeadingWhitespaces];
}
- (OFString*)stringByDeletingTrailingWhitespaces
{
if (initialized != SIZE_MAX)
[self finishInitialization];
return [super stringByDeletingTrailingWhitespaces];
}
- (OFString*)stringByDeletingEnclosingWhitespaces
{
if (initialized != SIZE_MAX)
[self finishInitialization];
return [super stringByDeletingEnclosingWhitespaces];
}
- (BOOL)hasPrefix: (OFString*)prefix
{
if (initialized != SIZE_MAX)
[self finishInitialization];
return [super hasPrefix: prefix];
}
- (BOOL)hasSuffix: (OFString*)suffix
{
if (initialized != SIZE_MAX)
[self finishInitialization];
return [super hasSuffix: suffix];
}
- (OFArray*)componentsSeparatedByString: (OFString*)delimiter
{
if (initialized != SIZE_MAX)
[self finishInitialization];
return [super componentsSeparatedByString: delimiter];
}
- (OFArray*)pathComponents
{
if (initialized != SIZE_MAX)
[self finishInitialization];
return [super pathComponents];
}
- (OFString*)lastPathComponent
{
if (initialized != SIZE_MAX)
[self finishInitialization];
return [super lastPathComponent];
}
- (OFString*)stringByDeletingLastPathComponent
{
if (initialized != SIZE_MAX)
[self finishInitialization];
return [super stringByDeletingLastPathComponent];
}
- (intmax_t)decimalValue
{
if (initialized != SIZE_MAX)
[self finishInitialization];
return [super decimalValue];
}
- (uintmax_t)hexadecimalValue
{
if (initialized != SIZE_MAX)
[self finishInitialization];
return [super hexadecimalValue];
}
- (float)floatValue
{
if (initialized != SIZE_MAX)
[self finishInitialization];
return [super floatValue];
}
- (double)doubleValue
{
if (initialized != SIZE_MAX)
[self finishInitialization];
return [super doubleValue];
}
- (of_unichar_t*)unicodeString
{
if (initialized != SIZE_MAX)
[self finishInitialization];
return [super unicodeString];
}
- (void)writeToFile: (OFString*)path
{
if (initialized != SIZE_MAX)
[self finishInitialization];
return [super writeToFile: path];
}
#ifdef OF_HAVE_BLOCKS
- (void)enumerateLinesUsingBlock: (of_string_line_enumeration_block_t)block
{
if (initialized != SIZE_MAX)
[self finishInitialization];
return [super enumerateLinesUsingBlock: block];
}
#endif
@end