00001 using System;
00002 using System.Text;
00003 using System.Collections;
00004 using System.Collections.Specialized;
00005
00006 namespace Common
00007 {
00011 public class CacheManager {
00012 protected Cache cache;
00013 protected long cacheSize;
00014 public URIMapper uriMapper;
00015 protected Object SyncRoot;
00016
00018
00019
00020
00021
00022 public CacheManager(long cacheSize) {
00023 this.cacheSize = cacheSize;
00024 cache = new Cache(cacheSize, this);
00025 uriMapper = new URIMapper();
00026 SyncRoot = new Object();
00027 }
00028
00030
00031
00032
00033
00034
00035
00036
00037
00038 public bool CanService(HTTPRequest request) {
00039 return (uriMapper.Contains(request.URI));
00040 }
00041
00048 public HTTPResponse Get(HTTPRequest request) {
00049 lock (SyncRoot) {
00050
00051 HTTPResponse result = null;
00052 HTTPBody resultBody = null;
00053 lock (uriMapper.SyncRoot) {
00054 URIMappingEntry mappingEntry = (URIMappingEntry)uriMapper[request.URI];
00055
00056 if (mappingEntry.CHK != null) {
00057 resultBody = cache.Get(mappingEntry.CHK);
00058 }
00059 HTTPResponseHeader resultHeader = new HTTPResponseHeader(mappingEntry.Headers);
00060 result = new HTTPResponse(resultHeader);
00061 if (resultBody != null) {
00062 result.AppendBody(resultBody);
00063 }
00064
00065
00066 }
00067 return result;
00068 }
00069 }
00070
00078 public void UpdateURIMapping(Uri URI, byte[] chk, string headers) {
00079 if (uriMapper.Contains(URI)) {
00080 ((URIMappingEntry)uriMapper[URI]).Freshen(chk, headers);
00081 } else {
00082 uriMapper.Add(URI, new URIMappingEntry(URI, chk, headers));
00083 }
00084 }
00085
00091 public bool CacheContains(byte[] chk) {
00092 return cache.Contains(chk);
00093 }
00094
00100 public void UpdateCache(HTTPResponse response, Uri requestURI) {
00101 if (response != null) {
00102 lock (SyncRoot) {
00103 lock(uriMapper.SyncRoot) {
00104
00105 byte[] responseChk = cache.Put(response.Body);
00106 UpdateURIMapping(requestURI, responseChk, response.Headers);
00107 }
00108 }
00109 }
00110 }
00111
00118 public HTTPBody GetByChk(byte[] chk) {
00119 return cache.Get(chk);
00120 }
00121 public static byte[] Patch(byte[] originalDocument, ArrayList changeHunks) {
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145 Console.WriteLine("- Beginning Patch process");
00146 string original = Encoding.ASCII.GetString(originalDocument);
00147 StringCollection source = new StringCollection();
00148 StringCollection target = new StringCollection();
00149 StringBuilder result = new StringBuilder();
00150 int currentSrcLine = 0;
00151 IEnumerator hunkEnum = changeHunks.GetEnumerator();
00152
00153 source.AddRange(original.Split(new char[] {'\n'}));
00154
00155 while(currentSrcLine < source.Count) {
00156 if (!hunkEnum.MoveNext()) {
00157 while (currentSrcLine < source.Count) {
00158 target.Add(source[currentSrcLine] + '\n');
00159 currentSrcLine++;
00160 }
00161 } else {
00162 JLibDiff.Hunk currentHunk = (JLibDiff.Hunk)hunkEnum.Current;
00163 int firstLineSrc = currentHunk.lowLine(0) - 1;
00164
00165 while (currentSrcLine < firstLineSrc) {
00166 target.Add(source[currentSrcLine] + '\n');
00167 currentSrcLine++;
00168 }
00169 switch(currentHunk.GetType().Name) {
00170 case "HunkAdd" : {
00171 if (currentHunk.lowLine(0) != 0) {
00172 target.Add(source[currentSrcLine]);
00173 }
00174 for (int i = 0; i < currentHunk.numLines(1); i++) {
00175 target.Add(currentHunk.relNum(1, i));
00176 }
00177 currentSrcLine++;
00178 break;
00179 }
00180 case "HunkChange": {
00181 for (int i = 0; i < currentHunk.numLines(1); i++) {
00182 target.Add(currentHunk.relNum(1, i));
00183 }
00184 currentSrcLine = currentHunk.highLine(0);
00185 break;
00186 }
00187 case "HunkDel" : {
00188 currentSrcLine = currentHunk.highLine(0);
00189 break; }
00190 default: { throw new Exception("Unknown Hunk type"); }
00191 }
00192 }
00193 }
00194
00195 foreach (string s in target) {
00196 result.Append(s);
00197 }
00198 Console.WriteLine("- Patch Process Complete");
00199 return Encoding.ASCII.GetBytes(result.ToString());
00200 }
00201
00202 public static ArrayList Diff(System.IO.Stream oldDocStream, System.IO.Stream newDocStream) {
00203 JLibDiff.diff myDiff = new JLibDiff.diff();
00204 myDiff.diffBuffer(new System.IO.StreamReader(oldDocStream), new System.IO.StreamReader(newDocStream));
00205 myDiff.print();
00206 return myDiff.getHunk();
00207 }
00208 }
00209 }