Index: /trunk/ab5.0/ablib/src/Classes/System/IO/StreamReader.ab
===================================================================
--- /trunk/ab5.0/ablib/src/Classes/System/IO/StreamReader.ab	(revision 654)
+++ /trunk/ab5.0/ablib/src/Classes/System/IO/StreamReader.ab	(revision 655)
@@ -43,13 +43,12 @@
 	*/
 	Override Function Peek() As Long
-		If cur = last Then
-			last = s.Read(buf As *Byte, 0, size)
-			cur = 0
-			If last = 0 Then
+		If charSize = charCur Then
+			fillCharBuf()
+			If charSize = charCur Then
 				Peek = -1
 				Exit Function
 			End If
 		End If
-		Peek = buf[cur]
+		Peek = charBuf[charCur]
 	End Function
 
@@ -61,23 +60,6 @@
 		Read = Peek()
 		If Read <> -1 Then
-			cur++
+			charCur++
 		End If
-	End Function
-
-	/*
-	@date 2008/02/26
-	@auther Egtra
-	*/
-	Override Function ReadToEnd() As String
-		Dim sb = New Text.StringBuilder(65536)
-		sb.Append(buf, cur, last - cur)
-		Do
-			Dim read = Read(buf, 0, size)
-			sb.Append(buf, 0, read)
-			If read < size Then
-				ReadToEnd = sb.ToString
-				Exit Function
-			End If
-		Loop
 	End Function
 
@@ -94,7 +76,4 @@
 		End If
 		s = Nothing
-		size = 0
-		cur = 0
-		last = 0
 	End Sub
 
@@ -103,33 +82,16 @@
 	@auther Egtra
 	*/
-	Override Function ReadImpl(buffer As *Char, index As Long, count As Long) As Long
-		Dim n = last - cur
-		If count <= n Then
-			ReadImpl = ReadFromBuffer(buffer, index, count)
+	Override Function ReadImpl(buffer As *WCHAR, count As Long) As Long
+		Dim n = charSize - charCur '現在のバッファに溜まっている文字数
+		If count <= n And charEof <> False Then
+			ReadImpl = readFromBuffer(buffer, count)
 			Exit Function
 		End If
-		Dim p = VarPtr(buffer[index])
-		ReadImpl = ReadFromBuffer(p, 0, n)
+		ReadImpl = readFromBuffer(buffer, n)
 		If ReadImpl = count Then 'バッファの中身で足りた場合
 			Exit Function
 		End If
-		p = VarPtr(p[n])
-		count -= n
-		If count > size Then
-			n = (count \ size) * size 'sizeの倍数分だけは直接bufferへ読み込ませる
-			Dim read = s.Read(p As *Byte, 0, n)
-			If read = 0 Then 'EOF
-				Exit Function
-			End If
-			p = VarPtr(p[n])
-			ReadImpl += n
-			count -= n
-		End If
-		last = s.Read(buffer As *Byte, 0, size)
-		cur = 0
-		If last = 0 Then 'EOF
-			Exit Function
-		End If
-		ReadImpl += ReadFromBuffer(p, 0, Math.Min(last, count))
+		fillCharBuf()
+		ReadImpl += ReadImpl(VarPtr(buffer[n]), count - n)
 	End Function
 
@@ -141,8 +103,17 @@
 	Sub init(str As Stream)
 		s = str
-		size = 4096
-		last = 0
-		cur = 0
-		buf = GC_malloc(size)
+		'暫定。正式版ではUTF-8を標準とする。
+		encoding = New Text.Detail.WindowsCodePageEncoding(CP_ACP)
+		decoder = encoding.GetDecoder()
+		charCapacity = 4096
+		byteCapacity = 4096
+		charBuf = GC_malloc(charCapacity * SizeOf(WCHAR))
+		byteBuf = GC_malloc(byteCapacity)
+		charCur = 0
+		byteCur = 0
+		charSize = 0
+		byteSize = 0
+		charEof = False
+		byteEof = False
 	End Sub
 
@@ -153,15 +124,50 @@
 	文字数が足りなくても、元のストリームまで読みには行かない。
 	*/
-	Function ReadFromBuffer(p As *Char, index As Long, count As Long) As Long
-		memcpy(VarPtr(p[index]), VarPtr(buf[cur]), count * SizeOf (Char))
-		cur += count
-		ReadFromBuffer = count
+	Function readFromBuffer(p As *WCHAR, count As Long) As Long
+		memcpy(p, VarPtr(charBuf[charCur]), count * SizeOf (WCHAR))
+		charCur += count
+		readFromBuffer = count
 	End Function
 
+	/*!
+	@brief byteBufを基にcharBufを埋める。charBufが空になったときに用いる。
+	@date 2008/11/08
+	@auther Egtra
+	*/
+	Sub fillCharBuf()
+		charCur = 0
+		charSize = 0
+		If charEof = False Then
+			If byteCur = byteSize Then
+				byteSize = s.Read(byteBuf, 0, byteCapacity)
+				byteCur = 0
+				If byteSize = 0 Then
+					byteEof = True
+				End If
+			End If
+			Dim charUsed As Long
+			Dim byteUsed As Long
+			decoder.Convert(VarPtr(byteBuf[byteCur]), byteSize - byteCur,
+				VarPtr(charBuf[charSize]), charCapacity - charSize,
+				byteEof, charUsed, byteUsed, charEof)
+			byteCur += byteUsed
+			charSize += charUsed
+		End If
+	End Sub
+
 	s As Stream
-	size As Long
-	cur As Long
-	last As Long '中身の終わり
-	buf As *SByte '暫定
+	encoding As Text.Encoding
+	decoder As Text.Decoder
+	charBuf As *WCHAR
+	byteBuf As *Byte
+	charCur As Long '読み取っていないデータの開始位置
+	byteCur As Long
+	charSize As Long 'Bufの内、有効なデータの数
+	byteSize As Long
+	charCapacity As Long '確保済み容量 = GC_mallocしたときの引数の値
+	byteCapacity As Long
+	charEof As Boolean 'Trueのとき、次にcur = sizeになるまでしかデータがことを示す
+	byteEof As Boolean
+	'常に0 <= cur <= size <= capacity
 End Class
 
Index: /trunk/ab5.0/ablib/src/Classes/System/IO/StringReader.ab
===================================================================
--- /trunk/ab5.0/ablib/src/Classes/System/IO/StringReader.ab	(revision 654)
+++ /trunk/ab5.0/ablib/src/Classes/System/IO/StringReader.ab	(revision 655)
@@ -23,5 +23,9 @@
 			Throw New ArgumentNullException("str")
 		End If
-		s = str
+		Dim length = GetStr(str, s)
+		If length > LONG_MAX Then
+			Throw New ArgumentException("Must be Length <= LONG_MAX", "str")
+		End If
+		len = length As Long
 		i = 0
 	End Sub
@@ -32,5 +36,5 @@
 	*/
 	Override Function Peek() As Long
-		If i = s.Length Then
+		If i = len Then
 			Peek = -1
 		Else
@@ -44,10 +48,6 @@
 	*/
 	Override Function Read() As Long
-		If i = s.Length Then
-			Read = -1
-		Else
-			Read = s[i]
-			i++
-		End If
+		Read = Peek()
+		i++
 	End Function
 
@@ -56,9 +56,10 @@
 	@auther Egtra
 	*/
+/*
 	Override Function ReadToEnd() As String
 		ReadToEnd = s.Substring(i)
 		i = s.Length
 	End Function
-
+*/
 Protected
 	/*
@@ -75,11 +76,12 @@
 	@auther Egtra
 	*/
-	Override Function ReadImpl(buffer As *Char, index As Long, count As Long) As Long
-		ReadImpl = Math.Min(count, s.Length - i)
-		ActiveBasic.Strings.ChrCopy(VarPtr(buffer[index]) As *Char, (StrPtr(s) + i * SizeOf (Char)) As *Char, ReadImpl As SIZE_T) 'ToDo: ポインタに対する+演算
+	Override Function ReadImpl(buffer As *WCHAR, count As Long) As Long
+		ReadImpl = Math.Min(count, len - i)
+		ActiveBasic.Strings.ChrCopy(buffer, VarPtr(s[i]), ReadImpl As SIZE_T) 'ToDo: ポインタに対する+演算
 	End Function
 
 Private
-	s As String
+	s As *WCHAR
+	len As Long
 	i As Long
 End Class
Index: /trunk/ab5.0/ablib/src/Classes/System/IO/TextReader.ab
===================================================================
--- /trunk/ab5.0/ablib/src/Classes/System/IO/TextReader.ab	(revision 654)
+++ /trunk/ab5.0/ablib/src/Classes/System/IO/TextReader.ab	(revision 655)
@@ -1,12 +1,7 @@
-NameSpace System
-NameSpace IO
+Namespace System
+Namespace IO
 
 Class TextReader
 	Implements System.IDisposable
-
-Public
-'Protected
-	Sub TextReader()
-	End Sub
 Public
 	Virtual Sub ~TextReader()
@@ -31,10 +26,17 @@
 	@auther Egtra
 	*/
-	Function Read(buffer As *Char, index As Long, count As Long) As Long
+	Function Read(buffer As *WCHAR, index As Long, count As Long) As Long
 		If buffer = 0 Then
+			Throw New ArgumentNullException("buffer")
 		ElseIf index < 0 Then
+			Throw New ArgumentOutOfRangeException("index")
 		ElseIf count < 0 Then
+			Throw New ArgumentOutOfRangeException("count")
 		End If
-		Read = ReadImpl(buffer, index, count)
+		Read = ReadImpl(VarPtr(buffer[index]), count)
+	End Function
+
+	Static Function Synchronized(reader As TextReader) As TextReader
+		Synchronized = New Detail.SynchronizedTextReader(reader)
 	End Function
 
@@ -45,9 +47,9 @@
 	@retval 有効なStringインスタンス 読み取った1行
 	*/
-	Virtual Function ReadLine() As String
+	Function ReadLine() As String
 		If Peek() = -1 Then
 			Exit Function
 		End If
-		Dim sb = New Text.StringBuilder(256)
+		Dim sb = New Collections.Generic.List<WCHAR>
 		Do
 			Dim ch = Read()
@@ -69,14 +71,14 @@
 				Case &h0D 'CR
 					Exit Do
-'				Case &h85 'NEL
-'					Exit Do
-'				Case &h2028 'LS
-'					Exit Do
-'				Case &h2029 'PS
-'					Exit Do
+				Case &h85 'NEL
+					Exit Do
+				Case &h2028 'LS
+					Exit Do
+				Case &h2029 'PS
+					Exit Do
 			End Select
-			sb.Append(ch As Char) 'ToDo キャスト不要にすべきというチケットを書くこと
+			sb.Add(ch As WCHAR)
 		Loop
-		ReadLine = sb.ToString
+		ReadLine = New String(sb As *WCHAR, sb.Count)
 	End Function
 	/*
@@ -97,9 +99,8 @@
 	End Function
 
-	Static Function Synchronized(reader As TextReader) As TextReader
-		Synchronized = New Detail.SynchronizedTextReader(reader)
-	End Function
+Protected
+	Sub TextReader()
+	End Sub
 
-Protected
 	Virtual Sub Dispose(disposing As Boolean)
 	End Sub
@@ -109,17 +110,16 @@
 	@auther Egtra
 	*/
-	Virtual Function ReadImpl(buffer As *Char, index As Long, count As Long) As Long
+	Virtual Function ReadImpl(buffer As *WCHAR, count As Long) As Long
 		Dim i As Long
-		Dim p = VarPtr(buffer[index])
 		For i = 0 To ELM(count)
 			Dim c = Read()
 			If c = -1 Then
-				ReadImpl = i - 1
+				ReadImpl = i
 				Exit Function
 			Else
-				p[i] = c As Char
+				buffer[i] = c As Char
 			End If
 		Next
-		ReadImpl = i - 1
+		ReadImpl = i
 	End Function
 End Class
@@ -147,16 +147,4 @@
 	End Function
 
-	Override Function ReadLine() As String
-'		Using lock = cs.Lock
-			ReadLine = base.ReadLine
-'		End Using
-	End Function
-
-	Override Function ReadToEnd() As String
-'		Using lock = cs.Lock
-			ReadToEnd = base.ReadToEnd
-'		End Using
-	End Function
-
 Protected
 	Override Sub Dispose(disposing As Boolean)
@@ -171,7 +159,7 @@
 	End Sub
 
-	Override Function ReadImpl(buffer As *Char, index As Long, count As Long) As Long
+	Override Function ReadImpl(buffer As *WCHAR, count As Long) As Long
 '		Using lock = cs.Lock
-			ReadImpl = base.ReadImpl(buffer, index, count)
+			ReadImpl = base.ReadImpl(buffer, count)
 '		End Using
 	End Function
@@ -183,4 +171,4 @@
 End Namespace
 
-End NameSpace
-End NameSpace
+End Namespace
+End Namespace
Index: /trunk/ab5.0/ablib/src/Classes/System/Text/Encoding.ab
===================================================================
--- /trunk/ab5.0/ablib/src/Classes/System/Text/Encoding.ab	(revision 654)
+++ /trunk/ab5.0/ablib/src/Classes/System/Text/Encoding.ab	(revision 655)
@@ -353,5 +353,5 @@
 		ByRef srcUsed As Long, ByRef dstUsed As Long, ByRef completed As Boolean)
 
-		If src = 0 Then
+		If src = 0 And srcCount > 0 Then
 			Throw New ArgumentNullException("src")
 		ElseIf srcCount < 0 Then
@@ -452,5 +452,5 @@
 		ByRef srcUsed As Long, ByRef dstUsed As Long, ByRef completed As Boolean)
 
-		If src = 0 Then
+		If src = 0 And srcCount > 0 Then
 			Throw New ArgumentNullException("src")
 		ElseIf srcCount < 0 Then
@@ -641,4 +641,5 @@
 
 	Override Function GetBytesCountCore(src As *WCHAR, srcCount As Long, flush As Boolean) As Long
+		GetBytesCountCore = srcCount * 2 + 1 '暫定
 	End Function
 
@@ -658,11 +659,48 @@
 	Override Sub ConvertCore(src As *Byte, srcCount As Long, dst As *WCHAR, dstCount As Long, flush As Boolean,
 		ByRef srcUsed As Long, ByRef dstUsed As Long, ByRef completed As Boolean)
+
+		Dim srcPos = 0 As Long
+		Dim dstPos = 0 As Long
+		If dstCount > 0 And nextByte <> 0 Then
+			Dim buf[1] As CHAR
+			buf[0] = nextByte As CHAR
+			buf[1] = src[1] As CHAR
+			Dim len = MultiByteToWideChar(cp, 0, buf, Len(buf), VarPtr(dst[dstPos]), 10)
+			If len = 0 Then
+				ActiveBasic.Windows.ThrowWithLastError()
+			End If
+			srcPos++
+			dstPos++
+			nextByte = 0
+		End If
+		While srcPos < srcCount And dstPos < srcCount
+			Dim srcCharSize = 1 As Long
+			If IsDBCSLeadByteEx(cp, src[srcPos]) Then
+				srcCharSize = 2
+				If srcPos + 1 = srcCount Then
+					nextByte = src[srcPos]
+					Exit While
+				End If
+			End If
+			'将来的には行毎に変換しMB_USEGLYPHCHARSを使うようにしたい。
+			Dim len = MultiByteToWideChar(cp, 0, VarPtr(src[srcPos]) As *CHAR, srcCharSize, VarPtr(dst[dstPos]), 1)
+			If len = 0 Then
+				ActiveBasic.Windows.ThrowWithLastError()
+			End If
+			srcPos += srcCharSize
+			dstPos++
+		Wend
+		srcUsed = srcPos
+		dstUsed = dstPos
+		completed = (srcPos = srcCount And dstPos = srcCount And nextByte = 0)
 	End Sub
 
 	Override Function GetCharsCountCore(src As *Byte, srcCount As Long, flush As Boolean) As Long
+		GetCharsCountCore = srcCount + 1 '暫定
 	End Function
 
 Private
 	cp As DWord
+	nextByte As Byte
 End Class
 
Index: /trunk/ab5.0/ablib/src/Classes/System/Xml/XmlDocument.ab
===================================================================
--- /trunk/ab5.0/ablib/src/Classes/System/Xml/XmlDocument.ab	(revision 654)
+++ /trunk/ab5.0/ablib/src/Classes/System/Xml/XmlDocument.ab	(revision 655)
@@ -95,16 +95,17 @@
 	/*!
 	@brief	指定したストリームからXML文書を読み込む。
+	@param	reader 読み込むリーダ。
+	*/
+	Virtual Sub Load( reader As System.IO.TextReader )
+		This.RemoveAll()
+		ActiveBasic.Xml.Parser.Parse( reader.ReadToEnd(), This )
+	End Sub
+
+	/*!
+	@brief	指定したストリームからXML文書を読み込む。
 	@param	stream 読み込み先のストリーム。
 	*/
 	Virtual Sub Load( inStream As System.IO.Stream )
-		Dim length = inStream.Length As DWord
-		Dim xmlBuffer = calloc( length + 1 ) As *Char
-		inStream.Read( xmlBuffer As *Byte, 0, length )
-		inStream.Close()
-		Dim xmlString = New String( xmlBuffer )
-		free( xmlBuffer )
-
-		This.RemoveAll()
-		ActiveBasic.Xml.Parser.Parse( xmlString, This )
+		Load( New System.IO.StreamReader( inStream ) )
 	End Sub
 
@@ -114,6 +115,7 @@
 	*/
 	Virtual Sub Load( filename As String )
-		Dim fileStream As System.IO.FileStream( filename, System.IO.FileMode.Open, System.IO.FileAccess.Read )
-		Load( fileStream )
+		Dim r = New System.IO.StreamReader( filename )
+		Load( r )
+		r.Dispose()
 	End Sub
 
@@ -123,7 +125,7 @@
 	*/
 	Virtual Sub Save( outStream As System.IO.Stream )
-		Dim xmlStr = InnerXmlSupportedIndent( True )
-		outStream.Write( xmlStr.StrPtr As *Byte, 0, xmlStr.Length * SizeOf( Char ) )
-		outStream.Close()
+		Dim writer = New IO.StreamWriter( outStream )
+		Save( writer )
+		writer.Flush()
 	End Sub
 
@@ -133,6 +135,7 @@
 	*/
 	Virtual Sub Save( filename As String )
-		Dim fileStream As System.IO.FileStream( filename, System.IO.FileMode.Create, System.IO.FileAccess.Write )
-		Save( fileStream )
+		Dim w = New IO.StreamWriter( filename )
+		Save( w )
+		w.Dispose()
 	End Sub
 
@@ -142,5 +145,5 @@
 	*/
 	Virtual Sub Save( writer As System.IO.TextWriter )
-		writer.Write(InnerXmlSupportedIndent( True ))
+		writer.Write( InnerXmlSupportedIndent( True ) )
 	End Sub
 End Class
