Changeset 94 for NEWT0/trunk

Show
Ignore:
Timestamp:
03/29/07 05:04:06 (20 months ago)
Author:
matthiasm
Message:

Added a rough version of the Package Writer.

NewtPkg now reads version 0 packages, converts it into a Newt Object hierarchy, and creates packages from such a hierarchy. My specific "Hello World" .pkg is binary identical after a full back and forth conversion. There is still a lot of debugging output in the source including a hardcoded file path. Next iteration will be cleaned thoroughly.

Location:
NEWT0/trunk/src/newt_core
Files:
2 modified

Legend:

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

    r92 r94  
    7474/// structure to manage the package reading process 
    7575typedef struct { 
    76     int8_t      verno;          ///< package version 0 or 1 
    77     uint8_t *   data;           ///< package data 
    78     uint32_t    size;           ///< size of package 
    79     pkg_header_t * header;      ///< pointer to the package header 
    80     uint8_t *   var_len_data;   ///< extra data for header 
    81     uint32_t    num_parts;      ///< number of parts in package 
    82     pkg_part_t* part_headers;   ///< pointer to first part header - can be used as an array 
    83     pkg_part_t* part_header;    ///< header of current part 
    84     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 
    87     newtErr     lastErr;        ///< a way to return error from deep below 
     76    int8_t      verno;          ///< r  package version 0 or 1 
     77    uint8_t *   data;           ///< rw package data 
     78    uint32_t    size;           ///< rw size of package 
     79    uint32_t    data_size;      ///< w  size of data block 
     80    pkg_header_t *header;       ///< r  pointer to the package header 
     81    uint32_t    header_size;    ///< w  size of header structure w/o var data 
     82    uint8_t *   var_data;       ///< r  extra data for header 
     83    uint32_t    var_data_size;  ///< w  size of variable length data block 
     84    uint32_t    num_parts;      ///< r  number of parts in package 
     85    pkg_part_t* part_headers;   ///< r  pointer to first part header - can be used as an array 
     86    pkg_part_t* part_header;    ///< r  header of current part 
     87    uint8_t *   part;           ///< r  start of current part data 
     88    uint32_t    part_offset;    ///< r  offset of current part to the beginning of data 
     89    newtRefVar  instances;      ///< rw array holding the previously generated instance of any ref per part 
     90    newtRefVar  precedents;     ///< w  array referencing the instances array 
     91    newtErr     lastErr;        ///< r  a way to return error from deep below 
    8892#ifdef HAVE_LIBICONV 
    89     iconv_t     from_utf16;     ///< strings in compatible packages are UTF16 
     93    iconv_t     from_utf16;     ///< r  strings in compatible packages are UTF16 
     94    iconv_t     to_utf16;       ///< w  strings in compatible packages are UTF16 
    9095#endif /* HAVE_LIBICONV */ 
    9196} pkg_stream_t; 
     
    9398 
    9499/* functions */ 
     100static newtRef  PkgPartGetPrecedent(pkg_stream_t *pkg, newtRefArg r); 
     101static void     PkgPartSetPrecedent(pkg_stream_t *pkg, newtRefArg r, newtRefArg val); 
     102 
     103static newtRef  PkgWriteObject(pkg_stream_t *pkg, newtRefArg obj); 
     104 
    95105static newtRef  PkgPartGetInstance(pkg_stream_t *pkg, uint32_t p_obj); 
    96106static void     PkgPartSetInstance(pkg_stream_t *pkg, uint32_t p_obj, newtRefArg r); 
     
    107117static newtRef  PkgReadHeader(pkg_stream_t *pkg); 
    108118 
     119/** Duplicate of same function in NSOF. 
     120 * Maybe we could make the original file publicly accessible 
     121 */ 
     122int32_t PkgArraySearch(newtRefArg array, newtRefArg r) 
     123{ 
     124    newtRef *   slots; 
     125    uint32_t    len; 
     126    uint32_t    i; 
     127 
     128    len = NewtArrayLength(array); 
     129    slots = NewtRefToSlots(array); 
     130 
     131    for (i = 0; i < len; i++) 
     132    { 
     133        if (slots[i] == r) 
     134            return i; 
     135    } 
     136 
     137    return -1; 
     138} 
     139 
     140/*------------------------------------------------------------------------*/ 
     141/** Verify if the give reference was already written to the package. 
     142 * 
     143 * @param pkg       [inout] the package 
     144 * @param ref       [in] the reference that we try to find 
     145 *  
     146 * @retval  ref to the previously written object 
     147 * @retval  or kNewtRefUnbind if the object still needs to be written 
     148 */ 
     149newtRef PkgPartGetPrecedent(pkg_stream_t *pkg, newtRefArg ref) 
     150{ 
     151    int32_t ix = PkgArraySearch(pkg->precedents, ref); 
     152    if (ix>=0) { 
     153        printf("*** Multiple: "); 
     154        NewtPrintObject(stdout, ref); 
     155        return NewtGetArraySlot(pkg->instances, ix); 
     156    } else { 
     157        return kNewtRefUnbind; 
     158    } 
     159} 
     160 
     161/*------------------------------------------------------------------------*/ 
     162/** Remember that a specific reference was already written. 
     163 * 
     164 * @param pkg       [inout] the package 
     165 * @param ref       [in] the original reference in memory 
     166 * @param val       [in] the reference needed to find this object in the package 
     167 */ 
     168void PkgPartSetPrecedent(pkg_stream_t *pkg, newtRefArg ref, newtRefArg val) 
     169{ 
     170    uint32_t n = NewtArrayLength(pkg->instances); 
     171    NewtInsertArraySlot(pkg->instances, n, val); 
     172    NewtInsertArraySlot(pkg->precedents, n, ref); 
     173} 
     174 
     175/*------------------------------------------------------------------------*/ 
     176/** Align the given value to 8 or 4 bytes. 
     177 *  
     178 * @param pkg       [inout] the package 
     179 * @param offset    [in] offset to be aligned 
     180 * 
     181 * @retval  new offset aligned to 8 bytes, or 4 bytes for the advance format 
     182 * 
     183 * @todo We shoudld add 4-byte alignment support at some point, so the  
     184 *       generated package is a bit smaller 
     185 */ 
     186uint32_t PkgAlign(pkg_stream_t *pkg, uint32_t offset) 
     187{ 
     188    return (offset+7)&(~7); 
     189} 
     190 
     191/*------------------------------------------------------------------------*/ 
     192/** Convenience function to get the integer value of a slot. 
     193 *  
     194 * @param frame     [in] find the slot in this frame 
     195 * @param name      [in] name of slot 
     196 * @param def       [in] default value if slot was not found 
     197 * 
     198 * @retval  value read if found, or default value if not found 
     199 */ 
     200uint32_t PkgGetSlotInt(newtRefArg frame, newtRefArg name, uint32_t def) 
     201{ 
     202    newtRef slot; 
     203    int32_t ix; 
     204     
     205    ix = NewtFindSlotIndex(frame, name); 
     206    if (ix<0) 
     207        return def; 
     208    slot = NewtGetArraySlot(frame, ix); 
     209    if (NewtRefIsInteger(slot)) { 
     210        return NewtRefToInteger(slot); 
     211    } else { 
     212        return def; 
     213    } 
     214} 
     215 
     216/*------------------------------------------------------------------------*/ 
     217/** Make some room for more data in the package 
     218 *  
     219 * @param pkg       [inout] the package 
     220 * @param offset    [in] offset where we will need room 
     221 * @param size  [in] number of bytes that we will need 
     222 */ 
     223void PkgMakeRoom(pkg_stream_t *pkg, uint32_t offset, uint32_t size) 
     224{ 
     225    uint32_t new_size = offset+size; 
     226 
     227    if (pkg->data_size<new_size) { 
     228        uint32_t os = pkg->data_size; 
     229        uint32_t ns = (new_size+16383) & (~16383); // alocate ein 16k blocks 
     230        pkg->data = realloc(pkg->data, ns); 
     231        memset(pkg->data+os, 0xbf, ns-os); // filler byte 
     232        pkg->data_size = ns; 
     233    } 
     234 
     235    if (pkg->size<new_size) 
     236        pkg->size = new_size; 
     237} 
     238 
     239/*------------------------------------------------------------------------*/ 
     240/** Write arbitrary data into the package at any position 
     241 *  
     242 * @param pkg       [inout] the package 
     243 * @param offset    [in] offset to the beginning of data 
     244 * @param data      [in] data to be copied to package 
     245 * @param size      [in] size of data block 
     246 */ 
     247void PkgWriteData(pkg_stream_t *pkg, uint32_t offset, void *data, uint32_t size) 
     248{ 
     249    if (pkg->data_size<offset+size)  
     250        PkgMakeRoom(pkg, offset, size); 
     251    if (pkg->size<offset+size) 
     252        pkg->size = offset+size; 
     253    memcpy(pkg->data+offset, data, size); 
     254} 
     255 
     256/*------------------------------------------------------------------------*/ 
     257/** Write a 32 bit integer into the package at any position 
     258 *  
     259 * @param pkg       [inout] the package 
     260 * @param offset    [in] offset to the beginning of data 
     261 * @param v         [in] value to be written  
     262 */ 
     263void PkgWriteU32(pkg_stream_t *pkg, uint32_t offset, uint32_t v) 
     264{ 
     265    v = htonl(v); 
     266    PkgWriteData(pkg, offset, &v, 4); 
     267} 
     268 
     269/*------------------------------------------------------------------------*/ 
     270/** Write the data in the object into the vardata section and generate the info ref 
     271 *  
     272 * @param pkg       [inout] the package 
     273 * @param offset    [in] whgere to write the info ref 
     274 * @param frame     [in] frame containing the data  
     275 * @param sym       [in] symbol of slot containing the data 
     276 */ 
     277void PgkWriteVarData(pkg_stream_t *pkg, uint32_t offset, newtRefVar frame, newtRefVar sym) 
     278{ 
     279    newtRef info; 
     280    uint32_t ix; 
     281     
     282    PkgWriteU32(pkg, offset, 0); 
     283 
     284    ix = NewtFindSlotIndex(frame, sym); 
     285    if (ix<0)  
     286        return; 
     287    info = NewtGetFrameSlot(frame, ix); 
     288    if (NewtRefIsBinary(info)) { 
     289        uint32_t size = NewtBinaryLength(info); 
     290        uint8_t *data = NewtRefToBinary(info); 
     291        pkg_info_ref_t info_ref; 
     292 
     293#       ifdef HAVE_LIBICONV 
     294            if (NewtRefIsString(info)) { 
     295                size_t buflen; 
     296                char *buf = NewtIconv(pkg->to_utf16, data, size, &buflen); 
     297                if (buf) { 
     298                    size = buflen; 
     299                    data = buf; 
     300                } 
     301            } 
     302#       endif /* HAVE_LIBICONV */ 
     303 
     304        info_ref.offset = htons(pkg->var_data_size); 
     305        info_ref.size = htons(size); 
     306 
     307        PkgWriteData(pkg, pkg->header_size + pkg->var_data_size, data, size); 
     308        PkgWriteData(pkg, offset, &info_ref, 4); 
     309 
     310        pkg->var_data_size += size;      
     311    } 
     312} 
     313 
     314/*------------------------------------------------------------------------*/ 
     315/** Append a frame object to the end of the Package 
     316 *  
     317 * @param pkg       [inout] the package 
     318 * @param frame     [in] the frame that we will write 
     319 * 
     320 * @retval  offset to the beginning of the object in the package file 
     321 */ 
     322newtRef PkgWriteFrame(pkg_stream_t *pkg, newtRefArg frame) 
     323{ 
     324    uint32_t dst, size, i, n; 
     325    newtRef map, map_pos; 
     326    newtRef slot, slot_pos; 
     327 
     328    // calculate the size of this chunk 
     329    dst = PkgAlign(pkg, pkg->size); 
     330    n = NewtFrameLength(frame); 
     331    size = (n+3)*4; 
     332 
     333    // make room for the entire chunk and write the header 
     334    PkgMakeRoom(pkg, dst, size); 
     335    PkgWriteU32(pkg, dst, (size<<8) | 0x40 | kObjSlotted | kObjFrame); 
     336    PkgWriteU32(pkg, dst+4, 0); 
     337 
     338    // recursively add all arrays making up the map 
     339    map = NewtFrameMap(frame); 
     340    map_pos = PkgWriteObject(pkg, map); 
     341    PkgWriteU32(pkg, dst+8, map_pos); 
     342 
     343    // now add all slots and fill in the rest of our chunk 
     344    for (i=0; i<n; i++) { 
     345        slot = NewtGetFrameSlot(frame, i); 
     346        slot_pos = PkgWriteObject(pkg, slot); 
     347        PkgWriteU32(pkg, dst+12+4*i, slot_pos); 
     348    } 
     349 
     350    return NewtMakePointer(dst); 
     351} 
     352 
     353/*------------------------------------------------------------------------*/ 
     354/** Append an array object to the end of the Package 
     355 *  
     356 * @param pkg       [inout] the package 
     357 * @param array     [in] the array that we will write 
     358 * 
     359 * @retval  offset to the beginning of the object in the package file 
     360 */ 
     361newtRef PkgWriteArray(pkg_stream_t *pkg, newtRefArg array) 
     362{ 
     363    uint32_t dst, size, i, n; 
     364    newtRef klass, klass_pos; 
     365    newtRef slot, slot_pos; 
     366 
     367    // calculate the size of this chunk 
     368    dst = PkgAlign(pkg, pkg->size); 
     369    n = NewtArrayLength(array); 
     370    size = (n+3)*4; 
     371 
     372    // make room for the entire chunk and write the header 
     373    PkgMakeRoom(pkg, dst, size); 
     374    PkgWriteU32(pkg, dst, (size<<8) | 0x40 | kObjSlotted); 
     375    PkgWriteU32(pkg, dst+4, 0); 
     376 
     377    // add the class information 
     378    klass = NcClassOf(array); 
     379    klass_pos = PkgWriteObject(pkg, klass); 
     380    PkgWriteU32(pkg, dst+8, klass_pos); 
     381 
     382    // now add all slots and fill in the rest of our chunk 
     383    for (i=0; i<n; i++) { 
     384        slot = NewtGetArraySlot(array, i); 
     385        slot_pos = PkgWriteObject(pkg, slot); 
     386        PkgWriteU32(pkg, dst+12+4*i, slot_pos); 
     387    } 
     388 
     389    return NewtMakePointer(dst); 
     390} 
     391 
     392/*------------------------------------------------------------------------*/ 
     393/** Append a binary object to the end of the Package 
     394 *  
     395 * @param pkg       [inout] the package 
     396 * @param obj       [in] the binary object that we will write 
     397 * 
     398 * @retval  offset to the beginning of the object in the package file 
     399 */ 
     400newtRef PkgWriteBinary(pkg_stream_t *pkg, newtRefArg obj) 
     401{ 
     402    uint32_t dst, size; 
     403    uint8_t *data; 
     404    newtRef klass, klass_ref = kNewtRefUnbind; 
     405 
     406    // calculate the size of this chunk 
     407    dst = PkgAlign(pkg, pkg->size); 
     408    size = NewtBinaryLength(obj); 
     409    data = NewtRefToBinary(obj); 
     410 
     411    // make room for the binary chunk and write the header 
     412    if (NewtRefIsSymbol(obj)) { 
     413        size = NewtSymbolLength(obj)+5; // remember the trailing zero! 
     414    } else if (NewtRefIsString(obj)) { 
     415#       ifdef HAVE_LIBICONV 
     416            size_t buflen; 
     417            char *buf = NewtIconv(pkg->to_utf16, data, size, &buflen); 
     418            if (buf) { 
     419                size = buflen; 
     420                data = buf; 
     421            } 
     422#       endif /* HAVE_LIBICONV */ 
     423    } 
     424    size += 12; 
     425 
     426    // make room for the binary chunk and write the header 
     427    PkgMakeRoom(pkg, dst, size); 
     428    PkgWriteU32(pkg, dst, (size<<8) | 0x40); 
     429    PkgWriteU32(pkg, dst+4, 0); 
     430 
     431    // symbols have special handling to avoid recursion 
     432    if (NewtRefIsSymbol(obj)) { 
     433        PkgWriteU32(pkg, dst+8, kNewtSymbolClass); 
     434        PkgWriteU32(pkg, dst+12, NewtRefToHash(obj)); // make sure the hash has the right endianness 
     435        PkgWriteData(pkg, dst+16, (uint8_t*)NewtSymbolGetName(obj), size-16); 
     436        return NewtMakePointer(dst); 
     437    } 
     438 
     439    // add the class information 
     440    klass = NcClassOf(obj); 
     441    klass_ref = PkgWriteObject(pkg, klass); 
     442    PkgWriteU32(pkg, dst+8, klass_ref); 
     443 
     444    // add a verbose copy of the binary data 
     445    PkgWriteData(pkg, dst+12, data, size-12); 
     446 
     447    return NewtMakePointer(dst); 
     448} 
     449 
     450/*------------------------------------------------------------------------*/ 
     451/** Append the object to the end of the Package 
     452 *  
     453 * @param pkg       [inout] the package 
     454 * @param obj       [in] the object that we will write 
     455 * 
     456 * @retval  offset to the beginning of the object in the package file 
     457 */ 
     458newtRef PkgWriteObject(pkg_stream_t *pkg, newtRefArg obj) 
     459{ 
     460    uint32_t dst = pkg->size; 
     461    newtRef prec; 
     462 
     463    if (NewtRefIsImmediate(obj)) { 
     464        printf("*** immediate: "); 
     465        NewtPrintObject(stdout, obj); 
     466        return obj; 
     467    }  
     468     
     469    prec = PkgPartGetPrecedent(pkg, obj); 
     470    if (prec!=kNewtRefUnbind) { 
     471        return prec; 
     472    } 
     473 
     474    if (NewtRefIsFrame(obj)) { 
     475        dst = PkgWriteFrame(pkg, obj); 
     476    } else if (NewtRefIsArray(obj)) { 
     477        dst = PkgWriteArray(pkg, obj); 
     478    } else if (NewtRefIsBinary(obj)) { 
     479        dst = PkgWriteBinary(pkg, obj); 
     480    } else { 
     481        printf("*** unsupported write: "); 
     482        NewtPrintObject(stdout, obj); 
     483        PkgMakeRoom(pkg, dst, 16); 
     484        PkgWriteU32(pkg, dst, 0xdeadbeef); 
     485        // FIXME add all possible types... 
     486    } 
     487 
     488    // make this ref available for later incarnations of the same object 
     489    PkgPartSetPrecedent(pkg, obj, dst); 
     490 
     491    return dst; 
     492} 
     493 
     494/*------------------------------------------------------------------------*/ 
     495/** Create a part in package format based on this object. 
     496 *  
     497 * @param pkg       [inout] the package 
     498 * @param part      [in] object containing part data 
     499 * 
     500 * @retval  ref to binary part data 
     501 */ 
     502newtRef PkgWritePart(pkg_stream_t *pkg, newtRefArg part) 
     503{ 
     504    uint32_t    dst = pkg->part_offset; 
     505    int32_t     ix; 
     506    newtRef     data; 
     507 
     508    ix = NewtFindSlotIndex(part, NSSYM(data)); 
     509    if (ix<0)  
     510        return kNewtRefNIL; 
     511    data = NewtGetFrameSlot(part, ix); 
     512 
     513    pkg->instances = NewtMakeArray(kNewtRefUnbind, 0); 
     514    pkg->precedents = NewtMakeArray(kNewtRefUnbind, 0); 
     515 
     516    PkgMakeRoom(pkg, dst, 16); 
     517    PkgWriteU32(pkg, dst,    0x00001041); 
     518    PkgWriteU32(pkg, dst+4,  0x00000000); 
     519    PkgWriteU32(pkg, dst+8,  0x00000002); 
     520    PkgWriteU32(pkg, dst+12, PkgWriteObject(pkg, data)); 
     521 
     522    NewtSetLength(pkg->precedents, 0); 
     523    NewtSetLength(pkg->instances, 0); 
     524 
     525    return kNewtRefNIL; 
     526} 
     527 
     528/*------------------------------------------------------------------------*/ 
     529/** Create a new binary object that conatins the object tree in package format 
     530 *  
     531 * @param rpkg  [in] object tree describing the package 
     532 * 
     533 * @retval  binary object with package 
     534 */ 
     535newtRef NewtWritePkg(newtRefArg package) 
     536{ 
     537    pkg_stream_t    pkg; 
     538    int32_t         num_parts, i, ix, directory_size; 
     539    newtRef         parts; 
     540     
     541    // setup pkg_stream_t 
     542    memset(&pkg, 0, sizeof(pkg)); 
     543 
     544#   ifdef HAVE_LIBICONV 
     545    {   char *encoding = NewtDefaultEncoding(); 
     546        pkg.to_utf16 = iconv_open("UTF-16BE", encoding); 
     547    } 
     548#   endif /* HAVE_LIBICONV */ 
     549 
     550    ix = NewtFindSlotIndex(package, NSSYM(parts)); 
     551    if (ix>=0) { 
     552        parts = NewtGetFrameSlot(package, ix); 
     553        num_parts = NewtFrameLength(parts); 
     554        pkg.header_size = sizeof(pkg_header_t) + num_parts * sizeof(pkg_part_t); 
     555 
     556        // start setting up the header with whatever we know 
     557            // sig 
     558        PkgWriteData(&pkg, 0, "package0", 8); 
     559            // type 
     560        PkgWriteData(&pkg, 8, "xxxx", 4); 
     561            // flags 
     562        PkgWriteU32(&pkg, 12, PkgGetSlotInt(package, NSSYM(flags), 0)); 
     563            // version 
     564        PkgWriteU32(&pkg, 16, PkgGetSlotInt(package, NSSYM(version), 0)); 
     565            // copyright 
     566        PgkWriteVarData(&pkg, 20, package, NSSYM(copyright)); 
     567            // name 
     568        PgkWriteVarData(&pkg, 24, package, NSSYM(name)); 
     569            // date 
     570        PkgWriteU32(&pkg, 32, 0xc2296aa5); // FIXME some fake creation date 
     571            // reserved2 
     572        PkgWriteU32(&pkg, 36, 0);  
     573            // reserved3 
     574        PkgWriteU32(&pkg, 40, 0);  
     575            // numParts 
     576        PkgWriteU32(&pkg, 48, num_parts); 
     577 
     578        // calculate the size of the header so we can correctly set our refs in the parts 
     579        for (i=0; i<num_parts; i++) { 
     580            newtRef part = NewtGetArraySlot(parts, i); 
     581            PgkWriteVarData(&pkg, sizeof(pkg_header_t) + i*sizeof(pkg_part_t) + 24, part, NSSYM(info)); 
     582        } 
     583 
     584        // the original file has this (c) message embedded 
     585        {   char msg[] = "Newton� ToolKit Package � 1992-1997, Apple Computer, Inc."; 
     586            PkgWriteData(&pkg, pkg.header_size + pkg.var_data_size, msg, sizeof(msg)); 
     587            pkg.var_data_size += sizeof(msg); 
     588        } 
     589 
     590        pkg.part_offset = directory_size = PkgAlign(&pkg, pkg.header_size + pkg.var_data_size); 
     591            // directorySize 
     592        PkgWriteU32(&pkg, 44, directory_size); 
     593 
     594        // create all parts 
     595        for (i=0; i<num_parts; i++) { 
     596            uint32_t part_size; 
     597            uint32_t hdr = sizeof(pkg_header_t) + i*sizeof(pkg_part_t); 
     598            newtRef part = NewtGetArraySlot(parts, i); 
     599 
     600            PkgWritePart(&pkg, part); 
     601            PkgMakeRoom(&pkg, PkgAlign(&pkg, pkg.size), 0); 
     602            part_size = pkg.size - pkg.part_offset; 
     603                // offset 
     604            PkgWriteU32(&pkg, hdr, pkg.part_offset - directory_size); 
     605                // size & size2 
     606            PkgWriteU32(&pkg, hdr+4, part_size); 
     607            PkgWriteU32(&pkg, hdr+8, part_size); 
     608                // type 
     609            // FIXME the 'type' field is actually always a fourcc like 'form' 
     610            // FIXME which Newt object should we use here? Binary? Int32? Symbol? 
     611            PkgWriteU32(&pkg, hdr+12, PkgGetSlotInt(part, NSSYM(type), 0x666f726d));  
     612                // reserved1 
     613            PkgWriteU32(&pkg, hdr+16, 0);  
     614                // flags 
     615            PkgWriteU32(&pkg, hdr+20, PkgGetSlotInt(part, NSSYM(flags), 0)); 
     616                // reserved2 
     617            PkgWriteU32(&pkg, hdr+28, 0);  
     618 
     619            pkg.part_offset += part_size; 
     620        } 
     621    } 
     622 
     623    // finish filling in the header 
     624        // size 
     625    PkgWriteU32(&pkg, 28, pkg.size); 
     626 
     627    // convert pkg_stream_t into binary package 
     628    // return new object 
     629 
     630    {   FILE *f = fopen("d:/home/matt/dev/Newton/ntk2/helloWRT.pkg", "wb"); 
     631        fwrite(pkg.data, 1, pkg.size, f); 
     632        fclose(f); 
     633    } 
     634 
     635#   ifdef HAVE_LIBICONV 
     636        iconv_close(pkg.to_utf16); 
     637#   endif /* HAVE_LIBICONV */ 
     638 
     639    return kNewtRefNIL; 
     640} 
    109641 
    110642/*------------------------------------------------------------------------*/ 
     
    216748            char *buf = NewtIconv(pkg->from_utf16, src, sze, &buflen); 
    217749            if (buf) { 
    218                 result = NewtMakeString2(buf, buflen, false); 
     750                result = NewtMakeString2(buf, buflen-1, false); // NewtMakeString2 appends another null 
    219751            } 
    220752#       endif /* HAVE_LIBICONV */ 
     
    444976        return kNewtRefNIL; 
    445977    } else { 
    446         uint8_t *src = pkg->var_len_data + ntohs(info_ref->offset); 
     978        uint8_t *src = pkg->var_data + ntohs(info_ref->offset); 
    447979        int size = ntohs(info_ref->size); 
    448980        return NewtMakeBinary(kNewtRefUnbind, src, size, true); 
     
    463995        return kNewtRefNIL; 
    464996    } else { 
    465         char *src = pkg->var_len_data + ntohs(info_ref->offset); 
     997        char *src = pkg->var_data + ntohs(info_ref->offset); 
    466998        int size = ntohs(info_ref->size); 
    467999#       ifdef HAVE_LIBICONV 
     
    4691001            char *buf = NewtIconv(pkg->from_utf16, src, size, &buflen); 
    4701002            if (buf) { 
    471                 return NewtMakeString2(buf, buflen, false); 
     1003                return NewtMakeString2(buf, buflen-1, false); 
    4721004            } 
    4731005#       endif /* HAVE_LIBICONV */ 
     
    4961028    newtRefVar  parts; 
    4971029 
    498     NcSetSlot(frame, NSSYM(version), NSINT(pkg->verno)); 
     1030    NcSetSlot(frame, NSSYM(flags), NewtMakeInt32(ntohl(pkg->header->flags))); 
     1031    NcSetSlot(frame, NSSYM(version), NewtMakeInt32(ntohl(pkg->header->version))); 
    4991032    NcSetSlot(frame, NSSYM(copyright), PkgReadVardataString(pkg, &pkg->header->copyright)); 
    5001033    NcSetSlot(frame, NSSYM(name), PkgReadVardataString(pkg, &pkg->header->name)); 
    501     NcSetSlot(frame, NSSYM(flags), NewtMakeInt32(ntohl(pkg->header->flags))); 
    5021034    // all other header values can be derived form the archive itself 
    5031035    // or can be calculated at creation time 
     
    5481080    pkg.num_parts = ntohl(pkg.header->numParts); 
    5491081    pkg.part_headers = (pkg_part_t*)(data + sizeof(pkg_header_t)); 
    550     pkg.var_len_data = data + sizeof(pkg_header_t) + pkg.num_parts*sizeof(pkg_part_t); 
     1082    pkg.var_data = data + sizeof(pkg_header_t) + pkg.num_parts*sizeof(pkg_part_t); 
    5511083#   ifdef HAVE_LIBICONV 
    5521084    {   char *encoding = NewtDefaultEncoding(); 
  • NEWT0/trunk/src/newt_core/incs/NewtPkg.h

    r89 r94  
    2323 
    2424newtRef     NewtReadPkg(uint8_t * data, size_t size); 
     25newtRef     NewtWritePkg(newtRefArg pkg); 
    2526 
    2627