| author | |
| committer | |
| log | a362d3963c879af47661f54b0a698729e142619f |
| tree | cc4580245fd8f153482c50c42148833975e4f051 |
| parent | 937138cb90ae9327b0f7a932910c8d6080984f5c |
5 files changed, 47 insertions(+), 34 deletions(-)
src/resinator/bmp.zig+1-1| ... | @@ -92,7 +92,7 @@ pub fn read(reader: anytype, max_size: u64) ReadError!BitmapInfo { | ... | @@ -92,7 +92,7 @@ pub fn read(reader: anytype, max_size: u64) ReadError!BitmapInfo { |
| 92 | const id = std.mem.readIntNative(u16, file_header[0..2]); | 92 | const id = std.mem.readIntNative(u16, file_header[0..2]); |
| 93 | if (id != windows_format_id) return error.InvalidFileHeader; | 93 | if (id != windows_format_id) return error.InvalidFileHeader; |
| 94 | 94 | ||
| 95 | bitmap_info.pixel_data_offset = std.mem.readIntNative(u32, file_header[10..14]); | 95 | bitmap_info.pixel_data_offset = std.mem.readIntLittle(u32, file_header[10..14]); |
| 96 | if (bitmap_info.pixel_data_offset > max_size) return error.ImpossiblePixelDataOffset; | 96 | if (bitmap_info.pixel_data_offset > max_size) return error.ImpossiblePixelDataOffset; |
| 97 | 97 | ||
| 98 | bitmap_info.dib_header_size = reader.readIntLittle(u32) catch return error.UnexpectedEOF; | 98 | bitmap_info.dib_header_size = reader.readIntLittle(u32) catch return error.UnexpectedEOF; |
src/resinator/compile.zig+18-16| ... | @@ -571,7 +571,7 @@ pub const Compiler = struct { | ... | @@ -571,7 +571,7 @@ pub const Compiler = struct { |
| 571 | } | 571 | } |
| 572 | 572 | ||
| 573 | try file.seekTo(entry.data_offset_from_start_of_file); | 573 | try file.seekTo(entry.data_offset_from_start_of_file); |
| 574 | const header_bytes = file.reader().readBytesNoEof(16) catch { | 574 | var header_bytes = file.reader().readBytesNoEof(16) catch { |
| 575 | return self.iconReadError( | 575 | return self.iconReadError( |
| 576 | error.UnexpectedEOF, | 576 | error.UnexpectedEOF, |
| 577 | filename_utf8, | 577 | filename_utf8, |
| ... | @@ -647,8 +647,11 @@ pub const Compiler = struct { | ... | @@ -647,8 +647,11 @@ pub const Compiler = struct { |
| 647 | }, | 647 | }, |
| 648 | }, | 648 | }, |
| 649 | .dib => { | 649 | .dib => { |
| 650 | const bitmap_header: *const ico.BitmapHeader = @ptrCast(@alignCast(&header_bytes)); | 650 | var bitmap_header: *ico.BitmapHeader = @ptrCast(@alignCast(&header_bytes)); |
| 651 | const bitmap_version = ico.BitmapHeader.Version.get(std.mem.littleToNative(u32, bitmap_header.bcSize)); | 651 | if (builtin.cpu.arch.endian() == .Big) { |
| 652 | std.mem.byteSwapAllFields(ico.BitmapHeader, bitmap_header); | ||
| 653 | } | ||
| 654 | const bitmap_version = ico.BitmapHeader.Version.get(bitmap_header.bcSize); | ||
| 652 | 655 | ||
| 653 | // The Win32 RC compiler only allows headers with | 656 | // The Win32 RC compiler only allows headers with |
| 654 | // `bcSize == sizeof(BITMAPINFOHEADER)`, but it seems unlikely | 657 | // `bcSize == sizeof(BITMAPINFOHEADER)`, but it seems unlikely |
| ... | @@ -684,15 +687,15 @@ pub const Compiler = struct { | ... | @@ -684,15 +687,15 @@ pub const Compiler = struct { |
| 684 | .icon => { | 687 | .icon => { |
| 685 | // The values in the icon's BITMAPINFOHEADER always take precedence over | 688 | // The values in the icon's BITMAPINFOHEADER always take precedence over |
| 686 | // the values in the IconDir, but not in the LOCALHEADER (see above). | 689 | // the values in the IconDir, but not in the LOCALHEADER (see above). |
| 687 | entry.type_specific_data.icon.color_planes = std.mem.littleToNative(u16, bitmap_header.bcPlanes); | 690 | entry.type_specific_data.icon.color_planes = bitmap_header.bcPlanes; |
| 688 | entry.type_specific_data.icon.bits_per_pixel = std.mem.littleToNative(u16, bitmap_header.bcBitCount); | 691 | entry.type_specific_data.icon.bits_per_pixel = bitmap_header.bcBitCount; |
| 689 | }, | 692 | }, |
| 690 | .cursor => { | 693 | .cursor => { |
| 691 | // Only cursors get the width/height from BITMAPINFOHEADER (icons don't) | 694 | // Only cursors get the width/height from BITMAPINFOHEADER (icons don't) |
| 692 | entry.width = @intCast(bitmap_header.bcWidth); | 695 | entry.width = @intCast(bitmap_header.bcWidth); |
| 693 | entry.height = @intCast(bitmap_header.bcHeight); | 696 | entry.height = @intCast(bitmap_header.bcHeight); |
| 694 | entry.type_specific_data.cursor.hotspot_x = std.mem.littleToNative(u16, bitmap_header.bcPlanes); | 697 | entry.type_specific_data.cursor.hotspot_x = bitmap_header.bcPlanes; |
| 695 | entry.type_specific_data.cursor.hotspot_y = std.mem.littleToNative(u16, bitmap_header.bcBitCount); | 698 | entry.type_specific_data.cursor.hotspot_y = bitmap_header.bcBitCount; |
| 696 | }, | 699 | }, |
| 697 | } | 700 | } |
| 698 | }, | 701 | }, |
| ... | @@ -826,9 +829,11 @@ pub const Compiler = struct { | ... | @@ -826,9 +829,11 @@ pub const Compiler = struct { |
| 826 | } | 829 | } |
| 827 | if (bitmap_info.getExpectedPaletteByteLen() > 0) { | 830 | if (bitmap_info.getExpectedPaletteByteLen() > 0) { |
| 828 | try writeResourceDataNoPadding(writer, file_reader, @intCast(bitmap_info.getActualPaletteByteLen())); | 831 | try writeResourceDataNoPadding(writer, file_reader, @intCast(bitmap_info.getActualPaletteByteLen())); |
| 829 | const padding_bytes = bitmap_info.getMissingPaletteByteLen(); | 832 | // We know that the number of missing palette bytes is <= 4096 |
| 833 | // (see `bmp_too_many_missing_palette_bytes` error case above) | ||
| 834 | const padding_bytes: usize = @intCast(bitmap_info.getMissingPaletteByteLen()); | ||
| 830 | if (padding_bytes > 0) { | 835 | if (padding_bytes > 0) { |
| 831 | try writer.writeByteNTimes(0, @intCast(padding_bytes)); | 836 | try writer.writeByteNTimes(0, padding_bytes); |
| 832 | } | 837 | } |
| 833 | } | 838 | } |
| 834 | try file.seekTo(bitmap_info.pixel_data_offset); | 839 | try file.seekTo(bitmap_info.pixel_data_offset); |
| ... | @@ -2855,7 +2860,7 @@ pub const SearchDir = struct { | ... | @@ -2855,7 +2860,7 @@ pub const SearchDir = struct { |
| 2855 | pub fn HeaderSlurpingReader(comptime size: usize, comptime ReaderType: anytype) type { | 2860 | pub fn HeaderSlurpingReader(comptime size: usize, comptime ReaderType: anytype) type { |
| 2856 | return struct { | 2861 | return struct { |
| 2857 | child_reader: ReaderType, | 2862 | child_reader: ReaderType, |
| 2858 | bytes_read: u64 = 0, | 2863 | bytes_read: usize = 0, |
| 2859 | slurped_header: [size]u8 = [_]u8{0x00} ** size, | 2864 | slurped_header: [size]u8 = [_]u8{0x00} ** size, |
| 2860 | 2865 | ||
| 2861 | pub const Error = ReaderType.Error; | 2866 | pub const Error = ReaderType.Error; |
| ... | @@ -2866,10 +2871,9 @@ pub fn HeaderSlurpingReader(comptime size: usize, comptime ReaderType: anytype) | ... | @@ -2866,10 +2871,9 @@ pub fn HeaderSlurpingReader(comptime size: usize, comptime ReaderType: anytype) |
| 2866 | if (self.bytes_read < size) { | 2871 | if (self.bytes_read < size) { |
| 2867 | const bytes_to_add = @min(amt, size - self.bytes_read); | 2872 | const bytes_to_add = @min(amt, size - self.bytes_read); |
| 2868 | const end_index = self.bytes_read + bytes_to_add; | 2873 | const end_index = self.bytes_read + bytes_to_add; |
| 2869 | const dest = self.slurped_header[@intCast(self.bytes_read)..@intCast(end_index)]; | 2874 | std.mem.copy(u8, self.slurped_header[self.bytes_read..end_index], buf[0..bytes_to_add]); |
| 2870 | std.mem.copy(u8, dest, buf[0..bytes_to_add]); | ||
| 2871 | } | 2875 | } |
| 2872 | self.bytes_read += amt; | 2876 | self.bytes_read +|= amt; |
| 2873 | return amt; | 2877 | return amt; |
| 2874 | } | 2878 | } |
| 2875 | 2879 | ||
| ... | @@ -3196,9 +3200,7 @@ pub const StringTable = struct { | ... | @@ -3196,9 +3200,7 @@ pub const StringTable = struct { |
| 3196 | // We already trimmed any trailing NULs, so we know it will be a new addition to the string. | 3200 | // We already trimmed any trailing NULs, so we know it will be a new addition to the string. |
| 3197 | if (compiler.null_terminate_string_table_strings) string_len_in_utf16_code_units += 1; | 3201 | if (compiler.null_terminate_string_table_strings) string_len_in_utf16_code_units += 1; |
| 3198 | try data_writer.writeIntLittle(u16, string_len_in_utf16_code_units); | 3202 | try data_writer.writeIntLittle(u16, string_len_in_utf16_code_units); |
| 3199 | for (trimmed_string) |wc| { | 3203 | try data_writer.writeAll(std.mem.sliceAsBytes(trimmed_string)); |
| 3200 | try data_writer.writeIntLittle(u16, wc); | ||
| 3201 | } | ||
| 3202 | if (compiler.null_terminate_string_table_strings) { | 3204 | if (compiler.null_terminate_string_table_strings) { |
| 3203 | try data_writer.writeIntLittle(u16, 0); | 3205 | try data_writer.writeIntLittle(u16, 0); |
| 3204 | } | 3206 | } |
src/resinator/errors.zig+14-2| ... | @@ -7,6 +7,7 @@ const res = @import("res.zig"); | ... | @@ -7,6 +7,7 @@ const res = @import("res.zig"); |
| 7 | const ico = @import("ico.zig"); | 7 | const ico = @import("ico.zig"); |
| 8 | const bmp = @import("bmp.zig"); | 8 | const bmp = @import("bmp.zig"); |
| 9 | const parse = @import("parse.zig"); | 9 | const parse = @import("parse.zig"); |
| 10 | const lang = @import("lang.zig"); | ||
| 10 | const CodePage = @import("code_pages.zig").CodePage; | 11 | const CodePage = @import("code_pages.zig").CodePage; |
| 11 | 12 | ||
| 12 | pub const Diagnostics = struct { | 13 | pub const Diagnostics = struct { |
| ... | @@ -558,8 +559,19 @@ pub const ErrorDetails = struct { | ... | @@ -558,8 +559,19 @@ pub const ErrorDetails = struct { |
| 558 | .hint => return, | 559 | .hint => return, |
| 559 | }, | 560 | }, |
| 560 | .string_already_defined => switch (self.type) { | 561 | .string_already_defined => switch (self.type) { |
| 561 | // TODO: better printing of language, using constant names from WinNT.h | 562 | .err, .warning => { |
| 562 | .err, .warning => return writer.print("string with id {d} (0x{X}) already defined for language {d},{d}", .{ self.extra.string_and_language.id, self.extra.string_and_language.id, self.extra.string_and_language.language.primary_language_id, self.extra.string_and_language.language.sublanguage_id }), | 563 | const language_id = self.extra.string_and_language.language.asInt(); |
| 564 | const language_name = language_name: { | ||
| 565 | if (std.meta.intToEnum(lang.LanguageId, language_id)) |lang_enum_val| { | ||
| 566 | break :language_name @tagName(lang_enum_val); | ||
| 567 | } else |_| {} | ||
| 568 | if (language_id == lang.LOCALE_CUSTOM_UNSPECIFIED) { | ||
| 569 | break :language_name "LOCALE_CUSTOM_UNSPECIFIED"; | ||
| 570 | } | ||
| 571 | break :language_name "<UNKNOWN>"; | ||
| 572 | }; | ||
| 573 | return writer.print("string with id {d} (0x{X}) already defined for language {s} (0x{X})", .{ self.extra.string_and_language.id, self.extra.string_and_language.id, language_name, language_id }); | ||
| 574 | }, | ||
| 563 | .note => return writer.print("previous definition of string with id {d} (0x{X}) here", .{ self.extra.string_and_language.id, self.extra.string_and_language.id }), | 575 | .note => return writer.print("previous definition of string with id {d} (0x{X}) here", .{ self.extra.string_and_language.id, self.extra.string_and_language.id }), |
| 564 | .hint => return, | 576 | .hint => return, |
| 565 | }, | 577 | }, |
src/resinator/literals.zig+7-7| ... | @@ -395,7 +395,7 @@ pub fn parseQuotedString( | ... | @@ -395,7 +395,7 @@ pub fn parseQuotedString( |
| 395 | while (try iterative_parser.next()) |parsed| { | 395 | while (try iterative_parser.next()) |parsed| { |
| 396 | const c = parsed.codepoint; | 396 | const c = parsed.codepoint; |
| 397 | if (parsed.from_escaped_integer) { | 397 | if (parsed.from_escaped_integer) { |
| 398 | try buf.append(@intCast(c)); | 398 | try buf.append(std.mem.nativeToLittle(T, @intCast(c))); |
| 399 | } else { | 399 | } else { |
| 400 | switch (literal_type) { | 400 | switch (literal_type) { |
| 401 | .ascii => switch (options.output_code_page) { | 401 | .ascii => switch (options.output_code_page) { |
| ... | @@ -658,7 +658,7 @@ test "parse quoted wide string" { | ... | @@ -658,7 +658,7 @@ test "parse quoted wide string" { |
| 658 | defer arena_allocator.deinit(); | 658 | defer arena_allocator.deinit(); |
| 659 | const arena = arena_allocator.allocator(); | 659 | const arena = arena_allocator.allocator(); |
| 660 | 660 | ||
| 661 | try std.testing.expectEqualSentinel(u16, 0, &[_:0]u16{ 'h', 'e', 'l', 'l', 'o' }, try parseQuotedWideString(arena, .{ | 661 | try std.testing.expectEqualSentinel(u16, 0, std.unicode.utf8ToUtf16LeStringLiteral("hello"), try parseQuotedWideString(arena, .{ |
| 662 | .slice = | 662 | .slice = |
| 663 | \\L"hello" | 663 | \\L"hello" |
| 664 | , | 664 | , |
| ... | @@ -672,21 +672,21 @@ test "parse quoted wide string" { | ... | @@ -672,21 +672,21 @@ test "parse quoted wide string" { |
| 672 | .code_page = .windows1252, | 672 | .code_page = .windows1252, |
| 673 | }, .{})); | 673 | }, .{})); |
| 674 | // hex max of 4 digits | 674 | // hex max of 4 digits |
| 675 | try std.testing.expectEqualSentinel(u16, 0, &[_:0]u16{ 0xFFFF, 'f' }, try parseQuotedWideString(arena, .{ | 675 | try std.testing.expectEqualSentinel(u16, 0, &[_:0]u16{ std.mem.nativeToLittle(u16, 0xFFFF), std.mem.nativeToLittle(u16, 'f') }, try parseQuotedWideString(arena, .{ |
| 676 | .slice = | 676 | .slice = |
| 677 | \\L"\XfFfFf" | 677 | \\L"\XfFfFf" |
| 678 | , | 678 | , |
| 679 | .code_page = .windows1252, | 679 | .code_page = .windows1252, |
| 680 | }, .{})); | 680 | }, .{})); |
| 681 | // octal max of 7 digits | 681 | // octal max of 7 digits |
| 682 | try std.testing.expectEqualSentinel(u16, 0, &[_:0]u16{ 0x9493, '3', '3' }, try parseQuotedWideString(arena, .{ | 682 | try std.testing.expectEqualSentinel(u16, 0, &[_:0]u16{ std.mem.nativeToLittle(u16, 0x9493), std.mem.nativeToLittle(u16, '3'), std.mem.nativeToLittle(u16, '3') }, try parseQuotedWideString(arena, .{ |
| 683 | .slice = | 683 | .slice = |
| 684 | \\L"\111222333" | 684 | \\L"\111222333" |
| 685 | , | 685 | , |
| 686 | .code_page = .windows1252, | 686 | .code_page = .windows1252, |
| 687 | }, .{})); | 687 | }, .{})); |
| 688 | // octal overflow | 688 | // octal overflow |
| 689 | try std.testing.expectEqualSentinel(u16, 0, &[_:0]u16{0xFF01}, try parseQuotedWideString(arena, .{ | 689 | try std.testing.expectEqualSentinel(u16, 0, &[_:0]u16{std.mem.nativeToLittle(u16, 0xFF01)}, try parseQuotedWideString(arena, .{ |
| 690 | .slice = | 690 | .slice = |
| 691 | \\L"\777401" | 691 | \\L"\777401" |
| 692 | , | 692 | , |
| ... | @@ -757,12 +757,12 @@ test "parse quoted ascii string as wide string" { | ... | @@ -757,12 +757,12 @@ test "parse quoted ascii string as wide string" { |
| 757 | .{}, | 757 | .{}, |
| 758 | )); | 758 | )); |
| 759 | // Maximum escape sequence value is also determined by the L prefix | 759 | // Maximum escape sequence value is also determined by the L prefix |
| 760 | try std.testing.expectEqualSentinel(u16, 0, std.unicode.utf8ToUtf16LeStringLiteral("\x1234"), try parseQuotedStringAsWideString( | 760 | try std.testing.expectEqualSentinel(u16, 0, &[_:0]u16{ std.mem.nativeToLittle(u16, 0x12), std.mem.nativeToLittle(u16, '3'), std.mem.nativeToLittle(u16, '4') }, try parseQuotedStringAsWideString( |
| 761 | arena, | 761 | arena, |
| 762 | .{ .slice = "\"\\x1234\"", .code_page = .windows1252 }, | 762 | .{ .slice = "\"\\x1234\"", .code_page = .windows1252 }, |
| 763 | .{}, | 763 | .{}, |
| 764 | )); | 764 | )); |
| 765 | try std.testing.expectEqualSentinel(u16, 0, &[_:0]u16{0x1234}, try parseQuotedStringAsWideString( | 765 | try std.testing.expectEqualSentinel(u16, 0, &[_:0]u16{std.mem.nativeToLittle(u16, 0x1234)}, try parseQuotedStringAsWideString( |
| 766 | arena, | 766 | arena, |
| 767 | .{ .slice = "L\"\\x1234\"", .code_page = .windows1252 }, | 767 | .{ .slice = "L\"\\x1234\"", .code_page = .windows1252 }, |
| 768 | .{}, | 768 | .{}, |
src/resinator/res.zig+7-8| ... | @@ -218,6 +218,7 @@ pub const ControlClass = enum(u16) { | ... | @@ -218,6 +218,7 @@ pub const ControlClass = enum(u16) { |
| 218 | }; | 218 | }; |
| 219 | 219 | ||
| 220 | pub const NameOrOrdinal = union(enum) { | 220 | pub const NameOrOrdinal = union(enum) { |
| 221 | // UTF-16 LE | ||
| 221 | name: [:0]const u16, | 222 | name: [:0]const u16, |
| 222 | ordinal: u16, | 223 | ordinal: u16, |
| 223 | 224 | ||
| ... | @@ -245,9 +246,7 @@ pub const NameOrOrdinal = union(enum) { | ... | @@ -245,9 +246,7 @@ pub const NameOrOrdinal = union(enum) { |
| 245 | pub fn write(self: NameOrOrdinal, writer: anytype) !void { | 246 | pub fn write(self: NameOrOrdinal, writer: anytype) !void { |
| 246 | switch (self) { | 247 | switch (self) { |
| 247 | .name => |name| { | 248 | .name => |name| { |
| 248 | for (name[0 .. name.len + 1]) |code_unit| { | 249 | try writer.writeAll(std.mem.sliceAsBytes(name[0 .. name.len + 1])); |
| 249 | try writer.writeIntLittle(u16, code_unit); | ||
| 250 | } | ||
| 251 | }, | 250 | }, |
| 252 | .ordinal => |ordinal| { | 251 | .ordinal => |ordinal| { |
| 253 | try writer.writeIntLittle(u16, 0xffff); | 252 | try writer.writeIntLittle(u16, 0xffff); |
| ... | @@ -281,7 +280,7 @@ pub const NameOrOrdinal = union(enum) { | ... | @@ -281,7 +280,7 @@ pub const NameOrOrdinal = union(enum) { |
| 281 | try buf.append(std.mem.nativeToLittle(u16, '�')); | 280 | try buf.append(std.mem.nativeToLittle(u16, '�')); |
| 282 | } else if (c < 0x7F) { | 281 | } else if (c < 0x7F) { |
| 283 | // ASCII chars in names are always converted to uppercase | 282 | // ASCII chars in names are always converted to uppercase |
| 284 | try buf.append(std.ascii.toUpper(@intCast(c))); | 283 | try buf.append(std.mem.nativeToLittle(u16, std.ascii.toUpper(@intCast(c)))); |
| 285 | } else if (c < 0x10000) { | 284 | } else if (c < 0x10000) { |
| 286 | const short: u16 = @intCast(c); | 285 | const short: u16 = @intCast(c); |
| 287 | try buf.append(std.mem.nativeToLittle(u16, short)); | 286 | try buf.append(std.mem.nativeToLittle(u16, short)); |
| ... | @@ -518,10 +517,10 @@ test "NameOrOrdinal" { | ... | @@ -518,10 +517,10 @@ test "NameOrOrdinal" { |
| 518 | var expected_u8_bytes = "00614982008907933748980730280674788429543776231864944218790698304852300002973622122844631429099469274282385299397783838528QFFL7SHNSIETG0QKLR1UYPBTUV1PMFQRRA0VJDG354GQEDJMUPGPP1W1EXVNTZVEIZ6K3IPQM1AWGEYALMEODYVEZGOD3MFMGEY8FNR4JUETTB1PZDEWSNDRGZUA8SNXP3NGO"; | 517 | var expected_u8_bytes = "00614982008907933748980730280674788429543776231864944218790698304852300002973622122844631429099469274282385299397783838528QFFL7SHNSIETG0QKLR1UYPBTUV1PMFQRRA0VJDG354GQEDJMUPGPP1W1EXVNTZVEIZ6K3IPQM1AWGEYALMEODYVEZGOD3MFMGEY8FNR4JUETTB1PZDEWSNDRGZUA8SNXP3NGO"; |
| 519 | var buf: [256:0]u16 = undefined; | 518 | var buf: [256:0]u16 = undefined; |
| 520 | for (expected_u8_bytes, 0..) |byte, i| { | 519 | for (expected_u8_bytes, 0..) |byte, i| { |
| 521 | buf[i] = byte; | 520 | buf[i] = std.mem.nativeToLittle(u16, byte); |
| 522 | } | 521 | } |
| 523 | // surrogate pair that is now orphaned | 522 | // surrogate pair that is now orphaned |
| 524 | buf[255] = 0xD801; | 523 | buf[255] = std.mem.nativeToLittle(u16, 0xD801); |
| 525 | break :blk buf; | 524 | break :blk buf; |
| 526 | }; | 525 | }; |
| 527 | try expectNameOrOrdinal( | 526 | try expectNameOrOrdinal( |
| ... | @@ -908,7 +907,7 @@ pub const ForcedOrdinal = struct { | ... | @@ -908,7 +907,7 @@ pub const ForcedOrdinal = struct { |
| 908 | var result: u16 = 0; | 907 | var result: u16 = 0; |
| 909 | for (utf16) |code_unit| { | 908 | for (utf16) |code_unit| { |
| 910 | if (result != 0) result *%= 10; | 909 | if (result != 0) result *%= 10; |
| 911 | result +%= code_unit -% '0'; | 910 | result +%= std.mem.littleToNative(u16, code_unit) -% '0'; |
| 912 | } | 911 | } |
| 913 | return result; | 912 | return result; |
| 914 | } | 913 | } |
| ... | @@ -929,7 +928,7 @@ test "forced ordinal" { | ... | @@ -929,7 +928,7 @@ test "forced ordinal" { |
| 929 | try std.testing.expectEqual(@as(u16, 0x4AF0), ForcedOrdinal.fromBytes(.{ .slice = "0\u{10100}", .code_page = .utf8 })); | 928 | try std.testing.expectEqual(@as(u16, 0x4AF0), ForcedOrdinal.fromBytes(.{ .slice = "0\u{10100}", .code_page = .utf8 })); |
| 930 | 929 | ||
| 931 | // From UTF-16 | 930 | // From UTF-16 |
| 932 | try std.testing.expectEqual(@as(u16, 0x122), ForcedOrdinal.fromUtf16Le(&[_:0]u16{ '0', 'Œ' })); | 931 | try std.testing.expectEqual(@as(u16, 0x122), ForcedOrdinal.fromUtf16Le(&[_:0]u16{ std.mem.nativeToLittle(u16, '0'), std.mem.nativeToLittle(u16, 'Œ') })); |
| 933 | try std.testing.expectEqual(@as(u16, 0x4AF0), ForcedOrdinal.fromUtf16Le(std.unicode.utf8ToUtf16LeStringLiteral("0\u{10100}"))); | 932 | try std.testing.expectEqual(@as(u16, 0x4AF0), ForcedOrdinal.fromUtf16Le(std.unicode.utf8ToUtf16LeStringLiteral("0\u{10100}"))); |
| 934 | } | 933 | } |
| 935 | 934 |