Implementing Undeniable Signature Scheme : random e1 and e2 failed to compute correct d in verify protocol - signature

First you check undeniable signature scheme verifying algorithm.
Than in that there is first step telling to chose two random x1 and x2.
But the verifying algo works sometime and sometime failed depending on two randoms. ( algo implemented in java and correctly).
For the same input if we run that algo multiple time, sometime it signature is matched and sometime not, last comparison is failed.
Plz help me. Im stuck here ( lack of math).

Actually it is an signature scheme and in paper it was confusing but now i've figure out solution.
Solution code is: let me know if you need me to explain this code.
import java.lang.*;
import java.util.*;
import java.math.*;
import java.security.MessageDigest;
import java.nio.file.*;
import java.io.*;
import java.security.*;
class UndeniableSignature {
int Q; // prime
int P; // prime of form P = 2Q + 1
BigInteger G; // Generator of Z*P
int D; // private key belongs to [2 ... Q-1]
BigInteger Y; // G^D (mod P)
int invD; // D^-1 (mod Q)
Random rand = new SecureRandom(); // uniform random generator
public int[] extendedEuclidean(int a, int b) {
if(b==0) {
int[] arr=new int[3];
arr[0] = a;
arr[1] = 1;
arr[2] = 0;
return arr;
}
int[] subResult = extendedEuclidean(b,a%b);
int[] arr=new int[3];
arr[0] = subResult[0];
arr[1] = subResult[2];
arr[2] = subResult[1] - (a/b) * subResult[2];
return arr;
}
public int secureRandom(int max) {
return rand.nextInt(max);
}
public BigInteger getGenerator(BigInteger p, BigInteger q){
BigInteger generator = BigInteger.ZERO;
BigInteger exp = p.subtract(BigInteger.ONE).divide(q);
for(int i=2;i<p.intValue()-1;i++) {
generator = BigInteger.valueOf(i);
generator = generator.modPow(exp, p);
if(!generator.equals(BigInteger.ONE)) return generator;
}
// do {
// generator = BigInteger.valueOf(this.secureRandom(p.intValue()));
// generator = generator.modPow(exp, p);
// } while(generator.equals(BigInteger.ONE));
return generator;
// BigInteger generator = BigInteger.ZERO;
// for(long i = 2; i < p.intValue()-1; i++)
// {
// generator = BigInteger.valueOf(i);
// if(generator.modPow(BigInteger.valueOf(2), p).equals(BigInteger.ONE)) continue;
// if(generator.modPow(q, p).equals(BigInteger.ONE)) continue;
// else return generator;
// }
// return generator;
}
public String readMessageFile(String filename) {
try {
return new String(Files.readAllBytes(Paths.get(filename)));
} catch(Exception ex) {
System.out.println("ERR: Can't read file.");
}
return null;
}
public int[] readSignatureFile(String filename) {
InputStream is=null;
DataInputStream dis=null;
try {
is = new FileInputStream(filename);
dis = new DataInputStream(is);
ArrayList intList = new ArrayList();
int count = 0;
while(dis.available()>0) {
intList.add(dis.readInt());
}
int[] data = new int[intList.size()];
for(int i=0;i<data.length;i++) {
data[i] = (int)intList.get(i);
}
dis.close();
is.close();
return data;
} catch(Exception ex) {
System.out.println("ERR: Can't read file.");
}
return null;
}
public static void writeSignatureFile(String filename, int[] contents) {
FileOutputStream fos=null;
DataOutputStream dos=null;
try {
fos = new FileOutputStream(filename);
dos = new DataOutputStream(fos);
for(int i=0;i<contents.length;i++) {
dos.writeInt(contents[i]);
}
dos.flush();
dos.close();
fos.close();
} catch(Exception ex) {
System.out.println("ERR: Can't write to file.");
}
}
public void keyGeneration() {
System.out.println("UNDENIABLE SIGNATURE SCHEME");
System.out.println("- KEY GENERATION");
System.out.print("\tEnter prime P (such that P=2Q+1) : ");
this.P = new Scanner(System.in).nextInt();
this.Q = (this.P - 1)/2;
System.out.println("\tPrime Q is "+this.Q+".");
this.G = this.getGenerator(BigInteger.valueOf(this.P),BigInteger.valueOf(this.Q));
System.out.println("\tGenerator G of group Z*("+this.P+") is "+this.G+".");
System.out.print("\tEnter private key D (belongs to Z*P) :");
this.D = new Scanner(System.in).nextInt();
while(this.D <= 0 || this.D >= this.P) {
System.out.println("\tInvalid private key selected, please try again.");
System.out.print("\tEnter private key D (belongs to Z*P) :");
this.D = new Scanner(System.in).nextInt();
}
this.Y = this.G.modPow(BigInteger.valueOf(this.D), BigInteger.valueOf(this.P));
System.out.println("\tG^D(mod P) = "+this.Y+".");
System.out.println("\tPublic Key [P, G, Y] is ["+this.P+", "+this.G+", "+this.Y+"].");
System.out.println("\tPrivate Key [D] is ["+this.D+"].");
int[] g = this.extendedEuclidean(this.D, this.Q);
this.invD = g[1];
if(this.invD < 0) {
this.invD = this.Q - Math.abs(this.invD);
System.out.println("\tInverse was negative.");
}
System.out.println("\tInverse of D (mod Q) is "+this.invD+".");
}
public void messageSigning(String message) {
int[] signatureBytes = new int[message.length()];
for(int i=0;i<message.length();i++) {
BigInteger m = BigInteger.valueOf((int)message.charAt(i));//this.H(message.charAt(i)+"");
BigInteger s = m.pow(this.D).mod(BigInteger.valueOf(this.P));
signatureBytes[i] = s.intValue();
// System.out.println("\tchar:"+message.charAt(i)+", m:"+m+", s:"+s+", S:"+signatureBytes[i]);
}
System.out.print("\tEnter signature filename : ");
String signatureFilename = new Scanner(System.in).nextLine();
this.writeSignatureFile(signatureFilename, signatureBytes);
System.out.println("\tSignature is successfully generated.");
}
// see the condition proof for w=W for solution of problem
public boolean signatureVerification(String message, int[] signature) {
for(int i=0;i<message.length();i++) {
// rand=new Random();
// int x1 = this.secureRandom(this.Q-1);
// while(x1<=1) x1 = this.secureRandom(this.Q-1);
// int x2 = this.secureRandom(this.Q-1);
// while(x2<=1) x2 = this.secureRandom(this.Q-1);
int x1 = 38, x2 = 397;
BigInteger S = BigInteger.valueOf(signature[i]);
BigInteger s = S.pow(x1);
BigInteger y = this.Y.pow(x2);
BigInteger z = s.multiply(y).mod(BigInteger.valueOf(this.P));
BigInteger w = signerChallengeForVerification(z);
BigInteger M = BigInteger.valueOf((int)message.charAt(i));//this.H(message.charAt(i)+"");
BigInteger m = M.pow(x1);
BigInteger g = this.G.pow(x2);
BigInteger mg = m.multiply(g);
BigInteger W = mg.mod(BigInteger.valueOf(this.P));
// System.out.println("\ti:"+i+", char:"+message.charAt(i)+", m:"+M+", s:"+S);
// System.out.println("\t\tz:"+z+", w:"+w+" , W:"+W);
if(!w.equals(W)) {
return false;
}
}
return true;
}
public boolean disavowalProtocol(String message, int[] signature) {
int x1 = 38, x2 = 397;
BigInteger response1 = BigInteger.ZERO;
BigInteger response2 = BigInteger.ZERO;
// verification 1
for(int i=0;i<message.length();i++) {
BigInteger S = BigInteger.valueOf(signature[i]);
BigInteger s = S.pow(x1);
BigInteger y = this.Y.pow(x2);
BigInteger z = s.multiply(y).mod(BigInteger.valueOf(this.P));
BigInteger w = signerChallengeForVerification(z);
BigInteger M = BigInteger.valueOf((int)message.charAt(i));//this.H(message.charAt(i)+"");
BigInteger m = M.pow(x1);
BigInteger g = this.G.pow(x2);
BigInteger mg = m.multiply(g);
BigInteger W = mg.mod(BigInteger.valueOf(this.P));
// System.out.println("\ti:"+i+", char:"+message.charAt(i)+", m:"+M+", s:"+S);
// System.out.println("\t\tz:"+z+", w:"+w+" , W:"+W);
if(!w.equals(W)) {
response1 = w;
break;
}
}
if(response1.equals(BigInteger.ZERO)) {
return false; // signature is not forgery bcoz signature is matched
}
// verification 2
for(int i=0;i<message.length();i++) {
BigInteger S = BigInteger.valueOf(signature[i]);
BigInteger s = S.pow(x1);
BigInteger y = this.Y.pow(x2);
BigInteger z = s.multiply(y).mod(BigInteger.valueOf(this.P));
BigInteger w = signerChallengeForVerification(z);
BigInteger M = BigInteger.valueOf((int)message.charAt(i));//this.H(message.charAt(i)+"");
BigInteger m = M.pow(x1);
BigInteger g = this.G.pow(x2);
BigInteger mg = m.multiply(g);
BigInteger W = mg.mod(BigInteger.valueOf(this.P));
// System.out.println("\ti:"+i+", char:"+message.charAt(i)+", m:"+M+", s:"+S);
// System.out.println("\t\tz:"+z+", w:"+w+" , W:"+W);
if(!w.equals(W)) {
response2 = w;
break;
}
}
if(response2.equals(BigInteger.ZERO)) {
return false; // signature is not forgery bcoz signature is matched
}
// forgery validation now it comes here only when one of above validation is failed
BigInteger A = response1.divide(this.G.pow(x2)).pow(x1).mod(BigInteger.valueOf(this.P));
BigInteger B = response2.divide(this.G.pow(x1)).pow(x2).mod(BigInteger.valueOf(this.P));
return A.equals(B); // signature is forgery if A == B
}
public BigInteger signerChallengeForVerification(BigInteger z) {
// System.out.println("\tchallange: "+z+", invD:"+this.invD+", d:"+(z.pow(this.invD).mod(BigInteger.valueOf(this.P))));
return z.pow(this.invD).mod(BigInteger.valueOf(this.P));
}
}
class Program {
public static void main(String[] args) {
String msgFilename, signatureFilename, message;
UndeniableSignature scheme = new UndeniableSignature();
scheme.keyGeneration();
int choice = 0;
do {
System.out.println();
System.out.println("- OPERATIONS");
System.out.println("\t1. Sign message");
System.out.println("\t2. Verify signature");
System.out.println("\t3. Disavowal protocal");
System.out.println("\t4. Exit");
System.out.print("\tChoice : ");
choice = new Scanner(System.in).nextInt();
System.out.println();
switch(choice) {
case 1:
System.out.println("- MESSAGE SIGNING");
System.out.print("\tEnter message filename : ");
msgFilename = new Scanner(System.in).nextLine();
message = new String(scheme.readMessageFile(msgFilename));
scheme.messageSigning(message);
break;
case 2:
System.out.println("- SIGNATURE VERIFICATION");
System.out.print("\tEnter message filename : ");
msgFilename = new Scanner(System.in).nextLine();
System.out.print("\tEnter signature filename : ");
signatureFilename = new Scanner(System.in).nextLine();
message = scheme.readMessageFile(msgFilename);
int[] signatureBytes = scheme.readSignatureFile(signatureFilename);
if(scheme.signatureVerification(message, signatureBytes)) {
System.out.println("\tSignature IS valid.");
} else {
System.out.println("\tSignature is NOT valid.");
}
break;
case 3:
System.out.println("- DISAVOWAL VERIFICATION");
System.out.print("\tEnter message filename : ");
msgFilename = new Scanner(System.in).nextLine();
System.out.print("\tEnter signature filename : ");
signatureFilename = new Scanner(System.in).nextLine();
message = scheme.readMessageFile(msgFilename);
signatureBytes = scheme.readSignatureFile(signatureFilename);
if(scheme.disavowalProtocol(message, signatureBytes)) {
System.out.println("\tSignature IS forgery.");
} else {
System.out.println("\tSignature is NOT forgery.");
}
break;
case 4:
System.out.println("- BYE BYE");
break;
}
} while(choice!=4);
}
}
thanks :D

Related

How to find maximum repeated characters in a string

I have a string "aaabbb".
Below program returned max repeated value as a.
But here in this case both a and b are max repeated characters.
How can I print that both a and b as max repeated characters.
import java.util.HashMap;
import java.util.Map.Entry;
class MaxRepeatedCharactersInString
{
public static void main(String[] args)
{
String s = "acakabbba";
HashMap<Character, Integer> map = new HashMap<>();
char[] ch = s.toCharArray();
for(char c : ch)
{
if(map.containsKey(c))
{
map.put(c, map.get(c)+1);
}
else
{
map.put(c, 1);
}
}
int maxCount = 0;
char maxChar = ' ';
System.out.println("Maximum repeated character in String: ");
for(Entry<Character, Integer> entry : map.entrySet())
{
if(maxCount < entry.getValue())
{
maxCount = entry.getValue();
maxChar = entry.getKey();
}
}
System.out.println(maxChar+"="+maxCount);
}
}
I added an extra Stack and a counter to store the maximum repeated characters
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Stack;
class MaxRepeatedCharactersInString {
public static void main(String[] args) {
String s = "aa";
HashMap<Character, Integer> map = new HashMap<>();
char[] ch = s.toCharArray();
for (char c : ch) {
if (map.containsKey(c)) {
map.put(c, map.get(c) + 1);
} else {
map.put(c, 1);
}
}
int maxCount = 0;
int noMax = 0;
Stack<Character> st = new Stack<>();
System.out.println("Maximum repeated characters in String: ");
for (Entry<Character, Integer> entry : map.entrySet()) {
if (maxCount < entry.getValue()) {
maxCount = entry.getValue();
noMax = 1;
st.push(entry.getKey());
} else if (maxCount == entry.getValue()) {
noMax++;
st.push(entry.getKey());
}
}
for (int i = 0; i < noMax; i++) {
System.out.println(st.pop() + "=" + maxCount);
}
}
}

REVIT Transfer floor sketch to Void Extrusion in Family

Struggling with some Revit code to copy the profile of a floor and use it as the sketch profile for a void extrusion in a family.
Here is the Full Sharp Development Code. It half works in my custom project template, when I try to use it in an out of the box project generated from revit default template it gives the error "a managed exception was thrown by revit or by one of its external applications"
In my template it cannot properly split the curves into a secondary array. It says the array elements are being changed but when the loop runs again the element i is back to it's original content??? The TaskDialog clearly says the elements have changed, until the loop iterates again.
Full code: To work it requires a generic family with the name "Void - Custom" to be in the project. The "If found" near the bottom last page and a half of code, is where the for loop is not behaving as expected.
/*
* Created by SharpDevelop.
* User: arautio
* Date: 4/30/2019
* Time: 11:10 AM
*
* To change this template use Tools | Options | Coding | Edit Standard Headers.
*/
using System;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Architecture;
using Autodesk.Revit.DB.Structure;
using Autodesk.Revit.UI.Selection;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using System.Text;
using System.IO;
using System.Diagnostics;
namespace ARC
{
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.DB.Macros.AddInId("3411F411-6FC1-4A4D-9CFD-37ABB2028A15")]
public partial class ThisApplication
{
private void Module_Startup(object sender, EventArgs e)
{
}
private void Module_Shutdown(object sender, EventArgs e)
{
}
#region Revit Macros generated code
private void InternalStartup()
{
this.Startup += new System.EventHandler(Module_Startup);
this.Shutdown += new System.EventHandler(Module_Shutdown);
}
#endregion
public void FloorGrating()
{
StringBuilder sb = new StringBuilder();
Dictionary<Floor, List<ModelCurve>> dict_SketchLines = new Dictionary<Floor, List<ModelCurve>>();
UIDocument uidoc = this.ActiveUIDocument;
Document document = uidoc.Document;
View activev = document.ActiveView;
ElementId levelId = null;
levelId = activev.LevelId;
Element levelem = document.GetElement( levelId );
Level lev = document.ActiveView.GenLevel;
Reference refsel = uidoc.Selection.PickObject(ObjectType.Element, "Select Floor to Add Grating To");
Element elem = document.GetElement(refsel.ElementId);
Floor f = elem as Floor;
List<ElementId> _deleted = null;
using (Transaction t = new Transaction(document, "temp"))
{
t.Start();
document.Regenerate();
_deleted = document.Delete(elem.Id).ToList();
t.RollBack();
}
bool SketchLinesFound = false;
List<ModelCurve> _sketchCurves = new List<ModelCurve>();
foreach (var id in _deleted)
{
ModelCurve mc = document.GetElement(id) as ModelCurve;
if (mc != null)
{
_sketchCurves.Add(mc);
SketchLinesFound = true;
}
else
{
if (SketchLinesFound) break;
}
}
dict_SketchLines.Add(f, _sketchCurves);
foreach (Floor key in dict_SketchLines.Keys)
{
List<ModelCurve> _curves = dict_SketchLines[key];
sb.AppendLine(string.Format("floor {0} has sketchlines:", key.Id));
foreach (ModelCurve mc in _curves)
{
sb.AppendLine(string.Format("{0} <{1}>", mc.GetType(), mc.Id));
sb.AppendLine(string.Format("<{0}>", mc.GeometryCurve.IsBound.ToString()));
if (mc.GetType().ToString() == "Autodesk.Revit.DB.ModelArc" && mc.GeometryCurve.IsBound == false)
{
TaskDialog.Show("Revit", "Circle Found");
}
try
{
sb.AppendLine(string.Format("<{0} -- {1}>", mc.GeometryCurve.GetEndPoint(0), mc.GeometryCurve.GetEndPoint(1)));
}
catch
{
}
}
sb.AppendLine();
}
//TaskDialog.Show("debug", sb.ToString());
Document docfamily;
Family fam;
string ftitle = document.Title;
string fpath = document.PathName;
int ftitlelen = ftitle.Length + 4;
int fpathlen = fpath.Length;
int finpathlen = fpathlen - ftitlelen;
string sfinpath = fpath.Substring(0,finpathlen);
string famname = "GratingVoid";
string fext = ".rfa";
int counter = 1;
while (counter < 100)
{
famname = ("GratingVoid" + counter as String);
Family family = FindElementByName(document,typeof(Family),famname)as Family;
if( null == family )
{
sfinpath = (sfinpath + famname + fext);
counter = 1000;
}
counter += 1;
}
FilteredElementCollector collector0 = new FilteredElementCollector(document);
ICollection<Element> collection0 = collector0.WhereElementIsNotElementType().ToElements();
List<FamilySymbol> fsym0 = new FilteredElementCollector(document).OfClass(typeof(FamilySymbol)).Cast<FamilySymbol>().ToList();
FamilySymbol famsymb0 = null;
foreach (FamilySymbol symb in fsym0)
{
if (symb.Name == "Void - Custom")
{
famsymb0 = symb as FamilySymbol;
}
}
fam = famsymb0.Family;
docfamily = document.EditFamily(fam);
try
{
docfamily.SaveAs(#sfinpath);
}
catch
{
TaskDialog.Show("Revit", "Could Not Save Void Family");
}
using (Transaction trans = new Transaction(docfamily))
{
trans.Start("family");
bool circleflag = false;
ElementId delid = null;
FilteredElementCollector collector = new FilteredElementCollector( docfamily );
foreach(Element element in collector.OfClass(typeof(GenericForm)))
{
delid = element.Id;
}
docfamily.Delete(delid);
CurveArray loccurva = new CurveArray();
foreach (Floor key in dict_SketchLines.Keys)
{
List<ModelCurve> _curves = dict_SketchLines[key];
foreach (ModelCurve mc in _curves)
{
if (mc.GetType().ToString() == "Autodesk.Revit.DB.ModelArc" && mc.GeometryCurve.IsBound == false)
{
circleflag = true;
}
LocationCurve lcurve = mc.Location as LocationCurve;
Curve c = lcurve.Curve as Curve;
loccurva.Append(c);
}
}
try
{
if (circleflag == true && loccurva.Size == 2)
{
Curve tempc;
if (loccurva.get_Item(0).GetType().ToString() == "Autodesk.Revit.DB.Arc")
{
tempc = loccurva.get_Item(0);
}
else
{
tempc = loccurva.get_Item(1);
}
loccurva.Clear();
loccurva.Append(tempc);
}
CurveArrArray newcurarr = new CurveArrArray();
newcurarr.Append(loccurva);
SortCurvesContiguousArray(newcurarr);
TaskDialog.Show("Revit CurveArray Array Size" , newcurarr.Size.ToString());
foreach (CurveArray ca in newcurarr)
{
TaskDialog.Show("Revit CurveArray within Array Size" , ca.Size.ToString());
}
// Below is edited for error control - leaving out the secondary loops for now
CurveArrArray switcharr = new CurveArrArray();
//switcharr.Append(newcurarr.get_Item(1));
switcharr.Append(newcurarr.get_Item(0));
//SortCurvesContiguousArray(loccurva);
//CurveArrArray newcurarr = new CurveArrArray();
//newcurarr.Append(loccurva);
double end = 1;
SketchPlane sketch = FindElementByName( docfamily,typeof( SketchPlane ), "Ref. Level" ) as SketchPlane;
docfamily.FamilyCreate.NewExtrusion(false, switcharr, sketch, end);
}
catch
{
TaskDialog.Show("Revit", "Could Not Write to Curve Array or Create Extrusion");
}
trans.Commit();
}
docfamily.Save();
docfamily.LoadFamily(document, new CustomFamilyLoadOption());
docfamily.Close();
File.Delete(sfinpath);
Family familynew = FindElementByName(document,typeof(Family),famname)as Family;
if( null == familynew )
{
TaskDialog.Show("Revit", "Family Does Not Exist");
}
FilteredElementCollector collector1 = new FilteredElementCollector(document);
ICollection<Element> collection = collector1.WhereElementIsNotElementType().ToElements();
List<FamilySymbol> fsym = new FilteredElementCollector(document).OfClass(typeof(FamilySymbol)).Cast<FamilySymbol>().ToList();
FamilySymbol famsymb = null;
foreach (FamilySymbol symb in fsym)
{
if (symb.Name == famname)
{
famsymb = symb as FamilySymbol;
}
}
using (Transaction trans = new Transaction(document))
{
trans.Start("PlaceVoid");
if( ! famsymb.IsActive )
{
famsymb.Activate();
}
XYZ p = new XYZ(0,0,0);
FamilyInstance gratingvoid = document.Create.NewFamilyInstance( p, famsymb, lev, lev, StructuralType.NonStructural );
document.Regenerate();
trans.Commit();
}
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------
static public Element FindElementByName(Document doc,Type targetType,string targetName)
{
return new FilteredElementCollector( doc ).OfClass( targetType ).FirstOrDefault<Element>(e => e.Name.Equals( targetName ) );
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------
public class CustomFamilyLoadOption : IFamilyLoadOptions
{
public bool OnFamilyFound(bool familyInUse, out bool overwriteParameterValues)
{
overwriteParameterValues = true;
return true;
}
public bool OnSharedFamilyFound(Family sharedFamily,bool familyInUse,out FamilySource source, out bool overwriteParameterValues)
{
source = FamilySource.Family;
overwriteParameterValues = true;
return true;
}
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------
const double _inch = 1.0 / 12.0;
const double _sixteenth = _inch / 16.0;
static Curve CreateReversedCurve(Curve orig )
{
//if( !IsSupported( orig ) )
//{
// throw new NotImplementedException("CreateReversedCurve for type " + orig.GetType().Name );
//}
if( orig is Line )
{
//return creapp.NewLineBound(orig.GetEndPoint( 1 ), orig.GetEndPoint( 0 ) );
return Line.CreateBound(orig.GetEndPoint( 1 ), orig.GetEndPoint( 0 ) );
}
else if( orig is Arc )
{
// return creapp.NewArc( orig.GetEndPoint( 1 ), orig.GetEndPoint( 0 ), orig.Evaluate( 0.5, true ) );
return Arc.Create( orig.GetEndPoint( 1 ), orig.GetEndPoint( 0 ), orig.Evaluate( 0.5, true ) );
}
else
{
throw new Exception(
"CreateReversedCurve - Unreachable" );
}
}
public static void SortCurvesContiguousArray(CurveArrArray curvesarr)
{
double _precision1 = 1.0 / 12.0 / 16.0; // around 0.00520833
double _precision2 = 0.001; // limit for CurveLoop.Create(...)
int cn = curvesarr.Size;
int ci = 0;
while (ci < cn)
{
CurveArray curves = curvesarr.get_Item(ci);
ci +=1;
// account for multiple curve loops with secondary array
CurveArray loop1 = new CurveArray();
CurveArray loop2 = new CurveArray();
int n = curves.Size;
int split = 1;
// Walk through each curve (after the first)
// to match up the curves in order
for (int i = 0; i < n; ++i)
{
TaskDialog.Show("Revit I Loop Run", i.ToString());
Curve curve = curves.get_Item(i);
if (curve.GetType().ToString() == "Autodesk.Revit.DB.Arc" && curve.IsBound == false)
{
break;
}
XYZ beginPoint = curve.GetEndPoint(0);
XYZ endPoint = curve.GetEndPoint(1);
XYZ p,q;
// Find curve with start point = end point
bool found = (i + 1 >= n);
for (int j = i + 1; j < n; ++j)
{
p = curves.get_Item(j).GetEndPoint(0);
q = curves.get_Item(j).GetEndPoint(1);
// If there is a match end->start,
// this is the next curve
if (p.DistanceTo(endPoint) < _precision1)
{
if (p.DistanceTo(endPoint) > _precision2)
{
XYZ intermediate = new XYZ((endPoint.X + p.X) / 2.0, (endPoint.Y + p.Y) / 2.0, (endPoint.Z + p.Z) / 2.0);
curves.set_Item(i, Line.CreateBound(beginPoint, intermediate));
curves.set_Item(j, Line.CreateBound(intermediate, q));
}
if (i + 1 != j)
{
Curve tmp = curves.get_Item(i + 1);
curves.set_Item(i + 1, curves.get_Item(j));
curves.set_Item(j, tmp);
}
found = true;
break;
}
// If there is a match end->end,
// reverse the next curve
if (q.DistanceTo(endPoint) < _precision1)
{
if (q.DistanceTo(endPoint) > _precision2)
{
XYZ intermediate = new XYZ((endPoint.X + q.X) / 2.0, (endPoint.Y + q.Y) / 2.0, (endPoint.Z + q.Z) / 2.0);
curves.set_Item(i, Line.CreateBound(beginPoint, intermediate));
curves.set_Item(j, Line.CreateBound(p, intermediate));
}
if (i + 1 == j)
{
curves.set_Item(i + 1, CreateReversedCurve(curves.get_Item(j)));
}
else
{
Curve tmp = curves.get_Item(i + 1);
curves.set_Item(i + 1, CreateReversedCurve(curves.get_Item(j)));
curves.set_Item(j, tmp);
}
found = true;
break;
}
}
if (!found)
{
// if not found, must be part of a new loop - move it to the back and keep going and add to second array
TaskDialog.Show("Revit No Match Found for item", i.ToString());
TaskDialog.Show("Revit", "Moveing it to back of list");
Curve tmp1 = curves.get_Item(i);
TaskDialog.Show("Revit tmp1 Current i item endpt", tmp1.GetEndPoint(0).ToString());
loop2.Append(tmp1);
Curve tmp2 = curves.get_Item(n - split);
TaskDialog.Show("Revit tmp2 Back of list item endpt", tmp2.GetEndPoint(0).ToString());
// set current item to rear
curves.set_Item(i, tmp2);
// set rear item to current
curves.set_Item(n - split, tmp1);
TaskDialog.Show("Revit new item i endpt", curves.get_Item(i).GetEndPoint(0).ToString());
TaskDialog.Show("Revit moved item endpt", curves.get_Item(n - split).GetEndPoint(0).ToString());
// error testing - try to append in a different manner and check values
//curves.set_Item(i, Line.CreateBound(curves.get_Item(i).GetEndPoint(0), curves.get_Item(i).GetEndPoint(1)));
//curves.set_Item(n - split, Line.CreateBound(curves.get_Item(n - split).GetEndPoint(0), curves.get_Item(n - split).GetEndPoint(1)));
//Curve ncurve = Line.CreateBound(curves.get_Item(n - split).GetEndPoint(0), curves.get_Item(n - split).GetEndPoint(1));
//TaskDialog.Show("Revit Appended to Loop2 Endpoint", ncurve.GetEndPoint(0).ToString());
//loop2.Append(ncurve);
//set the split off counter so items not fitting in first loop can be split to new array.
split += 1;
//reset the counter back so item moved from rear can be checked in next run of for loop
i -= 2;
}
//set counter to end for loop when all items that do not fit in first loop are processed
if (i >= n - (split + 1))
{
TaskDialog.Show("Revit", "End Of Looping");
TaskDialog.Show("Revit - The Split Number", split.ToString());
i = n;
}
}
int counter = 0;
// recreate array with only items from first loop found
while (counter <= (n - split))
{
loop1.Append(curves.get_Item(counter));
counter += 1;
}
TaskDialog.Show("Revit loop1 Size", loop1.Size.ToString());
curvesarr.Clear();
curvesarr.Append(loop1);
if (loop2.Size > 0)
{
string stringinfo = "";
// run the loop detection on a second array that was split from the first
TaskDialog.Show("Revit loop2 Size", loop2.Size.ToString());
CurveArrArray tmpcurvesarr = new CurveArrArray();
tmpcurvesarr.Append(loop2);
SortCurvesContiguousArray(tmpcurvesarr);
loop2.Clear();
loop2 = tmpcurvesarr.get_Item(0);
curvesarr.Append(loop2);
foreach (Curve ccc in loop2)
{
stringinfo = (stringinfo + " " + ccc.GetEndPoint(0).ToString() + " - " + ccc.GetEndPoint(1).ToString());
}
TaskDialog.Show("Revit", stringinfo);
}
}
}
}
}
Thanks for any and all help.
Shane

Accessing Map Value

static void getRecommendations(Map<User, HashMap<Item, Double>> map, User to) {
scores = sortMapByScore(scores, to);
TreeMap<User, Double> scores1 = (TreeMap<User, Double>) scores.get(to);
Set<User> user = (Set<User>) scores1.keySet();
Iterator<User> itr = user.iterator();
Map<Item, Double> rec = new HashMap<Item, Double>();
int i = 0;
while (itr.hasNext() && i < 5) {
User u = itr.next();
/* for(Item e:map.get(to).keySet()){ */
for (Item e1 : map.get(u).keySet()) {
if (!map.get(to).containsKey(e1)) {
if (rec.containsKey(e1)) {
double sc = rec.get(e1);
rec.put(e1, sc + map.get(u).get(e1) * scores.get(to).get(u));
} else {
// System.out.println(scores);
rec.put(e1, map.get(u).get(e1) * scores.get(to).get(u));
}
// }
}
}
i++;
}
TreeMap<Item, Double> res = new TreeMap<Item, Double>(
new ValueComparator(rec));
res.putAll(rec);
int k=0;
for(Item d:res.keySet()){
System.out.println(d.getmTitle());
k++;
if(k==5){break;}
}
}
I am using nested HashMap and TreeMap in this example.But I am facing the below problem.
In the code above in the line
rec.put(e1, map.get(u).get(e1) * scores.get(u).get(to));
I am getting a NullPointerException, even though I am using the same HashMap's keyset to get the Values.

Returning list of objects from Database

I am trying to return an object array from my database but can't get the call correct or the return object[s].
In the example below I just return an empty String trying to get this working. The listings[cnt] are being filled properly but I'm not sure how to make the call and return the Objects?
I am making 2 different calls to new Houses in getData() and that doesn't seem right either.
Houses[] listings = new Houses[cnt]; // Seems like I need this to initialize the array to a certain size.
listings[cnt] = new Houses(z,a,b,c,d,e,f,g,h); // Then I fill the Object with variables.
then return listings somehow.
// ??? How do I set it up so that I get an array of objects back?
// I am making the call from MainActivity here
myHelper = new GrumpyDB(this);
String h = new String();
h = myHelper.getData();
public String getData() {
Log.d(TAG, "Starting getData");
SQLiteDatabase db = helper.getWritableDatabase();
String[] columns = {myHelper.UID, myHelper.ADDRESS, myHelper.STREET, myHelper.CITY, myHelper.STATE, myHelper.ZIP, myHelper.ENTIRE_ADDRESS,myHelper.UPLOADS,myHelper.DOWNLOADS};
Cursor cursor = db.query(myHelper.TABLE_NAME_LOCATION, columns, null, null, null, null, null);
int cnt = cursor.getCount();
Houses[] listings = new Houses[cnt];
cnt = 0;
while (cursor.moveToNext()) {
int index0 = cursor.getColumnIndex(myHelper.UID);
int index1 = cursor.getColumnIndex(myHelper.ADDRESS);
int index2 = cursor.getColumnIndex(myHelper.STREET);
int index3 = cursor.getColumnIndex(myHelper.CITY);
int index4 = cursor.getColumnIndex(myHelper.STATE);
int index5 = cursor.getColumnIndex(myHelper.ZIP);
int index6 = cursor.getColumnIndex(myHelper.ENTIRE_ADDRESS);
int index7 = cursor.getColumnIndex(myHelper.UPLOADS);
int index8 = cursor.getColumnIndex(myHelper.DOWNLOADS);
String z = cursor.getString(index0);
String a = cursor.getString(index1);
String b = cursor.getString(index2);
String c = cursor.getString(index3);
String d = cursor.getString(index4);
String e = cursor.getString(index5);
String f = cursor.getString(index6);
String g = cursor.getString(index7);
String h = cursor.getString(index8);
listings[cnt] = new Houses(z,a,b,c,d,e,f,g,h);
Log.d(TAG, listings[cnt].UID + listings[cnt].address + listings[cnt].street + listings[cnt].city + listings[cnt].state + listings[cnt].zip + listings[cnt].upload + listings[cnt].download);
//buffer.append(f + "\n");
cnt++;
}
//Log.d(TAG, "Returning From getData");
//return listings;
cursor.close();
db.close();
return "";
//return listings;
}
I got it ..... this works.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//GrumpyDB myHelper;
myHelper = new GrumpyDB(this);
//String h = new String();
//h = myHelper.getData();
//Houses House;
Houses myList[] = myHelper.getData();
for(int i =0; i < myList.length; i++) {
Log.d(TAG,myList[i].street);
}
Button myBtn1 = (Button)findViewById(R.id.addHouseButton);
myBtn1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(getApplicationContext(), AddHouse.class);
intent.putExtra("func", "update"); // Use to pass items to next page
startActivity(intent); // Start Activity
}
});
}
public Houses[] getData() {
Log.d(TAG, "Starting getData");
SQLiteDatabase db = helper.getWritableDatabase();
String[] columns = {myHelper.UID, myHelper.ADDRESS, myHelper.STREET, myHelper.CITY, myHelper.STATE, myHelper.ZIP, myHelper.ENTIRE_ADDRESS, myHelper.UPLOADS, myHelper.DOWNLOADS};
Cursor cursor = db.query(myHelper.TABLE_NAME_LOCATION, columns, null, null, null, null, null);
int cnt = cursor.getCount();
Houses[] listings;
listings = new Houses[cnt];
cnt = 0;
while (cursor.moveToNext()) {
int index0 = cursor.getColumnIndex(myHelper.UID);
int index1 = cursor.getColumnIndex(myHelper.ADDRESS);
int index2 = cursor.getColumnIndex(myHelper.STREET);
int index3 = cursor.getColumnIndex(myHelper.CITY);
int index4 = cursor.getColumnIndex(myHelper.STATE);
int index5 = cursor.getColumnIndex(myHelper.ZIP);
int index6 = cursor.getColumnIndex(myHelper.ENTIRE_ADDRESS);
int index7 = cursor.getColumnIndex(myHelper.UPLOADS);
int index8 = cursor.getColumnIndex(myHelper.DOWNLOADS);
String z = cursor.getString(index0);
String a = cursor.getString(index1);
String b = cursor.getString(index2);
String c = cursor.getString(index3);
String d = cursor.getString(index4);
String e = cursor.getString(index5);
String f = cursor.getString(index6);
String g = cursor.getString(index7);
String h = cursor.getString(index8);
listings[cnt] = new Houses(z, a, b, c, d, e, f, g, h);
Log.d(TAG, listings[cnt].UID + listings[cnt].address + listings[cnt].street + listings[cnt].city + listings[cnt].state + listings[cnt].zip + listings[cnt].upload + listings[cnt].download);
//buffer.append(f + "\n");
cnt++;
}
//Log.d(TAG, "Returning From getData");
//return listings;
cursor.close();
db.close();
//return "";
return listings;
}
Change your method signature to
public Houses[] getData() {

How to Install safari extension using setup project?

i have a working safari extension and i able to install it manually by dragging it on safari web browser. i want to know how can i install it programmatically.
i have done this for firefox, chrome and IE.
in firefox just copy your .xpi file to this folder ("C:\Users\admin\AppData\Roaming\Mozilla\Firefox\Profiles\xxx.default\extensions") in windows 7 and your extension will get installed.
and in chrome you have to write these registry keys
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Google\Chrome\Extensions\dlilbimladfdhkfbbcbjjnbleakbogef]
"version"="3.6"
"path"="C:\\extension.crx"
but in safari when i copy my .safariextz file to this folder "C:\Users\admin\AppData\Local\Apple Computer\Safari\Extensions" than extension not get installed.
can anybody guide me how can i do this.
In the folder:
~\Users\\AppData\Local\Apple Computer\Safari\Extensions
there is a file named Extensions.plist you will also need to add an entry for your extension in this file.
Extension.plist in "~\Users\AppData\Local\Apple Computer\Safari\Extensions" folder is a binary file. for read and add an entry we can use this class.
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace PlistCS
{
public static class Plist
{
private static List<int> offsetTable = new List<int>();
private static List<byte> objectTable = new List<byte>();
private static int refCount;
private static int objRefSize;
private static int offsetByteSize;
private static long offsetTableOffset;
#region Public Functions
public static object readPlist(string path)
{
using (FileStream f = new FileStream(path, FileMode.Open, FileAccess.Read))
{
return readPlist(f);
}
}
public static object readPlistSource(string source)
{
return readPlist(System.Text.Encoding.UTF8.GetBytes(source));
}
public static object readPlist(byte[] data)
{
return readPlist(new MemoryStream(data));
}
public static plistType getPlistType(Stream stream)
{
byte[] magicHeader = new byte[8];
stream.Read(magicHeader, 0, 8);
if (BitConverter.ToInt64(magicHeader, 0) == 3472403351741427810)
{
return plistType.Binary;
}
else
{
return plistType.Xml;
}
}
public static object readPlist(Stream stream, plistType type = plistType.Auto)
{
if (type == plistType.Auto)
{
type = getPlistType(stream);
stream.Seek(0, SeekOrigin.Begin);
}
if (type == plistType.Binary)
{
using (BinaryReader reader = new BinaryReader(stream))
{
byte[] data = reader.ReadBytes((int)reader.BaseStream.Length);
return readBinary(data);
}
}
else
{
using (BinaryReader reader = new BinaryReader(stream))
{
byte[] data = reader.ReadBytes((int)reader.BaseStream.Length);
return readBinary(data);
}
}
}
public static void writeBinary(object value, string path)
{
using (BinaryWriter writer = new BinaryWriter(new FileStream(path, FileMode.Create)))
{
writer.Write(writeBinary(value));
}
}
public static void writeBinary(object value, Stream stream)
{
using (BinaryWriter writer = new BinaryWriter(stream))
{
writer.Write(writeBinary(value));
}
}
public static byte[] writeBinary(object value)
{
offsetTable.Clear();
objectTable.Clear();
refCount = 0;
objRefSize = 0;
offsetByteSize = 0;
offsetTableOffset = 0;
//Do not count the root node, subtract by 1
int totalRefs = countObject(value) - 1;
refCount = totalRefs;
objRefSize = RegulateNullBytes(BitConverter.GetBytes(refCount)).Length;
composeBinary(value);
writeBinaryString("bplist00", false);
offsetTableOffset = (long)objectTable.Count;
offsetTable.Add(objectTable.Count - 8);
offsetByteSize = RegulateNullBytes(BitConverter.GetBytes(offsetTable[offsetTable.Count - 1])).Length;
List<byte> offsetBytes = new List<byte>();
offsetTable.Reverse();
for (int i = 0; i < offsetTable.Count; i++)
{
offsetTable[i] = objectTable.Count - offsetTable[i];
byte[] buffer = RegulateNullBytes(BitConverter.GetBytes(offsetTable[i]), offsetByteSize);
Array.Reverse(buffer);
offsetBytes.AddRange(buffer);
}
objectTable.AddRange(offsetBytes);
objectTable.AddRange(new byte[6]);
objectTable.Add(Convert.ToByte(offsetByteSize));
objectTable.Add(Convert.ToByte(objRefSize));
var a = BitConverter.GetBytes((long)totalRefs + 1);
Array.Reverse(a);
objectTable.AddRange(a);
objectTable.AddRange(BitConverter.GetBytes((long)0));
a = BitConverter.GetBytes(offsetTableOffset);
Array.Reverse(a);
objectTable.AddRange(a);
return objectTable.ToArray();
}
#endregion
#region Private Functions
private static object readBinary(byte[] data)
{
offsetTable.Clear();
List<byte> offsetTableBytes = new List<byte>();
objectTable.Clear();
refCount = 0;
objRefSize = 0;
offsetByteSize = 0;
offsetTableOffset = 0;
List<byte> bList = new List<byte>(data);
List<byte> trailer = bList.GetRange(bList.Count - 32, 32);
parseTrailer(trailer);
objectTable = bList.GetRange(0, (int)offsetTableOffset);
offsetTableBytes = bList.GetRange((int)offsetTableOffset, bList.Count - (int)offsetTableOffset - 32);
parseOffsetTable(offsetTableBytes);
return parseBinary(0);
}
private static int countObject(object value)
{
int count = 0;
switch (value.GetType().ToString())
{
case "System.Collections.Generic.Dictionary`2[System.String,System.Object]":
Dictionary<string, object> dict = (Dictionary<string, object>)value;
foreach (string key in dict.Keys)
{
count += countObject(dict[key]);
}
count += dict.Keys.Count;
count++;
break;
case "System.Collections.Generic.List`1[System.Object]":
List<object> list = (List<object>)value;
foreach (object obj in list)
{
count += countObject(obj);
}
count++;
break;
default:
count++;
break;
}
return count;
}
private static byte[] writeBinaryDictionary(Dictionary<string, object> dictionary)
{
List<byte> buffer = new List<byte>();
List<byte> header = new List<byte>();
List<int> refs = new List<int>();
for (int i = dictionary.Count - 1; i >= 0; i--)
{
var o = new object[dictionary.Count];
dictionary.Values.CopyTo(o, 0);
composeBinary(o[i]);
offsetTable.Add(objectTable.Count);
refs.Add(refCount);
refCount--;
}
for (int i = dictionary.Count - 1; i >= 0; i--)
{
var o = new string[dictionary.Count];
dictionary.Keys.CopyTo(o, 0);
composeBinary(o[i]);//);
offsetTable.Add(objectTable.Count);
refs.Add(refCount);
refCount--;
}
if (dictionary.Count < 15)
{
header.Add(Convert.ToByte(0xD0 | Convert.ToByte(dictionary.Count)));
}
else
{
header.Add(0xD0 | 0xf);
header.AddRange(writeBinaryInteger(dictionary.Count, false));
}
foreach (int val in refs)
{
byte[] refBuffer = RegulateNullBytes(BitConverter.GetBytes(val), objRefSize);
Array.Reverse(refBuffer);
buffer.InsertRange(0, refBuffer);
}
buffer.InsertRange(0, header);
objectTable.InsertRange(0, buffer);
return buffer.ToArray();
}
private static byte[] composeBinaryArray(List<object> objects)
{
List<byte> buffer = new List<byte>();
List<byte> header = new List<byte>();
List<int> refs = new List<int>();
for (int i = objects.Count - 1; i >= 0; i--)
{
composeBinary(objects[i]);
offsetTable.Add(objectTable.Count);
refs.Add(refCount);
refCount--;
}
if (objects.Count < 15)
{
header.Add(Convert.ToByte(0xA0 | Convert.ToByte(objects.Count)));
}
else
{
header.Add(0xA0 | 0xf);
header.AddRange(writeBinaryInteger(objects.Count, false));
}
foreach (int val in refs)
{
byte[] refBuffer = RegulateNullBytes(BitConverter.GetBytes(val), objRefSize);
Array.Reverse(refBuffer);
buffer.InsertRange(0, refBuffer);
}
buffer.InsertRange(0, header);
objectTable.InsertRange(0, buffer);
return buffer.ToArray();
}
private static byte[] composeBinary(object obj)
{
byte[] value;
switch (obj.GetType().ToString())
{
case "System.Collections.Generic.Dictionary`2[System.String,System.Object]":
value = writeBinaryDictionary((Dictionary<string, object>)obj);
return value;
case "System.Collections.Generic.List`1[System.Object]":
value = composeBinaryArray((List<object>)obj);
return value;
case "System.Byte[]":
value = writeBinaryByteArray((byte[])obj);
return value;
case "System.Double":
value = writeBinaryDouble((double)obj);
return value;
case "System.Int32":
value = writeBinaryInteger((int)obj, true);
return value;
case "System.String":
value = writeBinaryString((string)obj, true);
return value;
case "System.DateTime":
value = writeBinaryDate((DateTime)obj);
return value;
case "System.Boolean":
value = writeBinaryBool((bool)obj);
return value;
default:
return new byte[0];
}
}
public static byte[] writeBinaryDate(DateTime obj)
{
List<byte> buffer = new List<byte>(RegulateNullBytes(BitConverter.GetBytes(PlistDateConverter.ConvertToAppleTimeStamp(obj)), 8));
buffer.Reverse();
buffer.Insert(0, 0x33);
objectTable.InsertRange(0, buffer);
return buffer.ToArray();
}
public static byte[] writeBinaryBool(bool obj)
{
List<byte> buffer = new List<byte>(new byte[1] { (bool)obj ? (byte)9 : (byte)8 });
objectTable.InsertRange(0, buffer);
return buffer.ToArray();
}
private static byte[] writeBinaryInteger(int value, bool write)
{
List<byte> buffer = new List<byte>(BitConverter.GetBytes((long)value));
buffer = new List<byte>(RegulateNullBytes(buffer.ToArray()));
while (buffer.Count != Math.Pow(2, Math.Log(buffer.Count) / Math.Log(2)))
buffer.Add(0);
int header = 0x10 | (int)(Math.Log(buffer.Count) / Math.Log(2));
buffer.Reverse();
buffer.Insert(0, Convert.ToByte(header));
if (write)
objectTable.InsertRange(0, buffer);
return buffer.ToArray();
}
private static byte[] writeBinaryDouble(double value)
{
List<byte> buffer = new List<byte>(RegulateNullBytes(BitConverter.GetBytes(value), 4));
while (buffer.Count != Math.Pow(2, Math.Log(buffer.Count) / Math.Log(2)))
buffer.Add(0);
int header = 0x20 | (int)(Math.Log(buffer.Count) / Math.Log(2));
buffer.Reverse();
buffer.Insert(0, Convert.ToByte(header));
objectTable.InsertRange(0, buffer);
return buffer.ToArray();
}
private static byte[] writeBinaryByteArray(byte[] value)
{
List<byte> buffer = new List<byte>(value);
List<byte> header = new List<byte>();
if (value.Length < 15)
{
header.Add(Convert.ToByte(0x40 | Convert.ToByte(value.Length)));
}
else
{
header.Add(0x40 | 0xf);
header.AddRange(writeBinaryInteger(buffer.Count, false));
}
buffer.InsertRange(0, header);
objectTable.InsertRange(0, buffer);
return buffer.ToArray();
}
private static byte[] writeBinaryString(string value, bool head)
{
List<byte> buffer = new List<byte>();
List<byte> header = new List<byte>();
foreach (char chr in value.ToCharArray())
buffer.Add(Convert.ToByte(chr));
if (head)
{
if (value.Length < 15)
{
header.Add(Convert.ToByte(0x50 | Convert.ToByte(value.Length)));
}
else
{
header.Add(0x50 | 0xf);
header.AddRange(writeBinaryInteger(buffer.Count, false));
}
}
buffer.InsertRange(0, header);
objectTable.InsertRange(0, buffer);
return buffer.ToArray();
}
private static byte[] RegulateNullBytes(byte[] value)
{
return RegulateNullBytes(value, 1);
}
private static byte[] RegulateNullBytes(byte[] value, int minBytes)
{
Array.Reverse(value);
List<byte> bytes = new List<byte>(value);
for (int i = 0; i < bytes.Count; i++)
{
if (bytes[i] == 0 && bytes.Count > minBytes)
{
bytes.Remove(bytes[i]);
i--;
}
else
break;
}
if (bytes.Count < minBytes)
{
int dist = minBytes - bytes.Count;
for (int i = 0; i < dist; i++)
bytes.Insert(0, 0);
}
value = bytes.ToArray();
Array.Reverse(value);
return value;
}
private static void parseTrailer(List<byte> trailer)
{
offsetByteSize = BitConverter.ToInt32(RegulateNullBytes(trailer.GetRange(6, 1).ToArray(), 4), 0);
objRefSize = BitConverter.ToInt32(RegulateNullBytes(trailer.GetRange(7, 1).ToArray(), 4), 0);
byte[] refCountBytes = trailer.GetRange(12, 4).ToArray();
Array.Reverse(refCountBytes);
refCount = BitConverter.ToInt32(refCountBytes, 0);
byte[] offsetTableOffsetBytes = trailer.GetRange(24, 8).ToArray();
Array.Reverse(offsetTableOffsetBytes);
offsetTableOffset = BitConverter.ToInt64(offsetTableOffsetBytes, 0);
}
private static void parseOffsetTable(List<byte> offsetTableBytes)
{
for (int i = 0; i < offsetTableBytes.Count; i += offsetByteSize)
{
byte[] buffer = offsetTableBytes.GetRange(i, offsetByteSize).ToArray();
Array.Reverse(buffer);
offsetTable.Add(BitConverter.ToInt32(RegulateNullBytes(buffer, 4), 0));
}
}
private static object parseBinaryDictionary(int objRef)
{
Dictionary<string, object> buffer = new Dictionary<string, object>();
List<int> refs = new List<int>();
int refCount = 0;
byte dictByte = objectTable[offsetTable[objRef]];
int refStartPosition;
refCount = getCount(offsetTable[objRef], out refStartPosition);
if (refCount < 15)
refStartPosition = offsetTable[objRef] + 1;
else
refStartPosition = offsetTable[objRef] + 2 + RegulateNullBytes(BitConverter.GetBytes(refCount), 1).Length;
for (int i = refStartPosition; i < refStartPosition + refCount * 2 * objRefSize; i += objRefSize)
{
byte[] refBuffer = objectTable.GetRange(i, objRefSize).ToArray();
Array.Reverse(refBuffer);
refs.Add(BitConverter.ToInt32(RegulateNullBytes(refBuffer, 4), 0));
}
for (int i = 0; i < refCount; i++)
{
buffer.Add((string)parseBinary(refs[i]), parseBinary(refs[i + refCount]));
}
return buffer;
}
private static object parseBinaryArray(int objRef)
{
List<object> buffer = new List<object>();
List<int> refs = new List<int>();
int refCount = 0;
byte arrayByte = objectTable[offsetTable[objRef]];
int refStartPosition;
refCount = getCount(offsetTable[objRef], out refStartPosition);
if (refCount < 15)
refStartPosition = offsetTable[objRef] + 1;
else
//The following integer has a header aswell so we increase the refStartPosition by two to account for that.
refStartPosition = offsetTable[objRef] + 2 + RegulateNullBytes(BitConverter.GetBytes(refCount), 1).Length;
for (int i = refStartPosition; i < refStartPosition + refCount * objRefSize; i += objRefSize)
{
byte[] refBuffer = objectTable.GetRange(i, objRefSize).ToArray();
Array.Reverse(refBuffer);
refs.Add(BitConverter.ToInt32(RegulateNullBytes(refBuffer, 4), 0));
}
for (int i = 0; i < refCount; i++)
{
buffer.Add(parseBinary(refs[i]));
}
return buffer;
}
private static int getCount(int bytePosition, out int newBytePosition)
{
byte headerByte = objectTable[bytePosition];
byte headerByteTrail = Convert.ToByte(headerByte & 0xf);
int count;
if (headerByteTrail < 15)
{
count = headerByteTrail;
newBytePosition = bytePosition + 1;
}
else
count = (int)parseBinaryInt(bytePosition + 1, out newBytePosition);
return count;
}
private static object parseBinary(int objRef)
{
byte header = objectTable[offsetTable[objRef]];
switch (header & 0xF0)
{
case 0:
{
//If the byte is
//0 return null
//9 return true
//8 return false
return (objectTable[offsetTable[objRef]] == 0) ? (object)null : ((objectTable[offsetTable[objRef]] == 9) ? true : false);
}
case 0x10:
{
return parseBinaryInt(offsetTable[objRef]);
}
case 0x20:
{
return parseBinaryReal(offsetTable[objRef]);
}
case 0x30:
{
return parseBinaryDate(offsetTable[objRef]);
}
case 0x40:
{
return parseBinaryByteArray(offsetTable[objRef]);
}
case 0x50://String ASCII
{
return parseBinaryAsciiString(offsetTable[objRef]);
}
case 0x60://String Unicode
{
return parseBinaryUnicodeString(offsetTable[objRef]);
}
case 0xD0:
{
return parseBinaryDictionary(objRef);
}
case 0xA0:
{
return parseBinaryArray(objRef);
}
}
throw new Exception("This type is not supported");
}
public static object parseBinaryDate(int headerPosition)
{
byte[] buffer = objectTable.GetRange(headerPosition + 1, 8).ToArray();
Array.Reverse(buffer);
double appleTime = BitConverter.ToDouble(buffer, 0);
DateTime result = PlistDateConverter.ConvertFromAppleTimeStamp(appleTime);
return result;
}
private static object parseBinaryInt(int headerPosition)
{
int output;
return parseBinaryInt(headerPosition, out output);
}
private static object parseBinaryInt(int headerPosition, out int newHeaderPosition)
{
byte header = objectTable[headerPosition];
int byteCount = (int)Math.Pow(2, header & 0xf);
byte[] buffer = objectTable.GetRange(headerPosition + 1, byteCount).ToArray();
Array.Reverse(buffer);
//Add one to account for the header byte
newHeaderPosition = headerPosition + byteCount + 1;
return BitConverter.ToInt32(RegulateNullBytes(buffer, 4), 0);
}
private static object parseBinaryReal(int headerPosition)
{
byte header = objectTable[headerPosition];
int byteCount = (int)Math.Pow(2, header & 0xf);
byte[] buffer = objectTable.GetRange(headerPosition + 1, byteCount).ToArray();
Array.Reverse(buffer);
return BitConverter.ToDouble(RegulateNullBytes(buffer, 8), 0);
}
private static object parseBinaryAsciiString(int headerPosition)
{
int charStartPosition;
int charCount = getCount(headerPosition, out charStartPosition);
var buffer = objectTable.GetRange(charStartPosition, charCount);
return buffer.Count > 0 ? Encoding.ASCII.GetString(buffer.ToArray()) : string.Empty;
}
private static object parseBinaryUnicodeString(int headerPosition)
{
int charStartPosition;
int charCount = getCount(headerPosition, out charStartPosition);
charCount = charCount * 2;
byte[] buffer = new byte[charCount];
byte one, two;
for (int i = 0; i < charCount; i += 2)
{
one = objectTable.GetRange(charStartPosition + i, 1)[0];
two = objectTable.GetRange(charStartPosition + i + 1, 1)[0];
if (BitConverter.IsLittleEndian)
{
buffer[i] = two;
buffer[i + 1] = one;
}
else
{
buffer[i] = one;
buffer[i + 1] = two;
}
}
return Encoding.Unicode.GetString(buffer);
}
private static object parseBinaryByteArray(int headerPosition)
{
int byteStartPosition;
int byteCount = getCount(headerPosition, out byteStartPosition);
return objectTable.GetRange(byteStartPosition, byteCount).ToArray();
}
#endregion
}
public enum plistType
{
Auto, Binary, Xml
}
public static class PlistDateConverter
{
public static long timeDifference = 978307200;
public static long GetAppleTime(long unixTime)
{
return unixTime - timeDifference;
}
public static long GetUnixTime(long appleTime)
{
return appleTime + timeDifference;
}
public static DateTime ConvertFromAppleTimeStamp(double timestamp)
{
DateTime origin = new DateTime(2001, 1, 1, 0, 0, 0, 0);
return origin.AddSeconds(timestamp);
}
public static double ConvertToAppleTimeStamp(DateTime date)
{
DateTime begin = new DateTime(2001, 1, 1, 0, 0, 0, 0);
TimeSpan diff = date - begin;
return Math.Floor(diff.TotalSeconds);
}
}
}
and use this method in commit action of Installer.cs class to add an entry of extension Extension.plist
public void InstallSafariExt()
{
string safariExtPlist = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\Apple Computer\\Safari\\Extensions\\Extensions.plist";
string safariSetupPlist = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) + "\YourComp\\YourSoft\\Extensions.plist";
string ExtDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\Apple Computer\\Safari\\Extensions";
if (!Directory.Exists(ExtDir))
{
Directory.CreateDirectory(ExtDir);
if (!File.Exists(safariExtPlist))
{
File.Copy(safariSetupPlist, safariExtPlist);
}
}
else
{
if (!File.Exists(safariExtPlist))
{
File.Copy(safariSetupPlist, safariExtPlist);
}
}
object obj = Plist.readPlist(safariExtPlist);
Dictionary<string, object> dict = (Dictionary<string, object>)obj;
Dictionary<string, object> NewExt = new Dictionary<string, object>();
NewExt.Add("Hidden Bars", new List<object>());
NewExt.Add("Added Non-Default Toolbar Items", new List<object>());
NewExt.Add("Enabled", true);
NewExt.Add("Archive File Name", "YourExtName.safariextz");
NewExt.Add("Removed Default Toolbar Items", new List<object>());
NewExt.Add("Bundle Directory Name", "YourExtName.safariextension");
List<object> listExt = (List<object>)dict["Installed Extensions"];
listExt.Add(NewExt);
Plist.writeBinary(obj, safariExtPlist);
string safariExtFile = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) + "\YourComp\\YourSoft\\YourExtName.safariextz";
string safariInstallfolder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\Apple Computer\\Safari\\Extensions\\YourExtName.safariextz";
string[] safExtFiles = Directory.GetFiles(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\Apple Computer\\Safari\\Extensions\\", "YourExtName*.safariextz");
for (int i = 0; i < safExtFiles.Length; i++)
{
if (File.Exists(safExtFiles[i]))
File.Delete(safExtFiles[i]);
}
File.Copy(safariExtFile, safariInstallfolder);
}

Resources