/*
   * When generating (no) code for init routine, also generate File*
   * and close() for file.
   */
  private static void genFileReaderInit(
      SIRFileReader fr,
      CType return_type,
      String function_name,
      int selfID,
      List /*String*/ cleanupCode,
      CodegenPrintWriter p) {

    int id = NodeEnumerator.getSIROperatorId(fr);
    String theType = "" + fr.getOutputType();
    // dispatch to special routine for bit type
    if (theType.equals("bit")) {
      p.print("FILE* " + fpName(fr) + ";");
      p.newLine();
      p.newLine();
    }

    startParameterlessFunction(CommonUtils.CTypeToStringA(return_type, true), function_name, p);

    if (theType.equals("bit")) {
      p.print(fpName(fr) + " = fopen(\"" + fr.getFileName() + "\", \"r\");");
      p.newLine();
      p.print("assert (" + fpName(fr) + ");");
      p.newLine();
    } else {
      p.print("__file_descr__" + id + " = FileReader_open(\"" + fr.getFileName() + "\");");
      p.newLine();
      p.print("assert (__file_descr__" + id + ");");
      p.newLine();
    }

    endFunction(p);

    String closeName = ClusterUtils.getWorkName(fr, selfID) + "__close";

    startParameterlessFunction("void", closeName, p);

    if (theType.equals("bit")) {
      p.println("fclose(" + fpName(fr) + ");");
    } else {
      p.println("FileReader_close(__file_descr__" + id + ");");
    }

    endFunction(p);

    cleanupCode.add(closeName + "();\n");
  }
  /*
   * When generating (no) code for init routine, also generate File*
   * and close() for file.
   */
  private static void genFileWriterInit(
      SIRFileWriter fw,
      CType return_type,
      String function_name,
      int selfID,
      List /*String*/ cleanupCode,
      CodegenPrintWriter p) {

    int id = NodeEnumerator.getSIROperatorId(fw);

    String theType = "" + fw.getInputType();
    String bits_to_go = bitsToGoName(fw);
    String the_bits = theBitsName(fw);

    if (theType.equals("bit")) {
      p.println("FILE* " + fpName(fw) + ";");
    }

    if (theType.equals("bit")) {
      // the bit type is special since you can not just read or
      // write a bit.  It requires buffering in some larger
      // integer type.

      p.println(bits_type + " " + the_bits + " = 0;");
      p.println("int " + bits_to_go + " = 8 * sizeof(" + the_bits + ");");
    }
    p.newLine();

    startParameterlessFunction(CommonUtils.CTypeToStringA(return_type, true), function_name, p);

    if (theType.equals("bit")) {
      p.println(fpName(fw) + " = fopen(\"" + fw.getFileName() + "\", \"w\");");
      p.println("assert (" + fpName(fw) + ");");
    } else {
      p.print("__file_descr__" + id + " = FileWriter_open(\"" + fw.getFileName() + "\");");
      p.newLine();
      p.print("assert (__file_descr__" + id + ");");
      p.newLine();
    }

    endFunction(p);

    String closeName = ClusterUtils.getWorkName(fw, selfID) + "__close";

    startParameterlessFunction("void", closeName, p);
    if (theType.equals("bit")) {
      p.println("if (" + bits_to_go + " != 8 * sizeof(" + the_bits + ")) {");
      p.indent();
      p.println(the_bits + " = " + the_bits + " << " + bits_to_go + ";");
      p.println(
          "fwrite("
              + "&"
              + the_bits
              + ", "
              + "sizeof("
              + the_bits
              + "), "
              + "1, "
              + fpName(fw)
              + ");");
      p.outdent();
      p.println("}");
    }

    if (theType.equals("bit")) {
      p.println("fclose(" + fpName(fw) + ");");
    } else {
      p.println("FileWriter_flush(__file_descr__" + id + ");");
      p.println("FileWriter_close(__file_descr__" + id + ");");
    }

    endFunction(p);

    cleanupCode.add(closeName + "();\n");
  }