Index: /trunk/Include/Classes/ActiveBasic/Xml/Parser.ab
===================================================================
--- /trunk/Include/Classes/ActiveBasic/Xml/Parser.ab	(revision 464)
+++ /trunk/Include/Classes/ActiveBasic/Xml/Parser.ab	(revision 465)
@@ -3,8 +3,285 @@
 
 
+Class ParserException
+	Inherits System.Exception
+Public
+	Sub ParserException( message As String )
+		Exception( message )
+	End Sub
+End Class
+
 Class Parser
+	xmlString As String
+	currentIndex As Long
+
+	doc As System.Xml.XmlDocument
+
+	Static Const tokenLPar = &H3C		' <
+	Static Const tokenRPar = &H3E		' >
+	Static Const tokenSlash = &H2F	' /
+	Static Const xmlHeaderStr = "<?xml"
+	Static Const commentHeader = "<!--"
+	Static Const cdataHeader = "<![CDATA["
+	Static Const dtdHeader = "<!"
+	Static Const versionAttributeName = "version"
+	Static Const encodingAttributeName = "encoding"
+
+	Static Function IsAlpha( c As Char ) As Boolean
+		Return ( &H41 <= c and c <= &H5A or &H61 <= c and c <= &H7A )
+	End Function
+
+	Static Function IsUnderscore( c As Char ) As Boolean
+		Return ( c = &H5F )
+	End Function
+
+	Static Function IsNumber( c As Char ) As Boolean
+		Return ( &H30 <= c and c <= &H39 )
+	End Function
+
+	Static Function IsWhiteSpace( c As Char ) As Boolean
+		If c = &H20 Then
+			' 空白
+			Return True
+		ElseIf c = &H09 Then
+			' タブ文字
+			Return True
+		ElseIf c = &H0A or c = &H0D Then
+			' 改行
+			Return True
+		End If
+		' その他
+		Return False
+	End Function
+
+	Sub ts()
+		MessageBox(0,xmlString.Substring(currentIndex),"test",0)
+	End Sub
+
+	Function StringWordEquals( src As String ) As Boolean
+		Dim nextChar = xmlString[currentIndex + src.Length] As Char
+		Return ( xmlString.Substring( currentIndex, src.Length ) = src and Not (IsAlpha( nextChar ) or IsUnderscore( nextChar ) or IsNumber( nextChar ) ) )
+	End Function
+
+	Function ReadName() As String
+		Dim startIndex = currentIndex
+
+		Dim c = xmlString[currentIndex] As Char
+
+		If Not( IsAlpha( c ) or IsUnderscore( c ) ) Then
+			Throw New ParserException( Ex"タグ名がアルファベットまたはアンダースコアから始まっていない" )
+		End If
+
+		While IsAlpha( c ) or IsUnderscore( c ) or IsNumber( c )
+			currentIndex++
+			c = xmlString[currentIndex] As Char
+		Wend
+
+		Return xmlString.Substring( startIndex, currentIndex - startIndex )
+	End Function
+
+	Function ReadStringInDoubleQuotes() As String
+		' '\"'分を進める
+		currentIndex++
+
+		Dim startIndex = currentIndex
+		Dim endIndex = 0 As Long
+
+		Do
+			If xmlString[currentIndex] = 0 Then
+				Throw New ParserException( Ex"属性の値の閉じ側のダブルクォートが存在しない" )
+			End If
+
+			If xmlString[currentIndex] = &H and xmlString[currentIndex+1] = &H22 Then
+				' エスケープシーケンス付きのダブルクォートは無視
+				currentIndex += 2
+				Continue
+			End If
+
+			If xmlString[currentIndex] = &H22 Then	' '\"'
+				' 閉じ側のダブルクォート
+				endIndex = currentIndex
+				currentIndex++
+				Exit Do
+			End If
+
+			currentIndex++
+		Loop
+
+		Return xmlString.Substring( startIndex, endIndex - startIndex )
+	End Function
+
+	Function ReadAttribute() As System.Xml.XmlAttribute
+		Dim attributeName = ReadName()
+		SkipWhiteSpace()
+
+		Dim atr = doc.CreateAttribute( attributeName )
+
+		If Not xmlString[currentIndex] = &H3D Then	' '='
+			Return atr
+		End If
+
+		currentIndex++ ' '='分を進める
+		SkipWhiteSpace()
+
+		If Not xmlString[currentIndex] = &H22 Then	'\"'
+			Throw New ParserException( Ex"属性の値がダブルクォートで囲まれていない" )
+		End If
+
+		atr.Value = ReadStringInDoubleQuotes()
+
+		Return atr
+	End Function
+
+	Function ReadTextArea() As String
+		Dim startIndex = currentIndex
+
+		While Not ( xmlString[currentIndex] = tokenLPar or xmlString[currentIndex] = 0 )
+			currentIndex++
+		Wend
+
+		Return xmlString.Substring( startIndex, currentIndex - startIndex )
+	End Function
+
+	Sub SkipWhiteSpace()
+		While IsWhiteSpace( xmlString[currentIndex] )
+			currentIndex++
+		Wend
+	End Sub
+
+	Function ParseDeclaration() As System.Xml.XmlDeclaration
+		Dim versionStr = Nothing As String
+		Dim encodingStr = Nothing As String
+		currentIndex += xmlHeaderStr.Length
+
+		SkipWhiteSpace()
+
+		Do
+			If xmlString[currentIndex] = 0 Then
+				Throw New ParserException( Ex"タグの閉じ括弧が見つからない" )
+			End If
+			If xmlString[currentIndex] = tokenRPar Then
+				currentIndex ++
+				Exit Do
+			End If
+
+			currentIndex ++
+		Loop
+
+		Return doc.CreateXmlDeclaration( "1.0", "shift-jis", Nothing )
+	End Function
+	Function ParseComment() As System.Xml.XmlNode
+	End Function
+	Function ParseCData() As System.Xml.XmlNode
+	End Function
+	Function ParseDtd() As System.Xml.XmlNode
+	End Function
+	Function ParseElement() As System.Xml.XmlElement
+		' '<'分を進める
+		currentIndex++
+
+		' タグ名を取得し、要素を作成
+		Dim name = ReadName()
+		Dim xmlElement = doc.CreateElement( name )
+
+		SkipWhiteSpace()
+
+		Do
+			If xmlString[currentIndex] = 0 Then
+				Throw New ParserException( Ex"タグの閉じ括弧が見つからない" )
+			End If
+			If xmlString[currentIndex] = tokenRPar or ( xmlString[currentIndex] = tokenSlash and xmlString[currentIndex+1] = tokenRPar ) Then
+				Exit Do
+			End If
+
+			' 属性を取得し、要素に追加
+			xmlElement.Attributes.Add( ReadAttribute() )
+
+			SkipWhiteSpace()
+		Loop
+
+		Dim closeTagStr = "</" + xmlElement.LocalName + ">"
+
+		If xmlString[currentIndex] = tokenRPar Then	' '>'
+			' ">" で閉じられている
+			currentIndex ++
+
+			Do
+				SkipWhiteSpace()
+
+				If xmlString[currentIndex] = 0 Then
+					Throw New ParserException( xmlElement.LocalName + Ex"の閉じタグが見つからない" )
+				End If
+
+				If xmlString[currentIndex] = tokenLPar Then	' '<'
+					' タグ
+					If StringWordEquals( closeTagStr ) Then
+						' タグが閉じられた
+						currentIndex += closeTagStr.Length
+						Exit Do
+					End If
+
+					xmlElement.AppendChild( ParseNode() )
+				Else
+					' タグ以外
+					xmlElement.AppendChild( doc.CreateTextNode( ReadTextArea() ) )
+				End If
+			Loop
+		Else
+			' "/>" で閉じられている
+			currentIndex += 2
+		End If
+
+		Return xmlElement
+	End Function
+
+	Function ParseNode() As System.Xml.XmlNode
+		If Not xmlString[currentIndex] = tokenLPar Then
+			' "<" で開始できないとき
+			Throw New ParserException( Ex"\q<\q で開始できない" )
+		End If
+
+		If StringWordEquals( xmlHeaderStr ) Then
+			' XMLヘッダ
+			Return ParseDeclaration()
+		ElseIf StringWordEquals( commentHeader ) Then
+			' コメントヘッダ
+			Return ParseComment()
+		ElseIf StringWordEquals( cdataHeader ) Then
+			' CDATAヘッダ
+			Return ParseCData()
+		ElseIf StringWordEquals( dtdHeader ) Then
+			' DTDヘッダ
+			Return ParseDtd()
+		Else
+			' その他のタグ
+			Return ParseElement()
+		End If
+	End Function
+
 Public
-	Static Function Parse( xmlString As String, doc As System.Xml.XmlDocument ) As Boolean
-	End Function
+
+	Sub Parser( xmlString As String, doc As System.Xml.XmlDocument )
+		This.xmlString = xmlString
+		This.doc = doc
+	End Sub
+
+	Sub Parse()
+		This.currentIndex = 0
+		This.doc.RemoveAll()
+
+		SkipWhiteSpace()
+
+		While currentIndex < xmlString.Length
+
+			This.doc.AppendChild( ParseNode() )
+
+			SkipWhiteSpace()
+		Wend
+	End Sub
+
+	Static Sub Parse( xmlString As String, doc As System.Xml.XmlDocument )
+		Dim parser = New Parser( xmlString, doc )
+		parser.Parse()
+	End Sub
 End Class
 
Index: /trunk/TestCase/SimpleTestCase/SerializeTest.ab
===================================================================
--- /trunk/TestCase/SimpleTestCase/SerializeTest.ab	(revision 465)
+++ /trunk/TestCase/SimpleTestCase/SerializeTest.ab	(revision 465)
@@ -0,0 +1,56 @@
+Namespace SerializeTest
+
+Class Foo
+	a As Long
+	b As Long
+	c As Long
+	d As Long
+Public
+	Sub Foo()
+		a=100
+		b=200
+		c=300
+		d=400
+	End Sub
+End Class
+
+Sub TestMain()
+	' 一時ディレクトリを取得
+	Dim tempDir = GetExclusiveTempDirPath( "SerializeTest" )
+
+	' fooインスタンスを生成
+	Dim foo = New Foo
+
+
+	'----------------------------------------------------------------
+	' シリアライズ
+	'----------------------------------------------------------------
+
+	' 保存先のファイルを開いて、
+	Dim fooXmlFilePath = tempDir + "\foo.xml"
+	Dim fs = New System.IO.FileStream( fooXmlFilePath, System.IO.FileMode.Create )
+
+	' シリアライズして、
+	Dim serializer = New System.Xml.Serialization.XmlSerializer( foo.GetType() )
+	serializer.Serialize( fs, foo )
+
+	' 閉じる。
+	fs.Close()
+
+
+	'----------------------------------------------------------------
+	' デシリアライズ
+	'----------------------------------------------------------------
+
+	' 読み込んでみる。
+	Dim doc = New System.Xml.XmlDocument
+	doc.Load( tempDir + "\foo.xml" )
+	System.Diagnostics.Debug.WriteLine( doc.OuterXml )
+
+	' TODO: デシリアライズは未完成(￣□￣；)
+End Sub
+
+
+End Namespace
+
+SerializeTest.TestMain()
Index: /trunk/TestCase/SimpleTestCase/SimpleTestCase.ab
===================================================================
--- /trunk/TestCase/SimpleTestCase/SimpleTestCase.ab	(revision 464)
+++ /trunk/TestCase/SimpleTestCase/SimpleTestCase.ab	(revision 465)
@@ -4,4 +4,18 @@
 
 Dim hStdOut = _System_hConsoleOut
+
+Sub Initialize()
+	' 初期化関数
+
+	' 一時ディレクトリを空にしておく
+	Dim tempDir = System.IO.Path.GetDirectoryName( System.Windows.Forms.Application.ExecutablePath ) + "\temp"
+	If System.IO.Directory.Exists( tempDir ) Then
+		' 存在するときは一旦消す
+		System.IO.Directory.Delete( tempDir, True )
+	End If
+	System.IO.Directory.CreateDirectory( tempDir )
+End Sub
+
+Initialize()
 
 Dim csbi As CONSOLE_SCREEN_BUFFER_INFO
@@ -40,4 +54,16 @@
 End Sub
 
+Function GetExclusiveTempDirPath( testCaseName As String ) As String
+	Dim tempDir = System.IO.Path.GetDirectoryName( System.Windows.Forms.Application.ExecutablePath ) + "\temp"
+	Dim exclusiveTempDirPath = tempDir + "\" + testCaseName
+
+	If Not System.IO.Directory.Exists( exclusiveTempDirPath ) Then
+		' 無かったら作る
+		System.IO.Directory.CreateDirectory( exclusiveTempDirPath )
+	End If
+
+	Return exclusiveTempDirPath
+End Function
+
 Print "Please Enter key"
 System.Console.ReadLine()
Index: /trunk/TestCase/SimpleTestCase/SimpleTestCase.idx
===================================================================
--- /trunk/TestCase/SimpleTestCase/SimpleTestCase.idx	(revision 464)
+++ /trunk/TestCase/SimpleTestCase/SimpleTestCase.idx	(revision 465)
@@ -38,6 +38,4 @@
 #include "XmlTest.ab"
 _ClearNamespaceImported
-
-'リソースファイル
-#include "resource.ab"
-#resource "SimpleTestCase.rc"
+#include "SerializeTest.ab"
+_ClearNamespaceImported
Index: /trunk/TestCase/SimpleTestCase/SimpleTestCase.pj
===================================================================
--- /trunk/TestCase/SimpleTestCase/SimpleTestCase.pj	(revision 464)
+++ /trunk/TestCase/SimpleTestCase/SimpleTestCase.pj	(revision 465)
@@ -23,5 +23,5 @@
 #DEBUG_EXE_PATH=
 
-#RESOURCE=SimpleTestCase.rc
+#RESOURCE=0
 
 #SOURCE
@@ -44,2 +44,3 @@
 StreamTest.ab
 XmlTest.ab
+SerializeTest.ab
Index: /trunk/TestCase/SimpleTestCase/XmlTest.ab
===================================================================
--- /trunk/TestCase/SimpleTestCase/XmlTest.ab	(revision 464)
+++ /trunk/TestCase/SimpleTestCase/XmlTest.ab	(revision 465)
@@ -3,6 +3,9 @@
 
 Sub TestMain()
+	' 一時ディレクトリを取得
+	Dim tempDir = GetExclusiveTempDirPath( "XmlTest" )
+
 	Dim doc = New System.Xml.XmlDocument()
-	doc.AppendChild( doc.CreateXmlDeclaration( "1.0", "UTF-8", Nothing ) )
+	doc.AppendChild( doc.CreateXmlDeclaration( "1.0", "shift-jis", Nothing ) )
 	doc.AppendChild( doc.CreateElement( "root" ) )
 	doc.ChildNodes[1].AppendChild( doc.CreateElement( "test" ) )
@@ -15,5 +18,13 @@
 	doc.ChildNodes[1].Attributes.Add( attr2 )
 
-	System.Diagnostics.Debug.WriteLine( doc.OuterXml() )
+	' 書いて
+	doc.Save( tempDir + "\test.xml" )
+
+	' 読んで
+	Dim clone = New System.Xml.XmlDocument
+	clone.Load( tempDir + "\test.xml" )
+
+	' 比較してみる
+	UnitTest( "XmlTest", doc.OuterXml = clone.OuterXml )
 End Sub
 
