How to load quickdic dictionary into C# - c#

I have downloaded a dictionary file from http://code.google.com/p/quickdic-dictionary/
But the file extension is .quickdic and is not plain text.
How can I load the quickdic dictionaries (.quickdic) into c# to make simple word queries?

I browsed through the git code, and a few things stuck out.
First, in the DictionaryActivity.java file, there is the following in onCreate():
final String name = application.getDictionaryName(dictFile.getName());
this.setTitle("QuickDic: " + name);
dictRaf = new RandomAccessFile(dictFile, "r");
dictionary = new Dictionary(dictRaf);
That Dictionary Class is not the built in class with Java, but is here according to the imports:
import com.hughes.android.dictionary.engine.Dictionary;
When I look there, it shows a constructor for a Dictionary taking a RandomAccessFile as the parameter. Here's that source code:
public Dictionary(final RandomAccessFile raf) throws IOException {
dictFileVersion = raf.readInt();
if (dictFileVersion < 0 || dictFileVersion > CURRENT_DICT_VERSION) {
throw new IOException("Invalid dictionary version: " + dictFileVersion);
}
creationMillis = raf.readLong();
dictInfo = raf.readUTF();
// Load the sources, then seek past them, because reading them later disrupts the offset.
try {
final RAFList<EntrySource> rafSources = RAFList.create(raf, new EntrySource.Serializer(this), raf.getFilePointer());
sources = new ArrayList<EntrySource>(rafSources);
raf.seek(rafSources.getEndOffset());
pairEntries = CachingList.create(RAFList.create(raf, new PairEntry.Serializer(this), raf.getFilePointer()), CACHE_SIZE);
textEntries = CachingList.create(RAFList.create(raf, new TextEntry.Serializer(this), raf.getFilePointer()), CACHE_SIZE);
if (dictFileVersion >= 5) {
htmlEntries = CachingList.create(RAFList.create(raf, new HtmlEntry.Serializer(this), raf.getFilePointer()), CACHE_SIZE);
} else {
htmlEntries = Collections.emptyList();
}
indices = CachingList.createFullyCached(RAFList.create(raf, indexSerializer, raf.getFilePointer()));
} catch (RuntimeException e) {
final IOException ioe = new IOException("RuntimeException loading dictionary");
ioe.initCause(e);
throw ioe;
}
final String end = raf.readUTF();
if (!end.equals(END_OF_DICTIONARY)) {
throw new IOException("Dictionary seems corrupt: " + end);
}
So, anyway, this is how his java code reads the file in.
Hopefully, this helps you simulate this in C#.
From here you would probably want to see how he is serializing the EntrySource, PairEntry, TextEntry, and HtmlEntry, as well as the indexSerializer.
Next look to see how RAFList.create() works.
Then see how that result is incorporated in creating a CachingList using CachingList.create()
Disclaimer: I'm not sure if the built in serializer in C# uses the same format as Java's, so you may need to simulate that too :)

Related

Solidworks C# can't extract item from feature that has TypeName equals "Reference"

i have opened solidworks assembly (swDocumentTypes_e.swDocASSEMBLY) using C# and i have iterated through all the features in order to get all the Sketchs called 'ISO/XXX' under each part of the assembly, here is the code
public void openFile(string skeletonFilePath)
{
object[] Features = null;
int i = 0;
string FeatType = null;[1]
string FeatTypeName = null;
if (string.IsNullOrWhiteSpace(skeletonFilePath)) { return; }
ModelDoc2 model = _sldWorks.OpenDoc("C:PATH/fileName.SLDASM", (int)swDocumentTypes_e.swDocASSEMBLY);
Feature swFeat = default(Feature);
SelectionMgr swSelMgr = default(SelectionMgr);
swSelMgr = (SelectionMgr)model.SelectionManager;
swFeat = (Feature)model.FirstFeature();
while ((swFeat != null))
{
FeatType = swFeat.Name;
FeatTypeName = swFeat.GetTypeName2();
if ((FeatTypeName == "Reference")
{
Debug.Print(" Name of feature: " + swFeat.Name);
Debug.Print(" Type of feature: " + swFeat.GetTypeName2());
}
swFeat = (Feature)swFeat.GetNextFeature();
}
}
the problem:
each time i try to extract the items under the feature (of one part) i got an exception, i have to tried these ways:
swFeat.GetDefinition() // i've got null exception
swFeat.GetSpecificFeature2() // i've got dynamic value which i don't know the class i need to cast with
var childs = (Object[])swFeatSupport.GetChildren(); // i've got only to constraints under the part
example of project
Your code is only iterating over top level features. You can use IFeature::GetFirstSubFeature() and IFeature::GetNextSubFeature to get sub feature. Make this function recursive so it will iterate over all features, regardless of how many levels deep they are. Another layer you need to consider is the components - you need to iterate over components in an assembly first if you need feature data in the context of individual parts.
Here's an example from the Solidworks API documentation. Its poorly written (IMO) but it will guide you in the right direction.

When loading data it gives an error " InvalidCastException: Specified cast is not valid "

e.g. I want to select a character and save his number
private Storage storage;
void Awake()
{
storage = new Storage();
}
public void SelectChar1()
{
numberChar = 1;//byte
storage.Save(DataPlayerSave);//save works fine
}
on awakening, the number is loaded
private DataPlayerSave dataPlayer;
private byte numberChar;
private void Awake()
{
dataPlayer = (DataPlayerSave)storage.Load(new DataPlayerSave());
numberChar = dataPlayer.numerChar;
}
I tried to divide the data into several parts and one large file, the result is almost always the same (sometimes everything works)
public class Storage()
{
public object Load(object saveDataByDefault)
{
filePath = Application.persistentDataPath + "/saves/GameSave.save";
if (!File.Exists(filePath))
{
if (saveDataByDefault != null)
{
Save(saveDataByDefault);
return saveDataByDefault;
}
}
var file = File.Open(filePath, FileMode.Open);
var saveData = formatter.Deserialize(file);
file.Close();
return saveData;
}
}
There are also similar classes that load data at the beginning of the scene. If there are 2 or more of them, then it gives an error, if 1, then everything works. I tried to set the sequence using the Coroutine did not help.
When loading data it gives an error "InvalidCastException: Specified cast is not valid."
dataPlayer = (DataPlayerSave)storage.Load(new DataPlayerSave());
if formatter is BinaryFormatter: please don't do that - it will hurt you; as for the exception: fundamentally, use a debugger and step through the code. In particular, if you say that the exception is coming from:
dataPlayer = (DataPlayerSave)storage.Load(new DataPlayerSave());
then we can assume that Load is not returning a DataPlayerSave. So: what is it? We can't tell you, but: you can find out:
var obj = storage.Load(new DataPlayerSave());
var type = obj.GetType(); // put a break-point here
Log(type.FullName); // or just log it
dataPlayer = (DataPlayerSave)obj;
and investigate what exactly obj is. Note that BinaryFormatter is very brittle as you change types (rename, move, refactor, etc) - but that isn't even the top reason not to use it.

C# - Saving and Loading data to file

I decided to get into coding and am learning c#, after making a few small projects, I decided to step it up a little and make a text adventure game, with saving and loading, and if I get to feeling zany I'll try to add some multiplayer. While I haven't really hit a road block because of it, I can't help but feel that I am doing load function REALLY sub-optimally. The save is fine, I feel like it works for me, but the load I feel can be really simplified, I just don't know what to use.
I also wouldn't really mind, but with this way, if I add other attributes/skills or whatever else that needs to be saved, I will have to add everything to the load function as well, and it will be even longer.
I have tried to search around on here, the c# documentation, and other sites, but can't find a solution that works for this case. can anyone help me find a better way of doing this? Or is this the best I can really do since it's varying data types?
Edit: To simplify and clarify what answer I am searching for, I am trying to find a simpler and more scalable way to save and load the data to a file.
static void LoadGame(CharData PlayerData)
{
Console.WriteLine("Enter the name of the character to load as shown below.");
//getting current directory info, setting to di
DirectoryInfo di = new DirectoryInfo(Directory.GetCurrentDirectory());
//need to initialize these outside of a loop
int SaveFiles = 0;
string DisplayName = " ";
int DisplayNameLength = 0;
//looks through files in working directory ending in '.fasv', displays them in format '{x}. John Smith'
foreach (var fi in di.GetFiles("*.fasv"))
{
SaveFiles++;
DisplayNameLength = fi.Name.Length;
//remove .fasv from displayed name to make it look nicer
DisplayName = fi.Name.Remove(DisplayNameLength - 5, 5);
Console.WriteLine(SaveFiles.ToString() + ". " + DisplayName);
}
string toLoad = Console.ReadLine();
using StreamReader sr = new StreamReader(toLoad + ".fasv");
//the name is easy to get since it's a string. but integers...
PlayerData.Name = sr.ReadLine();
//... not so much. i hate all of this and i feel like it's gross, but i don't know how else to do it
int hp, xp, level, toughness, innovation, mind, empathy, spryness;
Int32.TryParse(sr.ReadLine(), out hp);
Int32.TryParse(sr.ReadLine(), out xp);
Int32.TryParse(sr.ReadLine(), out level);
Int32.TryParse(sr.ReadLine(), out toughness);
Int32.TryParse(sr.ReadLine(), out innovation);
Int32.TryParse(sr.ReadLine(), out mind);
Int32.TryParse(sr.ReadLine(), out empathy);
Int32.TryParse(sr.ReadLine(), out spryness);
PlayerData.Health = hp;
PlayerData.Level = level;
PlayerData.XP = xp;
PlayerData.Toughness = toughness;
PlayerData.Innovation = innovation;
PlayerData.Mind = mind;
PlayerData.Empathy = empathy;
PlayerData.Spryness = spryness;
sr.Close();
InGame(PlayerData);
}
static void SaveGame(CharData PlayerData)
{
using (StreamWriter sw = new StreamWriter(PlayerData.Name + ".fasv"))
{
foreach (System.Reflection.PropertyInfo stat in PlayerData.GetType().GetProperties())
{
//write player data properties to file line by line, using stat to iterate through the player data properties
sw.WriteLine(stat.GetValue(PlayerData));
}
sw.Close();
}
}
If you aren't set on a particular data format for the file data, I would recommend using a serializer such as JSON.NET. You can use NuGet to add newtonsoft.json to your project, and that would allow you to just do something similar to:
using (StreamWriter file = File.CreateText(pathToPlayerFile))
{
var serializer = new JsonSerializer();
serializer.Serialize(file, playerData);
}
And then your code to read from the file would be pretty similar:
using (var file = File.OpenText(pathToPlayerFile))
{
var serializer = new JsonSerializer();
return (CharData)serializer.Deserialize(file, typeof(CharData));
}
I borrowed those code snippets from newtonsoft.com. CreateText will create (or overwrite) the file and write the object as a JSON object.

When using MergeField FieldCodes in OpenXml SDK in C# why do field codes disappear or fragment?

I have been working successfully with the C# OpenXml SDK (Unofficial Microsoft Package 2.5 from NuGet) for some time now, but have recently noticed that the following line of code returns different results depending on what mood Microsoft Word appears to be in when the file gets saved:
var fields = document.Descendants<FieldCode>();
From what I can tell, when creating the document in the first place (using Word 2013 on Windows 8.1) if you use the Insert->QuickParts->Field and choose MergeField from the Field names left hand pane, and then provide a Field name in the field properties and click OK then the field code is correctly saved in the document as I would expect.
Then when using the aforementioned line of code I will receive a field code count of 1 field. If I subsequently edit this document (and even leave this field well alone) the subsequent saving could mean that this field code no longer is returned in my query.
Another case of the same curiousness is when I see the FieldCode nodes split across multiple items. So rather than seeing say:
" MERGEFIELD Author \\* MERGEFORMAT "
As the node name, I will see:
" MERGEFIELD Aut"
"hor \\* MERGEFORMAT"
Split as two FieldCode node values. I have no idea why this would be the case, but it certainly makes my ability to match nodes that much more exciting. Is this expected behaviour? A known bug? I don't really want to have to crack open the raw xml and edit this document to work until I understand what is going on. Many thanks all.
I came across this very problem myself, and found a solution that exists within OpenXML: a utility class called MarkupSimplifier which is part of the PowerTools for Open XML project. Using this class solved all the problems I was having that you describe.
The full article is located here.
Here are some pertinent exercepts :
Perhaps the most useful simplification that this performs is to merge adjacent runs with identical formatting.
It goes on to say:
Open XML applications, including Word, can arbitrarily split runs as necessary. If you, for instance, add a comment to a document, runs will be split at the location of the start and end of the comment. After MarkupSimplifier removes comments, it can merge runs, resulting in simpler markup.
An example of the utility class in use is:
SimplifyMarkupSettings settings = new SimplifyMarkupSettings
{
RemoveComments = true,
RemoveContentControls = true,
RemoveEndAndFootNotes = true,
RemoveFieldCodes = false,
RemoveLastRenderedPageBreak = true,
RemovePermissions = true,
RemoveProof = true,
RemoveRsidInfo = true,
RemoveSmartTags = true,
RemoveSoftHyphens = true,
ReplaceTabsWithSpaces = true,
};
MarkupSimplifier.SimplifyMarkup(wordDoc, settings);
I have used this many times with Word 2010 documents using VS2015 .Net Framework 4.5.2 and it has made my life much, much easier.
Update:
I have revisited this code and have found it clears upon runs on MERGEFIELDS but not IF FIELDS that reference mergefields e.g.
{if {MERGEFIELD When39} = "Y???" "Y" "N" }
I have no idea why this might be so, and examination of the underlying XML offers no hints.
Word will often split text runs with into multiple text runs for no reason I've ever understood. When searching, comparing, tidying etc. We preprocess the body with method which combines multiple runs into a single text run.
/// <summary>
/// Combines the identical runs.
/// </summary>
/// <param name="body">The body.</param>
public static void CombineIdenticalRuns(W.Body body)
{
List<W.Run> runsToRemove = new List<W.Run>();
foreach (W.Paragraph para in body.Descendants<W.Paragraph>())
{
List<W.Run> runs = para.Elements<W.Run>().ToList();
for (int i = runs.Count - 2; i >= 0; i--)
{
W.Text text1 = runs[i].GetFirstChild<W.Text>();
W.Text text2 = runs[i + 1].GetFirstChild<W.Text>();
if (text1 != null && text2 != null)
{
string rPr1 = "";
string rPr2 = "";
if (runs[i].RunProperties != null) rPr1 = runs[i].RunProperties.OuterXml;
if (runs[i + 1].RunProperties != null) rPr2 = runs[i + 1].RunProperties.OuterXml;
if (rPr1 == rPr2)
{
text1.Text += text2.Text;
runsToRemove.Add(runs[i + 1]);
}
}
}
}
foreach (W.Run run in runsToRemove)
{
run.Remove();
}
}
I tried to simplify the document with Powertools but the result was a corrupted word file. I make this routine for simplify only fieldcodes that has specifics names, works in all parts on the docs (maindocumentpart, headers and footers):
internal static void SimplifyFieldCodes(WordprocessingDocument document)
{
var masks = new string[] { Constants.VAR_MASK, Constants.INP_MASK, Constants.TBL_MASK, Constants.IMG_MASK, Constants.GRF_MASK };
SimplifyFieldCodesInElement(document.MainDocumentPart.RootElement, masks);
foreach (var headerPart in document.MainDocumentPart.HeaderParts)
{
SimplifyFieldCodesInElement(headerPart.Header, masks);
}
foreach (var footerPart in document.MainDocumentPart.FooterParts)
{
SimplifyFieldCodesInElement(footerPart.Footer, masks);
}
}
internal static void SimplifyFieldCodesInElement(OpenXmlElement element, string[] regexpMasks)
{
foreach (var run in element.Descendants<Run>()
.Select(item => (Run)item)
.ToList())
{
var fieldChar = run.Descendants<FieldChar>().FirstOrDefault();
if (fieldChar != null && fieldChar.FieldCharType == FieldCharValues.Begin)
{
string fieldContent = "";
List<Run> runsInFieldCode = new List<Run>();
var currentRun = run.NextSibling();
while ((currentRun is Run) && currentRun.Descendants<FieldCode>().FirstOrDefault() != null)
{
var currentRunFieldCode = currentRun.Descendants<FieldCode>().FirstOrDefault();
fieldContent += currentRunFieldCode.InnerText;
runsInFieldCode.Add((Run)currentRun);
currentRun = currentRun.NextSibling();
}
// If there is more than one Run for the FieldCode, and is one we must change, set the complete text in the first Run and remove the rest
if (runsInFieldCode.Count > 1)
{
// Check fielcode to know it's one that we must simplify (for not to change TOC, PAGEREF, etc.)
bool applyTransform = false;
foreach (string regexpMask in regexpMasks)
{
Regex regex = new Regex(regexpMask);
Match match = regex.Match(fieldContent);
if (match.Success)
{
applyTransform = true;
break;
}
}
if (applyTransform)
{
var currentRunFieldCode = runsInFieldCode[0].Descendants<FieldCode>().FirstOrDefault();
currentRunFieldCode.Text = fieldContent;
runsInFieldCode.RemoveAt(0);
foreach (Run runToRemove in runsInFieldCode)
{
runToRemove.Remove();
}
}
}
}
}
}
Hope this helps!!!

Analysing C# source with Irony

This is what my team and I chose to do for our school project. Well, actually we haven't decided on how to parse the C# source files yet.
What we are aiming to achieve is, perform a full analysis on a C# source file, and produce up a report.
In which the report is going to contain stuff that happening in the codes.
The report only has to contain:
string literals
method names
variable names
field names
etc
I'm in charge of looking into this Irony library. To be honest, I don't know the best way to sort the data out into a clean readable report. I am using the C# grammar class packed with the zip.
Is there any step where I can properly identify each node children? (eg: using directives, namespace declaration, class declaration etc, method body)
Any help or advice would be very much appreciated. Thanks.
EDIT: Sorry I forgot to say we need to analysis the method calls too.
Your main goal is to master the basics of formal languages. A good start-up might be found here. This article describes the way to use Irony on the sample of a grammar of a simple numeric calculator.
Suppose you want to parse a certain file containing C# code the path to which you know:
private void ParseForLongMethods(string path)
{
_parser = new Parser(new CSharpGrammar());
if (_parser == null || !_parser.Language.CanParse()) return;
_parseTree = null;
GC.Collect(); //to avoid disruption of perf times with occasional collections
_parser.Context.SetOption(ParseOptions.TraceParser, true);
try
{
string contents = File.ReadAllText(path);
_parser.Parse(contents);//, "<source>");
}
catch (Exception ex)
{
}
finally
{
_parseTree = _parser.Context.CurrentParseTree;
TraverseParseTree();
}
}
And here is the traversal method itself with counting some info in the nodes. Actually this code counts the number of statements in every method of the class. If you have any question you are always welcome to ask me
private void TraverseParseTree()
{
if (_parseTree == null) return;
ParseNodeRec(_parseTree.Root);
}
private void ParseNodeRec(ParseTreeNode node)
{
if (node == null) return;
string functionName = "";
if (node.ToString().CompareTo("class_declaration") == 0)
{
ParseTreeNode tmpNode = node.ChildNodes[2];
currentClass = tmpNode.AstNode.ToString();
}
if (node.ToString().CompareTo("method_declaration") == 0)
{
foreach (var child in node.ChildNodes)
{
if (child.ToString().CompareTo("qual_name_with_targs") == 0)
{
ParseTreeNode tmpNode = child.ChildNodes[0];
while (tmpNode.ChildNodes.Count != 0)
{ tmpNode = tmpNode.ChildNodes[0]; }
functionName = tmpNode.AstNode.ToString();
}
if (child.ToString().CompareTo("method_body") == 0) //method_declaration
{
int statementsCount = FindStatements(child);
//Register bad smell
if (statementsCount>(((LongMethodsOptions)this.Options).MaxMethodLength))
{
//function.StartPoint.Line
int functionLine = GetLine(functionName);
foundSmells.Add(new BadSmellRegistry(name, functionLine,currentFile,currentProject,currentSolution,false));
}
}
}
}
foreach (var child in node.ChildNodes)
{ ParseNodeRec(child); }
}
I'm not sure this is what you need but you could use the CodeDom and CodeDom.Compiler namespaces to compile the C# code, and than analyze the results using Reflection, something like:
// Create assamblly in Memory
CodeSnippetCompileUnit code = new CodeSnippetCompileUnit(classCode);
CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerResults results = provider.CompileAssemblyFromDom(compileParams, code);
foreach(var type in results.CompiledAssembly)
{
// Your analysis go here
}
Update: In VS2015 you could use the new C# compiler (AKA Roslyn) to do the same, for example:
var root = (CompilationUnitSyntax)tree.GetRoot();
var compilation = CSharpCompilation.Create("HelloTDN")
.AddReferences(references: new[] { MetadataReference.CreateFromAssembly(typeof(object).Assembly) })
.AddSyntaxTrees(tree);
var model = compilation.GetSemanticModel(tree);
var nameInfo = model.GetSymbolInfo(root.Usings[0].Name);
var systemSymbol = (INamespaceSymbol)nameInfo.Symbol;
foreach (var ns in systemSymbol.GetNamespaceMembers())
{
Console.WriteLine(ns.Name);
}

Categories