#ifndef CODEFRAGMENTS_H
#define CODEFRAGMENTS_H

#ifndef MACTYPES_H
#include <CarbonCore/MacTypes.h>
#endif


#ifndef CFBUNDLE_H
#include <CoreFoundation/CFBundle.h>
#endif

#ifndef FILES_H
#include <CarbonCore/Files.h>
#endif

#ifndef MULTIPROCESSING_H
#include <CarbonCore/Multiprocessing.h>
#endif




#include <AvailabilityMacros.h>

#if PRAGMA_ONCE
#pragma once
#endif

#ifdef __cplusplus
extern "C" {
#endif

/*kCFragResourceType


enum {
   kCFragResourceType = 'cfrg',
   kCFragResourceID = 0,
   kCFragLibraryFileType = 'shlb',
   kCFragAllFileTypes = 0xFFFFFFFF
};
Constants
kCFragResourceType

Available in Mac OS X v10.0 and later.
kCFragResourceID

Available in Mac OS X v10.0 and later.
kCFragLibraryFileType

Available in Mac OS X v10.0 and later.
kCFragAllFileTypes

Available in Mac OS X v10.0 and later.*/

enum {
   kCFragResourceType = 'cfrg',
   kCFragResourceID = 0,
   kCFragLibraryFileType = 'shlb',
   kCFragAllFileTypes = 0xFFFFFFFF
};


/*kCompiledCFragArch


enum {
   kCompiledCFragArch = 'kPowerPCCFragArch'
};
Constants
kCompiledCFragArch

The value for this constant is 'kPowerPCCFragArch' if you have defined TARGET_CPU_PPC. If you define TARGET_CPU_X86, then the value of this constant is 'none'

Available in Mac OS X v10.0 and later.*/

enum {
   kCompiledCFragArch = 'kPowerPCCFragArch'
};



/*Symbol Class Constants


typedef UInt8 CFragSymbolClass;
enum {
   kCodeCFragSymbol = 0,
   kDataCFragSymbol = 1,
   kTVectorCFragSymbol = 2,
   kTOCCFragSymbol = 3,
   kGlueCFragSymbol = 4
};
Constants
kCodeCFragSymbol

Available in Mac OS X v10.0 and later.
kDataCFragSymbol

Available in Mac OS X v10.0 and later.
kTVectorCFragSymbol

Available in Mac OS X v10.0 and later.
kTOCCFragSymbol

Available in Mac OS X v10.0 and later.
kGlueCFragSymbol

Available in Mac OS X v10.0 and later.*/

typedef UInt8 CFragSymbolClass;
enum {
   kCodeCFragSymbol = 0,
   kDataCFragSymbol = 1,
   kTVectorCFragSymbol = 2,
   kTOCCFragSymbol = 3,
   kGlueCFragSymbol = 4
};

/*Unresolved Symbol Address


enum {
   kUnresolvedCFragSymbolAddress = 0
};
Constants
kUnresolvedCFragSymbolAddress

Available in Mac OS X v10.0 and later.*/
enum {
   kUnresolvedCFragSymbolAddress = 0
};


/*CFragSystem7DiskFlatLocator

Defines a disk location structure.

struct CFragSystem7DiskFlatLocator {
   FSSpec * fileSpec;
   UInt32 offset;
   UInt32 length;
};
typedef struct CFragSystem7DiskFlatLocator CFragSystem7DiskFlatLocator;
typedef CFragSystem7DiskFlatLocator DiskFragment;
Fields
fileSpec

A pointer to a file specification structure (a data structure of type FSSpec) for the data fork of a file. This pointer is valid only while the initialization function is executing. If you need to access the information in the file specification structure at any later time, you must make a copy of that structure. 
offset

The offset, in bytes, from the beginning of the file’s data fork to the beginning of the fragment.
length

The length, in bytes, of the fragment. If this field contains the value 0, the fragment extends to the end-of-file.
Discussion

For fragments located in the data fork of a file on disk, the onDisk field of a fragment location structure contains a disk location structure, which specifies the location of the fragment.

The fields of a fragment initialization block are aligned in memory in accordance with 680x0 alignment conventions. 
Availability
Available in Mac OS X v10.0 and later.*/
struct CFragSystem7DiskFlatLocator {
   FSSpec * fileSpec;
   UInt32 offset;
   UInt32 length;
};
typedef struct CFragSystem7DiskFlatLocator CFragSystem7DiskFlatLocator;
typedef CFragSystem7DiskFlatLocator DiskFragment;

/*CFragConnectionID


typedef struct OpaqueCFragConnectionID * CFragConnectionID;
Availability
Available in Mac OS X v10.0 and later.*/

typedef struct OpaqueCFragConnectionID * CFragConnectionID;

/*CFragContextID


typedef MPProcessID CFragContextID;
Availability
Available in Mac OS X v10.0 and later.*/
typedef MPProcessID CFragContextID;

/*CFragClosureID


typedef struct OpaqueCFragClosureID * CFragClosureID;
Availability
Available in Mac OS X v10.0 and later.*/
typedef struct OpaqueCFragClosureID * CFragClosureID;

/*CFragCFBundleLocator


struct CFragCFBundleLocator {
   CFBundleRef fragmentBundle;
   UInt32 offset;
   UInt32 length;
};
typedef struct CFragCFBundleLocator CFragCFBundleLocator;
Fields
fragmentBundle
offset
length
Availability
Available in Mac OS X v10.0 and later.*/

struct CFragCFBundleLocator {
   CFBundleRef fragmentBundle;
   UInt32 offset;
   UInt32 length;
};
typedef struct CFragCFBundleLocator CFragCFBundleLocator;

/*CFragSystem7SegmentedLocator

Defines a segment location structure.

struct CFragSystem7SegmentedLocator {
   FSSpec * fileSpec;
   OSType rsrcType;
   SInt16 rsrcID;
   UInt16 reservedA;
};
typedef struct CFragSystem7SegmentedLocator CFragSystem7SegmentedLocator;
typedef CFragSystem7SegmentedLocator SegmentedFragment;
Fields
fileSpec

A pointer to a file specification structure (a data structure of type FSSpec) for the resource fork of a file. This pointer is valid only while the initialization function is executing. If you need to access the information in the file specification structure at any later time, you must make a copy of that structure. 
rsrcType

The resource type of the resource containing the fragment.
rsrcID

The resource ID of the resource containing the fragment.
reservedA

This field is reserved for future use.
Discussion

For fragments located in the resource fork of a file on disk, the inSegs field of a fragment location structure contains a segment location structure, which specifies the location of the fragment. 

The fields of a fragment initialization block are aligned in memory in accordance with 680x0 alignment conventions. 
Availability
Available in Mac OS X v10.0 and later.*/

struct CFragSystem7SegmentedLocator {
   FSSpec * fileSpec;
   OSType rsrcType;
   SInt16 rsrcID;
   UInt16 reservedA;
};
typedef struct CFragSystem7SegmentedLocator CFragSystem7SegmentedLocator;
typedef CFragSystem7SegmentedLocator SegmentedFragment;

/*CFragSystem7MemoryLocator

Defines a memory location structure.

struct CFragSystem7MemoryLocator {
   LogicalAddress address;
   UInt32 length;
   Boolean inPlace;
   UInt8 reservedA;
   UInt16 reservedB;
};
typedef struct CFragSystem7MemoryLocator CFragSystem7MemoryLocator;
typedef CFragSystem7MemoryLocator MemFragment;
Fields
address

A pointer to the beginning of the fragment in memory.
length

The length, in bytes, of the fragment.
inPlace

A Boolean value that specifies whether the container’s data section is instantiated in place (true) or elsewhere (false).
reservedA

This field is reserved for future use. Set to 0.
reservedB

This field is reserved for future use. Set to 0.
Discussion

For fragments located in memory, the inMem field of a fragment location structure contains a memory location structure, which specifies the location of the fragment in memory.

The fields of a fragment initialization block are aligned in memory in accordance with 680x0 alignment conventions. 
Availability
Available in Mac OS X v10.0 and later.*/
struct CFragSystem7MemoryLocator {
   LogicalAddress address;
   UInt32 length;
   Boolean inPlace;
   UInt8 reservedA;
   UInt16 reservedB;
};
typedef struct CFragSystem7MemoryLocator CFragSystem7MemoryLocator;
typedef CFragSystem7MemoryLocator MemFragment;


/*CFragSystem7Locator

Defines a fragment location structure.

struct CFragSystem7Locator {
   SInt32 where
   union {
      CFragSystem7DiskFlatLocator onDisk;
      CFragSystem7MemoryLocator inMem;
      CFragSystem7SegmentedLocator inSegs;
      CFragCFBundleLocator inBundle;
   } u;
};
typedef struct CFragSystem7Locator CFragSystem7Locator;
typedef CFragSystem7Locator * CFragSystem7LocatorPtr;
typedef CFragSystem7Locator FragmentLocator;
Fields
where

A selector that determines which member of the following union is relevant. This field can contain one of the constants described in “Load Flag, Symbol Class, and Fragment Locator Constants”.
u

If the where field has the value kOnDiskFlat, a disk location structure. 
Discussion

The fragLocator field of an initialization block contains a fragment location structure that provides information about the location of a fragment.

The fields of a fragment initialization block are aligned in memory in accordance with 680x0 alignment conventions. 
Availability
Available in Mac OS X v10.0 and later.*/

struct CFragSystem7Locator {
   SInt32 where;
   union {
      CFragSystem7DiskFlatLocator onDisk;
      CFragSystem7MemoryLocator inMem;
      CFragSystem7SegmentedLocator inSegs;
      CFragCFBundleLocator inBundle;
   } u;
};
typedef struct CFragSystem7Locator CFragSystem7Locator;
typedef CFragSystem7Locator * CFragSystem7LocatorPtr;
typedef CFragSystem7Locator FragmentLocator;

/*CFragSystem7InitBlock


struct CFragSystem7InitBlock {
   CFragContextID contextID;
   CFragClosureID closureID;
   CFragConnectionID connectionID;
   CFragSystem7Locator fragLocator;
   StringPtr libName;
   UInt32 reservedA;
};
typedef struct CFragSystem7InitBlock CFragSystem7InitBlock;
typedef CFragSystem7InitBlock * CFragSystem7InitBlock;
typedef CFragSystem7InitBlock CFragInitBlock;
Fields
contextID

A context ID. 
closureID

A closure ID. 
connectionID

A connection ID. 
fragLocator

A fragment location structure, CFragSystem7Locator that specifies the location of the fragment. 
libName

A pointer to the name of the fragment being initialized. The name is a Pascal string (a length byte followed by the name itself).
reservedA

Reserved for use by Apple Computer.
Discussion

The Code Fragment Manager passes to your fragment’s initialization function a pointer to a fragment initialization block, which contains information about the fragment. A fragment initialization block is defined by the InitBlock data type.

The fields of a fragment initialization block are aligned in memory in accordance with 680x0 alignment conventions. 
Availability
Available in Mac OS X v10.0 and later.*/
struct CFragSystem7InitBlock {
   CFragContextID contextID;
   CFragClosureID closureID;
   CFragConnectionID connectionID;
   CFragSystem7Locator fragLocator;
   StringPtr libName;
   UInt32 reservedA;
};
typedef struct CFragSystem7InitBlock *CFragSystem7InitBlock;
//typedef CFragSystem7InitBlock * CFragSystem7InitBlock;
typedef CFragSystem7InitBlock CFragInitBlock;



/*CFragInitBlock


typedef CFragSystem7InitBlock CFragInitBlock;
Availability
Available in Mac OS X v10.0 and later.*/
typedef CFragSystem7InitBlock CFragInitBlock;

/*CFragInitFunction

Defines a fragment initialization function that is executed by the Code Fragment Manager when the fragment is first loaded into memory and prepared for execution.

typedef OSErr (*CFragInitFunction) (
   const CFragInitBlock * initBlock
);

If you name your function MyCFragInitFunction, you would declare it like this:

OSErr MyCFragInitFunction (
   const CFragInitBlock * initBlock
);
Parameters
initBlock

A pointer to a fragment initialization block specifying information about the fragment. 
Return Value

A result code. See “Code Fragment Manager Result Codes”. Your initialization function should return noErr if it executes successfully, and some other result code if it does not. If your initialization function returns any result code other than noErr, the entire load fails and the error fragUserInitProcErr is returned to the code that requested the root load.
Discussion

A fragment’s initialization function is executed immediately before the fragment’s main function (if it has one) is executed. The initialization function is passed a pointer to an initialization block, which contains information about the fragment, such as its location and connection ID. See InitBlock for a description of the fields of the initialization block.

You can use the initialization function to perform any tasks that need to be performed before any of the code or data in the fragment is accessed. For example, you might want to open the fragment’s resource fork (if it has one). You can determine the location of the fragment’s container from the FragmentLocator field of the fragment initialization block whose address is passed to your initialization function.*/

typedef OSErr (*CFragInitFunction) (
   const CFragInitBlock * initBlock
);

/*Load Options


typedef OptionBits CFragLoadOptions;
enum {
   kReferenceCFrag = 0x0001,
   kFindCFrag = 0x0002,
   kPrivateCFragCopy = 0x0005
};
Constants
kReferenceCFrag

Try to use existing copy, increment reference counts.

Available in Mac OS X v10.0 and later.
kFindCFrag

Try find an existing copy, do not increment reference counts.

Available in Mac OS X v10.0 and later.
kPrivateCFragCopy

Prepare a new private copy.

Available in Mac OS X v10.0 and later.*/

typedef OptionBits CFragLoadOptions;
enum {
   kReferenceCFrag = 0x0001,
   kFindCFrag = 0x0002,
   kPrivateCFragCopy = 0x0005
};

/*kLoadCFrag


enum {
   kLoadCFrag = kReferenceCFrag
};
Constants
kLoadCFrag

Available in Mac OS X v10.0 and later.*/

enum {
   kLoadCFrag = kReferenceCFrag
};



//function

/*FindSymbol

Searches for a specific exported symbol.

OSErr FindSymbol (
   CFragConnectionID connID,
   ConstStr255Param symName,
   Ptr * symAddr,
   CFragSymbolClass * symClass
);
Parameters
connID

A connection ID. 
symName

A symbol name. 
symAddr

On return, a pointer to the address of the symbol whose name is symName. 
symClass

On return, a pointer to the class of the symbol whose name is symName. The currently recognized symbol classes are defined by the “Load Flag, Symbol Class, and Fragment Locator Constants”. 
Return Value

A result code. See “Code Fragment Manager Result Codes”.
Discussion

The FindSymbol function searches the code fragment identified by the connID parameter for the symbol whose name is specified by the symName parameter. If that symbol is found, FindSymbol returns the address of the symbol in the symAddr parameter and the class of the symbol in the symClass parameter.

Because a fragment’s code is normally exported through transition vectors to that code, the value kCodeSymbol is not returned in the PowerPC environment. You can use the other two constants to distinguish exports that represent code (of class kTVectSymbol) from those that represent general data (of class kDataSymbol). 
Availability
Available in CarbonLib 1.0 and later when Code Fragment Manager 1.0 or later is present.
Available in Mac OS X 10.0 and later.
Declared In
CodeFragments.h*/
OSErr FindSymbol (
   CFragConnectionID connID,
   ConstStr255Param symName,
   Ptr * symAddr,
   CFragSymbolClass * symClass
);

/*GetDiskFragment

Locates and possibly also loads a fragment contained in a file’s data fork into your application’s context.

OSErr GetDiskFragment (
   const FSSpec * fileSpec,
   UInt32 offset,
   UInt32 length,
   ConstStr63Param fragName,
   CFragLoadOptions options,
   CFragConnectionID * connID,
   Ptr * mainAddr,
   Str255 errMessage
);
Parameters
fileSpec

A pointer to a file system specification that identifies the disk-based fragment to load. 
offset

The number of bytes from the beginning of the file’s data fork at which the beginning of the fragment is located. 
length

The length (in bytes) of the fragment. Specify the constant kWholeFork for this parameter if the fragment extends to the end-of-file of the data fork. Specify a nonzero value for the exact length of the fragment.
fragName

An optional name of the fragment. (This information is used primarily to allow you to identify the fragment during debugging. 
loadFlags

A flag that specifies the operation to perform on the fragment.The Code Fragment Manager recognizes the constants described in “Load Flag, Symbol Class, and Fragment Locator Constants”. 
connID

On return, a pointer to the connection ID that identifies the connection to the fragment. You can pass this ID to other Code Fragment Manager functions. 
mainAddr

On return, a pointer to the main address of the fragment. The value returned is specific to the fragment itself. Your application can use this parameter for its own purposes. 
errMessage

On return, the name of the fragment that could not successfully be loaded. This parameter is meaningful only if the call to GetDiskFragment fails. 
Return Value

A result code. See “Code Fragment Manager Result Codes”. The kFindLib constant in the loadFlags parameter specifies that the Code Fragment Manager search for the specified fragment. If the fragment is already prepared and connected to your application, GetDiskFragment returns fragNoErr. If the specified fragment is not found, GetDiskFragment returns the result code fragLibNotFound. If the specified fragment is found but could not be connected to your application, the function returns fragLibConnErr.
Discussion

Loading involves finding the specified fragment, reading it into memory (if it is not already in memory), and preparing it for execution. The Code Fragment Manager attempts to resolve all symbols imported by the fragment; to do so may involve loading import libraries.

If the fragment loading fails, the Code Fragment Manager returns an error code. Note, however, that the error encountered is not always in the fragment you asked to load. Rather, the error might have occurred while attempting to load an import library that the fragment you want to load depends on. For this reason, the Code Fragment Manager also returns, in the errMessage parameter, the name of the fragment that caused the load to fail. Although fragment names are restricted to 63 characters, the errMessage parameter is declared as type Str255; doing this allows future versions of the Code Fragment Manager to return a more informative message in the errMessage parameter. 
Availability
Modified in Carbon. Available in CarbonLib 1.0 and later when Code Fragment Manager 1.0 or later is present.
Available in Mac OS X 10.0 and later.
Carbon Porting Notes

On Mac OS X, GetDiskFragment does not include the folder containing the root fragment (assuming that it is different from the application fragment) in its search path for import libraries. For example, say your application used a special folder to store plugins. If that folder also contained special libraries for those plugins, then calling GetDiskFragment to load a plugin would not find those libraries. 

The workaround is to make sure that any import libraries you require are in the Code Fragment Manager's search path (such as by designating an application library subfolder in the code fragment resource, or placing the libraries in the application's container). For more details of how the Code Fragment Manager searches for import libraries, see Mac OS Runtime Architectures. 
Declared In
CodeFragments.h*/
OSErr GetDiskFragment (
   const FSSpec * fileSpec,
   UInt32 offset,
   UInt32 length,
   ConstStr63Param fragName,
   CFragLoadOptions options,
   CFragConnectionID * connID,
   Ptr * mainAddr,
   Str255 errMessage
);

/*CloseConnection

Closes a connection to a fragment.

OSErr CloseConnection (
   CFragConnectionID * connID
);
Parameters
connID

A pointer to a connection ID. 
Return Value

A result code. See “Code Fragment Manager Result Codes”.
Discussion

The CloseConnection function closes the connection to a fragment indicated by the connID parameter. CloseConnection decrements the count of existing connections to the specified fragment and, if the resulting count is 0, calls the fragment’s termination function and releases the memory occupied by the code and data sections of the fragment. If the resulting count is not 0, any per-connection data is released but the code section remains in memory.

When a fragment is unloaded as a result of its final connection having been closed, all libraries that depend on that fragment are also released, provided that their usage counts are also 0.

The Code Fragment Manager automatically closes any connections that remain open at the time ExitToShell is called for your application, so you need to call CloseConnection only for fragments you wish to unload before your application terminates. 
Special Considerations

You can close a connection only to the root of a loading sequence (that is, the fragment whose loading triggered the entire load chain).
Availability
Available in CarbonLib 1.0 and later when Code Fragment Manager 1.0 or later is present.
Available in Mac OS X 10.0 and later.
Declared In
CodeFragments.h*/

OSErr CloseConnection (
   CFragConnectionID * connID
);

/*CountSymbols

Determines how many symbols are exported from a specified fragment.

OSErr CountSymbols (
   CFragConnectionID connID,
   long * symCount
);
Parameters
connID

A connection ID. 
symCount

On return, a pointer to the number of exported symbols in the fragment whose connection ID is connID. You can use the value returned in symCount to index through all the exported symbols in a particular fragment (using the GetIndSymbol function). 
Return Value

A result code. See “Code Fragment Manager Result Codes”.
Availability
Available in CarbonLib 1.0 and later when Code Fragment Manager 1.0 or later is present.
Available in Mac OS X 10.0 and later.
Declared In
CodeFragments.h*/

OSErr CountSymbols (
   CFragConnectionID connID,
   long * symCount
);

/*GetIndSymbol

Gets information about the exported symbols in a fragment.

OSErr GetIndSymbol (
   CFragConnectionID connID,
   long symIndex,
   Str255 symName,
   Ptr * symAddr,
   CFragSymbolClass * symClass
);
Parameters
connID

A connection ID. 
symIndex

A symbol index. This index is zero-based. That is, the value of this parameter should be between zero and the number of symbols -1 (where the number of symbols is determined by calling the CountSymbols function). 
symName

On return, the name of the indicated symbol. 
symAddr

On return, a pointer to the address of the indicated symbol. 
symClass

On return, a pointer to the class of the indicated symbol. See “Load Flag, Symbol Class, and Fragment Locator Constants”. 
Return Value

A result code. See “Code Fragment Manager Result Codes”.
Discussion

If GetIndSymbol executes successfully, it returns the symbol’s name, starting address, and class in the symName, symAddr, and symClass parameters, respectively. A fragment’s exported symbols are retrieved in no predetermined order. 
Availability
Available in CarbonLib 1.0 and later when Code Fragment Manager 1.0 or later is present.
Available in Mac OS X 10.0 and later.
Declared In
CodeFragments.h*/
OSErr GetIndSymbol (
   CFragConnectionID connID,
   long symIndex,
   Str255 symName,
   Ptr * symAddr,
   CFragSymbolClass * symClass
);


#ifdef __cplusplus
}
#endif

#endif