访问元组(由libc定义)时使用索引

huangapple go评论61阅读模式
英文:

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 &lt;termios.h&gt;, 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 &#39;(cc_t, cc_t, cc_t ...)&#39; (aka &#39;(UInt8, UInt8, UInt8 ...)&#39;). The actual tuples have about twenty elements, all UInt8.

I guess I could just print the values of VMIN and VTIME (constants defined by &lt;termios.h&gt;), 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) -&gt; cc_t {
        get {
            var settings = self
            var res: cc_t = 0
            withUnsafePointer(to: &amp;settings.c_cc) { (tuplePtr) -&gt; 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: &amp;self.c_cc) { (tuplePtr) -&gt; 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: &amp;tty.c_cc)
{
	c_cc in
	c_cc[size_t(VMIN)]  = 1
	c_cc[size_t(VTIME)] = 0
}

huangapple
  • 本文由 发表于 2023年6月29日 00:00:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/76574904.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定