Skip to content

Commit 2379400

Browse files
authored
Merge pull request apple#1064 from tbkka/tbkka/avoidFoundationStringFormat
Reduce foundation usage
2 parents 0279688 + b8ddfe4 commit 2379400

File tree

4 files changed

+55
-23
lines changed

4 files changed

+55
-23
lines changed

Sources/SwiftProtobuf/Google_Protobuf_Duration+Extensions.swift

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -99,16 +99,8 @@ private func formatDuration(seconds: Int64, nanos: Int32) -> String? {
9999
guard seconds >= minDurationSeconds && seconds <= maxDurationSeconds else {
100100
return nil
101101
}
102-
103-
if nanos == 0 {
104-
return String(format: "%llds", seconds)
105-
} else if nanos % 1000000 == 0 {
106-
return String(format: "%lld.%03ds", seconds, abs(nanos) / 1000000)
107-
} else if nanos % 1000 == 0 {
108-
return String(format: "%lld.%06ds", seconds, abs(nanos) / 1000)
109-
} else {
110-
return String(format: "%lld.%09ds", seconds, abs(nanos))
111-
}
102+
let nanosString = nanosToString(nanos: nanos) // Includes leading '.' if needed
103+
return "\(seconds)\(nanosString)s"
112104
}
113105

114106
extension Google_Protobuf_Duration {

Sources/SwiftProtobuf/Google_Protobuf_Timestamp+Extensions.swift

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -191,19 +191,11 @@ private func formatTimestamp(seconds: Int64, nanos: Int32) -> String? {
191191
let (hh, mm, ss) = timeOfDayFromSecondsSince1970(seconds: seconds)
192192
let (YY, MM, DD) = gregorianDateFromSecondsSince1970(seconds: seconds)
193193

194-
if nanos == 0 {
195-
return String(format: "%04d-%02d-%02dT%02d:%02d:%02dZ",
196-
YY, MM, DD, hh, mm, ss)
197-
} else if nanos % 1000000 == 0 {
198-
return String(format: "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ",
199-
YY, MM, DD, hh, mm, ss, nanos / 1000000)
200-
} else if nanos % 1000 == 0 {
201-
return String(format: "%04d-%02d-%02dT%02d:%02d:%02d.%06dZ",
202-
YY, MM, DD, hh, mm, ss, nanos / 1000)
203-
} else {
204-
return String(format: "%04d-%02d-%02dT%02d:%02d:%02d.%09dZ",
205-
YY, MM, DD, hh, mm, ss, nanos)
206-
}
194+
let dateString = "\(fourDigit(YY))-\(twoDigit(MM))-\(twoDigit(DD))"
195+
let timeString = "\(twoDigit(hh)):\(twoDigit(mm)):\(twoDigit(ss))"
196+
let nanosString = nanosToString(nanos: nanos) // Includes leading '.' if needed
197+
198+
return "\(dateString)T\(timeString)\(nanosString)Z"
207199
}
208200

209201
extension Google_Protobuf_Timestamp {

Sources/SwiftProtobuf/StringUtils.swift

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,42 @@
2020

2121
import Foundation
2222

23+
/*
24+
Note: Once our minimum support version is at least Swift 5.3, we
25+
should probably recast the following to use
26+
String(unsafeUninitializedCapacity:)
27+
*/
28+
29+
// Note: We're trying to avoid Foundation's String(format:) since that's not
30+
// universally available.
31+
32+
fileprivate func formatZeroPaddedInt(_ value: Int32, digits: Int) -> String {
33+
precondition(value >= 0)
34+
let s = String(value)
35+
if s.count >= digits {
36+
return s
37+
} else {
38+
let pad = String(repeating: "0", count: digits - s.count)
39+
return pad + s
40+
}
41+
}
42+
43+
internal func twoDigit(_ value: Int32) -> String {
44+
return formatZeroPaddedInt(value, digits: 2)
45+
}
46+
internal func threeDigit(_ value: Int32) -> String {
47+
return formatZeroPaddedInt(value, digits: 3)
48+
}
49+
internal func fourDigit(_ value: Int32) -> String {
50+
return formatZeroPaddedInt(value, digits: 4)
51+
}
52+
internal func sixDigit(_ value: Int32) -> String {
53+
return formatZeroPaddedInt(value, digits: 6)
54+
}
55+
internal func nineDigit(_ value: Int32) -> String {
56+
return formatZeroPaddedInt(value, digits: 9)
57+
}
58+
2359
// Wrapper that takes a buffer and start/end offsets
2460
internal func utf8ToString(
2561
bytes: UnsafeRawBufferPointer,

Sources/SwiftProtobuf/TimeUtils.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,15 @@ internal func gregorianDateFromSecondsSince1970(seconds: Int64) -> (YY: Int32, M
5151

5252
return (YY: Int32(YY), MM: Int32(MM), DD: Int32(DD))
5353
}
54+
55+
internal func nanosToString(nanos: Int32) -> String {
56+
if nanos == 0 {
57+
return ""
58+
} else if nanos % 1000000 == 0 {
59+
return ".\(threeDigit(abs(nanos) / 1000000))"
60+
} else if nanos % 1000 == 0 {
61+
return ".\(sixDigit(abs(nanos) / 1000))"
62+
} else {
63+
return ".\(nineDigit(abs(nanos)))"
64+
}
65+
}

0 commit comments

Comments
 (0)