<NME> TranslationsGetRequest.java
<BEF> /*  Copyright (C) 2020-2021 Daniel Dakhno

    This file is part of Gadgetbridge.

    Gadgetbridge is free software: you can redistribute it and/or modify

import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.file.FileHandle;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileGetRawRequest;

public abstract class TranslationsGetRequest extends FileGetRawRequest {
    public TranslationsGetRequest(FossilWatchAdapter adapter) {
        super(FileHandle.ASSET_TRANSLATIONS, adapter);
    }

    @Override
    public void handleFileRawData(byte[] fileData) {
        ByteBuffer buffer = ByteBuffer.wrap(fileData);
        buffer.order(ByteOrder.LITTLE_ENDIAN);

        buffer.position(12);

        byte[] localeBytes = new byte[5];
        buffer.get(localeBytes);
        String locale = new String(localeBytes);
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.file.FileHandle;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileGetRequest;

        ArrayList<TranslationItem> translations = new ArrayList<>();

        while(buffer.remaining() > 4){
            int originalLength = buffer.getShort() - 1; // subtracting null terminator
            byte[] originalBytes = new byte[originalLength];
            buffer.get(originalBytes);
    public void handleFileData(byte[] fileData) {
        ByteBuffer buffer = ByteBuffer.wrap(fileData);
        buffer.order(ByteOrder.LITTLE_ENDIAN);

        byte[] localeBytes = new byte[5];
        buffer.get(localeBytes);
        String locale = new String(localeBytes);

        buffer.get(); // locale null byte

        ArrayList<TranslationItem> translations = new ArrayList<>();

        while(buffer.remaining() > 0){
            int originalLength = buffer.getShort() - 1; // subtracting null terminator
            byte[] originalBytes = new byte[originalLength];
            buffer.get(originalBytes);
            buffer.get(); // should always return null terminator
            int translatedLength = buffer.getShort() - 1;
            byte[] translatedBytes = new byte[translatedLength];
            buffer.get(translatedBytes);
            buffer.get(); // should always return null terminator

            String original = new String(originalBytes);
            String translated = new String(translatedBytes);

            translations.add(new TranslationItem(original, translated));
        }

        handleTranslations(
                new TranslationData(
                        locale,
                        translations.toArray(new TranslationItem[0])
                )
        );

    }

    public abstract void handleTranslations(TranslationData translationDate);
}

<MSG> Fossil Hybrid: reformatted requests to avoid raw files

<DFF> @@ -6,20 +6,18 @@ import java.util.ArrayList;
 
 import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;
 import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.file.FileHandle;
-import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileGetRawRequest;
+import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileGetRequest;
 
-public abstract class TranslationsGetRequest extends FileGetRawRequest {
+public abstract class TranslationsGetRequest extends FileGetRequest {
     public TranslationsGetRequest(FossilWatchAdapter adapter) {
         super(FileHandle.ASSET_TRANSLATIONS, adapter);
     }
 
     @Override
-    public void handleFileRawData(byte[] fileData) {
+    public void handleFileData(byte[] fileData) {
         ByteBuffer buffer = ByteBuffer.wrap(fileData);
         buffer.order(ByteOrder.LITTLE_ENDIAN);
 
-        buffer.position(12);
-
         byte[] localeBytes = new byte[5];
         buffer.get(localeBytes);
         String locale = new String(localeBytes);
@@ -28,7 +26,7 @@ public abstract class TranslationsGetRequest extends FileGetRawRequest {
 
         ArrayList<TranslationItem> translations = new ArrayList<>();
 
-        while(buffer.remaining() > 4){
+        while(buffer.remaining() > 0){
             int originalLength = buffer.getShort() - 1; // subtracting null terminator
             byte[] originalBytes = new byte[originalLength];
             buffer.get(originalBytes);

{'commit': 'diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/alarm/AlarmsGetRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/alarm/AlarmsGetRequest.java\nindex 76e3a39a6..5febf4d0d 100644\n--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/alarm/AlarmsGetRequest.java\n+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/alarm/AlarmsGetRequest.java\n@@ -22,12 +22,13 @@ import java.nio.ByteBuffer;\n import java.nio.ByteOrder;\n \n import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;\n-import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileLookupAndGetRequest;\n+import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.file.FileHandle;\n+import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileGetRequest;\n import nodomain.freeyourgadget.gadgetbridge.util.GB;\n \n-public class AlarmsGetRequest extends FileLookupAndGetRequest {\n+public class AlarmsGetRequest extends FileGetRequest {\n     public AlarmsGetRequest(FossilWatchAdapter adapter) {\n-        super((byte) 0x0A, adapter);\n+        super(FileHandle.ALARMS, adapter);\n     }\n \n     @Override\n@@ -35,14 +36,10 @@ public class AlarmsGetRequest extends FileLookupAndGetRequest {\n         ByteBuffer buffer = ByteBuffer.wrap(fileData);\n         buffer.order(ByteOrder.LITTLE_ENDIAN);\n \n-        short handle = buffer.getShort(0);\n-        if(handle != (short) 0x0A00) throw new RuntimeException("wrong alarm handle");\n-\n-        int length = buffer.getInt(8) / 3;\n+        int length = fileData.length / 3;\n         Alarm[] alarms = new Alarm[length];\n \n         for (int i = 0; i < length; i++){\n-            buffer.position(12 + i * 3);\n             byte[] alarmBytes = new byte[]{\n                     buffer.get(),\n                     buffer.get(),\n@@ -55,20 +52,5 @@ public class AlarmsGetRequest extends FileLookupAndGetRequest {\n     }\n \n     public void handleAlarms(Alarm[] alarms){\n-        Alarm[] alarms2 = new Alarm[alarms.length];\n-\n-        for(int i = 0; i < alarms.length; i++){\n-            alarms2[i] = Alarm.fromBytes(alarms[i].getData());\n-        }\n-        // TODO: This does nothing currently!\n-    }\n-\n-    @Override\n-    public void handleFileLookupError(FILE_LOOKUP_ERROR error) {\n-        if(error == FILE_LOOKUP_ERROR.FILE_EMPTY){\n-            GB.toast("alarm file empty yet", Toast.LENGTH_LONG,  GB.ERROR);\n-        }else{\n-            throw new RuntimeException("strange lookup stuff");\n-        }\n     }\n }\ndiff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/button/ButtonConfigurationGetRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/button/ButtonConfigurationGetRequest.java\nindex 9604f1463..67c43bf80 100644\n--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/button/ButtonConfigurationGetRequest.java\n+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/button/ButtonConfigurationGetRequest.java\n@@ -22,29 +22,25 @@ import java.nio.ByteOrder;\n import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;\n import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.buttonconfig.ConfigPayload;\n import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.file.FileHandle;\n-import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileGetRawRequest;\n+import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileGetRequest;\n \n-public class ButtonConfigurationGetRequest extends FileGetRawRequest {\n+public class ButtonConfigurationGetRequest extends FileGetRequest {\n     public ButtonConfigurationGetRequest(FossilWatchAdapter adapter) {\n         super(FileHandle.SETTINGS_BUTTONS, adapter);\n     }\n \n     @Override\n-    public void handleFileRawData(byte[] fileData) {\n+    public void handleFileData(byte[] fileData) {\n         log("fileData");\n \n         ByteBuffer buffer = ByteBuffer.wrap(fileData);\n         buffer.order(ByteOrder.LITTLE_ENDIAN);\n \n-        short fileHandle = buffer.getShort(0);\n-        // TODO check file handle\n-        // if(fileData != )\n-\n-        byte count = buffer.get(15);\n+        byte count = buffer.get(3);\n \n         ConfigPayload[] configs = new ConfigPayload[count];\n \n-        buffer.position(16);\n+        buffer.position(4);\n         for(int i = 0; i < count; i++){\n             int buttonIndex = buffer.get() >> 4;\n             int entryCount = buffer.get();\ndiff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/configuration/ConfigurationGetRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/configuration/ConfigurationGetRequest.java\nindex 65dc832ab..332b9b643 100644\n--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/configuration/ConfigurationGetRequest.java\n+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/configuration/ConfigurationGetRequest.java\n@@ -21,24 +21,18 @@ import nodomain.freeyourgadget.gadgetbridge.model.GenericItem;\n import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport;\n import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;\n import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.file.FileHandle;\n-import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileGetRawRequest;\n+import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileGetRequest;\n \n-public class ConfigurationGetRequest extends FileGetRawRequest {\n+public class ConfigurationGetRequest extends FileGetRequest {\n     public ConfigurationGetRequest(FossilWatchAdapter adapter) {\n         super(FileHandle.CONFIGURATION, adapter);\n     }\n \n     @Override\n-    public void handleFileRawData(byte[] fileData) {\n-        byte[] data = new byte[fileData.length - 12 - 4];\n-\n-        System.arraycopy(fileData, 12, data, 0, data.length);\n-        log("config file: " + getAdapter().arrayToString(fileData));\n-        log("config file: " + getAdapter().arrayToString(data));\n-\n+    public void handleFileData(byte[] fileData) {\n         GBDevice device = getAdapter().getDeviceSupport().getDevice();\n \n-        ConfigurationPutRequest.ConfigItem[] items = ConfigurationPutRequest.parsePayload(data);\n+        ConfigurationPutRequest.ConfigItem[] items = ConfigurationPutRequest.parsePayload(fileData);\n         for(ConfigurationPutRequest.ConfigItem item : items){\n             if(item instanceof ConfigurationPutRequest.VibrationStrengthConfigItem){\n                 device.addDeviceInfo(new GenericItem(QHybridSupport.ITEM_VIBRATION_STRENGTH, String.valueOf(((ConfigurationPutRequest.VibrationStrengthConfigItem) item).getValue())));\ndiff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/device_info/GetDeviceInfoRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/device_info/GetDeviceInfoRequest.java\nindex a66da4b05..fe8348c8d 100644\n--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/device_info/GetDeviceInfoRequest.java\n+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/device_info/GetDeviceInfoRequest.java\n@@ -6,9 +6,9 @@ import java.util.ArrayList;\n \n import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;\n import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.file.FileHandle;\n-import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileGetRawRequest;\n+import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileGetRequest;\n \n-public class GetDeviceInfoRequest extends FileGetRawRequest {\n+public class GetDeviceInfoRequest extends FileGetRequest {\n     enum INFO_CLASS{\n         SUPPORTED_FILE_VERSIONS((short) 0x0a, SupportedFileVersionsInfo.class),\n         ;\n@@ -41,14 +41,13 @@ public class GetDeviceInfoRequest extends FileGetRawRequest {\n     }\n \n     @Override\n-    public void handleFileRawData(byte[] fileData) {\n+    public void handleFileData(byte[] fileData) {\n         ByteBuffer buffer = ByteBuffer.wrap(fileData);\n         buffer.order(ByteOrder.LITTLE_ENDIAN);\n-        buffer.position(12);\n \n         ArrayList<DeviceInfo> deviceInfos = new ArrayList<>();\n \n-        while(buffer.remaining() > 4){\n+        while(buffer.remaining() > 0){\n             short type = buffer.getShort();\n             int length = buffer.get();\n             byte[] payload = new byte[length];\ndiff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/notification/NotificationFilterGetRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/notification/NotificationFilterGetRequest.java\nindex fe20888a1..9e354f83a 100644\n--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/notification/NotificationFilterGetRequest.java\n+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/notification/NotificationFilterGetRequest.java\n@@ -21,29 +21,16 @@ import java.nio.ByteOrder;\n \n import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;\n import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.file.FileHandle;\n-import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileGetRawRequest;\n+import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileGetRequest;\n import nodomain.freeyourgadget.gadgetbridge.util.CRC32C;\n \n-public class NotificationFilterGetRequest extends FileGetRawRequest {\n+public class NotificationFilterGetRequest extends FileGetRequest {\n     public NotificationFilterGetRequest(FossilWatchAdapter adapter) {\n         super(FileHandle.NOTIFICATION_FILTER, adapter);\n     }\n \n     @Override\n-    public void handleFileRawData(byte[] fileData) {\n-        log("handleFileData");\n-        ByteBuffer buffer = ByteBuffer.wrap(fileData);\n-        buffer.order(ByteOrder.LITTLE_ENDIAN);\n+    public void handleFileData(byte[] fileData) {\n \n-        byte[] data = new byte[fileData.length - 12 - 4];\n-\n-        System.arraycopy(fileData, 12, data, 0, data.length);\n-\n-        CRC32C crc32c = new CRC32C();\n-        crc32c.update(data,0,data.length);\n-\n-        if((int) crc32c.getValue() != buffer.getInt(fileData.length - 4)){\n-            throw new RuntimeException("CRC invalid");\n-        }\n     }\n }\ndiff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/translation/TranslationsGetRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/translation/TranslationsGetRequest.java\nindex 27d4c8676..94a5d3733 100644\n--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/translation/TranslationsGetRequest.java\n+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/translation/TranslationsGetRequest.java\n@@ -6,20 +6,18 @@ import java.util.ArrayList;\n \n import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;\n import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.file.FileHandle;\n-import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileGetRawRequest;\n+import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileGetRequest;\n \n-public abstract class TranslationsGetRequest extends FileGetRawRequest {\n+public abstract class TranslationsGetRequest extends FileGetRequest {\n     public TranslationsGetRequest(FossilWatchAdapter adapter) {\n         super(FileHandle.ASSET_TRANSLATIONS, adapter);\n     }\n \n     @Override\n-    public void handleFileRawData(byte[] fileData) {\n+    public void handleFileData(byte[] fileData) {\n         ByteBuffer buffer = ByteBuffer.wrap(fileData);\n         buffer.order(ByteOrder.LITTLE_ENDIAN);\n \n-        buffer.position(12);\n-\n         byte[] localeBytes = new byte[5];\n         buffer.get(localeBytes);\n         String locale = new String(localeBytes);\n@@ -28,7 +26,7 @@ public abstract class TranslationsGetRequest extends FileGetRawRequest {\n \n         ArrayList<TranslationItem> translations = new ArrayList<>();\n \n-        while(buffer.remaining() > 4){\n+        while(buffer.remaining() > 0){\n             int originalLength = buffer.getShort() - 1; // subtracting null terminator\n             byte[] originalBytes = new byte[originalLength];\n             buffer.get(originalBytes);\n', 'commit_subject': 'Fossil Hybrid: reformatted requests to avoid raw files', 'repo_name': 'Freeyourgadget/Gadgetbridge', 'committer': {'name': 'Daniel Dakhno', 'email': 'ed6112bef11a9e3378144e34be512fee6b8d70a2@gmail.com', 'time_sec': '1602899884', 'tz_offset': '120', 'date': {'seconds': '1602899884'}}, 'commit_tree': '25e3c488fb630b54b9d5f07b1648c44fbac1c6ee', 'commit_message': 'Fossil Hybrid: reformatted requests to avoid raw files\n', 'language_name': 'Shell', 'license': 'agpl-3.0', 'hunks': '@@ -6,20 +6,18 @@ import java.util.ArrayList;\n \n import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;\n import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.file.FileHandle;\n-import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileGetRawRequest;\n+import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileGetRequest;\n \n-public abstract class TranslationsGetRequest extends FileGetRawRequest {\n+public abstract class TranslationsGetRequest extends FileGetRequest {\n     public TranslationsGetRequest(FossilWatchAdapter adapter) {\n         super(FileHandle.ASSET_TRANSLATIONS, adapter);\n     }\n \n     @Override\n-    public void handleFileRawData(byte[] fileData) {\n+    public void handleFileData(byte[] fileData) {\n         ByteBuffer buffer = ByteBuffer.wrap(fileData);\n         buffer.order(ByteOrder.LITTLE_ENDIAN);\n \n-        buffer.position(12);\n-\n         byte[] localeBytes = new byte[5];\n         buffer.get(localeBytes);\n         String locale = new String(localeBytes);\n@@ -28,7 +26,7 @@ public abstract class TranslationsGetRequest extends FileGetRawRequest {\n \n         ArrayList<TranslationItem> translations = new ArrayList<>();\n \n-        while(buffer.remaining() > 4){\n+        while(buffer.remaining() > 0){\n             int originalLength = buffer.getShort() - 1; // subtracting null terminator\n             byte[] originalBytes = new byte[originalLength];\n             buffer.get(originalBytes);\n', 'addition_count': 4, 'deletion_count': 6, 'src_file': 'a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/translation/TranslationsGetRequest.java', 'tgt_file': 'b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/translation/TranslationsGetRequest.java', 'file_extension': '.java', 'before_file': '/*  Copyright (C) 2020-2021 Daniel Dakhno\n\n    This file is part of Gadgetbridge.\n\n    Gadgetbridge is free software: you can redistribute it and/or modify\n\nimport nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;\nimport nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.file.FileHandle;\nimport nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileGetRawRequest;\n\npublic abstract class TranslationsGetRequest extends FileGetRawRequest {\n    public TranslationsGetRequest(FossilWatchAdapter adapter) {\n        super(FileHandle.ASSET_TRANSLATIONS, adapter);\n    }\n\n    @Override\n    public void handleFileRawData(byte[] fileData) {\n        ByteBuffer buffer = ByteBuffer.wrap(fileData);\n        buffer.order(ByteOrder.LITTLE_ENDIAN);\n\n        buffer.position(12);\n\n        byte[] localeBytes = new byte[5];\n        buffer.get(localeBytes);\n        String locale = new String(localeBytes);\nimport nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.file.FileHandle;\nimport nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileGetRequest;\n\n        ArrayList<TranslationItem> translations = new ArrayList<>();\n\n        while(buffer.remaining() > 4){\n            int originalLength = buffer.getShort() - 1; // subtracting null terminator\n            byte[] originalBytes = new byte[originalLength];\n            buffer.get(originalBytes);\n    public void handleFileData(byte[] fileData) {\n        ByteBuffer buffer = ByteBuffer.wrap(fileData);\n        buffer.order(ByteOrder.LITTLE_ENDIAN);\n\n        byte[] localeBytes = new byte[5];\n        buffer.get(localeBytes);\n        String locale = new String(localeBytes);\n\n        buffer.get(); // locale null byte\n\n        ArrayList<TranslationItem> translations = new ArrayList<>();\n\n        while(buffer.remaining() > 0){\n            int originalLength = buffer.getShort() - 1; // subtracting null terminator\n            byte[] originalBytes = new byte[originalLength];\n            buffer.get(originalBytes);\n            buffer.get(); // should always return null terminator\n            int translatedLength = buffer.getShort() - 1;\n            byte[] translatedBytes = new byte[translatedLength];\n            buffer.get(translatedBytes);\n            buffer.get(); // should always return null terminator\n\n            String original = new String(originalBytes);\n            String translated = new String(translatedBytes);\n\n            translations.add(new TranslationItem(original, translated));\n        }\n\n        handleTranslations(\n                new TranslationData(\n                        locale,\n                        translations.toArray(new TranslationItem[0])\n                )\n        );\n\n    }\n\n    public abstract void handleTranslations(TranslationData translationDate);\n}\n', 'message': 'Fossil Hybrid: reformatted requests to avoid raw files\n', 'author_name': 'Daniel Dakhno', 'lang': 'java'}