4 Replies Latest reply on Aug 28, 2012 7:22 AM by TomHays

    Reading bytes in a file.

    pedantic

      Hello everyone.

       

      In my Filemaker I have to enter information on data files, including which version the data file is to be used with, for example "CS2", "CS3" and so forth. It just so happens that if I examine bytes 29 and 33 of the file I can get the information I need to determine version. I am using the following code in order to trap that information:

       

      TrFile_GetContents( "" ; Files::Path & Files::Name ; 0; 20)

       

      and then the following code to determine whether I got the right information:

       

      Show Custom Dialog["Digit values"; "The first digit is " & $FirstDigit & " and the second digit is " & $SecondDigit & "."]

       

      TrFile_GetContents() should be returning 0 or 0x07 (or some similar value between 4 and 9) or 0x05 (the only value ither than 0). No matter what I do, however, I cannot seem to get the single digits to print. Without fail I get a space where the data should be. I've tried using some of the native functions that come with Filemaker to make FM recognize the values, but nothing seems to work. Does anyone have an idea I might try?

       

      The ultimate plan is to use the digit values either in a switch statement or a nested if/else statement to assign text to a field, like this:

       

      if($FirstDigit = 4)

      Field:version = "CS3"

      else if($FirstDigit = 5)

      Field:version = "CS4"

       

      and so on.

       

      Does anyone have an idea I might try?

        • 1. Re: Reading bytes in a file.
          taylorsharpe

          I assume there is some reason you want to look in the file itself instead of the file name?  I usually just grab the last 3 characters of the file name when determining file types because that is much easier.  Would that not work for you?  It should unless your users are putting non-standard extensions on their file names. 

          • 2. Re: Reading bytes in a file.
            pedantic

            Thanks for replying Taylorsharpe.

             

            The answer is yes, there is a specific reason.  All of these files are InDesign files and all of them regardless of version have file extensions of .indd, so the only way to determine whether these are CS3, CS4, CS5 files, etc., is to actually look inside the file for the exact version. The version values are found, as I said, at bytes 29 and 33.

             

            R,

            John

            • 3. Re: Reading bytes in a file.
              taylorsharpe

              Ahhh... that makes sense.  Hmmm... I would have to play with reading the files hex values and see what I could come up with.  I would probably first look at what functions are available in ScriptMaster. 

              • 4. Re: Reading bytes in a file.
                TomHays

                I think the problem you are experiencing is due to the distinction between raw binary and FileMaker's text encoding. If you assign an arbitrary binary sequence directly to a FileMaker string, there is no FileMaker function that will let you access the raw bytes to get what you need. FileMaker's string handling functions assume that the data is a properly encoded (UTF16, I think) string.

                 

                Taylor's suggestion of using a plug-in that can interpret the binary data is the right approach.

                 

                I can show you how to solve this using the free LuaFy plug-in (www.luafy.com) which uses the Lua scripting language embedded in the plug-in (unlike ScriptMaster, no Java installation is required).

                 

                The Lua script is

                 

                local theFilePath = ...

                local fp = io.open(theFilePath, 'rb')

                fp:seek('set', 29)

                local firstByte = fp:read(1)

                fp:seek('set', 33)

                local secondByte = fp:read(1)

                fp:close()

                return firstByte:byte(1) .. '\r' .. secondByte:byte(1)

                 

                Using SetVariable:

                $luaResult = LuaFy_RunScript("the Lua Script above"; Files::Path & Files::Name)

                 

                Using that Lua Script this function returns two numeric values separated by a line break.

                $FirstDigit = GetValue($luaResult; 1)

                $SecondDigit = GetValue($luaResult; 2)

                 

                -Tom

                (the author of the LuaFy plug-in)

                 

                Added example file