From 50a73fee64fb34ef4d145e478828a532b9bc872f Mon Sep 17 00:00:00 2001 From: Brad Roberts Date: Mon, 10 Sep 2007 03:46:34 +0000 Subject: [PATCH] phobos 0.79 --- internal/aApply.d | 387 ++++++++++++++++++++++++++++++++++++++++++++++ linux.mak | 14 +- std/base64.d | 232 +++++++++++++++++++++++++++ std/file.d | 2 +- std/regexp.d | 4 +- win32.mak | 18 ++- 6 files changed, 644 insertions(+), 13 deletions(-) create mode 100644 internal/aApply.d create mode 100644 std/base64.d diff --git a/internal/aApply.d b/internal/aApply.d new file mode 100644 index 000000000..27391402a --- /dev/null +++ b/internal/aApply.d @@ -0,0 +1,387 @@ +//_ aApply.d +// Copyright (c) 2004 by Digital Mars +// Written by Walter Bright + +/* This code handles decoding UTF strings for foreach loops. + * There are 6 combinations of conversions between char, wchar, + * and dchar, and 2 of each of those. + */ + +import std.utf; + +//debug=apply; + +/********************************************** + * 'apply' for associative arrays - to support foreach + */ + +// dg is D, but _aApplycd() is C +extern (D) typedef int delegate(void *) dg_t; + +extern (C) int _aApplycd1(char[] aa, dg_t dg) +{ int result; + size_t i; + size_t len = aa.length; + + debug(apply) printf("_aApplycd1(), len = %d\n", len); + for (i = 0; i < len; ) + { dchar d; + + d = aa[i]; + if (d & 0x80) + d = std.utf.decode(aa, i); + else + i++; + result = dg((void *)&d); + if (result) + break; + } + return result; +} + +extern (C) int _aApplywd1(wchar[] aa, dg_t dg) +{ int result; + size_t i; + size_t len = aa.length; + + debug(apply) printf("_aApplywd1(), len = %d\n", len); + for (i = 0; i < len; ) + { dchar d; + + d = aa[i]; + if (d & ~0x7F) + d = std.utf.decode(aa, i); + else + i++; + result = dg((void *)&d); + if (result) + break; + } + return result; +} + +extern (C) int _aApplycw1(char[] aa, dg_t dg) +{ int result; + size_t i; + size_t len = aa.length; + + debug(apply) printf("_aApplycw1(), len = %d\n", len); + for (i = 0; i < len; ) + { dchar d; + wchar w; + + w = aa[i]; + if (w & 0x80) + { d = std.utf.decode(aa, i); + if (d <= 0xFFFF) + w = cast(wchar) d; + else + { + w = (((d - 0x10000) >> 10) & 0x3FF) + 0xD800; + result = dg((void *)&w); + if (result) + break; + w = ((d - 0x10000) & 0x3FF) + 0xDC00; + } + } + else + i++; + result = dg((void *)&w); + if (result) + break; + } + return result; +} + +extern (C) int _aApplywc1(wchar[] aa, dg_t dg) +{ int result; + size_t i; + size_t len = aa.length; + + debug(apply) printf("_aApplywc1(), len = %d\n", len); + for (i = 0; i < len; ) + { dchar d; + wchar w; + char c; + + w = aa[i]; + if (w & ~0x7F) + { + char[4] buf; + char[] b; + + d = std.utf.decode(aa, i); + b = std.utf.toUTF8(buf, d); + foreach (char c; b) + { + result = dg((void *)&c); + if (result) + return result; + } + continue; + } + else + { c = cast(char)w; + i++; + } + result = dg((void *)&c); + if (result) + break; + } + return result; +} + +extern (C) int _aApplydc1(dchar[] aa, dg_t dg) +{ int result; + + debug(apply) printf("_aApplydc1(), len = %d\n", aa.length); + foreach (dchar d; aa) + { + char c; + + if (d & ~0x7F) + { + char[4] buf; + char[] b; + + b = std.utf.toUTF8(buf, d); + foreach (char c; b) + { + result = dg((void *)&c); + if (result) + return result; + } + continue; + } + else + { + c = cast(char)d; + } + result = dg((void *)&c); + if (result) + break; + } + return result; +} + +extern (C) int _aApplydw1(dchar[] aa, dg_t dg) +{ int result; + + debug(apply) printf("_aApplydw1(), len = %d\n", aa.length); + foreach (dchar d; aa) + { + wchar w; + + if (d <= 0xFFFF) + w = cast(wchar) d; + else + { + w = (((d - 0x10000) >> 10) & 0x3FF) + 0xD800; + result = dg((void *)&w); + if (result) + break; + w = ((d - 0x10000) & 0x3FF) + 0xDC00; + } + result = dg((void *)&w); + if (result) + break; + } + return result; +} + + +/****************************************************************************/ + +// dg is D, but _aApplycd2() is C +extern (D) typedef int delegate(void *, void *) dg2_t; + +extern (C) int _aApplycd2(char[] aa, dg2_t dg) +{ int result; + size_t i; + size_t n; + size_t len = aa.length; + + debug(apply) printf("_aApplycd2(), len = %d\n", len); + for (i = 0; i < len; i += n) + { dchar d; + + d = aa[i]; + if (d & 0x80) + { + n = i; + d = std.utf.decode(aa, n); + n -= i; + } + else + n = 1; + result = dg(&i, (void *)&d); + if (result) + break; + } + return result; +} + +extern (C) int _aApplywd2(wchar[] aa, dg2_t dg) +{ int result; + size_t i; + size_t n; + size_t len = aa.length; + + debug(apply) printf("_aApplywd2(), len = %d\n", len); + for (i = 0; i < len; i += n) + { dchar d; + + d = aa[i]; + if (d & ~0x7F) + { + n = i; + d = std.utf.decode(aa, n); + n -= i; + } + else + n = 1; + result = dg(&i, (void *)&d); + if (result) + break; + } + return result; +} + +extern (C) int _aApplycw2(char[] aa, dg2_t dg) +{ int result; + size_t i; + size_t n; + size_t len = aa.length; + + debug(apply) printf("_aApplycw2(), len = %d\n", len); + for (i = 0; i < len; i += n) + { dchar d; + wchar w; + + w = aa[i]; + if (w & 0x80) + { n = i; + d = std.utf.decode(aa, n); + n -= i; + if (d <= 0xFFFF) + w = cast(wchar) d; + else + { + w = (((d - 0x10000) >> 10) & 0x3FF) + 0xD800; + result = dg(&i, (void *)&w); + if (result) + break; + w = ((d - 0x10000) & 0x3FF) + 0xDC00; + } + } + else + n = 1; + result = dg(&i, (void *)&w); + if (result) + break; + } + return result; +} + +extern (C) int _aApplywc2(wchar[] aa, dg2_t dg) +{ int result; + size_t i; + size_t n; + size_t len = aa.length; + + debug(apply) printf("_aApplywc2(), len = %d\n", len); + for (i = 0; i < len; i += n) + { dchar d; + wchar w; + char c; + + w = aa[i]; + if (w & ~0x7F) + { + char[4] buf; + char[] b; + + n = i; + d = std.utf.decode(aa, n); + n -= i; + b = std.utf.toUTF8(buf, d); + foreach (char c; b) + { + result = dg(&i, (void *)&c); + if (result) + return result; + } + continue; + } + else + { c = cast(char)w; + n = 1; + } + result = dg(&i, (void *)&c); + if (result) + break; + } + return result; +} + +extern (C) int _aApplydc2(dchar[] aa, dg2_t dg) +{ int result; + size_t i; + size_t len = aa.length; + + debug(apply) printf("_aApplydc2(), len = %d\n", len); + for (i = 0; i < len; i++) + { dchar d; + char c; + + d = aa[i]; + if (d & ~0x7F) + { + char[4] buf; + char[] b; + + b = std.utf.toUTF8(buf, d); + foreach (char c; b) + { + result = dg(&i, (void *)&c); + if (result) + return result; + } + continue; + } + else + { c = cast(char)d; + } + result = dg(&i, (void *)&c); + if (result) + break; + } + return result; +} + +extern (C) int _aApplydw2(dchar[] aa, dg2_t dg) +{ int result; + + debug(apply) printf("_aApplydw2(), len = %d\n", aa.length); + foreach (size_t i, dchar d; aa) + { + wchar w; + + if (d <= 0xFFFF) + w = cast(wchar) d; + else + { + w = (((d - 0x10000) >> 10) & 0x3FF) + 0xD800; + result = dg(&i, (void *)&w); + if (result) + break; + w = ((d - 0x10000) & 0x3FF) + 0xDC00; + } + result = dg(&i, (void *)&w); + if (result) + break; + } + return result; +} + + diff --git a/linux.mak b/linux.mak index d0c2d9ed3..2e5b2fd33 100644 --- a/linux.mak +++ b/linux.mak @@ -47,8 +47,8 @@ unittest.o : unittest.d OBJS= asserterror.o deh2.o switch.o complex.o gcstats.o \ critical.o object.o monitor.o arraycat.o invariant.o \ - dmain2.o outofmemory.o aaA.o adi.o file.o \ - compiler.o system.o moduleinit.o md5.o \ + dmain2.o outofmemory.o aaA.o adi.o aApply.o file.o \ + compiler.o system.o moduleinit.o md5.o base64.o \ cast.o path.o string.o memset.o math.o \ outbuffer.o ctype.o regexp.o random.o linux.o \ stream.o switcherr.o array.o gc.o \ @@ -83,7 +83,7 @@ SRC= errno.c object.d unittest.d crc32.d gcstats.d SRC_STD= std/zlib.d std/zip.d std/stdint.d std/conv.d std/utf.d std/uri.d \ std/gc.d std/math.d std/string.d std/path.d std/date.d \ std/ctype.d std/file.d std/compiler.d std/system.d std/moduleinit.d \ - std/outbuffer.d std/math2.d std/thread.d std/md5.d \ + std/outbuffer.d std/math2.d std/thread.d std/md5.d std/base64.d \ std/asserterror.d std/dateparse.d std/outofmemory.d \ std/intrinsic.d std/array.d std/switcherr.d std/syserror.d \ std/regexp.d std/random.d std/stream.d std/process.d std/recls.d @@ -116,7 +116,7 @@ SRC_INT= \ internal/arraycat.d internal/invariant.d internal/monitor.c \ internal/memset.d internal/arraycast.d internal/aaA.d internal/adi.d \ internal/dmain2.d internal/cast.d internal/qsort.d internal/deh2.d \ - internal/cmath2.d internal/obj.d internal/mars.h + internal/cmath2.d internal/obj.d internal/mars.h internal/aApply.d SRC_STD_WIN= std/windows/registry.d \ std/windows/iunknown.d @@ -261,6 +261,9 @@ gcstats.o : gcstats.d aaA.o : internal/aaA.d $(DMD) -c $(DFLAGS) internal/aaA.d +aApply.o : internal/aApply.d + $(DMD) -c $(DFLAGS) internal/aApply.d + adi.o : internal/adi.d $(DMD) -c $(DFLAGS) internal/adi.d @@ -326,6 +329,9 @@ array.o : std/array.d asserterror.o : std/asserterror.d $(DMD) -c $(DFLAGS) std/asserterror.d +base64.o : std/base64.d + $(DMD) -c $(DFLAGS) std/base64.d + compiler.o : std/compiler.d $(DMD) -c $(DFLAGS) std/compiler.d diff --git a/std/base64.d b/std/base64.d new file mode 100644 index 000000000..1b1c29d60 --- /dev/null +++ b/std/base64.d @@ -0,0 +1,232 @@ +/* base64.d + * Modified from C. Miller's version, his copyright is below. + */ + +/* + Copyright (C) 2004 Christopher E. Miller + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +module std.base64; + +class Base64Exception: Exception +{ + this(char[] msg) + { + super(msg); + } +} + + +class Base64CharException: Base64Exception +{ + this(char[] msg) + { + super(msg); + } +} + + +const char[] array = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + +uint encodeLength(uint slen) //returns the number of bytes needed to encode a string of this length +{ + uint result; + result = slen / 3; + if(slen % 3) + result++; + return result * 4; +} + + +char[] encode(char[] str, char[] buf) //buf must be large enough +in +{ + assert(buf.length >= encodeLength(str.length)); +} +body +{ + if(!str.length) + return buf[0 .. 0]; + + uint stri; + uint strmax = str.length / 3; + uint strleft = str.length % 3; + uint x; + char* sp, bp; + + bp = &buf[0]; + sp = &str[0]; + for(stri = 0; stri != strmax; stri++) + { + x = (*sp++ << 16) | (*sp++ << 8) | (*sp++); + *bp++ = array[(x & 0b11111100_00000000_00000000) >> 18]; + *bp++ = array[(x & 0b00000011_11110000_00000000) >> 12]; + *bp++ = array[(x & 0b00000000_00001111_11000000) >> 6]; + *bp++ = array[(x & 0b00000000_00000000_00111111)]; + } + + switch(strleft) + { + case 2: + x = (*sp++ << 16) | (*sp++ << 8); + *bp++ = array[(x & 0b11111100_00000000_00000000) >> 18]; + *bp++ = array[(x & 0b00000011_11110000_00000000) >> 12]; + *bp++ = array[(x & 0b00000000_00001111_11000000) >> 6]; + *bp++ = '='; + break; + + case 1: + x = *sp++ << 16; + *bp++ = array[(x & 0b11111100_00000000_00000000) >> 18]; + *bp++ = array[(x & 0b00000011_11110000_00000000) >> 12]; + *bp++ = '='; + *bp++ = '='; + break; + + case 0: + break; + } + + return buf[0 .. (bp - &buf[0])]; +} + + +char[] encode(char[] str) +{ + return encode(str, new char[encodeLength(str.length)]); +} + + +unittest +{ + assert(encode("f") == "Zg=="); + assert(encode("fo") == "Zm8="); + assert(encode("foo") == "Zm9v"); + assert(encode("foos") == "Zm9vcw=="); + assert(encode("all your base64 are belong to foo") == "YWxsIHlvdXIgYmFzZTY0IGFyZSBiZWxvbmcgdG8gZm9v"); +} + + +uint decodeLength(uint elen) //returns the number of bytes needed to decode an encoded string of this length +{ + return elen / 4 * 3; +} + + +char[] decode(char[] estr, char[] buf) //buf must be large enough to store decoded string +in +{ + assert(buf.length + 2 >= decodeLength(estr.length)); //account for '=' padding +} +body +{ + void badc(char ch) + { + throw new Base64CharException("Invalid base64 character '" ~ (&ch)[0 .. 1] ~ "'"); + } + + + uint arrayIndex(char ch) + out(result) + { + assert(ch == array[result]); + } + body + { + if(ch >= 'A' && ch <= 'Z') + return ch - 'A'; + if(ch >= 'a' && ch <= 'z') + return 'Z' - 'A' + 1 + ch - 'a'; + if(ch >= '0' && ch <= '9') + return 'Z' - 'A' + 1 + 'z' - 'a' + 1 + ch - '0'; + if(ch == '+') + return 'Z' - 'A' + 1 + 'z' - 'a' + 1 + '9' - '0' + 1; + if(ch == '/') + return 'Z' - 'A' + 1 + 'z' - 'a' + 1 + '9' - '0' + 1 + 1; + badc(ch); + } + + + if(!estr.length) + return buf[0 .. 0]; + + if(estr.length % 4) + throw new Base64Exception("Invalid encoded base64 string"); + + uint estri; + uint estrmax = estr.length / 4; + uint x; + char* sp, bp; + char ch; + + sp = &estr[0]; + bp = &buf[0]; + for(estri = 0; estri != estrmax; estri++) + { + x = arrayIndex(*sp++) << 18 | arrayIndex(*sp++) << 12; + + ch = *sp++; + if(ch == '=') + { + if(*sp++ != '=') + badc('='); + *bp++ = x >> 16; + break; + } + x |= arrayIndex(ch) << 6; + + ch = *sp++; + if(ch == '=') + { + *bp++ = x >> 16; + *bp++ = (x >> 8) & 0xFF; + break; + } + x |= arrayIndex(ch); + + *bp++ = x >> 16; + *bp++ = (x >> 8) & 0xFF; + *bp++ = x & 0xFF; + } + + return buf[0 .. (bp - &buf[0])]; +} + + +char[] decode(char[] estr) +{ + return decode(estr, new char[decodeLength(estr.length)]); +} + + +unittest +{ + assert(decode(encode("f")) == "f"); + assert(decode(encode("fo")) == "fo"); + assert(decode(encode("foo")) == "foo"); + assert(decode(encode("foos")) == "foos"); + assert(decode(encode("all your base64 are belong to foo")) == "all your base64 are belong to foo"); + + assert(decode(encode("testing some more")) == "testing some more"); + assert(decode(encode("asdf jkl;")) == "asdf jkl;"); + assert(decode(encode("base64 stuff")) == "base64 stuff"); + assert(decode(encode("\1\2\3\4\5\6\7foo\7\6\5\4\3\2\1!")) == "\1\2\3\4\5\6\7foo\7\6\5\4\3\2\1!"); +} + diff --git a/std/file.d b/std/file.d index d9c92a0bf..0d88a9687 100644 --- a/std/file.d +++ b/std/file.d @@ -52,7 +52,7 @@ private int useWfuncs = 1; static this() { // Win 95, 98, ME do not implement the W functions - useWfuncs = (GetVersion() >= 0x80000000); + useWfuncs = (GetVersion() < 0x80000000); } /******************************************** diff --git a/std/regexp.d b/std/regexp.d index 827c5d409..3b87ab6f0 100644 --- a/std/regexp.d +++ b/std/regexp.d @@ -1,6 +1,6 @@ // Regular Expressions -// Copyright (c) 2000-2003 by Digital Mars +// Copyright (c) 2000-2004 by Digital Mars // All Rights Reserved // Written by Walter Bright // www.digitalmars.com @@ -510,7 +510,7 @@ public tchar[][] exec() public int test(tchar[] string) { - return test(string, pmatch[0].rm_eo); + return test(string, 0 /*pmatch[0].rm_eo*/); } /************************************************ diff --git a/win32.mak b/win32.mak index b0038a6ea..b4b0d6036 100644 --- a/win32.mak +++ b/win32.mak @@ -15,8 +15,8 @@ CP=cp CFLAGS=-g -mn -6 -r -#DFLAGS=-O -release -DFLAGS=-unittest -g +DFLAGS=-O -release +#DFLAGS=-unittest -g CC=sc #DMD=\dmd\bin\dmd @@ -53,8 +53,8 @@ unittest.exe : unittest.d phobos.lib OBJS= asserterror.obj deh.obj switch.obj complex.obj gcstats.obj \ critical.obj object.obj monitor.obj arraycat.obj invariant.obj \ - dmain2.obj outofmemory.obj aaA.obj adi.obj file.obj \ - compiler.obj system.obj moduleinit.obj md5.obj \ + dmain2.obj outofmemory.obj aaA.obj adi.obj aApply.obj file.obj \ + compiler.obj system.obj moduleinit.obj md5.obj base64.obj \ cast.obj syserror.obj path.obj string.obj memset.obj math.obj \ outbuffer.obj ctype.obj regexp.obj random.obj windows.obj \ stream.obj switcherr.obj com.obj array.obj gc.obj \ @@ -78,7 +78,7 @@ SRC= errno.c object.d unittest.d crc32.d gcstats.d SRC_STD= std\zlib.d std\zip.d std\stdint.d std\conv.d std\utf.d std\uri.d \ std\gc.d std\math.d std\string.d std\path.d std\date.d \ std\ctype.d std\file.d std\compiler.d std\system.d std\moduleinit.d \ - std\outbuffer.d std\math2.d std\thread.d std\md5.d \ + std\outbuffer.d std\math2.d std\thread.d std\md5.d std\base64.d \ std\asserterror.d std\dateparse.d std\outofmemory.d \ std\intrinsic.d std\array.d std\switcherr.d std\syserror.d \ std\regexp.d std\random.d std\stream.d std\process.d std\recls.d @@ -111,7 +111,7 @@ SRC_INT= \ internal\arraycat.d internal\invariant.d internal\monitor.c \ internal\memset.d internal\arraycast.d internal\aaA.d internal\adi.d \ internal\dmain2.d internal\cast.d internal\qsort.d internal\deh2.d \ - internal\cmath2.d internal\obj.d internal\mars.h + internal\cmath2.d internal\obj.d internal\mars.h internal\aApply.d SRC_STD_WIN= std\windows\registry.d \ std\windows\iunknown.d @@ -245,6 +245,9 @@ phobos.lib : $(OBJS) minit.obj internal\gc\dmgc.lib etc\c\zlib\zlib.lib \ aaA.obj : internal\aaA.d $(DMD) -c $(DFLAGS) internal\aaA.d +aApply.obj : internal\aApply.d + $(DMD) -c $(DFLAGS) internal\aApply.d + adi.obj : internal\adi.d $(DMD) -c $(DFLAGS) internal\adi.d @@ -298,6 +301,9 @@ array.obj : std\array.d asserterror.obj : std\asserterror.d $(DMD) -c $(DFLAGS) std\asserterror.d +base64.obj : std\base64.d + $(DMD) -c $(DFLAGS) -inline std\base64.d + compiler.obj : std\compiler.d $(DMD) -c $(DFLAGS) std\compiler.d