Skip to content

Commit

Permalink
fix: make format of internal hex strings consistent
Browse files Browse the repository at this point in the history
  • Loading branch information
pwespi committed Jan 25, 2025
1 parent f9775a9 commit 3ec8a98
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,11 @@ fun stringToBytes(value: String): ByteArray {
if (value == "") {
return ByteArray(0)
}
val hexValues = value.split(" ")
val bytes = ByteArray(hexValues.size)
for (i in hexValues.indices) {
bytes[i] = hexToByte(hexValues[i])
require(value.length % 2 == 0) { "Input string must have an even length, not ${value.length}" }
val bytes = ByteArray(value.length / 2)
for (i in bytes.indices) {
val hexPair = value.substring(i * 2, i * 2 + 2)
bytes[i] = hexToByte(hexPair)
}
return bytes
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class ConversionKtTest : TestCase() {
}

fun testStringToBytes() {
val input = "A1 2E 38 D4 89 C3"
val input = "a12e38d489c3"
val output = stringToBytes(input)
val expected = byteArrayOfInts(0xA1, 0x2E, 0x38, 0xD4, 0x89, 0xC3)
expected.forEachIndexed { index, byte ->
Expand Down
17 changes: 13 additions & 4 deletions ios/Plugin/Conversion.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,19 @@ func dataToString(_ data: Data) -> String {
}

func stringToData(_ dataString: String) -> Data {
let hexValues = dataString.split(separator: " ")
var data = Data(capacity: hexValues.count)
for hex in hexValues {
data.append(UInt8(hex, radix: 16)!)
guard dataString.count % 2 == 0 else {
fatalError("Input string must have an even length, not \(dataString.count)")
}
var data = Data(capacity: dataString.count / 2)
for i in stride(from: 0, to: dataString.count, by: 2) {
let start = dataString.index(dataString.startIndex, offsetBy: i)
let end = dataString.index(start, offsetBy: 2)
let hexPair = dataString[start..<end]
if let byte = UInt8(hexPair, radix: 16) {
data.append(byte)
} else {
fatalError("Invalid hexadecimal value: \(hexPair)")
}
}
return data
}
Expand Down
2 changes: 1 addition & 1 deletion ios/PluginTests/ConversionTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class ConversionTests: XCTestCase {
}

func testStringToData() throws {
let input = "a1 2e 38 d4 89 c3"
let input = "a12e38d489c3"
let output = stringToData(input)
let expected = Data([0xA1, 0x2E, 0x38, 0xD4, 0x89, 0xC3])
for (index, byte) in output.enumerated() {
Expand Down
28 changes: 14 additions & 14 deletions src/bleClient.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ describe('BleClient', () => {
expect(BluetoothLe.addListener).toHaveBeenCalledWith('onEnabledChanged', expect.any(Function));
expect(BluetoothLe.startEnabledNotifications).toHaveBeenCalledTimes(1);
expect((BleClient as unknown as BleClientWithPrivate).eventListeners.get('onEnabledChanged')).toBe(
mockPluginListenerHandle,
mockPluginListenerHandle
);
});

Expand All @@ -120,7 +120,7 @@ describe('BleClient', () => {

await BleClient.startEnabledNotifications(mockCallback);
expect((BleClient as unknown as BleClientWithPrivate).eventListeners.get('onEnabledChanged')).toBe(
mockPluginListenerHandle,
mockPluginListenerHandle
);
await BleClient.stopEnabledNotifications();
expect(mockPluginListenerHandle.remove).toHaveBeenCalledTimes(1);
Expand Down Expand Up @@ -210,7 +210,7 @@ describe('BleClient', () => {
(BluetoothLe.addListener as jest.Mock).mockReturnValue(mockPluginListenerHandle);
await BleClient.connect(mockDevice.deviceId, mockDisconnectCallback);
expect((BleClient as unknown as BleClientWithPrivate).eventListeners.get('disconnected|123')).toBe(
mockPluginListenerHandle,
mockPluginListenerHandle
);
expect(BluetoothLe.connect).toHaveBeenCalledTimes(1);
});
Expand Down Expand Up @@ -238,14 +238,14 @@ describe('BleClient', () => {
});

it('should run read', async () => {
(BluetoothLe.read as jest.Mock).mockReturnValue({ value: '00 05 c8 ' });
(BluetoothLe.read as jest.Mock).mockReturnValue({ value: '0005c8' });
const result = await BleClient.read(mockDevice.deviceId, service, characteristic);
expect(result).toEqual(hexStringToDataView('00 05 c8'));
expect(result).toEqual(hexStringToDataView('0005c8'));
expect(BluetoothLe.read).toHaveBeenCalledWith({ deviceId: mockDevice.deviceId, service, characteristic });
});

it('should run read with timeout', async () => {
(BluetoothLe.read as jest.Mock).mockReturnValue({ value: '00 05 c8 ' });
(BluetoothLe.read as jest.Mock).mockReturnValue({ value: '0005c8' });
await BleClient.read(mockDevice.deviceId, service, characteristic, { timeout: 6000 });
expect(BluetoothLe.read).toHaveBeenCalledWith({
deviceId: mockDevice.deviceId,
Expand Down Expand Up @@ -276,7 +276,7 @@ describe('BleClient', () => {
deviceId: mockDevice.deviceId,
service,
characteristic,
value: '00 01',
value: '0001',
});
});

Expand All @@ -289,7 +289,7 @@ describe('BleClient', () => {
deviceId: mockDevice.deviceId,
service,
characteristic,
value: '03 04 05 06 07',
value: '0304050607',
});
});

Expand All @@ -300,7 +300,7 @@ describe('BleClient', () => {
deviceId: mockDevice.deviceId,
service,
characteristic,
value: '00 01',
value: '0001',
timeout: 6000,
});
});
Expand All @@ -325,7 +325,7 @@ describe('BleClient', () => {
deviceId: mockDevice.deviceId,
service,
characteristic,
value: '00 01',
value: '0001',
timeout: 6000,
});
});
Expand Down Expand Up @@ -369,7 +369,7 @@ describe('BleClient', () => {
});

it('should run readDescriptor with timeout', async () => {
(BluetoothLe.readDescriptor as jest.Mock).mockReturnValue({ value: '00 05 c8 ' });
(BluetoothLe.readDescriptor as jest.Mock).mockReturnValue({ value: '0005c8' });
const result = await BleClient.readDescriptor(mockDevice.deviceId, service, characteristic, descriptor, {
timeout: 6000,
});
Expand All @@ -380,7 +380,7 @@ describe('BleClient', () => {
descriptor,
timeout: 6000,
});
expect(result).toEqual(hexStringToDataView('00 05 c8'));
expect(result).toEqual(hexStringToDataView('0005c8'));
});

it('should run writeDescriptor with timeout', async () => {
Expand All @@ -393,14 +393,14 @@ describe('BleClient', () => {
numbersToDataView([0, 1]),
{
timeout: 6000,
},
}
);
expect(BluetoothLe.writeDescriptor).toHaveBeenCalledWith({
deviceId: mockDevice.deviceId,
service,
characteristic,
descriptor,
value: '00 01',
value: '0001',
timeout: 6000,
});
});
Expand Down
8 changes: 4 additions & 4 deletions src/conversion.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ describe('textToDataView', () => {
const result = textToDataView('Hello world');
expect(result.byteLength).toEqual(11);
expect(result.byteOffset).toEqual(0);
expect(dataViewToHexString(result)).toEqual('48 65 6c 6c 6f 20 77 6f 72 6c 64');
expect(dataViewToHexString(result)).toEqual('48656c6c6f20776f726c64');
});

it('should convert an empty text to a DataView', () => {
Expand All @@ -69,7 +69,7 @@ describe('textToDataView', () => {

describe('dataViewToText', () => {
it('should convert a DataView to text', () => {
const value = hexStringToDataView('48 65 6c 6c 6f 20 77 6f 72 6c 64');
const value = hexStringToDataView('48656c6c6f20776f726c64');
const result = dataViewToText(value);
expect(result).toEqual('Hello world');
});
Expand All @@ -96,7 +96,7 @@ describe('numberToUUID', () => {

describe('hexStringToDataView', () => {
it('should convert a hex string to a DataView', () => {
const value = '00 05 c8';
const value = '0005c8';
const result = hexStringToDataView(value);
expect(result.byteLength).toEqual(3);
expect(result.byteOffset).toEqual(0);
Expand Down Expand Up @@ -135,7 +135,7 @@ describe('dataViewToHexString', () => {
it('should convert a DataView to a hex string', () => {
const value = new DataView(Uint8Array.from([0, 5, 200]).buffer);
const result = dataViewToHexString(value);
expect(result).toEqual('00 05 c8');
expect(result).toEqual('0005c8');
});

it('should convert an empty DataView to a hex string', () => {
Expand Down
2 changes: 1 addition & 1 deletion src/conversion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export function dataViewToHexString(value: DataView): string {
}
return s;
})
.join(' ');
.join('');
}

export function webUUIDToString(uuid: string | number): string {
Expand Down

0 comments on commit 3ec8a98

Please sign in to comment.