I have the following Visual Basic 6.0 function which writes an ANSI string to a new file over FTP. I would like it to write the file as UTF-16LE. Is there any good way to do that within this following method?
Public Sub writeToFile(ByVal FTPServer As String _
, ByVal userName As String _
, ByVal password As String _
, ByVal contents As String _
, ByVal destinationFile As String)
Dim hFile As Long
Dim lCount As Long
inetOpen
inetConnect FTPServer, userName, password
hFile = apiFtpOpenFile(m_hFTP, destinationFile, GENERIC_WRITE, FTP_TRANSFER_TYPE_BINARY, 0&)
If hFile = 0 Then
Err.Raise EWMFTPErrorCodes.wmFTPSendError, , internetError
End If
If apiInternetWriteFile(hFile, contents, Len(contents), lCount) = 0 Then
Err.Raise EWMFTPErrorCodes.wmFTPSendError, , internetError
End If
apiInternetCloseHandle hFile
End Sub
I haven't done Visual Basic 6.0 in about 10 years, so I'm shaky at best. Any input would be greatly appreciated.
Here is the apiInternetWriteFile declaration;
Private Declare Function apiInternetWriteFile Lib "wininet.dll" Alias "InternetWriteFile" ( _
ByVal hFile As Long _
, ByVal lpBuffer As String _
, ByVal dwNumberOfBytesToWrite As Long _
, ByRef lpdwNumberOfBytesWritten As Long) As Long
We need to see the declaration for apiInternetWriteFile. I'm pretty sure it's a Declare into an API call, maybe something in WinINet.dll. My guess is that you need to:
Change the Declare so it expects a ByVal Long for the 2nd argument
EDIT to get a BOM at the start, try Contents = ChrW(&HFEFF&) & Contents. Or possibly FFEF, not sure of the endianness.
Pass StrPtr(contents) for the 2nd argument
Pass Len(contents)*2 for the 3rd argument (length in bytes)
That will pass a Unicode UTF-16 string as the contents argument
Related
i am new to kotlin.
In swift i can do :
let endpoint = "categories/" + "%#/issues/"
let number = "4"
let finalstring = String(format: endpoint, number)
The final output of the string will be : categories/4/issues/ as a string .
I have looked at string format in kotlin but it's only work afterwards meaning that i can't define a template for my string and fill it later.
var value1 = "categories/"
var value2 = 4
var value3 = "/issues/"
println(java.lang.String.format("%s%d%s", value1, value2, value3))
This give me the same result but it's mean that i have to manualy write the end of the string.
What i want to do i to have a template for my string in a Road file.
Then complet my string at the run time. The probleme is that the part of my string that i want to complete is in the middle of the string.
Of course i can use substring and remplace but i am looking for a clean way to do it as in swift.
Thanks for helping.
One possible option would be to define a local function that does the formatting:
fun requestString(number: Int) = "categories/$number/issues/"
val finalString = requestString(4)
You can create your format string up front with all the constant parts, and with relevant placeholders (like %d for numbers) (more info in the javadoc).
Later, use the regular Java String.format() later with the parameters:
// define this constant up front
val format = "categories/%d/issues/"
// and then later:
val categoryId = 4
println(String.format(format, categoryId))
You already have the answer right there in your example, you just have to put it together.
String.format takes %s as placeholder for a String or %d for a number (and many more placeholder options).
So your template string would be: "categories/%d/issues/". To format it you use:
val format = "categories/%d/issues/"
val number = 4
val string = String.format(format, number)
About interpolation vs formatting, they can be used in different situations.
If you have the template string available in source code then you would use interpolation:
val string = "categories/${category.id}/issues/"
But when you have no control over the string, because it comes from an external source (such as a file), then you would have to use the formatting.
I wanted to replace the first character of a String and got it to work like this:
s.replaceSubrange(Range(NSMakeRange(0,1),in:s)!, with:".")
I wonder if there is a simpler method to achieve the same result?
[edit]
Get nth character of a string in Swift programming language doesn't provide a mutable substring. And it requires writing a String extension, which isn't really helping when trying to shorten code.
To replace the first character, you can do use String concatenation with dropFirst():
var s = "πhello world!"
s = "." + s.dropFirst()
print(s)
Result:
.hello world!
Note: This will not crash if the String is empty; it will just create a String with the replacement character.
Strings work very differently in Swift than many other languages. In Swift, a character is not a single byte but instead a single visual element. This is very important when working with multibyte characters like emoji (see: Why are emoji characters like π©βπ©βπ§βπ¦ treated so strangely in Swift strings?)
If you really do want to set a single random byte of your string to an arbitrary value as you expanded on in the comments of your question, you'll need to drop out of the string abstraction and work with your data as a buffer. This is sort of gross in Swift thanks to various safety features but it's doable:
var input = "Hello, world!"
//access the byte buffer
var utf8Buffer = input.utf8CString
//replace the first byte with whatever random data we want
utf8Buffer[0] = 46 //ascii encoding of '.'
//now convert back to a Swift string
var output:String! = nil //buffer for holding our new target
utf8Buffer.withUnsafeBufferPointer { (ptr) in
//Load the byte buffer into a Swift string
output = String.init(cString: ptr.baseAddress!)
}
print(output!) //.ello, world!
I just started with with Swift this week, specifically Swift 4, and I'm using a C library through a bridging header, liblo, which handles sending/receiving OSC (Open Sound Control) formatted messages over a network socket.
I'm able to start a server thread, receive OSC messages via C callback->Swift closure, and read the numeric argument values with Swift just fine. I'm running into trouble, however, with reading string values.
The liblo message argument type lo_arg is a C typedef for a union and the string argument types are declared as simple chars which are mapped to Swift as Int8.
In C, you can grab the string via &argv[i]->s from your callback's lo_arg **argv array. In an Obj-C project with liblo, I use:
// get string value of first argument
lo_arg arg = argv[0];
NSString *s = [NSString stringWithUTF8String:&arg->s];
// do something with s
In Swift, I've tried getting the address of the Int8 and feeding it to String which works, but only grabs the first character:
// get string value of first argument
if var arg : lo_arg = argv?.pointee![0] {
withUnsafePointer(to: &arg.s) {
let s = String(cString: $0)
// so something with s
}
}
Am I doing something wrong? I would think these would be equivalent but passing $0 to strlen() ala print("strlen: \(strlen($0)") only prints a length of "1". I've verified a multi-character string is indeed being sent with a non-Swift test program. I'm wondering now if Swift is somehow assuming the string is a single character instead of C string head address and/or I need some further pointer conversion.
After some digging, I can confirm Swift truncates the lo_arg->s & lo_arg->S string values to 8 bytes on my 64 bit system aka sizeof(char). This happens when trying to read the string from an lo_arg coming from Swift. Reading the same value in C works fine, so Swift seems to reserve/allow reading from only the space for a single char. Forwarding the lo_arg from Swift to C and printing the string via printf() also shows truncated strings up to 8 characters.
The quick fix is to avoid reading the strings from the lo_arg generated by Swift, grab an lo_arg from the raw lo_message in C, and cast the char "pointer" to a const char* Swift will understand as a variable length string. Here are some working utility functions I added to my bridging header:
/// return an lo_message argv[i]->s in a format Swift can understand as a String
const char* lo_message_get_string(lo_message message, int at) {
return (const char *)&lo_message_get_argv(message)[at]->s;
}
/// return an lo_message argv[i]->S in a format Swift can understand as a String
const char* lo_message_get_symbol(lo_message message, int at) {
return (const char *)&lo_message_get_argv(message)[at]->S;
}
In Swift, I can then convert to a String:
let s = String(cString: lo_message_get_string(msg, 0))
// do something with s
So I know how to convert String to utf8 format like this
for character in strings.utf8 {
// for example A will converted to 65
var utf8Value = character
}
I already read the guide but can't find how to convert Unicode code point that represented by integer to String. For example: converting 65 to A. I already tried to use the "\u"+utf8Value but it still failed.
Is there any way to do this?
If you look at the enum definition for Character you can see the following initializer:
init(_ scalar: UnicodeScalar)
If we then look at the struct UnicodeScalar, we see this initializer:
init(_ v: UInt32)
We can put them together, and we get a whole character
Character(UnicodeScalar(65))
and if we want it in a string, it's just another initializer away...
1> String(Character(UnicodeScalar(65)))
$R1: String = "A"
Or (although I can't figure out why this one works) you can do
String(UnicodeScalar(65))
http://play.golang.org/p/SKtaPFtnKO
func md(str string) []byte {
h := md5.New()
io.WriteString(h, str)
fmt.Printf("%x", h.Sum(nil))
// base 16, with lower-case letters for a-f
return h.Sum(nil)
}
All I need is Hash-key string that is converted from an input string. I was able to get it in bytes format usting h.Sum(nil) and able to print out the Hash-key in %x format. But I want to return the %x format from this function so that I can use it to convert email address to Hash-key and use it to access Gravatar.com.
How do I get %x format Hash-key using md5 function in Go?
Thanks,
If I understood correctly you want to return the %x format:
you can import "encoding/hex" and use the EncodeToString method
str := hex.EncodeToString(h.Sum(nil))
or just Sprintf the value:
func md(str string) string {
h := md5.New()
io.WriteString(h, str)
return fmt.Sprintf("%x", h.Sum(nil))
}
note that Sprintf is slower because it needs to parse the format string and then reflect based on the type found
http://play.golang.org/p/vsFariAvKo
You should avoid using the fmt package for this. The fmt package uses reflection, and it is expensive for anything other than debugging. You know what you have, and what you want to convert to, so you should be using the proper conversion package.
For converting from binary to hex, and back, use the encoding/hex package.
To Hex string:
str := hex.EncodeToString(h.Sum(nil))
From Hex string:
b, err := hex.DecodeString(str)
There are also Encode / Decode functions for []byte.
When you need to convert to / from a decimal use the strconv package.
From int to string:
str := strconv.Itoa(100)
From string to int:
num, err := strconv.Atoi(str)
There are several other functions in this package that do other conversions (base, etc.).
So unless you're debugging or formatting an error message, use the proper conversions. Please.