Changeset 91 for NEWT0/trunk

Show
Ignore:
Timestamp:
03/27/07 22:18:22 (20 months ago)
Author:
matthiasm
Message:

NewtPkg : Package Reader implementation finished and tested on a bunch of existing packages. Although I can not yet test the integrity and completeness of the generated objects, packages seem to be read well. There may be features missing that go beyond NewtonFormats2.0. ANy input is greatly appreciated.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • NEWT0/trunk/src/newt_core/NewtPkg.c

    r90 r91  
    8383    pkg_part_t* part_header;    ///< header of current part 
    8484    uint8_t *   part;           ///< start of current part data 
     85    uint32_t    part_offset;    ///< offset of current part to the beginning of data 
     86    newtRefVar  instances;      ///< array holding the previously generated instance of any ref per part 
    8587    newtErr     lastErr;        ///< a way to return error from deep below 
    8688#ifdef HAVE_LIBICONV 
     
    9395uint32_t PkgReadU32(uint8_t *d); 
    9496 
     97newtRef PkgPartGetInstance(pkg_stream_t *pkg, uint32_t p_obj); 
     98void    PkgPartSetInstance(pkg_stream_t *pkg, uint32_t p_obj, newtRefArg r); 
     99 
    95100newtRef PkgReadRef(pkg_stream_t *pkg, uint32_t p_obj); 
    96101newtRef PkgReadBinaryObject(pkg_stream_t *pkg, uint32_t p_obj); 
     
    120125 
    121126/*------------------------------------------------------------------------*/ 
    122 /** Generate a ref from package data 
     127/** Check if there was already an object created for the given offset. 
     128 *  
     129 * @param pkg       [inout] the package 
     130 * @param p_obj     [in] offset to object 
     131 * 
     132 * @retval  ref to previously create object or kNewtRefUnbind 
     133 */ 
     134newtRef PkgPartGetInstance(pkg_stream_t *pkg, uint32_t p_obj) 
     135{ 
     136    uint32_t ix = (p_obj - pkg->part_offset) / 4; 
     137    return NewtGetArraySlot(pkg->instances, ix); 
     138} 
     139 
     140/*------------------------------------------------------------------------*/ 
     141/** Set the object ref for the given offset in the file 
     142 *  
     143 * @param pkg       [inout] the package 
     144 * @param r         [in] ref to new object 
     145 * @param p_obj     [in] offset into data block 
     146 */ 
     147void PkgPartSetInstance(pkg_stream_t *pkg, uint32_t p_obj, newtRefArg r) 
     148{ 
     149    uint32_t ix = (p_obj - pkg->part_offset) / 4; 
     150    NewtSetArraySlot(pkg->instances, ix, r); 
     151} 
     152 
     153/*------------------------------------------------------------------------*/ 
     154/** Interprete a ref in the Package data block. 
    123155 *  
    124156 * @param pkg       [inout] the package 
    125157 * @param p_obj     [in] offset to Ref data relative to package start 
    126158 * 
    127  * @retval  Newt object version of package Ref 
     159 * @retval  Newt version of Package Ref 
    128160 */ 
    129161newtRef PkgReadRef(pkg_stream_t *pkg, uint32_t p_obj) 
     
    144176        else if (ref&0x0f==0x0a) result = NewtMakeCharacter(ref>>4); 
    145177        else if (ref==kNewtSymbolClass) result = kNewtSymbolClass; 
    146         else if (ref==0x32) { 
    147             result = 0x32; 
    148             printf("*** PkgReader: PkgReadRef - unsupported ref 0x%08x - what is this?\n", ref); 
    149         } else { 
     178        else { 
    150179#           ifdef DEBUG_PKG 
    151                 printf("*** PkgReader: PkgReadRef - unsupported ref 0x%08x\n", ref); 
     180                printf("*** PkgReader: PkgReadRef - unknown ref 0x%08x\n", ref); 
    152181#           endif 
    153182            result = ref;  
     
    156185    case 3: // magic pointer 
    157186#       ifdef __NAMED_MAGIC_POINTER__ 
    158             result = kNewtRefNIL; // no timplemented 
     187            result = kNewtRefNIL; // not implemented 
    159188#       else 
    160189            result = ref; // already a correct magic pointer 
     
    167196 
    168197/*------------------------------------------------------------------------*/ 
    169 /** Generate a binary object from package data 
     198/** Generate a binary object from Package data 
    170199 *  
    171200 * @param pkg       [inout] the package 
     
    224253 
    225254/*------------------------------------------------------------------------*/ 
    226 /** Generate an array from package data 
     255/** Generate an Array Object from Package data 
    227256 *  
    228257 * @param pkg       [inout] the package 
     
    252281 
    253282/*------------------------------------------------------------------------*/ 
    254 /** Generate a frame from package data 
     283/** Generate a Frame Object from Package data 
    255284 *  
    256285 * @param pkg       [inout] the package 
     
    291320{ 
    292321    uint32_t obj = PkgReadU32(pkg->data + p_obj); 
    293     newtRef ret = kNewtRefNIL; 
    294  
     322    newtRef ret = PkgPartGetInstance(pkg, p_obj); 
     323 
     324    // avoid generating objects twice 
     325    if (ret!=kNewtRefUnbind) 
     326        return ret; 
     327 
     328    // create an object based on its low 8 bit type 
    295329    switch (obj & 0xff) { 
    296330    case 0x40: // binary object 
     
    310344        break; 
    311345    } 
     346 
     347    // remember that we created this object 
     348    PkgPartSetInstance(pkg, p_obj, ret); 
     349 
    312350    return ret; 
    313351} 
     
    322360newtRef PkgReadNOSPart(pkg_stream_t *pkg) 
    323361{ 
    324     uint32_t p_obj = PkgReadU32(pkg->part+12); 
    325     return PkgReadObject(pkg, p_obj&~3); 
     362    uint32_t    p_obj; 
     363    newtRefVar  result; 
     364 
     365    // verify that we have a correct header  
     366    if (PkgReadU32(pkg->part)!=0x00001041 || PkgReadU32(pkg->part+8)!=0x00000002) { 
     367#       ifdef DEBUG_PKG 
     368        printf("*** PkgReader: PkgReadPart - unsupported NOS Part intro at %d\n", 
     369            pkg->part-pkg->data); 
     370#       endif 
     371        return kNewtRefNIL; 
     372    } 
     373     
     374    // create an array that holds a ref to all creted objects, avoiding double instantiation 
     375    if (pkg->instances)  
     376        NewtSetLength(pkg->instances, ntohl(pkg->part_header->size)/4); 
     377    else 
     378        pkg->instances = NewtMakeArray(kNewtRefUnbind, ntohl(pkg->part_header->size)/4); 
     379 
     380    // now recursively load all objects 
     381    p_obj = PkgReadU32(pkg->part+12); 
     382    result = PkgReadObject(pkg, p_obj&~3); 
     383 
     384    // release our helper array 
     385    NewtSetLength(pkg->instances, 0); 
     386 
     387    return result; 
    326388} 
    327389 
     
    347409 
    348410    pkg->part_header = pkg->part_headers + index; 
    349     pkg->part = pkg->data  
    350                 + ntohl(pkg->header->directorySize)  
    351                 + ntohl(pkg->part_header->offset); 
     411    pkg->part_offset = ntohl(pkg->header->directorySize) + ntohl(pkg->part_header->offset); 
     412    pkg->part = pkg->data + pkg->part_offset; 
    352413    flags = ntohl(pkg->part_header->flags); 
    353414 
     
    360421    switch (flags&0x03) { 
    361422    case kNOSPart: 
    362         if (   PkgReadU32(pkg->part)  !=0x00001041 
    363             || PkgReadU32(pkg->part+8)!=0x00000002)  
    364         { 
    365 #           ifdef DEBUG_PKG 
    366                 printf("*** PkgReader: PkgReadPart - unsupported NOS Part intro at %d\n", 
    367                     pkg->part-pkg->data); 
    368 #           endif 
    369             break; 
    370         } 
    371423        NcSetSlot(frame, NSSYM(info), PkgReadVardataBinary(pkg, &pkg->part_header->info)); 
    372424        NcSetSlot(frame, NSSYM(data), PkgReadNOSPart(pkg));