Welcome to the PeekIt PlugIn SDK version 1.0.0
Download SDK
Why Plugins?
PeekIt only supports a few basic data types in it's data formatter section,
the ability to build larger structures from those data types seemed to be enough
when we first designed the feature. We Were Wrong. People have asked for many
other types. And one person even said "why not just make plugins for new
data types?" He
was a smart guy, so we did what he said.
The universe of data types is huge, and we're never going to support all of them. Covering all the IEEE types alone would be a major effort, much less custom data types you use, and would keep us from adding new features. The answer? Create a plugin model where other smart people could create data formatters that augment what PeekIt has, allowing for a near limitless number of data types that can be presented. The goal is to present data in a human-readable form. Some file data is a particular thing, an IEEE 64 bit float, a number of U.S. dollars, a weight. Presenting this value as the end goal, instead of the raw bytes, can really help someone interprete a file more quickly and effectively.
Our hope is that many formatter plugins will be created. We'll highlight them on Ravenware.com on the new PeekIt Plugins page. See that page for submission guidelines if you want to share a plugin.
Data Formatter Plugin operation overview
Implementation
Download and examine the sample plugin. It's simple enough, but full
featured, and should provide most of the information you need to build a plugin.
Formatter plugins are Mac OS X bundles (see ADC's Bundle
Programming documentation). The key things that PeekIt extracts from the
bundle is the list of plist keys describing the plugin, and entry points
for two functions PeekIt will call. All PeekIt formatter plugins have the extension
.PIFormPlug. If you don't use that extension then PeekIt will
normally not be able to use the plugin.
Note: Plugins are managed by name, the name in the plist. If there are multiple plugins with the same plist name, PeekIt will use the last one loaded. Yes, this could be a problem if people make duplicate named plugins. I'm not going to worry about that (and write the code to manage it) until I get a report of it happening. Yes, that's lazy, but I don't even know if anyone is going to write any plugins, much less conflicting ones, so I'm not going to.
Info.plist Entries
The info.plist provides information PeekIt needs without having to query
your plugin programtically. Easier to maintain, easier to read. The info.plist
information that PeekIt relies on are the following keys. The keys are defined
in PeekitFormatterPlugIn.h.
If a key value is not in the plist file, the default
value will be used.
kPIFormandDrawFuncNameKey ("PeekItFormatterFormatAndDrawFunc")
-
Name of the function that will format a data string and return a text buffer.
PeekIt will use CFBundleGetFunctionPointerForName to extract this
entry point from your bundle and call it. Either this or the kPIFormatFuncNameKey must
exist or your plugin will be ignored.
kPIFormatFuncNameKey ("PeekItFormatterFormatFunc")
- Name of the function that will format a data string and return a text buffer.
PeekIt will use CFBundleGetFunctionPointerForName to extract this
entry point from your bundle and call it. Either
this or the kPIFormandDrawFuncNameKey must exist or your plugin will
be ignored.
kPIPeekItFormatterName ("PeekItFormatterName")
- Name of this formatter required. Should be a
single line of text. No default, your plugin will be rejected without a name
kPIAuthorNameKey ("PeekItAuthorName")
- Name of the author of this plugin. Displayed in the Formatter Info pane.
Should be a single line of text. Defaults to "unknown".
kPIAuthorOrganizationKey ("PeekItOrganizationName")
- Group, company, team, or other organization that the author of this plugin
is affiliated with. Should
be a single line of text. Defaults to "unknown".
kPIAuthorEmailKey ("PeekItAuthorEmail")
- Contact email for theis plugin.
Should
be a single line of text. Defaults to "unknown".
kPIPeekItAuthorWebsiteKey ("PeekItAuthorWebsite")
- Web site for more information or other information the author would like
to present. Should
be a single line of text. Defaults to "unknown".
kPIFormatterDesc ("PeekItFormatterDesc")
- Description of the operation of this formatter. Can be a short paragraph.
Defaults to "unknown".
kPIFormatterBytesConsumed ("PeekItFormatterBytesConsumed")
- How many bytes this formatter needs, or -1 if data defined. Defaults to
-1.
kPIFormatterLinesNeeded ("PeekItFormatterLinesNeeded")
- Number of lines needed. Lines is defined as (textSize + 2). Defaults to
1.
The only key that must be present is the kPIPeekItFormatterName key. And, of course, at least one of the two function entry points. PeekIt manages plugins by the text of the kPIPeekItFormatterName key, it must be there or PeekIt will reject the plugin. All the others are optional, though we recommend you use all of them to provide our mutual users with the best experience.
The kPIPeekItFormatterName must also be unique, if PeekIt finds two (or more) plugins with the same kPIPeekItFormatterName key, it will default to using the first one it finds. Use a descriptive name, look at other formatters inside PeekIt (or jsut look at their plist files) to make sure they don't have the name you'd like.
Functions to provide
Each plugin can provide two functions, and must provide at least one.
The first takes file data, converts into the appropriate formatting,and draws
it into the gaphics context provided. The second takes file data and passes
a buffer back that holds a text string of the value.
One of these functions must exist, or the plugin is ignored. If only one function
is provided, then of course only that one is used. If both fuctions are provided,
PeekIt will use the Draw function. However, future versions of PeekIt will
change this, there will be times
in the future where both functions will be called on the same file data. Make
no assumptions inside your formatting fuctions about who will be called when,
or where your results are being presented.
You can return kPIFDisableThisFunction at any point, and the
function will no longer be called.
If you have a Format and Draw function and
a Format-only fuction, the Draw function is being called. If the Draw function
returns kPIFDisableThisFunction
PeekIt will stop calling the Draw fuction and switch to the Format-only
function for future calls. If the Format-only function subsequently returns kPIFDisableThisFunction
then PeekIt will stop calling your plugin completely, until next launch.
If you provide both functions you can also return kPIFRotateFunctions, this will tell PeekIt to stop using the current function and use the other. The term rotate is used instead of alternate for future compatability where there may be more than two functions.
The first function takes a string of hex bytes, converts them to the appropriate text representation internally, then draws the result into the Core Graphics context provided in the rectangle provided. Please only use Core Graphics drawing, QuickDraw is not supported. If we can go to Core Graphics after 20 years of QuickDraw, so can you.
OSStatus SampleNameFormatAndDrawThisByteString(const Ptr inputByteStream,UInt16 numberBytesProvided,UInt32 *bytesConsumed,CGContextRef theCGContext, HIRect rect,UInt32 flags)
Ptr inputByteStream - The stream of bytes to convert.
If you specify a consumed number in kPIFormatterBytesConsumed plist key ,
then this byte stream will only contain that many bytes or less.
If you specified a variable-length byte stream then this byte stream will contain
up to 1024 bytes. It will be LESS than 1024 if there are less than 1024 bytes
left in the file. Note that this pointer does not point to actual file
data, this is a copy handed to you that will be freed as soon as your function
returns.
UInt16 numberBytesProvided - number of bytes provided for
conversion.
Also indicates the length of the data stream provided in inputByteStream.
UInt32 *bytesConsumed - Pointer to an unsigned long containing
the number of buffer bytes you used to format the data
CGContextRef theCGContext
The graphics context to draw into. Set to PeekIt standard font size and colors.
Context has been saved before your function was called, and will be restored
to that state after your function returns.
HIRect rec
Rectangle that you can draw into, do not exceed the bounds of that
rectangle.
UInt32 flags
Various informational flags, see PeekitFormatterPlugIn.h for the latest
information.
The next function takes a string of hex bytes, converts them to the appropriate
text representation, and returns that text string to PeekIt for display. Make
no assumptions about graphic states or application state when this function
is called, PeekIt will call this function at times other than
window drawing times.
OSStatus SampleNameFormatThisByteString(const Ptr inputByteStream,UInt16
numberBytesProvided,Ptr *outputTextStream,UInt16 *outputTextStreamLen,UInt32
*bytesConsumed,UInt32 flags)
Ptr inputByteStream - The stream of bytes to convert.
If you specify a consumed number in kPIFormatterBytesConsumed plist
key ,
then this byte stream will only contain that many bytes or less.
If you specified a variable-length byte stream then this byte stream will
contain up to 1024 bytes. It will be LESS than 1024 if there are less than
1024 bytes left in the file. Note that this pointer does not point
to actual file data, this is a copy handed to you that will be freed as soon
as your function returns.
UInt16 numberBytesProvided - number of bytes provided for conversion.
Also indicates the length of the data stream provided in inputByteStream.
Ptr *outputTextStream - A pointer to the location where you should place
the text stream result of formatting.
This must be a pointer created by your routine with malloc. PeekIt WILL
dispose of this pointer at some point. This must be a string of ASCII/UTF-8
characters, no count word and no termination byte.
UInt16 *outputStreamLen - A pointer to a location where you place the length
of the text returned in outputTextStream
UInt32 *bytesConsumed - Pointer to an unsigned long containing the number
of buffer bytes you used to format the data
UInt32 flags
Various informational flags, see PeekitFormatterPlugIn.h for the latest information.
PlugIn Return values
noErr (0)
The normal return value.
kPIFDisableThisFunction
Return kPIFDisableThisFunction if you would like PeekIt to stop calling
this fuction. If this is the only function your plugin provides, or you've
previously disabled the other fuction, returning this value will disable
your plugin completely until PeekIt is quit and relaunched.
kPIFExpandDrawingArea, Only accepted as a return value
from FPIPluginFormatAndDrawThisByteString
kPIFExpandDrawingArea will add one line height to the rectangle you are
able to draw in . PeekIt will assume that you have NOT drawn anything yet,
will expand the drawing area and call your function again so you can draw.
This of course means that you can continue to return kPIFExpandDrawingArea
until you have enough space to draw. The drawing area line height is set to
this new height for all subsequent calls to your plugin until PeekIt is launched
again, or you resize the height by passing other return values back in the
future.
You MUST monitor the flag word passed in to your function!
If the flag kPIFUnableToResizeDrawingArea is passed in, that means that PeekIt
is unable to expand or compress the drawing any further and you MUST do your
best to draw something, you will not be called again for this particular
file position no matter
what you return. This is NOT static, the next time your function is
called the drawing area may again be resizable, just be certain to check the
flag.
kPIFCompressDrawingArea, Only accepted as a return value
from FPIPluginFormatAndDrawThisByteString
kPIFCompressDrawingArea will subtract one line height to the rectangle you
are able to draw in PeekIt will assume that you have NOT drawn anything yet,
will compress the drawing area and call your function again so you can draw.
This of course means that you can continue to return kPIFCompressDrawingArea
until you have enough space to draw.
You MUST monitor the flag word passed in to your function!
If the flag kPIFUnableToResizeDrawingArea is passed in, that means that
PeekIt is unable to expand or compress the drawing any further and you MUST
do your best to draw something, you will not be called again for this particular
file position no matter what you return. This is NOT static, the next time
your function is called the drawing area may again be resizable, just be certain
to check the flag.
kPIFRotateFunctions
kPIFRotateFunction can be returned from either function and tells PeekIt to stop
using this function and switch to the other function. Ignored if your plugin
only maintains one function. Similar to the drawing resize return codes, PeekIt
will assume that you have not done any drawing or formatting,
and will immediately call your alternate function with the current file data.
The term rotate is used instead of alternate for future compatability
where there may be more than two functions. You can only rotate functions once
for a data value to prevent inadvertent infinite looping. If this is a problem,
send us an email and explain why it would be useful to switch multiple times.
Keep in mind that switching once, with the subsequent re-call, allows both functions
to be called for every value.
Code Implementation
PeekIt is a straight C, Carbon application built with gcc version
4.0 or later. I have not, and will not, test other versions of gcc, thought
they probably will work.Your functions are entered as straight C. What
you do inside your plugin is up to you, just don't expect anything to be
readied except Carbon frameworks, and don't assume there is any C++
exception handling or Objective-C runtime, or other non-straight C facilities
present. And longjmps are right out.....
Other Details
If you have a plugin you think people might be interested in, put it in a
.zip archive and email it to pifplugins
at ravenware.com . I will post it to the Ravenware site. We reserve the
right to refuse posting of any plugin, and the right to remove any plugin from
the site, with no notice and no reason given.
Providing source code of course
will make it more interesting to people.
There is no support, debugging, or additional guidance available for building PeekIt formatter plugins. Please report bugs, that's the best support mechanism, and check this page occasionally for updates.
Documentation written by Alex Kinnison.
Copyright 2006 Ravenware Industries, LLC