英文:
Access tuple (defined by libc) using an index
问题
I understand that Swift tuples cannot be indexed at runtime. However, I'm working with the POSIX terminal interface (defined by <termios.h>
, which is part of libc).
In the C code, we are able to modify the state of the terminal by doing stuff like this:
termios_struct.c_cc[VMIN] = 0;
termios_struct.c_cc[VTIME] = 0;
Translating that to Swift raises an error, complaining that it cannot access element using subscript for tuple type '(cc_t, cc_t, cc_t ...)' (aka '(UInt8, UInt8, UInt8 ...)'). The actual tuples have about twenty elements, all UInt8.
I guess I could just print the values of VMIN and VTIME (constants defined by <termios.h>
), then use their values to directly index the tuples, but I'm not sure their values are consistent across platforms, and it's just generally hacky.
What's the proper way to handle this situation?
Edit: This issue is addressed by this answer to another question, named Using termios
in Swift.
英文:
I understand that Swift tuples cannot be indexed at runtime. However, I'm working with the POSIX terminal interface (defined by <termios.h>
, which is part of libc).
In the C code, we are able to modify the state of the terminal by doing stuff like this:
termios_struct.c_cc[VMIN] = 0;
termios_struct.c_cc[VTIME] = 0;
Translating that to Swift raises an error, complaining that it cannot access element using subscript for tuple type '(cc_t, cc_t, cc_t ...)' (aka '(UInt8, UInt8, UInt8 ...)')
. The actual tuples have about twenty elements, all UInt8
.
I guess I could just print the values of VMIN
and VTIME
(constants defined by <termios.h>
), then use their values to directly index the tuples, but I'm not sure their values are consistent across platforms, and it's just generally hacky.
What's the proper way to handle this situation?
Edit: This issue is addressed by this answer to another question, named Using termios
in Swift.
答案1
得分: 1
使用您引用的答案作为指南,我创建了以下扩展,似乎可以工作。
extension termios {
subscript(c_cc index: Int32) -> cc_t {
get {
var settings = self
var res: cc_t = 0
withUnsafePointer(to: &settings.c_cc) { (tuplePtr) -> Void in
tuplePtr.withMemoryRebound(to: cc_t.self, capacity: MemoryLayout.size(ofValue: self.c_cc)) {
res = $0[Int(index)]
}
}
return res
}
set {
var settings = self
withUnsafeMutablePointer(to: &self.c_cc) { (tuplePtr) -> Void in
tuplePtr.withMemoryRebound(to: cc_t.self, capacity: MemoryLayout.size(ofValue: settings.c_cc)) {
$0[Int(index)] = newValue
}
}
}
}
}
这里是一些示例代码:
var settings = termios()
print(settings.c_cc)
settings[c_cc: VMIN] = 1
print(settings.c_cc)
print(settings[c_cc: VMIN])
输出如下:
(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0)
1
英文:
Using the answer you referenced as a guide, I came up with the following extension that seems to work.
extension termios {
subscript(c_cc index: Int32) -> cc_t {
get {
var settings = self
var res: cc_t = 0
withUnsafePointer(to: &settings.c_cc) { (tuplePtr) -> Void in
tuplePtr.withMemoryRebound(to: cc_t.self, capacity: MemoryLayout.size(ofValue: self.c_cc)) {
res = $0[Int(index)]
}
}
return res
}
set {
var settings = self
withUnsafeMutablePointer(to: &self.c_cc) { (tuplePtr) -> Void in
tuplePtr.withMemoryRebound(to: cc_t.self, capacity: MemoryLayout.size(ofValue: settings.c_cc)) {
$0[Int(index)] = newValue
}
}
}
}
}
Here's some sample code:
var settings = termios()
print(settings.c_cc)
settings[c_cc: VMIN] = 1
print(settings.c_cc)
print(settings[c_cc: VMIN])
which outputs:
>(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0)
1
答案2
得分: 1
由于 c_cc
是一个字节数组,例如 [UInt8]
,您可以执行以下操作:
var tty = termios()
withUnsafeMutableBytes(of: &tty.c_cc) { c_cc in
c_cc[size_t(VMIN)] = 1
c_cc[size_t(VTIME)] = 0
}
英文:
Since c_cc
is an array of bytes, e.g. [UInt8]
, you can do following
var tty = termios()
withUnsafeMutableBytes(of: &tty.c_cc)
{
c_cc in
c_cc[size_t(VMIN)] = 1
c_cc[size_t(VTIME)] = 0
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论