ArkUtils.swift 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. //
  2. // Copyright 2026 Aarav Ravindra Kharade
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. //
  16. // ── Pure-libc utilities replacing Foundation APIs ─────────────────
  17. /// Read an entire file into a String via fopen/fread (replaces String(contentsOfFile:)).
  18. public func readFileContents(_ path: String) -> String? {
  19. guard let fp = fopen(path, "r") else { return nil }
  20. defer { fclose(fp) }
  21. var buffer = [UInt8](repeating: 0, count: 8192)
  22. var result = ""
  23. while true {
  24. let n = fread(&buffer, 1, buffer.count, fp)
  25. if n == 0 { break }
  26. buffer.withUnsafeBufferPointer { ptr in
  27. let slice = UnsafeBufferPointer(start: ptr.baseAddress, count: n)
  28. for byte in slice {
  29. result.append(Character(UnicodeScalar(byte)))
  30. }
  31. }
  32. }
  33. return result.isEmpty ? nil : result
  34. }
  35. /// Trim whitespace and newlines from both ends of a string (replaces .trimmingCharacters(in:)).
  36. public func trimWhitespace(_ s: String) -> String {
  37. var chars = Array(s)
  38. while let first = chars.first, first == " " || first == "\n" || first == "\r" || first == "\t" {
  39. chars.removeFirst()
  40. }
  41. while let last = chars.last, last == " " || last == "\n" || last == "\r" || last == "\t" {
  42. chars.removeLast()
  43. }
  44. return String(chars)
  45. }
  46. /// Simple snprintf-style format for a single Double with one decimal place.
  47. public func formatDouble(_ value: Double, decimals: Int = 1) -> String {
  48. let intPart = Int(value)
  49. var factor = 1
  50. for _ in 0..<decimals { factor *= 10 }
  51. let fracPart = abs(Int((value - Double(intPart)) * Double(factor)))
  52. return "\(intPart).\(fracPart)"
  53. }