-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathSAUCE.bas
451 lines (323 loc) · 14.5 KB
/
SAUCE.bas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
'-----------------------------------------------------------------------------------------------------------------------
' QB64-PE SAUCE Library
' Copyright (c) 2024 Samuel Gomes
'
' See https://github.com/radman1/sauce
'-----------------------------------------------------------------------------------------------------------------------
$INCLUDEONCE
'$INCLUDE:'SAUCE.bi'
'-----------------------------------------------------------------------------------------------------------------------
' TEST CODE
'-----------------------------------------------------------------------------------------------------------------------
'DIM buffer AS STRING: buffer = _READFILE$("C:\Users\samue\source\repos\a740g\ANSI-Print-64\demos\aa-fldontcare.ans")
'PRINT SAUCE_IsPresent(buffer)
'DIM sauce AS SAUCEType: SAUCE_Read buffer, sauce
'PRINT SAUCE_GetAuthor(sauce)
'PRINT SAUCE_GetDataType(sauce)
'PRINT SAUCE_GetFileType(sauce)
'PRINT SAUCE_GetTypeInfoLong1(sauce), SAUCE_GetTypeInfoLong2(sauce)
'PRINT _BIN$(SAUCE_GetTypeFlags(sauce))
'PRINT SAUCE_GetTypeInfoString(sauce)
'END
'-----------------------------------------------------------------------------------------------------------------------
' Returns the position of the SAUCE record in a string buffer
FUNCTION __SAUCE_GetRecordPosition~& (buffer AS STRING)
IF LEN(buffer) >= __SAUCE_RECORD_SIZE THEN
DIM position AS _UNSIGNED LONG: position = 1 + LEN(buffer) - __SAUCE_RECORD_SIZE
IF __SAUCE_ID = MID$(buffer, position, LEN(__SAUCE_ID)) THEN
__SAUCE_GetRecordPosition = position
END IF
END IF
END FUNCTION
' Returns the position of the SAUCE comment block in a string buffer
' The SAUCE record should be read pior to calling this function!
FUNCTION __SAUCE_GetCommentBlockPosition~& (buffer AS STRING, sauceRecord AS __SAUCERecordType)
DIM commentBlockSize AS _UNSIGNED LONG: commentBlockSize = LEN(__SAUCE_COMMENT_ID) + sauceRecord.commentLines * __SAUCE_COMMENT_SIZE
DIM totalRecordSize AS _UNSIGNED LONG: totalRecordSize = commentBlockSize + LEN(sauceRecord)
IF LEN(buffer) >= totalRecordSize THEN
DIM position AS _UNSIGNED LONG: position = 1 + LEN(buffer) - totalRecordSize
IF __SAUCE_COMMENT_ID = MID$(buffer, position, LEN(__SAUCE_COMMENT_ID)) THEN
__SAUCE_GetCommentBlockPosition = position
END IF
END IF
END FUNCTION
' Detects the presence of a SAUCE record in a memory loaded file
FUNCTION SAUCE_IsPresent%% (buffer AS STRING)
SAUCE_IsPresent = __SAUCE_GetRecordPosition(buffer) > 0
END FUNCTION
' Removes a SAUCE record from a memory loaded file if it is present
SUB SAUCE_Remove (buffer AS STRING)
IF __SAUCE_GetRecordPosition(buffer) > 0 THEN
DIM sauce AS SAUCEType: SAUCE_Read buffer, sauce
' The total size of the SAUCE record is sizeof(EOF byte) + sizeof(comment block) + sizeof(SAUCE record)
DIM bytesToRemove AS _UNSIGNED LONG: bytesToRemove = _SIZE_OF_BYTE + LEN(sauce.record)
' Add the comments block if we have one
IF LEN(sauce.comments) > 0 THEN bytesToRemove = bytesToRemove + LEN(__SAUCE_COMMENT_ID) + LEN(sauce.comments)
IF LEN(buffer) >= bytesToRemove THEN
buffer = LEFT$(buffer, LEN(buffer) - bytesToRemove)
END IF
END IF
END SUB
' Initializes a sauce record (everything is cleared to defaults)
SUB SAUCE_Initialize (sauce AS SAUCEType)
' Zero the underlying SAUCE record
SetMemoryByte _OFFSET(sauce.record), NULL, LEN(sauce.record)
' Zap the comments
sauce.comments = _STR_EMPTY
' Set the SAUCE ID
sauce.record.id = __SAUCE_ID
' Set the current date
DIM systemDate AS STRING: systemDate = DATE$
sauce.record.date = RIGHT$(systemDate, 4) + LEFT$(systemDate, 2) + MID$(systemDate, 4, 2)
END SUB
' Reads the SAUCE record from a memory loaded file
' Is there is none, it will simply initialize the SAUCE record
SUB SAUCE_Read (buffer AS STRING, sauce AS SAUCEType)
DIM position AS _UNSIGNED LONG: position = __SAUCE_GetRecordPosition(buffer)
IF position > 0 THEN
' Read in the SAUCE record first
CopyMemory _OFFSET(sauce.record), _OFFSET(buffer) + position - 1, LEN(sauce.record)
' Get the position a comment block
position = __SAUCE_GetCommentBlockPosition(buffer, sauce.record)
IF position > 0 THEN
sauce.comments = MID$(buffer, position + LEN(__SAUCE_COMMENT_ID), sauce.record.commentLines * __SAUCE_COMMENT_SIZE) ' read comments
ELSE
sauce.comments = _STR_EMPTY ' no comments
END IF
ELSE
SAUCE_Initialize sauce
END IF
END SUB
' Writes (attaches) the SAUCE record to a memory loaded file
' If the SAUCE record is not initialized then it is automatically initialized
' The size field in the record is automatically adjusted
SUB SAUCE_Write (sauce AS SAUCEType, buffer AS STRING)
' Initialze the sauce record if needed
IF sauce.record.id <> __SAUCE_ID THEN SAUCE_Initialize sauce
' Remove any existing record
SAUCE_Remove buffer
' Update the file size
sauce.record.fileSize = LEN(buffer)
' Add the EOF marker
buffer = buffer + CHR$(__SAUCE_EOF_CHARACTER)
' Add the comment block if needed
IF LEN(sauce.comments) > 0 THEN
buffer = buffer + __SAUCE_COMMENT_ID + sauce.comments
END IF
' Now add the SAUCE record
buffer = buffer + SPACE$(LEN(sauce.record))
CopyMemory _OFFSET(buffer) + LEN(buffer) - LEN(sauce.record), _OFFSET(sauce.record), LEN(sauce.record)
END SUB
' Returns the SAUCE record version
FUNCTION SAUCE_GetVersion~% (sauce AS SAUCEType)
' Initialze the sauce record if needed
IF sauce.record.id <> __SAUCE_ID THEN SAUCE_Initialize sauce
SAUCE_GetVersion = sauce.record.version
END FUNCTION
' Gets the SAUCE file title
FUNCTION SAUCE_GetTitle$ (sauce AS SAUCEType)
' Initialze the sauce record if needed
IF sauce.record.id <> __SAUCE_ID THEN SAUCE_Initialize sauce
SAUCE_GetTitle = sauce.record.caption
END FUNCTION
' Sets the SAUCE file title
SUB SAUCE_SetTitle (sauce AS SAUCEType, caption AS STRING)
' Initialze the sauce record if needed
IF sauce.record.id <> __SAUCE_ID THEN SAUCE_Initialize sauce
sauce.record.caption = caption
END SUB
' Gets the SAUCE file author
FUNCTION SAUCE_GetAuthor$ (sauce AS SAUCEType)
' Initialze the sauce record if needed
IF sauce.record.id <> __SAUCE_ID THEN SAUCE_Initialize sauce
SAUCE_GetAuthor = sauce.record.author
END FUNCTION
' Sets the SAUCE file author
SUB SAUCE_SetAuthor (sauce AS SAUCEType, author AS STRING)
' Initialze the sauce record if needed
IF sauce.record.id <> __SAUCE_ID THEN SAUCE_Initialize sauce
sauce.record.author = author
END SUB
' Gets the SAUCE file group
FUNCTION SAUCE_GetGroup$ (sauce AS SAUCEType)
' Initialze the sauce record if needed
IF sauce.record.id <> __SAUCE_ID THEN SAUCE_Initialize sauce
SAUCE_GetGroup = sauce.record.group
END FUNCTION
' Sets the SAUCE file group
SUB SAUCE_SetGroup (sauce AS SAUCEType, group AS STRING)
' Initialze the sauce record if needed
IF sauce.record.id <> __SAUCE_ID THEN SAUCE_Initialize sauce
sauce.record.group = group
END SUB
' Gets the SAUCE file date in CCYYMMDD format
FUNCTION SAUCE_GetDate$ (sauce AS SAUCEType)
' Initialze the sauce record if needed
IF sauce.record.id <> __SAUCE_ID THEN SAUCE_Initialize sauce
SAUCE_GetDate = sauce.record.date
END FUNCTION
' Sets the SAUCE file date in CCYYMMDD format
SUB SAUCE_SetDate (sauce AS SAUCEType, dateString AS STRING)
' Initialze the sauce record if needed
IF sauce.record.id <> __SAUCE_ID THEN SAUCE_Initialize sauce
' Do some validation
IF String_IsDigit(ASC(dateString, 1)) THEN
IF String_IsDigit(ASC(dateString, 2)) THEN
IF String_IsDigit(ASC(dateString, 3)) THEN
IF String_IsDigit(ASC(dateString, 4)) THEN
IF String_IsDigit(ASC(dateString, 5)) THEN
IF String_IsDigit(ASC(dateString, 6)) THEN
IF String_IsDigit(ASC(dateString, 7)) THEN
IF String_IsDigit(ASC(dateString, 8)) THEN
sauce.record.date = dateString
EXIT SUB
END IF
END IF
END IF
END IF
END IF
END IF
END IF
END IF
ERROR _ERR_ILLEGAL_FUNCTION_CALL
END SUB
' Returns the original file size not including the SAUCE information
FUNCTION SAUCE_GetFileSize~& (sauce AS SAUCEType)
' Initialze the sauce record if needed
IF sauce.record.id <> __SAUCE_ID THEN SAUCE_Initialize sauce
SAUCE_GetFileSize = sauce.record.fileSize
END FUNCTION
' Gets the SAUCE data type
FUNCTION SAUCE_GetDataType~& (sauce AS SAUCEType)
' Initialze the sauce record if needed
IF sauce.record.id <> __SAUCE_ID THEN SAUCE_Initialize sauce
SAUCE_GetDataType = sauce.record.dataType
END FUNCTION
' Sets the SAUCE data type
SUB SAUCE_SetDataType (sauce AS SAUCEType, dataType AS _UNSIGNED LONG)
' Initialze the sauce record if needed
IF sauce.record.id <> __SAUCE_ID THEN SAUCE_Initialize sauce
' Do some validation
IF dataType < __SAUCE_DATATYPE_COUNT THEN
sauce.record.dataType = dataType
ELSE
ERROR _ERR_ILLEGAL_FUNCTION_CALL
END IF
END SUB
' Gets the SAUCE file type
FUNCTION SAUCE_GetFileType~& (sauce AS SAUCEType)
' Initialze the sauce record if needed
IF sauce.record.id <> __SAUCE_ID THEN SAUCE_Initialize sauce
SAUCE_GetFileType = sauce.record.fileType
END FUNCTION
' Sets the SAUCE file type
SUB SAUCE_SetFileType (sauce AS SAUCEType, fileType AS _UNSIGNED LONG)
' Initialze the sauce record if needed
IF sauce.record.id <> __SAUCE_ID THEN SAUCE_Initialize sauce
sauce.record.fileType = fileType
END SUB
' Gets the SAUCE Info1 field
FUNCTION SAUCE_GetTypeInfoLong1~& (sauce AS SAUCEType)
' Initialze the sauce record if needed
IF sauce.record.id <> __SAUCE_ID THEN SAUCE_Initialize sauce
SAUCE_GetTypeInfoLong1 = sauce.record.tInfo1
END FUNCTION
' Sets the SAUCE Info1 field
SUB SAUCE_SetTypeInfoLong1 (sauce AS SAUCEType, typeInfo AS _UNSIGNED LONG)
' Initialze the sauce record if needed
IF sauce.record.id <> __SAUCE_ID THEN SAUCE_Initialize sauce
sauce.record.tInfo1 = typeInfo
END SUB
' Gets the SAUCE Info2 field
FUNCTION SAUCE_GetTypeInfoLong2~& (sauce AS SAUCEType)
' Initialze the sauce record if needed
IF sauce.record.id <> __SAUCE_ID THEN SAUCE_Initialize sauce
SAUCE_GetTypeInfoLong2 = sauce.record.tInfo2
END FUNCTION
' Sets the SAUCE Info2 field
SUB SAUCE_SetTypeInfoLong2 (sauce AS SAUCEType, typeInfo AS _UNSIGNED LONG)
' Initialze the sauce record if needed
IF sauce.record.id <> __SAUCE_ID THEN SAUCE_Initialize sauce
sauce.record.tInfo2 = typeInfo
END SUB
' Gets the SAUCE Info3 field
FUNCTION SAUCE_GetTypeInfoLong3~& (sauce AS SAUCEType)
' Initialze the sauce record if needed
IF sauce.record.id <> __SAUCE_ID THEN SAUCE_Initialize sauce
SAUCE_GetTypeInfoLong3 = sauce.record.tInfo3
END FUNCTION
' Sets the SAUCE Info3 field
SUB SAUCE_SetTypeInfoLong3 (sauce AS SAUCEType, typeInfo AS _UNSIGNED LONG)
' Initialze the sauce record if needed
IF sauce.record.id <> __SAUCE_ID THEN SAUCE_Initialize sauce
sauce.record.tInfo3 = typeInfo
END SUB
' Gets the SAUCE Info4 field
FUNCTION SAUCE_GetTypeInfoLong4~& (sauce AS SAUCEType)
' Initialze the sauce record if needed
IF sauce.record.id <> __SAUCE_ID THEN SAUCE_Initialize sauce
SAUCE_GetTypeInfoLong4 = sauce.record.tInfo4
END FUNCTION
' Sets the SAUCE Info4 field
SUB SAUCE_SetTypeInfoLong4 (sauce AS SAUCEType, typeInfo AS _UNSIGNED LONG)
' Initialze the sauce record if needed
IF sauce.record.id <> __SAUCE_ID THEN SAUCE_Initialize sauce
sauce.record.tInfo4 = typeInfo
END SUB
' Gets the number of SAUCE comment lines
FUNCTION SAUCE_GetCommentLines~%% (sauce AS SAUCEType)
' Initialze the sauce record if needed
IF sauce.record.id <> __SAUCE_ID THEN SAUCE_Initialize sauce
SAUCE_GetCommentLines = sauce.record.commentLines
END FUNCTION
' Gets the SAUCE type flags
FUNCTION SAUCE_GetTypeFlags~%% (sauce AS SAUCEType)
' Initialze the sauce record if needed
IF sauce.record.id <> __SAUCE_ID THEN SAUCE_Initialize sauce
SAUCE_GetTypeFlags = sauce.record.tFlags
END FUNCTION
' Sets the SAUCE type flags
SUB SAUCE_SetTypeFlags (sauce AS SAUCEType, typeFlags AS _UNSIGNED _BYTE)
' Initialze the sauce record if needed
IF sauce.record.id <> __SAUCE_ID THEN SAUCE_Initialize sauce
sauce.record.tFlags = typeFlags
END SUB
' Gets the SAUCE type info string
FUNCTION SAUCE_GetTypeInfoString$ (sauce AS SAUCEType)
' Initialze the sauce record if needed
IF sauce.record.id <> __SAUCE_ID THEN SAUCE_Initialize sauce
SAUCE_GetTypeInfoString = String_ToBStr(sauce.record.tInfoS)
END FUNCTION
' Sets the SAUCE type info string
SUB SAUCE_SetTypeInfoString (sauce AS SAUCEType, typeInfo AS STRING)
' Initialze the sauce record if needed
IF sauce.record.id <> __SAUCE_ID THEN SAUCE_Initialize sauce
sauce.record.tInfoS = LEFT$(typeInfo, LEN(sauce.record.tInfoS) - 1) + CHR$(NULL)
END SUB
' Gets a SAUCE comment line
' commentLine can (1 - 255)
FUNCTION SAUCE_GetComment$ (sauce AS SAUCEType, commentLine AS _UNSIGNED _BYTE)
' Initialze the sauce record if needed
IF sauce.record.id <> __SAUCE_ID THEN SAUCE_Initialize sauce
IF sauce.record.commentLines > 0 THEN
SAUCE_GetComment = MID$(sauce.comments, 1 + (commentLine - 1) * __SAUCE_COMMENT_SIZE, __SAUCE_COMMENT_SIZE)
ELSE
ERROR _ERR_ILLEGAL_FUNCTION_CALL
END IF
END FUNCTION
' Sets a SAUCE comment line
' commentLine can (1 - 255)
SUB SAUCE_SetComment (sauce AS SAUCEType, commentLine AS _UNSIGNED _BYTE, comment AS STRING)
' Initialze the sauce record if needed
IF sauce.record.id <> __SAUCE_ID THEN SAUCE_Initialize sauce
' Calculate the total comment size based on commentLine
DIM totalSize AS _UNSIGNED LONG: totalSize = commentLine * __SAUCE_COMMENT_SIZE
' Grow the comments buffer if it is less than the total size
IF totalSize > LEN(sauce.comments) THEN
sauce.comments = sauce.comments + SPACE$(totalSize - LEN(sauce.comments))
sauce.record.commentLines = commentLine ' update the number of lines
END IF
' Now insert the comment line
MID$(sauce.comments, 1 + (commentLine - 1) * __SAUCE_COMMENT_SIZE, __SAUCE_COMMENT_SIZE) = LEFT$(comment, __SAUCE_COMMENT_SIZE)
END SUB
'$INCLUDE:'StringOps.bas'