Mercurial > projects > dwt2
comparison base/src/java/lang/StringBuffer.d @ 120:536e43f63c81
Comprehensive update for Win32/Linux32 dmd-2.053/dmd-1.068+Tango-r5661
===D2===
* added [Try]Immutable/Const/Shared templates to work with differenses in D1/D2 instead of version statements
used these templates to work with strict type storage rules of dmd-2.053
* com.ibm.icu now also compilable with D2, but not tested yet
* small fixes
Snippet288 - shared data is in TLS
===Phobos===
* fixed critical bugs in Phobos implemention
completely incorrect segfault prone fromStringz (Linux's port ruthless killer)
terrible, incorrect StringBuffer realization (StyledText killer)
* fixed small bugs as well
Snippet72 - misprint in the snippet
* implemented missed functionality for Phobos
ByteArrayOutputStream implemented (image loading available)
formatting correctly works for all DWT's cases
As a result, folowing snippets now works with Phobos (Snippet### - what is fixed):
Snippet24, 42, 111, 115, 130, 235, 276 - bad string formatting
Snippet48, 282 - crash on image loading
Snippet163, 189, 211, 213, 217, 218, 222 - crash on copy/cut in StyledText
Snippet244 - hang-up
===Tango===
* few changes for the latest Tango trunc-r5661
* few small performance improvments
===General===
* implMissing-s for only one version changed to implMissingInTango/InPhobos
* incorrect calls to Format in toString-s fixed
* fixed loading \uXXXX characters in ResourceBundle
* added good UTF-8 support for StyledText, TextLayout (Win32) and friends
UTF functions revised and tested. It is now in java.nonstandard.*Utf modules
StyledText and TextLayout (Win32) modules revised for UTF-8 support
* removed small diferences in most identical files in *.swt.* folders
*.swt.internal.image, *.swt.events and *.swt.custom are identical in Win32/Linux32
now 179 of 576 (~31%) files in *.swt.* folders are fully identical
* Win32: snippets now have right subsystem, pretty icons and native system style controls
* small fixes in snippets
Snippet44 - it's not Snippet44
Snippet212 - functions work with different images and offsets arrays
Win32: Snippet282 - crash on close if the button has an image
Snippet293 - setGrayed is commented
and others
Win32: As a result, folowing snippets now works
Snippet68 - color doesn't change
Snippet163, 189, 211, 213, 217, 218, 222 - UTF-8 issues (see above)
Snippet193 - no tabel headers
author | Denis Shelomovskij <verylonglogin.reg@gmail.com> |
---|---|
date | Sat, 09 Jul 2011 15:50:20 +0300 |
parents | fcf926c91ca4 |
children |
comparison
equal
deleted
inserted
replaced
119:d00e8db0a568 | 120:536e43f63c81 |
---|---|
1 module java.lang.StringBuffer; | 1 module java.lang.StringBuffer; |
2 | 2 |
3 import java.lang.util; | 3 import java.lang.util; |
4 import java.lang.exceptions; | |
5 import java.lang.String; | |
4 | 6 |
5 version(Tango){ | 7 version(Tango){ |
6 static import tango.text.Text; | 8 static import tango.text.Text; |
7 static import tango.text.convert.Utf; | 9 static import tango.text.convert.Utf; |
8 } else { // Phobos | 10 } else { // Phobos |
9 static import std.uni; | 11 static import std.outbuffer; |
10 static import std.utf; | 12 static import std.utf; |
11 } | 13 } |
12 | 14 |
13 class StringBuffer : CharSequence { | 15 class StringBuffer : CharSequence { |
14 version(Tango){ | 16 version(Tango){ |
15 alias tango.text.Text.Text!(char) TBuf; | 17 alias tango.text.Text.Text!(char) TBuf; |
16 TBuf buf; | |
17 } else { // Phobos | 18 } else { // Phobos |
18 const int STDINCR = 128; | 19 alias std.outbuffer.OutBuffer TBuf; |
19 char[] buf; | 20 } |
20 int used; | 21 private TBuf buffer; |
21 } | |
22 | 22 |
23 public this(){ | 23 public this(){ |
24 version(Tango){ | 24 buffer = new TBuf(); |
25 buf = new TBuf(); | |
26 } else { // Phobos | |
27 } | |
28 } | 25 } |
29 | 26 |
30 public this( int cap ){ | 27 public this( int cap ){ |
31 version(Tango){ | 28 version(Tango){ |
32 buf = new TBuf(cap); | 29 buffer = new TBuf(cap); |
33 } else { // Phobos | 30 } else { // Phobos |
34 buf.length = cap; | 31 buffer = new TBuf(); |
35 } | 32 buffer.reserve(cap); |
36 } | 33 } |
37 | 34 } |
38 public this( CString content ){ | 35 |
39 version(Tango){ | 36 public this( String content ){ |
40 buf = new TBuf( content ); | 37 version(Tango){ |
41 } else { // Phobos | 38 buffer = new TBuf( content ); |
42 buf.length = content.length + STDINCR; | 39 } else { // Phobos |
43 buf[ 0 .. content.length ] = content; | 40 buffer = new TBuf(); |
44 used = content.length; | 41 append(content); |
45 } | 42 } |
46 } | 43 } |
47 | 44 |
48 char charAt(int index){ | 45 char charAt(int index){ |
49 version(Tango){ | 46 version(Tango){ |
50 return buf.slice()[ index ]; | 47 return buffer.slice()[ index ]; |
51 } else { // Phobos | 48 } else { // Phobos |
52 return buf[ index ]; | 49 return buffer.toBytes()[ index ]; |
53 } | 50 } |
54 } | 51 } |
55 | 52 |
56 int length(){ | 53 int length(){ |
57 version(Tango){ | 54 version(Tango){ |
58 return buf.length(); | 55 return buffer.length(); |
59 } else { // Phobos | 56 } else { // Phobos |
60 return used; | 57 return buffer.offset; |
61 } | 58 } |
62 } | 59 } |
63 | 60 |
64 CharSequence subSequence(int start, int end){ | 61 CharSequence subSequence(int start, int end){ |
65 version(Tango){ | 62 return new StringCharSequence( substring(start, end) ); |
66 return new StringBuffer( buf.slice()[ start .. end ] ); | |
67 } else { // Phobos | |
68 return new StringBuffer( cast(String)buf[ start .. end ] ); | |
69 } | |
70 } | 63 } |
71 | 64 |
72 String toString(){ | 65 String toString(){ |
73 version(Tango){ | 66 version(Tango){ |
74 return buf.slice(); | 67 return buffer.slice().dup; |
75 } else { // Phobos | 68 } else { // Phobos |
76 return cast(String)buf[ 0 .. used ]; | 69 return buffer.toString(); |
77 } | 70 } |
78 } | 71 } |
79 | 72 |
80 StringBuffer append( CString s ){ | 73 StringBuffer append( in char[] s ){ |
81 version(Tango){ | 74 version(Tango){ |
82 buf.append( s ); | 75 buffer.append( s ); |
83 } else { // Phobos | 76 } else { // Phobos |
84 if( buf.length < used + s.length ){ | 77 buffer.write( s ); |
85 buf.length = used + s.length + STDINCR; | |
86 } | |
87 buf[ used .. used + s.length ] = s; | |
88 used += s.length; | |
89 } | 78 } |
90 return this; | 79 return this; |
91 } | 80 } |
92 | 81 |
93 StringBuffer append( CString s, int offset, int len ){ | 82 StringBuffer append( in char[] s, int offset, int len ){ |
94 return append( s[ offset .. offset+len ] ); | 83 return append( s[ offset .. offset+len ] ); |
95 } | 84 } |
96 | 85 |
97 StringBuffer append( StringBuffer other ){ | 86 StringBuffer append( StringBuffer other ){ |
98 return append( other.slice() ); | 87 return append( other.slice() ); |
101 StringBuffer append( Object obj ){ | 90 StringBuffer append( Object obj ){ |
102 return append( obj.toString() ); | 91 return append( obj.toString() ); |
103 } | 92 } |
104 | 93 |
105 StringBuffer append( char c ){ | 94 StringBuffer append( char c ){ |
106 char[1] src; | 95 version(Tango){ |
107 src[0] = c; | 96 char[1] src = c; |
108 return append( cast(String)src ); | 97 return append( src ); |
98 } else { // Phobos | |
99 buffer.write(c); | |
100 return this; | |
101 } | |
109 } | 102 } |
110 | 103 |
111 StringBuffer append( wchar c ){ | 104 StringBuffer append( wchar c ){ |
112 wchar[1] src; | 105 version(Tango){ |
113 src[0] = c; | 106 wchar[1] src = c; |
114 version(Tango){ | 107 char[1 * 2 + 3] trg; // or Tango will reallocate output to input.length * 2 + 3 |
115 char[2] trg; | |
116 auto arr = tango.text.convert.Utf.toString( src, trg ); | 108 auto arr = tango.text.convert.Utf.toString( src, trg ); |
117 } else { // Phobos | 109 return append( arr ); |
118 auto arr = std.utf.toUTF8( src ); | 110 } else { // Phobos |
119 } | 111 char[4] trg; |
120 return append( arr ); | 112 return append( trg[0 .. std.utf.encode(trg, c)] ); |
113 } | |
114 } | |
115 | |
116 StringBuffer append( dchar c ){ | |
117 version(Tango){ | |
118 dchar[1] src = c; | |
119 char[1 * 2 + 4] trg; // or Tango will reallocate output to input.length * 2 + 4 | |
120 auto arr = tango.text.convert.Utf.toString( src, trg ); | |
121 return append( arr ); | |
122 } else { // Phobos | |
123 char[4] trg; | |
124 return append( trg[0 .. std.utf.encode(trg, c)] ); | |
125 } | |
121 } | 126 } |
122 | 127 |
123 StringBuffer append( bool i ){ | 128 StringBuffer append( bool i ){ |
124 return append( String_valueOf(i) ); | 129 return append( String_valueOf(i) ); |
125 } | 130 } |
130 | 135 |
131 StringBuffer append( long i ){ | 136 StringBuffer append( long i ){ |
132 return append( String_valueOf(i) ); | 137 return append( String_valueOf(i) ); |
133 } | 138 } |
134 | 139 |
135 StringBuffer append( dchar c ){ | 140 StringBuffer replace(int start, int end, in char[] str) { |
136 dchar[1] src; | 141 if(start < 0 || start > length() || start > end) |
137 src[0] = c; | 142 throw new StringIndexOutOfBoundsException("start is negative, greater than length(), or greater than end"); |
138 version(Tango){ | 143 |
139 char[4] trg; | 144 version(Tango){ |
140 auto arr = tango.text.convert.Utf.toString( src, trg ); | 145 buffer.select(start, end-start); |
141 } else { // Phobos | 146 buffer.replace(str); |
142 auto arr = std.utf.toUTF8( src ); | 147 buffer.select(); |
143 } | 148 } else { // Phobos |
144 return append( arr ); | 149 if(end >= length()) { |
145 } | 150 buffer.offset = start; |
146 | 151 return append(str); |
147 | 152 } |
153 int strEnd = start + str.length, incr = strEnd - end; | |
154 | |
155 if( incr > 0 ) { | |
156 buffer.spread(end, incr); | |
157 } | |
158 else if( incr < 0 ) { | |
159 auto bytes = buffer.toBytes(); | |
160 bytes[ start .. strEnd ] = cast(ubyte[])str; | |
161 foreach (i, b; bytes[ end .. $ ]) { | |
162 bytes[strEnd + i] = bytes[end + i]; | |
163 } | |
164 buffer.offset += incr; | |
165 } | |
166 buffer.toBytes()[ start .. strEnd ] = cast(ubyte[])str; | |
167 } | |
168 return this; | |
169 } | |
170 | |
171 StringBuffer insert(int offset, in char[] str){ | |
172 return replace( offset, offset, str ); | |
173 } | |
174 | |
148 StringBuffer insert(int offset, int i){ | 175 StringBuffer insert(int offset, int i){ |
149 return insert( offset, String_valueOf(i) ); | 176 return insert( offset, String_valueOf(i) ); |
150 } | 177 } |
151 StringBuffer insert(int offset, CString str){ | |
152 return replace( offset, offset, str ); | |
153 } | |
154 | 178 |
155 StringBuffer insert(int offset, StringBuffer other){ | 179 StringBuffer insert(int offset, StringBuffer other){ |
156 return insert( offset, other.slice()); | 180 return insert( offset, other.slice() ); |
157 } | |
158 | |
159 StringBuffer replace(int start, int end, CString str) { | |
160 version(Tango){ | |
161 buf.select(start, end-start); | |
162 buf.replace(str); | |
163 buf.select(); | |
164 } else { // Phobos | |
165 int incr = end - start - str.length; | |
166 if( incr > 0 ){ | |
167 if( buf.length < used + incr ){ | |
168 char[] newbuf = new char[ 2*(used + incr) + STDINCR ]; | |
169 newbuf[ 0 .. start ] = buf[ 0 .. start ]; | |
170 newbuf[ start .. start + str.length ] = str; | |
171 newbuf[ start + str.length .. used + str.length ] = buf[ end .. used ]; | |
172 buf = newbuf; | |
173 } | |
174 else{ | |
175 char* s = buf.ptr + start; | |
176 char* t = buf.ptr + start + str.length; | |
177 char* e = buf.ptr + start + str.length; | |
178 while( s !is e ){ | |
179 *t = *s; | |
180 s++; t++; | |
181 } | |
182 buf[ start .. start + str.length ] = str; | |
183 } | |
184 } | |
185 else if( incr == 0 ){ | |
186 buf[ start .. end ] = str; | |
187 } | |
188 else{ | |
189 buf[ start .. end ] = str; | |
190 char* s = buf.ptr + end; | |
191 char* t = buf.ptr + start + str.length; | |
192 char* e = buf.ptr + start + str.length; | |
193 while( s !is e ){ | |
194 *t = *s; | |
195 s--; t--; | |
196 } | |
197 } | |
198 used += incr; | |
199 } | |
200 return this; | |
201 } | 181 } |
202 | 182 |
203 void setLength( int newLength ){ | 183 void setLength( int newLength ){ |
204 version(Tango){ | 184 if(newLength < 0) |
205 buf.truncate( newLength ); | 185 throw new IndexOutOfBoundsException("the newLength argument is negative"); |
206 } else { // Phobos | 186 |
207 if( buf.length < newLength ){ | 187 version(Tango){ |
208 buf.length = 2*newLength + STDINCR; | 188 buffer.truncate( newLength ); |
209 } | 189 } else { // Phobos |
210 used = newLength; | 190 immutable d = newLength - length(); |
191 if( d > 0 ) | |
192 buffer.reserve(d); | |
193 else | |
194 buffer.offset += d; | |
211 } | 195 } |
212 } | 196 } |
213 | 197 |
214 String substring( int start, int end ){ | 198 String substring( int start, int end ){ |
215 version(Tango){ | 199 if(start < 0 || end < 0 || end > length() || start > end) |
216 return buf.slice()[ start .. end ].dup; | 200 throw new StringIndexOutOfBoundsException("start or end are negative, if end is greater than length(), or if start is greater than end"); |
217 } else { // Phobos | 201 |
218 return buf[ start .. end ].idup; | 202 version(Tango){ |
203 return buffer.slice()[ start .. end ].dup; | |
204 } else { // Phobos | |
205 return (cast(char[]) buffer.toBytes()[ start .. end ]).idup; | |
219 } | 206 } |
220 } | 207 } |
221 | 208 |
222 void delete_( int start, int end ){ | 209 void delete_( int start, int end ){ |
223 replace( start, end, "" ); | 210 replace( start, end, "" ); |
224 } | 211 } |
225 String slice(){ | 212 |
226 version(Tango){ | 213 TryConst!(char)[] slice(){ |
227 return buf.slice(); | 214 version(Tango){ |
228 } else { // Phobos | 215 return buffer.slice(); |
229 return cast(String)buf[ 0 .. used ]; | 216 } else { // Phobos |
230 } | 217 return cast(TryConst!(char)[]) buffer.toBytes(); |
231 } | 218 } |
219 } | |
220 | |
232 void truncate( int start ){ | 221 void truncate( int start ){ |
233 setLength( start ); | 222 setLength( start ); |
234 } | 223 } |
235 } | 224 } |
236 | 225 |