How to make Delphi and Android use the same charset? - android

I'm doing a project for anwsering questionnaires. The user creates the project with the questions on Delphi, than exports the project in a .txt file to Android, where the file is read and the user can answer. My problem is in characters like á,à,É,Ú, that appear like a ? in Android, with the code 65533. So, I need to know how to configure Android and Delphi to work in the same charset.

Android is Linux based and so presumably uses UTF-8. On the other hand, Android is also very Java-like and so possibly prefers UTF-16.
If you need the file to be UTF-8, you can do it like this, assuming you have your text in a TStringList.
StringList.SaveToFile(FileName, TEncoding.UTF8);
This will include a BOM in the file which I imagine Android won't like—Windows UTF-8 apps tend to use BOMs, but not Linux. If you want to output without a BOM do it like this:
type
TUTF8EncodingNoBOM = class(TUTF8Encoding)
public
function GetPreamble: TBytes; override;
end;
function TUTF8EncodingNoBOM.GetPreamble: TBytes;
begin
Result := nil;
end;
...
var
UTF8EncodingNoBOM: TEncoding;//make this a global variable
...
UTF8EncodingNoBOM := TUTF8EncodingNoBOM.Create;//create in a unit initialization, remember to free it
...
StringList.SaveToFile(FileName, UTF8EncodingNoBOM);
If you discover you need UTF-16 then use TEncoding.Unicode for UTF-16LE or TEncoding.BigEndianUnicode for UTF-16BE. If you need to strip the BOM then that's easy enough with the same technique as above.
Summary
Work out what encoding you need, and its endianness.
Find an appropriate TEncoding.
Use TStrings.SaveToFile with that TEncoding instance.

Use Unicode. UTF-16 or UTF-8 should work fine.
See Davids answer for an explanation why this should work and how to do it in D2009 and newer.
For Delphi 2007 and older you have to use another solution, UTF8Encode + Ansi TStringList can be used, you can also convert your strings to WideStrings and use WideStrings.
To write UTF-8 using D2007 and older see this question:
How can a text file be converted from ANSI to UTF-8 with Delphi 7?
To write UTF-16 using D2007 you can use the WideStrings unit which contains a TWideStringList. Beware that this class doesn't write the BOM by default.
There are also other WideStringList implementations for older Delphi versions out there.

Related

Does Kotlin code gets "minified" when compiled?

In Typescript (or JavaScript) I always try to write in a way that if I (or another developer) has to touch my code in one year, it is really easy to understand what is happening. So I do not try to find the shortest code possible but the clearer one.
I do not worry about the size of the file because I know in production this function:
function myFunction(value: number) {
if(otherFunction(number){
return true;
}
if(yetAtherFunction(number){
return true;
}
return false;
}
will be converted to this:
function myFunction(n){return!!otherFunction(n)||!!yetAtherFunction(n)}
Would something similar happens with kotlin?
I ask because I offen find this kind of code:
val myDrawable = item?.image?.let { Uri.parse(it.toString()) } ?: R.drawable.my_default_image
and to me it is not easy to do a fast parse to know what is happening why doing a PR or similar.
If I write that in a more verbose way, would it have an impact on the size of the final apk ?
Important:
To clarify, I am not asking is it better to write in this or that way? I am asking if the compiler tries to optimize the input like a typescript/javascript minifier does.
In Kotlin / Java world, all code must get compiled into bytecode before it can run anywhere, and in general this is basically an incredibly optimized binary blob where whitespace doesn't exist.
In interpreted languages like JS, the client / browser downloads a copy of the source and runs the source directly. Minifying is super important in these cases because it reduces the size of the file clients need to download by removing logically redundant characters. In TS, most clients cannot run it directly, so it instead gets transpiled into JS, and that is what is typically served to browsers / clients. (Some exceptions like Deno exist for example, which has a native ts interpreter).
The reason you see inlined code stuffed into one line, is purely for cosmetic / code style purposes.
Additional whitespace and variable names generally have no impact on the size / performance of your compiled Android app, so you can simply write code in the way that seems most presentable to you.

How to use unordered_map in Android?

I am trying to use a hash_map, defined in the Android NDK, but I get a "deprecation warning":
ndk/sources/cxx-stl/gnu-libstdc++/4.6/include/ext/../backward/backward_warning.h:33:2:
error: #warning This file includes at least one deprecated or antiquated header which may
be removed without further notice at a future date. Please use a non-deprecated interface
with equivalent functionality instead. For a listing of replacement headers and
interfaces, consult the file backward_warning.h. To disable this warning use -Wno-
deprecated. [-Werror=cpp]
And since "unordered_map" is present in gnu-libstdc++/4.6/include/ and also in gnu-libstdc++/4.6/include/tr1/, I believe that there is a way to use it.
The point is that I cannot find it. Which of the following is the right one (if any):
#include <tr1/unordered_map.h>
#include <unordered_map>
And then, how to use it? __gnu_cxx::unordered_map is not recognized... and I don't know how to find this information.
In case you don't want/need C++11 support, you can use the one from the STLPort using:
// Here we are referencing the stlport one:
#include <unordered_map>
...
std::tr1::unordered_map<int, int> test;
That's because STLPort defines unordered_map inside tr1 namespace, but the STLPort header is not inside any /tr1/ folder.
I eventually found a way by adding C++11 support in my Android project. Pretty easy when we know it, but I took some time to figure it out. Neither STLPort nor Boost were needed. Once C++11 was integrated, I could use "unordered_map" as follows:
#include <unordered_map>
...
std::unordered_map<int, int> test;
I created a new question to explain how to enable C++11 support in Android here.

Is File.separatorChar based on OS, locale or something else?

100% of the Java work I do is on Android. When constructing file paths, I always make sure to use File.pathSeparator File.separatorChar instead of "/".
What determines the value of File.pathSeperator? Are there any Android devices where File.pathSeparator File.separatorChar will not be "/" ?
According to the source code of File.java, pathSeparator is pulled from the char System.getProperty("path.separator", ":").charAt(0). separator, on the other hand, comes from System.getProperty("file.separator", "/").charAt(0).
Because Android is Linux-based, it should always be /. However, I have seen glitches where : has appeared instead (Motorola Droid; see bug report), by using the default value above.
When I code, I always use /... to be honest, I don't think it's necessary to reference the File class (this would mostly be for non-Android work). It's just best to stick to /, I think.
Additionally, according to this answer (pertains to Java, not just Android), / can safely be used on all Java platforms, and it will figure out what it needs to use internally.
I think you mean File.separator and File.separatorChar right? If you look in the docs it states:
public static final char separatorChar
The system-dependent character used to separate components in filenames ('/'). Use of this (rather than hard-coding '/') helps portability to other operating systems.
This field is initialized from the system property "file.separator". Later changes to that property will have no effect on this field or this class.
It is system-dependent. Technically it could be possible for someone to implement Android on a non-Linux platform (see BlueStacks) where the path separator is something other than '/'. In practice, I'd imagine you can get away with using '/' mostly without issue but it's a good habit to use these fields instead.

Android - cross-platform friendly debug/logger macro

I am building C++ code that is used on both android and iOS. I need some form of debugger macro to insert debugging easily into the code.
For example, I was thinking of something like this:
#ifdef ANDROID
# define MY_DEBUG(debugmsg) __android_log_print(ANDROID_LOG_INFO, ANDROID_DEBUG_TAG,debugmsg)
# define MY_DEBUG(debugmsg, mystr) __android_log_print(ANDROID_LOG_INFO, ANDROID_DEBUG_TAG,debugmsg,mystr)
#elif defined (iOS)
# define MY_DEBUG(debugmsg) printf(debugmsg)
# define MY_DEBUG(debugmsg, mystr) printf(debugmsg, mystr)
#endif
So for example I could use MY_DEBUG("hello %s","world") and MY_DEBUG("hello")
However it complains about macro redefinition (and rightfully so). How do I make a macro.. 'overload', or accept more than one parameter if entered?
Also - does printf() send data to the iOS console?
You can't overload macros the way you can with functions because the preprocessor has not changed significantly, if at all, since C. A common approach is to use MY_DEBUG and MY_DEBUG2 etc.
There are variatic macros but I avoid them in multi-platform code.

What's the difference in GCC between -std=gnu++0x and -std=c++0x and which one should be used?

I'm having troubles with <stdint.h> when using -std=c++0x in GCC 4.4.3 (for Android):
// using -std=c++0x
#include <stdint.h>
uint64_t value; // error: 'uint64_t' does not name a type
But using -std=gnu++0x works:
// using -std=gnu++0x
#include <stdint.h>
uint64_t value; // OK
Is <stdint.h> incompatible with C++0x?
So far as I can tell, I think this could be argued an implementation bug (or actually, since C++0x isn't published, not a bug per se but an incomplete implementation of the current state of the upcoming standard).
Here's why, referring to n3225 for the expected behavior of -std=c++0x:
D.7 says
Every C header, each of which has a
name of the form name.h, behaves as if
each name placed in the standard
library namespace by the corresponding
cname header is placed within the
global namespace scope
OK, so far so easy. What does <cstdint> place in the standard library namespace?
18.4.1:
typedef unsigned integer type uint64_t; // optional
How optional? 18.4.1/2:
The header defines all functions,
types, and macros the same as 7.18 in
the C standard
Drat. What does the C standard say? Taking out n1256, 7.18.1.1/3:
These types are optional. However,
if an implementation provides integer
types with widths of 8, 16, 32, or 64
bits, no padding bits, and (for the
signed types) that have a
two's complement representation, it
shall define the corresponding typedef
names
But hang on, surely on Android with -std=c++0x GCC does provide a 64 bit unsigned type with no padding bits: unsigned long long. So <cstdint> is required to provide std::uint64_t and hence stdint.h is required to provide uint64_t in the global namespace.
Go on, someone tell me why I'm wrong :-) One possibility is that C++0x refers to "ISO/IEC 9899:1999 Programming languages — C" without specifying a version. Can it really be that (a) 7.18.1.1/3 was added in one of the TCs, and also (b) C++0x intends to reference the original standard as of 1999, not the amendments since then? I doubt either of these is the case, but I don't have the original C99 on hand to check (a) and I'm not even sure how to check (b).
Edit: oh, as for which one should be used -std=c++0x isn't really a strict standards-compliant mode yet, since there isn't a strict standard yet. And even if there was a standard, gcc 4.4.3 certainly isn't a finished implementation of it. So I see no great need to use it if -std=gnu++0x is actually more complete, at least in this respect for your combination of gcc version and platform.
However, gnu++0x will enable other GNU extensions, that you might not want your code to use. If you're aiming to write portable C++0x, then eventually you'd want to switch to -std=c++0x. But I don't think GCC 4.4 or any other C++0x implementation-in-progress is complete enough yet for it to be practical to write code from the (draft) standard, such that you could say with a straight face "I'm programming C++0x, and it's only 2011!". So I'd say, use whichever one works, and understand that whichever one you use now, you'll probably be switching to -std=c++11 eventually anyway.

Categories

Resources