/////////////////////////////////////////////////////////////////////////////// // // Microsoft Research Singularity // // Copyright (c) Microsoft Corporation. All rights reserved. // // Note: // Ported literally SpecWeb99 source code. // // Strongly avoid writing programs like this. // // This file compiles under CSC for testing on Windows and SGC // on Singularity. using System; using System.IO; using FileSystem.Utils; using Microsoft.SingSharp; using Microsoft.SingSharp.Runtime; using Microsoft.Singularity; using Microsoft.Singularity.Channels; using Microsoft.Singularity.Directory; using System.Text; using Microsoft.Contracts; using Microsoft.SingSharp.Reflection; using Microsoft.Singularity.Applications; using Microsoft.Singularity.Io; using Microsoft.Singularity.Configuration; [assembly: Transform(typeof(ApplicationResourceTransform))] namespace Microsoft.Singularity.Applications { [ConsoleCategory(HelpMessage="Show attributes associated with a file", DefaultAction=true)] internal class Parameters { [InputEndpoint("data")] public readonly TRef Stdin; [OutputEndpoint("data")] public readonly TRef Stdout; [Endpoint] public readonly TRef nsRef; [StringParameter( "d", Mandatory=true, HelpMessage="Directory in which to gen files")] internal string directory; [LongParameter( "e", Mandatory=true, HelpMessage="pttime")] internal long pttime; [LongParameter( "t", Mandatory=true, HelpMessage="max number of threads")] internal long maxthread; [LongParameter( "exp1", Mandatory=true, HelpMessage="expiredAd1")] internal long expiredAd1; [LongParameter( "exp2", Mandatory=true, HelpMessage="expiredAd2")] internal long expiredAd2; reflective internal Parameters(); internal int AppMain() { CadGen99.AppMain(this); return 0; } } /////////////////////////////////////// // Quick and dirty abstraction of file operations ////////////////////////////////////// public class FILE { private TRef! connRef; private long filePos; private string! path; public static FILE CreateFile(string! path) { if (FileUtils.CreateFile(path) != 0) { return null; } return OpenFile(path); } public static FILE OpenFile(string! path) { FileContract.Imp conn = FileUtils.OpenFile(path); if (conn != null) { return new FILE(conn, path); } else { return null; } } private FILE([Claims] FileContract.Imp:Ready! conn, string! thePath) { connRef = new TRef(conn); filePos = 0; path = thePath; base(); } public int Write(string! str) { byte[] bytes = Encoding.ASCII.GetBytes(str); return Write(bytes, 0, bytes.Length); } public int Write(byte[]! buf, int offset, int length) { FileContract.Imp conn = connRef.Acquire(); byte[]! in ExHeap bytes = Bitter.FromByteArray(buf, offset, length); try { long bytesWritten; int error; conn.SendWrite(bytes, 0, filePos, bytes.Length); conn.RecvAckWrite(out bytes, out bytesWritten, out error); delete bytes; filePos += bytesWritten; if (error != 0) { return 0; } } finally { connRef.Release(conn); } return buf.Length; } public int Read(byte[]! buf, int offset, int maxLength) { FileContract.Imp conn = connRef.Acquire(); byte[]! in ExHeap bytes = new[ExHeap] byte[maxLength]; try { long bytesRead; int error; conn.SendRead(bytes, 0, filePos, bytes.Length); conn.RecvAckRead(out bytes, out bytesRead, out error); filePos += bytesRead; if (error != 0) { delete bytes; return 0; } Bitter.ToByteArray(bytes, 0, maxLength, buf, offset); delete bytes; } finally { connRef.Release(conn); } return buf.Length; } public int Size { // TODO get { long size; FileAttributesRecord fileAttributes; ErrorCode error; DirectoryServiceContract.Imp! rootNS = DirectoryService.NewClientEndpoint(); bool ok = FileUtils.GetAttributes(path, rootNS, out fileAttributes, out error); delete rootNS; if (!ok) { throw new Exception("Failed to get attributes"); } else { return unchecked((int)fileAttributes.FileSize); } } } public void Close() { FileContract.Imp conn = connRef.Acquire(); try { conn.SendClose(); } finally { connRef.Release(conn); } } } public class CadGen99 { // Constants from client.h private const int CAD_SEARCH_INTERVAL = 24; private const int CADFILE_ENTRIES = 360; private const int MAX_CAD_WEIGHT = 75; private static readonly string AdsFile = "Custom.Ads"; private static void Usage() { Console.WriteLine("cadgen99 -C -e -t "); Console.WriteLine("All arguments are mandatory."); Console.WriteLine("Expired ads beyond 1 and 2 can be supplied but are ignored per SpecWeb source."); Console.WriteLine("Output written to: /{0}", AdsFile); Console.WriteLine("NB better exist."); } internal static void AppMain(Parameters! config) { string /*!*/ directory = ""; int pttime = 0; int maxthread = 0; int [] expired = new int[2]; pttime = (int) config.pttime; maxthread = (int) config.maxthread; expired[0] = (int) config.expiredAd1; expired[1] = (int) config.expiredAd2; directory = config.directory; if (pttime == 0) { pttime = 1800; } // XXX : cadgen99 uses time(...) which is time in seconds // since since January 1, 1970. DateTime(1970, 1, 1). TimeSpan delta1970 = DateTime.Now - new DateTime(1970, 1, 1); int ts = ((int)delta1970.TotalSeconds) + (pttime * 2); int exp_ts = ts - 31622400; int [] demographic = new int [CADFILE_ENTRIES]; int [] weight = new int [CADFILE_ENTRIES]; int [] minmatch = new int [CADFILE_ENTRIES]; int [] expired_date = new int [CADFILE_ENTRIES]; // // Cut-and-paste from cadgen99.c with minor edits // (in-place type declarations and commenting out unused variables) // int my_n = CAD_SEARCH_INTERVAL; int match1 = (maxthread + CAD_SEARCH_INTERVAL) % my_n; int j; int i; for (j = 0; j < CADFILE_ENTRIES; j++) { int k = (j * 10000)%12301; if (k == 0) k = 12300; int c4 = (k ) & 0xf; int c3 = (k >> 4) & 0xf; int c2 = (k >> 8) & 0xf; // int c1 = (k >> 12) & 0xf; // XXX [oh]: not used in test int gender = (k) % 2; if (gender == 1) gender = 0x20000000; else gender = 0x10000000; int age = (k) % 4; if (age == 0) age = 0x08000000; else if (age == 1) age = 0x04000000; else if (age == 2) age = 0x02000000; else if (age == 3) age = 0x01000000; int area = (c4 + c2) % 4; if (area == 0) area = 0x00800000; else if (area == 1) area = 0x00400000; else if (area == 2) area = 0x00200000; else if (area == 3) area = 0x00100000; int interest1 = (c4 + c3) % 10; if (interest1 == 0) interest1 = 0x00080000; if (interest1 == 1) interest1 = 0x00040000; if (interest1 == 2) interest1 = 0x00020000; if (interest1 == 3) interest1 = 0x00010000; if (interest1 == 4) interest1 = 0x00008000; if (interest1 == 5) interest1 = 0x00004000; if (interest1 == 6) interest1 = 0x00002000; if (interest1 == 7) interest1 = 0x00001000; if (interest1 == 8) interest1 = 0x00000800; if (interest1 == 9) interest1 = 0x00000400; int interest2 = c4 % 10; if (interest2 == 0) interest2 = 0x00000200; else if (interest2 == 1) interest2 = 0x00000100; else if (interest2 == 2) interest2 = 0x00000080; else if (interest2 == 3) interest2 = 0x00000040; else if (interest2 == 4) interest2 = 0x00000010; else if (interest2 == 5) interest2 = 0x00000020; else if (interest2 == 6) interest2 = 0x00000008; else if (interest2 == 7) interest2 = 0x00000004; else if (interest2 == 8) interest2 = 0x00000002; else if (interest2 == 9) interest2 = 0x00000001; int combined = gender | age | area | interest1 | interest2; int wts=k*k; wts = wts % 1048576; if (wts == 0) wts = 0x27104; int match = MAX_CAD_WEIGHT; demographic[j] = combined; weight[j] = wts; minmatch[j] = match; expired_date[j] = ts; } for (j = 0; j < CADFILE_ENTRIES; j++) { if (j == match1) { minmatch[j] = 1; weight[j] = 0x3ffff; demographic[j] = demographic[j] | 0x3ff; match1 = match1 + my_n; } } // Mark two ranges as expired j = expired[0]; for (i = 0; i < my_n; i++) { if (j > CADFILE_ENTRIES - 1) expired_date[j-CADFILE_ENTRIES] = exp_ts; else expired_date[j] = exp_ts; j = j+1; } j = expired[1]; for (i = 0; i < my_n; i++) { if (j > CADFILE_ENTRIES - 1) expired_date[j-CADFILE_ENTRIES] = exp_ts; else expired_date[j] = exp_ts; j = j+1; } GenerateOutput(directory, demographic, weight, minmatch, expired_date); } #if SINGULARITY private static void GenerateOutput(string /*!*/ directory, int [] /*!*/ demographic, int [] /*!*/ weight, int [] /*!*/ minmatch, int [] /*!*/ expired_date) { FILE fp; string path; if (directory == "") { path = AdsFile; } else if (directory[directory.Length - 1] == '/') { path = directory + AdsFile; } else { path = directory + "/" + AdsFile; } fp = FILE.CreateFile(path); if (fp == null) { Console.WriteLine("Can't open file \"" + path + "\""); return; } for (int j = 0; j < CADFILE_ENTRIES; j++) { fp.Write( String.Format("{0,5:d} {1,8:X} {2,8:X} {3,3:d} {4,10:d}\n", j, demographic[j], weight[j], minmatch[j], expired_date[j]) ); } fp.Close(); } #else private static void GenerateOutput(string directory, int [] demographic, int [] weight, int [] minmatch, int [] expired_date) { for (int j = 0; j < CADFILE_ENTRIES; j++) { Console.WriteLine("{0,5:d} {1,8:X} {2,8:X} {3,3:d} {4,10:d}", j, demographic[j], weight[j], minmatch[j], expired_date[j]); } } #endif } #if SINGULARITY } #endif