ArrayList assemblies;
ArrayList dependencies;
Hashtable anames;
- string privateBinPath;
string baseDir;
string baseVDir;
#if !NET_2_0
CompilationConfiguration compilationConfig;
-#else
+#endif
+
+#if NET_2_0
TextReader reader;
#endif
+
int appAssemblyIndex = -1;
Type cachedType;
protected SimpleWebHandlerParser (HttpContext context, string virtualPath, string physicalPath)
+ : this (context, virtualPath, physicalPath, null)
+ {}
+
+ internal SimpleWebHandlerParser (HttpContext context, string virtualPath, string physicalPath, TextReader reader)
{
+#if NET_2_0
+ this.reader = reader;
+#endif
cachedType = CachingCompiler.GetTypeFromCache (physicalPath);
if (cachedType != null)
return; // We don't need anything else.
- this.context = context;
+ // context is obsolete in 2.0+ - MSDN recommends passing null, so we need to
+ // take that into account
+ if (context != null)
+ this.context = context;
+ else
+ this.context = HttpContext.Current;
+
this.vPath = virtualPath;
- this.physPath = physicalPath;
- AddDependency (physicalPath);
+ AddDependency (virtualPath);
+
+ // physicalPath is obsolete in 2.0+ - same note what for context applies here
+ if (physicalPath != null && physicalPath.Length > 0)
+ this.physPath = physicalPath;
+ else {
+ HttpRequest req = this.context != null ? context.Request : null;
+ if (req != null)
+ this.physPath = req.MapPath (virtualPath);
+ }
assemblies = new ArrayList ();
string location = Context.ApplicationInstance.AssemblyLocation;
GetDirectivesAndContent ();
}
-#if NET_2_0
- internal SimpleWebHandlerParser (HttpContext context, string virtualPath, string physicalPath, TextReader reader)
- : this (context, virtualPath, physicalPath)
- {
- this.reader = reader;
- }
-#endif
protected Type GetCompiledTypeFromCache ()
{
{
string line;
bool directiveFound = false;
+ bool inDirective = false;
+ StringBuilder directive = null;
StringBuilder content = new StringBuilder ();
- using (StreamReader reader = new StreamReader (File.OpenRead (physPath))) {
- while ((line = reader.ReadLine ()) != null && cachedType == null) {
- string trimmed = line.Trim ();
- if (!directiveFound && trimmed == String.Empty)
+ int idxStart, idxEnd, length;
+ StreamReader sr;
+
+#if NET_2_0
+ if (reader != null)
+ sr = reader as StreamReader;
+ else
+#endif
+ sr = new StreamReader (File.OpenRead (physPath), WebEncoding.FileEncoding);
+
+ using (sr) {
+ while ((line = sr.ReadLine ()) != null && cachedType == null) {
+ length = line.Length;
+ if (length == 0) {
+ content.Append ("\n");
continue;
+ }
+
+ idxStart = line.IndexOf ("<%");
+ if (idxStart > -1) {
+ idxEnd = line.IndexOf ("%>");
+ if (idxStart > 0)
+ content.Append (line.Substring (0, idxStart));
+
+ if (directive == null)
+ directive = new StringBuilder ();
+ else
+ directive.Length = 0;
+
+ if (idxEnd > -1) {
+ directiveFound = true;
+ inDirective = false;
+ directive.Append (line.Substring (idxStart, idxEnd - idxStart + 2));
+ if (idxEnd < length - 2)
+ content.Append (line.Substring (idxEnd + 2, length - idxEnd - 2));
+ } else {
+ inDirective = true;
+ directiveFound = false;
+ directive.Append (line.Substring (idxStart));
+ continue;
+ }
+ }
+
+ if (inDirective) {
+ int idx = line.IndexOf ("%>");
+ if (idx > -1) {
+ directive.Append (line.Substring (0, idx + 2));
+ if (idx < length)
+ content.Append (line.Substring (idx + 2) + "\n");
+ inDirective = false;
+ directiveFound = true;
+ } else {
+ directive.Append (line);
+ continue;
+ }
+ }
- if (trimmed.StartsWith ("<")) {
- ParseDirective (trimmed);
- directiveFound = true;
+ if (directiveFound) {
+ ParseDirective (directive.ToString ());
+ directiveFound = false;
if (gotDefault) {
cachedType = CachingCompiler.GetTypeFromCache (physPath);
if (cachedType != null)
}
content.Append (line + "\n");
- content.Append (reader.ReadToEnd ());
}
+ directive = null;
}
if (!gotDefault)
if (tagtype != System.Web.Compilation.TagType.Directive)
throw new ParseException (location, "Unexpected tag");
- if (String.Compare (tagid, DefaultDirectiveName, true) == 0) {
+ if (tagid == null || tagid.Length == 0 || String.Compare (tagid, DefaultDirectiveName, true) == 0) {
AddDefaultDirective (location, attributes);
} else if (String.Compare (tagid, "Assembly", true) == 0) {
AddAssemblyDirective (location, attributes);
void ParseDirective (string line)
{
- AspParser parser = new AspParser (physPath, new StringReader (line));
+ AspParser parser;
+
+ using (StringReader input = new StringReader (line)) {
+ parser = new AspParser (physPath, input);
+ }
+
parser.Error += new ParseErrorHandler (ParseError);
parser.TagParsed += new TagParsedHandler (TagParsed);
parser.TextParsed += new TextParsedHandler (TextParsed);
internal virtual void AddDefaultDirective (ILocation location, TagAttributes attrs)
{
+#if NET_2_0
+ CompilationSection compConfig;
+#else
+ CompilationConfiguration compConfig;
+#endif
+ compConfig = CompilationConfig;
+
if (gotDefault)
throw new ParseException (location, "duplicate " + DefaultDirectiveName + " directive");
debug = (String.Compare (d, "true", true) == 0);
if (debug == false && String.Compare (d, "false", true) != 0)
throw new ParseException (null, "Invalid value for Debug attribute");
- }
+ } else
+ debug = compConfig.Debug;
language = GetAndRemove (attributes, "language");
if (language == null)
- language = CompilationConfig.DefaultLanguage;
+ language = compConfig.DefaultLanguage;
GetAndRemove (attributes, "codebehind");
if (attributes.Count > 0)
internal virtual void AddAssembly (Assembly assembly, bool fullPath)
{
+ if (assembly == null)
+ throw new ArgumentNullException ("assembly");
+
if (anames == null)
anames = new Hashtable ();
return assembly;
}
+ Exception ex = null;
try {
assembly = Assembly.LoadWithPartialName (name);
} catch (Exception e) {
- throw new ParseException (location, "Assembly " + name + " not found", e);
+ ex = e;
+ assembly = null;
}
+ if (assembly == null)
+ throw new ParseException (location, String.Format ("Assembly '{0}' not found", name), ex);
+
AddAssembly (assembly, true);
return assembly;
}
void AddAssembliesInBin ()
{
- if (!Directory.Exists (PrivateBinPath))
- return;
-
- string [] binDlls = Directory.GetFiles (PrivateBinPath, "*.dll");
- foreach (string dll in binDlls) {
+ foreach (string s in HttpApplication.BinDirectoryAssemblies) {
try {
- Assembly assembly = Assembly.LoadFrom (dll);
+ Assembly assembly = Assembly.LoadFrom (s);
AddAssembly (assembly, true);
} catch (Exception e) {
- throw new Exception ("Error while loading " + dll, e);
+ throw new Exception ("Error while loading " + s, e);
}
}
}
Assembly LoadAssemblyFromBin (string name)
{
- Assembly assembly;
- if (!Directory.Exists (PrivateBinPath))
- return null;
-
- string [] binDlls = Directory.GetFiles (PrivateBinPath, "*.dll");
- foreach (string dll in binDlls) {
+ Assembly assembly = null;
+ foreach (string dll in HttpApplication.BinDirectoryAssemblies) {
string fn = Path.GetFileName (dll);
fn = Path.ChangeExtension (fn, null);
if (fn != name)
assembly = Assembly.LoadFrom (dll);
return assembly;
}
-
+
return null;
}
if (!File.Exists (realPath))
throw new ParseException (location, "File " + vpath + " not found");
- AddDependency (realPath);
+ AddDependency (vpath);
CompilerResults result = CachingCompiler.Compile (language, realPath, realPath, assemblies);
if (result.NativeCompilerReturnValue != 0) {
- StreamReader reader = new StreamReader (realPath);
- throw new CompilationException (realPath, result.Errors, reader.ReadToEnd ());
+ using (StreamReader sr = new StreamReader (realPath)) {
+ throw new CompilationException (realPath, result.Errors, sr.ReadToEnd ());
+ }
}
AddAssembly (result.CompiledAssembly, true);
return result.CompiledAssembly;
}
- internal Type GetTypeFromBin (string typeName)
+ internal Type GetTypeFromBin (string tname)
{
+ if (tname == null || tname.Length == 0)
+ throw new ArgumentNullException ("tname");
+
Type result = null;
+ string typeName;
+ string assemblyName;
+ int comma = tname.IndexOf (',');
+
+ if (comma != -1) {
+ typeName = tname.Substring (0, comma).Trim ();
+ assemblyName = tname.Substring (comma + 1).Trim ();
+ } else {
+ typeName = tname;
+ assemblyName = null;
+ }
+
+ Type type = null;
+ Assembly assembly = null;
+ if (assemblyName != null) {
+ assembly = Assembly.Load (assemblyName);
+ if (assembly != null)
+ type = assembly.GetType (typeName, false);
+ if (type != null)
+ return type;
+ }
+
#if NET_2_0
IList toplevelAssemblies = BuildManager.TopLevelAssemblies;
if (toplevelAssemblies != null && toplevelAssemblies.Count > 0) {
foreach (Assembly asm in toplevelAssemblies) {
- Type type = asm.GetType (typeName, false);
+ type = asm.GetType (typeName, false);
if (type != null) {
if (result != null)
throw new HttpException (String.Format ("Type {0} is not unique.", typeName));
+ result = type;
}
- result = type;
}
}
#endif
- if (!Directory.Exists (PrivateBinPath))
- if (result == null)
- throw new HttpException (String.Format ("Type {0} not found.", typeName));
- else
- return result;
-
- string [] binDlls = Directory.GetFiles (PrivateBinPath, "*.dll");
- foreach (string dll in binDlls) {
- Assembly assembly = Assembly.LoadFrom (dll);
- Type type = assembly.GetType (typeName, false);
+
+ foreach (string dll in HttpApplication.BinDirectoryAssemblies) {
+ assembly = Assembly.LoadFrom (dll);
+ type = assembly.GetType (typeName, false);
if (type != null) {
if (result != null)
throw new HttpException (String.Format ("Type {0} is not unique.", typeName));
-
+
result = type;
- }
+ }
}
+
if (result == null)
throw new HttpException (String.Format ("Type {0} not found.", typeName));
}
internal string Program {
- get { return program; }
+ get {
+ if (program != null)
+ return program;
+
+ return String.Empty;
+ }
}
internal ArrayList Assemblies {
get { return dependencies; }
}
- internal string PrivateBinPath {
- get {
- if (privateBinPath != null)
- return privateBinPath;
-
- AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation;
- privateBinPath = setup.PrivateBinPath;
-
- if (!Path.IsPathRooted (privateBinPath)) {
- string appbase = setup.ApplicationBase;
- if (appbase.StartsWith ("file://")) {
- appbase = appbase.Substring (7);
- if (Path.DirectorySeparatorChar != '/')
- appbase = appbase.Replace ('/', Path.DirectorySeparatorChar);
- }
- privateBinPath = Path.Combine (appbase, privateBinPath);
- }
-
- return privateBinPath;
- }
- }
-
internal string BaseDir {
get {
if (baseDir == null)