Skip to content

Commit

Permalink
Fix fixed-length string attribute reading and writing
Browse files Browse the repository at this point in the history
  • Loading branch information
alejandro-isaza committed Nov 3, 2019
1 parent 8517b19 commit f7fd046
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 3 deletions.
3 changes: 3 additions & 0 deletions Source/Datatype.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ public class Datatype : Object, Equatable {
guard id >= 0 else {
fatalError("Failed to create Datatype")
}
if dataClass == .string {
H5Tset_cset(id, H5T_CSET_UTF8)
}
self.init(id: id)
}

Expand Down
42 changes: 39 additions & 3 deletions Source/StringAttribute.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ open class StringAttribute: Attribute {
let string = String(utf8String: pointer.baseAddress! + index)!
strings.append(string)
index += string.lengthOfBytes(using: .utf8)
while index <= size && pointer[index] == 0 {
while index < size && pointer[index] == 0 {
index += 1
}
}
Expand All @@ -77,6 +77,14 @@ open class StringAttribute: Attribute {
}

public func write(_ data: String) throws {
if type.isVariableLengthString {
try writeVariable(data)
} else {
try writeFixed(data)
}
}

public func writeVariable(_ data: String) throws {
let size = self.space.size
precondition(1 == size, "Data size doesn't match Dataspace dimensions")

Expand All @@ -94,12 +102,30 @@ open class StringAttribute: Attribute {
}
}

public func writeFixed(_ data: String) throws {
let size = self.space.size
precondition(1 == size, "Data size doesn't match Dataspace dimensions")

let stringSize = self.type.size
var data = data
if stringSize != -1 && data.utf8.count < stringSize {
data.append(contentsOf: String(repeating: "\0", count: stringSize - data.utf8.count))
}

try data.utf8CString.withUnsafeBufferPointer { pointer in
let type = Datatype.createString(size: stringSize)
guard H5Awrite(id, type.id, pointer.baseAddress) >= 0 else {
throw Error.ioError
}
}
}

}


public extension GroupType {
/// Creates a `String` attribute.
public func createStringAttribute(_ name: String) -> StringAttribute? {
func createStringAttribute(_ name: String) -> StringAttribute? {
guard let datatype = Datatype(type: String.self) else {
return nil
}
Expand All @@ -110,8 +136,18 @@ public extension GroupType {
return StringAttribute(id: attributeID)
}

/// Creates a fixed-length `String` attribute.
func createFixedStringAttribute(_ name: String, size: Int) -> StringAttribute? {
let datatype = Datatype(dataClass: .string, size: size)
let dataspace = Dataspace(dims: [1])
let attributeID = name.withCString { name in
return H5Acreate2(id, name, datatype.id, dataspace.id, 0, 0)
}
return StringAttribute(id: attributeID)
}

/// Opens a `String` attribute.
public func openStringAttribute(_ name: String) -> StringAttribute? {
func openStringAttribute(_ name: String) -> StringAttribute? {
let attributeID = name.withCString{ name in
return H5Aopen(id, name, 0)
}
Expand Down
12 changes: 12 additions & 0 deletions Tests/HDF5KitTests/AttributeTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,19 @@ class AttributeTests: XCTestCase {

let writeData = "ABCD😀"
try attribute.write(writeData)
XCTAssertEqual(try attribute.read(), [writeData])
}

func testWriteReadFixedString() throws {
let filePath = tempFilePath()
guard let file = File.create(filePath, mode: .truncate) else {
fatalError("Failed to create file")
}
let group = file.createGroup("group")
let attribute = try XCTUnwrap(group.createFixedStringAttribute("attribute", size: 50))

let writeData = "ABCD😀"
try attribute.write(writeData)
XCTAssertEqual(try attribute.read(), [writeData])
}
}

0 comments on commit f7fd046

Please sign in to comment.