CCCPaste
#include <cstdio>
#include <cstdlib>
#include <cstring>

#define ILLEGAL_FILE_TYPE 0

int main (char** argc, int argv) {
if (argv < 3) {
printf("Usage: sbconvert [input path] [output path]");
return EXIT_FAILURE;
}
FILE* in = fopen(argc[1], "rbx");
if (in == NULL) {
printf("Could not open input file (be sure it exists!)");
return EXIT_FAILURE;
}
FILE* out = fopen(argc[2], "wbx");
if (out == NULL) {
printf("Could not open output file (be sure it exists!)");
return EXIT_FAILURE;
}
try {
convert(in, out);
return EXIT_SUCCESS;
} catch (int error) {
printError(error);
return EXIT_FAILURE;
}
}

void convert (FILE* in, FILE* out) {
if (strcmp(readString(in, 8), "ScratchV") == 0) {
convertSB(in, out);
return;
}
fseek(in, 0, SEEK_SET);
if (strcmp(readString(in, 2), "PK") == 0) {
fseek(in, 0, SEEK_SET);
convertZIP(in, out);
return;
}
throw ILLEGAL_FILE_TYPE;
}

void convertZIP (FILE* in, FILE* out) {
ScratchProject p = readZIP(in);
writeSB(p, out);
}

void convertSB (FILE* in, FILE* out) {
ScratchProject p = readSB(in);
writeZIP(p, out);
}

ScratchProject readZIP (FILE* in) {
unsigned long inlen = 0;
while (fgetc(in) != EOF) inlen++
if (!feof(in)) throw IO_ERROR;
fseek(in, 0, SEEK_SET);
unsigned char* buf[inlen];
for (unsigned long l = 0; l < inlen; l++)
buf[l] = fgetc(in);
zipios::ZipFile f = zipios::ZipFile(sstream::istringstream(buf), 0, inlen);
std::vector<std::shared_ptr<FileEntry>> vector = f.entries();
ByteBuffer bitmaps[vector.size()];
int bi = 0;
ByteBuffer vectors[vector.size()];
int vi = 0;
ByteBuffer sounds[vector.size()];
int si = 0;
ByteBuffer projectJSON = NULL;
for (std::vector<std::shared_ptr<FileEntry>>::iterator it = entries.begin(); it != entries.end(); ++it) {
FileEntry e = *(*it);
if (suffixMatch(e.getName(), "project.json")) {
if (projectJSON) throw MULTIPLE_PROJECT_JSONS;
projectJSON = readString(e);
} else if (suffixMatch(e.getName(), ".png")) {
bitmaps[bi++] = readBinary(e);
} else if (suffixMatch(e.getName(), ".svg")) {
vectors[vi++] = readString(e);
} else if (suffixMatch(e.getName(), ".wav")) {
sounds[si++] = readBinary(e);
}
}
if (!projectJSON) throw NO_PROJECT_JSON;
return read(projectJSON, bitmaps, bi, vectors, vi, sounds, si);
}

ByteBuffer readBinary (FileEntry e, FileCollection zf) {
zipios::ZipFile::stream_pointer_t is = zf.getInputStream(e.getName());
if (is) {
is.seekg (0, is.end);
int size = is.tellg();
is.seekg (0, is.beg);
unsigned char buf[size];
is->read(buf, size);
if (is) return ByteBuffer(buf, size);
}
throw ENTRY_READ_ERROR;
}

char* readString (FileEntry e, FileCollection zf) {
zipios::ZipFile::stream_pointer_t is = zf.getInputStream(e.getName());
if (is) {
is.seekg(0, is.end);
int size = is.tellg();
is.seekg(0, is.beg);
char buf[size + 1];
is->read(buf, size);
buf[size] = '\0';
if (is) return buf;
}
throw ENTRY_READ_ERROR;
}

ScratchProject read (char* project,
ByteBuffer* bitmaps, int blen,
char** vectors, int vlen,
ByteBuffer* sounds, int slen) {
Reader::Reader reader = Reader::Reader();
Value::Value value = Value::Value(ValueType.objectValue);
if (!reader.parse(project, project + strlen(project), &value, false)) throw INVALID_JSON;
if (!value["targets"].isArray()) throw MALFORMED_JSON;
if (!value["monitors"].isArray()) throw MALFORMED_JSON;
if (!value["extensions"].isArray()) throw MALFORMED_JSON;
if (value["extensions"].size() != 0) throw UNSUPPORTED_FEATURE;
ScratchProject p = ScratchProject();
readTargets(value["targets"], bitmaps, blen, vectors, vlen, sounds, slen);
readMonitors(value["monitors"], bitmaps, blen, vectors, vlen, sounds, slen);
return p;
}