@@ -68,7 +68,7 @@ open class StringAttribute: Attribute {
6868 let string = String ( utf8String: pointer. baseAddress! + index) !
6969 strings. append ( string)
7070 index += string. lengthOfBytes ( using: . utf8)
71- while index <= size && pointer [ index] == 0 {
71+ while index < size && pointer [ index] == 0 {
7272 index += 1
7373 }
7474 }
@@ -77,6 +77,14 @@ open class StringAttribute: Attribute {
7777 }
7878
7979 public func write( _ data: String ) throws {
80+ if type. isVariableLengthString {
81+ try writeVariable ( data)
82+ } else {
83+ try writeFixed ( data)
84+ }
85+ }
86+
87+ public func writeVariable( _ data: String ) throws {
8088 let size = self . space. size
8189 precondition ( 1 == size, " Data size doesn't match Dataspace dimensions " )
8290
@@ -94,12 +102,30 @@ open class StringAttribute: Attribute {
94102 }
95103 }
96104
105+ public func writeFixed( _ data: String ) throws {
106+ let size = self . space. size
107+ precondition ( 1 == size, " Data size doesn't match Dataspace dimensions " )
108+
109+ let stringSize = self . type. size
110+ var data = data
111+ if stringSize != - 1 && data. utf8. count < stringSize {
112+ data. append ( contentsOf: String ( repeating: " \0 " , count: stringSize - data. utf8. count) )
113+ }
114+
115+ try data. utf8CString. withUnsafeBufferPointer { pointer in
116+ let type = Datatype . createString ( size: stringSize)
117+ guard H5Awrite ( id, type. id, pointer. baseAddress) >= 0 else {
118+ throw Error . ioError
119+ }
120+ }
121+ }
122+
97123}
98124
99125
100126public extension GroupType {
101127 /// Creates a `String` attribute.
102- public func createStringAttribute( _ name: String ) -> StringAttribute ? {
128+ func createStringAttribute( _ name: String ) -> StringAttribute ? {
103129 guard let datatype = Datatype ( type: String . self) else {
104130 return nil
105131 }
@@ -110,8 +136,18 @@ public extension GroupType {
110136 return StringAttribute ( id: attributeID)
111137 }
112138
139+ /// Creates a fixed-length `String` attribute.
140+ func createFixedStringAttribute( _ name: String , size: Int ) -> StringAttribute ? {
141+ let datatype = Datatype ( dataClass: . string, size: size)
142+ let dataspace = Dataspace ( dims: [ 1 ] )
143+ let attributeID = name. withCString { name in
144+ return H5Acreate2 ( id, name, datatype. id, dataspace. id, 0 , 0 )
145+ }
146+ return StringAttribute ( id: attributeID)
147+ }
148+
113149 /// Opens a `String` attribute.
114- public func openStringAttribute( _ name: String ) -> StringAttribute ? {
150+ func openStringAttribute( _ name: String ) -> StringAttribute ? {
115151 let attributeID = name. withCString { name in
116152 return H5Aopen ( id, name, 0 )
117153 }
0 commit comments