Getting key without iterating in YAML-cpp - yaml-cpp

Is there an easy way to get the key in a map using YAML-cpp without iterating? I see in the instructions that I can use the first() method of the YAML-cpp iterator class, but I don't need to actually iterate. I have a key that I can identify by indentation level, but what I need to do now is throw an exception if the key is not one of a known list. My code currently looks like this:
std::string key;
if (doc.FindValue("goodKey")
{
// do stuff
key = "goodKey";
} else if (doc.FindValue("alsoGoodKey") {
// do stuff
key = "alsoGoodKey";
} else throw (std::runtime_error("unrecognized key");
// made it this far, now let's continue parsing
doc[key]["otherThing"] >> otherThingVar;
// etc.
See, I need the key string to continue parsing because otherThing is under goodKey in the YAML file. This works fine, but I'd like to tell the user what the unrecognized key was. I don't know how to access it, though. I don't see any functions in the header file that give me that value. How do I get it?

There isn't necessarily a single "unrecognized key". For example, your YAML file might look like:
someKey: [blah]
someOtherKey: [blah]
or it might even be empty, e.g., {}. In the former case, which one do you want? In the latter case, there are no keys.
You're asking for how to "get the key in a map", but maps can have zero or more keys.
As a side note, you can simplify some of this using the actual result of FindValue, assuming you don't actually need the name of the key that you grabbed. For example:
const YAML::Node *pNode = doc.FindValue("goodKey");
if(!pNode)
pNode = doc.FindValue("alsoGoodKey");
if(!pNode)
throw std::runtime_error("unrecognized key");
(*pNode)["otherThing"] >> otherThingVar;
// etc

Related

How to verify an instance of a List is not another List instance?

I have a list
var theDataList: List<Data> // populated with some data
and made a copy of it
val copy = theDataList.toMutableList()
downstream in the code it would like to verify whether it is the copy one or the original one
the .hashCode() returns same for both
If just want to use Log to print out, how to do it?
the Log.d("+++", "theDataList: ${theDataList.hashCode()}, copy: ${copy.hashCode()"}) print out same number.
And Log.d("+++", "copy: ${copy}") prints out the list content
Problem:
The hash code for both lists is the same because it is based on the data in the list, which is the same.
Solution:
What you actually want is to compare the references of both lists. You can do that with Kotlin's referential equality operator ===.
theDataList === copy // false
There is no ID/hash you can rely on to identify an object on the JVM the way you want. For more info take a look here.
Use the === operator to compare references are the same (not calling equals method)

Check field errors in word references with VSTO

How can I check if some fields in my word have errors? I have a large document that contains many references to other chapters or images. When those chapters or images are missing in the document, the fields containing those references will display Error! Reference Source Not Found instead of the reference.
The problem is, that I need to create an algorithm that will check for those reference errors, no matter what the locale and language of the file is. The problem is, that this field error is localized in the language of the system of the user who uses the word.
How can I do this? Is there any property on Field that can be used to check if the source is available?
Currently, I check for errors in the fields by using the result text of the field:
Int32 fieldErrors = 0;
foreach (Word.Field field in doc.Fields)
{
field.Update();
if (field.Result.Text.StartsWith("Error!"))
++fieldErrors;
}
Unfortunately, this will only work in english word instances.
In the documentation for Field types it is seen that a Field instance has an Update() method that returns a bool. The documentation does not state what the semantic meaning of the return value is, however, by doing a short empirical study I found that the method returns true if the Update() succeeded and false if the update did not succeed. This means that in order to find fields with errors you can do something like:
var fieldsWithErrors = new List<Field>();
foreach (Field field in document.Fields)
{
if(!field.Update())
fieldsWithErrors.Add(field);
}
... or shorter with LINQ:
var fieldsWithErrors = document.Fields.Cast<Field>().Where(field => !field.Update()).ToList();
Another (and faster) approach would be to use the Update() method exposed by the Fields collection.
var indexOfFirstError = document.Fields.Update();
... the method returns the index of the first field with an error. If no errors are found, the method returns 0.
For complete documentation please see the MSDN references:
Field.Update()
Fields.Update()
Field members
Fields members

Why does Javassist insist on looking for a default annotation value when one is explicitly specified?

I am using Javassist to add and modify annotations on a package-info "class".
In some cases, I need to deal with the following edge case. Someone has (incorrectly) specified an #XmlJavaTypeAdapters annotation on the package-info package, but has not supplied a value attribute (which is defined as being required). So it looks like this:
#XmlJavaTypeAdapters // XXX incorrect; value() is required, but javac has no problem
package com.foobar;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters;
In Javassist, this comes through slightly oddly.
The javassist.bytecode.annotation.Annotation representing the #XmlJavaTypeAdapters annotation does not have a member value (getMemberValue("value") returns null), as expected.
It is of course possible to add a value() member value, and that is what I've done:
if (adaptersAnnotation.getMemberValue("value") == null) {
final ArrayMemberValue amv = new ArrayMemberValue(new AnnotationMemberValue(constantPool), constantPool);
adaptersAnnotation.addMemberValue("value", amv);
annotationsAttribute.addAnnotation(adaptersAnnotation);
}
In the code snippet above, I've created a new member value to hold an array of annotations, because the value() attribute of #XmlJavaTypeAdapters is an array of #XmlJavaTypeAdapter. I've specified its array type by trying to divine the Zen-like documentation's intent—it seems that if you supply another MemberValue that this MemberValue will somehow serve as the array's type. In my case I want the type of the array to be #XmlJavaTypeAdapter, which is an annotation, so the only kind of MemberValue that seemed appropriate was AnnotationMemberValue. So I've created an empty one of those and set it as the array type.
This works fine as far as it goes, as long as you stay "within" Javassist.
However, something seems to have gone wrong. If I ask Javassist to convert all of its proprietary annotations into genuine Java java.lang.annotation.Annotations, then when I try to access the value() attribute of this #XmlJavaTypeAdapters annotation, Javassist tells me that there is no default value. Huh?
In other words, that's fine—indeed there is not—but I have specified what I had hoped was a zero-length array (that is, the default value shouldn't be used; my explicitly specified zero-length array should be used instead):
final List<Object> annotations = java.util.Arrays.asList(packageInfoClass.getAnnotations());
for (final Object a : annotations) {
System.out.println("*** class annotation: " + a); // OK; one of these is #XmlJavaTypeAdapters
System.out.println(" ...of type: " + a.getClass()); // OK; resolves to XmlJavaTypeAdapters
System.out.println(" ...assignable to java.lang.annotation.Annotation? " + java.lang.annotation.Annotation.class.isInstance(a)); // OK; returns true
if (a instanceof XmlJavaTypeAdapters) {
final XmlJavaTypeAdapters x = (XmlJavaTypeAdapters)a;
System.out.println(" ...value: " + java.util.Arrays.asList(x.value())); // XXX x.value() throws an exception
}
}
So why is Javassist looking for a default value in this case?
My larger issue is of course to handle this (unfortunately somewhat common) case where #XmlJavaTypeAdapters is specified with no further information on it. I need to add a value member value that can hold an array of #XmlJavaTypeAdapter annotations. I can't seem to figure out how to accomplish this with Javassist. As always, all help appreciated.
For posterity, it appears that in this particular case (to avoid a NullPointerException and/or a RuntimeException), you need to do this:
if (adaptersAnnotation.getMemberValue("value") == null) {
final ArrayMemberValue amv = new ArrayMemberValue(constantPool);
amv.setValue(new AnnotationMemberValue[0]);
adaptersAnnotation.addMemberValue("value", amv);
annotationsAttribute.addAnnotation(adaptersAnnotation);
}
Note in particular that I deliberately omit the array type when building the ArrayMemberValue (including one of any kind will result in an exception). Then I explicitly set its value to an empty array of type AnnotationMemberValue. Any other combination here will result in an exception.
Additionally, and very oddly, the last line in that if block is critical. Even though in this particular case the annotation itself was found, and so hence was already present in the AnnotationsAttribute, you must re-add it. If you do not, you will get a RuntimeException complaining about the lack of a default value.
I hope this helps other Javassist hackers.

Use UUID as action parameters in Play Framework

I'd like to use UUID as action parameters. However, unless I use .toString() on the UUID objects when generating the action URL's, Play seems to serialize the object differently; Something like this: referenceId.sequence=-1&referenceId.hashCode=1728064460&referenceId.version=-1&referenceId.variant=-1&referenceId.timestamp=-1&referenceId.node=-1
However, using toString "works", but when I redirect from one action to another by simply invoking the method directly, there's no way I can call toString, as the method expects a UUID. Therefore it gives me the representation shown above.
Is there any way I can intersect the serialization of a certain type?
aren't you able to just use string in your action parameter? you know that this string is an UUID, so you can always recreate UUID from it. Maybe this is not the solution for you but that's my first thought. As far as I know play serializes objects like that when passing them trough paremeters.
If this does not work for you try finding something here: http://www.playframework.org/documentation/1.2.4/controllers
I found a way to do this, but right now it means hacking a part of the frameworks code itself.
What you basically need is a TypeBinder for binding the value from the String to the UUID
and a small code change in
play/framework/src/play/data/binding/Unbinder.java
if (!isAsAnnotation) {
// We want to use that one so when redirecting it looks ok. We could as well use the DateBinder.ISO8601 but the url looks terrible
if (Calendar.class.isAssignableFrom(src.getClass())) {
result.put(name, new SimpleDateFormat(I18N.getDateFormat()).format(((Calendar) src).getTime()));
} else {
result.put(name, new SimpleDateFormat(I18N.getDateFormat()).format((Date) src));
}
}
}
//here's the changed code
else if (UUID.class.isAssignableFrom(src.getClass()))
{
result.put(name, src.toString());
}
else {
// this code is responsible for the behavior you're seeing right now
Field[] fields = src.getClass().getDeclaredFields();
for (Field field : fields) {
if ((field.getModifiers() & BeanWrapper.notwritableField) != 0) {
// skip fields that cannot be bound by BeanWrapper
continue;
}
I'm working with the framework authors on a fix for this. will come back later with results.
if you need this urgently, apply the change to the code yourself and rebuild the framework by issuing
ant
in the playframework/framework
directory.

Write a compiler for a language that looks ahead and multiple files?

In my language I can use a class variable in my method when the definition appears below the method. It can also call methods below my method and etc. There are no 'headers'. Take this C# example.
class A
{
public void callMethods() { print(); B b; b.notYetSeen();
public void print() { Console.Write("v = {0}", v); }
int v=9;
}
class B
{
public void notYetSeen() { Console.Write("notYetSeen()\n"); }
}
How should I compile that? what i was thinking is:
pass1: convert everything to an AST
pass2: go through all classes and build a list of define classes/variable/etc
pass3: go through code and check if there's any errors such as undefined variable, wrong use etc and create my output
But it seems like for this to work I have to do pass 1 and 2 for ALL files before doing pass3. Also it feels like a lot of work to do until I find a syntax error (other than the obvious that can be done at parse time such as forgetting to close a brace or writing 0xLETTERS instead of a hex value). My gut says there is some other way.
Note: I am using bison/flex to generate my compiler.
My understanding of languages that handle forward references is that they typically just use the first pass to build a list of valid names. Something along the lines of just putting an entry in a table (without filling out the definition) so you have something to point to later when you do your real pass to generate the definitions.
If you try to actually build full definitions as you go, you would end up having to rescan repatedly, each time saving any references to undefined things until the next pass. Even that would fail if there are circular references.
I would go through on pass one and collect all of your class/method/field names and types, ignoring the method bodies. Then in pass two check the method bodies only.
I don't know that there can be any other way than traversing all the files in the source.
I think that you can get it down to two passes - on the first pass, build the AST and whenever you find a variable name, add it to a list that contains that blocks' symbols (it would probably be useful to add that list to the corresponding scope in the tree). Step two is to linearly traverse the tree and make sure that each symbol used references a symbol in that scope or a scope above it.
My description is oversimplified but the basic answer is -- lookahead requires at least two passes.
The usual approach is to save B as "unknown". It's probably some kind of type (because of the place where you encountered it). So you can just reserve the memory (a pointer) for it even though you have no idea what it really is.
For the method call, you can't do much. In a dynamic language, you'd just save the name of the method somewhere and check whether it exists at runtime. In a static language, you can save it in under "unknown methods" somewhere in your compiler along with the unknown type B. Since method calls eventually translate to a memory address, you can again reserve the memory.
Then, when you encounter B and the method, you can clear up your unknowns. Since you know a bit about them, you can say whether they behave like they should or if the first usage is now a syntax error.
So you don't have to read all files twice but it surely makes things more simple.
Alternatively, you can generate these header files as you encounter the sources and save them somewhere where you can find them again. This way, you can speed up the compilation (since you won't have to consider unchanged files in the next compilation run).
Lastly, if you write a new language, you shouldn't use bison and flex anymore. There are much better tools by now. ANTLR, for example, can produce a parser that can recover after an error, so you can still parse the whole file. Or check this Wikipedia article for more options.