ciderpress/diskimg/TwoImg.h
Andy McFadden aa3145856c Use types with explicit sizes
Focusing on the diskimg library this time, which deals with a lot of
filesystem structures that have specific widths.

This is still a bit lax in places, e.g. using "long" for lengths.
Should either specify a bit width or use di_off_t.

Also, added "override" keyword where appropriate.

Also, bumped library version to 5.0.0.
2014-11-24 15:57:25 -08:00

135 lines
4.2 KiB
C++

/*
* CiderPress
* Copyright (C) 2007 by faddenSoft, LLC. All Rights Reserved.
* See the file LICENSE for distribution terms.
*/
/*
* Support for the "2MG"/"2IMG" disk image format.
*
* This gets its own header because CiderPress uses these definitions and
* functions directly.
*/
#ifndef DISKIMG_TWOIMG_H
#define DISKIMG_TWOIMG_H
#include "DiskImg.h"
namespace DiskImgLib {
/*
* 2IMG header definition (was on http://www.magnet.ch/emutech/Tech/,
* now on http://www.a2central.com/programming/filetypes/ftne00130.html
* as filetype $e0/$0130).
*
* Meaning of "flags":
* bit 31 : disk is "locked"; used by emulators as write-protect sticker.
* bit 8 : if set, bits 0-7 specify DOS 3.3 volume number
* bit 0-7: if bit 8 is set, use this as DOS volume; else use 254
*
* All values are stored little-endian.
*/
class DISKIMG_API TwoImgHeader {
public:
TwoImgHeader(void) : fDOSVolumeNum(-1), fComment(NULL), fCreatorChunk(NULL)
{}
virtual ~TwoImgHeader(void) {
delete[] fComment;
delete[] fCreatorChunk;
}
/*
* Header fields.
*/
//char fMagic[4];
//char fCreator[4];
uint32_t fMagic;
uint32_t fCreator;
uint16_t fHeaderLen;
uint16_t fVersion;
uint32_t fImageFormat;
uint32_t fFlags; // may include DOS volume num
uint32_t fNumBlocks; // 512-byte blocks
uint32_t fDataOffset;
uint32_t fDataLen;
uint32_t fCmtOffset;
uint32_t fCmtLen;
uint32_t fCreatorOffset;
uint32_t fCreatorLen;
uint32_t fSpare[4];
/*
* Related constants.
*/
enum {
// imageFormat
kImageFormatDOS = 0,
kImageFormatProDOS = 1,
kImageFormatNibble = 2,
// flags
kFlagLocked = (1L<<31),
kDOSVolumeSet = (1L<<8),
kDOSVolumeMask = (0xff),
kDefaultVolumeNum = 254,
// constants used when creating a new header
kOurHeaderLen = 64,
kOurVersion = 1,
kBlockSize = 512,
kMagic = 0x32494d47, // 2IMG
kCreatorCiderPress = 0x43647250, // CdrP
kCreatorSweet16 = 0x574f4f46, // WOOF
};
/*
* Basic functions.
*
* The read header function will read the comment, but the write
* header function will not. This is because the GenericFD functions
* don't allow seeking past the current EOF.
*
* ReadHeader/WriteHeader expect the file to be seeked to the initial
* offset. WriteFooter expects the file to be seeked just past the
* end of the data section. This is done in case the file has some
* sort of wrapper outside the 2MG header.
*/
int InitHeader(int imageFormat, uint32_t imageSize, uint32_t imageBlockCount);
int ReadHeader(FILE* fp, uint32_t totalLength);
int ReadHeader(GenericFD* pGFD, uint32_t totalLength);
int WriteHeader(FILE* fp) const;
int WriteHeader(GenericFD* pGFD) const;
int WriteFooter(FILE* fp) const;
int WriteFooter(GenericFD* pGFD) const;
void DumpHeader(void) const; // for debugging
/*
* Getters & setters.
*/
const char* GetMagicStr(void) const { return fMagicStr; }
const char* GetCreatorStr(void) const { return fCreatorStr; }
int16_t GetDOSVolumeNum(void) const;
void SetDOSVolumeNum(short dosVolumeNum);
const char* GetComment(void) const { return fComment; }
void SetComment(const char* comment);
const void* GetCreatorChunk(void) const { return fCreatorChunk; }
void SetCreatorChunk(const void* creatorBlock, long len);
private:
int UnpackHeader(const uint8_t* buf, uint32_t totalLength);
void PackHeader(uint8_t* buf) const;
int GetChunk(GenericFD* pGFD, di_off_t relOffset, long len, void** pBuf);
int GetChunk(FILE* fp, di_off_t relOffset, long len, void** pBuf);
int16_t fDOSVolumeNum; // 8-bit volume number, or -1
char fMagicStr[5];
char fCreatorStr[5];
char* fComment;
char* fCreatorChunk;
};
} // namespace DiskImgLib
#endif /*DISKIMG_TWOIMG_H*/