Open Source PDF Libraries and Tools

Trackback: http://pdf-house.blogspot.com.au/

DocumentBurster

DocumentBurster is a report distribution software which can burst reports such as payslips, invoices or statements in order to break up and distribute (by email, web, file share, etc.) relevant parts to each of your employees, customers or partners.

DocumentBurster is a report distribution software which works with any reporting software including Crystal Reports, Microsoft Access, Microsoft SQL Server Reporting Services, IBM Cognos, Oracle Hyperion and QlikView.

Using DocumentBurster it is easy to integrate report distribution and report bursting capabilities into existing in-house built legacy software or with systems like SAP ERP, Oracle Applications, Sage, Microsoft Dynamics, PeopleSoft, JD Edwards, MYOB or QuickBooks accounting software.

Features

  • Automate high-volume document delivery to customers, vendors, employees and prospects.
  • Split reports and documents into personalized PDF files and e-mail them securely and reliably.
  • It has out of the box delivery targets like email and ftp. Email is referring to any SMTP compatible server including gmail and yahoo.
  • It has command line support so it is easy to automate the bursting of reports.

http://www.pdfburst.com/

Apache PDFBox

Apache PDFBox is an open source Java PDF library for working with PDF documents. This project allows creation of new PDF documents, manipulation of existing documents and the ability to extract content from documents. Apache PDFBox also includes several command line utilities.

Features

  • PDF to text extraction
  • Merge PDF Documents
  • PDF Document Encryption/Decryption
  • Lucene Search Engine Integration
  • Fill in form data FDF and XFDF
  • Create a PDF from a text file
  • Create images from PDF pages
  • Print a PDF

http://pdfbox.apache.org/

Apache FOP

Apache FOP (Formatting Objects Processor) is a print formatter driven by XSL formatting objects (XSL-FO) and an output independent formatter. It is a Java application that reads a formatting object (FO) tree and renders the resulting pages to a specified output. Output formats currently supported include PDF, PS, PCL, AFP, XML (area tree representation), Print, AWT and PNG, and to a lesser extent, RTF and TXT. The primary output target is PDF.

http://xmlgraphics.apache.org/fop/

iText PDF

iText is a library that allows you to generate PDF files on the fly.

iText is an ideal library for developers looking to enhance web- and other applications with dynamic PDF document generation and/or manipulation. iText is not an end-user tool. Typically you won’t use it on your Desktop as you would use Acrobat or any other PDF application. Rather, you’ll build iText into your own applications so that you can automate the PDF creation and manipulation process.

You can use iText to:

  • Serve PDF to a browser
  • Generate dynamic documents from XML files or databases
  • Use PDF’s many interactive features
  • Add bookmarks, page numbers, watermarks, etc.
  • Split, concatenate, and manipulate PDF pages
  • Automate filling out of PDF forms
  • Add digital signatures to a PDF file
  • And much more…

www.itextpdf.com

iTextSharp

iTextSharp is a library that allows you to generate PDF files on the fly. iTextSharp is a port of the iText, a free Java-Pdf library.

http://itextsharp.sourceforge.net/

PDFCreator

PDFCreator is an application for converting documents into Portable Document Format (PDF) format on Microsoft Windows operating systems. Once installed, it allows the user to select PDFCreator as their printer, permitting almost any application to print to PDF.

http://www.pdfforge.org/

Ghostscript

Ghostscript is an interpreter for the PostScript (TM) language. A PostScript interpreter usually takes as input a set of graphics commands. The output is usually a page bitmap which is then sent to an output device such as a printer or display. PostScript is embedded in many printers.

http://www.ghostscript.com/

pdftk

If PDF is electronic paper, then pdftk is an electronic staple-remover, hole-punch, binder, secret-decoder-ring, and X-Ray-glasses. Pdftk is a simple tool for doing everyday things with PDF documents. Keep one in the top drawer of your desktop and use it to:

  • Merge PDF Documents
  • Split PDF Pages into a New Document
  • Rotate PDF Pages or Documents
  • Decrypt Input as Necessary (Password Required)
  • Encrypt Output as Desired
  • Fill PDF Forms with FDF Data or XFDF Data and/or Flatten Forms
  • Apply a Background Watermark or a Foreground Stamp
  • Report on PDF Metrics such as Metadata, Bookmarks, and Page Labels
  • Update PDF Metadata
  • Attach Files to PDF Pages or the PDF Document
  • Unpack PDF Attachments
  • Burst a PDF Document into Single Pages
  • Uncompress and Re-Compress Page Streams
  • Repair Corrupted PDF (Where Possible)

Pdftk allows you to manipulate PDF easily and freely. It does not require Acrobat, and it runs on Windows, Linux, Mac OS X, FreeBSD and Solaris.

http://www.accesspdf.com/pdftk/index.html

PDFsam

pdfsam is an open source tool (GPL license) designed to handle pdf files. It’s released in 2 versions, basic and enhanced.

Requirements:

pdfsam branch 1: Java Virtual Machine 1.4.2 or higher
pdfsam branch 2: Java Virtual Machine 1.6 or higher

pdfsam basic:

A simple tool designed to split and merge pdf files. With it’s simple and intuitive interface you can:

  • split your pdf documents (into chapters, single pages, etc.).
  • merge many pdf documents or subsections of them.
  • extract sections of your document into a single pdf document.
  • mix alternate pages taken from two pdf documents in straight or reverse order into a single document.
  • rotate pages of the selected pdf documents.
  • visually reorder pages of a selected pdf document.
  • visually compose a document dragging pages from selected pdf documents.
  • save and load your environment to automatize your recurrent jobs.
  • manage pdfsam settings and set an environment to load at start up.

pdfsam enhanced:

This is the enhanced version of pdfsam. In this version you’ll find all the basic features plus:

  • encrypt your pdf files (RC40 bits, RC128 bits, AES128 bits) and set permissions on them.
  • add a pdf frontpage or an addendum (or both) to your pdf documents.
  • decrypt pdf documents.
  • extract attachments from your pdf documents.
  • set viewer options to a document to tell the viewer application how should open the document.
  • set the metadata of a document (author, title, subject and keywords).

http://www.pdfsam.org/

PDF Renderer

The PDF Renderer is all Java library which renders PDF documents to the screen using Java2D. Typically this means drawing into a Swing panel, but it could also draw to other Graphics2D implementations.

http://java.net/projects/pdf-renderer

PDF Clown

PDF Clown is a Java/.NET library for manipulating PDF files, with multiple abstraction layers to satisfy different programming styles: from the lower level (PDF object model) to the higher (PDF document structure and content streaming).

http://clown.stefanochizzolini.it/

PJX

PJX is a general purpose PDF programming library for Java; with support for reading, combining, manipulating, and writing PDF documents.

http://www.etymon.com/epub.html

JPedal

JPedal is an application for viewing and printing of pdf files. Features of JPedal:

* JPedal supports a wide variety of different font technologies.
* Jpedal supports the following colour spaces: DeviceRGB, CalRGB, DeviceGRAY, CalGRAY, ICC, indexed, DeviceCMYK and DeviceN.
* Jpedal also reads and displays raw tiff, jpg and gif file formats.
* Text can be extracted from an entire document, a single page, from within page co-ordinates or from tables. Font information and metadata can also be extracted.
* JPedal can extract any image from a pdf with a choice of output options.
* View, edit, print and extract content from interactive FDF forms.
* JPedal includes an interactive search function that allows you to search either the current page or the entire pdf document for occurrences of a word or a phrase.

http://www.jpedal.org/

PDFjet – Open Source Edition

A library for dynamic generation of PDF documents from Java and .NET.
Create PDF documents and reports with just a few lines of Java or C# code.http://pdfjet.com/index.html

gnujpdf

gnujpdf is a Java package (gnu.jpdf.*) licensed under the LGPL. It provides a simple API to create pdf files and print using subclasses of java.awt.Graphics and java.awt.PrintJob. The PDF classes write to an OutputStream in pdf format instead of a typical Graphics object, but the method calls are the same as they would be in any Applet or Application drawing to a canvas.

http://gnujpdf.sourceforge.net/

jPod

jPod is a mature PDF manipulation and rendering library. It supports COS and PD level manipulation of PDF documents, AFM and TrueTypes fonts, incremental writing of files, and parsing of files that slightly deviate from the specification.

http://sourceforge.net/projects/jpodlib/

Report.NET

Report.NET is a powerful library that will help you to generate PDF documents in a simple and flexible manner. The document can be created with data that have been retrieved from any ADO.NET data set. The Report.NET library is available for free under the LGPL license.

Features
– entirely written in C# for the Microsoft .NET framework
– very compact code (Hello World: 6 lines)
– supported graphic objects: text, lines, rectangles, jpeg images
– easy alignment and transformation of graphic objects
– ASP.NET can generate dynamic PDF pages
– XML Documentation (Comment Web Pages)

http://report.sourceforge.net/

PDFsharp

PDFsharp is the Open Source library that easily creates PDF documents from any .NET language.The same drawing routines can be used to create PDF documents, draw on the screen, or send output to any printer.

http://www.pdfsharp.com/

SharpPDF

SharpPDF is a C# library that implements different objects for the creation of PDF documents with few steps. It is created for .NET framework 1.1 and it can create 100% compatible PDF (tested with Acrobat Reader, Ghostscript , JAWS PDF Editor and other PDF readers). The most important goal of this library is the simple way of use.
It can be used in many ways:

  • You can use it with Windows Forms to generate new pdf files or to save them on a database.
  • You can use it with Web Applications (ASP.NET) to generate files or to get them directly into the browser.

http://sharppdf.sourceforge.net/

ASP.NET FO PDF

FO PDF is similar to ASP.NET Server Controls, written in C#.It takes DataTable and few other params to generate the XSL FO and renders a DataGrid like PDF Report using NFOP (Apache FOP Port in J#) PDF Formatter.More tags to generate XSL FO will be added.

http://sourceforge.net/projects/npdf/

NFop

NFop is a Formatting Objects Processor (FOP) for XSL-FO that runs on the .NET Framework. It is a port from the Apache XML Project’s FOP Java source to .NET’s Visual J#. This makes it great for pure .NET reporting modules.

http://sourceforge.net/projects/nfop/

Haru Free PDF Library

libHaru is a free, cross platform, open source library for generating PDF files.

It supports the following features:

  • Generating PDF files with lines, text, images.
  • Outline, text annotation, link annotation.
  • Compressing document with deflate-decode.
  • Embedding PNG, Jpeg images.
  • Embedding Type1 font and TrueType font.
  • Creating encrypted PDF files.
  • Using various character sets (ISO8859-1~16, MSCP1250~8, KOI8-R).
  • Supporting CJK fonts and encodings.
  • You can add the feature of PDF creation by using HARU without understanding complicated internal structure of PDF.

libHaru is written in ANSI C, so theoretically it supports most of the modern OSes.

http://libharu.org

libpdfdoc

libpdfdoc is a library to access PDF (Portable Document Format). It provides classes and functions for reading and writing to PDF files.

Features

  • read/write PDF files with the same API
  • not much right now

http://libpdfxx.sourceforge.net/

PoDoFo

The PoDoFo library is a free, portable C++ library. It can parse existing PDF files and create new ones from scratch.

http://podofo.sourceforge.net/

Cairo

Cairo is a 2D graphics library with support for multiple output devices. Currently supported output targets include the X Window System, Quartz, Win32, image buffers, PostScript, PDF, and SVG file output. Experimental backends include OpenGL (through glitz), XCB, BeOS, OS/2, and DirectFB.

http://cairographics.org/

QPDF

QPDF is a C++ library and set of programs that inspect and manipulate the structure of PDF files. It can encrypt and linearize files, expose the internals of a PDF file, and do many other operations useful to end users and PDF developers.
http://qpdf.sourceforge.net/

Xpdf

Xpdf is an open source PDF viewer for the X Window System and Motif.Xpdf runs on practically any Unix-like operating system. Xpdf can decode LZW and read encrypted PDFs. The official version obeys the DRM restrictions of PDF files, which may prevent copying, printing, or converting some PDF files.There are patches which make Xpdf ignore these DRM restrictions.
Xpdf includes several programs that don’t require the X Window System, including programs which extract images from PDF files or convert PDF to PostScript or text. These programs run on DOS, Windows as well as Linux and Unix.http://www.foolabs.com/xpdf/

BePDF

BePDF is a PDF viewer for the BeOS, Haiku & Zeta.
Besides viewing, it supports annotating and user-defined bookmarking for unencrypted PDFs. It’s fully localized for 20 languages at the moment with additional languages being easily added via text files.http://bepdf.sourceforge.net/

ePDFView

ePDFView is a free lightweight PDF document viewer using Poppler and GTK+ libraries.
The aim of ePDFView is to make a simple PDF document viewer, in the lines of Evince but without using the Gnome libraries.http://trac.emma-soft.com/epdfview/

Evince

Evince is a document viewer for multiple document formats. It currently supports pdf, postscript, djvu, tiff and dvi. The goal of evince is to replace the multiple document viewers that exist on the GNOME Desktop with a single simple application.

http://projects.gnome.org/evince/

gv

gv allows to view and navigate through PostScript and PDF documents on an X display by providing a user interface for the ghostscript interpreter.

http://www.gnu.org/software/gv/

KPDF

KPDF is a free PDF reader based on Xpdf. It is integrated with the KDE platform, so it embeds very well in Konqueror as KPart. Feature highlights:

  • Three different ways of searching: find dialog, thumbnail filter and type-ahead find.
  • Capture images and text easily with kpdf by dragging a rectangle around what is desired to be captured.
  • Choosing the default background/text colors, like a CSS style sheet.
  • Ability to add bookmarks to pages.

http://kpdf.kde.org/

MuPDF

MuPDF is a lightweight PDF viewer and toolkit written in portable C.
The renderer in MuPDF is tailored for high quality anti-aliased graphics. It renders text with metrics and spacing accurate to within fractions of a pixel for the highest fidelity in reproducing the look of a printed page on screen.
MuPDF has a small footprint. A binary that includes the standard Roman fonts is only one megabyte. A build with full CJK support (including an Asian font) is approximately five megabytes.
MuPDF has support for all non-interactive PDF 1.7 features, and the toolkit provides a simple API for accessing the internal structures of the PDF document. Example code for navigating interactive links and bookmarks, encrypting PDF files, extracting fonts, images, and searchable text, and rendering pages to image files is provided.http://mupdf.com/

Okular

Okular is a universal document viewer based on KPDF for KDE 4.

The last stable release is Okular 0.10, shipped in the kdegraphics module of KDE SC 4.4.

Okular combines the excellent functionalities of KPDF with the versatility of supporting different kind of documents, like PDF, Postscript, DjVu, CHM, and others.
The document format handlers page has a chart describing in more detail the supported formats and the features supported in each of them.

http://okular.kde.org/

Sumatra PDF

Sumatra PDF is a slim, free, open-source PDF viewer for Windows. Portable out of the box.
Sumatra has a minimalistic design. Simplicity has a higher priority than a lot of features.
It’s small and starts up very fast.
It’s designed for portable use: only one file so you can run it from external USB drive. Doesn’t write to registry.http://blog.kowalczyk.info/software/sumatrapdf/index.html

Vindaloo

A PDF Reader. It is currently under active development. Vindaloo runs under Mac OS X and GNUstep. The OSX version that comes as a dmg-file does not require installation of PopplerKit. For GNUstep, you need to download and compile PopplerKit first.

http://home.gna.org/gsimageapps/

Yap(formerly GPSText)

A PostScript/PDF previewer and front end to the a2ps text formatting tool. Harness the full power of a2ps to beautifully format source code (C, Objective C, Scheme, Perl, etc.) and many other kinds of text files. PostScript/PDF rendering is done using GPL GhostScript.

Features

  • extensive use of OOP programming techniques
  • preview PostScript files
  • format text files with a2ps
  • opens files that are listed on the command line for easy previewing
  • set
    • paper size
    • pretty print style
    • prologue
    • encoding

    double click on any of these to read a description of the respective feature

  • set a2ps options via an easy-to-use GUI

http://www.freebsdsoftware.org/graphics/yap.html

FPDF

FPDF is a PHP class which allows to generate PDF files with pure PHP, that is to say without using the PDFlib library. F from FPDF stands for Free: you may use it for any kind of usage and modify it to suit your needs.

FPDF has other advantages: high level functions. Here is a list of its main features:

  • Choice of measure unit, page format and margins
  • Page header and footer management
  • Automatic page break
  • Automatic line break and text justification
  • Image support (JPEG, PNG and GIF)
  • Colors
  • Links
  • TrueType, Type1 and encoding support
  • Page compression

http://www.fpdf.org/

pear File_PDF

PDF generation using only PHP. This package provides PDF generation using only PHP, without requiring any external libraries.

http://pear.php.net/package/File_PDF

TCPDF

TCPDF project was started in 2002 and now it is freely used all over the world by millions of people. TCPDF is a Free Libre Open Source Software (FLOSS).

Main Features:

  • no external libraries are required for the basic functions;
  • all ISO page formats, custom page formats, custom margins and units of measure;
  • UTF-8 Unicode and Right-To-Left languages;
  • TrueTypeUnicode, OpenTypeUnicode, TrueType, OpenType, Type1 and CID-0 fonts;
  • Font subsetting;
  • methods to publish some XHTML + CSS code, Javascript and Forms;
  • images, graphic (geometric figures) and transformation methods;
  • native support for JPEG, PNG and SVG images;
  • 1D and 2D barcodes: CODE 39, ANSI MH10.8M-1983, USD-3, 3 of 9, CODE 93, USS-93, Standard 2 of 5, Interleaved 2 of 5, CODE 128 A/B/C, 2 and 5 Digits UPC-Based Extention, EAN 8, EAN 13, UPC-A, UPC-E, MSI, POSTNET, PLANET, RMS4CC (Royal Mail 4-state Customer Code), CBC (Customer Bar Code), KIX (Klant index – Customer index), Intelligent Mail Barcode, Onecode, USPS-B-3200, CODABAR, CODE 11, PHARMACODE, PHARMACODE TWO-TRACKS, QR-Code, PDF417;
  • Grayscale, RGB, CMYK, Spot Colors and Transparencies;
  • automatic page header and footer management;
  • document encryption and digital signature certifications;
  • transactions to UNDO commands;
  • PDF annotations, including links, text and file attachments;
  • text rendering modes (fill, stroke and clipping);
  • multiple columns mode;
  • bookmarks and table of content;
  • text hyphenation;
  • automatic page break, line break and text alignments including justification;
  • automatic page numbering and page groups;
  • move and delete pages;
  • page compression.

http://www.tecnick.com/public/code/cp_dpage.php?aiocp_dp=tcpdf

Synopse PDF engine

Synopse PDF engine is an Open Source PDF document creation library for Delphi, embedded in one unit. It’s used in the 1.7 version of SQLite3 framework, for creating PDF files from reports.
Among its features, you can use a true TCanvas to create the PDF, and embed True Type fonts subsets. Of course, it’s Unicode ready, and licensed under a MPL/GPL/LGPL tri-license.

The Synopse PDF engine features:

  • Create PDF documents containing text, graphics, and bitmaps;
  • Use a TCanvas instance to draw the page content with your VCL code, just as usual (you can even use the Handle property of the TCanvas to use low level GDI commands);
  • Automatic document Compression;
  • Embed JPG or BMP/GIF/PNG pictures (bitmaps are compressed into the PDF content);
  • You can draw any EMF file or TMetaFile instance, which will be converted to vectorial;
  • Fully handle Unicode text content;
  • Embed TrueType fonts, as a whole, or as a subset (i.e. only used glyphs are stored into the PDF);
  • Easily add outlines or change page format;
  • PDF file content generation is very fast: after profiling, it appears that the creation time is mostly spent in compression, not in content generation;
  • Works in Delphi 7 up to 2010;
  • Whole engine is only one unit (i.e. no external dll is required), and doesn’t require our SQLite3 database framework;
  • Freeware Opensource unit, licensed under a MPL/GPL/LGPL tri-license.

http://blog.synopse.info/post/2010/05/03/Synopse-PDF-engine

Advertisements

The iOS Text Editor roundup

Trackback: http://brettterpstra.com/ios-text-editors/#main

Key

  • Yes: Feature exists, see notes for any additional details
  • $$: Feature is available as in-app purchase or external premium add-on
  • No: Feature does not exist
  • ?: Feature has not been verified yet
  • * Newly added to the list
Price iPhone iPad [Sync] DropBox iCloud WebDAV iTunes Proprietary [Export] Plain Text Copy HTML Email HTML Email PDF Print Open in … [Features] TextExpander Markdown preview/export Markdown editing features Appearance options Syntax Highlighting Extra Keyboard row In-document text search Search and replace Full-text file search Word count Char count Page count Reading time URL handler(s) Web Browser Desktop App
1a Easy Writer $1.99 N Y | Y Y N Y N | Y N Y N N Y Y | N N N N N Y N N N N N N N N Y N
1Writer $2.99 Y Y | Y Y N Y N | Y N Y Y Y Y Y | Y Y Y Y N Y N N Y N N N N Y N N
AppWriter $19.99 N Y | Y N N N N | Y N Y N N N N | N N N N N N N N N N N N N N N N
Buffer Editor $3.99 Y Y | Y N N Y N | Y N Y N N N Y | N N N Y Y Y Y Y N N N N N N N N
Byword $4.99 Y Y | Y Y N Y N | Y Y Y Y Y Y Y | Y Y Y Y Y Y N N Y Y Y N N Y N Y
Caret $0.99 Y Y | Y N N N N | Y N N N N N N | N N N N N N N N N N N N N N N N
Clean Writer $0.99 N Y | Y N N Y N | Y N Y N N N Y | N N N Y N Y N N N Y Y N N N N N
CloudNote $0.99 Y Y | Y N N N N | Y N Y N Y N Y | Y Y N N N Y N N N N N N N N N N
Codeanywhere Free Y Y | Y N N N Y | Y Y N N N N N | N N Y N Y Y Y Y Y N N N N N N N
Compositions $1.99 Y Y | Y N N N Y | Y N Y N N N N | Y N N Y N N N N N Y N N N N N N
Daedalus $4.99 Y Y | Y Y Y Y N | Y N Y N Y Y Y | Y Y Y Y N Y Y N Y Y Y N N N Y Y
Diet Coda $19.99 N Y | N N N N Y | N Y N N N N N | N N N Y Y Y Y Y N N N N N N Y N
Drafts $1.99 Y N | N N N N Y | Y Y Y Y N N Y | Y Y N Y N N N N Y Y Y N N Y N N
Drafts for iPad $2.99 N Y | N N N N Y | Y Y Y Y N N Y | Y Y N Y N Y N N Y Y Y N N Y N N
Drag Pad $1.99 Y Y | N N N N N | Y N Y Y N Y N | N Y Y N N N N N N N N N N N N N
DropText $0.99 Y Y | Y N N N N | N N N N N N N | Y N N N N Y N ? N N N N N N ? N
Editorial $6.99 Y Y | Y N N Y N | Y Y Y Y N Y N | Y Y Y Y Y Y Y Y Y Y Y N N Y Y N
FastEver $1.99 Y N | N N N N Y | N N N N N N N | Y N N N N N N N N N N N N N N Y
FastEverXL $3.99 N Y | N N N N Y | N N N N N N N | Y N N N N N N N N N N N N N N Y
FioWriter $4.99 Y Y | Y Y N Y N | Y N Y N N Y Y | Y N N N N Y Y Y N Y Y N N N N N
FTPedit $2.99 N Y | N N N N N | N N N N N N N | N N N Y Y Y N N N N N N N N N N
Glyphs+ $1.99 Y Y | N Y N Y N | Y Y Y Y N Y Y | Y Y Y N N N N N N Y Y N Y Y Y N
Gusto $9.99 N Y | N N N Y N | N N Y Y N N Y | N N N N Y Y N N Y N N N N N Y N
Gusto Mobile $4.99 Y N | N N N Y N | N N Y Y N N Y | N N N N Y Y N N Y N N N N N Y N
Heart Writer $1.99 N Y | Y N N Y N | Y N Y N N N N | N N N N N Y Y Y N N N N N N N N
iA Writer $0.99 Y Y | Y Y N Y N | Y Y Y Y N Y Y | Y Y Y N N Y N N N Y Y N Y N N Y
Index Card $4.99 Y Y | Y Y N Y N | Y N N Y N Y N | N N N N N N N N N N N N N N N N
Indigo In Free Y Y | N Y N N Y | Y N Y N N N N | Y N N N N N N N N N N N N N N Y
Inkwell Free N Y | Y N N N N | Y N Y N N N N | N N N N N N N N N Y N N N Y N N
iWriter $2.99 N Y | Y N N Y N | Y N Y N N Y Y | N N N Y N Y N N N Y Y N Y N N N
Jottings $3.99 Y N | Y N N N N | Y Y Y Y N Y N | Y Y N N N N N N Y Y Y N N N N N
Knowtes $2.99 N Y | Y N N N N | Y N N N N N Y | N Y N Y N Y N N N Y Y N N N Y N
Koder $5.99 N Y | Y N N Y N | Y N N N N N Y | N N N Y Y Y Y Y N N N N N N Y N
Kodiak PHP $9.99 N Y | N N N N N | N N Y N N N Y | N N N Y Y Y N N N N N N N N N N
KWrite $0.99 Y Y | Y N N Y N | Y N Y N Y Y N | N Y N N N Y N ? N N N N N ? ? N
Letterspace Free Y Y | N Y N N N | N N Y Y N Y Y | N N Y Y Y Y N N Y N N N N N N N
Locayta Notes Free Y Y | Y N N N N | Y N N N N N N | N N N Y N N N N N N N N N N N N
MarkNote $4.99 N Y | Y N N N N | Y Y N Y N N N | N Y Y N N Y N N N N N N N N N N
MobileFolio $2.99 Y Y | Y N N Y N | Y N Y Y N N Y | N Y Y Y N Y N N N Y Y N N N Y N
My Writing Spot $2/4.99 Y Y | N N N N Y | Y Y Y Y N Y N | Y N N N N Y N N N Y Y N N N N N
MyEditor $3.99 Y Y | N Y N N N | Y N Y N N Y Y | Y Y N Y N N Y Y Y Y Y N N Y N N
MyText Free Free Y Y | N N N N Y | Y N Y N N Y Y | N N N Y N N Y Y N N N N N N N N
Nebulous Notes $4.99 Y Y | Y N N N N | Y Y Y Y Y Y Y | Y Y Y Y N Y Y N Y Y Y N N N N N
NewPad Free N Y | N N N N N | N N N Y N Y N | N N N N N Y N N N N N N N N N N
Nocs Free/$$ Y Y | Y N N Y N | Y N N N N N N | Y Y N Y N N N N N N N N N N Y N
Notability $1.99 N Y | Y N N Y N | Y N Y Y Y N Y | N N N N N N N N N N N N N N N N
Note & Share $0.99 Y Y | Y N N N Y | Y Y Y Y N N N | Y Y Y N N N N N Y N Y N N N N N
Notebook $4.99 Y Y | Y N N N N | Y N Y N N N N | Y N N Y N Y N N Y N N N N Y N N
Notebooks $5/8.99 Y Y | Y N Y Y Y | Y Y Y Y Y Y Y | Y Y Y Y N Y Y ? Y Y Y N N N N Y
Notefile $4.99 Y Y | N Y N N Y | N N Y N N N N | Y N N N N N N N N N N N N Y N N
Notelet $0.99 Y Y | Y N N N N | Y N Y N N Y Y | N N N N N N N N N N Y N N N N N
Notesdeck $2.99 Y Y | Y Y N N Y | N N Y N N N Y | Y N N Y N N N N Y N N N N N N N
Notesy $4.99 Y Y | Y N N N N | Y Y Y Y N Y N | Y Y Y Y N N N N Y Y Y N N Y N N
nvNotes $2.99 Y N | Y N N N N | Y N Y N N N Y | N Y Y Y Y Y Y N Y Y Y N N Y N N
OmmWriter $4.99 N Y | N N N ? N | Y N N N N N N | N N N Y N Y ? N N N N N N N N Y
Paragraft $0.99 Y Y | N N N Y N | N N N N N N N | N Y Y N N N N ? N Y N N N N N N
Phraseology $3.99 N Y | N N N N N | Y Y Y Y N Y Y | Y Y N Y N Y N ? N Y Y N N Y N N
Pinyin Typist $1.99 Y Y | N N N N N | Y N Y Y N N N | N Y N Y N Y N N N N N N N N N N
PlainText Free/$$ Y Y | Y N N Y N | Y N Y N N Y N | Y N N N N N N N N Y Y N N Y N N
Pop for iOS $0.99 Y Y | N N N N N | Y N N N N N N | N N N N N N N N N Y N N N N N N
Procoding $4.99 Y Y | Y Y N Y Y | Y Y Y N N N Y | N N N Y Y Y Y Y N N N N N N Y Y
Quick Drafts $2.99 Y N | Y N N N N | Y N Y N N N Y | N N N N N N N N Y Y Y N N N N N
Quick Drafts for iPad $3.99 N Y | Y N N N N | Y N Y N N N Y | N N N N N N N N N Y Y N N N N N
Schreibkraft $3.99 N Y | Y Y N Y N | Y N Y N N Y N | N N N Y N Y N N N Y Y Y Y N Y N
Scratch $2.99 Y N | Y N N N N | N N Y N N N N | N N Y N N Y N N Y Y Y N N N N N
Scriptus $0.99 N Y | Y N N Y N | Y N Y N Y Y Y | Y N N Y N Y N N N N N N Y N N N
SecureTexts pocket $2.99 Y Y | N Y N Y Y | Y N Y N Y Y Y | N Y N N N Y Y Y N Y Y N N N N N
Simplenote Free/$$ Y Y | $$ N N N Y | Y N Y N N Y N | N N N Y N N Y N Y Y Y N N N N Y
Smultron 2 $5 Y Y | N Y N N N | N N N N N N N | N N N N Y N N N N N N N N N N N
Split Pea $1.99 N Y | N N N Y N | Y Y Y Y N Y N | N Y N N N N N ? Y N N N N ? Y N
Storyist $9.99 Y Y | Y N N Y Y | Y N Y N Y N Y | N N N Y N N Y Y Y Y Y Y N N N N
Textastic iPad $9.99 N Y | Y Y Y Y N | Y Y Y Y N N Y | Y Y Y Y Y Y Y Y N Y Y N N Y Y Y
Textastic iPhone $9.99 Y N | Y Y Y Y N | Y Y Y Y N N Y | Y Y Y Y Y Y Y Y N Y Y N N Y Y Y
TextCenter $1.99 Y Y | N Y N Y N | Y Y Y Y N Y Y | Y Y Y Y N Y N N Y Y Y N N Y N N
TextCrafter $2.99 Y Y | N N N N N | Y N Y N N N N | N N N Y N N N N N Y Y N N N N N
Textforce $2.99 Y Y | Y N N ? N | Y N N N N N Y | Y N N N N Y Y Y N N Y N N N N N
Textilus $4.99 N Y | Y Y N Y Y | Y Y Y Y Y Y Y | Y N N Y Y Y Y Y Y Y Y Y Y Y Y N
Textkraft $3.99 N Y | Y Y N Y N | Y N Y N N Y Y | N N N N N Y N N N Y Y Y Y N Y N
Textly $0.99 Y Y | N Y N N N | Y Y Y Y N Y Y | Y Y Y Y N Y N N N Y Y N N Y N N
Textwell $2.99 Y Y | Y Y N N N | Y N Y N N Y Y | Y Y N Y N N Y Y Y Y Y N N Y Y N
Threadnote $1.99 Y N | N N N N Y | Y N Y N N N Y | Y N N N N Y N N Y N N N N Y Y N
TopXNotes touch $0.99 Y Y | N N N N Y | Y N N Y N N Y | N N N Y N N Y N Y N N N N Y N N
Trunk Notes $3.99 Y Y | Y N N Y N | Y N Y Y N N N | Y Y Y N N Y Y N Y N N N N N N Y
UpWord Free/$$ Y Y | Y N N N N | Y N Y N Y Y N | Y N N Y N N Y N N Y Y N N Y N N
UX Write $14.99 Y Y | Y N Y Y N | N Y N Y Y Y Y | N Y N Y N Y N N N N N N N Y N N
Verses notebook $1.99 Y Y | N N N N N | N N N N N N N | N N N N N N N N N N N N N N N N
Vesper $4.99 Y N | N N N N N | N N Y N N Y N | N N N N N N N N Y N N N N N Y N
Vim Free Y Y | N N N Y N | N N N N N N N | N N N N Y N Y Y Y Y Y Y N N N Y
Werdsmith Free/2.99 Y Y | N Y N $$ N | Y N Y N N N N | N N N N N N N N N $$ N N Y N N N
Whitespace Free Y N | N N N N N | Y N Y Y N N N | N Y Y N Y Y Y N Y Y Y N N N N N
Wisdom Writer $4.99 Y Y | Y N N N Y | Y Y Y Y Y Y Y | N Y Y Y N Y N N N Y Y N N N N N
Wordbox $4.99 Y N | Y N N N N | Y Y Y Y Y Y Y | Y Y Y N N Y N N N Y Y N N N N N
WordEver $1.99 Y N | Y Y N Y N | Y Y Y Y Y Y Y | Y Y Y Y Y Y N N N Y Y N Y Y Y N
WordEver HD $3.99 N Y | Y Y N Y N | Y Y Y Y Y Y Y | Y Y Y Y Y Y N N N Y Y N Y Y Y N
Write 2 Free/2.99 Y Y | Y N N N N | Y N Y N Y Y N | Y Y Y Y N Y Y ? Y Y Y N N N N N
Write for Dropbox $0.99 Y N | Y N N Y N | Y Y Y Y N Y Y | N Y Y Y N Y Y N N Y Y N N Y N N
Writebox $1.99 Y Y | Y N N N N | N N N N N N N | N Y Y N N N N N N N N N N N N N
WriteDown $0.99 Y N | Y Y N N Y | Y Y Y Y Y Y Y | Y Y Y Y N Y Y Y N Y Y N N N Y Y
WriteRight $4.99 Y Y | Y Y N Y N | Y Y Y Y Y Y Y | N Y Y Y N Y Y Y Y Y Y Y N Y Y N
WriteRoom $4.99 Y Y | Y N N Y N | Y N Y N Y Y N | Y N N Y N Y N N Y Y Y N N Y N Y
WriteUp $2.99 Y Y | Y N N N N | Y Y Y Y N N N | Y Y Y Y N Y Y N Y Y Y Y Y Y Y N
Writing $1.99 Y Y | N N N N N | Y N Y N N N N | N N N Y N Y N N N Y Y N N N N N
Writing Kit $4.99 Y Y | Y N N N N | Y Y Y Y Y Y Y | Y Y Y Y N Y Y N N Y Y N N Y Y N
Writings $4.99 N Y | Y N N Y N | Y N Y N N Y N | Y N N Y N Y Y ? N Y Y N N ? N N
WWrite $1.99 N Y | N N N Y N | Y N Y N N N N | N N N N N N N N N Y Y N N N N N
WWriteFree Free N Y | N N N Y N | Y N Y N N N N | N N N N N N N N N Y Y N N N N N
Yelena $2.99 N Y | Y N N N N | N N N N N N N | N N N Y Y Y Y N Y N Y N N N N N

打印调用堆栈

原文地址:http://blog.csdn.net/chief1985/article/details/4618492

java里面可以使用Throwable类来获取堆栈,示例代码如下:


package name.xu;
public class CallStack {
	public static void printCallStatck() {
		Throwable ex = new Throwable();
		StackTraceElement[] stackElements = ex.getStackTrace();
		if (stackElements != null) {
			for (int i = 0; i < stackElements.length; i++) {
				System.out.print(stackElements[i].getClassName()+"/t");
				System.out.print(stackElements[i].getFileName()+"/t");
				System.out.print(stackElements[i].getLineNumber()+"/t");
				System.out.println(stackElements[i].getMethodName());
				System.out.println("-----------------------------------");
			}
		}
	}
	
}

 

C#里面使用与java类似的方法,示例代码如下:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
namespace TestProjectCSharp
{
    class CallStack
    {
        public static void printCallStack()
        {
            StackTrace ss = new StackTrace(true);
            String flName = ss.GetFrame(1).GetFileName();// GetMethod().DeclaringType; 
            int lineNo = ss.GetFrame(1).GetFileLineNumber();
            String methodName = ss.GetFrame(1).GetMethod().Name;
            Console.WriteLine(flName+"---"+lineNo+"---"+methodName);
        }
    }
}

 

c里面获取堆栈跟系统有关(主要是获取函数名称不一致,获取地址是一致的),
linux下使用backtrace和backtrace_symbols函数,示例代码如下:(编译方法:gcc -o funstack -rdynamic -ldl funstack.c)


//funstack.c
#define _GNU_SOURCE
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#if defined(REG_RIP)
# define SIGSEGV_STACK_IA64
# define REGFORMAT "%016lx"
#elif defined(REG_EIP)
# define SIGSEGV_STACK_X86
# define REGFORMAT "%08x"
#else
# define SIGSEGV_STACK_GENERIC
# define REGFORMAT "%x"
#endif
static void signal_segv(int signum, siginfo_t* info, void*ptr) {
        static const char *si_codes[3] = {"", "SEGV_MAPERR", "SEGV_ACCERR"};
        size_t i;
        ucontext_t *ucontext = (ucontext_t*)ptr;
#if defined(SIGSEGV_STACK_X86) || defined(SIGSEGV_STACK_IA64)
        int f = 0;
        Dl_info dlinfo;
        void **bp = 0;
        void *ip = 0;
#else
        void *bt[20];
        char **strings;
        size_t sz;
#endif
#if defined(SIGSEGV_STACK_X86) || defined(SIGSEGV_STACK_IA64)
# if defined(SIGSEGV_STACK_IA64)
        ip = (void*)ucontext->uc_mcontext.gregs[REG_RIP];
        bp = (void**)ucontext->uc_mcontext.gregs[REG_RBP];
# elif defined(SIGSEGV_STACK_X86)
        ip = (void*)ucontext->uc_mcontext.gregs[REG_EIP];
        bp = (void**)ucontext->uc_mcontext.gregs[REG_EBP];
# endif
        fprintf(stderr, "Stack trace:/n");
        while(bp && ip) {
                if(!dladdr(ip, &dlinfo))
                        break;
                const char *symname = dlinfo.dli_sname;
                fprintf(stderr, "% 2d: %p %s+%u (%s)/n",
                                ++f,
                                ip,
                                symname,
                                (unsigned)(ip - dlinfo.dli_saddr),
                                dlinfo.dli_fname);
                if(dlinfo.dli_sname && !strcmp(dlinfo.dli_sname, "main"))
                        break;
                ip = bp[1];
                bp = (void**)bp[0];
        }
#else
        fprintf(stderr, "Stack trace (non-dedicated):/n");
        sz = backtrace(bt, 20);
        strings = backtrace_symbols(bt, sz);
        for(i = 0; i < sz; ++i)
                fprintf(stderr, "%s/n", strings[i]);
#endif
        fprintf(stderr, "End of stack trace/n");
        return;
}
int setup_sigsegv() {
        struct sigaction action;
        memset(&action, 0, sizeof(action));
        action.sa_sigaction = signal_segv;
        action.sa_flags = SA_SIGINFO;
        if(sigaction(SIGUSR1, &action, NULL) < 0) {
                perror("sigaction");
                return 0;
        }
        return 1;
}

void func1()
{
        raise(SIGUSR1);
        return ;
}
void func2()
{
        raise(SIGUSR1);
        return ;
}
void entry()
{
        func1();
        func2();
        return;
}
int main()
{
        setup_sigsegv();
        entry();
}

 

windows下使用GetThreadContext ,StackWalk,SymGetOptions ,SymFunctionTableAccess,示例代码如下:


#include "SimpleSymbolEngine.h"
#include 
#include 
#include 
#include 
#include 
#include 
#pragma comment( lib, "dbghelp" )
static char const szRCSID[] = "$Id: SimpleSymbolEngine.cpp,v 1.4 2005/05/04 21:52:05 Eleanor Exp $";
//////////////////////////////////////////////////////////////////////////////////////
// Singleton for the engine (SymInitialize doesn't support multiple calls)
SimpleSymbolEngine& SimpleSymbolEngine::instance()
{
static SimpleSymbolEngine theEngine;
    return theEngine;
}
/////////////////////////////////////////////////////////////////////////////////////
SimpleSymbolEngine::SimpleSymbolEngine()
{
    hProcess = GetCurrentProcess();
    DWORD dwOpts = SymGetOptions();
    dwOpts |= SYMOPT_LOAD_LINES | SYMOPT_DEFERRED_LOADS;
    SymSetOptions ( dwOpts );
    ::SymInitialize( hProcess, 0, true );
}
/////////////////////////////////////////////////////////////////////////////////////
SimpleSymbolEngine::~SimpleSymbolEngine()
{
    ::SymCleanup( hProcess );
}
/////////////////////////////////////////////////////////////////////////////////////
std::string SimpleSymbolEngine::addressToString( PVOID address )
{
    std::ostringstream oss;
    // First the raw address
    oss << "0x" <
MaxNameLength = sizeof( SymInfo ) – offsetof( tagSymInfo, symInfo.Name ); DWORD dwDisplacement; if ( SymGetSymFromAddr( hProcess, (DWORD)address, &dwDisplacement, pSym) ) { oss << ” ” <Name; if ( dwDisplacement != 0 ) oss << “+0x” << std::hex << dwDisplacement << std::dec; } // Finally any file/line number IMAGEHLP_LINE lineInfo = { sizeof( IMAGEHLP_LINE ) }; if ( SymGetLineFromAddr( hProcess, (DWORD)address, &dwDisplacement, &lineInfo ) ) { char const *pDelim = strrchr( lineInfo.FileName, ‘//’ ); oss << ” at ” << ( pDelim ? pDelim + 1 : lineInfo.FileName ) << “(” << lineInfo.LineNumber << “)”; } return oss.str(); } ///////////////////////////////////////////////////////////////////////////////////// // StackTrace: try to trace the stack to the given output void SimpleSymbolEngine::StackTrace( PCONTEXT pContext, std::ostream & os ) { os <Eip; stackFrame.AddrPC.Mode = AddrModeFlat; stackFrame.AddrFrame.Offset = pContext->Ebp; stackFrame.AddrFrame.Mode = AddrModeFlat; stackFrame.AddrStack.Offset = pContext->Esp; stackFrame.AddrStack.Mode = AddrModeFlat; while ( ::StackWalk( IMAGE_FILE_MACHINE_I386, hProcess, GetCurrentThread(), // this value doesn’t matter much if previous one is a real handle &stackFrame, pContext, NULL, ::SymFunctionTableAccess, ::SymGetModuleBase, NULL ) ) { os << ” 0x” << (PVOID) stackFrame.AddrFrame.Offset << ” ” << addressToString( (PVOID)stackFrame.AddrPC.Offset ) << “/n”; } os.flush(); }

 

完整的代码到http://www.howzatt.demon.co.uk/articles/SimpleSymbolEngine.zip下载。http://www.codeproject.com/KB/threads/StackWalker.aspx里面也有例子。

参考:

http://www.diybl.com/course/3_program/java/javashl/2008119/96739.html

http://topic.csdn.net/u/20090618/11/7c19832a-975e-4be6-987b-e61d789b31b5.html

http://bbs3.chinaunix.net/viewthread.php?tid=950357&extra=&page=2

http://www.codeproject.com/KB/threads/StackWalker.aspx

http://topic.csdn.net/u/20070515/21/fc3ebc11-b871-4761-90ae-3c6ddc7b4248.html

http://www.diybl.com/course/3_program/c++/cppjs/20090403/163752_2.html

http://accu.org/index.php/journals/276

http://blog.thepimp.net/archives/how-to-generate-backtraces-on-windows-without-compiler.html

———-淡定的分割线———-

codeproject的例子可以编译通过,但是运行报错。又找到第二个更简洁的可行例子。

原文地址:http://blog.csdn.net/jfyy/article/details/6759243


BOOL WINAPI StackWalk64(
    __in      DWORD MachineType,
    __in      HANDLE hProcess,
    __in      HANDLE hThread,
    __inout   LPSTACKFRAME64 StackFrame,
    __inout   PVOID ContextRecord,
    __in_opt  PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine,
    __in_opt  PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine,
    __in_opt  PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine,
    __in_opt  PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress
    );

而后将原文中的的方法简单做了修改和封装。

调用方法: vector CallStack::GetCallStack();

#include 
#include 
#include 
#include 

#define MAX_ADDRESS_LENGTH 32
#define MAX_NAME_LENGTH 1024
using namespace std;

struct CrashInfo
{
    char ErrorCode[MAX_ADDRESS_LENGTH];
    char Address[MAX_ADDRESS_LENGTH];
    char Flags[MAX_ADDRESS_LENGTH];
};

// CallStack信息
//
struct CallStackInfo
{
    char ModuleName[MAX_NAME_LENGTH];
    char MethodName[MAX_NAME_LENGTH];
    char FileName[MAX_NAME_LENGTH];
    char LineNumber[MAX_NAME_LENGTH];
};


class CallStack
{
public:
    CallStack(void);
    ~CallStack(void);
    static vector GetCallStack();

protected:
    static void SafeStrCpy(char* szDest, size_t nMaxDestSize, const char* szSrc);
    static vector GetCallStack(const CONTEXT *pContext);
    static CrashInfo GetCrashInfo(const EXCEPTION_RECORD *pRecord);
};


#include "StdAfx.h"
#include "CallStackInfo.h"


// 添加对dbghelp.lib的编译依赖   
//   
#pragma comment(lib, "dbghelp.lib")
#pragma once


CallStack::CallStack(void)
{
}

CallStack::~CallStack(void)
{
}

// 安全拷贝字符串函数
//   
void CallStack::SafeStrCpy(char* szDest, size_t nMaxDestSize, const char* szSrc)
{
    if (nMaxDestSize <= 0)
        return;
    if (strlen(szSrc) ExceptionAddress);
    sprintf_s(crashinfo.ErrorCode, "%08X", pRecord->ExceptionCode);
    sprintf_s(crashinfo.Flags, "%08X", pRecord->ExceptionFlags);

    return crashinfo;
}


vector CallStack::GetCallStack()
{
    CONTEXT context;
    HANDLE hThread = GetCurrentThread();

    // get context
    context.ContextFlags = (CONTEXT_FULL);
    if (GetThreadContext(hThread, &context))
    {
        return GetCallStack(&context);
    }
    else{
        vector arrCallStackInfo;
        return arrCallStackInfo;
    }

}

// 得到CallStack信息
//   
vector CallStack::GetCallStack(const CONTEXT *pContext)
{
    HANDLE hProcess = GetCurrentProcess();

    SymInitialize(hProcess, NULL, TRUE);

    vector arrCallStackInfo;

    CONTEXT c = *pContext;

    STACKFRAME64 sf;
    memset(&sf, 0, sizeof(STACKFRAME64));
    DWORD dwImageType = IMAGE_FILE_MACHINE_I386;

    // 不同的CPU类型,具体信息可查询MSDN
    //
#ifdef _M_IX86   
    sf.AddrPC.Offset = c.Eip;
    sf.AddrPC.Mode = AddrModeFlat;
    sf.AddrStack.Offset = c.Esp;
    sf.AddrStack.Mode = AddrModeFlat;
    sf.AddrFrame.Offset = c.Ebp;
    sf.AddrFrame.Mode = AddrModeFlat;
#elif _M_X64   
    dwImageType = IMAGE_FILE_MACHINE_AMD64;
    sf.AddrPC.Offset = c.Rip;
    sf.AddrPC.Mode = AddrModeFlat;
    sf.AddrFrame.Offset = c.Rsp;
    sf.AddrFrame.Mode = AddrModeFlat;
    sf.AddrStack.Offset = c.Rsp;
    sf.AddrStack.Mode = AddrModeFlat;
#elif _M_IA64   
    dwImageType = IMAGE_FILE_MACHINE_IA64;
    sf.AddrPC.Offset = c.StIIP;
    sf.AddrPC.Mode = AddrModeFlat;
    sf.AddrFrame.Offset = c.IntSp;
    sf.AddrFrame.Mode = AddrModeFlat;
    sf.AddrBStore.Offset = c.RsBSP;
    sf.AddrBStore.Mode = AddrModeFlat;
    sf.AddrStack.Offset = c.IntSp;
    sf.AddrStack.Mode = AddrModeFlat;
#else   
#error "Platform not supported!"
#endif   

    HANDLE hThread = GetCurrentThread();

    while (true)
    {
        // 该函数是实现这个功能的最重要的一个函数
        // 函数的用法以及参数和返回值的具体解释可以查询MSDN
        //   
        if (!StackWalk64(dwImageType, hProcess, hThread, &sf, &c, NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL))
        {
            break;
        }

        if (sf.AddrFrame.Offset == 0)
        {
            break;
        }

        CallStackInfo callstackinfo;
        SafeStrCpy(callstackinfo.MethodName, MAX_NAME_LENGTH, "N/A");
        SafeStrCpy(callstackinfo.FileName, MAX_NAME_LENGTH, "N/A");
        SafeStrCpy(callstackinfo.ModuleName, MAX_NAME_LENGTH, "N/A");
        SafeStrCpy(callstackinfo.LineNumber, MAX_NAME_LENGTH, "N/A");

        BYTE symbolBuffer[sizeof(IMAGEHLP_SYMBOL64)+MAX_NAME_LENGTH];
        IMAGEHLP_SYMBOL64 *pSymbol = (IMAGEHLP_SYMBOL64*)symbolBuffer;
        memset(pSymbol, 0, sizeof(IMAGEHLP_SYMBOL64)+MAX_NAME_LENGTH);

        pSymbol->SizeOfStruct = sizeof(symbolBuffer);
        pSymbol->MaxNameLength = MAX_NAME_LENGTH;

        DWORD symDisplacement = 0;

        BOOL bGetFileName = FALSE;
        // 得到函数名
        //   
        if (SymGetSymFromAddr64(hProcess, sf.AddrPC.Offset, NULL, pSymbol))
        {
            SafeStrCpy(callstackinfo.MethodName, MAX_NAME_LENGTH, pSymbol->Name);
        }

        IMAGEHLP_LINE64 lineInfo;
        memset(&lineInfo, 0, sizeof(IMAGEHLP_LINE64));

        lineInfo.SizeOfStruct = sizeof(IMAGEHLP_LINE64);

        DWORD dwLineDisplacement;

        // 得到文件名和所在的代码行
        //
        if (SymGetLineFromAddr64(hProcess, sf.AddrPC.Offset, &dwLineDisplacement, &lineInfo))
        {
            //该类本身不需要记载
            if (strcmp(lineInfo.FileName, __FILE__))
                bGetFileName = TRUE;

            SafeStrCpy(callstackinfo.FileName, MAX_NAME_LENGTH, lineInfo.FileName);
            sprintf_s(callstackinfo.LineNumber, "%d", lineInfo.LineNumber);//后文中有改动——亦忧
        }

        IMAGEHLP_MODULE64 moduleInfo;
        memset(&moduleInfo, 0, sizeof(IMAGEHLP_MODULE64));

        moduleInfo.SizeOfStruct = sizeof(IMAGEHLP_MODULE64);

        // 得到模块名
        //
        if (SymGetModuleInfo64(hProcess, sf.AddrPC.Offset, &moduleInfo))
        {
            SafeStrCpy(callstackinfo.ModuleName, MAX_NAME_LENGTH, moduleInfo.ModuleName);
        }

        if (bGetFileName)
            arrCallStackInfo.push_back(callstackinfo);
    }

    SymCleanup(hProcess);

    return arrCallStackInfo;
}

 

———-淡定的分割线———-

运行发现除了调用堆栈的行号除了第一句外,其他都不准确。http://www.codeproject.com/KB/threads/StackWalker.aspx的例子讨论中有解决方法。


This is solvable as follows:
 
Add this to the StackWalkerInternal

//pSGLFA != NULL )
    { // yes, we have SymGetLineFromAddr64()
        if (this->pSGLFA(hProcess, dwAddr, pdwDisplacement, pLine) != FALSE)
        {
            csEntry.lineNumber = pLine->LineNumber;
            // TODO: Mache dies sicher...!
            strcpy_s(csEntry.lineFileName, sizeof(csEntry.lineFileName), pLine->FileName);
            success = TRUE;
        }
        else
        {
            this->m_parent->OnDbgHelpErr("SymGetLineFromAddr64", GetLastError(), dwAddr);
        }
    } // yes, we have SymGetLineFromAddr64()
    return success;
}
//pSGLFA != NULL )
    { // yes, we have SymGetLineFromAddr64()
        if (this->pSGLFA(hProcess, dwAddr, pdwDisplacement, pLine) != FALSE)
        {
            csEntry.lineNumber = pLine->LineNumber;
            // TODO: Mache dies sicher...!
            strcpy_s(csEntry.lineFileName, sizeof(csEntry.lineFileName), pLine->FileName);
            success = TRUE;
        }
        else
        {
            this->m_parent->OnDbgHelpErr("SymGetLineFromAddr64", GetLastError(), dwAddr);
        }
    } // yes, we have SymGetLineFromAddr64()

NEW:

    if (this->m_sw->FindLine(this->m_hProcess, s.AddrPC.Offset, &(csEntry.offsetFromLine), &Line, csEntry))
    {
        this->m_sw->FindPreviousLine(this->m_hProcess, s.AddrPC.Offset, &(csEntry.offsetFromLine), &Line, csEntry);	// ignore return status
    }

 

再次测试发现,应该除去第一次的情况。即调用堆栈第一句不适合FindPreviousLine。结合几家所言,终于完美了。

第二个例子获得文件名和行号的部分改为以下:


        if (SymGetLineFromAddr64(hProcess, sf.AddrPC.Offset, &dwLineDisplacement, &lineInfo))
        {
            SafeStrCpy(callstackinfo.FileName, MAX_NAME_LENGTH, lineInfo.FileName);

            // Get correct line number including return status
            if (arrCallStackInfo.size() > 0)
            {
                DWORD64 qwAddr = sf.AddrPC.Offset;
                DWORD pdwDisplacement = dwLineDisplacement;
                IMAGEHLP_LINE64 Line64 = lineInfo;
                DWORD nextLine = lineInfo.LineNumber;
                BOOL bOk = FALSE;
                do
                {
                    --qwAddr;
                    bOk = SymGetLineFromAddr64(hProcess, qwAddr, &pdwDisplacement, &lineInfo);
                } while (bOk && (nextLine == lineInfo.LineNumber));
                if (!bOk)
                {
                    dwLineDisplacement = pdwDisplacement;
                    lineInfo = Line64;
                }
            }

            sprintf_s(callstackinfo.LineNumber, "%d", lineInfo.LineNumber);
        }

 

Ubuntu学习笔记100-Wine安装MSI程序包

Trackback: http://wiki.winehq.org/msiexec

wine msiexec /i msxml3.msi

Install a product:
msiexec {package|productcode} [property]
msiexec /i {package|productcode} [property]
msiexec /a package [property]
Repair an installation:
msiexec /f[p|o|e|d|c|a|u|m|s|v] {package|productcode}
Uninstall a product:
msiexec /x {package|productcode} [property]
Advertise a product:
msiexec /j[u|m] package [/t transform] [/g languageid]
msiexec {u|m} package [/t transform] [/g languageid]
Apply a patch:
msiexec /p patchpackage [property]
msiexec /p patchpackage /a package [property]
Modifiers for above operations:
msiexec /l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile
msiexec /q{|n|b|r|f|n+|b+|b-}
Register a module:
msiexec /y module
Unregister a module:
msiexec /z module
Display usage and copyright:
msiexec {/h|/?}

Howto: Using wxSocket in a secondary thread

Trackback:  http://www.litwindow.com/Knowhow/wxSocket/wxsocket.html

Howto: Using wxSocket in a secondary thread.

If you have tried this, you will have stumbled across the following problem(s):

100% CPU usage by wxWidgets application
All socket operations such as Read/Write time out.
Things work if you put them in the main thread.

Note: This information is valid for wxMSW (Microsoft Windows Platforms).

I have not tested this on Linux or other platforms.

To use wxSockets in a secondary thread, you must

call wxSocketBase::Initialize from the main thread before creating any sockets. The best place to do this is in wxApp::OnInit.
make sure that the main thread is running always. Do not sleep or use semaphores to block the main thread.

Here is a little background: This is an excerpt from my post on wx-users…

for wxWidgetsMSW (which also explains the
odd requirement to call wxSocketBase::Initialize in the main thread):
When Initialize is called for the first time, it creates a hidden
window. Socket operations do not block. Instead they use an
asynchronous model. All internal socket operation will return
immediately. When a write is completed, the OS will send a windows
message to the window created by Initialize.

What happens in your case is:

a) If you don’t call Initialize in the main thread, the window will be
created in the secondary thread, which under wxWidgets has no message
loop. The main message loop will only handle windows created in the
main thread. So the events sent to this window will get lost.

b) If you do call Initialize in the main thread: When you call Write
in a secondary thread, the wxWidgets socket code waits in a busy loop.
It will call write once and then call a ‘getstatus’ method which loops
until an internal flag has been set. The code looks somewhat like:

while (!flag) {
sleep(0); // give up timeslice
}

If you block the main thread with sleep or wxCondition, the event sent
by the operating system cannot be processed and will never reach the
hidden socket sink window and so cannot set the flag.

It is my impression that the socket classes seem to be not very well
integrated into wxWidgets and – at least in part – not very well
written. IMHO busy loops really should be avoided.

从Amazon Cloud Reader导出离线电子书

原文地址:http://sakinijino.com/archives/4022

功能:通过Amazon Cloud Reader,获得已购买书籍的原文。

步骤:

访问 https://read.amazon.com/
右键想获得原文的书,选择Download & Pin
等待下载结束,书上出现绿色别针
点击进入阅读
打开链接。把其中文本复制到Amazon Reader的地址栏中
(Safari下过;但在Chrome下测试出现诡异的错误。如果Chrome没效果,可以按F12进入Console Tab,把“javascript:”后面的部分粘贴到命令行中)
等一会儿,然后Ctrl-A & Ctrl-C
回馈社会

原理:Kindle Reader用了localStorage database来存储Pin到本地书籍,这些数据库中的内容除了被lz压缩外,没有特殊处理,所以只要把数据取出来解压缩即可。

不足:不能获得图片(图片也是被放进database的,实现起来不难,只是我懒得改了);文本是带html标签的,直接贴到支持html标签的编辑器中可能会出问题。

原文源代码


(function (){
function getContent(cb){
  function getAsin(cb){
    var title = $("#KindleReaderIFrame")[0].contentWindow.document.getElementById("kindleReader_title").innerHTML;
    KindleDBClient.getAppDb().getTable('bookdata').getRecord({title:title}).done(function(e){cb(e[0].asin)});
  };
  function getF(asin, cb){
    var bookdb =$("#KindleReaderIFrame")[0].contentWindow.KindleReaderBookInfoProviderDB.BookInfoDB(asin);
    bookdb.getFragmentIds().done(function(e){
      bookdb.getFragments(e).done(cb);
    })
  };
  function getMD(asin, cb){KindleDBClient.getBookDb().getTable("bookinfo").getRecord({asin:asin}).done(function(e){cb(e[0].metadata)})};

  getAsin(function(asin){
  getF(asin, function(fragments){
  getMD(asin, function(md){
    var kc = $("#KindleReaderIFrame")[0].contentWindow.KindleCompression;
    c = {};
    kc.lzAddStringsToDictionary(md.cpr, c);
    kc.lzAddNumbersToDictionary(c);
    d = kc.lzGetDecompressionDictionary(c);
    content = "";
    for (var i=0; i<fragments.length; ++i)
      if (fragments[i]) content += kc.lzExpandWithStaticDictionary(fragments[i].fragmentData, d, 256);
    cb(content);
  })})})
};
getContent(function(c){document.body.innerHTML = c});
})();

以下为亦忧更新部分:

在Chrome中运行,有的书会报错。Uncaught TypeError: Cannot read property ‘asin’ of undefined。找了下原因。

有的书网页上的书名和缓存数据库中的书名不匹配,导致代码第四行title在数据库查询中返回空对象undefined。

修正:
1、Chrome中按ctrl+shift+j,进入开发模式。Resources下找到Databases>K4W>bookdata,将title列中的值替换第四行代码。即:
var title = $(“#KindleReaderIFrame”)[0].contentWindow.document.getElementById(“kindleReader_title”).innerHTML;
改为
var title = “Robin Nixon’s PHP Crash Course: Learn PHP in 14 easy lessons”;(比如这本书)

Chrome可以直接保存文件为完整的HTML。默认滚动条会被隐藏。用文本编辑器打开保存的文件,去掉头上没用的HTML标签,就可以方便阅读了。

继续更新:

2、发现下载有的书出现第二个错误,Uncaught TypeError: Object [object Window] has no method ‘getBookDb’。将第8行代码修改了一下。即:
var bookdb =$(“#KindleReaderIFrame”)[0].contentWindow.KindleReaderBookInfoProviderDB.BookInfoDB(asin);
改为
var bookdb = KindleDBClient.getBookDb().BookInfoDB(asin);

3、又发现第三个错误,TypeError: Object # has no method ‘getAppDb’。查了一下KindleDBClient的值似乎丢失了,找不到相应的函数调用。简单的解决方法:将KindleDBClient替换为KindleModuleManager.getModuleSync(KindleModuleManager.DB_CLIENT)

20140605更新:
4、发现#2号更新失效,再次改为:
var bookdb = KindleModuleManager.getModuleSync(KindleModuleManager.DB_CLIENT).getBookDb().BookInfoDB(asin);

修改后的代码如下:


(function (){
function getContent(cb){
  function getAsin(cb){
    var title = $("#KindleReaderIFrame")[0].contentWindow.document.getElementById("kindleReader_title").innerHTML;
    KindleModuleManager.getModuleSync(KindleModuleManager.DB_CLIENT).getAppDb().getTable('bookdata').getRecord({title:title}).done(function(e){cb(e[0].asin)});
  };
  function getF(asin, cb){
    var bookdb = KindleModuleManager.getModuleSync(KindleModuleManager.DB_CLIENT).getBookDb().BookInfoDB(asin);
    bookdb.getFragmentIds().done(function(e){
      bookdb.getFragments(e).done(cb);
    })
  };
  function getMD(asin, cb){KindleModuleManager.getModuleSync(KindleModuleManager.DB_CLIENT).getBookDb().getTable("bookinfo").getRecord({asin:asin}).done(function(e){cb(e[0].metadata)})};

  getAsin(function(asin){
  getF(asin, function(fragments){
  getMD(asin, function(md){
    var kc = $("#KindleReaderIFrame")[0].contentWindow.KindleCompression;
    c = {};
    kc.lzAddStringsToDictionary(md.cpr, c);
    kc.lzAddNumbersToDictionary(c);
    d = kc.lzGetDecompressionDictionary(c);
    content = "";
    for (var i=0; i<fragments.length; ++i)
      if (fragments[i]) content += kc.lzExpandWithStaticDictionary(fragments[i].fragmentData, d, 256);
    cb(content);
  })})})
};
getContent(function(c){document.body.innerHTML = c});
})();

Best Audio Format for iPhone Audio Programming

Trackback: http://www.totodotnet.net/tag/avaudiorecorder/

I had never done audio programming before I started my iPhone programming. After starting iPhone programming, I started to learn CoreAudio Framework, Audio Unit for Mac OS X system and iPhone System, and largest problem is which audio format should I choose for best practice?

After iPhone OS 3.0 beta was released, Apple finally introduced AVAudioRecorder class to AVFoundation framework. With which, we can play and record audio more efficiently! For me, I can cut the original playback code down from 400+ lines to 20 lines. And for recording, cut down from 300+ lines to 30 lines.

When testing AVAudioRecorder, the file format will significantly effect the file size. I had tried all the available data format when packed with .CAF file.  Here is the result:

[Updated@2009-05-25] YES, we can record with this format on simulator, but we CANNOT record this on the device! Remember this. While another one we can refer to is Apple’s official QA1615

[Updated@2009-06-15] Please do not use AAC if you want to play a system sound.

[Updated@2009-09-30] iPhone 3GS support AAC recording since iPhone OS 3.1 was released on Sept 9th. You can use hardware assisted encoding to record the AAC formatted audio file. But let me remind you, you can not use AVAudioRecord to record AAC audio file yet. The only option is using the RemoteIO Unit.

  • kAudioFormatLinearPCM               = ‘lpcm’,    OK    20.2M    .CAF
  • kAudioFormatAppleIMA4               = ‘ima4′,    OK    2.7M     .CAF [Best Choice]
  • kAudioFormatMPEG4AAC                = ‘aac ‘,    OK    968K     .CAF [Updated 2009-05-25], [Updated 2009-09-30] Best Choice for iPhone 3GS
  • kAudioFormatMACE3                   = ‘MAC3′,    NG            .CAF
  • kAudioFormatMACE6                   = ‘MAC6′,    NG            .CAF
  • kAudioFormatULaw                    = ‘ulaw’,    OK    5.1M     .CAF
  • kAudioFormatALaw                    = ‘alaw’,    OK    5.1M     .CAF
  • kAudioFormatQDesign                 = ‘QDMC’,    NG            .CAF
  • kAudioFormatQDesign2                = ‘QDM2′,    NG            .CAF
  • kAudioFormatQUALCOMM                = ‘Qclp’,    NG            .CAF
  • kAudioFormatMPEGLayer1              = ‘.mp1′,    NG            .CAF
  • kAudioFormatMPEGLayer2              = ‘.mp2′,    NG            .CAF
  • kAudioFormatMPEGLayer3              = ‘.mp3′,    NG            .CAF
  • kAudioFormatAppleLossless           = ‘alac’        OK    4M        .CAF
  • kAudioFormatMPEG4AAC_LD             = ‘aacl’,    NG            .CAF
  • kAudioFormatAMR                     = ‘samr’,    NG            .CAF
  • kAudioFormatiLBC                    = ‘ilbc’,    NG    Wierd    .CAF

The list here has omitted all the other data format that are not supported by CAF file extension. You can use the console application afconvert to verify each supported file format and data format via typing this:

afconvert -h

All the tests were recorded in 60 seconds, with sample rate@44100, 2 channels, 96kbps. The RecordSetting Dictionary object is used as below:

recordSetting = [[NSMutableDictionary alloc] init];

//General Audio Format Settings (Necessary for all audio format.)
[recordSetting setValue:[NSNumber numberWithInt: kAudioFormatMPEG4AACkAudioFormatAppleIMA4] forKey:AVFormatIDKey];
[recordSetting setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey];
[recordSetting setValue:[NSNumber numberWithInt: 2] forKey:AVNumberOfChannelsKey];

//Linear PCM Format Settings (only necessary when you want to record Liner PCM format)
[recordSetting setValue:[NSNumber numberWithInt: 32] forKey:AVLinearPCMBitDepthKey];
[recordSetting setValue:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey];
[recordSetting setValue:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsFloatKey];

//Encoder Settings (Only necessary if you want to change it.)
[recordSetting setValue:[NSNumber numberWithInt:AVAudioQualityMin] forKey:AVEncoderAudioQualityKey];
[recordSetting setValue:[NSNumber numberWithInt:96] forKey:AVEncoderBitRateKey];
[recordSetting setValue:[NSNumber numberWithInt:16] forKey:AVEncoderBitDepthHintKey];

//Sample Rate Conversion Settings (Only necessary when you want to change the sample rate to a value different to the hardware sample rate, AVAudioQualityHigh means no conversion, usually, 44.1KHz)
[recordSetting setValue:[NSNumber numberWithInt:AVAudioQualityHigh] forKey:AVSampleRateConverterAudioQualityKey];

[Updated 2009-09-30], The record settings listed above was for example only, if you want to record IMA4 or other compressed audio format, you are no need to put the Liner PCM part. Other parts are commented for their purpose.

You can see, the MPEG4AAC has the minimum file size and same quality when compare to other file formats. About the AAC format, please refer to [Wikipedia – AAC”]

Apple, you could just give us a best practice guide! So I won’t need to test it one by one myself. OK, I know, you are working out of people, hire me, I would love to do these works.