Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

import CardReaderProviderApi
import Foundation
import GemCommonsKit
import OSLog
import SwiftSocket

public class SimulatorCard: CardType {
Expand All @@ -36,7 +36,7 @@ public class SimulatorCard: CardType {

required init(host: String, port: Int32, channel protocol: CardProtocol = .t1, timeout: Int = 10) {
self.protocol = `protocol`
atr = Data.empty
atr = Data()
self.host = host
self.port = port
connectTimeout = timeout
Expand All @@ -59,26 +59,26 @@ public class SimulatorCard: CardType {
}

public func openLogicChannel() throws -> CardChannelType {
throw CardError.connectionError(CommonError.notImplementedError)
throw CardError.connectionError(nil)
}

public func openLogicChannelAsync() async throws -> CardChannelType {
throw CardError.connectionError(CommonError.notImplementedError)
throw CardError.connectionError(nil)
}

public func disconnect(reset _: Bool) throws {
do {
try basicChannel?.close()
} catch {
ALog("Error while closing basicChannel: [\(error)]")
Logger.cardSimulationCardReaderProvider.fault("Error while closing basicChannel: [\(error)]")
}
}

deinit {
do {
try disconnect(reset: false)
} catch {
ALog("Error while deinit: [\(error)]")
Logger.cardSimulationCardReaderProvider.fault("Error while deinit: [\(error)]")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

import CardReaderProviderApi
import Foundation
import GemCommonsKit
import OSLog
import SwiftSocket

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import CardReaderProviderApi
import CardSimulationLoader
import Foundation
import GemCommonsKit

public class SimulatorCardReader: CardReaderType {
public enum CardReaderError: Error {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import CardReaderProviderApi
import CardSimulationLoader
import Foundation
import GemCommonsKit

public class SimulatorCardReaderController: CardReaderControllerType {
public let name = SimulatorCardReaderProvider.name
Expand Down Expand Up @@ -78,3 +77,137 @@ extension SimulatorCardReaderController: SimulationManagerDelegate {
}
}
}

/// A Collection similar to an array, but wraps its Elements in a `WeakRef`.
class WeakArray<T: Any> {
private var _array = [WeakRef<AnyObject>]()

/// Initialize an empty WeakArray
init() {}

/// Add an object reference to the array
/// - Parameter object: the object to weak reference before adding it to the array
func add(object: T) {
let ref = makePointer(object)
_array.append(ref)
}

/// Dereference the object at index when not released
/// - Parameter index: index to get
/// - Returns: The object when not deinitialized
func object(at index: Int) -> T? {
guard index < count, let pointer = _array[index].value else {
return nil
}
guard let object = pointer as? T else {
return nil
}
return object
}

/// Insert an object reference at a specified index
/// - Parameters:
/// - object: the object to weak reference before adding it to the array
/// - index: the index to insert at
func insert(object: T, at index: Int) {
guard index < count else {
return
}
_array.insert(makePointer(object), at: index)
}

/// Replace a weak reference with a new object
/// - Parameters:
/// - index: the index to replace
/// - object: the object to weak reference before replacing the reference at index
func replaceObject(at index: Int, with object: T) {
guard index < count else {
return
}
_array[index] = makePointer(object)
}

/// Remove an object reference at a specified index
/// - Parameter index: index of the reference to remove
func removeObject(at index: Int) {
guard index < count else {
return
}
_array.remove(at: index)
}

/// Get the current count of available (not-released) object references
/// - Note: complexity O(n) - since we filter out the zeroed `WeakRef`s
/// - Returns: the current active reference count
var count: Int {
_array = _array.filter { $0.value != nil }
return _array.count
}

/// Dereference the object at index when not released
/// - Parameter index: index to get
/// - See: object(at:)
/// - Returns: The object when not deinitialized
subscript(index: Int) -> T? {
object(at: index)
}

/// Find the index of an object in the array
/// - Parameter object: the object to search for
/// - Note: complexity O(2n)
/// - Returns: the index when found else nil
func index(of object: T) -> Int? {
let anyObject = object as AnyObject
for index in 0 ..< count {
if let current = self[index] as AnyObject?, current === anyObject {
return index
}
}
return nil
}
}

private func makePointer(_ object: Any) -> WeakRef<AnyObject> {
let strongObject = object as AnyObject
let ref = WeakRef(strongObject)
return ref
}

extension WeakArray {
/// Convenience initializer for weak referencing an entire array
/// - Parameter objects: the object to weak reference in the newly initialized WeakArray
convenience init(objects: [T]) {
self.init()
objects.forEach {
add(object: $0)
}
}

/// Get objects referenced by `Self` as a strong array
/// - Returns: Array with available objects
var array: [T] {
_array.compactMap {
$0.value as? T
}
}
}

extension Array where Element: AnyObject {
/// Create a WeakArray with elements from `Self`
/// - Returns: WeakArray with references to all Elements in `Self`
var weakArray: WeakArray<Element> {
WeakArray(objects: self)
}
}

/// Swift object that holds a weak reference to an Object like its Java counter-part WeakReference.
class WeakRef<T: AnyObject> {
/// The weak referenced object
private(set) weak var value: T?

/// Initialize a weak reference.
/// - Parameter obj: the object to weak reference
required init(_ obj: T) {
value = obj
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
//

import Foundation
import GemCommonsKit
import OSLog
import SwiftSocket

extension TCPClient: TCPClientType {
Expand All @@ -33,7 +33,7 @@ extension TCPClient: TCPClientType {

let bufferSize = min(Int(availableBytes), len)
guard let bytes = read(bufferSize) else {
ALog("Read error")
Logger.cardSimulationCardReaderProvider.fault("Read error")
return -1
}
buffer.assign(from: bytes, count: bytes.count)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
//

import Foundation
import GemCommonsKit
import OSLog

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
//

import Foundation
import GemCommonsKit
import OSLog

/// Protocol that describes G2-Kartensimulation Configuration files (pre-)processors
Expand Down Expand Up @@ -113,7 +112,9 @@ public protocol SimulationManagerType {
public class SimulationManager {
/// Singleton instance of `SimulationManager`
public static let shared = {
SimulationManager()
SimulationManager(tempDir: NSTemporaryDirectory().asURL.appendingPathComponent(
ProcessInfo.processInfo.globallyUniqueString, isDirectory: true
))
}()

/// The default G2-Kartensimulation version
Expand All @@ -137,9 +138,7 @@ public class SimulationManager {
/// - Parameters:
/// - tempDir: path to a directory to be used as temporary directory for storing dependencies and configuration.
/// - Returns: a new SimulationManger
public init(tempDir: URL = NSTemporaryDirectory().asURL.appendingPathComponent(
ProcessInfo.processInfo.globallyUniqueString, isDirectory: true
)) {
public init(tempDir: URL) {
Logger.cardSimulationLoader.debug("Init with tempDir: [\(tempDir)]")
tempDirectory = tempDir
}
Expand Down Expand Up @@ -202,7 +201,8 @@ public class SimulationManager {
guard let simClassPath = info.simulatorClassPath else {
throw SimulationLoaderError.malformedConfiguration
}
let simulator = SimulationRunner(simulator: file, classPath: simClassPath)
let currentDir = FileManager.default.currentDirectoryPath.asURL
let simulator = SimulationRunner(simulator: file, classPath: simClassPath, workingDirectory: currentDir)
simulator.delegate = self
_runners.append((url: file, simulator: simulator))
return simulator
Expand Down Expand Up @@ -242,7 +242,7 @@ public class SimulationManager {
do {
try FileManager.default.removeItem(at: $0.url)
} catch {
ALog("Failed to clean simulator runner environment: [\(error)]")
Logger.cardSimulationLoader.fault("Failed to clean simulator runner environment: [\(error)]")
}
}
/// Remove the simulation from the runners array
Expand All @@ -262,7 +262,7 @@ public class SimulationManager {
do {
try FileManager.default.removeItem(at: tempDirectory)
} catch {
ALog("Failed to clean [\(error)]")
Logger.cardSimulationLoader.fault("Failed to clean [\(error)]")
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
//

import Foundation
import GemCommonsKit
import OSLog
import StreamReader

Expand Down Expand Up @@ -87,7 +86,7 @@ public class SimulationRunner {
*/
public required init(simulator file: URL,
classPath: URL,
workingDirectory dir: URL = FileManager.default.currentDirectoryPath.asURL,
workingDirectory dir: URL,
in thread: KeepAliveRunLoop = KeepAliveRunLoop()) {
simulatorConfig = file
javaClassPath = classPath
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// Copyright (c) 2022 gematik GmbH
//
// Licensed under the Apache License, Version 2.0 (the License);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an 'AS IS' BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#import "ExceptionCatcher.h"
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//
// Copyright (c) 2024 gematik GmbH
//
// Licensed under the Apache License, Version 2.0 (the License);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an 'AS IS' BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#import <Foundation/Foundation.h>

/**
Catch NSExceptions from ObjC dependencies.

To use this function create a Bridging-Header and import this header file.
Then you'll just have to call:

```swift
if let error = gemTryBlock({
// Execute code that can raise NSException(s)
}) {
// Handle the exception/error
print("An exception was thrown!", error.localizedDescription)
}
```
*/
NS_INLINE NSException * _Nullable gemTryBlock(void(^_Nonnull tryBlock)(void)) {
@try {
tryBlock();
}
@catch (NSException *exception) {
return exception;
}
return nil;
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
//

import Foundation
import GemCommonsKit
import OSLog

protocol JavaProcessConfig {
Expand Down Expand Up @@ -111,7 +110,7 @@ extension JavaProcess {
delegate: JavaProcessUpdateDelegate? = nil) {
#if os(macOS) || os(Linux)
guard process == nil else {
ALog("WARN: double start. Process already started/initialized")
Logger.cardSimulationLoader.warning("WARN: double start. Process already started/initialized")
return
}
#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

import AEXML
import Foundation
import GemCommonsKit
import OSLog

extension SimulationManager {
Expand Down
Loading