Hi,
GNUstep's NSString currently lacks
getBytes:maxLength:usedLength:encoding:options:range:remainingRange:
(added in OS X 10.5).
I wanted to implement this function, but GSFromUnicode()'s behavior is
not the best fit for this method:
1) it fails if the output buffer is too small - we don't want that in
this case
2) it doesn't tell you how many input characters were converted (which
is understandable because of 1)
So I decided to use iconv() directly, which has a pitfall. I'd need to
access static members (EntrySupported) of Unicode.m to know the iconv
encoding's name etc. So I guess the iconv-related code (as attached)
should be moved into Unicode.m.
===============
So I have a question: is it OK to write a function with declaration:
BOOL GSFromUnicodePartial(NSStringEncoding enc, int options, unichar
**inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft);
that wouldn't suffer from 1) and 2) and add it into
Source/Additions/Unicode.m next to GSFromUnicode()?
--
Luboš Doležel
Index: NSString.m
===================================================================
--- NSString.m (revision 36703)
+++ NSString.m (working copy)
@@ -1712,6 +1712,91 @@
}
/**
+ * Retrieves a part of the string while converting it to a specified encoding
+ */
+- (BOOL) getBytes: (void*)buffer
+ maxLength: (NSUInteger)maxBufferCount
+ usedLength: (NSUInteger*)usedBufferCount
+ encoding: (NSStringEncoding)encoding
+ options: (NSStringEncodingConversionOptions)options
+ range: (NSRange)range
+ remainingRange: (NSRangePointer)leftover
+{
+#ifdef HAVE_ICONV
+ unichar *chars;
+ struct _strenc_ *encInfo;
+ iconv_t cd;
+ char *inbuf;
+ char *outbuf;
+ size_t inbytesleft;
+ size_t outbytesleft;
+ size_t icresult;
+ const char *enc;
+
+ encInfo = EntrySupported(encoding);
+
+ if (!encInfo)
+ return NO;
+
+ enc = encInfo->iconv;
+
+ if (options & NSStringEncodingConversionAllowLossy)
+ enc = encInfo->lossy;
+ cd = iconv_open(estr, UNICODE_ENC);
+
+ if (cd == (iconv_t)-1)
+ {
+ NSLog(@"[NSString getBytes]: No iconv for encoding %@ tried to use %s",
+ GSPrivateEncodingName(encoding), enc);
+ return NO;
+ }
+
+ inbytesleft = range.length * sizeof(unichar);
+#if GS_WITH_GC
+ chars = NSAllocateCollectable(inbytesleft, 0);
+#else
+ chars = NSZoneMalloc([self zone], inbytesleft);
+#endif
+
+ [self getCharacters: chars
+ range: range];
+
+ inbuf = (char*) chars;
+ outbuf = (unsigned char*) buffer;
+ outbytesleft = maxBufferCount;
+
+ icresult = iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
+
+#if !GS_WITH_GC
+ NSZoneFree([self zone], src);
+#endif
+
+ if (icresult == (iconv_t)-1 && errno != E2BIG)
+ return NO;
+
+ if (leftover != NULL)
+ {
+ if (inbytesleft > 0)
+ {
+ leftover->length = inbytesleft / sizeof(unichar);
+ leftover->location = range.location + range.length
+ - leftover->length;
+ }
+ else
+ leftover->length = 0;
+ }
+
+ if (usedBufferCount != NULL)
+ *usedBufferCount = maxBufferCount - outbytesleft;
+
+ return YES;
+
+#else
+ return NO;
+#endif
+}
+
+/**
* Constructs a new ASCII string which is a representation of the receiver
* in which characters are escaped where necessary in order to produce a
* version of the string legal for inclusion within a URL.<br />
_______________________________________________
Gnustep-dev mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/gnustep-dev