1 /* treaty_builder.h common macros to build a treaty module
\r
3 * 2006 By L. Ross Raszewski
\r
5 * This file is public domain, but be aware that any changes to it may
\r
6 * cause it to cease to be compliant with the Treaty of Babel.
\r
8 * This file depends on treaty.h
\r
10 * The purpose of this file is to simplify the building of a treaty
\r
11 * module. It automatically generates a generic treaty function.
\r
15 * #define the following values:
\r
16 * FORMAT The treaty name of the format
\r
17 * HOME_PAGE A string containing the URL of the format home page
\r
18 * FORMAT_EXT A string containing a comma separated list of common
\r
19 * extensions for game files in this format
\r
20 * NO_METADATA If the format does not support metadata
\r
21 * NO_COVER If the format does not support cover art
\r
22 * CUSTOM_EXTENSION If game files should not always use the first listed extension
\r
24 * (Note: Formats which support metadata and cover art via a container should
\r
25 * define NO_METADATA and NO_COVER as container support is handled separately)
\r
27 * #include "treaty_builder.h"
\r
28 * Define the following functions:
\r
29 * static int32 get_story_file_IFID(void *, int32, char *, int32);
\r
30 * static int32 claim_story_file(void *, int32);
\r
31 * Define the following functions if NO_METADATA is not defined:
\r
32 * static int32 get_story_file_metadata_extent(void *, int32);
\r
33 * static int32 get_story_file_metadata(void *, int32, char *, int32);
\r
34 * Define the following functions if NO_COVER is not defined
\r
35 * static int32 get_story_file_cover_extent(void *, int32);
\r
36 * static int32 get_story_file_cover_format(void *, int32);
\r
37 * static int32 get_story_file_cover(void *, int32, void *, int32);
\r
38 * Define the following if CUSTOM_EXTENSION is defined
\r
39 * static int32 get_story_file_extension(void *, int32, char *, int32);
\r
41 * The two-parameter functions take the story file and story file extent
\r
42 * as parameters. The four-parameter ones also take the output
\r
43 * buffer and its extent. They perform the corresponding task to the
\r
44 * similarly-named selector.
\r
46 * This file also defines the macro ASSERT_OUTPUT_SIZE(x) which
\r
47 * returns INVALID_USAGE_RV if output_extent is less than x.
\r
49 * #define CONTAINER_FORMAT before inclusion to generate a container
\r
50 * module. A container module should define three additional functions:
\r
51 * static int32 get_story_format(void *, int32, char *, int32);
\r
52 * static int32 get_story_extent(void *, int32);
\r
53 * static int32 get_story_file(void *, int32, void *, int32);
\r
57 #ifndef TREATY_BUILDER
\r
58 #define TREATY_BUILDER
\r
63 #define ASSERT_OUTPUT_SIZE(x) do { if (output_extent < (x)) return INVALID_USAGE_RV; } while (0)
\r
66 static int32 get_story_file_metadata_extent(void *, int32);
\r
67 static int32 get_story_file_metadata(void *, int32, char *, int32);
\r
70 static int32 get_story_file_cover_extent(void *, int32);
\r
71 static int32 get_story_file_cover_format(void *, int32);
\r
72 static int32 get_story_file_cover(void *, int32, void *, int32);
\r
74 static int32 get_story_file_IFID(void *, int32, char *, int32);
\r
75 static int32 claim_story_file(void *, int32);
\r
76 #ifdef CONTAINER_FORMAT
\r
77 static int32 get_story_file(void *, int32, void *, int32);
\r
78 static int32 get_story_format(void *, int32, char *, int32);
\r
79 static int32 get_story_extent(void *, int32);
\r
81 #ifdef CUSTOM_EXTENSION
\r
82 static int32 get_story_file_extension(void *, int32, char *, int32);
\r
85 static int32 get_story_file_extension(void *sf, int32 extent, char *out, int32 output_extent)
\r
89 if (!sf || !extent) return INVALID_STORY_FILE_RV;
\r
91 for(i=0;FORMAT_EXT[i] && FORMAT_EXT[i]!=',';i++);
\r
92 ASSERT_OUTPUT_SIZE(i+1);
\r
93 memcpy(out,FORMAT_EXT,i);
\r
100 #define TREATY_FUNCTION(X) DEEP_TREATY_FUNCTION(X)
\r
101 #define DEEP_TREATY_FUNCTION(X) X ## _treaty
\r
102 #define dSTRFRY(X) #X
\r
103 #define STRFRY(X) dSTRFRY(X)
\r
105 int32 TREATY_FUNCTION(FORMAT)(int32 selector,
\r
106 void *story_file, int32 extent,
\r
107 void *output, int32 output_extent)
\r
110 if ((TREATY_SELECTOR_INPUT & selector) &&
\r
111 (csf=claim_story_file(story_file, extent))<NO_REPLY_RV)
\r
112 return INVALID_STORY_FILE_RV;
\r
115 if ((TREATY_SELECTOR_OUTPUT & selector) &&
\r
116 (output_extent ==0 ||
\r
118 return INVALID_USAGE_RV;
\r
121 case GET_HOME_PAGE_SEL:
\r
122 ASSERT_OUTPUT_SIZE((signed) strlen(HOME_PAGE)+1);
\r
123 strcpy((char *) output,HOME_PAGE);
\r
124 return NO_REPLY_RV;
\r
125 case GET_FORMAT_NAME_SEL:
\r
126 ASSERT_OUTPUT_SIZE(512);
\r
127 strncpy((char *) output,STRFRY(FORMAT),output_extent-1);
\r
128 return NO_REPLY_RV;
\r
129 case GET_FILE_EXTENSIONS_SEL:
\r
130 ll=(strlen(FORMAT_EXT)+1) < 512 ? (strlen(FORMAT_EXT)+1):512;
\r
131 ASSERT_OUTPUT_SIZE(ll);
\r
132 strncpy((char *) output, FORMAT_EXT, output_extent);
\r
133 return NO_REPLY_RV;
\r
134 case CLAIM_STORY_FILE_SEL:
\r
136 case GET_STORY_FILE_METADATA_EXTENT_SEL:
\r
137 #ifndef NO_METADATA
\r
138 return get_story_file_metadata_extent(story_file, extent);
\r
140 case GET_STORY_FILE_METADATA_SEL:
\r
141 #ifndef NO_METADATA
\r
142 return get_story_file_metadata(story_file, extent, (char *)output, output_extent);
\r
144 return NO_REPLY_RV;
\r
146 case GET_STORY_FILE_COVER_EXTENT_SEL:
\r
148 return get_story_file_cover_extent(story_file, extent);
\r
150 case GET_STORY_FILE_COVER_FORMAT_SEL:
\r
152 return get_story_file_cover_format(story_file, extent);
\r
154 case GET_STORY_FILE_COVER_SEL:
\r
156 return get_story_file_cover(story_file, extent, output, output_extent);
\r
158 return NO_REPLY_RV;
\r
160 case GET_STORY_FILE_IFID_SEL:
\r
161 return get_story_file_IFID(story_file, extent, (char *)output, output_extent);
\r
162 case GET_STORY_FILE_EXTENSION_SEL:
\r
163 return get_story_file_extension(story_file, extent, (char *)output, output_extent);
\r
164 #ifdef CONTAINER_FORMAT
\r
165 case CONTAINER_GET_STORY_FORMAT_SEL:
\r
166 return get_story_format(story_file, extent, (char *)output, output_extent);
\r
167 case CONTAINER_GET_STORY_EXTENT_SEL:
\r
168 return get_story_extent(story_file, extent);
\r
169 case CONTAINER_GET_STORY_FILE_SEL:
\r
170 return get_story_file(story_file, extent, output, output_extent);
\r
174 return UNAVAILABLE_RV;
\r
179 #error "treaty_builder should be used as most once in any source file";
\r