diff -r 000000000000 -r ca70ae20a155 src/tools/py2sis/ensymble/rscfile.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/tools/py2sis/ensymble/rscfile.py Tue Feb 16 10:07:05 2010 +0530 @@ -0,0 +1,202 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +############################################################################## +# rscfile.py - Symbian OS compiled resource file (RSC) utilities +# Copyright 2006, 2007 Jussi Ylänen +# +# This file is part of Ensymble developer utilities for Symbian OS(TM). +# +# Ensymble is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# Ensymble is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ensymble; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +############################################################################## + +import struct + +import symbianutil + + +############################################################################## +# Module-level functions which are normally only used by this module +############################################################################## + +def makeuidfromoffset(offset): + '''Convert a Symbian OS resource file offset to a UID. + + ---- From rcomp v7.01 source ---- + space: 0, A: 1, B: 2, ..., Z: 26 + + ABCD corresponds to the number 4321 which becomes + ((4*27 + 3) * 27 + 2) * 27 + 1. + ---- ---- + + The description above contains an error. The actual situation + is reversed: ABCD corresponds to the number 1234 which results in + ((1*27 + 2) * 27 + 3) * 27 + 4. + ''' + + if len(offset) not in range(1, 5): + raise ValueError("offset must be four characters or less") + uid = 0L + offset = offset.upper() + for c in offset: + try: + ordc = " ABCDEFGHIJKLMNOPQRSTUVWXYZ".index(c) + except ValueError: + raise ValueError("invalid character '%s' in offset" % c) + uid *= 27 + uid += ordc + return uid + + +############################################################################## +# Resource class for containing binary fields +############################################################################## + +class Resource(object): + '''A Symbian OS resource type + + Limitations: + + - Write only + - Available types are limited to BYTE, WORD, LONG, LLINK and LTEXT. + - Unicode compression is not supported.''' + + def __init__(self, fieldtypes, *args): + self.fieldtypes = fieldtypes + self.fieldvalues = [] + + if len(self.fieldtypes) != len(args): + raise ValueError("invalid number of field values") + + offset = 0 + for n in xrange(len(args)): + ftype = self.fieldtypes[n] + fval = args[n] + if ftype == "BYTE": + if fval < 0: + fval += 0x100 + if fval < 0 or fval > 255: + raise ValueError("byte integer too large") + self.fieldvalues.append(struct.pack(" 65535: + raise ValueError("word integer too large") + self.fieldvalues.append(struct.pack(" 4294967295: + raise ValueError("long integer too large") + self.fieldvalues.append(struct.pack(" 255: + raise ValueError("Unicode string too long") + self.fieldvalues.append(struct.pack(" 0: + if (offset & 1) != 0: + # Odd offset. Add padding byte (only if length > 0). + self.fieldvalues.append(struct.pack("B", 0xab)) + offset += 1 + fval_enc = fval.encode("UTF-16LE") + self.fieldvalues.append(fval_enc) + offset += len(fval_enc) + + # TODO: Arrays, recursive structs + # TODO: TEXT, DOUBLE, BUF, BUF8, BUF, LINK, SRLINK + + def tostring(self): + return "".join(self.fieldvalues) + + # TODO: fromstring() + + +############################################################################## +# RSCWriter class for creating Symbian OS compiled resource files (RSC) +############################################################################## + +class RSCWriter(object): + '''A Symbian OS compiled resource file (RSC) file generator + + Limitations: + + - Output format is always "Compressed Unicode resource format". + - Despite the format name, nothing is compressed.''' + + def __init__(self, uid2, uid3 = None, offset = None): + self.resources = [] + + if ((uid3 == None and offset == None) or + (uid3 != None and offset != None)): + raise AttributeError("one of uid3 or offset required, not both") + + self.flags = 0x00 + if offset != None: + try: + uid3 = makeuidfromoffset(offset) + except: + raise ValueError("invalid offset '%s'" % offset) + self.flags = 0x01 + + self.uid2 = uid2 + self.uid3 = uid3 + + def addresource(self, resource): + self.addrawresource(resource.tostring()) + + def addrawresource(self, string): + self.resources.append(string) + + def tostring(self): + # UIDs (UID1 always 0x101f4a6b) + fields = [symbianutil.uidstostring(0x101f4a6bL, self.uid2, self.uid3)] + + # Flags + fields.append(struct.pack(" maxrlen: + maxrlen = rlen + offsets.append(foffset) + fields.append(res) + foffset += rlen + offsets.append(foffset) + + # Update longest resource. + fields[2] = struct.pack("