1/*********************************************************************
2 *   Copyright 1993, UCAR/Unidata
3 *   See netcdf/COPYRIGHT file for copying and redistribution conditions.
4 *   $Header: /upc/share/CVS/netcdf-3/ncgen/genj.c,v 1.2 2010/05/17 23:26:44 dmh Exp $
5 *********************************************************************/
6
7#include "includes.h"
8#include "nc_iter.h"
9
10#ifdef ENABLE_JAVA
11
12#undef EXCEPTWRAP
13
14#undef TRACE
15
16/*MNEMONIC*/
17#define USEMEMORY 1
18
19extern Listvlenconstants;  /* List<Constant*>;*/
20
21/* Forward */
22static void genj_definevardata(Symbolvsym);
23
24static const char* jtypeallcaps(nc_type type);
25static const char* jtypecap(nc_type type);
26static const char* jtype(nc_type type);
27static const char* jarraytype(nc_type type);
28static const char* jname(Symbolsym);
29
30static void genj_defineattr(Symbolasym);
31static void genj_definevardata(Symbol*);
32static void genj_write(Generator*,SymbolsymBytebuffercode,
33                       int rank, size_t* start, size_t* count);
34static void genj_writevar(Generator*,Symbol*,Bytebuffer*,int,size_t*,size_t*);
35static void genj_writeattr(Generator*,Symbol*,Bytebuffer*,int,size_t*,size_t*);
36
37/*
38 * Generate code for creating netCDF from in-memory structure.
39 */
40void
41gen_ncjava(const char *filename)
42{
43    int idimivariattmaxdims;
44    int ndimsnvarsnattsngatts;
45
46    ndims = listlength(dimdefs);
47    nvars = listlength(vardefs);
48    natts = listlength(attdefs);
49    ngatts = listlength(gattdefs);
50
51    /* Construct the main class */
52    codeline("import java.util.*;");
53    codeline("import ucar.ma2.*;");
54    codeline("import ucar.nc2.*;");
55    codeline("import ucar.nc2.NetcdfFile.*;");
56
57    codeline("");
58    codepartial("public class ");
59    codeline(mainname);
60    codeline("{");
61
62    /* Now construct the main procedure*/
63
64    codeline("");
65    codeline("static public void main(String[] argv) throws Exception");
66    codeline("{");
67
68    /* create necessary declarations */
69
70    if(ndims > 0) {
71 codeline("");
72 codelined(1,"/* dimension lengths */");
73 for(idim = 0; idim < ndimsidim++) {
74     Symboldsym = (Symbol*)listget(dimdefs,idim);
75     if(dsym->dim.declsize == NC_UNLIMITED) {
76 bbprintf0(stmt,"%sfinal int %s_len = 0;\n",
77 indented(1),jname(dsym));
78     } else {
79 bbprintf0(stmt,"%sfinal int %s_len = %lu;\n",
80 indented(1),
81 jname(dsym),
82 (unsigned long) dsym->dim.declsize);
83     }
84     codedump(stmt);
85 }
86    }
87    codeflush();
88
89    maxdims = 0; /* most dimensions of any variable */
90    for(ivar = 0; ivar < nvarsivar++) {
91      Symbolvsym = (Symbol*)listget(vardefs,ivar);
92      if(vsym->typ.dimset.ndims > maxdims)
93 maxdims = vsym->typ.dimset.ndims;
94    }
95
96    codeline("");
97#ifdef EXCEPTWRAP
98    codelined(1,"try {");
99#endif
100
101    /* create netCDF file, uses NC_CLOBBER mode */
102    codeline("");
103    codelined(1,"/* enter define mode */");
104
105    bbprintf0(stmt,
106                "%sNetcdfFileWriteable ncfile = NetcdfFileWriteable.createNew(\"%s\", %s);\n",
107  indented(1),filename,(nofill_flag?"false":"true"));
108    codedump(stmt);
109    codeflush();
110
111    /* define dimensions from info in dims array */
112    if(ndims > 0) {
113 codeline("");
114 codelined(1,"/* define dimensions */");
115        for(idim = 0; idim < ndimsidim++) {
116            Symboldsym = (Symbol*)listget(dimdefs,idim);
117     if(dsym->dim.declsize == NC_UNLIMITED) {
118                bbprintf0(stmt,"%sDimension %s_dim = ncfile.addUnlimitedDimension(\"%s\");\n",
119                    indented(1),jname(dsym),jescapifyname(dsym->name));
120     } else {
121                bbprintf0(stmt,"%sDimension %s_dim = ncfile.addDimension(\"%s\", %s_len);\n",
122                    indented(1),jname(dsym),jescapifyname(dsym->name), jname(dsym));
123     }
124            codedump(stmt);
125       }
126       codeflush();
127    }
128
129    /* define variables from info in vars array */
130    if(nvars > 0) {
131        codeline("");
132        codelined(1,"/* define variables */");
133        for(ivar = 0; ivar < nvarsivar++) {
134            Symbolvsym = (Symbol*)listget(vardefs,ivar);
135            Symbolbasetype = vsym->typ.basetype;
136            Dimsetdimset = &vsym->typ.dimset;
137            codeline("");
138            bbprintf0(stmt,"%sArrayList %s_dimlist = new ArrayList();\n",
139                                        indented(1),jname(vsym));
140            codedump(stmt);
141            if(dimset->ndims > 0) {
142                for(idim = 0; idim < dimset->ndimsidim++) {
143                    Symboldsym = dimset->dimsyms[idim];
144                    bbprintf0(stmt,"%s%s_dimlist.add(%s_dim);\n",
145                            indented(1),jname(vsym),jname(dsym));
146                    codedump(stmt);
147                }
148     }
149            bbprintf0(stmt,
150                            "%sncfile.addVariable(\"%s\", DataType.%s, %s_dimlist);\n",
151     indented(1),
152                            jescapifyname(vsym->name),
153                            jtypeallcaps(basetype->typ.typecode),
154                            jname(vsym));
155            codedump(stmt);
156        }
157        codeflush();
158    }
159
160    /* Define the global attributes*/
161    if(ngatts > 0) {
162        codeline("");
163        codelined(1,"/* assign global attributes */");
164        for(iatt = 0; iatt < ngattsiatt++) {
165            Symbolgasym = (Symbol*)listget(gattdefs,iatt);
166            genj_defineattr(gasym);
167        }
168        codeline("");
169        codeflush();
170    }
171
172    /* Define the variable specific attributes*/
173    if(natts > 0) {
174        codeline("");
175        codelined(1,"/* assign per-variable attributes */");
176        for(iatt = 0; iatt < nattsiatt++) {
177            Symbolasym = (Symbol*)listget(attdefs,iatt);
178            genj_defineattr(asym);
179        }
180        codeline("");
181        codeflush();
182    }
183
184    codelined(1,"ncfile.create();"); /* equiv to nc_enddef */
185
186    if(!header_only) {
187        /* Load values into those variables with defined data */
188        if(nvars > 0) {
189            codeline("");
190            codelined(1,"/* assign variable data */");
191            for(ivar = 0; ivar < nvarsivar++) {
192                Symbolvsym = (Symbol*)listget(vardefs,ivar);
193                if(vsym->data != NULLgenj_definevardata(vsym);
194            }
195            codeline("");
196        }
197    }
198
199    codeflush();
200
201}
202
203void
204cl_java(void)
205{
206    codelined(1,"ncfile.close();");
207    codeline("");
208#ifdef EXCEPTIONWRAP
209    codelined(1,"} catch(Exception e) {e.printStackTrace();};");
210#endif
211    codelined(1,"}"); /* main */
212    codeline("}"); /* class Main */
213    codeflush();
214}
215
216const char*
217jtypeallcaps(nc_type type)
218{
219    switch (type) {
220      case NC_CHAR: return "CHAR";
221      case NC_BYTE: return "BYTE";
222      case NC_SHORT: return "SHORT";
223      case NC_INT: return "INT";
224      case NC_FLOAT: return "FLOAT";
225      case NC_DOUBLE: return "DOUBLE";
226      case NC_UBYTE: return "LONG";
227      case NC_USHORT: return "LONG";
228      case NC_UINT: return "LONG";
229      case NC_INT64: return "LONG";
230      case NC_UINT64: return "LONG";
231      case NC_STRING: return "STRING";
232      default: PANIC1("ncctype: bad type code:%d",type);
233    }
234    return 0;
235}
236
237static const char*
238jtypecap(nc_type type)
239{
240    switch (type) {
241      case NC_CHAR: return "Char";
242      case NC_BYTE: return "Byte";
243      case NC_SHORT: return "Short";
244      case NC_INT: return "Int";
245      case NC_FLOAT: return "Float";
246      case NC_DOUBLE: return "Double";
247      case NC_UBYTE: return "Long";
248      case NC_USHORT: return "Long";
249      case NC_UINT: return "Long";
250      case NC_INT64: return "Long";
251      case NC_UINT64: return "Long";
252      case NC_STRING: return "String";
253      case NC_ENUM: return "Int";
254      case NC_OPAQUE: return "String";
255      default: PANIC1("ncctype: bad type code:%d",type);
256    }
257    return 0;
258}
259
260void
261jquotestring(Bytebufferdatabuf, char quote)
262{
263    char* escaped = jescapify(bbContents(databuf),'"',bbLength(databuf));
264    bbClear(databuf);
265    bbAppend(databuf,quote);
266    if(escaped != NULLbbCat(databuf,escaped);
267    bbAppend(databuf,quote);
268}
269
270/* Compute the name for a given symbol*/
271/* Cache in symbol->lname*/
272static const char*
273jname(Symbolsym)
274{
275    char* name;
276    assert (sym->fqn != NULL);
277    /* convert to language form*/
278    name = codify(sym->fqn); /* convert to usable form*/
279    return name;
280}
281
282
283/*
284 * Return java type name for netCDF type, given type code.
285 */
286static const char*
287jtype(nc_type type)
288{
289    switch (type) {
290      case NC_CHAR: return "char";
291      case NC_BYTE: return "byte";
292      case NC_SHORT: return "short";
293      case NC_INT: return "int";
294      case NC_FLOAT: return "float";
295      case NC_DOUBLE: return "double";
296      case NC_UBYTE: return "long";
297      case NC_USHORT: return "long";
298      case NC_UINT: return "long";
299      case NC_INT64: return "long";
300      case NC_UINT64: return "long";
301      case NC_STRING: return "String";
302      case NC_ENUM: return "int";
303      case NC_OPAQUE: return "String";
304      default: PANIC1("ncctype: bad type code:%d",type);
305    }
306    return 0;
307}
308
309/*
310 * Return a type name and dimensions for constant arrays
311 * for netCDF type, given type code.
312 */
313static const char*
314jarraytype(nc_type type)
315{
316    switch (type) {
317      case NC_CHAR:
318 return "String";
319      case NC_BYTE:
320 return "byte";
321      case NC_SHORT:
322 return "short";
323      case NC_INT:
324 return "int";
325      case NC_FLOAT:
326 return "float";
327      case NC_DOUBLE:
328 return "double";
329      case NC_UBYTE:
330 return "long";
331      case NC_USHORT:
332 return "long";
333      case NC_UINT:
334 return "long";
335      case NC_INT64:
336 return "long";
337      case NC_UINT64:
338 return "long";
339      case NC_STRING:
340 return "String";
341      case NC_ENUM:
342 return "int";
343      case NC_OPAQUE:
344 return "String";
345      default:
346 PANIC1("ncctype: bad type code:%d",type);
347    }
348    return 0;
349}
350
351/*
352 * Return netcdf interface type name for netCDF type suffix, given type code.
353 */
354const char*
355jstype(nc_type nctype)
356{
357    switch (nctype) {
358      case NC_CHAR:
359 return "text";
360      case NC_BYTE:
361 return "schar";
362      case NC_SHORT:
363 return "short";
364      case NC_INT:
365 return "int";
366      case NC_FLOAT:
367 return "float";
368      case NC_DOUBLE:
369 return "double";
370      case NC_UBYTE:
371 return "ubyte";
372      case NC_USHORT:
373 return "ushort";
374      case NC_UINT:
375 return "uint";
376      case NC_INT64:
377 return "longlong";
378      case NC_UINT64:
379 return "ulonglong";
380      case NC_STRING:
381 return "string";
382      case NC_OPAQUE:
383 return "opaque";
384      case NC_ENUM:
385 return "enum";
386      default:
387 derror("ncstype: bad type code: %d",nctype);
388 return 0;
389    }
390}
391
392static void
393genj_defineattr(Symbolasym)
394{
395    Bytebuffercode; /* capture so we can dump vlens first */
396    ASSERT(asym->data != NULL);
397    code = bbNew();
398    generator_reset(j_generator,NULL);
399    generate_attrdata(asym,j_generator,(Writer)genj_write,code);
400    bbFree(code);
401}
402
403
404static void
405genj_definevardata(Symbolvsym)
406{
407    Bytebuffercode; /* capture so we can dump vlens first */
408    if(vsym->data == NULL) return;
409    code = bbNew();
410    generator_reset(j_generator,NULL);
411    generate_vardata(vsym,j_generator,(Writer)genj_write,code);
412    bbFree(code);
413}
414
415static void
416genj_write(GeneratorgeneratorSymbolsymBytebuffercode,
417           int rank, size_t* start, size_t* count)
418{
419    if(sym->objectclass == NC_ATT)
420 genj_writeattr(generator,sym,code,rank,start,count);
421    else if(sym->objectclass == NC_VAR)
422 genj_writevar(generator,sym,code,rank,start,count);
423    else
424 PANIC("illegal symbol for genj_write");
425}
426
427static void
428genj_writevar(GeneratorgeneratorSymbolvsymBytebuffercode,
429              int rank, size_t* start, size_t* count)
430{
431    Dimsetdimset = &vsym->typ.dimset;
432    int typecode = vsym->typ.basetype->typ.typecode;
433    int i;
434
435    codeline("");
436    codelined(1,"{"); /* Enclose in {...} for scoping */
437
438    if(rank == 0) {
439        bbprintf0(stmt,"%sArray%s.D0 data = new Array%s.D0();\n",
440 indented(1),jtypecap(typecode), jtypecap(typecode));
441        codedump(stmt);
442        if(typecode == NC_CHAR) {
443            /* Construct the data Array */
444            jquotestring(code,'\'');
445     bbprintf0(stmt,"%sdata.set((char)%s);\n",
446   indented(1),bbContents(code));
447 } else {
448     commify(code);
449            bbprintf0(stmt,"%sdata.set((%s)%s);\n",
450         indented(1),jtype(typecode),bbContents(code));
451        }
452 codedump(stmt);
453        /* do the actual write */
454        bbprintf0(stmt,"%sncfile.write(\"%s\",data);\n",
455 indented(1),jescapifyname(vsym->name));
456 codedump(stmt);
457    } else { /* array */
458 Bytebufferdimbuf = bbNew();
459        /* Construct the dimension set*/
460 bbCat(dimbuf,"new int[]{");
461 for(i=0;i<rank;i++) {
462            Symboldsym = dimset->dimsyms[i];
463     char tmp[32];
464     nprintf(tmp,sizeof(tmp),"%lu",dsym->dim.declsize);
465     if(i>0) {bbCat(dimbuf,", ");}
466     bbCat(dimbuf,tmp);
467 }
468 bbCat(dimbuf,"}");
469        /* Construct the data array and capture its index */
470 if(typecode == NC_CHAR) {
471     jquotestring(code,'"');
472            bbprintf0(stmt,"%sString contents = ",
473 indented(1));
474 } else {
475            bbprintf0(stmt,"%s%s[] contents = new %s[] {",
476 indented(1),jtype(typecode),jtype(typecode));
477     commify(code);
478 }
479 codedump(stmt);
480        codedump(code);
481        if(typecode != NC_CHARcodepartial("}");
482        codeline(";");
483        bbprintf0(stmt,"%sArray%s data = new Array%s(%s);\n",
484 indented(1),
485 jtypecap(typecode),
486 jtypecap(typecode),
487 bbContents(dimbuf));
488        codedump(stmt);
489        codelined(1,"IndexIterator iter = data.getIndexIterator();");
490        codelined(1,"int count = 0;");
491        codelined(1,"while(iter.hasNext())");
492 if(typecode == NC_CHAR)
493            bbprintf0(stmt,
494 "%siter.setCharNext(contents.charAt(count++));\n",indented(2));
495 else
496            bbprintf0(stmt,"%siter.set%sNext(contents[count++]);\n",
497                    indented(2),jtypecap(typecode));
498 codedump(stmt);
499        bbFree(dimbuf);
500 /* Construct the origin set from the start set */
501        bbprintf0(stmt,"%sint[] origin = new int[]{",indented(1));
502 for(i=0;i<rank;i++) {
503     bbprintf(stmt,"%s%lu",(i>0?", ":""),start[i]);
504 }
505 bbCat(stmt,"};\n");
506 codedump(stmt);
507        /* do the actual write */
508        bbprintf0(stmt,"%sncfile.write(\"%s\",origin,data);\n",
509 indented(1),jescapifyname(vsym->name));
510 codedump(stmt);
511    }
512    codelined(1,"}"); /* Enclose in {...} for scoping */
513    codeflush();
514}
515
516static void
517genj_writeattr(GeneratorgeneratorSymbolasymBytebuffercode,
518               int rank, size_t* start, size_t* count)
519{
520    Symbolbasetype = asym->typ.basetype;
521    nc_type typecode = basetype->typ.typecode;
522    /* default assumption */
523    size_t len = asym->data == NULL?0:asym->data->length;
524
525    codeprintf("%s/* attribute: %s */\n",indented(1),asym->name);
526
527    /* Handle NC_CHAR specially */
528    if(typecode == NC_CHAR) {
529        /* revise the length count */
530        len = bbLength(code);
531        if(len == 0) {
532     bbAppend(code,'\0'); len++;
533     bbClear(code);
534     bbCat(code,"\"\"");
535     len++;
536 } else
537            jquotestring(code,'"');
538 bbNull(code);
539    } else { /* not NC_CHAR*/
540        char* code2;
541 commify(code);
542        /* Convert to constant */
543        code2 = bbDup(code);
544        bbClear(code);
545        bbprintf0(stmt,"new %s[]",
546                jarraytype(typecode));
547        bbCatbuf(code,stmt);
548        bbCat(code,"{");
549        bbCat(code,code2);
550        bbCat(code,"}");
551        efree(code2);
552    }
553    switch (typecode) {
554    case NC_BYTE:
555    case NC_SHORT:
556    case NC_INT:
557    case NC_FLOAT:
558    case NC_DOUBLE:
559 codelined(1,"{");
560 bbprintf0(stmt,"%sArray data = Array.factory(%s.class, new int[]{%lu}, ",
561 indented(1),
562 jtype(basetype->typ.typecode),
563 len);
564 codedump(stmt);
565        codedump(code);
566 codeline(");");
567 if(asym->att.var == NULL) {
568            bbprintf0(stmt,"%sncfile.addGlobalAttribute(\"%s\",data);\n",
569                indented(1),jescapifyname(asym->name));
570 } else {
571            bbprintf0(stmt,"%sncfile.addVariableAttribute(\"%s\",\"%s\",data);\n",
572 indented(1),
573 jescapifyname(asym->att.var->name),
574                jescapifyname(asym->name));
575 }
576        codedump(stmt);
577 codelined(1,"}");
578        codeflush();
579        break;
580
581    case NC_CHAR:
582 if(asym->att.var == NULL) {
583            bbprintf0(stmt,"%sncfile.addGlobalAttribute(\"%s\",%s);\n",
584 indented(1),
585                jescapifyname(asym->name),
586 bbContents(code));
587 } else {
588            bbprintf0(stmt,"%sncfile.addVariableAttribute(\"%s\",\"%s\",%s);\n",
589 indented(1),
590 jescapifyname(asym->att.var->name),
591                jescapifyname(asym->name),
592 bbContents(code));
593 }
594        codedump(stmt);
595        codeflush();
596        break;
597
598    default: break;
599    }
600    codeflush();
601}
602
603
604#endif /*ENABLE_JAVA*/


HyperKWIC - Version 7.20DA executed at 11:37 on 27 Oct 2017 | Polyhedron Solutions - INTERNAL USE | COMMERCIAL (Any O/S) SN 4AKIed