<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet title="XSL formatting" type="text/xsl" href="http://blog.synopse.info/feed/rss2/xslt" ?><rss version="2.0"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:wfw="http://wellformedweb.org/CommentAPI/"
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
  xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
  <title>Synopse</title>
  <link>http://blog.synopse.info/</link>
  <atom:link href="http://blog.synopse.info/feed/rss2" rel="self" type="application/rss+xml"/>
  <description>&quot;Synopse Informatique&quot; Software solutions, and associated open source database and low level components.</description>
  <language>en</language>
  <pubDate>Thu, 02 Sep 2010 12:35:06 +0200</pubDate>
  <copyright>©2010 Synopse Informatique</copyright>
  <docs>http://blogs.law.harvard.edu/tech/rss</docs>
  <generator>Dotclear</generator>
  
    
  <item>
    <title>Synopse</title>
    <link>http://blog.synopse.info/post/2009/09/13/first</link>
    <guid isPermaLink="false">urn:md5:6ff3d64863f84cdc1520a5c1fc251216</guid>
    <pubDate>Sun, 01 May 2011 12:00:00 +0000</pubDate>
    <dc:creator>A.Bouchez</dc:creator>
        <category>Synopse Company</category>
        <category>Delphi</category><category>Freelance</category>    
    <description>&lt;p&gt;About the &lt;em&gt;Synopse Informatique&lt;/em&gt; company and our &lt;em&gt;Open Source&lt;/em&gt;
approach.&lt;/p&gt;
&lt;p&gt;If your project needs Delphi software development, it's the right place to
search.&lt;/p&gt;    &lt;h1&gt;About Synopse&lt;/h1&gt;
&lt;p&gt;&amp;quot;Synopse Informatique&amp;quot; (aka Synopse) is a French software development firm
founded by Arnaud Bouchez, specialized in providing custom database and search
engines, written in the object pascal language.&lt;/p&gt;
&lt;div&gt;&amp;quot;Synopse Informatique&amp;quot; in french translates more or less in &amp;quot;Synopsis
Software&amp;quot;... here &amp;quot;Synopsis&amp;quot; doesn't mean a brief summary, but comes from late
latin, itself from Ancient Greek σύνοψις (sunopsis), &lt;em&gt;i.e.&lt;/em&gt; σύν (sun,
“with”) + ὄψις (opsis, “view”). It's commonly used to describe a book
displaying some similar documents in parallel, &lt;em&gt;e.g.&lt;/em&gt; the three &lt;a href=&quot;http://en.wikipedia.org/wiki/Synoptic_problem&quot;&gt;synoptic gospels&lt;/a&gt;. Using
such a concept for a software company indicates a global approach, a kwow-how
and proven experience used to create innovative solutions. By having a global
vision, using agile methods and mastering software advanced technologies,
Synopse is able to create the software you need, not what computer or
marketing specialists think of, and, sometimes, more than you ever
expected.&lt;/div&gt;
&lt;h1&gt;Synopse projetcs&lt;/h1&gt;
&lt;div&gt;Synopse is proud to release some Delphi/Object pascal projects and tools
as &lt;a href=&quot;http://blog.synopse.info/category/Open-Source-Projects&quot;&gt;Open
Source&lt;/a&gt;:&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://blog.synopse.info/category/Open-Source-Projects/Enhanced-Delphi-Run-Time&quot;&gt;
Enhanced Delphi Run Time library&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The &lt;a href=&quot;http://blog.synopse.info/category/Open-Source-Projects/SQLite3-Framework&quot;&gt;SQLite3
framework&lt;/a&gt; (full SQLite3-based JSON client/server framework and UI
tools)&lt;/li&gt;
&lt;li&gt;The &lt;a href=&quot;http://blog.synopse.info/category/Open-Source-Projects/SynProject-documentation-and-versioning&quot;&gt;
SynProject&lt;/a&gt; automated documentation and code versioning tool&lt;/li&gt;
&lt;li&gt;The &lt;a href=&quot;http://blog.synopse.info/category/Open-Source-Projects/Synopse-Database&quot;&gt;Synopse
database engine&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1&gt;The Synopse database engine&lt;/h1&gt;
&lt;div&gt;Synopse is releasing a new open source database engine, founded on some
successfull projects like &lt;a href=&quot;http://bouchez.info/ictus.html&quot;&gt;Ictus
Win&lt;/a&gt; or &lt;a href=&quot;http://bouchez.info/roc.html&quot;&gt;ROC&lt;/a&gt;. It's a whole new
database engine, not SQL-based, but purely object/XML related.&lt;/div&gt;
&lt;div&gt;The Synopse company is able to develop business rules and tuned solutions
using the Synopse database engine. This software development can be
made private by an appropriate contract, but will rely on the proven Synopse
database engine.&lt;/div&gt;
&lt;h1&gt;Open Source model&lt;/h1&gt;
&lt;div&gt;Synopse does believe in the &lt;a href=&quot;http://www.opensource.org&quot;&gt;Open
Source&lt;/a&gt; approach:&lt;/div&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;em&gt;Open source is a development method for software that harnesses the
power of distributed peer review and transparency of process. The promise of
open source is better quality, higher reliability, more flexibility, lower
cost, and an end to predatory vendor lock-in.&lt;/em&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;div&gt;Therefore, the company will provide some usefull components they use, from
User Interface to communication layers, under a &lt;a href=&quot;http://www.mozilla.org/MPLl&quot;&gt;MPL/GPL/LGPL tri-license&lt;/a&gt; to the Delphi
community. &lt;/div&gt;
&lt;div&gt;The fully featured Synopse database engine itself is published under a
dual licence model, similar to the one used by &lt;a href=&quot;http://www.mysql.com/about/legal/licensing/oem/&quot;&gt;Sun™ for MySQL™&lt;/a&gt;: a
commercial licence for OEMs, ISVs, VARs and other distributors of commercial
applications; and a &lt;a href=&quot;http://www.gnu.org/licenses/old-licenses/gpl-2.0.html&quot;&gt;GPL licence&lt;/a&gt; for
open source projects (FOSS).&lt;/div&gt;
&lt;h1&gt;Synopse Blog&lt;/h1&gt;
&lt;div&gt;We decided to use this simple blog site as a major place to inform the
community about our projects and open source initiative.&lt;/div&gt;
&lt;div&gt;Stay tuned on this web site!&lt;/div&gt;
&lt;h1&gt;Freelance Programming&lt;/h1&gt;
&lt;div&gt;Our company is able to help you in whatever Delphi project. We may help
with Delphi expertise, corrective or preventive maintenance, customization
of one of our libraries according to your purposes.&lt;/div&gt;
&lt;div&gt;You can contact us at freelance at synopse dot info&lt;/div&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Synopse SQLite3 Framework 1.9.1</title>
    <link>http://blog.synopse.info/post/2010/08/24/Synopse-SQLite3-Framework-1.9</link>
    <guid isPermaLink="false">urn:md5:57a7b8a1a249224ca4788209f5b3db56</guid>
    <pubDate>Tue, 24 Aug 2010 11:16:00 +0200</pubDate>
    <dc:creator>A.Bouchez</dc:creator>
        <category>SQLite3 Framework</category>
        <category>AJAX</category><category>Database</category><category>Delphi</category><category>FTS3</category><category>HTTP</category><category>JSON</category><category>multithread</category><category>ORM</category><category>SQLite3</category>    
    <description>&lt;p&gt;The Synopse SQLite3 Database Framework was just released under version
1.9.1:&lt;br /&gt;
- internal SQLite3 database engine is updated to version 3.7.2;&lt;br /&gt;
- new TSQLRecordFTS3 record, for using FTS3 virtual tables, i.e. implementing
full-text search;&lt;br /&gt;
- new SQLite3UIEdit unit, to edit table content with a dialog created from
RTTI;&lt;br /&gt;
- new dedicated BLOB methods and JSON array serialization;&lt;br /&gt;
- a lot of fixes and speed enhancements (including our HTTP/1.1 RESTful server
now using Thread Pool).&lt;/p&gt;
&lt;p&gt;The new 3.7.2 version of the SQLite3 engine, which is mandatory according to
SQLite3's authors, is included.&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;Changes in SynCommons.pas unit:&lt;/strong&gt;&lt;br /&gt;
  - now compiles under CrossKylix, and tested under Linux&lt;br /&gt;
  - new JSONEncodeArray procedures, to create JSON array content from
supplied Delphi arrays (handle RawUTF8 text, double or integer arrays)&lt;br /&gt;
  - new AddCSV methods in TTextWriter handling Delphi arrays to be added
as Comma-Separated-Values (handle RawUTF8 text, double or integer arrays)&lt;br /&gt;
  - new definition of PtrInt/PtrUInt, to match NativeInt/NativeUInt types,
available since Delphi 2007 - some code rewrite in order to avoid any implicit
conversion from/to integer/cardinal&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Changes in SynCrtSock.pas unit:&lt;/strong&gt;&lt;br /&gt;
  - avoid some GPF during client deconnection when the server shut
down&lt;br /&gt;
  - rewrite HTTP Server handle request loop keep alive timing&lt;br /&gt;
  - HTTP Server now use a Thread Pool to speed up multi-connections: this
speed up a lot HTTP/1.0 requests, by creating a Thread only if necessary&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Changes in SynCrypto.pas unit:&lt;/strong&gt;&lt;br /&gt;
   - now use direct Windows threads, since we don't need any
exception handling nor memory usage inside the AES encryption Thread
handler&lt;br /&gt;
     -&amp;gt; avoid classes.TThread and system.BeginThread()
use&lt;br /&gt;
     -&amp;gt; application is still &amp;quot;officialy&amp;quot; mono-threaded (i.e.
IsMultiThread=false), for faster System.pas and FastMM4 (prevent CPU locking -
see &lt;a href=&quot;http://synopse.info/forum/viewtopic.php?id=57&quot;&gt;http://synopse.info/forum/viewtopic.php?id=57&lt;/a&gt;
about Delphi &amp;amp; multi-core)&lt;br /&gt;
   - some other minor fixes and enhancements&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Changes in SynZip.pas unit:&lt;/strong&gt;&lt;br /&gt;
   - crc32 is now coded in inlined fast asm (crc32.obj is no longer
necessary)&lt;br /&gt;
   - crc32 hashing is performed using 8 tables, for better CPU
pipelining and faster execution&lt;br /&gt;
   - crc32 tables are created on the fly during unit initialization,
therefore save 8 KB of code size from standard crc32.obj, with no speed
penalty&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Changes in SynSelfTests.pas unit:&lt;/strong&gt;&lt;br /&gt;
  - test multi-threaded AES encryption/decryption of 4 MB blocks&lt;br /&gt;
  - added crc32 tests&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Changes in SynGdiPlus.pas unit:&lt;/strong&gt;&lt;br /&gt;
   - small enhancements for framework Main Demo release
(RectNotBiggerThan and MaxPixelsForBiggestSide parameter in SaveAs function
e.g.)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Changes in SQLite3.pas unit:&lt;/strong&gt;&lt;br /&gt;
    - database engine updated to 3.7.1&lt;br /&gt;
    - fix issue in TSQLRestServerDB.CreateMissingTables when an
exception occured&lt;br /&gt;
    - handle now RowID as a valid alias to the ID field (needed for
TSQLRecordFTS3)&lt;br /&gt;
    - handle TSQLRecordFTS3 record, for using FTS3 virtual tables,
i.e. implementing full-text search (including dedicated regression tests)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Changes in SQLite3Commons.pas unit:&lt;/strong&gt;&lt;br /&gt;
    - update engine to version 3.7.1&lt;br /&gt;
    - fixed error calling a TSQLRestServerCallBack with both record
&amp;amp; parameters&lt;br /&gt;
    - TSQLRecordSigned must now be signed with a specified content
(content was formerly a fixed field of type RawUTF8, but it didn't apply in all
cases, e.g. if content field is defined as TSQLRawBlob)&lt;br /&gt;
    - new TSQLRestClientURI.ForceBlobTransfert property which enable
to get and set BLOB fields values with usual Add/Update/Retrieve methods&lt;br /&gt;
    - new TSQLRestClientURI.RetrieveBlobFields/UpdateBlobFields
methods for retrieving/updating all BLOB fields of a record at once&lt;br /&gt;
    - better handling of sftID in the User Interface and database use
(e.g. creates a dedicated index for the TSQLRecord published fields)&lt;br /&gt;
    - some code rewrite in order to avoid any implicit conversion
from/to integer/cardinal after new definition of PtrInt/PtrUInt (matching
NativeInt/NativeUInt types, available since Delphi 2007)&lt;br /&gt;
    - updated TSQLRibbonTabParameters object, with some new fields
dedicated to the automatic edition of records, via the new SQLite3UIEdit
unit&lt;br /&gt;
    - new sftSet SQL field kind, handling a TSQLRecord published
property with a set of enumeration as Delphi type (stored as bit-mapped
INTEGER)&lt;br /&gt;
    - handle now RowID as a valid alias to the ID field (needed for
TSQLRecordFTS3)&lt;br /&gt;
    - defines a new TSQLRecordFTS3 type, for defining a FTS3 virtual
table, i.e. implementing full-text search&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Changes in SQLite3UILogin.pas unit:&lt;/strong&gt;&lt;br /&gt;
    - improved Delphi 2009/2010 UnicodeString compatibility&lt;br /&gt;
    - new PassWord method to enter a password e.g. for Cypher (i.e.
with no UserName)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Changes in SQLite3ToolBar.pas unit:&lt;/strong&gt;&lt;br /&gt;
    - improved Delphi 2009/2010 UnicodeString compatibility&lt;br /&gt;
    - add TMS components stylers coherency update&lt;br /&gt;
    - added TSQLRibbon to factorize most used Ribbon-related User
Interface data, functions and events in one class&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Changes in SQLite3UIQuery.pas unit:&lt;/strong&gt;&lt;br /&gt;
  - custom queries can now handle standard operators, following a
specified set&lt;br /&gt;
  - TSQLQueryEvent() usage has therefore been modified for custom
queries&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Changes in SQLite3UI.pas unit:&lt;/strong&gt;&lt;br /&gt;
    - improved Delphi 2009/2010 UnicodeString compatibility&lt;br /&gt;
    - fix some issues, and complete implementation of marking from
time elapsed&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;New SQLite3UIEdit.pas unit:&lt;/strong&gt;&lt;br /&gt;
  - Initial Release, handling most common kind of SQL field (sftRecord,
sftTimeLog, sftCurrency, sftDateTime, sftFloat and sftBlob) are not handled
yet, because is not needed; perhaps sftTimeLog, sftCurrency, sftDateTime and
sftFloat should be handled in the future (using TDateTimePicker or a to be
written TSynExtendedLabeledEdit components)&lt;br /&gt;
  - all user interface (fields, layout, etc...) is created from RTTI data
and some custom parameters&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Changes in SQLite3Pages.pas unit:&lt;/strong&gt;&lt;br /&gt;
  - new AppendRichEdit method to draw RichEdit content&lt;br /&gt;
  - new WordWrapLeftCols property used to optionaly word wrap caLeft
columns into multiple lines, i.e. if the text is wider than the column width,
its content is wrapped to the next line (set to false by default) - this also
will handle #13/#10 in column text as a &amp;quot;go to next line&amp;quot; command&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Changes in SQLite3i18n.pas unit:&lt;/strong&gt;&lt;br /&gt;
  - new TLanguageFile.BooleanToString method, returning 'No' or
'Yes'&lt;br /&gt;
  - new TLanguageFile.PropToString method to convert a TSQLRecord
published property value into ready to be displayed text&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Changes in SQLite3UIOptions.pas unit:&lt;/strong&gt;&lt;br /&gt;
    - some code refactoring to share code with the new SQLite3UIEdit
unit&lt;br /&gt;
    - minor fixes and enhancements&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Last minute update:&lt;br /&gt;
Main version updated to 1.9.1:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We had to update the SQLite3 internal engine to version 3.7.2: an obscure
but very old bug makes SQLite authors recommend to use 3.7.2 for all new
development.&lt;br /&gt;
Upgrading from all prior SQLite versions is also recommended. See
http://sqlite.org/releaselog/3_7_2.html&lt;/p&gt;
&lt;p&gt;So we do. And increase our version number to 1.9.1.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Don't forget to consult the &lt;a href=&quot;http://synopse.info/forum/viewtopic.php?id=55&quot;&gt;draft version of the
documentation of this framework&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;The full source code from the framework is available to download from
&lt;a href=&quot;http://synopse.info/files/SynopseSQLite3.zip&quot;&gt;SynopseSQLite3.zip&lt;/a&gt;
licensed under a &lt;a href=&quot;http://synopse.info/forum/viewtopic.php?id=27&quot;&gt;MPL/GPL/LGPL
tri-license&lt;/a&gt;.&lt;br /&gt;
Compatible with Delphi 7 to Delphi 2010.&lt;/p&gt;
&lt;p&gt;Comments and feedback are welcome on our forum:&lt;br /&gt;
&lt;a href=&quot;http://synopse.info/forum/viewtopic.php?id=96&quot;&gt;http://synopse.info/forum/viewtopic.php?id=96&lt;/a&gt;&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>How to implement multi-tier architecture in our SQLite3 Framework</title>
    <link>http://blog.synopse.info/post/2010/08/19/How-to-implement-multi-tier-architecture-in-our-SQLite3-Framework</link>
    <guid isPermaLink="false">urn:md5:95a9f42818ccb3108826076b3c15d5f5</guid>
    <pubDate>Thu, 19 Aug 2010 10:48:00 +0200</pubDate>
    <dc:creator>A.Bouchez</dc:creator>
        <category>SQLite3 Framework</category>
        <category>AJAX</category><category>Delphi</category><category>HTTP</category><category>IDE</category><category>JSON</category><category>ORM</category><category>SQLite3</category>    
    <description>&lt;p&gt;In software engineering, multi-tier architecture (often referred to as
n-tier architecture) is a client–server architecture in which the presentation,
the application processing, and the data management are logically separate
processes. For example, an application that uses middleware to service data
requests between a user and a database employs multi-tier architecture. The
most widespread use of multi-tier architecture is the three-tier
architecture.&lt;/p&gt;
&lt;p&gt;Both ORM and RESTful aspects of our framework makes it easy to develop using
such a three-tier architecture.&lt;/p&gt;    &lt;p&gt;In our SQLite3 Open Source framework, for Delphi 7-2010, you can follow this
development pattern:&lt;br /&gt;
- &lt;strong&gt;Data Tier&lt;/strong&gt; is either SQLite3 and/or an internal very fast
in-memory database, most SQL queries are created on the fly;&lt;br /&gt;
- &lt;strong&gt;Logic Tier&lt;/strong&gt; is performed by pure ORM aspect: you write Delphi
classes which are mapped by the Data Tier into the database, and you can write
your business logic in both Client or Server side, just by adding some events
or methods to the classes;&lt;br /&gt;
- &lt;strong&gt;Presentation Tier&lt;/strong&gt; is either a Delphi Client, either an AJAX
application, because the framework can communicate using RESTful JSON over
HTTP/1.1 (the Delphi Client User Interface is generated from Code, by using
RTTI and structures, not as a RAD - and the Ajax applications need to be
written by using your own tools and JavaScript framework, there is no
&amp;quot;official&amp;quot; Ajax framework used yet).&lt;/p&gt;
&lt;p&gt;If you need a RAD approach, it's perhaps not the right tool for you.&lt;br /&gt;
But if you like describing your application with classes, it's worth taking a
look at it, and contributes to this open source project!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;We can give you &lt;a href=&quot;http://synopse.info/forum/viewtopic.php?id=93&quot;&gt;more details about each
Tier/Layer in our forum.&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>FPC and Delphi: toward a &quot;fratricidal war&quot;?</title>
    <link>http://blog.synopse.info/post/2010/08/14/FPC-and-Delphi%3A-toward-a-%22fratricidal-war%22</link>
    <guid isPermaLink="false">urn:md5:043e1c0dce5c528e8c80c29723e59658</guid>
    <pubDate>Sat, 14 Aug 2010 10:28:00 +0200</pubDate>
    <dc:creator>A.Bouchez</dc:creator>
        <category>Pascal Programing</category>
        <category>CrossPlatform</category><category>Delphi</category><category>FreePascal</category><category>Linux</category><category>MaxOSX</category>    
    <description>&lt;p&gt;&lt;a href=&quot;http://blog.synopse.info/post/2010/08/10/Writing-Delphi-code-for-64-bits-compiler&quot;&gt;
Speaking about [upcoming] 64 bit Delphi compiler&lt;/a&gt;, I
did forecast they will surely release their compiler 5 years later
than FPC's... hoping they will follow the FPC way, just as Intel did about 64
bits instructions, against AMD.&lt;/p&gt;
&lt;p&gt;What I was referring to is that AMD was the first to publish a 64 bit x86
CPU, with a new instruction set. Intel released somewhat later their own 64 bit
x86 CPU, following the same instruction set.&lt;br /&gt;
There are some variants between AMD and Intel CPU, some dedicated instructions
or implementations.&lt;br /&gt;
But most instruction set is perfectly compatible.&lt;/p&gt;
&lt;p&gt;And I suspect the more it gets, the less compatible FPC and Delphi will
be.&lt;/p&gt;
&lt;p&gt;The main difference between Delphi and FPC is that the first is a business
company project (Embarcadero), the second an Open Source solution. They are not
two billions dollars companies fighting each other, with some state-level
institutions watching about any unfair competition or monopoly... FPC compiler
is technically a great and robust project, but EMB follows business rules. I
don't think anyone will play &amp;quot;Anti-monopoly&amp;quot; in favor of FPC.&lt;/p&gt;    &lt;strong&gt;&lt;br /&gt;
FPC and 64 bit: the future is today&lt;/strong&gt;
&lt;p&gt;FPC published a 64 bit compiler using the Delphi/object pascal language in
2006.&lt;/p&gt;
It could have been fair and less confusing that Delphi engineers just follow
the same patterns, for example use PtrInt and PtrUInt.
&lt;p&gt;I guess that in 2006, the 64 bit Delphi compiler was already a R&amp;amp;D
project at Borland, (and Codegear since February).&lt;br /&gt;
That's why NativeUInt and NativeInt were made available in Delphi 2007.&lt;br /&gt;
But FPC published its 64 bit compiler in 2006... and EMB is not able to promise
such a working x86-64 compiler before end of 2011.&lt;/p&gt;
&lt;p&gt;The preview 64-bit compiler is still indicated with a &amp;quot;first half of 2011&amp;quot;
like it was and future versions should have both 64-bit and Mac support,
although from the slides it is not clear which features actually go into Pulsar
(&amp;quot;Introduction of 64-bit and cross-platform to the RAD Studio product line&amp;quot;),
Wheelhouse (&amp;quot;Extending support for 64-bit and additional platforms&amp;quot;), and
Commodore (&amp;quot;Full support for 64-bit compilers for Windows, Mac OS, and Linux&amp;quot;).
Part of the differentiators comes from the fact Delphi language will be there
before C++, according to come of the details.&lt;br /&gt;
See &lt;a href=&quot;http://edn.embarcadero.com/article/39934&quot;&gt;http://edn.embarcadero.com/article/39934&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;br /&gt;
Some kind of messy&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;About the IDE, RadStudio is much more advanced than Lazarus. But there are
some newcomers around, like &lt;a href=&quot;http://www.msegui.org&quot;&gt;mseide&lt;/a&gt;, which
is light and powerful.&lt;/p&gt;
&lt;p&gt;Newest Delphi compiler have some language enhancements (like generics and
attributes, without naming Unicode which is mostly VCL-related), but FPC
evolves (it includes generics and in the future clever &lt;a href=&quot;http://wiki.lazarus.freepascal.org/Property_attributes&quot;&gt;property
attributes&lt;/a&gt;).&lt;br /&gt;
But the more it goes, the less compatible.&lt;br /&gt;
If you want your code to compile with both Delphi and FPC, you need a lot of
{$ifdef} and/or custom types... and a good knowledge of every compiler.&lt;/p&gt;
That's quite a mess, and a pity!
&lt;p&gt;Sometimes, I miss a &amp;quot;standardized language&amp;quot;, like C#, even if the libraries
are not standardized (if you want to work cross-platform, e.g. using Mono, you
can't rely simply on latest Microsoft libraries).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;br /&gt;
Will there be a &amp;quot;fratricidal war&amp;quot;?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If such a war happens (but isn't it already there?) in the object pascal
world, we can worry.&lt;br /&gt;
My first reaction is to think about &amp;quot;poor little FPC&amp;quot;. And imagine me at the
compiler graveyard, praying on its tomb.&lt;br /&gt;
But after some deeper thinking, it's not so simple.&lt;br /&gt;
I'm not able to see which one will be the winner. &lt;/p&gt;
&lt;p&gt;First of all, FPC is Open Source: it can't dye, if people
have interest in it.&lt;br /&gt;
And because of object pascal language strength, even a small team of coders can
handle it.&lt;/p&gt;
&lt;p&gt;At a glance, Delphi seems more powerful than FPC, because of EMB. But it
could be exactly the contrary...&lt;br /&gt;
Remember the Delphi for DotNet compiler: it was replaced by Oxygene, a not EMB
product, but a more reactive product.&lt;/p&gt;
&lt;p&gt;Since FPC is written in pure object pascal code (and the Delphi compiler
isn't, by the way), it could be easy for EMB to embed the FPC compiler into
their RadStudio XE... And by using &lt;a href=&quot;http://www.twinforms.com/products/wxformsdelphi/index.php&quot;&gt;wxforms&lt;/a&gt;,
extending it with DB components, RadStudio could easily cross-compile to both
Linux and MacOsX.&lt;/p&gt;
&lt;p&gt;So will the Delphi for Win32 compiler dye, just as the Delphi for DotNet
did?&lt;br /&gt;
Isn't FPC  at the right place, at the right moment?&lt;/p&gt;
&lt;div&gt;&lt;strong&gt;Feedback and comments are welcome &lt;a href=&quot;http://synopse.info/forum/viewtopic.php?pid=383#p383&quot;&gt;on our
forum&lt;/a&gt;!&lt;/strong&gt;&lt;/div&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Writing Delphi code for 64 bits compiler</title>
    <link>http://blog.synopse.info/post/2010/08/10/Writing-Delphi-code-for-64-bits-compiler</link>
    <guid isPermaLink="false">urn:md5:ad33e521da41b11b738e6c1325d6c1b4</guid>
    <pubDate>Tue, 10 Aug 2010 09:19:00 +0200</pubDate>
    <dc:creator>A.Bouchez</dc:creator>
        <category>Pascal Programing</category>
        <category>asm</category><category>CrossPlatform</category><category>Delphi</category><category>FreePascal</category><category>Linux</category><category>Unicode</category>    
    <description>&lt;p&gt;There will be an upcoming 64 bits Delphi compiler.
Embarcadero promised it.&lt;/p&gt;
Florian (the architect of FPC) showed a first &amp;quot;Hello world&amp;quot; program for Win64
in March 2006.&lt;br /&gt;
This was remarkable since GCC and the binutils don't even support this target
at this time.&lt;br /&gt;
In fact, FPC used its Internal linker on Win32 and Win64 platforms, just like
Delphi does.
&lt;p&gt;Here are some points on how you could make your code ready to compile under
FPC 64 bits, therefore (I hope) under future Delphi 64 bits compiler.&lt;/p&gt;    &lt;p&gt;Under FPC, all common types (like integer, cardinal, etc...) have the same
size. They are all 32 bits.&lt;/p&gt;
&lt;p&gt;So most of you code don't need to be rewritten. But if you have some asm
part in your code, you'll have to write it in pascal.&lt;/p&gt;
&lt;p&gt;Use the PUREPASCAL conditional, and always provide a pure pascal version of
any asm function. It's therefore a good practice to always code in pascal, then
add an optimized asm version only if it's necessary.&lt;br /&gt;
Here is one example extracted from our framework:&lt;/p&gt;
&lt;pre&gt;
function IdemPropName(const P1,P2: shortstring): boolean; overload;&lt;br /&gt;
{$ifdef PUREPASCAL}&lt;br /&gt;
var i: integer;&lt;br /&gt;
begin&lt;br /&gt;
  result := false;&lt;br /&gt;
  if P1[0]&amp;lt;&amp;gt;P2[0] then&lt;br /&gt;
    exit;&lt;br /&gt;
  for i := 1 to ord(P1[0]) do&lt;br /&gt;
    if (ord(P1[i]) xor ord(P2[i])) and $DF&amp;lt;&amp;gt;0 then&lt;br /&gt;
      exit;&lt;br /&gt;
  result := true;&lt;br /&gt;
end;&lt;br /&gt;
{$else}&lt;br /&gt;
asm // eax=P1 edx=P2&lt;br /&gt;
    mov cl,[eax]&lt;br /&gt;
    cmp cl,[edx]&lt;br /&gt;
    jne @z      // length differs&lt;br /&gt;
    or cl,cl&lt;br /&gt;
@1: lea eax,[eax+1]&lt;br /&gt;
    lea edx,[edx+1]&lt;br /&gt;
    jz @ok&lt;br /&gt;
    mov ch,[eax]&lt;br /&gt;
    xor ch,[edx]&lt;br /&gt;
    and ch,$DF   // case insensitive compare&lt;br /&gt;
    jne @z&lt;br /&gt;
    dec cl&lt;br /&gt;
    jmp @1&lt;br /&gt;
@ok:mov al,1&lt;br /&gt;
    ret&lt;br /&gt;
@z: xor eax,eax&lt;br /&gt;
end;&lt;br /&gt;
{$endif}
&lt;/pre&gt;
If you use pointer arithmetic, you should use PtrInt instead of integer to
typecast pointers.&lt;br /&gt;
See http://wiki.freepascal.org/Multiplatform_Programming_Guide#32.2F64_bit It's
perfectly cross-compiler. We defined these types for working with Delphi and
FPC on the same code:&lt;br /&gt;
&lt;pre&gt;
{$ifdef FPC}&lt;br /&gt;
  {$ifdef CPU64}&lt;br /&gt;
    {$define PUREPASCAL}&lt;br /&gt;
  {$endif}&lt;br /&gt;
{$else}&lt;br /&gt;
type&lt;br /&gt;
  /// a CPU-dependent unsigned integer type cast of a pointer / register&lt;br /&gt;
  // - used for 64 bits compatibility, native under Free Pascal Compiler&lt;br /&gt;
  PtrUInt = cardinal;&lt;br /&gt;
  /// a CPU-dependent unsigned integer type cast of a pointer of pointer&lt;br /&gt;
  // - used for 64 bits compatibility, native under Free Pascal Compiler&lt;br /&gt;
  PPtrUInt = ^PtrUInt;&lt;br /&gt;
&lt;br /&gt;
  /// a CPU-dependent signed integer type cast of a pointer / register&lt;br /&gt;
  // - used for 64 bits compatibility, native under Free Pascal Compiler&lt;br /&gt;
  PtrInt = integer;&lt;br /&gt;
  /// a CPU-dependent signed integer type cast of a pointer of pointer&lt;br /&gt;
  // - used for 64 bits compatibility, native under Free Pascal Compiler&lt;br /&gt;
  PPtrInt = ^PtrInt;&lt;br /&gt;
&lt;br /&gt;
  /// unsigned Int64 doesn't exist under Delphi, but is defined in FPC&lt;br /&gt;
  QWord = Int64;&lt;br /&gt;
{$endif}
&lt;/pre&gt;
&lt;p&gt;So it's always a good practice to use these PtrInt instead of integer in any
pointer arithmetic, just as you should use AnsiString/AnsiChar/PAnsiChar for
any ansi content, even on Delphi 7.&lt;br /&gt;
And if you use loop variables like for i := 0 to Lines.Count-1, you should
better use var i: PtrInt instead of i: integer &lt;/p&gt;
&lt;div&gt;Note that there is a CPU64 define set if you're compiling for a 64 bits
CPU.
&lt;div&gt;
&lt;div&gt;For example, since PtrInt = Int64 in fact, you can test {$ifdef CPU64} to
avoid writing a Int64 specific function, if a PtrInt one has already been
defined.&lt;/div&gt;
&lt;div&gt;I just hope that EMB will follow the same rules for their future 64 bits
compiler.&lt;/div&gt;
&lt;div&gt;They will be 5 years late... I hope they will follow the FPC way, just as
Intel did about 64 bits instructions, against AMD. &lt;/div&gt;
&lt;div&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/div&gt;
&lt;div&gt;&lt;strong&gt;As always, &lt;a href=&quot;http://synopse.info/forum/viewtopic.php?id=86&quot;&gt;feedback and comments are
welcome on our forum&lt;/a&gt;&lt;/strong&gt;.&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Every Delphi DB program contains hidden code for EMB license checking</title>
    <link>http://blog.synopse.info/post/2010/08/07/Every-Delphi-DB-program-has-hidden-code-for-EMB-license-checking</link>
    <guid isPermaLink="false">urn:md5:9c92f9e191e59a300e1854d218f4b8ef</guid>
    <pubDate>Sat, 07 Aug 2010 17:16:00 +0200</pubDate>
    <dc:creator>A.Bouchez</dc:creator>
        <category>Pascal Programing</category>
            
    <description>&lt;p&gt;After looking further at the SysUtils unit, I found out some small piece of
asm code I didn't notice at first.&lt;/p&gt;
&lt;p&gt;There is some hidden and not documented code in every program using the DB
features, in order to verify that you have the right to use some drivers or DB
features.&lt;/p&gt;
&lt;p&gt;The license checking performed by Borland (it was a trick existing in Delphi
4, or perhaps before) is somewhat childish.&lt;/p&gt;    &lt;p&gt;So here are the three function procedures in SysUtils.pas, not
documented:&lt;/p&gt;
&lt;pre&gt;
function GDAL: LongWord;
&lt;/pre&gt;
&lt;pre&gt;
procedure RCS;
&lt;/pre&gt;
&lt;pre&gt;
procedure RPR;
&lt;/pre&gt;
&lt;div&gt;Here is a first explanation: &lt;a href=&quot;http://assarbad.net/stuff/!export/dvclal/jeremyres.html&quot;&gt;http://assarbad.net/stuff/!export/dvclal/jeremyres.html&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;The purpose of these functions is to check the presence of the DVCLAL
resource in the exe (or one of the current module). &lt;/p&gt;
&lt;p&gt;This resource is just an array of 4 longword, i.e. 4 cardinal values.&lt;/p&gt;
&lt;p&gt;The function GDAL, for example, returns either 0, -16, -5136, or -1
depending of the version of your current Delphi license (i.e. Professional,
Entreprise, Architecture, GPL, whatever). The returned value of GDAL is checked
in the following units:
 SqlExpr.pas BDEReg.pas DBReg.pas DBTables.pas BDEReg.pas
DBReg.pas MidReg.pas&lt;/p&gt;
&lt;p&gt;And the protection takes place easily, for example here is an extract of the
BDEReg.pas code:&lt;/p&gt;
&lt;pre&gt;
procedure Register;
begin
  { Database Components are excluded from the STD SKU }
  if GDAL &amp;lt;&amp;gt; LongWord(-16) then
  begin
    // Restrict these components to only be used with VCL components.
    GroupDescendentsWith(TBDEDataSet, Controls.TControl);
&lt;/pre&gt;
&lt;pre&gt;
....
&lt;/pre&gt;
&lt;pre&gt;
    { Components that are excluded from the STD &amp;amp; PRO SKUs }
    if GDAL = 0 then
      RegisterComponents(srBDE, [TNestedTable]);
&lt;/pre&gt;
&lt;p&gt;The RPR procedure is a bit more agressive: it raises an exception in case
you don't have the right to use some components registered in DBXClient.pas
DbxFirebird.pas DbxInterbase.pas DbxMySql.pas DbxSybaseASA.pas DSServer.pas
DB.pas dbcgrids.pas HTTPApp.pas HTTPProd.pas Sockets.pas SOAPConn.pas
units.&lt;/p&gt;
&lt;p&gt;And within the RCS procedure, the exception is raised for other components
registered in DBXClient.pas DbxDb2.pas DbxInformix.pas DbxMSSQL.pas
DbxOracle.pas DbxSybaseASE.pas DBClient.pas MConnect.pas TConnect.pas
HTTPApp.pas HTTPProd.pas MXDB.PAS MXGRAPH.PAS MXGRID.PAS MXPIVSRC.PAS
units.&lt;/p&gt;
&lt;p&gt;I let you guess which component is what, just from the official EMB feature
matrix.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why all this?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Since the raw compiler is the same, that is the language feature and RTL is
the same for all Delphi versions (from Professional up to Architect), you could
be tempted buying the Professional version, then copy the dcu/bpl from an
Architect, and use it... but in fact, you won't have the &amp;quot;magic&amp;quot; resource in
your exe, so the trick won't play.&lt;/p&gt;
&lt;p&gt;Writing a patcher for your exe is very easy. You don't even have to patch
the memory, just some standard Win32 API like BeginUpdateResource /
UpdateResource / EndUpdateResource like stated in &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms648008(v=VS.85).aspx&quot;&gt;msdn&lt;/a&gt; will
do the work.&lt;br /&gt;
I won't commit Delphi code here, because I want to stay friend with EMB. But
guess what, it's not a great protection system!&lt;/p&gt;
&lt;p&gt;I don't blame Borland/EMB. But lol ! Such a weak &amp;quot;protection&amp;quot;, giving all
the source code at once. Thanks EMB for making me smile after &lt;a href=&quot;http://synopse.info/forum/viewtopic.php?id=80&quot;&gt;my &amp;quot;object type&amp;quot;
funeral&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Comments and more source code&lt;/strong&gt; &lt;a href=&quot;http://synopse.info/forum/viewtopic.php?id=83&quot;&gt;&lt;strong&gt;in our forum, just as
usual&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;.&lt;/strong&gt;&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Save object, stop class hegemony!</title>
    <link>http://blog.synopse.info/post/2010/08/06/Save-object%2C-stop-class-hegemony%21</link>
    <guid isPermaLink="false">urn:md5:8eb85429e503842e0da845c537facd33</guid>
    <pubDate>Fri, 06 Aug 2010 11:31:00 +0200</pubDate>
    <dc:creator>A.Bouchez</dc:creator>
        <category>Pascal Programing</category>
        <category>CrossPlatform</category><category>Delphi</category><category>FreePascal</category><category>object</category>    
    <description>&lt;p&gt;In a recent thread in the &lt;a href=&quot;https://forums.embarcadero.com/thread.jspa?threadID=41078&quot;&gt;Embarcadero
Discussion Forums&lt;/a&gt;, Vedran Vuk posted some questions about object
keyword.&lt;br /&gt;
His purpose was to use object instead of class to improve speed and memory
consumption: &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I do use classes. I just want to use objects on smaller classes that
don't really need initialization or RTTI. Plus, I can directly operate on it
like a record with no need for constructors and it can be sealed and has
inheritance. Every byte matters in this case.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div&gt;Rudy posted on the EMB forum that
&lt;blockquote&gt;
&lt;p&gt;The &amp;quot;object&amp;quot; type is deprecated. As was said, it mainly exists for
compatibility with old Turbo Pascal. That is why it is not documented very
well. It's use is not promoted.&lt;/p&gt;
&lt;/blockquote&gt;
I have the same requirement sometimes, for example for our framework or for
low-level units.&lt;/div&gt;
&lt;div&gt;I do like such plain-old object type, and don't want to see this object
feature marked as deprecated in future EMB versions.&lt;/div&gt;    &lt;p&gt;Delphi has always had three kind of coders:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;high-level coders, using components and RAD, standard library and its
classes;&lt;/li&gt;
&lt;li&gt;low-level coders, using pure code SW development, looking at the asm code
generated and tracking down memory and CPU usage;&lt;/li&gt;
&lt;li&gt;and to be honest, all low-level coders use the high-level tools, because
for a simple form, RAD is great, and standard library is to be used
anyway. &lt;/li&gt;
&lt;/ol&gt;
In fact, the object type is one feature which low-level coders like a
lot.&lt;br /&gt;
For example, the whole KOL library relies and it, and performs a great job with
it. The XMLRad framework uses it a lot for all basic types, in order to
increase speed, and improve multi-threaded server response time.
&lt;div&gt;&lt;br /&gt;
&lt;div&gt;Here are some cases I use &lt;em&gt;object&lt;/em&gt; for:&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;a memory mapped file, which I want to parse very quickly: a pointer to such
an object is just great, and you still have methods at hand; I use this for
TFileHeader or TFileInfo which map the .zip header, in SynZip.pas;&lt;/li&gt;
&lt;li&gt;a Win32 structure, as defined by a API call, in which I put handy
methods;&lt;/li&gt;
&lt;li&gt;a temporary structure defined on the stack, just used during a procedure: I
use this for TZStream in SynZip.pas, or for our RTTI related classes, which map
the Delphi generated RTTI in an Object-Oriented way not as the TypeInfo which
is function/procedure oriented. By mapping the RTTI memory content directly,
our code is faster than using the new RTTI classes created on the heap. We
don't instanciate any memory, which, for an ORM framework like ours, is good
for its speed. We need a lot of RTTI info, but we need it quick, we need it
directly.&lt;/li&gt;
&lt;/ol&gt;
In fact, I discovered that new Delphi compiler doesn't like packed
object.&lt;br /&gt;
See &lt;a href=&quot;http://qc.embarcadero.com/wc/qcmain.aspx?d=79792&quot;&gt;http://qc.embarcadero.com/wc/qcmain.aspx?d=79792&lt;/a&gt;&lt;br /&gt;

I've an &lt;em&gt;Internal Error DT5830&lt;/em&gt; under Delphi 2009 Update 3, but previous
compiler versions (including Delphi 2009 Update 2) did accept a packed object
declaration.&lt;br /&gt;
There is a simple workaround: define it as &lt;em&gt;packed record&lt;/em&gt;... this
works, but is not compatible with previous version of the compiler.&lt;br /&gt;
So here is how such a packed object must be coded, if you want your code to
work on most Delphi compiler versions:
&lt;pre&gt;
type&lt;br /&gt;
{$A-} { force packed object (not allowed under Delphi 2009) }&lt;br /&gt;
  /// the internal memory structure as expected by the ZLib library&lt;br /&gt;
  TZStream = {$ifdef UNICODE}record{$else}object{$endif}&lt;br /&gt;
...
&lt;/pre&gt;
It's a pity that Embarcadero seems not to a have a full regression test of all
compiler/language features, and run it before every release, like Free Pascal
compiler does.
&lt;div&gt;It's a pity that EMB changed the record type, by allowing adding methods
on it. IMHO, it's exactly a no-feature. Noone asked for it, or for any good
reason. If you want a &amp;quot;pure object pascal language&amp;quot;, with no history, just
created from scratch, with nice high-level features, just use PRISM.&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;br /&gt;
So here is my today's claim:&lt;/div&gt;
&lt;div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Don't forget low-level Delphi coders! Save our object
type!&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;/div&gt;
Feedback and discussion is &lt;a href=&quot;http://synopse.info/forum/viewtopic.php?id=80&quot;&gt;welcome on our forum&lt;/a&gt;.&lt;/div&gt;
&lt;/div&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Synopse SQLite3 Framework Main Demo - draft</title>
    <link>http://blog.synopse.info/post/2010/08/04/Synopse-SQLite3-Framework-Main-Demo-draft</link>
    <guid isPermaLink="false">urn:md5:4de865c6c7111f12af4d75a12ea7c444</guid>
    <pubDate>Wed, 04 Aug 2010 00:48:00 +0200</pubDate>
    <dc:creator>A.Bouchez</dc:creator>
        <category>SQLite3 Framework</category>
        <category>Database</category><category>Delphi</category><category>ORM</category><category>Rest</category><category>Source</category><category>SQLite3</category>    
    <description>The SQLite3 MainDemo source code has just been uploaded to the repository.
&lt;p&gt;This application is just a database tool which stores text content and files
into the database, in both clear and &amp;quot;safe&amp;quot; manner. Safe records are stored
using AES-256/SHA-256 encryption. There is an Audit Trail table for tracking
the changes.&lt;/p&gt;    &lt;p&gt;Here are some screen shots of this sample application: &lt;br /&gt;
&lt;a href=&quot;http://synopse.info/files/pictures/synfilebeta.png&quot;&gt;http://synopse.info/files/pictures/synfilebeta.png&lt;/a&gt;&lt;br /&gt;

&lt;a href=&quot;http://synopse.info/files/pictures/synfilebeta1.png&quot;&gt;http://synopse.info/files/pictures/synfilebeta1.png&lt;/a&gt;&lt;br /&gt;

&lt;a href=&quot;http://synopse.info/files/pictures/synfilebeta2.png&quot;&gt;http://synopse.info/files/pictures/synfilebeta2.png&lt;/a&gt;&lt;/p&gt;
&lt;div&gt;It shows you some interesting features like integrated User Interface
generation and i18n, reporting and export to PDF, client/server services.
&lt;p&gt;And you'll discover how our ORM and client/server database system is
implemented: all is done in code (no RAD/IDE approach here), but with very
little code lines count...&lt;/p&gt;
&lt;p&gt;An executable (still in draft status) can be downloaded from &lt;a href=&quot;http://synopse.info/files/samples/synfile.zip&quot;&gt;http://synopse.info/files/samples/synfile.zip&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;More details and feedback &lt;a href=&quot;http://synopse.info/forum/viewtopic.php?id=77&quot;&gt;in our dedicated forum
page&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Compiler enhancement proposal:  threadlocalvar</title>
    <link>http://blog.synopse.info/post/2010/07/30/Compiler-enhancement-proposal%3A-threadlocalvar</link>
    <guid isPermaLink="false">urn:md5:a2bb09624417f60d52469d1640c8cfbe</guid>
    <pubDate>Fri, 30 Jul 2010 11:25:00 +0200</pubDate>
    <dc:creator>A.Bouchez</dc:creator>
        <category>Pascal Programing</category>
        <category>asm</category><category>Delphi</category><category>multithread</category>    
    <description>&lt;p&gt;As I wrote &lt;a href=&quot;http://blog.synopse.info/post/2010/07/15/Delphi-doesn-t-like-multi-core-CPUs-%28or-the-contrary%29&quot;&gt;in
a previous post&lt;/a&gt;, Delphi string, dynamic array and memory manager don't like
multi-core CPU.&lt;/p&gt;
&lt;p&gt;My proposal is to add a &lt;em&gt;threadlocalvar&lt;/em&gt; keyword, to be used instead
of &lt;em&gt;var&lt;/em&gt; in your code, to mark some variables to be used in only the
current thread. Then the compiler and RTL won't have to use the LOCK
instruction, and the application will be MUCH faster in multi-thread
environment.&lt;/p&gt;    &lt;p&gt;I made this proposal in both the &lt;a href=&quot;https://forums.codegear.com/thread.jspa?threadID=30826&amp;amp;tstart=90&quot;&gt;Embarcadero
forum&lt;/a&gt; and in the FreePascal forum.&lt;/p&gt;
And what about using a &lt;em&gt;threadlocalvar&lt;/em&gt; new reserved word, in a
&lt;em&gt;threadvar&lt;/em&gt; way, which could define the variable (string, dynamic array)
to be accessed by the current thread only, and won't have any LOCK call? 
&lt;div&gt;My guess is that any server thread uses mostly such local variables (e.g.
for string concatenation of XML or HTML stream), and don't need the thread safe
approach most of the time. &lt;/div&gt;
&lt;div&gt;It could lead into some confusion for less advanced Delphi users, but the
&lt;em&gt;threadvar&lt;/em&gt; itself does exist for years, but is used only by those how
need this feature. If you need it, you use it. Otherwise you ignore it, and
your application will be slower in some cases, but wil work. For some CPU
intensive applications, like multi-thread servers, it should be a great
improvement to have such a &lt;em&gt;threadlocalvar&lt;/em&gt; at hand.&lt;/div&gt;
&lt;div&gt;Note 1: the &lt;em&gt;threadvar&lt;/em&gt; implements one variable instance per
thread, and the &lt;em&gt;threadlocalvar&lt;/em&gt; should implements one variable instance
for the current thread only. &lt;/div&gt;
&lt;div&gt;Note 2: any &lt;em&gt;threadlocalvar&lt;/em&gt; could be assigned to a normal var,
when a multi-thread safe variable is needed (e.g. for communication between
threads): in this case, it will be a direct write, not a copy on write. Copy on
write would be enabled between &lt;em&gt;threadlocalvar&lt;/em&gt;, of course, for better
performance.&lt;/div&gt;
Note 3: it's up to the programmer to take care of the multi-thread approach,
but writing threadlocalvar (so many characters to type!) will prevent for doing
it without knowing it. &lt;img src=&quot;/themes/default/smilies/smile.png&quot; alt=&quot;:)&quot; class=&quot;smiley&quot; /&gt;
&lt;p&gt;This could be something like that: &lt;/p&gt;
&lt;pre&gt;
function TServer.ComputePage: string; 
threadlocalvar
  tmp: string; // differs from var tmp: string 
  i: integer;  // i is defined as threadlocalvar, but is the same as normal var 
begin
  for i := 0 to high(ListStr) do // ListStr[] is a dynamic array
   tmp := tmp+ListStr[i]+#13#10; // very fast computation, without LOCK
  result := tmp; // copy from local heap to global heap 
end; 
&lt;/pre&gt;
&lt;div&gt;To implement this at the compiler and RTL level, we could use reference
count &amp;lt;=-2 for these variables (-1=const, -2=ref 0, -3=ref 1..). &lt;/div&gt;
&lt;div&gt;The RTL (i.e. system.pas unit) should be modified as such, for example for
handling a &lt;em&gt;threadlocalvar&lt;/em&gt; string reference counting add:&lt;/div&gt;
&lt;pre&gt;
function _LStrAddRef(var str): Pointer;
var P: PStrRec;
begin
  if Integer(str)&amp;lt;&amp;gt;0 then begin
    P := Pointer(Integer(str) - sizeof(StrRec));
    if P.refcnt &amp;gt;= 0 then
      InterlockedIncrement(P.refcnt) else // slow multi-thread safe reference count
    if P.refcnt &amp;lt; -1 then // -1 for const
      dec(P.refcnt);      // -2,-3... for threadlocalvar
  end;
  Result := Pointer(str);
end;
&lt;/pre&gt;
&lt;p&gt;And a local threadheap should be implemented for such threadlocalvar, with
threadlocalgetmem() and such functions.&lt;/p&gt;
&lt;p&gt;Another possibility should be do add a &amp;quot;&lt;em&gt;threadlocal&lt;/em&gt;&amp;quot; attribute for
types, to be used for local variables and properties:&lt;/p&gt;
&lt;pre&gt;
TServer = class
public
  ListStr: threadlocal array of string;
...
&lt;/pre&gt;
In this case, the method above should begin with:
&lt;pre&gt;
function TServer.ComputePage: string;
var
  tmp: threadlocal string; // differs from var tmp: string
....
&lt;/pre&gt;
But this syntax sound a bit not &amp;quot;pascalish&amp;quot;, whereas the threadlocalvar does
(it sounds like the treadvar feature) ... another idea?
&lt;div&gt;&lt;strong&gt;Comments and ideas are welcome on our forum.&lt;/strong&gt;&lt;/div&gt;
&lt;div&gt;&lt;strong&gt;See &lt;a href=&quot;http://synopse.info/forum/viewtopic.php?pid=305&quot;&gt;http://synopse.info/forum/viewtopic.php?pid=305&lt;/a&gt;&lt;/strong&gt;&lt;/div&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Hyphenation in Delphi</title>
    <link>http://blog.synopse.info/post/2010/07/27/Hyphenation-in-Delphi</link>
    <guid isPermaLink="false">urn:md5:0f766e817144f21b14c140a8cc707acd</guid>
    <pubDate>Tue, 27 Jul 2010 10:32:00 +0200</pubDate>
    <dc:creator>A.Bouchez</dc:creator>
        <category>Open Source libraries</category>
        <category>CrossPlatform</category><category>Delphi</category><category>hyphenation</category><category>libhnj</category><category>Linux</category><category>Source</category>    
    <description>&lt;p&gt;We made some years ago a Delphi unit for hyphenation of text.&lt;/p&gt;
&lt;p&gt;Such an unit, together with our SynPdf library for example, could be useful
in your application. So we released the source!&lt;/p&gt;    &lt;p&gt;What it hyphenation?&lt;/p&gt;
&lt;p&gt;As stated by wikipedia:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The hyphen ( ‐ ) is a punctuation mark used to join words and to
separate syllables of a single word. It is often confused with dashes ( –, —, ―
), which are longer and have different uses, and with the minus sign ( − )
which is also longer. The use of hyphens is called hyphenation.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Our engine does rely on Libhnj, more exactly on the version enhanced
for use in Open Office.&lt;/p&gt;
&lt;p&gt;See &lt;a href=&quot;http://lingucomponent.openoffice.org/hyphenator.html&quot;&gt;http://lingucomponent.openoffice.org/hyphenator.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can download the source code from &lt;a href=&quot;http://synopse.info/files/hyphen.zip&quot;&gt;http://synopse.info/files/hyphen.zip&lt;/a&gt;&lt;/p&gt;
There are english, french, italian and spanish hyphen tables included (as pure
delphi .res) in this release. But you can use official Open Office tables if
you want to include any other language.
&lt;p&gt;No external dll is necessary, you can hyphen any word directly in your
Delphi project.&lt;/p&gt;
&lt;p&gt;It was developed and tested under Delphi 7 and Kylix 3, under both
Windows and Linux. If you need it, I could make a version compatible up to
Delphi 2010.&lt;/p&gt;
&lt;p&gt;Source code released as dual licensed under LGPL and MPL, like the original
Libhnj library, so you can use it in both GPL and commercial products.&lt;/p&gt;
&lt;p&gt;This is a first release, as draft. If you find it useful, we may enhance and
document it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Comments and questions are&lt;/strong&gt; &lt;a href=&quot;http://synopse.info/forum/viewtopic.php?id=74&quot;&gt;&lt;strong&gt;welcome on our
forum&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;!&lt;/strong&gt;&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Damnatio Memoriae</title>
    <link>http://blog.synopse.info/post/2010/07/24/Damnatio-Memoriae</link>
    <guid isPermaLink="false">urn:md5:d6f6e7a48f547cdae33665845e981ebf</guid>
    <pubDate>Sat, 24 Jul 2010 18:50:00 +0200</pubDate>
    <dc:creator>A.Bouchez</dc:creator>
        <category>Pascal Programing</category>
        <category>Delphi</category><category>Kylix</category><category>Linux</category>    
    <description>&lt;p&gt;You sure heard about the &amp;quot;CrossKylixGate&amp;quot;... A Great tool I used for
years (&lt;a href=&quot;http://crosskylix.untergrund.net/&quot;&gt;CrossKylix&lt;/a&gt;) has just
been updated. Its author (named Simon) posted an announcement in the
Embarcadero forums. Then the post has been deleted by &amp;quot;Team B&amp;quot; members, because
of some old story.&lt;/p&gt;
&lt;p&gt;But not only Simon has been censured. Since I like and use this free tool, I
posted a very &amp;quot;soft&amp;quot; post just with the announcement of the CrossKylix update,
with some explanations and precisions. No debate. Just a link to the download
page. Then my whole thread was deleted.&lt;/p&gt;
&lt;p&gt;It just sounds like a &amp;quot;&lt;em&gt;damnatio memoriae&lt;/em&gt;&amp;quot; to me.&lt;/p&gt;    From wikipedia: &amp;quot;&lt;em&gt;Damnatio memoriae&lt;/em&gt; is the Latin phrase literally
meaning &amp;quot;damnation of memory&amp;quot; in the sense of removal from remembrance. It was
a form of dishonor that could be passed by the Roman Senate upon traitors or
others who brought discredit to the Roman State.&amp;quot;
&lt;p&gt;Are we back to the tyrany of the Caesars in old Rome?&lt;br /&gt;
Will Simon feed the lions?&lt;br /&gt;
I hope not, at least because of CrossKylix, I'll thumbs up and pray for
mercy!&lt;/p&gt;
The worse in this case is that it's not the Senate (i.e. Embarcadero) who made
the decision, but some &amp;quot;Team B&amp;quot; zealous and proud anonymous.&lt;br /&gt;
Thumbs down for him!
&lt;p&gt;&amp;quot;&lt;em&gt;Iste asinus hominis currit; ergo illius hominis asinus currit&lt;/em&gt;&amp;quot;...
I let you guess who is the donkey, and who is the man!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Comments are welcome &lt;a href=&quot;http://synopse.info/forum/viewtopic.php?id=66&quot;&gt;on our forum&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Unit Testing light in Delphi</title>
    <link>http://blog.synopse.info/post/2010/07/23/Unit-Testing-light-in-Delphi</link>
    <guid isPermaLink="false">urn:md5:07ea1cce9a8fa1d16b45781f97135205</guid>
    <pubDate>Fri, 23 Jul 2010 15:35:00 +0200</pubDate>
    <dc:creator>A.Bouchez</dc:creator>
        <category>Pascal Programing</category>
        <category>Delphi</category><category>Source</category><category>Testing</category><category>UnitTesting</category>    
    <description>&lt;p&gt;Automated Unit Testing is a great improvement in coding safe
applications.&lt;/p&gt;
&lt;p&gt;If you don't know about it, visit &lt;a href=&quot;http://xprogramming.com/index.php&quot;&gt;http://xprogramming.com/index.php&lt;/a&gt; then
come back here, and you'll discover how we implement unit testing in a KISS
way, in pure Delphi code.&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;What about automated testing?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;You know that testing is (almost) everything if you want to avoid regression
problems in your application.&lt;/p&gt;
&lt;p&gt;How can you be confident that any change made to your software code won't
create any error in other part of the software?&lt;/p&gt;
&lt;p&gt;So automated unit testing is the good candidate for implementing this.&lt;/p&gt;
&lt;p&gt;And even better, testing-driven coding is great:&lt;br /&gt;
0. write a void implementation of a feature, that is code the interface with no
implementation;&lt;br /&gt;
1. write a test code;&lt;br /&gt;
2. launch the test - it must fail;&lt;br /&gt;
3. implement the feature;&lt;br /&gt;
4. launch the test - it must pass;&lt;br /&gt;
5. add some features, and repeat all previous tests every time you add a new
feature.&lt;/p&gt;
&lt;p&gt;It could sounds like a waste of time, but such coding improve your code
quality a lot, and, at least, it help you write and optimize every
implementation feature.&lt;/p&gt;
&lt;p&gt;But don't forget that unit testing is not enough: you have to do tests with
your real application, and perform tasks like any user, in order to validate it
works as expected. That's why we added the writing and cross-referencing of
test protocols in our   &lt;a href=&quot;http://synopse.info/forum/viewforum.php?id=16&quot;&gt;SynProject documentation
tool&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;So how is testing implemented in our framework?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We may have used DUnit - &lt;a href=&quot;http://sourceforge.net/projects/dunit&quot;&gt;http://sourceforge.net/projects/dunit&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;But I didn't like the fact that it relies on IDE and create separated units
for testing. I find it useful to make tests in pure code, in the same unit
which implement them. Smartlink of the Delphi compiler won't put the testing
code in your final application, so I don't see a lot of drawbacks. And I don't
like visual interfaces with red or green lights... I prefer text files and
command line. And DUnit code is bigger than mine, and I don't need so many
options. That's a matter of taste - you can not agree, that's fine.&lt;/p&gt;
&lt;p&gt;So what about using RTTI for adding tests to your program?&lt;/p&gt;
&lt;p&gt;The SynCommons unit implements two classes:&lt;/p&gt;
&lt;div class=&quot;codebox&quot;&gt;
&lt;pre class=&quot;vscroll&quot;&gt;
type
  /// a class used to run a suit of test cases
  TSynTests = class(TSynTest)
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;which is used to register/list the tests; and&lt;/p&gt;
&lt;div class=&quot;codebox&quot;&gt;
&lt;pre class=&quot;vscroll&quot;&gt;
type
  /// a class implementing a test case
  // - should handle a test unit, i.e. one or more tests
  // - individual tests are written in the published methods of this class
  TSynTestCase = class(TSynTest)
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;which is the parent of any test case: in published methods of these classes,
you write your own tests.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sample code&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Here are the functions we want to test:&lt;br /&gt;&lt;/p&gt;
&lt;div class=&quot;codebox&quot;&gt;
&lt;pre&gt;
function Add(A,B: double): Double; overload;
begin
  result := A+B;
end;
 
function Add(A,B: integer): integer; overload;
begin
  result := A+B;
end;
 
function Multiply(A,B: double): Double; overload;
begin
  result := A*B;
end;
 
function Multiply(A,B: integer): integer; overload;
begin
  result := A*B;
end;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So we create three classes one for the whole test suit, one for testing
addition, one for testing multiplication:&lt;/p&gt;
&lt;div class=&quot;codebox&quot;&gt;
&lt;pre&gt;
type
  TTestNumbersAdding = class(TSynTestCase)
  published
    procedure TestIntegerAdd;
    procedure TestDoubleAdd;
  end;
 
  TTestNumbersMultiplying = class(TSynTestCase)
  published
    procedure TestIntegerMultiply;
    procedure TestDoubleMultiply;
  end;
 
  TTestSuit = class(TSynTests)
  published
    procedure MyTestSuit;
  end;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The trick is to create published methods.&lt;/p&gt;
&lt;p&gt;Here is how one of these test methods are implemented (I let you guess the
others):&lt;/p&gt;
&lt;div class=&quot;codebox&quot;&gt;
&lt;pre&gt;
procedure TTestNumbersAdding.TestDoubleAdd;
var A,B: double;
    i: integer;
begin
  for i := 1 to 1000 do
  begin
    A := Random;
    B := Random;
    Check(SameValue(A+B,Adding(A,B)));
  end;
end;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The SameValue() is necessary because of floating-point precision problem, we
can't trust plain = operator.&lt;/p&gt;
&lt;p&gt;And here is the test case implementation:&lt;/p&gt;
&lt;div class=&quot;codebox&quot;&gt;
&lt;pre&gt;
procedure TTestSuit.MyTestSuit;
begin
  AddCase([TTestNumbersAdding,TTestNumbersMultiplying]);
end;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And the main program:&lt;/p&gt;
&lt;div class=&quot;codebox&quot;&gt;
&lt;pre&gt;
with TTestSuit.Create do
  try
    ToConsole := @Output; // so we will see something on screen
    Run;
    readln;
  finally
    Free;
  end;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Just run this program, and you'll get:&lt;/p&gt;
&lt;div class=&quot;codebox&quot;&gt;
&lt;pre&gt;
Suit
  ------
 
 
1. My test suit
 
 1.1. Numbers adding:
  - Test integer add: 1000 assertions passed
  - Test double add: 1000 assertions passed
  Total failed: 0 / 2000  - Numbers adding PASSED
 
 1.2. Numbers multiplying:
  - Test integer multiply: 1000 assertions passed
  - Test double multiply: 1000 assertions passed
  Total failed: 0 / 2000  - Numbers multiplying PASSED
 
 
Generated with: Delphi 7 compiler
 
Time elapsed for all tests: 1.96ms
Tests performed at 23/07/2010 15:24:30
 
Total assertions failed for all test suits:  0 / 4000
 
! All tests passed successfully.
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can see that all text on screen was created by &amp;quot;uncamelcasing&amp;quot; the
method names, and that the test suit just follows the classes defined.&lt;/p&gt;
&lt;p&gt;I've uploaded this test in the &lt;em&gt;SQLite3\Sample\07 - SynTest&lt;/em&gt; folder
of our &lt;a href=&quot;http://synopse.info/fossil&quot;&gt;Source Code Repository&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;You can post comments and get feedback in&lt;/strong&gt; &lt;a href=&quot;http://synopse.info/forum/viewtopic.php?id=72&quot;&gt;&lt;strong&gt;our
forum&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;.&lt;/strong&gt;&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Synopse SQLite3 Framework 1.8</title>
    <link>http://blog.synopse.info/post/2010/07/22/Synopse-SQLite3-Framework-1.8</link>
    <guid isPermaLink="false">urn:md5:7ba1d2f2e329a62409805c9dda9352c9</guid>
    <pubDate>Thu, 22 Jul 2010 22:44:00 +0200</pubDate>
    <dc:creator>A.Bouchez</dc:creator>
        <category>SQLite3 Framework</category>
        <category>Delphi</category><category>PDF</category><category>Source</category><category>SQLite3</category>    
    <description>&lt;p&gt;The Synopse SQLite3 Database Framework was just released under Version
1.8.&lt;/p&gt;
&lt;p&gt;SQLite3 just officially reached version 3.7.0, so it's time to commit our
changes from our &lt;a href=&quot;http://synopse.info/fossil&quot;&gt;source code
repository&lt;/a&gt; to the main &amp;quot;stable&amp;quot; zip.&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;SynCommons.pas&lt;/strong&gt;&lt;br /&gt;
  - includes Unitary Testing class and functions&lt;br /&gt;
  - bug fixed in WinAnsiBufferToUtf8() and all WinAnsi to UTF-8
encoding&lt;br /&gt;
    functions (issue identified thanks to new _UTF8 testing
function)&lt;br /&gt;
  - bug fixed in val() under Delphi 2009/2010 for some values (issue
identified&lt;br /&gt;
    thanks to new NumericalConversion testing function)&lt;br /&gt;
  - bug fixed in AnsiICompW() - used in SynPdf unit&lt;br /&gt;
  - ambiguous SameText() function rewritten as SameTextU() with UTF-8
decoding&lt;br /&gt;
  - TTextWriter class moved from SQLite3Commons to SynCommons&lt;br /&gt;
  - new JSONEncode and JSONDecode functions to directly encode or decode
any&lt;br /&gt;
    content to/from a valid UTF-8 JSON object content&lt;br /&gt;
  - enhanced URLEncode() and URLDecode() functions&lt;br /&gt;
  - new ExtendedToStr/ExtendedToString functions&lt;br /&gt;
  - new tests added (mostly relative to the new functions or classes)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SynCrypto.pas&lt;/strong&gt;&lt;br /&gt;
   - mostly code review for Delphi 2009/2010 integration&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SynGdiPlus.pas&lt;/strong&gt;&lt;br /&gt;
   - small modifications to better handling Jpeg saving&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SynPdf.pas&lt;/strong&gt;&lt;br /&gt;
  - font substitution if the font is not existing in the system (worse
case&lt;br /&gt;
    will use Arial for all fonts)&lt;br /&gt;
  - now handle ETO_GLYPH_INDEX in metafile rendering&lt;br /&gt;
  - new feature: allow forced JPEG compression for graphics&lt;br /&gt;
  - new feature: UNDERLINE + STRIKEOUT support (also in RICH TEXT and
rotated text !)&lt;br /&gt;
  - new USE_SYNGDIPLUS conditional if you want to use the default jpeg
unit&lt;br /&gt;
    instead of our SynGdiPlus (but you loose TIF, PNG, and GIF
support)&lt;br /&gt;
  - enhanced: PenWidth changed to Single -&amp;gt; better precision (e.g. for
underlined text)&lt;br /&gt;
  - fix issue: Rotated text was misplaced for some angles&lt;br /&gt;
  - some small fixes about FillRect() + scaling, and move/line
stroke&lt;br /&gt;
  - REDDWARF / ONDREJ made a very good work - I had very few thinks to
rewrite&lt;br /&gt;
  - added optional XOff,YOff parameters to RenderMetaFile()&lt;br /&gt;
  - now handle EMR_STRETCHDIBITS (used in Html2Pdf)&lt;br /&gt;
  - fix strike out line position (was too low)&lt;br /&gt;
  - fixed TextWidth() and TextMeasure()&lt;br /&gt;
  - fixed font enumeration problem (trigerred with asiatic windows)&lt;br /&gt;
  - system font enumeration is now stored using UTF-8, and any non ASCII
font&lt;br /&gt;
    name will used in the PDF content the official Postscript name
extracted&lt;br /&gt;
    from its TrueType font content&lt;br /&gt;
  - optional charset parameter is now available in TPdfCanvas.SetFont:
this&lt;br /&gt;
    was needed in case of TMetaFile rendering to fix some encoding
problems&lt;br /&gt;
  - bitmap embedding fix - see &lt;a href=&quot;http://synopse.info/forum/viewtopic.php?pid=237&quot;&gt;http://synopse.info/forum/viewtopic.php?pid=237&lt;/a&gt;&lt;br /&gt;

  - now initializes the Gdi+ library if necessary&lt;br /&gt;
  - fix small issue with font orientation in metafile enumaration&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SynSelfTests.pas&lt;/strong&gt;&lt;br /&gt;
  - first public release, corresponding to SQLite3 Framework 1.8&lt;br /&gt;
  - includes Unitary Testing class and functions&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SQLite3Commons.pas&lt;/strong&gt;&lt;br /&gt;
    - includes Unitary Testing class and functions&lt;br /&gt;
    - update engine to version 3.7&lt;br /&gt;
    - new direct methods to handle BLOB fields from clients or
servers&lt;br /&gt;
    - new URI to GET or PUT BLOB fields:
ModelRoot/TableName/ID/BlobFieldName&lt;br /&gt;
    - fixed bug in TSQLTable.GetJSONValues: FirstRow parameter not
used&lt;br /&gt;
    - TTextWriter class moved from SQLite3Commons to SynCommons&lt;br /&gt;
    - new ModelRoot/[TableName/ID/]MethodName RESTful GET/PUT
request&lt;br /&gt;
     (see TSQLRestServerCallBack definition and comments):
implements some custom&lt;br /&gt;
     Client/Server request, similar to the DataSnap technology,
but in a KISS way;&lt;br /&gt;
     it's fully integrated in the Client/Server architecture of
our framework,&lt;br /&gt;
     and extend its ORM feature to Object-less communication -
see new&lt;br /&gt;
     ModelRoot/Stat method implement in TSQLRestServer&lt;br /&gt;
    - floating point numbers are now encoded using new
ExtendedStr[ing] methods:&lt;br /&gt;
     such values are now encoded in a more human readable way in
the JSON content&lt;br /&gt;
    - new tests added (mostly relative to the new functions or
classes)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SQLite3.pas&lt;/strong&gt;&lt;br /&gt;
    - includes Unitary Testing class and functions&lt;br /&gt;
    - update engine to version 3.7&lt;br /&gt;
    - SetWALMode() method for enabling Write-Ahead Logging for the
database&lt;br /&gt;
    - the RTREE extension is now compiled by default into the
engine&lt;br /&gt;
    - new tests added (mostly relative to the new functions or
classes)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SQLite3HttpServer.pas&lt;/strong&gt;&lt;br /&gt;
        - includes Unitary Testing class and
functions&lt;br /&gt;
        - allows content-type changing for GET blob
fields&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SQLite3Pages.pas&lt;/strong&gt;&lt;br /&gt;
  - some fixes for compilation under Delphi 2009/2010&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SQLite3Toolbar.pas&lt;/strong&gt;&lt;br /&gt;
    - possibility to add a background picture to the ribbon
pages&lt;br /&gt;
     (creating a TSQLAdvPage class from TAdvPage with a
BackgroundPicture property)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SQLite3UI.pas&lt;/strong&gt;&lt;br /&gt;
    - added TSynIntegerLabeledEdit component (e.g. used in
SQLite3UIOptions)&lt;/p&gt;
&lt;p&gt;Don't forget to consult the &lt;a href=&quot;http://synopse.info/forum/viewtopic.php?id=55&quot;&gt;draft version of the
documentation of this framework&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;The full source code from the framework is available to download from
&lt;a href=&quot;http://synopse.info/files/SynopseSQLite3.zip&quot;&gt;SynopseSQLite3.zip&lt;/a&gt;
licensed under a &lt;a href=&quot;http://synopse.info/forum/viewtopic.php?id=27&quot;&gt;MPL/GPL/LGPL
tri-license&lt;/a&gt;.&lt;br /&gt;
Compatible with Delphi 7 to Delphi 2010.&lt;/p&gt;
&lt;p&gt;Comments and feedback are welcome on our forum:&lt;br /&gt;
&lt;a href=&quot;http://synopse.info/forum/viewtopic.php?pid=260&quot;&gt;http://synopse.info/forum/viewtopic.php?pid=260&lt;/a&gt;&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>DataSnap-like Client-Server JSON RESTful Services in Delphi 7-2010</title>
    <link>http://blog.synopse.info/post/2010/07/18/DataSnap-like-Client-Server-JSON-RESTful-Services-in-Delphi-7-2010</link>
    <guid isPermaLink="false">urn:md5:eba749aba5d4876bb5b6068a833f76ed</guid>
    <pubDate>Sun, 18 Jul 2010 17:44:00 +0200</pubDate>
    <dc:creator>A.Bouchez</dc:creator>
        <category>SQLite3 Framework</category>
            
    <description>&lt;p&gt;You certainly knows about the new DataSnap Client-Server features, based on
JSON, introduced in Delphi 2010.&lt;br /&gt;
&lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/Developing_DataSnap_Applications&quot;&gt;http://docwiki.embarcadero.com/RADStudi
… plications&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We added such communication in our SQLite3 Framework, in a KISS (i.e.
simple) way: no expert, no new unit or new class. Just add a published method
Server-side, then use easy functions about JSON or URL-parameters to get the
request encoded and decoded as expected, on Client-side.&lt;/p&gt;    &lt;p&gt;We'll implement the same example as in the official Embarcadero docwiki page
above. Add two numbers. Very useful service, isn't it? &lt;img src=&quot;http://synopse.info/forum/img/smilies/wink.png&quot; width=&quot;15&quot; height=&quot;15&quot; alt=&quot;wink&quot; /&gt;&lt;/p&gt;
&lt;p&gt;We'll first code the Server-side:&lt;/p&gt;
&lt;p&gt;First the declaration of the class:&lt;/p&gt;
&lt;div class=&quot;codebox&quot;&gt;
&lt;pre&gt;
&lt;code&gt;TSQLRestServerTest = class(TSQLRestServerDB)
published
function Sum(aRecord: TSQLRecord; aParameters: PUTF8Char;
const aSentData: RawUTF8; var aResp, aHead: RawUTF8): Integer;
end;&lt;/code&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This method name will be used for the URL encoding, and will be called here
with ModelRoot/Sum URL.&lt;/p&gt;
&lt;p&gt;This method, like all Server-side methods, MUST have all these parameters,
and follow the TSQLRestServerCallBack prototype:&lt;/p&gt;
&lt;div class=&quot;codebox&quot;&gt;
&lt;pre&gt;
&lt;code&gt;type
TSQLRestServerCallBack = function(aRecord: TSQLRecord;
aParameters: PUTF8Char; const aSentData: RawUTF8;
var aResp, aHead: RawUTF8): Integer of object;&lt;/code&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then we implement this method:&lt;/p&gt;
&lt;div class=&quot;codebox&quot;&gt;
&lt;pre&gt;
&lt;code&gt;function TSQLRestServerTest.Sum(aRecord: TSQLRecord; aParameters: PUTF8Char;
const aSentData: RawUTF8; var aResp, aHead: RawUTF8): Integer;
var a,b: Extended;
begin
if not UrlDecodeNeedParameters(aParameters,'A,B') then
begin
result := 404; // invalid Request
exit;
end;
while aParameters&amp;lt;&amp;gt;nil do
begin
UrlDecodeExtended(aParameters,'A=',a);
UrlDecodeExtended(aParameters,'B=',b,@aParameters);
end;
aResp := JSONEncodeResult([a+b]);
// same as : aResp := JSONEncode(['result',a+b],TempMemoryStream);
result := 200; // success
end;&lt;/code&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Not difficult to follow, isn't?&lt;/p&gt;
&lt;p&gt;OK, now the client-side:&lt;/p&gt;
&lt;div class=&quot;codebox&quot;&gt;
&lt;pre&gt;
&lt;code&gt;function Sum(aClient: TSQLRestClientURI; a, b: double): double;
var err: integer;
begin
val(aClient.CallBackGetResult('sum',['a',a,'b',b]),Result,err);
end;&lt;/code&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And... that's all!&lt;/p&gt;
&lt;p&gt;You have to create the server instance, and the corresponding
TSQLRestClientURI, with the same database model, just as usual...&lt;/p&gt;
&lt;p&gt;Note that this Client-Server protocol uses JSON here, but you can serve any
kind of data, binary, HTML, whatever...&lt;br /&gt;
The usual protocols of our framework can be used: HTTP/1.1, Named Pipe, Windows
GDI messages, direct in-memory/in-process access.&lt;/p&gt;
&lt;p&gt;Just to be noticed that the data transmitted is a valid JSON content, like
this one:&lt;/p&gt;
&lt;div class=&quot;codebox&quot;&gt;
&lt;pre&gt;
&lt;code&gt;{ &amp;quot;result&amp;quot;:3.141592653}&lt;/code&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So you can consume these services, implemented Server-Side in fast Delphi
code, with any AJAX application Client-Side.&lt;/p&gt;
&lt;p&gt;Of course, these services can be related to any table/class of our ORM
framework, so you would be able to create easily any RESTful compatible
requests on URL like ModelRoot/TableName/ID/MethodName. For example, here we
return a BLOB field content as hexa:&lt;/p&gt;
&lt;div class=&quot;codebox&quot;&gt;
&lt;pre&gt;
&lt;code&gt;function TSQLRestServerTest.DataAsHex(aRecord: TSQLRecordPeople; aParameters: PUTF8Char;
const aSentData: RawUTF8; var aResp, aHead: RawUTF8): Integer;
var aData: TSQLRawBlob;
begin
result := 404; // invalid Request
if (self=nil) or (aRecord=nil) or not aRecord.InheritsFrom(TSQLRecord) or
(aRecord.ID&amp;lt;0) then
exit; // we need a valid record and its ID
if not EngineRetrieveBlob(TSQLRecordPeople,aRecord.ID,
aRecord.FieldProp('Data'),aData) then
exit; // impossible to retrieve the Data BLOB field
aResp := JSONEncodeResult([SynCommons.BinToHex(aData)]);
// idem: aResp := JSONEncode(['result',BinToHex(aRecord.fData)],TempMemoryStream);
result := 200; // success
end;&lt;/code&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;p&gt;Full source code is available in &lt;a href=&quot;http://synopse.info/fossil&quot;&gt;our
Source Code Repository&lt;/a&gt;.&lt;br /&gt;
It should work from Delphi 7 to Delphi 2010.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Your comments are welcome on &lt;a href=&quot;http://synopse.info/forum/viewtopic.php?pid=233&quot;&gt;our forum&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Delphi doesn't like multi-core CPUs (or the contrary)</title>
    <link>http://blog.synopse.info/post/2010/07/15/Delphi-doesn-t-like-multi-core-CPUs-%28or-the-contrary%29</link>
    <guid isPermaLink="false">urn:md5:7d2ae3b77d287351b4f696de87e3449e</guid>
    <pubDate>Thu, 15 Jul 2010 17:46:00 +0200</pubDate>
    <dc:creator>A.Bouchez</dc:creator>
        <category>Pascal Programing</category>
        <category>asm</category><category>Delphi</category><category>multithread</category>    
    <description>&lt;p&gt;If you're like me, you are proud of the new CPU your computer runs on - in
my case a i7-720Q with 8 embedded cores...&lt;/p&gt;
&lt;p&gt;But Delphi is not very multi-thread or multi-core friendly... guess
why....&lt;/p&gt;    &lt;h4&gt;&lt;strong&gt;The root cause the is the LOCK prefix&lt;/strong&gt; &lt;/h4&gt;
&lt;p&gt;All X86 CPUs are equipped with the ability to lock a specific memory
address, preventing other system buses to read or modify it while the following
instruction runs. &lt;/p&gt;
&lt;p&gt;The LOCK prefix to an assembly instruction causes the CPUs to assert the
LOCK# signal, and practically ensures exclusive use of the memory address in
multiprocessors / multi-thread environments. &lt;/p&gt;
&lt;div&gt;
&lt;p&gt;The LOCK prefix works only with the following instructions:&lt;/p&gt;
&lt;pre&gt;
BT, BTS, BTR, BTC   (mem, reg/imm)
XCHG, XADD  (reg, mem / mem, reg)
ADD, OR, ADC, SBB   (mem, reg/imm)
AND, SUB, XOR   (mem, reg/imm)
NOT, NEG, INC, DEC  (mem)
&lt;/pre&gt;
&lt;p&gt;Note: XCHG and XADD (and all the ‘X’ family of instructions) are planned to
be thread-safe, and always asserts LOCK# regardless of the presence of the LOCK
prefix. &lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;These low-level LOCK mechanisms ensure that some memory is modified by only
one thread at a time. &lt;/p&gt;
&lt;h4&gt;&lt;strong&gt;So what is wrong with these LOCKed
instructions?&lt;/strong&gt; &lt;/h4&gt;
&lt;p&gt;On a multi-core CPU, all cores just freeze in order to make this LOCKed asm
function threadsafe. If you have a lot of threads with more than one CPU, the
context of every CPU core has to be frozen, cleared, all cores wait for the
LOCKed asm instruction to complete, then the context is to be retrieved, and
execution continue. &lt;/p&gt;
&lt;p&gt;So guess what... when the CPU has to execute such instructions, all cores
just freeze and your brand new 8 cores CPU just run as a 1 core CPU...&lt;/p&gt;
&lt;div style=&quot;display: inline !important;&quot;&gt;&lt;strong&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight: normal;&quot;&gt;This is the same LOCKed asm function which is used
internally by Windows with its &lt;em&gt;Critical Sections&lt;/em&gt;. That's why Windows
itself is told not to be very multi-core friendly, because it does use a lot of
critical sections in its internal... Linux is much more advanced, and scales
pretty well on massive multi-core architectures.&lt;/span&gt;&lt;/strong&gt;&lt;/div&gt;
&lt;h4&gt;&lt;strong&gt;What about Delphi?&lt;/strong&gt; &lt;/h4&gt;
&lt;div&gt;
&lt;p&gt;In Delphi, I discovered at least two performance problem in its RTL:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Default memory manager, i.e. FastMM4, uses a LOCKed asm instruction for
every memory allocation or dis-allocation. &lt;/li&gt;
&lt;li&gt;string types and dynamic arrays just use the same LOCKed asm instruction
everywhere, i.e. for every access which may lead into a write to the
string. &lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;p&gt;See what I wrote in &lt;a href=&quot;https://forums.codegear.com/thread.jspa?threadID=30826&amp;amp;tstart=90&quot;&gt;the
Embarcadero forum&lt;/a&gt;... this post was not very popular, but indeed I think
I've raised a big issue on the Delphi compiler internals and performance here -
and I don't think Embarcadero has plans to resolve this... &lt;/p&gt;
&lt;p&gt;IMHO if you use strings in your application and need speed, using another
memory manager than FastMM4 is not enough. You'll have to avoid most string
use, and implement a safe TStringBuilder-like class. &lt;/p&gt;
&lt;div&gt;
&lt;p&gt;ShortStrings could be handy here, even if they are limited to 255 character
long. &lt;/p&gt;
&lt;p&gt;Using regular PAnsiChar, and fixed buffers in the stack is also a solution,
but it must be safe...&lt;/p&gt;
&lt;/div&gt;
&lt;h4&gt;&lt;strong&gt;Our enhanced RTL&lt;/strong&gt;&lt;/h4&gt;
&lt;div&gt;In our enhanced RTL for Delphi 7, we avoid use of this LOCKed asm
instruction if your application has only one thread: so if you use our enhanced
RTL, and make thread by yourself (not using the TThread object), you'll have
the best multi-thread performance possible.&lt;/div&gt;
For example, here is how we coded the clearing of a string:
&lt;pre&gt;
&lt;code&gt;asm     { -&amp;gt;    EAX pointer to str      }
        MOV     EDX,[EAX]                       { fetch str                     }
        TEST    EDX,EDX                         { if nil, nothing to do         }
        JE      @@done 
        lea ecx,[edx-skew].StrRec.refCnt
        mov dword ptr [EAX],0  // clear str
        cmp [ecx],0
        jl @@done     // refCnt=-1: literal str
{$ifdef AVOIDLOCK}
        cmp IsMultiThread,false
        jnz @@lock
        dec [ecx]     // not threadsafe dec refCount, but faster
{$else} lock  dec [ecx]     // threadsafe dec refCount
{$endif}jne @@done
@@free: push eax
        mov eax,ecx
        call MemoryManager.FreeMem // inlined _FreeMem() code
        or eax,eax
        jnz _JmpInvalidPtr
        pop eax
{$ifdef AVOIDLOCK}
        ret
@@lock: lock  dec [ecx]     // threadsafe dec refCount
        je @@free
{$else}{$ifndef NOAMD}ret{$endif} // AMD trick: avoid branch misprediction
{$endif}
@@done:{$ifndef NOAMD}db $F3{$endif} // rep ret AMD trick: avoid branch misprediction
end;&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;So if the AVOIDLOCK conditional is defined, and there is only one thread in
your application (the &lt;em&gt;IsMultiThread&lt;/em&gt; is false), the &lt;em&gt;lock dec
[ecx]&lt;/em&gt; instruction won't be called, but a much faster (and
core-friendly) &lt;em&gt;dec [ecx]&lt;/em&gt; instruction is used.&lt;/p&gt;
&lt;p&gt;Note that there is a similar check already in FastMM4: if
&lt;em&gt;IsMultiThread&lt;/em&gt; is false, no LOCKed instruction will be used.&lt;/p&gt;
&lt;p&gt;The only drawback is that if you want to use threads in your application,
you'll have:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;TThread is not to be used: the creation of one TThread just
set &lt;em&gt;IsMultiThread&lt;/em&gt; to true, so enable LOCKed
instructions;&lt;/li&gt;
&lt;li&gt;BeginThread() function must be avoided also (it set also the flag);&lt;/li&gt;
&lt;li&gt;So you'll have to call directly CreateThread() Win32 APIs for your
threads;&lt;/li&gt;
&lt;li&gt;And none of your units should use either TThread either BeginThread!&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;That's why it could be useful that Embarcadero take this problem in
account, and try to resolve it at the compiler level....&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;You may post comments or react on our forum&lt;/strong&gt;&lt;/div&gt;
&lt;div&gt;&lt;strong&gt;  &lt;a href=&quot;http://synopse.info/forum/viewtopic.php?pid=205&quot;&gt;http://synopse.info/forum/viewtopic.php?pid=205&lt;/a&gt;&lt;/strong&gt;&lt;/div&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>htm2pdf free tool</title>
    <link>http://blog.synopse.info/post/2010/07/14/htm2pdf-free-tool</link>
    <guid isPermaLink="false">urn:md5:3829a33e418f63040a4320cbc25009a1</guid>
    <pubDate>Wed, 14 Jul 2010 19:07:00 +0200</pubDate>
    <dc:creator>A.Bouchez</dc:creator>
        <category>Open Source libraries</category>
        <category>Delphi</category><category>GIF</category><category>htm2pdf</category><category>PDF</category><category>PNG</category><category>Synopse</category>    
    <description>&lt;p&gt;Using our SynPDF library and a public domain THtmlView component, and
discussion with some of our users, we were able to make a html to pdf
conversion tool.&lt;/p&gt;    &lt;p&gt;After &lt;a href=&quot;http://synopse.info/forum/viewtopic.php?id=34&quot;&gt;a discussion
with Pawel Stroinski&lt;/a&gt; on our forum, the THtmlView component was used to make
a tool converting any html document into pdf, i.e. &amp;quot;printing&amp;quot; a html document
as a pdf.&lt;/p&gt;
&lt;p&gt;I downloaded via SVN the &lt;a href=&quot;http://code.google.com/p/thtmlviewer/&quot;&gt;latest THtmlView source code available
from the successor of the well-known HTMLViewer components for Delphi&lt;/a&gt;
(previously sold by &lt;a href=&quot;http://www.pbear.com&quot;&gt;PBear.com&lt;/a&gt;), i.e.
r36.&lt;/p&gt;
&lt;p&gt;Then I compiled it under Delphi 7. Some errors in the code. I therefore
fixed them. Then try to compile under Delphi 2010 - a lot of warnings, and some
main feature not working as expected (like css support). Fixed most bugs, and
made a lot of code refactoring - a lot of warning remains, and the component is
not truly Unicode: THtmlView use internaly UTF-8 encoding. But it works better
than the original version.&lt;/p&gt;
&lt;p&gt;Then I used Pawel Stroinski's code using our &lt;a href=&quot;http://synopse.info/forum/viewforum.php?id=1&quot;&gt;SynPdf&lt;/a&gt; unit to produce a pdf
file from any html content.&lt;/p&gt;
&lt;p&gt;Some bitmaps where not printed: fixed some part of the &lt;em&gt;SynPdf&lt;/em&gt;
library (now in version 1.8.3 in our source code repository).&lt;/p&gt;
&lt;p&gt;And since the code from THtmlView did rely on jpeg.pas and was handling PNG
just with Delphi 2010, I added a compilation define (set by default) in order
to use our &lt;a href=&quot;http://synopse.info/forum/viewforum.php?id=4&quot;&gt;SynGdiPlus&lt;/a&gt; library to read
GIF, PNG and JPEG files. So the resulting executable is smaller in size (less
than 890 KB), and work as expected. If you don't like all this, and need GIF
animated in your PDF (??? it's a joken pdf doesn't allow this), you can turn
the compilation define OFF, and use the previous code.&lt;/p&gt;
&lt;p&gt;I've uploaded the source code in the &lt;em&gt;HtmlView&lt;/em&gt; sub directory of our
&lt;a href=&quot;http://synopse.info/fossil&quot;&gt;Source Code Repository&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You can download an executable file from&lt;br /&gt;
 &lt;a href=&quot;http://synopse.info/files/pdf/htm2pdf.zip&quot;&gt;http://synopse.info/files/pdf/htm2pdf.zip&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Just extract the htm2pdf.exe file in a directory, then launch it:&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://synopse.info/files/pdf/htm2pdf.png&quot;&gt;&lt;img src=&quot;http://synopse.info/files/pdf/htm2pdf.png&quot; alt=&quot;&quot; width=&quot;413&quot; height=&quot;282&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Click on the &amp;quot;Open&amp;quot; button to open a html file, then browse it on the screen,
update the parameters below (like margins or paper size), and click on the
&amp;quot;Save as&amp;quot; or &amp;quot;Save&amp;quot; buttons.&lt;br /&gt;
A pdf file will be created, containing the whole html content, together with
the files.&lt;/p&gt;
&lt;p&gt;As a demo, I included in the &lt;em&gt;HtmlView/demo&lt;/em&gt; sub directory of our
&lt;a href=&quot;http://synopse.info/fossil&quot;&gt;Source Code Repository&lt;/a&gt; some html, css
and picture files. &lt;/p&gt;
&lt;p&gt;You can download the resulting pdf from &lt;a href=&quot;http://synopse.info/files/pdf/sample.pdf&quot;&gt;http://synopse.info/files/pdf/sample.pdf&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This &lt;em&gt;htm2pdf&lt;/em&gt; tool can be used from the command line, without the
GUI window above:&lt;/p&gt;
&lt;p&gt;1. you'll observe that the last used parameters are saved in a
&lt;em&gt;htm2pdf.ini&lt;/em&gt; file in the same directory than the executable.&lt;/p&gt;
&lt;p&gt;If you launch&lt;/p&gt;
&lt;div class=&quot;codebox&quot;&gt;
&lt;pre&gt;
&lt;code&gt;htm2pdf /silent&lt;/code&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;all parameters from htm2pdf.ini will be used, no GUI will be displayed, and
the conversion will be made.&lt;/p&gt;
&lt;p&gt;2. you can force to specify a html source file name, and an optional
destination pdf file:&lt;/p&gt;
&lt;div class=&quot;codebox&quot;&gt;
&lt;pre&gt;
&lt;code&gt;htm2pdf sample.htm&lt;/code&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;will create a &lt;em&gt;sample.pdf&lt;/em&gt; file in the same directory as
&lt;em&gt;sample.htm&lt;/em&gt;&lt;/p&gt;
&lt;div class=&quot;codebox&quot;&gt;
&lt;pre&gt;
&lt;code&gt;htm2pdf sample.htm dest.pdf&lt;/code&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;will create a &lt;em&gt;dest.pdf&lt;/em&gt; file&lt;/p&gt;
&lt;p&gt;This tool is released under the Public Domain, free but with no warranty at
all.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Discussion and comments are welcome on our
forum:&lt;br /&gt;&lt;/strong&gt;&lt;a href=&quot;http://synopse.info/forum/viewtopic.php?pid=187&quot;&gt;&lt;strong&gt;http://synopse.info/forum/viewtopic.php?pid=187&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Draft Documentation of the Synopse SQLite3 Framework</title>
    <link>http://blog.synopse.info/post/2010/07/12/Draft-Documentation-of-the-Synopse-SQLite3-Framework</link>
    <guid isPermaLink="false">urn:md5:37fa79f73e16188d6179167c0b80c234</guid>
    <pubDate>Mon, 12 Jul 2010 14:55:00 +0200</pubDate>
    <dc:creator>A.Bouchez</dc:creator>
        <category>SQLite3 Framework</category>
        <category>Delphi</category><category>Documentation</category><category>Forums</category><category>SQLite3</category><category>Synopse</category><category>SynProject</category>    
    <description>&lt;p&gt;As a tutorial about SynProject, the documentation for the SQLite3 framework
itself has been generated for the first time.&lt;/p&gt;    You asked for documentation about our Synopse SQLite3 framework, we have
generated it automatically, thanks to &lt;a href=&quot;http://blog.synopse.info/category/Open-Source-Projects/SynProject-documentation-and-versioning&quot;&gt;
SynProject&lt;/a&gt;!  
&lt;div&gt;&lt;br /&gt;
&lt;div&gt;The resulting documentation of our SQLite3 framework (in draft status) can
be downloaded from &lt;a href=&quot;http://synopse.info/files/synproject/sampledoc.zip&quot;&gt;sampledoc.zip&lt;/a&gt;. &lt;/div&gt;
&lt;div&gt;If you want to know how this documentation was created in a few click
using SynProject, follow &lt;a href=&quot;http://synopse.info/fossil/wiki?name=SynProject+Tutorial&quot;&gt;this link&lt;/a&gt;.&lt;/div&gt;
&lt;div&gt;This documentation will progress, and the associated .pro file will be
available in our source code repository.&lt;/div&gt;
&lt;div&gt;Comments are welcome in &lt;a href=&quot;http://synopse.info/forum/viewtopic.php?id=55&quot;&gt;our forum&lt;/a&gt;!&lt;/div&gt;
&lt;/div&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>How to unzip or zip files content</title>
    <link>http://blog.synopse.info/post/2010/07/11/How-to-unzip-or-zip-files-content</link>
    <guid isPermaLink="false">urn:md5:42afed1ff14eec9cc877771e90af36be</guid>
    <pubDate>Sun, 11 Jul 2010 20:34:00 +0200</pubDate>
    <dc:creator>A.Bouchez</dc:creator>
        <category>Open Source</category>
        <category>compression</category><category>Delphi</category><category>Synopse</category><category>zip</category>    
    <description>&lt;p&gt;Didn't you ever wanted to unzip some archive content, or embed a zip file
into your exe?&lt;/p&gt;
&lt;p&gt;Didn't you ever wanted to create a zip archive file, from some data in
memory, in pure Delphi code, without using any external dll?&lt;/p&gt;
&lt;p&gt;One of the open source unit we use allow you to do these tasks in a easy
way.&lt;/p&gt;    &lt;p&gt;First of all, all the zip compression is embedded in an unique Delphi unit,
named SynZip which is meant to replace the default zlib unit of Delphi, and
enhance it. It works from Delphi 7 to Delphi 2010, from the same source code,
which is released under a GPL/LGPL/MPL tri-license.&lt;/p&gt;
&lt;p&gt;Do you want to compress some data in memory? Use CompressString() and
UnCompressString() methods. Both work with RawByteString encoded data:&lt;/p&gt;
&lt;pre&gt;
function test: boolean;&lt;br /&gt;
var  tmp: RawByteString;&lt;br /&gt;
begin&lt;br /&gt;
  tmp := 'some data';&lt;br /&gt;
  result := (UnCompressString(CompressString(tmp,False,comp))=tmp);&lt;br /&gt;
end;
&lt;/pre&gt;
&lt;p&gt;Do you want to create a zip archive file? Use our TZipWrite class.&lt;/p&gt;
&lt;pre&gt;
procedure TestCompression;&lt;br /&gt;
var FN: TFileName;&lt;br /&gt;
begin&lt;br /&gt;
  FN := ChangeFileExt(paramstr(0),'.zip');&lt;br /&gt;
  with TZipWrite.Create(FN) do&lt;br /&gt;
  try&lt;br /&gt;
    AddDeflated('one.exe',pointer(Data),length(Data));&lt;br /&gt;
    assert(Count=1);&lt;br /&gt;
    AddDeflated('ident.txt',M.Memory,M.Position);&lt;br /&gt;
    assert(Count=2);&lt;br /&gt;
  finally&lt;br /&gt;
    Free;&lt;br /&gt;
  end;&lt;br /&gt;
end;
&lt;/pre&gt;
&lt;p&gt;Do you want to read a zip archive file? Use our TZipRead class.&lt;/p&gt;
&lt;pre&gt;
procedure TestUnCompression;&lt;br /&gt;
var FN: TFileName;&lt;br /&gt;
i: integer;&lt;br /&gt;
begin&lt;br /&gt;
  FN := ChangeFileExt(paramstr(0),'.zip');&lt;br /&gt;
  with TZipRead.Create(FN) do&lt;br /&gt;
  try&lt;br /&gt;
    i := NameToIndex('ONE.exe');&lt;br /&gt;
    assert(i&amp;gt;=0);&lt;br /&gt;
    assert(UnZip(i)=Data);&lt;br /&gt;
    i := NameToIndex('ident.TXT');&lt;br /&gt;
    assert(i&amp;gt;=0);&lt;br /&gt;
    assert(Entry[i].info^.zcrc32=crc32(0,M.Memory,M.Position));&lt;br /&gt;
  finally&lt;br /&gt;
    Free;&lt;br /&gt;
  end;&lt;br /&gt;
  DeleteFile(FN);&lt;br /&gt;
end;
&lt;/pre&gt;
&lt;p&gt;And if you want the file to be embedded to your executable, there is a
dedicated Create constructor in the TZipRead just for handling that:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;create your exe file with a TZipRead instance created with it;&lt;/li&gt;
&lt;li&gt;append your zip content to your exe (by using TZipWrite or by using copy /b
on command line);&lt;/li&gt;
&lt;li&gt;that's all!&lt;/li&gt;
&lt;/ol&gt;
Couldn't it be easier?
&lt;div&gt;&lt;br /&gt;
&lt;div&gt;Code above was extracted and adapted from our SynSelfTests test
unit.&lt;/div&gt;
&lt;div&gt;Comments and questions are welcome on &lt;a href=&quot;http://synopse.info/forum/viewtopic.php?pid=163#p163&quot;&gt;our forum&lt;/a&gt;.&lt;/div&gt;
&lt;/div&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>SynProject screen shots available</title>
    <link>http://blog.synopse.info/post/2010/07/10/SynProject-screen-shots-available</link>
    <guid isPermaLink="false">urn:md5:a8371fe59ff9619ed75f9794b441e583</guid>
    <pubDate>Sat, 10 Jul 2010 17:30:00 +0200</pubDate>
    <dc:creator>A.Bouchez</dc:creator>
        <category>SynProject documentation and versioning</category>
        <category>Delphi</category><category>SynProject</category>    
    <description>&lt;p&gt;On the wiki of the Source Code repository, I've added some screen shots of
our SynProject tool.&lt;/p&gt;    &lt;div&gt;See &lt;a href=&quot;http://synopse.info/fossil/wiki?name=SynProject&quot;&gt;this
page&lt;/a&gt; for all this new content. &lt;/div&gt;
&lt;div&gt;I hope these screen shots and comments will give you some interest about
using and collaborating on this great Open Source (GPL) project!&lt;/div&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Named Pipe, Vista, Seven and Service</title>
    <link>http://blog.synopse.info/post/2010/07/04/Named-Pipe%2C-Vista%2C-Seven-and-Service</link>
    <guid isPermaLink="false">urn:md5:7f6138077f20986a63f5af2ce53083d3</guid>
    <pubDate>Sun, 04 Jul 2010 16:38:00 +0200</pubDate>
    <dc:creator>A.Bouchez</dc:creator>
        <category>Pascal Programing</category>
            
    <description>&lt;p&gt;If you want some local communicate between a service software and a
front-end GUI application, named pipes are a viable mechanism for this
communication. It worked fine until Windows XP, then came Vista, Seven, and the
UAC...&lt;/p&gt;    &lt;p&gt;By default, when you create a named pipe under Windows, it is accessible
only by other applications running under the same user account. Under XP, it
worked if the two users were part of the same group, or at least did share some
security policy attributes. But, for security reasons, if the background
service runs as local system while the application with the user interface runs
as the logged on user, you'll receive a ERROR_ACCESS_DENIED flag under Vista
and Seven.&lt;/p&gt;
&lt;p&gt;If you are willing to open up access to your pipe to all clients, you'd have
to explicitly create a &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: 'Courier New', Courier, monospace; font-size: 13px; white-space: pre;&quot;&gt;TSecurityAttributes&lt;/span&gt; record
instance, initialized with full user rights:&lt;/p&gt;
&lt;pre&gt;
procedure InitializeSecurity(var SA: TSecurityAttributes; var SD);
begin
fillchar(SD,SECURITY_DESCRIPTOR_MIN_LENGTH,0);
// Initialize the new security descriptor
if InitializeSecurityDescriptor(@SD, SECURITY_DESCRIPTOR_REVISION) then begin
// Add a NULL descriptor ACL to the security descriptor
if SetSecurityDescriptorDacl(@SD, true, nil, false) then begin
// Set up the security attributes structure
SA.nLength := sizeof(TSecurityAttributes);
SA.lpSecurityDescriptor := @SD;
SA.bInheritHandle := true;
exit; // mark OK
end;
end;
fillchar(SA,sizeof(SA),0); // mark error: no security
end;
&lt;/pre&gt;
&lt;div&gt;
&lt;p&gt;This works fine, but it doesn't allow you remote access to a service from
another computer.&lt;/p&gt;
&lt;p&gt;I've tried to implement what Microsoft told officially on &lt;a href=&quot;http://support.microsoft.com/kb/813414&quot;&gt;http://support.microsoft.com/kb/813414&lt;/a&gt;,
but I didn't succeed as expected. The trick is to allow access as anonymous
user to the pipe...&lt;/p&gt;
&lt;p&gt;Here is the code I wrote from original c sample&lt;/p&gt;
&lt;pre&gt;
function GetUserSid(var SID: PSID; var Token: THandle): boolean;
var TokenUserSize: DWORD;
TokenUserP: PSIDAndAttributes;
begin
result := false;
if not OpenThreadToken(GetCurrentThread, TOKEN_QUERY, True, Token) then
if (GetLastError &amp;lt;&amp;gt; ERROR_NO_TOKEN) or
not OpenProcessToken(GetCurrentProcess, TOKEN_QUERY, Token) then
Exit;
TokenUserP := nil;
TokenUserSize := 0;
try
if not GetTokenInformation(Token, TokenUser, nil, 0, TokenUserSize) and
(GetLastError &amp;lt;&amp;gt; ERROR_INSUFFICIENT_BUFFER) then
Exit;
TokenUserP := AllocMem(TokenUserSize);
if not GetTokenInformation(Token, TokenUser, TokenUserP,
TokenUserSize, TokenUserSize) then
Exit;
SID := TokenUserP^.Sid;
result := true;
finally
FreeMem(TokenUserP);
end;
end;
{$ALIGN ON}
type
ACE_HEADER = record
AceType: BYTE;
AceFlags: BYTE;
AceSize: WORD;
end;
ACCESS_ALLOWED_ACE = record
Header: ACE_HEADER;
Mask: ACCESS_MASK;
SidStart: DWORD;
end;
{$A8}
procedure InitializeSecurity(var SA: TSecurityAttributes; var SD);
const
SECURITY_NT_AUTHORITY: TSIDIdentifierAuthority = (Value: (0, 0, 0, 0, 0, 5));
SECURITY_ANONYMOUS_LOGON_RID = ($00000007);
ACL_REVISION = 2;
var pSidAnonymous, pSidOwner: PSID;
dwAclSize: integer;
ACLP: PACL;
Token: THandle;
begin
fillchar(SD,SECURITY_DESCRIPTOR_MIN_LENGTH,0);
// Initialize the new security descriptor
if InitializeSecurityDescriptor(@SD, SECURITY_DESCRIPTOR_REVISION) and
GetUserSid(pSidOwner,Token) then begin
AllocateAndInitializeSid(SECURITY_NT_AUTHORITY,1,
SECURITY_ANONYMOUS_LOGON_RID,0,0,0,0,0,0,0,pSidAnonymous);
try
dwAclSize := sizeof(TACL) +
2 * ( sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) ) +
GetLengthSid(pSidAnonymous) + GetLengthSid(pSidOwner) ;
ACLP := AllocMem(dwAclSize);
try
InitializeAcl(ACLP^,dwAclSize,ACL_REVISION);
if not AddAccessAllowedAce(ACLP^,ACL_REVISION,
GENERIC_ALL,pSidOwner) then
exit;
if not AddAccessAllowedAce(ACLP^,ACL_REVISION,
GENERIC_READ or GENERIC_WRITE,pSidAnonymous) then
exit;
if SetSecurityDescriptorDacl(@SD,true,ACLP,false) then begin
// Set up the security attributes structure
SA.nLength := sizeof(TSecurityAttributes);
SA.lpSecurityDescriptor := @SD;
SA.bInheritHandle := true;
exit; // mark OK
end;
finally
FreeMem(ACLP);
end;
finally
FreeSid(pSidAnonymous);
CloseHandle(Token);
end;
end;
fillchar(SA,sizeof(SA),0); // mark error: no security
end;
&lt;/pre&gt;
&lt;p&gt;But it didn't work as expected. Of course, I added the name of the pipe to
the SYSTEM\CurrentControlSet\Services\lanmanserver\parameters\NullSessionPipes
registry entry, but it didn't work...&lt;/p&gt;
&lt;p&gt;Whole source code is available from &lt;a href=&quot;http://synopse.info/fossil&quot;&gt;our
source code repository&lt;/a&gt;, file SQLite3\SQlite3Commons.pas&lt;/p&gt;
&lt;p&gt;You can continue to &lt;a href=&quot;http://synopse.info/forum/viewtopic.php?id=43&quot;&gt;discuss on our forum, and share
any solution&lt;/a&gt;...&lt;/p&gt;
&lt;p&gt;Of course, we have implemented HTTP/1.1 connection, which works very well
remotely over a network, so if you need networking, consider using HTTP... but
it could be an interesting challenge to make named pipes work over
the network!&lt;/p&gt;
&lt;/div&gt;</description>
    
    
    
      </item>
    
</channel>
</rss>