IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

CRC : VB->C++


Sujet :

C++

  1. #1
    Membre du Club
    Homme Profil pro
    Inscrit en
    Septembre 2009
    Messages
    65
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2009
    Messages : 65
    Points : 41
    Points
    41
    Par défaut CRC : VB->C++
    Bonjour,

    Je dois ré-écrire en C++ un module VB effectuant des calculs de CRC. Le problème est que je n'ai absolument aucune connaissance dans le domaine et que le code n'est pratiquement pas commenté. Le CRC en question est un CRC16-CCITT (du moins il me semble).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
     
    Private Declare Function bSHL Lib "bitwise.dll" (ByVal a1 As Long, ByVal a2 As Integer) As Long
     
    Private Declare Function bLongToWord Lib "bitwise.dll" (ByVal a1 As Long) As Integer
     
    Private OutFileName As String
     
    Dim fOut As Integer
    Dim PutBitMask As Byte
    Dim PutBitByte As Byte
    Dim PutBitOffset As Long
    Dim bPutBitFixupMode As Boolean
    Dim PutBitRecNum As Long
    Dim FxLog As Integer
    Public FxCRCLog As Integer
    Dim LogFileName As String
    Public bLogging As Boolean, bCRCLogging As Boolean
     
    Public nErrors As Long
     
    Public Const LOGINFO = 0
    Public Const LOGWARN = 1
    Public Const LOGV1 = 100
    Public Const LOGERROR = 9
     
    Public Const NUMBITSSTRING = -2
    Public Const NUMBITSBINARY = -3
     
    Dim crc16 As Integer
    Const MTT = &H1021
    Const INIT = &HFFFF
     
    Private Type ALengthFixup
      Offset As Long
      Value As Long
    End Type
     
    Private Type ACRCFixup
      OffsetStart As Long
      OffsetStop  As Long
      OffsetRewrite As Long
    End Type
     
    Private Const MAXLFIXUPTABLE = 500
    Private Const MAXCFIXUPTABLE = 500
    Private LFixupTable(1 To MAXLFIXUPTABLE) As ALengthFixup
    Private CFixupTable(1 To MAXCFIXUPTABLE) As ACRCFixup
    Private IxLFixupTable As Integer
    Private IxCFixupTable As Integer
    Public DepthLFixupTable As Integer
    Public OutFile_bHidden As Boolean
    Public Const NOTVISIBLESTRING = "<NOT VISIBLE>"
     
    ''Output file related functions
     
    Public Function OutFile_Init(FN As String) As Boolean
      On Error Resume Next
      fOut = FreeFile
      Open FN For Binary Access Read Write As #fOut
      OutFile_Init = (Err.Number = 0)
      PutBitMask = &H80
      PutBitByte = 0
      PutBitOffset = 0
      PutBitRecNum = 1
      bPutBitFixupMode = False
      IxLFixupTable = 0
      IxCFixupTable = 0
      DepthLFixupTable = 0
      OutFileName = FN
      OutFile_bHidden = False
    End Function
     
    Public Sub OutFile_Purge()
      If PutBitMask <> &H80 Then
        Put #fOut, PutBitRecNum, PutBitByte
        PutBitByte = 0
        PutBitMask = &H80
      End If
    End Sub
     
    Public Function OutFile_GetPutBitOffset() As String
      OutFile_GetPutBitOffset = Format(PutBitOffset, "00000000")
    End Function
     
    Public Sub OutFile_PutBit(bitvalue As Byte) 
      On Error GoTo 0
      PutBitOffset = PutBitOffset + 1
      If bitvalue = 1 Then PutBitByte = PutBitByte Or PutBitMask Else PutBitByte = PutBitByte And (Not PutBitMask)
      If PutBitMask = 1 Then
        Put #fOut, PutBitRecNum, PutBitByte  
        PutBitRecNum = PutBitRecNum + 1
        If bPutBitFixupMode Then '' must read previouly written value
          Get #fOut, PutBitRecNum, PutBitByte ''read back previous value
        Else
          PutBitByte = 0
        End If
        PutBitMask = &H80
      Else
        PutBitMask = PutBitMask \ 2
      End If
    End Sub
     
    Public Function OutFile_PutValue(ByVal sv As String, ByVal cResol As Double, ByVal NumberOfBits As Integer, Optional StringSize As Integer) As String
    Dim Final As String, Ix As Integer, re As Byte, v As Double
      Dim ForLog As String
      Dim iSS As Integer
      Dim aze As Double
     
      '' Make sure no exceptions are raised
      OutFile_PutValue = "?"
      If NumberOfBits <> NUMBITSSTRING Then
         If NumberOfBits < 1 Then
            Exit Function
         End If
      End If
     
      ForLog = OutFile_GetPutBitOffset
      If NumberOfBits = NUMBITSSTRING Then
        iSS = Abs(StringSize)
        If Len(sv) > iSS Then
           If bLogging Then Call AppendLog(LOGERROR, "Length of '" & sv & "' exceeds asked for length (" & iSS & ")")
           nErrors = nErrors + 1
        End If
        sv = Left(sv & Space(iSS), iSS)
        OutFile_PutValue = sv
        For Ix = 1 To iSS
          If StringSize < 0 Then
            Call OutFile_PutValue("0", 1, 8)
            Call OutFile_PutValue("0", 1, 8)
            Call OutFile_PutValue("0", 1, 8)
          End If
          Call OutFile_PutValue(CStr(Asc(Mid(sv, Ix, 1))), 1, 8)
        Next Ix
        Exit Function
      End If
     
      On Error Resume Next
      v = CDbl(sv)
      If Err.Number <> 0 Then
        v = 0: Err.Clear
      End If
      If cResol <> 1 Then
         If cResol <> 0 Then
            v = CDec(v) / CDec(cResol) 
         End If
      End If
      Final = String(NumberOfBits, "0")
      For Ix = 1 To NumberOfBits
        re = CMod(v, 2)
        v = Int(CDec(v) / 2) 
        If re <> 0 Then Mid(Final, NumberOfBits - Ix + 1, 1) = "1"
      Next Ix
      For Ix = 1 To NumberOfBits
        If Mid(Final, Ix, 1) = "1" Then Call OutFile_PutBit(1) Else Call OutFile_PutBit(0)
      Next Ix
      OutFile_PutValue = Final
      If bLogging Then
      If OutFile_bHidden Then
         If bLogging Then Call AppendLog(LOGINFO, ForLog & " > " & NOTVISIBLESTRING)
      Else
         If bLogging Then Call AppendLog(LOGINFO, ForLog & " > " & Final)
      End If
      End If
    End Function
     
    Public Sub OutFile_Rewrite32bits(lOffset As Long, lValue As Long)
      Dim ldiv As Long, lmod As Integer, bOldMode As Boolean, Ix As Integer
     
      '' Can only be called with a PURGED BinaryFile
      bOldMode = bPutBitFixupMode
      Call OutFile_Purge
      bPutBitFixupMode = True
      ldiv = 1 + (lOffset \ 8) '' first byte is offset 1
      lmod = lOffset Mod 8
      Get #fOut, ldiv, PutBitByte
      PutBitMask = &H80
      For Ix = 1 To lmod: PutBitMask = PutBitMask \ 2: Next Ix
      PutBitOffset = lOffset
      PutBitRecNum = ldiv  
      Call OutFile_PutValue(lValue, 1, 32)
      Call OutFile_Purge
      bPutBitFixupMode = bOldMode
    End Sub
     
    Public Sub OutFile_PatchLength(lOffset As Long, lValue As Long)
      Call OutFile_Rewrite32bits(lOffset, lValue)
      If bLogging Then Call AppendLog(LOGINFO, "Setting length @" & CStr(lOffset) & " to " & CStr(lValue))
    End Sub
     
    Public Function OutFile_OpenLFixup() As Integer
      If IxLFixupTable >= MAXLFIXUPTABLE Then
        If bLogging Then Call AppendLog(LOGERROR, "too many length fixups defined")
        nErrors = nErrors + 1
      Else
        IxLFixupTable = IxLFixupTable + 1
        LFixupTable(IxLFixupTable).Offset = PutBitOffset
      End If
      DepthLFixupTable = DepthLFixupTable + 1
      If bLogging Then Call AppendLog(LOGINFO, "$$$$Remembering Length FIXUP position " & CStr(IxLFixupTable) & " Depth=" & CStr(DepthLFixupTable) & " at " & CStr(PutBitOffset))
      OutFile_OpenLFixup = IxLFixupTable
    End Function
     
    Public Sub OutFile_CloseLFixup(FixupIndex As Integer)
      LFixupTable(FixupIndex).Value = PutBitOffset - LFixupTable(FixupIndex).Offset - 32
      If bLogging Then Call AppendLog(LOGINFO, "$$$$Closing Length FIXUP position " & CStr(FixupIndex) & " Depth=" & CStr(DepthLFixupTable) & " at " & CStr(PutBitOffset))
      DepthLFixupTable = DepthLFixupTable - 1
    End Sub
     
    Public Sub OutFile_ProcessLFixups()
      Dim Ix As Integer
     
      If bLogging Then Call AppendLog(LOGINFO, "")
      If bLogging Then Call AppendLog(LOGINFO, "$$$$Actual file size is " & CStr(LOF(fOut)))
      If bLogging Then Call AppendLog(LOGINFO, "Rewriting " & CStr(IxLFixupTable) & " Length fixup(s)")
      Ix = 1
      While Ix <= IxLFixupTable
        With LFixupTable(Ix)
          Call OutFile_PatchLength(.Offset, .Value)
        End With
        Ix = Ix + 1
      Wend
    End Sub
     
    Public Sub OutFile_CRC16Init()
      crc16 = INIT
      If bCRCLogging Then Print #FxCRCLog, ">>> INIT to " & CStr(crc16)
    End Sub
     
    Private Function Cut16(l As Long) As Integer
      Cut16 = bLongToWord(l)
    End Function
     
    Public Sub OutFile_CRC16UpdCRC(ByVal c As Integer)
      Dim w As Long, i As Integer
      On Error GoTo 0
      If bCRCLogging Then Print #FxCRCLog, "Adding " & CStr(c)
      w = CLng(c)
      w = bSHL(w, 8)                          '' c <<= 8; (local copy into w)
      For i = 0 To 7                                '' for (i=0;i<8;i++) {
        ''&H8000&: the final & is MANDATORY (0.28)
        If (Cut16(crc16 Xor w) And &H8000&) <> 0 Then     '' if (crc16 ^ w) & 0x8000)
          crc16 = Cut16(bSHL(crc16, 1)) Xor MTT            '' crc16 = (crc16 << 1) ^^MTT;
        Else                                        '' else
          crc16 = Cut16(bSHL(crc16, 1))                    ''  crc16 = crc16 << 1;
        End If                                      ''
        w = bSHL(w, 1)                              '' w <<= 1;
      Next i
    End Sub
     
    Public Function OutFile_CRC16GetCRC() As Long
      Dim l As Long
      l = CLng(crc16)
      If l < 0 Then l = l + 65536
      If bCRCLogging Then Print #FxCRCLog, "<<<< GIVES " & CStr(l)
      OutFile_CRC16GetCRC = l
    End Function
     
    Public Function OutFile_CRC16ComputeOnPartOfFile(lOStart As Long, lOEnd As Long) As Long
      '' assume file is open
      Dim lIx As Long, b As Byte, Ix As Integer
      Dim lmodE As Integer, ldivE As Long, lmodS As Integer, ldivS As Long
      Dim mskE As Byte, mskS As Byte
     
      ldivS = 1 + (lOStart \ 8) '' first byte is offset 1
      lmodS = lOStart Mod 8
      mskS = &HFF
      For Ix = 1 To lmodS: mskS = mskS \ 2: Next Ix
     
      ldivE = 1 + (lOEnd \ 8) '' first byte is offset 1
      lmodE = lOEnd Mod 8
      mskE = &H7F
      For Ix = 1 To lmodE: mskE = mskE \ 2: Next Ix
      mskE = Not mskE
     
      Call OutFile_CRC16Init
      If ldivS = ldivE Then
        '' special case if lDivS = ldivE: range is one single byte (maybe part of)
        Call OutFile_CRC16Init
        Get #fOut, ldivS, b
        b = (b And mskS) And mskE
        Call OutFile_CRC16UpdCRC(b)
      Else
        '' first handle first byte
        lIx = ldivS
        Get #fOut, lIx, b
        Call OutFile_CRC16UpdCRC(b And mskS)
        lIx = lIx + 1
        '' next handle all whole bytes till one BEFORE last byte
        While (lIx < ldivE)
          Get #fOut, lIx, b
          Call OutFile_CRC16UpdCRC(b)
          lIx = lIx + 1
        Wend
        '' finally handle last byte
        Get #fOut, lIx, b
        Call OutFile_CRC16UpdCRC(b And mskE)
      End If
     
      OutFile_CRC16ComputeOnPartOfFile = OutFile_CRC16GetCRC
    End Function
     
    Public Function OutFile_OpenCFixup() As Integer
      If IxCFixupTable >= MAXCFIXUPTABLE Then
        If bLogging Then Call AppendLog(LOGERROR, "too many CRC fixups defined")
        nErrors = nErrors + 1
      Else
        IxCFixupTable = IxCFixupTable + 1
        CFixupTable(IxCFixupTable).OffsetStart = PutBitOffset
      End If
      If bLogging Then Call AppendLog(LOGINFO, "$$$$Remembering CRC FIXUP position " & CStr(IxLFixupTable) & " at " & CStr(PutBitOffset))
      OutFile_OpenCFixup = IxCFixupTable
    End Function
     
    Public Sub OutFile_CloseCFixup(FixupIndex As Integer)
      ''parameter is ignored, left to keep symmetry with OpenLFixup & CloseLFixup
      CFixupTable(IxCFixupTable).OffsetStop = PutBitOffset - 1
      CFixupTable(IxCFixupTable).OffsetRewrite = PutBitOffset
      If bLogging Then Call AppendLog(LOGINFO, "$$$$Closing CRC FIXUP position " & CStr(FixupIndex) & " at " & CStr(PutBitOffset - 1))
    End Sub
     
    Public Sub OutFile_CRC16ProcessCFixups()
      Dim lCRC As Long, Ix As Integer
     
      ''to be called AFTER purge and length fixups
     
      If bLogging Then Call AppendLog(LOGINFO, "")
      If bLogging Then Call AppendLog(LOGINFO, "$$$$Actual file size is " & CStr(LOF(fOut)))
      If bLogging Then Call AppendLog(LOGINFO, "Rewriting " & CStr(IxCFixupTable) & " CRC fixup(s)")
     
      Ix = 1
      While Ix <= IxCFixupTable
        With CFixupTable(Ix)
     
          '' compute crc for range
          If bLogging Then Call AppendLog(LOGINFO, "Computing CRC from " & CStr(.OffsetStart) & " to " & CStr(.OffsetStop))
          lCRC = OutFile_CRC16ComputeOnPartOfFile(.OffsetStart, .OffsetStop)
     
          '' seek to correct position and write value
          Call OutFile_Rewrite32bits(.OffsetRewrite, lCRC)
          If bLogging Then Call AppendLog(LOGINFO, "Setting CRC @" & CStr(.OffsetRewrite) & " to " & CStr(lCRC) & " (hex=" & Hex(lCRC) & ")")
     
          Ix = Ix + 1
        End With
      Wend
     
    End Sub
     
    Public Function CMod(pVal As Double, pParm As Long) As Double
    Dim c As String * 1    
        Select Case Val(Right$(Str(pVal), 1))
               Case 0, 2, 4, 6, 8
                    CMod = 0
               Case Else
                    CMod = 1
        End Select
    End Function
    Les appendLog() écrivent dans un fichier les logs de tout ce qui est réalisé.

    Alors évidemment, je ne demande pas que l'on fasse tout le boulot à ma place mais si j'ai déjà du mal à comprendre le code, je n'arriverai pas à le ré-écrire en C++... Simplement si quelqu'un pouvait m'aiguiller, m'expliquer un peu ou bien m'aider à traduire ce code en C++, je lui en serais fort reconnaissant. Par exemple, n'y a-t-il pas des codes C++ qui font déjà ce qui est ci-dessus (que ce soit en tout ou en partie) ?

    Merci d'avance.

  2. #2
    Membre éclairé
    Inscrit en
    Décembre 2010
    Messages
    290
    Détails du profil
    Informations forums :
    Inscription : Décembre 2010
    Messages : 290
    Points : 719
    Points
    719
    Par défaut
    S'il s'agit bien du CRC 16 du CCITT (et visiblement, le polynome 1021 semble le confirmer), alors il existe plusieurs sources disponibles, notamment :
    https://github.com/id-Software/Quake...WinQuake/crc.c
    mais attention : il est sous GPL.

    <mode troll> Je comprends rien au VB, mais ça me semble méchamment compliqué pour ce que ça fait. </mode troll>

  3. #3
    Expert éminent sénior
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 361
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 361
    Points : 20 381
    Points
    20 381
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Private Type ALengthFixup
      Offset As Long
      Value As Long
    End Type
    ça équivaut à struct
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    typedef struct ALengthFixup
    {
    long Offset;
    long value;
    }


    Const INIT = &HFFFF=> le "&" avec VB c'est le signe de la notation hexadécimale 0xffff

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Public Function OutFile_Init(FN As String) As Boolean
      On Error Resume Next
      fOut = FreeFile
      Open FN For Binary Access Read Write As #fOut
    End Function
    équivaut à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     
    bool OutFile_Init(char * FN) 
    {
    FILE fOut;
    fOut=fopen("fichier.bin","wb");
    ....
    }
    FreeFile c'est l'équivalent de la structure File pour ouvrir des fichiers

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Call OutFile_CRC16Init
    l'instruction Call n'est pas indispensable en VB; cela signifie qu'on appelle une fonction ou procédure

  4. #4
    Membre du Club
    Homme Profil pro
    Inscrit en
    Septembre 2009
    Messages
    65
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2009
    Messages : 65
    Points : 41
    Points
    41
    Par défaut
    J'ai entamé la ré-écriture du code, si quelqu'un a le temps d'y jeter un coup d’œil pour voir si ça lui semble correct, ou bien si vous avez des conseils à me donner, n'hésitez pas.
    PS : je travaille sous C++ Builder 5.

    ModOutFile.h :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
     
    #ifndef ModOutFileH
    #define ModOutFileH
     
    #include <fstream>
    #include <iostream>
    #include <stdlib.h>
    #include <stdio.h>
     
    class ModOutFile
    {
       private:
            static TDateTime st;
            static bool bLogFileOpen;
            static bool bLogging;
            static bool bCRCLogging;
     
       public:
            static const int LOGINFO;
            static const int LOGWARN;
            static const int LOGV1;
            static const int LOGERROR;
     
            static const int NUMBITSSTRING;
            static const int NUMBITSBINARY;
     
            static const String NOTVISIBLESTRING;
     
            static std::ofstream fxLog;
            static std::ofstream fxCRCLog;
            static String logFileName;
     
            static unsigned char putBitMask;   //byte
            static unsigned char putBitByte;   //byte
            static int putBitOffset;
            static long putBitRecNum;
            static bool bPutBitFixupMode;
            static int ixLFixupTable;
            static int ixCFixupTable;
            static int depthLFixupTable;
            static String outFileName;
            static bool outFilebHidden;
            static FILE* fOut;
     
            static void __fastcall appendLog(int logType, String sLogEntry);
            static void __fastcall openLogFile(String fn);
            static void __fastcall closeLogFile(bool bProposeToView);
            static bool __fastcall outFileInit(String fn);
            static void __fastcall outFilePurge();
            static void __fastcall outFileDone();
            static void __fastcall outFileDelete();
            static String __fastcall outFileGetPutBitOffset();
            static void __fastcall outFilePutBit(unsigned char bitvalue);
            static String __fastcall outFilePutValue(String sv, double cResol, int numberOfBits, int stringSize = 0);
            static double __fastcall cMod(double pVal);
     
    };
    #endif
    ModOutFile.cpp :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
     
    #include <vcl.h>
    #pragma hdrstop
     
    #include <iostream>
    #include <sstream>
    #include "ModOutFile.h"
     
    TDateTime ModOutFile::st;
    bool ModOutFile::bLogFileOpen;
    bool ModOutFile::bLogging;
    bool ModOutFile::bCRCLogging;
     
    unsigned char ModOutFile::putBitMask;
    unsigned char ModOutFile::putBitByte;
    int ModOutFile::putBitOffset;
    long ModOutFile::putBitRecNum;
    bool ModOutFile::bPutBitFixupMode;
    int ModOutFile::ixLFixupTable;
    int ModOutFile::ixCFixupTable;
    int ModOutFile::depthLFixupTable;
    String ModOutFile::outFileName;
    bool ModOutFile::outFilebHidden;
    FILE* ModOutFile::fOut = NULL;
     
    String ModOutFile::logFileName;
     
    std::ofstream ModOutFile::fxLog;
    std::ofstream ModOutFile::fxCRCLog;
     
    const int ModOutFile::LOGINFO = 0;
    const int ModOutFile::LOGWARN = 1;
    const int ModOutFile::LOGV1 = 100;
    const int ModOutFile::LOGERROR = 9;
     
    const int ModOutFile::NUMBITSSTRING = -2;
    const int ModOutFile::NUMBITSBINARY = -3;
     
    const String ModOutFile::NOTVISIBLESTRING = "<NOT VISIBLE>";
     
    // OK sauf que
    // normalement dans le if de LOGERROR on teste s'il y eu une erreur et
    // si c'est le cas alors on l'ajoute à sLogEntry
    // comment traduire ça en C++ ?
    void __fastcall ModOutFile::appendLog(int logType, String sLogEntry)
    {
       String sPrefix, time;
       unsigned short hour, min, sec, msec;
     
       if(logType == LOGERROR)
            sPrefix = " ###ERR### ";
       else if(logType == LOGWARN)
            sPrefix = " ---WRN--- ";
       else if(logType == LOGV1)
            sPrefix = " ::V1EXT::";
     
       if(bLogFileOpen)
       {
            st = st.CurrentTime();
            st.DecodeTime(&hour, &min, &sec, &msec);
            TVarRec vr[] = {hour, min, sec, msec};
            time = Format("%.2u:%.2u:%.2u,%.3u", vr, 3);
     
            fxLog << time.c_str() << sPrefix.c_str() << sLogEntry.c_str() << std::endl;
            // ici normalement on close et on ré-ouvre (utilité ?)
       }
    }
     
    // OK
    void __fastcall ModOutFile::openLogFile(String fn)
    {
       bLogFileOpen = false;
       bLogging = false;
       bCRCLogging = false;
     
       if(fn.Trim() == "")
            return;
     
       fxLog.open(fn.c_str(), std::ios::app);
       bLogFileOpen = true;
       bLogging = true;
       logFileName = fn;
       int index = fn.Pos(".logc");
       if((index == fn.Length()-4) && (index != 0))
       {
            String fileName = fn + ".CRC";
            fxCRCLog.open(fileName.c_str());
            bCRCLogging = true;
       }
    }
     
    // OK
    void __fastcall ModOutFile::closeLogFile(bool bProposeToView)
    {
       if(bLogFileOpen)
       {
            if(bCRCLogging)
                    fxCRCLog.close();
            fxLog.close();
            if(bProposeToView)
            {
                    if(Application->MessageBox("Do you want to view the logfile?", "logfile", MB_YESNO | MB_ICONQUESTION) == IDYES)
                    {
                            if(!(ShellExecute(NULL, "open", "notepad++.exe", logFileName.c_str(), NULL, SW_SHOW) > (HINSTANCE)32))
                            {
                                    String info = "Cannot start 'notepad.exe " + logFileName + "'";
                                    Application->MessageBox(info.c_str(), "logSQL", MB_OK);
                            }
                    }                              
            }
       }
       bLogFileOpen = false;
    }
     
    // normalement OK mais attention à putBitRecNum (voir comm)
    bool __fastcall ModOutFile::outFileInit(String fn)
    {
       putBitMask = 0x80;
       putBitByte = 0;
       putBitOffset = 0;
       putBitRecNum = 0;  //normalement =1 mais avec fseek le début est à 0
       bPutBitFixupMode = false;
       ixLFixupTable = 0;
       ixCFixupTable = 0;
       depthLFixupTable = 0;
       outFileName = fn;
       outFilebHidden = false;
     
       //using the C way is the only way to open in read AND write mode
       fOut = fopen(fn.c_str(), "wb+");
       if (fOut != NULL)
            return true;
       else
            return false;
    }
     
    void __fastcall ModOutFile::outFilePurge()
    {
       if(putBitMask != 0x80)
       {
            fseek(fOut, putBitRecNum * sizeof(char), SEEK_SET);
            fwrite(&putBitByte, sizeof(char), 1, fOut);
            putBitByte = 0;
            putBitMask = 0x80;
       }
    }
     
    // OK
    void __fastcall ModOutFile::outFileDone()
    {
       outFilePurge();
       fclose(fOut);
    }
     
    // OK
    void __fastcall ModOutFile::outFileDelete()
    {
       fclose(fOut);
       if(FileExists(outFileName))
            remove(outFileName.c_str());
    }
     
    // OK
    // si 9 chiffres alors il affiche aussi le 9ème
    // comportement similaire à la fonction format de VB
    String __fastcall ModOutFile::outFileGetPutBitOffset()
    {
       TVarRec vr[] = {putBitOffset};
       return Format("%.8u", vr, 0);
    }
     
    //normalement ok 
    void __fastcall ModOutFile::outFilePutBit(unsigned char bitvalue)
    {
       ++putBitOffset;
       if(bitvalue == 1)
            putBitByte |= putBitMask;
       else
            putBitByte &= (~putBitMask);
     
       if(putBitMask == 1)
       {
            fseek(fOut, putBitRecNum * sizeof(char), SEEK_SET);
            fwrite(&putBitByte, sizeof(char), 1, fOut);
            ++putBitRecNum;
            //d'après le commentaire on lit ici la valeur précédente
            // mais on incrémente putBitRecNum qui sert pourtant 
            // justement à se positionner dans le fichier, ?
            if(bPutBitFixupMode) 
            {
                    fseek(fOut, putBitRecNum * sizeof(char), SEEK_SET);
                    fread(&putBitByte, sizeof(char), 1, fOut);
            }
            else
                    putBitByte = 0;
            putBitMask = 0x80;
       }
       else
            putBitMask >>= 1; // divide by 2
    }
     
    //finie mais pas vérifiée du tout
    String __fastcall ModOutFile::outFilePutValue(String sv, double cResol, int numberOfBits, int stringSize)
    {
       String ret, forLog, final;
       int iSS;
       double v;
       unsigned char re;
     
       ret = "?";
       // OPTIMISATION = if(numberOfBits != NUMBITSSTRING && numberOfBits < 1)
       if(numberOfBits != NUMBITSSTRING)
       {
            if(numberOfBits < 1)
                    return ret;
       }
       forLog = outFileGetPutBitOffset();
       if(numberOfBits == NUMBITSSTRING)
       {
            iSS = abs(stringSize);
            if(sv.Length() > iSS)
            {
                    if(bLogging)
                            appendLog(LOGERROR, "Length of '" + sv + "' exceeds asked for length (" + iSS + ")");
            }
            //construct spaces string
            String iSSSpaces = "";
            for(int i = 0; i < iSS; ++i)
                    iSSSpaces += " ";
            String svWithSpaces = sv + iSSSpaces;
            sv = svWithSpaces.SubString(1, iSS);
            ret = sv;
            for(int ix = 1; ix <= iSS; ++ix)
            {
                    if(stringSize < 0)
                    {
                            outFilePutValue("0", 1, 8);
                            outFilePutValue("0", 1, 8);
                            outFilePutValue("0", 1, 8);
                    }
                    //get ASCII value here because no Asc() function in C/C++
                    String car = sv.SubString(ix, 1);
                    int val = *(car.c_str());
                    outFilePutValue(IntToStr(val), 1, 8);
            }
            return ret; 
       }
     
       try { v = StrToFloat(sv); } // attention si , ou .
       catch(EConvertError &e) { v = 0; }
       // OPTIMISATION = if(cResol != 1 && cResol != 0)
       if(cResol != 1)
       {
            if(cResol != 0)
                    v /= cResol;
       }
       //best way i found to init string with a certain number of characters
       std::string finalC = std::string(numberOfBits, '0');
       final = finalC.c_str();
       for(int ix = 1; ix <= numberOfBits; ++ix)
       {
            re = cMod(v);
            v = (int) (v/2);
            if(re != 0)
                    final[numberOfBits - ix + 1] = '1';
       }
       for(int ix = 1; ix <= numberOfBits; ++ix)
       {
            if(final.SubString(ix, 1) == "1")
                    outFilePutBit(1);
            else
                    outFilePutBit(0);
       }
       ret = final;
       if(bLogging)
       {
            if(outFilebHidden)
                    appendLog(LOGINFO, forLog + " > " + NOTVISIBLESTRING);
            else
                    appendLog(LOGINFO, forLog + " > " + final);
       }
    }
     
    // p-e bug possible du fait que lorsque qu'on utilise ostringstream, la conversion
    // ne prend pas le 0 de fin, ex : 1.10 donnera 1.1 d'où au lieu de retourner 0
    // ça retournera 1
    double __fastcall ModOutFile::cMod(double pVal)
    {
       std::string s;
       std::ostringstream oss;
     
       //convert double into string
       oss << pVal;
       s = oss.str();
       //get last character
       char c = s[s.length()-1];
       int val = atoi(&c);
     
       if(val == 0 || val == 2 || val == 4 || val == 6 || val == 8)
            return 0;
       else
            return 1;
    }
     
    #pragma package(smart_init)

Discussions similaires

  1. [SRC] Calcul de CRC
    Par cfdev dans le forum C++Builder
    Réponses: 3
    Dernier message: 07/03/2005, 13h08
  2. générer un CRC
    Par Eugénie dans le forum MFC
    Réponses: 43
    Dernier message: 22/12/2003, 15h53
  3. Cherche l'algo crc 16 bits
    Par icepower dans le forum Algorithmes et structures de données
    Réponses: 2
    Dernier message: 21/08/2002, 13h27
  4. codes crc
    Par patturbo dans le forum C++Builder
    Réponses: 7
    Dernier message: 24/07/2002, 09h28

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo