Calculating checksums for different structures.

Discussion in 'C++' started by grishin-mailing-lists, Jul 3, 2010.

  1. Hi there,

    I've been writing a program that generates a subfont-file of a given
    font and number of needed glyphs. User decides which glyphs to
    preserve and which to remove. Though it's not really important.

    What is important that I have to rebuild some font tables -> their
    checksums will change.
    When I start the project I was dealing with tables of plain
    structures, like:
    typedef struct
    {
    USHORT MajorVersion;
    USHORT MinorVersion;
    USHORT NumTables;
    USHORT SearchRange;
    USHORT EntrySelector;
    USHORT RangeShift;
    } ttFontHeader;

    I used casting to char * and calculated all of the new checksums by
    this routine:
    ULONG CalcTableChecksum(ULONG *Table, ULONG Length)
    {
    ULONG Sum = 0L;
    ULONG *EndPtr = Table+((Length+3) & ~3) / sizeof(ULONG);
    while (Table < EndPtr)
    {
    Sum += swap32(*Table++);
    }

    return Sum;
    }

    It worked well.
    I've ended up with rebuilding cmap format 4 table which has a
    sophisticated structure. I had to use vectors:
    typedef struct
    { /* ÐÏÐÙÔËÁ ÓÄÅÌÁÔØ ÏÂÝÅÅ ÈÒÁÎÉÌÉÝÅ ÄÌÑ ÞÁÓÔÏ ÉÓÐÏÌØÚÕÅÍÙÈ ÆÏÒÍÁÔÏ×
    (0 É 4) */
    USHORT Format;
    USHORT Length;
    USHORT Language;
    unsigned SegCount;
    signed SearchRange;
    signed EntrySelector;
    signed RangeShift;
    std::vector<ttCmapSegment> Segments;
    std::vector<USHORT> GlyphIDs;
    } ttCmapSubtable;
    typedef struct
    {
    USHORT Version;
    USHORT NumTables;
    std::vector<ttCmapEncodingRecord> EncRecords;
    std::vector<ttCmapSubtable> Subtables;
    } ttCmap;
    and now I can't just cast this to char* but I still need to calculate
    its' checksum somehow.
    For now I've written a special routine that calculates checksum
    specially for cmap table.
    What if I have to rebuild other 31 table? I have to write 31 checksum
    functions -- one for the table!
    There should be more elegant solution.

    Thank you.
     
    grishin-mailing-lists, Jul 3, 2010
    #1
    1. Advertisements

  2. grishin-mailing-lists

    Jonathan Lee Guest

    That's not going to be portable. Even if there isn't padding in
    in the struct, endianness can change across platforms. Maybe
    you're only supporting one platform, though.
    I think it makes more sense to provide a CRC routine that expects
    a certain format, and then provide member functions to convert
    your structs to this format. Usually a CRC would take raw
    "byte data" (I mean an array of unsigned chars). A well defined
    structure-to-byte-data conversion is usually named serialize().
    If you're exporting your font data to a particular file format
    on disk, this is probably identical or very similar. If you're
    not doing this, you'll probably want to google for "serialization".

    --Jonathan
     
    Jonathan Lee, Jul 3, 2010
    #2
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.