Ejemplo n.º 1
0
        public static TMoFile GetMoFile(string filename, TDebugLogger DebugLogger)
        {
            Int64 offset, size;

            // Find real filename
            offset = 0;
            size   = 0;
            string realfilename = filename;

            if (filename.StartsWith(basedirectory))
            {
                filename = filename.Substring(basedirectory.Length);
                int idx = filelist.IndexOf(filename);
                if (idx != -1)
                {
                    TEmbeddedFileInfo fi = (TEmbeddedFileInfo)filelist.Objects[idx];
                    realfilename = TGnuGettextInstance.ExecutableFilename;
                    offset       = fi.offset;
                    size         = fi.size;
#if DXGETTEXTDEBUG
                    DebugLogger("Instead of " + filename + ", using " + realfilename + " from offset " + (offset).ToString() + ", size " + (size).ToString());
#endif
                }
            }


#if DXGETTEXTDEBUG
            DebugLogger("Reading .mo data from file ''" + filename + "''");
#endif

            // Find TMoFile object
            TMoFile Result;
            MoFilesCS.AcquireWriterLock(Timeout.Infinite);
            try
            {
                string idxname = realfilename + " //\\ " + (offset).ToString();
                int    idx;
                if (MoFiles.Find(idxname, out idx))
                {
                    Result = (TMoFile)MoFiles.Objects[idx];
                }
                else
                {
                    Result = new TMoFile(realfilename, offset, size, TGnuGettextInstance.UseMemoryMappedFiles);
                    MoFiles.AddObject(idxname, Result);
                }
                Result.Users++;
            }
            finally
            {
                MoFilesCS.ReleaseWriterLock();
            }
            return(Result);
        }
Ejemplo n.º 2
0
        public static void Analyze()
        {
            // DetectionSignature: used solely to detect gnugettext usage by assemble
            const string DetectionSignature = "2E23E563-31FA-4C24-B7B3-90BE720C6B1A";
            // Embedded Header Begin Signature (without dynamic prefix written by assemble)
            const string BeginHeaderSignature = "BD7F1BE4-9FCF-4E3A-ABA7-3443D11AB362";
            // Embedded Header End Signature (without dynamic prefix written by assemble)
            const string EndHeaderSignature = "1C58841C-D8A0-4457-BF54-D8315D4CF49D";
            // Assemble Prefix (do not put before the Header Signatures!)
            const string SignaturePrefix = "DXG"; // written from assemble

            int HeaderSize = BeginHeaderSignature.Length;
            int PrefixSize = SignaturePrefix.Length;

            basedirectory = Utils.IncludeTrailingPathDelimiter(Path.GetDirectoryName(TGnuGettextInstance.ExecutableFilename));
            try
            {
                FileStream fs = new FileStream(TGnuGettextInstance.ExecutableFilename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                try
                {
                    // try to find new header begin and end signatures
                    long headerbeginpos = FindSignaturePos(SignaturePrefix + BeginHeaderSignature, fs);
                    long headerendpos   = FindSignaturePos(SignaturePrefix + EndHeaderSignature, fs);

                    if (headerbeginpos > -1 && headerendpos > -1)
                    {
                        // adjust positions (to the end of each signature)
                        headerbeginpos = headerbeginpos + HeaderSize + PrefixSize;

                        // get file table offset (8 byte, stored directly before the end header)
                        fs.Seek(headerendpos - 8, SeekOrigin.Begin);
                        // get relative offset and convert to absolute offset during runtime
                        Int64 tableoffset = headerbeginpos + ReadInt64(fs);

                        // go to beginning of embedded block
                        fs.Seek(headerbeginpos, SeekOrigin.Begin);

                        Int64 offset = tableoffset;
                        Debug.Assert(sizeof(Int64) == 8);
                        while (true && fs.Position < headerendpos)
                        {
                            fs.Position = offset;
                            offset      = ReadInt64(fs);
                            if (offset == 0)
                            {
                                return;
                            }
                            offset = headerbeginpos + offset;
                            TEmbeddedFileInfo fi = new TEmbeddedFileInfo();
                            try
                            {
                                // get embedded file info (adjusting dynamic to real offsets now)
                                fi.offset = headerbeginpos + ReadInt64(fs);
                                fi.size   = ReadInt64(fs);
                                byte[] filename8bit = new byte[offset - fs.Position];
                                fs.Read(filename8bit, 0, (int)(offset - fs.Position));
                                string filename = Encoding.UTF8.GetString(filename8bit).Trim();
                                if (TGnuGettextInstance.PreferExternal && File.Exists(basedirectory + filename))
                                {
                                    // Disregard the internal version and use the external version instead
                                }
                                else
                                {
                                    filelist.AddObject(filename, fi);
                                }
                            }
                            catch
                            {
                                throw;
                            }
                        }
                    }
                }
                finally
                {
                    fs.Dispose();
                }
            }
            catch
            {
#if DXGETTEXTDEBUG
                throw;
#endif
            }
        }