Reputation: 12925
I have a binary file test.data containing the following data:
01 E6 B5 8B E8 AF 95 02
The first byte is just for example a sequence number 01. The next 6 bytes are two UTF8 Chinese characters "测试".Then the 8th byte is again another sequence number 02.
As I know the UTF8 is variable length (1-4 bytes). Please refer to this post.
I'm using the following code to read Int32 and Byte(UInt8):
extension NSInputStream
{
func readInt32() -> Int
{
var readBuffer = Array<UInt8>(count:sizeof(Int32), repeatedValue: 0)
var numberOfBytesRead = self.read(&readBuffer, maxLength: readBuffer.count)
return Int(readBuffer[0]) << 24 |
Int(readBuffer[1]) << 16 |
Int(readBuffer[2]) << 8 |
Int(readBuffer[3])
}
func readByte() -> Byte {
var readBuffer : Byte = 0
return self.read(&readBuffer, maxLength: sizeof(UInt8))
}
I'd like to write a method to read Strings from the stream. Here is what I'm thinking:
But the problem is how many bytes to read for a Character because the UTF8 length is variant? In general my question is how I'm supposed to read UTF8 String? Thanks in advance.
Upvotes: 1
Views: 7189
Reputation: 4629
Here is the fixed version I mentioned in my comment to bagusflyer's post :
extension NSInputStream
{
public func readString(length:Int) -> String {
var str = ""
if length > 0 {
var readBuffer = UnsafeMutablePointer<UInt8>.alloc(length+1)
var numberOfBytesRead = self.read(readBuffer, maxLength: length)
// modified this from == length to > 0
if numberOfBytesRead > 0 {
var buf = UnsafeMutablePointer<CChar>(readBuffer)
buf[numberOfBytesRead] = 0
// the C String must be null terminated
if let utf8String = String.fromCString(buf) {
str = utf8String
}
}
readBuffer.dealloc(length+1)
}
return str
}
}
Upvotes: 4
Reputation:
Just read to UnsafeMutablePointer buffer and convert it to a String. The returned String will be UTF8.
extension NSInputStream
{
public func readString(length:Int) -> String {
var str = ""
if length > 0 {
var readBuffer = UnsafeMutablePointer<UInt8>.alloc(length+1)
var numberOfBytesRead = self.read(readBuffer, maxLength: length)
if numberOfBytesRead == length {
var buf = UnsafeMutablePointer<CChar>(readBuffer)
buf[length] = 0
// the C String must be null terminated
if let utf8String = String.fromCString(buf) {
str = utf8String
}
}
readBuffer.dealloc(length)
}
return str
}
}
Upvotes: 4