xref: /aosp_15_r20/external/sandboxed-api/contrib/libxls/utils/utils_libxls.cc (revision ec63e07ab9515d95e79c211197c445ef84cefa6a)
1*ec63e07aSXin Li // Copyright 2022 Google LLC
2*ec63e07aSXin Li //
3*ec63e07aSXin Li // Licensed under the Apache License, Version 2.0 (the "License");
4*ec63e07aSXin Li // you may not use this file except in compliance with the License.
5*ec63e07aSXin Li // You may obtain a copy of the License at
6*ec63e07aSXin Li //
7*ec63e07aSXin Li //     https://www.apache.org/licenses/LICENSE-2.0
8*ec63e07aSXin Li //
9*ec63e07aSXin Li // Unless required by applicable law or agreed to in writing, software
10*ec63e07aSXin Li // distributed under the License is distributed on an "AS IS" BASIS,
11*ec63e07aSXin Li // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*ec63e07aSXin Li // See the License for the specific language governing permissions and
13*ec63e07aSXin Li // limitations under the License.
14*ec63e07aSXin Li 
15*ec63e07aSXin Li #include "contrib/libxls/utils/utils_libxls.h"
16*ec63e07aSXin Li 
17*ec63e07aSXin Li #include <fstream>
18*ec63e07aSXin Li #include <iostream>
19*ec63e07aSXin Li #include <string>
20*ec63e07aSXin Li 
21*ec63e07aSXin Li #include "contrib/libxls/sandboxed.h"
22*ec63e07aSXin Li 
GetError(LibxlsApi * api,xls_error_t error_code)23*ec63e07aSXin Li absl::Status GetError(LibxlsApi* api, xls_error_t error_code) {
24*ec63e07aSXin Li   SAPI_ASSIGN_OR_RETURN(const char* c_errstr, api->xls_getError(error_code));
25*ec63e07aSXin Li   sapi::v::RemotePtr sapi_errstr(const_cast<char*>(c_errstr));
26*ec63e07aSXin Li   SAPI_ASSIGN_OR_RETURN(std::string errstr,
27*ec63e07aSXin Li                         api->GetSandbox()->GetCString(sapi_errstr));
28*ec63e07aSXin Li 
29*ec63e07aSXin Li   return absl::UnavailableError(errstr);
30*ec63e07aSXin Li }
31*ec63e07aSXin Li 
Open(LibxlsSapiSandbox * sandbox,const std::string & filename,const std::string & encode)32*ec63e07aSXin Li absl::StatusOr<LibXlsWorkbook> LibXlsWorkbook::Open(LibxlsSapiSandbox* sandbox,
33*ec63e07aSXin Li                                                     const std::string& filename,
34*ec63e07aSXin Li                                                     const std::string& encode) {
35*ec63e07aSXin Li   if (sandbox == nullptr) {
36*ec63e07aSXin Li     return absl::InvalidArgumentError("Sandbox has to be defined");
37*ec63e07aSXin Li   }
38*ec63e07aSXin Li 
39*ec63e07aSXin Li   LibxlsApi api(sandbox);
40*ec63e07aSXin Li 
41*ec63e07aSXin Li   sapi::v::IntBase<xls_error_t> sapi_error;
42*ec63e07aSXin Li   sapi::v::CStr sapi_filename(filename.c_str());
43*ec63e07aSXin Li   sapi::v::CStr sapi_encode(encode.c_str());
44*ec63e07aSXin Li 
45*ec63e07aSXin Li   SAPI_ASSIGN_OR_RETURN(
46*ec63e07aSXin Li       xlsWorkBook * wb,
47*ec63e07aSXin Li       api.xls_open_file(sapi_filename.PtrBefore(), sapi_encode.PtrBefore(),
48*ec63e07aSXin Li                         sapi_error.PtrAfter()));
49*ec63e07aSXin Li 
50*ec63e07aSXin Li   if (wb == nullptr) {
51*ec63e07aSXin Li     return GetError(&api, sapi_error.GetValue());
52*ec63e07aSXin Li   }
53*ec63e07aSXin Li 
54*ec63e07aSXin Li   sapi::v::Struct<xlsWorkBook> sapi_wb;
55*ec63e07aSXin Li   sapi_wb.SetRemote(wb);
56*ec63e07aSXin Li   SAPI_RETURN_IF_ERROR(sandbox->TransferFromSandboxee(&sapi_wb));
57*ec63e07aSXin Li 
58*ec63e07aSXin Li   return LibXlsWorkbook(sandbox, wb, sapi_wb.data().sheets.count);
59*ec63e07aSXin Li }
60*ec63e07aSXin Li 
~LibXlsWorkbook()61*ec63e07aSXin Li LibXlsWorkbook::~LibXlsWorkbook() {
62*ec63e07aSXin Li   if (rwb_ != nullptr) {
63*ec63e07aSXin Li     sapi::v::RemotePtr sapi_rwb(rwb_);
64*ec63e07aSXin Li     LibxlsApi api(sandbox_);
65*ec63e07aSXin Li     api.xls_close_WB(&sapi_rwb).IgnoreError();
66*ec63e07aSXin Li   }
67*ec63e07aSXin Li }
68*ec63e07aSXin Li 
GetSheetCount()69*ec63e07aSXin Li size_t LibXlsWorkbook::GetSheetCount() { return sheet_count_; }
70*ec63e07aSXin Li 
OpenSheet(uint32_t index)71*ec63e07aSXin Li absl::StatusOr<LibXlsSheet> LibXlsWorkbook::OpenSheet(uint32_t index) {
72*ec63e07aSXin Li   if (GetSheetCount() <= index) {
73*ec63e07aSXin Li     return absl::OutOfRangeError("Index out of range");
74*ec63e07aSXin Li   }
75*ec63e07aSXin Li 
76*ec63e07aSXin Li   LibxlsApi api(sandbox_);
77*ec63e07aSXin Li   sapi::v::RemotePtr sapi_rwb(rwb_);
78*ec63e07aSXin Li   SAPI_ASSIGN_OR_RETURN(xlsWorkSheet * ws,
79*ec63e07aSXin Li                         api.xls_getWorkSheet(&sapi_rwb, index));
80*ec63e07aSXin Li   if (ws == nullptr) {
81*ec63e07aSXin Li     return absl::UnavailableError("Unable to open sheet");
82*ec63e07aSXin Li   }
83*ec63e07aSXin Li 
84*ec63e07aSXin Li   sapi::v::Struct<xlsWorkSheet> sapi_ws;
85*ec63e07aSXin Li   sapi_ws.SetRemote(ws);
86*ec63e07aSXin Li   SAPI_ASSIGN_OR_RETURN(xls_error_t error_code,
87*ec63e07aSXin Li                         api.xls_parseWorkSheet(sapi_ws.PtrAfter()));
88*ec63e07aSXin Li   if (error_code != 0) {
89*ec63e07aSXin Li     return GetError(&api, error_code);
90*ec63e07aSXin Li   }
91*ec63e07aSXin Li 
92*ec63e07aSXin Li   return LibXlsSheet(sandbox_, ws, sapi_ws.data().rows.lastrow + 1,
93*ec63e07aSXin Li                      sapi_ws.data().rows.lastcol + 1);
94*ec63e07aSXin Li }
95*ec63e07aSXin Li 
GetRowCount() const96*ec63e07aSXin Li size_t LibXlsSheet::GetRowCount() const { return row_; }
97*ec63e07aSXin Li 
GetColCount() const98*ec63e07aSXin Li size_t LibXlsSheet::GetColCount() const { return col_; }
99*ec63e07aSXin Li 
GetStr(const sapi::v::Struct<xlsCell> & sapi_cell)100*ec63e07aSXin Li absl::StatusOr<std::string> LibXlsSheet::GetStr(
101*ec63e07aSXin Li     const sapi::v::Struct<xlsCell>& sapi_cell) {
102*ec63e07aSXin Li   if (sapi_cell.data().str == nullptr) {
103*ec63e07aSXin Li     return "";
104*ec63e07aSXin Li   }
105*ec63e07aSXin Li 
106*ec63e07aSXin Li   sapi::v::RemotePtr sapi_str(sapi_cell.data().str);
107*ec63e07aSXin Li   return sandbox_->GetCString(sapi_str);
108*ec63e07aSXin Li }
109*ec63e07aSXin Li 
GetNewCell(const sapi::v::Struct<xlsCell> & sapi_cell)110*ec63e07aSXin Li absl::StatusOr<LibXlsCell> LibXlsSheet::GetNewCell(
111*ec63e07aSXin Li     const sapi::v::Struct<xlsCell>& sapi_cell) {
112*ec63e07aSXin Li   int id = sapi_cell.data().id;
113*ec63e07aSXin Li   double d = sapi_cell.data().d;
114*ec63e07aSXin Li 
115*ec63e07aSXin Li   switch (id) {
116*ec63e07aSXin Li     case XLS_RECORD_RK:
117*ec63e07aSXin Li     case XLS_RECORD_MULRK:
118*ec63e07aSXin Li     case XLS_RECORD_NUMBER:
119*ec63e07aSXin Li       return LibXlsCell{XLS_RECORD_NUMBER, d};
120*ec63e07aSXin Li     case XLS_RECORD_BLANK:
121*ec63e07aSXin Li       return LibXlsCell{XLS_RECORD_BLANK, 0.0};
122*ec63e07aSXin Li     case XLS_RECORD_FORMULA:
123*ec63e07aSXin Li       SAPI_ASSIGN_OR_RETURN(std::string cell_str, GetStr(sapi_cell));
124*ec63e07aSXin Li       if (cell_str == "bool") {
125*ec63e07aSXin Li         return LibXlsCell{XLS_RECORD_BOOL, d > 0};
126*ec63e07aSXin Li       } else if (cell_str == "error") {
127*ec63e07aSXin Li         return LibXlsCell{XLS_RECORD_ERROR, cell_str};
128*ec63e07aSXin Li       }
129*ec63e07aSXin Li       return LibXlsCell{XLS_RECORD_STRING, cell_str};
130*ec63e07aSXin Li   }
131*ec63e07aSXin Li 
132*ec63e07aSXin Li   return absl::UnavailableError("Unknown type");
133*ec63e07aSXin Li }
134*ec63e07aSXin Li 
GetCell(uint32_t row,uint32_t col)135*ec63e07aSXin Li absl::StatusOr<LibXlsCell> LibXlsSheet::GetCell(uint32_t row, uint32_t col) {
136*ec63e07aSXin Li   if (row >= GetRowCount()) {
137*ec63e07aSXin Li     return absl::OutOfRangeError("Row out of range");
138*ec63e07aSXin Li   }
139*ec63e07aSXin Li   if (col >= GetColCount()) {
140*ec63e07aSXin Li     return absl::OutOfRangeError("Col out of range");
141*ec63e07aSXin Li   }
142*ec63e07aSXin Li 
143*ec63e07aSXin Li   LibxlsApi api(sandbox_);
144*ec63e07aSXin Li   sapi::v::RemotePtr sapi_rws(rws_);
145*ec63e07aSXin Li   SAPI_ASSIGN_OR_RETURN(xlsCell * cell, api.xls_cell(&sapi_rws, row, col));
146*ec63e07aSXin Li   if (cell == nullptr) {
147*ec63e07aSXin Li     return absl::UnavailableError("Unable to get cell");
148*ec63e07aSXin Li   }
149*ec63e07aSXin Li   sapi::v::Struct<xlsCell> sapi_cell;
150*ec63e07aSXin Li   sapi_cell.SetRemote(cell);
151*ec63e07aSXin Li   SAPI_RETURN_IF_ERROR(sandbox_->TransferFromSandboxee(&sapi_cell));
152*ec63e07aSXin Li 
153*ec63e07aSXin Li   return GetNewCell(sapi_cell);
154*ec63e07aSXin Li }
155*ec63e07aSXin Li 
~LibXlsSheet()156*ec63e07aSXin Li LibXlsSheet::~LibXlsSheet() {
157*ec63e07aSXin Li   if (rws_ != nullptr) {
158*ec63e07aSXin Li     LibxlsApi api(sandbox_);
159*ec63e07aSXin Li     sapi::v::RemotePtr sapi_rws(rws_);
160*ec63e07aSXin Li     api.xls_close_WS(&sapi_rws).IgnoreError();
161*ec63e07aSXin Li   }
162*ec63e07aSXin Li }
163