mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
General cleanup and refactor.
This commit is contained in:
@@ -30,6 +30,14 @@
|
||||
// Copyright © 2011-2022 Natalia Portillo
|
||||
// ****************************************************************************/
|
||||
|
||||
|
||||
|
||||
// ReSharper disable JoinDeclarationAndInitializer
|
||||
// ReSharper disable InlineOutVariableDeclaration
|
||||
// ReSharper disable TooWideLocalVariableScope
|
||||
|
||||
namespace Aaru.Core.Devices.Dumping;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
@@ -42,12 +50,6 @@ using Aaru.Console;
|
||||
using Aaru.Core.Logging;
|
||||
using Aaru.Devices;
|
||||
|
||||
// ReSharper disable JoinDeclarationAndInitializer
|
||||
// ReSharper disable InlineOutVariableDeclaration
|
||||
// ReSharper disable TooWideLocalVariableScope
|
||||
|
||||
namespace Aaru.Core.Devices.Dumping;
|
||||
|
||||
partial class Dump
|
||||
{
|
||||
// TODO: Fix offset
|
||||
@@ -65,8 +67,8 @@ partial class Dump
|
||||
double cmdDuration; // Command execution time
|
||||
DateTime timeSpeedStart; // Time of start for speed calculation
|
||||
ulong sectorSpeedStart = 0; // Used to calculate correct speed
|
||||
bool gotFirstTrackPregap = false;
|
||||
int firstTrackPregapSectorsGood = 0;
|
||||
var gotFirstTrackPregap = false;
|
||||
var firstTrackPregapSectorsGood = 0;
|
||||
var firstTrackPregapMs = new MemoryStream();
|
||||
|
||||
_dumpLog.WriteLine("Reading first track pregap");
|
||||
@@ -89,9 +91,9 @@ partial class Dump
|
||||
Invoke($"Trying to read first track pregap sector {firstTrackPregapBlock} ({currentSpeed:F3} MiB/sec.)");
|
||||
|
||||
// ReSharper disable IntVariableOverflowInUncheckedContext
|
||||
sense = _dev.ReadCd(out cmdBuf, out _, (uint)firstTrackPregapBlock, blockSize, 1,
|
||||
MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true,
|
||||
MmcErrorField.None, supportedSubchannel, _dev.Timeout, out cmdDuration);
|
||||
sense = _dev.ReadCd(out cmdBuf, out _, (uint)firstTrackPregapBlock, blockSize, 1, MmcSectorTypes.AllTypes,
|
||||
false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None,
|
||||
supportedSubchannel, _dev.Timeout, out cmdDuration);
|
||||
|
||||
// ReSharper restore IntVariableOverflowInUncheckedContext
|
||||
|
||||
@@ -142,17 +144,17 @@ partial class Dump
|
||||
/// <param name="dbDev">Database entry for device</param>
|
||||
/// <param name="inexactPositioning">Set if we found the drive does not return the exact subchannel we requested</param>
|
||||
/// <param name="dumping">Set if dumping, otherwise media info</param>
|
||||
public static void SolveTrackPregaps(Device dev, DumpLog dumpLog, UpdateStatusHandler updateStatus,
|
||||
Track[] tracks, bool supportsPqSubchannel, bool supportsRwSubchannel,
|
||||
public static void SolveTrackPregaps(Device dev, DumpLog dumpLog, UpdateStatusHandler updateStatus, Track[] tracks,
|
||||
bool supportsPqSubchannel, bool supportsRwSubchannel,
|
||||
Database.Models.Device dbDev, out bool inexactPositioning, bool dumping)
|
||||
{
|
||||
bool sense = true; // Sense indicator
|
||||
byte[] subBuf = null;
|
||||
int posQ;
|
||||
uint retries;
|
||||
bool? bcd = null;
|
||||
byte[] crc;
|
||||
Dictionary<uint, int> pregaps = new Dictionary<uint, int>();
|
||||
var sense = true; // Sense indicator
|
||||
byte[] subBuf = null;
|
||||
int posQ;
|
||||
uint retries;
|
||||
bool? bcd = null;
|
||||
byte[] crc;
|
||||
var pregaps = new Dictionary<uint, int>();
|
||||
inexactPositioning = false;
|
||||
|
||||
if(!supportsPqSubchannel &&
|
||||
@@ -193,14 +195,14 @@ partial class Dump
|
||||
foreach(Track t in tracks)
|
||||
pregaps[t.Sequence] = 0;
|
||||
|
||||
for(int t = 0; t < tracks.Length; t++)
|
||||
for(var t = 0; t < tracks.Length; t++)
|
||||
{
|
||||
Track track = tracks[t];
|
||||
int trackRetries = 0;
|
||||
var trackRetries = 0;
|
||||
|
||||
// First track of each session has at least 150 sectors of pregap and is not always readable
|
||||
if(tracks.Where(trk => trk.Session == track.Session).OrderBy(trk => trk.Sequence).
|
||||
FirstOrDefault().Sequence == track.Sequence)
|
||||
if(tracks.Where(trk => trk.Session == track.Session).OrderBy(trk => trk.Sequence).FirstOrDefault().
|
||||
Sequence == track.Sequence)
|
||||
{
|
||||
AaruConsole.DebugWriteLine("Pregap calculator", "Skipping track {0}", track.Sequence);
|
||||
|
||||
@@ -230,27 +232,26 @@ partial class Dump
|
||||
AaruConsole.DebugWriteLine("Pregap calculator", "Track {0}", track.Sequence);
|
||||
|
||||
int lba = (int)track.StartSector - 1;
|
||||
bool pregapFound = false;
|
||||
var pregapFound = false;
|
||||
Track previousTrack = tracks.FirstOrDefault(trk => trk.Sequence == track.Sequence - 1);
|
||||
|
||||
bool goneBack = false;
|
||||
bool goFront = false;
|
||||
bool forward = false;
|
||||
bool crcOk = false;
|
||||
bool previousPregapIsPreviousTrack = false;
|
||||
var goneBack = false;
|
||||
var goFront = false;
|
||||
var forward = false;
|
||||
var crcOk = false;
|
||||
var previousPregapIsPreviousTrack = false;
|
||||
|
||||
// Check if pregap is 0
|
||||
for(retries = 0; retries < 10 && !pregapFound; retries++)
|
||||
{
|
||||
sense = supportsRwSubchannel
|
||||
? GetSectorForPregapRaw(dev, (uint)lba, dbDev, out subBuf,
|
||||
track.Type == TrackType.Audio)
|
||||
: GetSectorForPregapQ16(dev, (uint)lba, out subBuf, track.Type == TrackType.Audio);
|
||||
? GetSectorForPregapRaw(dev, (uint)lba, dbDev, out subBuf, track.Type == TrackType.Audio)
|
||||
: GetSectorForPregapQ16(dev, (uint)lba, out subBuf, track.Type == TrackType.Audio);
|
||||
|
||||
if(sense)
|
||||
{
|
||||
AaruConsole.DebugWriteLine("Pregap calculator", "LBA: {0}, Try {1}, Sense {2}", lba,
|
||||
retries + 1, sense);
|
||||
AaruConsole.DebugWriteLine("Pregap calculator", "LBA: {0}, Try {1}, Sense {2}", lba, retries + 1,
|
||||
sense);
|
||||
|
||||
continue;
|
||||
}
|
||||
@@ -263,8 +264,8 @@ partial class Dump
|
||||
AaruConsole.DebugWriteLine("Pregap calculator",
|
||||
"LBA: {0}, Try {1}, Sense {2}, Q: {3:X2} {4:X2} {5:X2} {6:X2} {7:X2} {8:X2} {9:X2} {10:X2} {11:X2} {12:X2} CRC 0x{13:X2}{14:X2}, Calculated CRC: 0x{15:X2}{16:X2}",
|
||||
lba, retries + 1, sense, subBuf[0], subBuf[1], subBuf[2], subBuf[3],
|
||||
subBuf[4], subBuf[5], subBuf[6], subBuf[7], subBuf[8], subBuf[9],
|
||||
subBuf[10], subBuf[11], crc[0], crc[1]);
|
||||
subBuf[4], subBuf[5], subBuf[6], subBuf[7], subBuf[8], subBuf[9], subBuf[10],
|
||||
subBuf[11], crc[0], crc[1]);
|
||||
|
||||
crcOk = crc[0] == subBuf[10] && crc[1] == subBuf[11];
|
||||
|
||||
@@ -285,7 +286,7 @@ partial class Dump
|
||||
subBuf[6] = 0;
|
||||
|
||||
// Fix BCD numbering
|
||||
for(int i = 1; i < 10; i++)
|
||||
for(var i = 1; i < 10; i++)
|
||||
{
|
||||
if((subBuf[i] & 0xF0) > 0xA0)
|
||||
subBuf[i] &= 0x7F;
|
||||
@@ -300,13 +301,11 @@ partial class Dump
|
||||
crcOk = crc[0] == subBuf[10] && crc[1] == subBuf[11];
|
||||
|
||||
if(crcOk)
|
||||
{
|
||||
AaruConsole.DebugWriteLine("Pregap calculator",
|
||||
"LBA: {0}, Try {1}, Sense {2}, Q (FIXED): {3:X2} {4:X2} {5:X2} {6:X2} {7:X2} {8:X2} {9:X2} {10:X2} {11:X2} {12:X2} CRC 0x{13:X2}{14:X2}, Calculated CRC: 0x{15:X2}{16:X2}",
|
||||
lba, retries + 1, sense, subBuf[0], subBuf[1], subBuf[2],
|
||||
subBuf[3], subBuf[4], subBuf[5], subBuf[6], subBuf[7], subBuf[8],
|
||||
subBuf[9], subBuf[10], subBuf[11], crc[0], crc[1]);
|
||||
}
|
||||
lba, retries + 1, sense, subBuf[0], subBuf[1], subBuf[2], subBuf[3],
|
||||
subBuf[4], subBuf[5], subBuf[6], subBuf[7], subBuf[8], subBuf[9],
|
||||
subBuf[10], subBuf[11], crc[0], crc[1]);
|
||||
else
|
||||
continue;
|
||||
}
|
||||
@@ -317,7 +316,7 @@ partial class Dump
|
||||
if((subBuf[0] & 0xF) != 1)
|
||||
continue;
|
||||
|
||||
posQ = (subBuf[7] * 60 * 75) + (subBuf[8] * 75) + subBuf[9] - 150;
|
||||
posQ = subBuf[7] * 60 * 75 + subBuf[8] * 75 + subBuf[9] - 150;
|
||||
|
||||
if(subBuf[1] != track.Sequence - 1 ||
|
||||
subBuf[2] == 0 ||
|
||||
@@ -343,16 +342,14 @@ partial class Dump
|
||||
sense = supportsRwSubchannel
|
||||
? GetSectorForPregapRaw(dev, (uint)lba - 10, dbDev, out subBuf,
|
||||
track.Type == TrackType.Audio)
|
||||
: GetSectorForPregapQ16(dev, (uint)lba - 10, out subBuf,
|
||||
track.Type == TrackType.Audio);
|
||||
: GetSectorForPregapQ16(dev, (uint)lba - 10, out subBuf, track.Type == TrackType.Audio);
|
||||
|
||||
for(retries = 0; retries < 10; retries++)
|
||||
{
|
||||
sense = supportsRwSubchannel
|
||||
? GetSectorForPregapRaw(dev, (uint)lba, dbDev, out subBuf,
|
||||
track.Type == TrackType.Audio)
|
||||
: GetSectorForPregapQ16(dev, (uint)lba, out subBuf,
|
||||
track.Type == TrackType.Audio);
|
||||
: GetSectorForPregapQ16(dev, (uint)lba, out subBuf, track.Type == TrackType.Audio);
|
||||
|
||||
if(sense)
|
||||
continue;
|
||||
@@ -387,7 +384,7 @@ partial class Dump
|
||||
subBuf[6] = 0;
|
||||
|
||||
// Fix BCD numbering
|
||||
for(int i = 1; i < 10; i++)
|
||||
for(var i = 1; i < 10; i++)
|
||||
{
|
||||
if((subBuf[i] & 0xF0) > 0xA0)
|
||||
subBuf[i] &= 0x7F;
|
||||
@@ -406,9 +403,8 @@ partial class Dump
|
||||
AaruConsole.DebugWriteLine("Pregap calculator",
|
||||
"LBA: {0}, Try {1}, Sense {2}, Q (FIXED): {3:X2} {4:X2} {5:X2} {6:X2} {7:X2} {8:X2} {9:X2} {10:X2} {11:X2} {12:X2} CRC 0x{13:X2}{14:X2}, Calculated CRC: 0x{15:X2}{16:X2}",
|
||||
lba, retries + 1, sense, subBuf[0], subBuf[1], subBuf[2],
|
||||
subBuf[3], subBuf[4], subBuf[5], subBuf[6], subBuf[7],
|
||||
subBuf[8], subBuf[9], subBuf[10], subBuf[11], crc[0],
|
||||
crc[1]);
|
||||
subBuf[3], subBuf[4], subBuf[5], subBuf[6], subBuf[7], subBuf[8],
|
||||
subBuf[9], subBuf[10], subBuf[11], crc[0], crc[1]);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -428,10 +424,8 @@ partial class Dump
|
||||
{
|
||||
if(pregaps[track.Sequence] == 0)
|
||||
{
|
||||
if((previousTrack.Type == TrackType.Audio &&
|
||||
track.Type != TrackType.Audio) ||
|
||||
(previousTrack.Type != TrackType.Audio &&
|
||||
track.Type == TrackType.Audio))
|
||||
if(previousTrack.Type == TrackType.Audio && track.Type != TrackType.Audio ||
|
||||
previousTrack.Type != TrackType.Audio && track.Type == TrackType.Audio)
|
||||
{
|
||||
dumpLog?.
|
||||
WriteLine("Could not read subchannel for this track, supposing 150 sectors.");
|
||||
@@ -537,7 +531,7 @@ partial class Dump
|
||||
previousPregapIsPreviousTrack = false;
|
||||
|
||||
// Pregap according to Q position
|
||||
posQ = (subBuf[7] * 60 * 75) + (subBuf[8] * 75) + subBuf[9] - 150;
|
||||
posQ = subBuf[7] * 60 * 75 + subBuf[8] * 75 + subBuf[9] - 150;
|
||||
int diff = posQ - lba;
|
||||
int pregapQ = (int)track.StartSector - lba;
|
||||
|
||||
@@ -566,8 +560,8 @@ partial class Dump
|
||||
// If CRC is not OK, only accept pregaps less than 10 sectors longer than previously now
|
||||
if(crcOk || pregapQ - pregaps[track.Sequence] < 10)
|
||||
{
|
||||
AaruConsole.DebugWriteLine("Pregap calculator", "Pregap for track {0}: {1}",
|
||||
track.Sequence, pregapQ);
|
||||
AaruConsole.DebugWriteLine("Pregap calculator", "Pregap for track {0}: {1}", track.Sequence,
|
||||
pregapQ);
|
||||
|
||||
pregaps[track.Sequence] = pregapQ;
|
||||
}
|
||||
@@ -593,14 +587,14 @@ partial class Dump
|
||||
trk.Pregap = (ulong)pregaps[trk.Sequence];
|
||||
|
||||
// Do not reduce pregap, or starting position of session's first track
|
||||
if(tracks.Where(t => t.Session == trk.Session).OrderBy(t => t.Sequence).FirstOrDefault().
|
||||
Sequence == trk.Sequence)
|
||||
if(tracks.Where(t => t.Session == trk.Session).OrderBy(t => t.Sequence).FirstOrDefault().Sequence ==
|
||||
trk.Sequence)
|
||||
continue;
|
||||
|
||||
if(dumping)
|
||||
{
|
||||
// Minus five, to ensure dumping will fix if there is a pregap LBA 0
|
||||
int red = 5;
|
||||
var red = 5;
|
||||
|
||||
while(trk.Pregap > 0 &&
|
||||
red > 0)
|
||||
@@ -652,21 +646,21 @@ partial class Dump
|
||||
|
||||
if(sense)
|
||||
sense = dev.ReadCd(out cmdBuf, out _, lba, 2448, 1, MmcSectorTypes.Cdda, false, false, false,
|
||||
MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.Raw,
|
||||
dev.Timeout, out _);
|
||||
MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.Raw, dev.Timeout,
|
||||
out _);
|
||||
}
|
||||
|
||||
if(!sense)
|
||||
{
|
||||
byte[] tmpBuf = new byte[96];
|
||||
var tmpBuf = new byte[96];
|
||||
Array.Copy(cmdBuf, 2352, tmpBuf, 0, 96);
|
||||
subBuf = DeinterleaveQ(tmpBuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
sense = dev.ReadCd(out cmdBuf, out _, lba, 96, 1, MmcSectorTypes.AllTypes, false, false, false,
|
||||
MmcHeaderCodes.None, false, false, MmcErrorField.None, MmcSubchannel.Raw,
|
||||
dev.Timeout, out _);
|
||||
MmcHeaderCodes.None, false, false, MmcErrorField.None, MmcSubchannel.Raw, dev.Timeout,
|
||||
out _);
|
||||
|
||||
if(sense)
|
||||
sense = dev.ReadCd(out cmdBuf, out _, lba, 96, 1, MmcSectorTypes.Cdda, false, false, false,
|
||||
@@ -674,14 +668,11 @@ partial class Dump
|
||||
dev.Timeout, out _);
|
||||
|
||||
if(!sense)
|
||||
{
|
||||
subBuf = DeinterleaveQ(cmdBuf);
|
||||
}
|
||||
else if(dbDev?.ATAPI?.RemovableMedias?.Any(d => d.SupportsPlextorReadCDDA == true) == true ||
|
||||
dbDev?.SCSI?.RemovableMedias?.Any(d => d.SupportsPlextorReadCDDA == true) == true ||
|
||||
dev.Manufacturer.ToLowerInvariant() == "plextor")
|
||||
sense = dev.PlextorReadCdDa(out cmdBuf, out _, lba, 96, 1, PlextorSubchannel.All, dev.Timeout,
|
||||
out _);
|
||||
sense = dev.PlextorReadCdDa(out cmdBuf, out _, lba, 96, 1, PlextorSubchannel.All, dev.Timeout, out _);
|
||||
|
||||
{
|
||||
if(!sense)
|
||||
@@ -723,8 +714,8 @@ partial class Dump
|
||||
|
||||
if(sense)
|
||||
sense = dev.ReadCd(out cmdBuf, out _, lba, 2368, 1, MmcSectorTypes.Cdda, false, false, false,
|
||||
MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.Q16,
|
||||
dev.Timeout, out _);
|
||||
MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.Q16, dev.Timeout,
|
||||
out _);
|
||||
}
|
||||
|
||||
if(!sense)
|
||||
@@ -735,8 +726,8 @@ partial class Dump
|
||||
else
|
||||
{
|
||||
sense = dev.ReadCd(out cmdBuf, out _, lba, 16, 1, MmcSectorTypes.AllTypes, false, false, false,
|
||||
MmcHeaderCodes.None, false, false, MmcErrorField.None, MmcSubchannel.Q16,
|
||||
dev.Timeout, out _);
|
||||
MmcHeaderCodes.None, false, false, MmcErrorField.None, MmcSubchannel.Q16, dev.Timeout,
|
||||
out _);
|
||||
|
||||
if(sense)
|
||||
sense = dev.ReadCd(out cmdBuf, out _, lba, 16, 1, MmcSectorTypes.Cdda, false, false, false,
|
||||
@@ -755,10 +746,10 @@ partial class Dump
|
||||
/// <returns>De-interleaved Q subchannel</returns>
|
||||
static byte[] DeinterleaveQ(byte[] subchannel)
|
||||
{
|
||||
int[] q = new int[subchannel.Length / 8];
|
||||
var q = new int[subchannel.Length / 8];
|
||||
|
||||
// De-interlace Q subchannel
|
||||
for(int iq = 0; iq < subchannel.Length; iq += 8)
|
||||
for(var iq = 0; iq < subchannel.Length; iq += 8)
|
||||
{
|
||||
q[iq / 8] = (subchannel[iq] & 0x40) << 1;
|
||||
q[iq / 8] += subchannel[iq + 1] & 0x40;
|
||||
@@ -770,12 +761,10 @@ partial class Dump
|
||||
q[iq / 8] += (subchannel[iq + 7] & 0x40) >> 6;
|
||||
}
|
||||
|
||||
byte[] deQ = new byte[q.Length];
|
||||
var deQ = new byte[q.Length];
|
||||
|
||||
for(int iq = 0; iq < q.Length; iq++)
|
||||
{
|
||||
for(var iq = 0; iq < q.Length; iq++)
|
||||
deQ[iq] = (byte)q[iq];
|
||||
}
|
||||
|
||||
return deQ;
|
||||
}
|
||||
@@ -784,29 +773,29 @@ partial class Dump
|
||||
/// <param name="q">Q subchannel</param>
|
||||
static void BinaryToBcdQ(byte[] q)
|
||||
{
|
||||
q[1] = (byte)(((q[1] / 10) << 4) + (q[1] % 10));
|
||||
q[2] = (byte)(((q[2] / 10) << 4) + (q[2] % 10));
|
||||
q[3] = (byte)(((q[3] / 10) << 4) + (q[3] % 10));
|
||||
q[4] = (byte)(((q[4] / 10) << 4) + (q[4] % 10));
|
||||
q[5] = (byte)(((q[5] / 10) << 4) + (q[5] % 10));
|
||||
q[6] = (byte)(((q[6] / 10) << 4) + (q[6] % 10));
|
||||
q[7] = (byte)(((q[7] / 10) << 4) + (q[7] % 10));
|
||||
q[8] = (byte)(((q[8] / 10) << 4) + (q[8] % 10));
|
||||
q[9] = (byte)(((q[9] / 10) << 4) + (q[9] % 10));
|
||||
q[1] = (byte)(((q[1] / 10) << 4) + q[1] % 10);
|
||||
q[2] = (byte)(((q[2] / 10) << 4) + q[2] % 10);
|
||||
q[3] = (byte)(((q[3] / 10) << 4) + q[3] % 10);
|
||||
q[4] = (byte)(((q[4] / 10) << 4) + q[4] % 10);
|
||||
q[5] = (byte)(((q[5] / 10) << 4) + q[5] % 10);
|
||||
q[6] = (byte)(((q[6] / 10) << 4) + q[6] % 10);
|
||||
q[7] = (byte)(((q[7] / 10) << 4) + q[7] % 10);
|
||||
q[8] = (byte)(((q[8] / 10) << 4) + q[8] % 10);
|
||||
q[9] = (byte)(((q[9] / 10) << 4) + q[9] % 10);
|
||||
}
|
||||
|
||||
/// <summary>In place converts Q subchannel from BCD to binary numbering</summary>
|
||||
/// <param name="q">Q subchannel</param>
|
||||
static void BcdToBinaryQ(byte[] q)
|
||||
{
|
||||
q[1] = (byte)((q[1] / 16 * 10) + (q[1] & 0x0F));
|
||||
q[2] = (byte)((q[2] / 16 * 10) + (q[2] & 0x0F));
|
||||
q[3] = (byte)((q[3] / 16 * 10) + (q[3] & 0x0F));
|
||||
q[4] = (byte)((q[4] / 16 * 10) + (q[4] & 0x0F));
|
||||
q[5] = (byte)((q[5] / 16 * 10) + (q[5] & 0x0F));
|
||||
q[6] = (byte)((q[6] / 16 * 10) + (q[6] & 0x0F));
|
||||
q[7] = (byte)((q[7] / 16 * 10) + (q[7] & 0x0F));
|
||||
q[8] = (byte)((q[8] / 16 * 10) + (q[8] & 0x0F));
|
||||
q[9] = (byte)((q[9] / 16 * 10) + (q[9] & 0x0F));
|
||||
q[1] = (byte)(q[1] / 16 * 10 + (q[1] & 0x0F));
|
||||
q[2] = (byte)(q[2] / 16 * 10 + (q[2] & 0x0F));
|
||||
q[3] = (byte)(q[3] / 16 * 10 + (q[3] & 0x0F));
|
||||
q[4] = (byte)(q[4] / 16 * 10 + (q[4] & 0x0F));
|
||||
q[5] = (byte)(q[5] / 16 * 10 + (q[5] & 0x0F));
|
||||
q[6] = (byte)(q[6] / 16 * 10 + (q[6] & 0x0F));
|
||||
q[7] = (byte)(q[7] / 16 * 10 + (q[7] & 0x0F));
|
||||
q[8] = (byte)(q[8] / 16 * 10 + (q[8] & 0x0F));
|
||||
q[9] = (byte)(q[9] / 16 * 10 + (q[9] & 0x0F));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user