Jypeli  5
The simple game programming library
LoadState.cs
Siirry tämän tiedoston dokumentaatioon.
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Xml;
6 using System.IO;
7 
8 namespace Jypeli
9 {
10  public class LoadState : IDisposable
11  {
12  public StorageFile File { get; private set; }
13 
14  private FileManager manager;
15  private XmlReader reader;
16  private List<String> objectsRead;
17 
18  internal LoadState( FileManager manager, string fileName )
19  {
20  this.manager = manager;
21  File = manager.Open( fileName, false );
22  BeginReadXml();
23  objectsRead = new List<string>();
24  }
25 
26  internal LoadState( StorageFile file, string fileName )
27  {
28  File = file;
29  BeginReadXml();
30  objectsRead = new List<string>();
31  }
32 
33  public void EndLoad()
34  {
35  reader.Close();
36  File.Close();
37  }
38 
39  public void Dispose()
40  {
41  reader.Close();
42  File.Close();
43  }
44 
45  private void ResetFile()
46  {
47  reader.Close();
48  reader = null;
49  objectsRead.Clear();
50 
51  if ( File.Stream.CanSeek )
52  {
53  File.Stream.Seek( 0, System.IO.SeekOrigin.Begin );
54  }
55  else
56  {
57  string fileName = File.Name;
58  File.Close();
59  File = manager.Open( fileName, false );
60  }
61 
62  BeginReadXml();
63  }
64 
65  private void BeginReadXml()
66  {
67  if ( reader != null )
68  return;
69 
70  reader = XmlReader.Create( File.Stream );
71  reader.Read();
72  if ( !reader.IsStartElement( "State" ) ) throw new ArgumentException( "File is corrupted or not a save state file." );
73  }
74 
75  public T Load<T>( T obj, string name )
76  {
77  return (T)Load( obj, typeof( T ), name );
78  }
79 
80  public object Load( object obj, Type type, string name )
81  {
82  if ( objectsRead.Contains( name ) )
83  {
84  // Start from beginning
85  ResetFile();
86  }
87  else
88  BeginReadXml();
89 
90  int depth = 0;
91 
92  while ( !reader.EOF )
93  {
94  reader.Read();
95 
96  if ( reader.NodeType == XmlNodeType.None )
97  throw new IOException( "Error loading object: reader not initialized" );
98 
99  if ( reader.NodeType == XmlNodeType.Element )
100  {
101  if ( depth == 0 )
102  {
103  if ( reader.Name != "Object" )
104  throw new XmlException( "Unexpected element in save state file: " + reader.Name );
105 
106  string objName = reader.GetAttribute( "Name" );
107  if ( string.IsNullOrEmpty( objName ) )
108  throw new XmlException( "Unnamed object in save state file" );
109 
110  if ( name == objName )
111  return File.LoadData( reader, type, obj );
112  else
113  objectsRead.Add( objName );
114  }
115 
116  if ( !reader.IsEmptyElement )
117  depth++;
118  }
119  else if ( reader.NodeType == XmlNodeType.EndElement )
120  {
121  depth--;
122  if ( depth < 0 ) throw new InvalidOperationException( "Error loading object: parse depth < 0" );
123  }
124  }
125 
126  throw new KeyNotFoundException( "Object with name " + name + " could not be found in file " + File.Name );
127  }
128  }
129 }
object Load(object obj, Type type, string name)
Definition: LoadState.cs:80
StorageFile File
Definition: LoadState.cs:12
T Load< T >(T obj, string name)
Definition: LoadState.cs:75
abstract StorageFile Open(string fileName, bool write)
void EndLoad()
Definition: LoadState.cs:33
void Dispose()
Definition: LoadState.cs:39