diff options
Diffstat (limited to 'FreeRTOS/Demo/WIN32-MSVC-lwIP/lwIP_Apps/apps/httpserver_raw_from_lwIP_download/makefsdata/makefsdata.c')
-rw-r--r-- | FreeRTOS/Demo/WIN32-MSVC-lwIP/lwIP_Apps/apps/httpserver_raw_from_lwIP_download/makefsdata/makefsdata.c | 610 |
1 files changed, 0 insertions, 610 deletions
diff --git a/FreeRTOS/Demo/WIN32-MSVC-lwIP/lwIP_Apps/apps/httpserver_raw_from_lwIP_download/makefsdata/makefsdata.c b/FreeRTOS/Demo/WIN32-MSVC-lwIP/lwIP_Apps/apps/httpserver_raw_from_lwIP_download/makefsdata/makefsdata.c deleted file mode 100644 index b065caa08..000000000 --- a/FreeRTOS/Demo/WIN32-MSVC-lwIP/lwIP_Apps/apps/httpserver_raw_from_lwIP_download/makefsdata/makefsdata.c +++ /dev/null @@ -1,610 +0,0 @@ -/** - * makefsdata: Converts a directory structure for use with the lwIP httpd. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Jim Pettinato - * Simon Goldschmidt - * - * @todo: - * - take TCP_MSS, LWIP_TCP_TIMESTAMPS and - * PAYLOAD_ALIGN_TYPE/PAYLOAD_ALIGNMENT as arguments - */ - -#include <stdio.h> -#include <stdlib.h> -#ifdef WIN32 -#define WIN32_LEAN_AND_MEAN -#include "windows.h" -#else -#include <dir.h> -#endif -#include <dos.h> -#include <string.h> - -/* Compatibility defines Win32 vs. DOS */ -#ifdef WIN32 - -#define FIND_T WIN32_FIND_DATAA -#define FIND_T_FILENAME(fInfo) (fInfo.cFileName) -#define FIND_T_IS_DIR(fInfo) ((fInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) -#define FIND_T_IS_FILE(fInfo) ((fInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) -#define FIND_RET_T HANDLE -#define FINDFIRST_FILE(path, result) FindFirstFileA(path, result) -#define FINDFIRST_DIR(path, result) FindFirstFileA(path, result) -#define FINDNEXT(ff_res, result) FindNextFileA(ff_res, result) -#define FINDFIRST_SUCCEEDED(ret) (ret != INVALID_HANDLE_VALUE) -#define FINDNEXT_SUCCEEDED(ret) (ret == TRUE) - -#define GETCWD(path, len) GetCurrentDirectoryA(len, path) -#define CHDIR(path) SetCurrentDirectoryA(path) - -#define NEWLINE "\r\n" -#define NEWLINE_LEN 2 - -#else - -#define FIND_T struct fflbk -#define FIND_T_FILENAME(fInfo) (fInfo.ff_name) -#define FIND_T_IS_DIR(fInfo) ((fInfo.ff_attrib & FA_DIREC) == FA_DIREC) -#define FIND_T_IS_FILE(fInfo) (1) -#define FIND_RET_T int -#define FINDFIRST_FILE(path, result) findfirst(path, result, FA_ARCH) -#define FINDFIRST_DIR(path, result) findfirst(path, result, FA_DIREC) -#define FINDNEXT(ff_res, result) FindNextFileA(ff_res, result) -#define FINDFIRST_SUCCEEDED(ret) (ret == 0) -#define FINDNEXT_SUCCEEDED(ret) (ret == 0) - -#define GETCWD(path, len) getcwd(path, len) -#define CHDIR(path) chdir(path) - -#endif - -/* define this to get the header variables we use to build HTTP headers */ -#define LWIP_HTTPD_DYNAMIC_HEADERS 1 -#include "../httpd_structs.h" - -#include "../../../lwip-1.4.0/src/core/ipv4/inet_chksum.c" -#include "../../../lwip-1.4.0/src/core/def.c" - -/** (Your server name here) */ -const char *serverID = "Server: "HTTPD_SERVER_AGENT"\r\n"; - -/* change this to suit your MEM_ALIGNMENT */ -#define PAYLOAD_ALIGNMENT 4 -/* set this to 0 to prevent aligning payload */ -#define ALIGN_PAYLOAD 1 -/* define this to a type that has the required alignment */ -#define PAYLOAD_ALIGN_TYPE "unsigned int" -static int payload_alingment_dummy_counter = 0; - -#define HEX_BYTES_PER_LINE 16 - -#define MAX_PATH_LEN 256 - -#define COPY_BUFSIZE 10240 - -int process_sub(FILE *data_file, FILE *struct_file); -int process_file(FILE *data_file, FILE *struct_file, const char *filename); -int file_write_http_header(FILE *data_file, const char *filename, int file_size, - u16_t *http_hdr_len, u16_t *http_hdr_chksum); -int file_put_ascii(FILE *file, const char *ascii_string, int len, int *i); -int s_put_ascii(char *buf, const char *ascii_string, int len, int *i); -void concat_files(const char *file1, const char *file2, const char *targetfile); - -static unsigned char file_buffer_raw[COPY_BUFSIZE]; -/* 5 bytes per char + 3 bytes per line */ -static char file_buffer_c[COPY_BUFSIZE * 5 + ((COPY_BUFSIZE / HEX_BYTES_PER_LINE) * 3)]; - -char curSubdir[MAX_PATH_LEN]; -char lastFileVar[MAX_PATH_LEN]; -char hdr_buf[4096]; - -unsigned char processSubs = 1; -unsigned char includeHttpHeader = 1; -unsigned char useHttp11 = 0; -unsigned char precalcChksum = 0; - -int main(int argc, char *argv[]) -{ - FIND_T fInfo; - FIND_RET_T fret; - char path[MAX_PATH_LEN]; - char appPath[MAX_PATH_LEN]; - FILE *data_file; - FILE *struct_file; - int filesProcessed; - int i; - char targetfile[MAX_PATH_LEN]; - strcpy(targetfile, "fsdata.c"); - - memset(path, 0, sizeof(path)); - memset(appPath, 0, sizeof(appPath)); - - printf(NEWLINE " makefsdata - HTML to C source converter" NEWLINE); - printf(" by Jim Pettinato - circa 2003 " NEWLINE); - printf(" extended by Simon Goldschmidt - 2009 " NEWLINE NEWLINE); - - strcpy(path, "fs"); - for(i = 1; i < argc; i++) { - if (argv[i][0] == '-') { - if (strstr(argv[i], "-s")) { - processSubs = 0; - } else if (strstr(argv[i], "-e")) { - includeHttpHeader = 0; - } else if (strstr(argv[i], "-11")) { - useHttp11 = 1; - } else if (strstr(argv[i], "-c")) { - precalcChksum = 1; - } else if((argv[i][1] == 'f') && (argv[i][2] == ':')) { - strcpy(targetfile, &argv[i][3]); - printf("Writing to file \"%s\"\n", targetfile); - } - } else { - strcpy(path, argv[i]); - } - } - - /* if command line param or subdir named 'fs' not found spout usage verbiage */ - fret = FINDFIRST_DIR(path, &fInfo); - if (!FINDFIRST_SUCCEEDED(fret)) { - /* if no subdir named 'fs' (or the one which was given) exists, spout usage verbiage */ - printf(" Failed to open directory \"%s\"." NEWLINE NEWLINE, path); - printf(" Usage: htmlgen [targetdir] [-s] [-i] [-f:<filename>]" NEWLINE NEWLINE); - printf(" targetdir: relative or absolute path to files to convert" NEWLINE); - printf(" switch -s: toggle processing of subdirectories (default is on)" NEWLINE); - printf(" switch -e: exclude HTTP header from file (header is created at runtime, default is off)" NEWLINE); - printf(" switch -11: include HTTP 1.1 header (1.0 is default)" NEWLINE); - printf(" switch -c: precalculate checksums for all pages (default is off)" NEWLINE); - printf(" switch -f: target filename (default is \"fsdata.c\")" NEWLINE); - printf(" if targetdir not specified, htmlgen will attempt to" NEWLINE); - printf(" process files in subdirectory 'fs'" NEWLINE); - exit(-1); - } - - printf("HTTP %sheader will %s statically included." NEWLINE, - (includeHttpHeader ? (useHttp11 ? "1.1 " : "1.0 ") : ""), - (includeHttpHeader ? "be" : "not be")); - - sprintf(curSubdir, ""); /* start off in web page's root directory - relative paths */ - printf(" Processing all files in directory %s", path); - if (processSubs) { - printf(" and subdirectories..." NEWLINE NEWLINE); - } else { - printf("..." NEWLINE NEWLINE); - } - - GETCWD(appPath, MAX_PATH_LEN); - data_file = fopen("fsdata.tmp", "wb"); - if (data_file == NULL) { - printf("Failed to create file \"fsdata.tmp\"\n"); - exit(-1); - } - struct_file = fopen("fshdr.tmp", "wb"); - if (struct_file == NULL) { - printf("Failed to create file \"fshdr.tmp\"\n"); - exit(-1); - } - - CHDIR(path); - - fprintf(data_file, "#include \"fs.h\"" NEWLINE); - fprintf(data_file, "#include \"lwip/def.h\"" NEWLINE); - fprintf(data_file, "#include \"fsdata.h\"" NEWLINE NEWLINE NEWLINE); - - fprintf(data_file, "#define file_NULL (struct fsdata_file *) NULL" NEWLINE NEWLINE NEWLINE); - - sprintf(lastFileVar, "NULL"); - - filesProcessed = process_sub(data_file, struct_file); - - /* data_file now contains all of the raw data.. now append linked list of - * file header structs to allow embedded app to search for a file name */ - fprintf(data_file, NEWLINE NEWLINE); - fprintf(struct_file, "#define FS_ROOT file_%s" NEWLINE, lastFileVar); - fprintf(struct_file, "#define FS_NUMFILES %d" NEWLINE NEWLINE, filesProcessed); - - fclose(data_file); - fclose(struct_file); - - CHDIR(appPath); - /* append struct_file to data_file */ - printf(NEWLINE "Creating target file..." NEWLINE NEWLINE); - concat_files("fsdata.tmp", "fshdr.tmp", targetfile); - - /* if succeeded, delete the temporary files */ - remove("fsdata.tmp"); - remove("fshdr.tmp"); - - printf(NEWLINE "Processed %d files - done." NEWLINE NEWLINE, filesProcessed); - - return 0; -} - -static void copy_file(const char *filename_in, FILE *fout) -{ - FILE *fin; - size_t len; - fin = fopen(filename_in, "rb"); - if (fin == NULL) { - printf("Failed to open file \"%s\"\n", filename_in); - exit(-1); - } - - while((len = fread(file_buffer_raw, 1, COPY_BUFSIZE, fin)) > 0) - { - fwrite(file_buffer_raw, 1, len, fout); - } - fclose(fin); -} - -void concat_files(const char *file1, const char *file2, const char *targetfile) -{ - FILE *fout; - fout = fopen(targetfile, "wb"); - if (fout == NULL) { - printf("Failed to open file \"%s\"\n", targetfile); - exit(-1); - } - copy_file(file1, fout); - copy_file(file2, fout); - fclose(fout); -} - -int process_sub(FILE *data_file, FILE *struct_file) -{ - FIND_T fInfo; - FIND_RET_T fret; - int filesProcessed = 0; - char oldSubdir[MAX_PATH_LEN]; - - if (processSubs) { - /* process subs recursively */ - strcpy(oldSubdir, curSubdir); - fret = FINDFIRST_DIR("*", &fInfo); - if (FINDFIRST_SUCCEEDED(fret)) { - do { - const char *curName = FIND_T_FILENAME(fInfo); - if (curName == NULL) continue; - if (curName[0] == '.') continue; - if (strcmp(curName, "CVS") == 0) continue; - if (!FIND_T_IS_DIR(fInfo)) continue; - CHDIR(curName); - strcat(curSubdir, "/"); - strcat(curSubdir, curName); - printf(NEWLINE "processing subdirectory %s/..." NEWLINE, curSubdir); - filesProcessed += process_sub(data_file, struct_file); - CHDIR(".."); - strcpy(curSubdir, oldSubdir); - } while (FINDNEXT_SUCCEEDED(FINDNEXT(fret, &fInfo))); - } - } - - fret = FINDFIRST_FILE("*.*", &fInfo); - if (FINDFIRST_SUCCEEDED(fret)) { - /* at least one file in directory */ - do { - if (FIND_T_IS_FILE(fInfo)) { - const char *curName = FIND_T_FILENAME(fInfo); - printf("processing %s/%s..." NEWLINE, curSubdir, curName); - if (process_file(data_file, struct_file, curName) < 0) { - printf(NEWLINE "Error... aborting" NEWLINE); - return -1; - } - filesProcessed++; - } - } while (FINDNEXT_SUCCEEDED(FINDNEXT(fret, &fInfo))); - } - return filesProcessed; -} - -int get_file_size(const char* filename) -{ - FILE *inFile; - int file_size = -1; - inFile = fopen(filename, "rb"); - if (inFile == NULL) { - printf("Failed to open file \"%s\"\n", filename); - exit(-1); - } - fseek(inFile, 0, SEEK_END); - file_size = ftell(inFile); - fclose(inFile); - return file_size; -} - -void process_file_data(const char *filename, FILE *data_file) -{ - FILE *source_file; - size_t len, written, i, src_off=0; - - source_file = fopen(filename, "rb"); - - do { - size_t off = 0; - len = fread(file_buffer_raw, 1, COPY_BUFSIZE, source_file); - if (len > 0) { - for (i = 0; i < len; i++) { - sprintf(&file_buffer_c[off], "0x%02.2x,", file_buffer_raw[i]); - off += 5; - if ((++src_off % HEX_BYTES_PER_LINE) == 0) { - memcpy(&file_buffer_c[off], NEWLINE, NEWLINE_LEN); - off += NEWLINE_LEN; - } - } - written = fwrite(file_buffer_c, 1, off, data_file); - } - } while(len > 0); - fclose(source_file); -} - -int write_checksums(FILE *struct_file, const char *filename, const char *varname, - u16_t hdr_len, u16_t hdr_chksum) -{ - int chunk_size = TCP_MSS; - int offset; - size_t len; - int i = 0; - FILE *f; -#if LWIP_TCP_TIMESTAMPS - /* when timestamps are used, usable space is 12 bytes less per segment */ - chunk_size -= 12; -#endif - - fprintf(struct_file, "#if HTTPD_PRECALCULATED_CHECKSUM" NEWLINE); - fprintf(struct_file, "const struct fsdata_chksum chksums_%s[] = {" NEWLINE, varname); - - memset(file_buffer_raw, 0xab, sizeof(file_buffer_raw)); - f = fopen(filename, "rb"); - if (f == INVALID_HANDLE_VALUE) { - printf("Failed to open file \"%s\"\n", filename); - exit(-1); - } - if (hdr_len > 0) { - /* add checksum for HTTP header */ - fprintf(struct_file, "{%d, 0x%04x, %d}," NEWLINE, 0, hdr_chksum, hdr_len); - i++; - } - for (offset = hdr_len; ; offset += len) { - unsigned short chksum; - len = fread(file_buffer_raw, 1, chunk_size, f); - if (len == 0) { - break; - } - chksum = ~inet_chksum(file_buffer_raw, (u16_t)len); - /* add checksum for data */ - fprintf(struct_file, "{%d, 0x%04x, %d}," NEWLINE, offset, chksum, len); - i++; - } - fclose(f); - fprintf(struct_file, "};" NEWLINE); - fprintf(struct_file, "#endif /* HTTPD_PRECALCULATED_CHECKSUM */" NEWLINE); - return i; -} - -int process_file(FILE *data_file, FILE *struct_file, const char *filename) -{ - char *pch; - char varname[MAX_PATH_LEN]; - int i = 0; - char qualifiedName[MAX_PATH_LEN]; - int file_size; - u16_t http_hdr_chksum = 0; - u16_t http_hdr_len = 0; - int chksum_count = 0; - - /* create qualified name (TODO: prepend slash or not?) */ - sprintf(qualifiedName,"%s/%s", curSubdir, filename); - /* create C variable name */ - strcpy(varname, qualifiedName); - /* convert slashes & dots to underscores */ - while ((pch = strpbrk(varname, "./\\")) != NULL) { - *pch = '_'; - } -#if ALIGN_PAYLOAD - /* to force even alignment of array */ - fprintf(data_file, "static const " PAYLOAD_ALIGN_TYPE " dummy_align_%s = %d;" NEWLINE, varname, payload_alingment_dummy_counter++); -#endif /* ALIGN_PAYLOAD */ - fprintf(data_file, "static const unsigned char data_%s[] = {" NEWLINE, varname); - /* encode source file name (used by file system, not returned to browser) */ - fprintf(data_file, "/* %s (%d chars) */" NEWLINE, qualifiedName, strlen(qualifiedName)+1); - file_put_ascii(data_file, qualifiedName, strlen(qualifiedName)+1, &i); -#if ALIGN_PAYLOAD - /* pad to even number of bytes to assure payload is on aligned boundary */ - while(i % PAYLOAD_ALIGNMENT != 0) { - fprintf(data_file, "0x%02.2x,", 0); - i++; - } -#endif /* ALIGN_PAYLOAD */ - fprintf(data_file, NEWLINE); - - file_size = get_file_size(filename); - if (includeHttpHeader) { - file_write_http_header(data_file, filename, file_size, &http_hdr_len, &http_hdr_chksum); - } - if (precalcChksum) { - chksum_count = write_checksums(struct_file, filename, varname, http_hdr_len, http_hdr_chksum); - } - - /* build declaration of struct fsdata_file in temp file */ - fprintf(struct_file, "const struct fsdata_file file_%s[] = { {" NEWLINE, varname); - fprintf(struct_file, "file_%s," NEWLINE, lastFileVar); - fprintf(struct_file, "data_%s," NEWLINE, varname); - fprintf(struct_file, "data_%s + %d," NEWLINE, varname, i); - fprintf(struct_file, "sizeof(data_%s) - %d," NEWLINE, varname, i); - fprintf(struct_file, "%d," NEWLINE, includeHttpHeader); - if (precalcChksum) { - fprintf(struct_file, "#if HTTPD_PRECALCULATED_CHECKSUM" NEWLINE); - fprintf(struct_file, "%d, chksums_%s," NEWLINE, chksum_count, varname); - fprintf(struct_file, "#endif /* HTTPD_PRECALCULATED_CHECKSUM */" NEWLINE); - } - fprintf(struct_file, "}};" NEWLINE NEWLINE); - strcpy(lastFileVar, varname); - - /* write actual file contents */ - i = 0; - fprintf(data_file, NEWLINE "/* raw file data (%d bytes) */" NEWLINE, file_size); - process_file_data(filename, data_file); - fprintf(data_file, "};" NEWLINE NEWLINE); - - return 0; -} - -int file_write_http_header(FILE *data_file, const char *filename, int file_size, - u16_t *http_hdr_len, u16_t *http_hdr_chksum) -{ - int i = 0; - int response_type = HTTP_HDR_OK; - int file_type = HTTP_HDR_DEFAULT_TYPE; - const char *cur_string; - size_t cur_len; - int written = 0; - size_t hdr_len = 0; - u16_t acc; - const char *file_ext; - int j; - - memset(hdr_buf, 0, sizeof(hdr_buf)); - - if (useHttp11) { - response_type = HTTP_HDR_OK_11; - } - - fprintf(data_file, NEWLINE "/* HTTP header */"); - if (strstr(filename, "404") == filename) { - response_type = HTTP_HDR_NOT_FOUND; - if (useHttp11) { - response_type = HTTP_HDR_NOT_FOUND_11; - } - } else if (strstr(filename, "400") == filename) { - response_type = HTTP_HDR_BAD_REQUEST; - if (useHttp11) { - response_type = HTTP_HDR_BAD_REQUEST_11; - } - } else if (strstr(filename, "501") == filename) { - response_type = HTTP_HDR_NOT_IMPL; - if (useHttp11) { - response_type = HTTP_HDR_NOT_IMPL_11; - } - } - cur_string = g_psHTTPHeaderStrings[response_type]; - cur_len = strlen(cur_string); - fprintf(data_file, NEWLINE "/* \"%s\" (%d bytes) */" NEWLINE, cur_string, cur_len); - written += file_put_ascii(data_file, cur_string, cur_len, &i); - i = 0; - if (precalcChksum) { - memcpy(&hdr_buf[hdr_len], cur_string, cur_len); - hdr_len += cur_len; - } - - cur_string = serverID; - cur_len = strlen(cur_string); - fprintf(data_file, NEWLINE "/* \"%s\" (%d bytes) */" NEWLINE, cur_string, cur_len); - written += file_put_ascii(data_file, cur_string, cur_len, &i); - i = 0; - if (precalcChksum) { - memcpy(&hdr_buf[hdr_len], cur_string, cur_len); - hdr_len += cur_len; - } - - file_ext = filename; - while(strstr(file_ext, ".") != NULL) { - file_ext = strstr(file_ext, "."); - file_ext++; - } - if((file_ext == NULL) || (*file_ext == 0)) { - printf("failed to get extension for file \"%s\", using default.\n", filename); - } else { - for(j = 0; j < NUM_HTTP_HEADERS; j++) { - if(!strcmp(file_ext, g_psHTTPHeaders[j].extension)) { - file_type = g_psHTTPHeaders[j].headerIndex; - break; - } - } - if (j >= NUM_HTTP_HEADERS) { - printf("failed to get file type for extension \"%s\", using default.\n", file_ext); - file_type = HTTP_HDR_DEFAULT_TYPE; - } - } - - if (useHttp11) { - char intbuf[MAX_PATH_LEN]; - memset(intbuf, 0, sizeof(intbuf)); - - cur_string = g_psHTTPHeaderStrings[HTTP_HDR_CONTENT_LENGTH]; - cur_len = strlen(cur_string); - fprintf(data_file, NEWLINE "/* \"%s%d\r\n\" (%d+ bytes) */" NEWLINE, cur_string, file_size, cur_len+2); - written += file_put_ascii(data_file, cur_string, cur_len, &i); - if (precalcChksum) { - memcpy(&hdr_buf[hdr_len], cur_string, cur_len); - hdr_len += cur_len; - } - - _itoa(file_size, intbuf, 10); - strcat(intbuf, "\r\n"); - cur_len = strlen(intbuf); - written += file_put_ascii(data_file, intbuf, cur_len, &i); - i = 0; - if (precalcChksum) { - memcpy(&hdr_buf[hdr_len], intbuf, cur_len); - hdr_len += cur_len; - } - - cur_string = g_psHTTPHeaderStrings[HTTP_HDR_CONN_CLOSE]; - cur_len = strlen(cur_string); - fprintf(data_file, NEWLINE "/* \"%s\" (%d bytes) */" NEWLINE, cur_string, cur_len); - written += file_put_ascii(data_file, cur_string, cur_len, &i); - i = 0; - if (precalcChksum) { - memcpy(&hdr_buf[hdr_len], cur_string, cur_len); - hdr_len += cur_len; - } - } - - cur_string = g_psHTTPHeaderStrings[file_type]; - cur_len = strlen(cur_string); - fprintf(data_file, NEWLINE "/* \"%s\" (%d bytes) */" NEWLINE, cur_string, cur_len); - written += file_put_ascii(data_file, cur_string, cur_len, &i); - i = 0; - if (precalcChksum) { - memcpy(&hdr_buf[hdr_len], cur_string, cur_len); - hdr_len += cur_len; - - LWIP_ASSERT("hdr_len <= 0xffff", hdr_len <= 0xffff); - LWIP_ASSERT("strlen(hdr_buf) == hdr_len", strlen(hdr_buf) == hdr_len); - acc = ~inet_chksum(hdr_buf, (u16_t)hdr_len); - *http_hdr_len = (u16_t)hdr_len; - *http_hdr_chksum = acc; - } - - return written; -} - -int file_put_ascii(FILE *file, const char* ascii_string, int len, int *i) -{ - int x; - for(x = 0; x < len; x++) { - unsigned char cur = ascii_string[x]; - fprintf(file, "0x%02.2x,", cur); - if ((++(*i) % HEX_BYTES_PER_LINE) == 0) { - fprintf(file, NEWLINE); - } - } - return len; -} - -int s_put_ascii(char *buf, const char *ascii_string, int len, int *i) -{ - int x; - int idx = 0; - for(x = 0; x < len; x++) { - unsigned char cur = ascii_string[x]; - sprintf(&buf[idx], "0x%02.2x,", cur); - idx += 5; - if ((++(*i) % HEX_BYTES_PER_LINE) == 0) { - sprintf(&buf[idx], NEWLINE); - idx += NEWLINE_LEN; - } - } - return len; -} |