C++ beginner here. Wondering what the syntax is for this piece of Java code on restricting user input. Here is an example of a Java code I wrote
while (!in.hasNext("[A-Za-z]+")){}
Where "in" is my scanner variable. This piece of code runs when the input is not a real number, and returns an error message with the option to enter something in again. I haven't been able to find the equivalent of this "range" condition on C++. Any help would be appreciated.
EDIT:
I have tried using the regex function in Dev C++ but it gives me a warning like this:
#ifndef _CXX0X_WARNING_H
#define _CXX0X_WARNING_H 1
#if __cplusplus < 201103L
#error This file requires compiler and library support for the \
ISO C++ 2011 standard. This support is currently experimental, and must be \
enabled with the -std=c++11 or -std=gnu++11 compiler options.
#endif
#endif
Does this mean that I cant use the regex function in Dev C++?
Example:
cin >> inputStr;
if (std::regex_match (inputStr, std::regex("[A-Za-z]+") )) {
// do something, will you ?
}
Note: you will need to include <regex>.
More info: http://www.cplusplus.com/reference/regex/regex_match/
If you wan to loop until you get a real number then you can use:
do
{
cin >> input;
} while(std::regex_match (input, std::regex("[A-Za-z]+")));
You can also use std::stod() to convert a std::string to a double. Doing that will make sure you are getting a valid real number since a number and have e/E in it. You can do that with:
std::string input;
double value;
size_t pos;
do
{
cin >> input;
value = stod(input, &pos);
} while (pos < input.size());
Related
I want to make a little modification to the Android source to meet my requirement. Here is the requirement:
I want index all the objects in an Android app by adding one more public int field to the java.lang.Object class. Therefore, all the classes can inherit the newly added field because all of them are the subclasses of the Object class.
What I have done so far is modify the java.lang.Object class under <Android_source>/libcore/libart/src/main/java/java/lang folder and recompile the source.
I want to ask if I am doing the right thing. Can my Android app recognize this change (e.g. can a String object access the newly added field)?
Edit
After around 3 weeks try and error, I finally got the complete answer. I want to share this experience with others if anybody else want to modify the core java libraries of Android source (e.g., modifying Object.java and String.java etc.). Again, as mentioned by Michael, please note that such a modification may only be suitable for research or testing purpose.
The key challenge in making a successful modification (here 'successful' means the modified Android source can be built and run on emulators or real devices without any problem) is that some of the classes in the core java library have their C++ mirrors (located in <Android_source>/art/runtime/mirrors/). When modifying these java classes, you should also make the same modifications to their C++ mirrors. Otherwise, you could fail the build process because there are a bunch of checkings that you need to pass. Since I only add a new field to the Object.java, I will list some checkings (or requirements) I encountered below:
1.The size of an object instance = the size of its C++ mirror. For example, if I add a long field into Object.java, I should also add a uint64_t field to its C++ mirror to make their size equal.
2.Try to make the size of an object instance be the power of 2 (e.g., 2, 4, 8, 16, ...). For example, the size of the original Object.java is 8, therefore I add a long field to increase the size to 16. If I add an int field, the size becomes 12 and it can fail many checkings. I don't figure out the exact reason but I guess it has something to do with memory alignment.
3.Try to put primitive-type fields after non-primitive-type fields and primitive-type fields should be ordered by size. This means you should put reference-type fields in the front, followed by 8-byte-primitive-type fields, then 4-byte-primitive-type fields, then 2-byte-primitive-type fields, then 1-byte-primitive-type fields. Again, I guess the reason is memory alignment
That's all I done to meet my requirements. I am open to any discussions if you have any ideas about the purpose of these checkings (especially the 2ed and 3rd one)
New edit
More specifically, I did the following things:
Add a new field (e.g., public long tag;) in Object.java
Change static constexpr uint32_t kObjectHeaderSize = kUseBrooksReadBarrier ? 16 : 8; to static constexpr uint32_t kObjectHeaderSize = kUseBrooksReadBarrier ? 24 : 16; in Object.h
Add the following method in Object.h (Only on Android 7)
static MemberOffset TagOffset() {
return OFFSET_OF_OBJECT_MEMBER(Object, tag);
}
Add a new public field public: uint64_t tag; in Object.h
Change
#define MIRROR_OBJECT_CLASS_OFFSET 0
ADD_TEST_EQ(MIRROR_OBJECT_CLASS_OFFSET, art::mirror::Object::ClassOffset().Int32Value())
#define MIRROR_OBJECT_LOCK_WORD_OFFSET 4
ADD_TEST_EQ(MIRROR_OBJECT_LOCK_WORD_OFFSET, art::mirror::Object::MonitorOffset().Int32Value())
#if defined(USE_BROOKS_READ_BARRIER)
#define MIRROR_OBJECT_HEADER_SIZE 16
#else
#define MIRROR_OBJECT_HEADER_SIZE 8
to
#define MIRROR_OBJECT_CLASS_OFFSET 0
ADD_TEST_EQ(MIRROR_OBJECT_CLASS_OFFSET, art::mirror::Object::ClassOffset().Int32Value())
#define MIRROR_OBJECT_LOCK_WORD_OFFSET 4
ADD_TEST_EQ(MIRROR_OBJECT_LOCK_WORD_OFFSET, art::mirror::Object::MonitorOffset().Int32Value())
#define MIRROR_OBJECT_CLASS_TAG 8
ADD_TEST_EQ(MIRROR_OBJECT_CLASS_TAG, art::mirror::Object::TagOffset().Int32Value())
#if defined(USE_BROOKS_READ_BARRIER)
#define MIRROR_OBJECT_HEADER_SIZE 24
#else
#define MIRROR_OBJECT_HEADER_SIZE 16
in asm_support.h (Only on Android 7)
Add addOffset(OFFSETOF_MEMBER(mirror::Object, tag), "tag"); in class_linker_test.cc
Change
static_assert(kObjectHeaderSize == sizeof(mirror::HeapReference<mirror::Class>) +
sizeof(LockWord),
to
static_assert(kObjectHeaderSize == sizeof(mirror::HeapReference<mirror::Class>) +
sizeof(LockWord) + 8,
in art/runtime/gc/collector/concurrent_copying.cc
8 Change static constexpr size_t kFirstElementOffset = 12u; to static constexpr size_t kFirstElementOffset = 20u; in array.h
9 Change static constexpr size_t kObjectAlignmentShift = 3; to static constexpr size_t kObjectAlignmentShift = 4; in runtime_globals.h (Not done yet)
10 Change
static_assert(kObjectAlignment == 8, "Alignment check");
class PACKED(8) ImageHeader {
to
static_assert(kObjectAlignment == 16, "Alignment check");
class PACKED(16) ImageHeader {
in image.h (Not done yet)
11 Change static constexpr size_t kAlignment = 8; to static constexpr size_t kAlignment = 16; in gc::space::BumpPointerSpace (Not done yet)
12 Change #!/usr/bin/python to #!/usr/local/bin/python in device/generic/goldfish/tools/mk_combined_img.py (The value depends on your /bin/env python)(Only on Android 10)
13 Change
#define DCHECK_ALIGNED_PARAM(value, alignment) \
DCHECK(::art::IsAlignedParam(value, alignment)) << reinterpret_cast<const void*>(value)
to
#define DCHECK_ALIGNED_PARAM(value, alignment) \
DCHECK(::art::IsAlignedParam(value, alignment)) << reinterpret_cast<const void*>(value) << "," << alignment
in art/libartbase/base/bit_utils.h (for debug purpose)(Only for Android 11)
14 Change
DCHECK_ALIGNED_PARAM(remaining_space, object_class->GetObjectSize());
Object* end = dst + remaining_space / object_class->GetObjectSize();
to
DCHECK_ALIGNED_PARAM(remaining_space, kObjectAlignment);
Object* end = dst + remaining_space / kObjectAlignment;
in art/dex2oat/linker/image_writer.cc (Only for Android 11)
Change
memcpy(reinterpret_cast<uint8_t*>(to_ref) + kObjectHeaderSize,
reinterpret_cast<const uint8_t*>(from_ref) + kObjectHeaderSize,
obj_size - kObjectHeaderSize);
to
memcpy(reinterpret_cast<uint8_t*>(to_ref) + kObjectHeaderSize - 8,
reinterpret_cast<const uint8_t*>(from_ref) + kObjectHeaderSize - 8,
obj_size - kObjectHeaderSize + 8);
in concurrent_copying.cc (on Android 10)(reference)
Firstly, I'd like to state that I don't think this is a good idea and is probably overkill outside of research purposes. If you are modifying AOSP then the code you write will be dependent on the target device running that customised build of AOSP. However, it is still possible.
I'm assuming you already know how to compile and flash a custom AOSP build to a device. In order to write code that makes use of your new functionality, you'll also need to compile a custom SDK. This is so that Android Studio will know that your new method exists within Object, and can compile correctly against it. The full documentation can be found here, but essentially it boils down to:
. build/envsetup.sh
lunch sdk-eng
make sdk
When you have your SDK zip file, you'll need to unzip it to your SDK's platforms directory - it should now show up checked in your SDK manager. If you have given your SDK a custom platform ID then you should be able to use that in your build.gradle files.
Disclaimer: This advice is purely from memory, it's a lengthy process so I've not had time to double-check, and chances are there may be a couple of minor things I've missed. This should get you most of the way towards where you want to be though.
This is a Peter Norvig's repl function:
def repl(prompt='lis.py> '):
"A prompt-read-eval-print loop."
while True:
val = eval(parse(raw_input(prompt)))
if val is not None:
print(schemestr(val))
def schemestr(exp):
"Convert a Python object back into a Scheme-readable string."
if isinstance(exp, List):
return '(' + ' '.join(map(schemestr, exp)) + ')'
else:
return str(exp)
Which works:
>>> repl()
lis.py> (define r 10)
lis.py> (* pi (* r r))
314.159265359
lis.py> (if (> (* 11 11) 120) (* 7 6) oops)
42
lis.py>
I'm trying to write program with the same functionality in Java, tried classes from Java docs, but nothing works like that; any idea? Thanks.
A REPL is called REPL because it is a Loop that Reads and Evaluates code and Prints the results. In Lisp, the code is literally:
(LOOP (PRINT (EVAL (READ))))
In an unstructured language, it would be something like:
#loop:
$code ← READ;
$res ← EVAL($code);
PRINT($res);
GOTO #loop;
That's where the name comes from.
In Java, it would be something like:
while (true) {
Code code = read(System.in);
Object res = eval(code);
System.out.println(res);
}
But, there are no methods corresponding to READ or EVAL in Java or the JRE. You will have to write read, eval, and Code yourself. Note that read is essentially a parser for Java, and eval is an interpreter for Java. Both the syntax and the semantics for Java are described in the Java Language Specification, all you have to do is read the JLS and implement those two methods.
I am preparing an R wrapper for a java code that I didn't write myself (and in fact I don't know java). I am trying to use rJava for the first time and I am struggling to get the .jcall right.
Here is an extract of the java code for which I write a wrapper:
public class Model4R{
[...cut...]
public String[][] runModel(String dir, String initFileName, String[] variableNames, int numSims) throws Exception {
[...cut...]
dir and initFileName are character strings for the directory and file name with initial conditions, variable names is a list of character strings that I would write like this in R: c("var1", "var2", "var3", ...) and can be of length from one to five. Finally, numSim is an integer.
Here is my tentative R code for a wrapper function:
runmodel <- function(dir, inFile, varNames, numSim){
hjw <- .jnew("Model4R")
out <- .jcall(hjw, "[[Ljava/lang/String", "runModel", as.character(dir), as.character(inFile), as.vector(varNames), as.integer(numSim))
return(out)
}
The error in R is:
Error in .jcall(hjw, "[[Ljava/lang/String", "runModel", as.character(dir),
: method runModel with signature (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;II)[[Ljava/lang/String not found
I suspect that the JNI type isn't correct for String[][]. Anyhow, any help that could direct me towards a solution would be welcome!
You're missing a semicolon at the end of the JNI for String[][] - it should be "[[Ljava/lang/String;". Also, I think you need to call .jarray instead of as.vector on varNames. The R error is telling you that rJava thinks the class of the third argument is Ljava/lang/String; instead of [Ljava/lang/String;.
I am using SWIG to generate an interface to some C code which I have compiled as an Android NDK library. My C code NDK library uses a structure, MY_STRUCT that contains char* elements that pass data in both the in and out directions and the SWIG generated JNI works fine as far as that goes, ie I can read the strings in the C code, set data and read the result in the Java code as required.
However I have a problem in that if I pass in a java String that contains null bytes the nulls are replaced by "\300\200"
Eg, if I create a string in java as follows :
MY_STRUCT myStruct = new MY_STRUCT();
byte[] myBytes = new byte[21];
String myString = new String(myBytes);
myStruct.setName(myString);
then myStruct has it's name field set to 21 null bytes as required and this is visible in the java debugger, but the string passed across to my NDK library code as seen in the NDK C debugger is as follows :
"\300\200\300\200\300\200\300\200\300\200\300\200\300\200\300\200\300\200\300\200\300\200\300\200\300\200\300\200\300\200\300\200\300\200\300\200\300\200\300\200\300\200"
My SWIG .i file has the following relevant portion :
%include various.i
%include cpointer.i
%pointer_functions(int, intp);
%include ../../../mydir/myheader.h
myheader.h has the following relevant portion :
typedef struct
{
...
char* name;
...
} *P_MY_STRUCT, MY_STRUCT;
The C code debugs fine and I can read and write all the strings pointed to by the name etc elements of MY_STRUCT, the only issue is the transformation of null elements of the strings input to the SWIG generated JNI code into the strange "\300\200" elements in the C code in the NDK library.
EDIT:
Considering an alternative : I have several functions that take byte arrays instead of strings for C-function char* arguments and this is achieved in the myModule.i file as follows :
bool myFunc(P_MY_STRUCT, char* BYTE, int32_t);
Is there any way in SWIG of achieving the equivalent of the BYTE functionality for structure members ? I tried using the same BYTE trick in myModule.i as follows but it didn't work :
typedef struct
{
...
char* BYTE;
...
} *P_MY_STRUCT, MY_STRUCT;
Thanks again,
This is known crazy behavior by Java and described in the answers to this question:
What does it mean to say "Java Modified UTF-8 Encoding"?
I have a purely native Android NDK app, and need to retrieve values such as:
android.os.Build.MODEL
Unfortunately I cannot find good examples of how to go about this?
These values are easy to obtain in native code via the interface defined in <sys/system_properties.h>, which has been around since the first NDK release. You just need to know the string identifier used on the Java side. Fortunately, with an open-source OS, we can find these easily. Here is a working example of retrieving the model name.
#include <sys/system_properties.h>
//
// Public codes are defined in http://developer.android.com/reference/java/lang/System.html#getProperty(java.lang.String).
// Codes below are defined in https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/os/Build.java.
// Items with * are intended for display to the end user.
//
#define ANDROID_OS_BUILD_VERSION_RELEASE "ro.build.version.release" // * The user-visible version string. E.g., "1.0" or "3.4b5".
#define ANDROID_OS_BUILD_VERSION_INCREMENTAL "ro.build.version.incremental" // The internal value used by the underlying source control to represent this build.
#define ANDROID_OS_BUILD_VERSION_CODENAME "ro.build.version.codename" // The current development codename, or the string "REL" if this is a release build.
#define ANDROID_OS_BUILD_VERSION_SDK "ro.build.version.sdk" // The user-visible SDK version of the framework.
#define ANDROID_OS_BUILD_MODEL "ro.product.model" // * The end-user-visible name for the end product..
#define ANDROID_OS_BUILD_MANUFACTURER "ro.product.manufacturer" // The manufacturer of the product/hardware.
#define ANDROID_OS_BUILD_BOARD "ro.product.board" // The name of the underlying board, like "goldfish".
#define ANDROID_OS_BUILD_BRAND "ro.product.brand" // The brand (e.g., carrier) the software is customized for, if any.
#define ANDROID_OS_BUILD_DEVICE "ro.product.device" // The name of the industrial design.
#define ANDROID_OS_BUILD_PRODUCT "ro.product.name" // The name of the overall product.
#define ANDROID_OS_BUILD_HARDWARE "ro.hardware" // The name of the hardware (from the kernel command line or /proc).
#define ANDROID_OS_BUILD_CPU_ABI "ro.product.cpu.abi" // The name of the instruction set (CPU type + ABI convention) of native code.
#define ANDROID_OS_BUILD_CPU_ABI2 "ro.product.cpu.abi2" // The name of the second instruction set (CPU type + ABI convention) of native code.
#define ANDROID_OS_BUILD_DISPLAY "ro.build.display.id" // * A build ID string meant for displaying to the user.
#define ANDROID_OS_BUILD_HOST "ro.build.host"
#define ANDROID_OS_BUILD_USER "ro.build.user"
#define ANDROID_OS_BUILD_ID "ro.build.id" // Either a changelist number, or a label like "M4-rc20".
#define ANDROID_OS_BUILD_TYPE "ro.build.type" // The type of build, like "user" or "eng".
#define ANDROID_OS_BUILD_TAGS "ro.build.tags" // Comma-separated tags describing the build, like "unsigned,debug".
#define ANDROID_OS_BUILD_FINGERPRINT "ro.build.fingerprint" // A string that uniquely identifies this build. 'BRAND/PRODUCT/DEVICE:RELEASE/ID/VERSION.INCREMENTAL:TYPE/TAGS'.
char model_id[PROP_VALUE_MAX]; // PROP_VALUE_MAX from <sys/system_properties.h>.
int len;
len = __system_property_get(ANDROID_OS_BUILD_MODEL, model_id); // On return, len will equal (int)strlen(model_id).
The NDK isn't meant to replace the Java based API but to supplement it. To get Build you'll have to find its private implementation in C/C++ or provide the information from Java via JNI.
Pseudo Code:
android_main(struct *android_app){
JNIEnv *env = android_app->activity->env;
jclass build_class = FindClass(env, "android.os.Build");
jfieldID brand_id = GetStaticFieldID(env, build_class, "BRAND", "Ljava/lang/String;");
jstring brand_obj = (jstring)GetStaticObjectField(env, brand_id);
}
I don't think you can do this unfortunately. You could always start in VM and jump down via JNI to native after retrieving the values you want to access.